base-trixie: the image on Debian trixie, Postfix 3.10.13; Received: hidden on 465/587
test / test (push) Canceled after 0s
test / test (push) Canceled after 0s
The runtime base is debian:trixie-slim, the build stage golang:1.26-trixie:
Postfix 3.10.13 with upstream's 2026 security fixes up to the August
batch, libmilter 8.18.1, OpenSSL 3.5. Every citation of another program in
code, scripts and documents was re-read against the trixie sources
(dev/upstream; bookworm's kept in dev/upstream-bookworm) and updated;
development.md's cited-package table holds the trixie versions.
What the re-reading changed in behaviour:
- logtail: reject lines with sasl_method/sasl_username/sasl_sender
(smtpd_check.c:1019-1026); cleanup's "removed (canceled)" forgets a
port-25 id (cleanup_api.c:363-364).
- internal/postfix/retry.go reads postconf's stdout only: since 3.9 a
deprecated-parameter warning on stderr made one value too many and the
panel fell back to the compiled-in retry policy.
- logrotate-loop.sh: logrotate 3.22 exits 1 when it ignores a config;
the loop refuses on that output whatever the status.
- postfix-config.sh: cyrus_sasl_config_path set explicitly (bookworm's
07_sasl_config.diff is gone); maillog_file_permissions=0640; mynetworks
explicit; Dockerfile: SYNC_CHROOT= in /etc/default/postfix,
opendkim-tools dropped, openssl named, systemd-standalone-sysusers so
cron does not bring the whole of systemd.
- The selfpost group is 10998, outside the system range 100-999: in
trixie a package took 998 and the build failed (owner's decision:
a conflict-free id, the distribution's own ids untouched). The
entrypoint hands /data back by name when the user or the group differs.
Guide, backup refusal text, help (design commit 68ec8b2), e2e.
- smtpd_hide_client_session=yes on smtps and submission (owner's
decision): Received: names no client, TLS, login or protocol; port 25
keeps the full header. e2e checks both.
- test/upstream/opendkim-probe.sh makes keys with openssl genrsa.
Tests: on the server, make e2e exit 0 (674 s, the image built on trixie),
go vet + go test 27 packages ok. CHANGELOG [Unreleased], guide,
architecture.md, security.md, roadmap.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,7 @@ func TestCleanAddress(t *testing.T) {
|
||||
// The journal row's recipient has to be the address Postfix later logs in
|
||||
// to=<…>, or the delivery line matches no row and the sweep closes it as
|
||||
// bounced: the local part unquoted, then quoted again only when it is not a
|
||||
// dot-string (Postfix 3.7.11, src/global/tok822_parse.c and
|
||||
// dot-string (Postfix 3.10.13, src/global/tok822_parse.c and
|
||||
// quote_822_local.c). Composed by hand after those functions.
|
||||
func TestRecipientAsLogged(t *testing.T) {
|
||||
for _, c := range []struct{ in, want string }{
|
||||
|
||||
@@ -34,7 +34,7 @@ type InboundStore interface {
|
||||
// Postfix attaches the socket with default_action=accept, so
|
||||
// neither an error here nor the panel being down holds up inbound mail.
|
||||
//
|
||||
// Postfix 3.7.11, src/milter/milter.c, milter_message(): the milters are asked
|
||||
// Postfix 3.10.13, src/milter/milter.c, milter_message(): the milters are asked
|
||||
// in turn while the reply is null, so one that refuses is the last asked;
|
||||
// src/milter/milter8.c, milter8_comm_error(): default_action=accept gives no
|
||||
// reply when this milter cannot answer.
|
||||
@@ -91,7 +91,7 @@ func (s *inboundSession) RcptTo(rcpt string, m *milter.Modifier) (milter.Respons
|
||||
// the last one read is its own - when it is up. Whether it was is decided at
|
||||
// end-of-message, by the signature.
|
||||
//
|
||||
// Postfix 3.7.11, src/milter/milter.c, milter_message(), hands each milter the
|
||||
// Postfix 3.10.13, src/milter/milter.c, milter_message(), hands each milter the
|
||||
// queue file from the start of the content; src/milter/milter8.c,
|
||||
// milter8_message(), reads it with rec_get(), which follows the pointer
|
||||
// records src/cleanup/cleanup_milter.c, cleanup_add_header(), leaves after
|
||||
@@ -151,7 +151,7 @@ func (s *inboundSession) signed(queueID string) bool {
|
||||
// upstream. "Continue" lets it through as "accept" would, and keeps this
|
||||
// session for the connection's next message.
|
||||
//
|
||||
// The queue id: Postfix 3.7.11, src/global/mail_params.h, DEF_MILT_EOD_MACROS
|
||||
// The queue id: Postfix 3.10.13, src/global/mail_params.h, DEF_MILT_EOD_MACROS
|
||||
// "i", answered by src/cleanup/cleanup_milter.c, cleanup_milter_eval(). The
|
||||
// rest as session.Body in milter.go.
|
||||
func (s *inboundSession) Body(m *milter.Modifier) (milter.Response, error) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
// reservationTTL bounds how long a message may stay reserved. A reservation is
|
||||
// released at end-of-message or on ABORT. A client that drops the connection
|
||||
// mid-transaction still produces ABORT: Postfix 3.7.11, src/smtpd/smtpd.c,
|
||||
// mid-transaction still produces ABORT: Postfix 3.10.13, src/smtpd/smtpd.c,
|
||||
// smtpd_proto() on a lost connection runs mail_reset(), which calls
|
||||
// milter_abort() (src/milter/milter8.c, milter8_abort(), SMFIC_ABORT)
|
||||
// (assumptions B-G7). What produces neither is smtpd itself dying, or the
|
||||
|
||||
@@ -2,7 +2,7 @@ package milter
|
||||
|
||||
// The address OpenDKIM signs for, found as OpenDKIM finds it: a port of
|
||||
// libopendkim's dkim_mail_parse() and its tokenizer, from Debian's
|
||||
// opendkim 2.11.0~beta2-8+deb12u1 (libopendkim/dkim-mailparse.c, identical
|
||||
// opendkim 2.11.0~beta2-9.1+b1 (libopendkim/dkim-mailparse.c, identical
|
||||
// there to upstream's develop branch), line for line. OpenDKIM calls it on the
|
||||
// value of the message's first From: field (opendkim/opendkim.c, mlfi_eoh(),
|
||||
// dkimf_findheader(dfc, "from", 0): build/opendkim.conf sets no SenderHeaders),
|
||||
|
||||
+15
-15
@@ -13,7 +13,7 @@
|
||||
// Postfix is configured with default_action=accept for this milter's socket,
|
||||
// so even a crash or hang fails open (architecture.md § Mail path).
|
||||
//
|
||||
// Postfix 3.7.11, src/milter/milter8.c, milter8_comm_error(): a milter that
|
||||
// Postfix 3.10.13, src/milter/milter8.c, milter8_comm_error(): a milter that
|
||||
// cannot be reached, or does not answer within milter_*_timeout, gives no
|
||||
// reply with default_action=accept - the message goes on.
|
||||
package milter
|
||||
@@ -55,7 +55,7 @@ type Store interface {
|
||||
//
|
||||
// go-milter v0.4.1, session.go, Process(), case CodeMacro: every macro packet
|
||||
// replaces the map; server.go, Serve(): NewMilter() for each connection.
|
||||
// Postfix 3.7.11, src/milter/milter8.c, milter8_event(): a macro packet, empty
|
||||
// Postfix 3.10.13, src/milter/milter8.c, milter8_event(): a macro packet, empty
|
||||
// or not, goes before every event (milter.c, milter_macro_lookup(), never
|
||||
// returns null).
|
||||
type session struct {
|
||||
@@ -69,7 +69,7 @@ type session struct {
|
||||
// clientIP is the client's address. Postfix gives it at Connect, once per
|
||||
// connection, and again with every MAIL FROM as the {client_addr} macro
|
||||
// (milter_mail_macros in build/postfix-config.sh). The second is the one
|
||||
// that can be relied on: see MailFrom. Postfix 3.7.11,
|
||||
// that can be relied on: see MailFrom. Postfix 3.10.13,
|
||||
// src/smtpd/smtpd_milter.c, smtpd_milter_eval(): {client_addr} is
|
||||
// state->rfc_addr (see clientAddr).
|
||||
clientIP string
|
||||
@@ -84,7 +84,7 @@ type session struct {
|
||||
// Connect captures the client IP of a connection's first message. It is not
|
||||
// enough on its own - see MailFrom.
|
||||
//
|
||||
// Postfix 3.7.11, src/smtpd/smtpd.c, smtpd_proto(): milter_conn_event() is
|
||||
// Postfix 3.10.13, src/smtpd/smtpd.c, smtpd_proto(): milter_conn_event() is
|
||||
// given state->addr, the address without "IPv6:". go-milter v0.4.1,
|
||||
// session.go, case CodeConn: net.ParseIP of it - nil for "unknown" and for a
|
||||
// family that sends no address.
|
||||
@@ -115,7 +115,7 @@ func (s *session) Connect(host, family string, port uint16, addr net.IP, m *milt
|
||||
//
|
||||
// go-milter v0.4.1, session.go, HandleMilterCommands(): after a reply whose
|
||||
// Continue() is false (response.go: accept, discard, reject, tempfail) the
|
||||
// backend is replaced by NewMilter(). Postfix 3.7.11, src/milter/milter8.c,
|
||||
// backend is replaced by NewMilter(). Postfix 3.10.13, src/milter/milter8.c,
|
||||
// milter8_conn_event(): CONNECT goes once per milter connection.
|
||||
// {auth_authen}: src/smtpd/smtpd_milter.c, smtpd_milter_eval(), gives
|
||||
// state->sasl_username, null without authentication, and then milter.c,
|
||||
@@ -146,11 +146,11 @@ func (s *session) MailFrom(from string, m *milter.Modifier) (milter.Response, er
|
||||
// RcptTo records each recipient. Postfix calls this once per recipient, which
|
||||
// is what lets the journal keep a separate row per (queue-id, recipient).
|
||||
//
|
||||
// Postfix 3.7.11, src/smtpd/smtpd.c, rcpt_cmd(): milter_rcpt_event() once per
|
||||
// Postfix 3.10.13, src/smtpd/smtpd.c, rcpt_cmd(): milter_rcpt_event() once per
|
||||
// RCPT TO; a recipient Postfix refused goes only to a milter that asked for
|
||||
// SMFIP_RCPT_REJ, which Serve's Protocol does not.
|
||||
// A recipient given twice - in any case - is one row: cleanup keeps the first
|
||||
// and drops the rest (Postfix 3.7.11, src/cleanup/cleanup_out_recipient.c,
|
||||
// and drops the rest (Postfix 3.10.13, src/cleanup/cleanup_out_recipient.c,
|
||||
// cleanup_out_recipient(), been_here() on a table made with BH_FLAG_FOLD in
|
||||
// cleanup_state.c), so only one delivery line will come (assumptions A-31).
|
||||
// Its key also holds the DSN NOTIFY= and ORCPT= of the RCPT TO command, which
|
||||
@@ -181,7 +181,7 @@ func (s *session) Header(name, value string, m *milter.Modifier) (milter.Respons
|
||||
// message through just as "accept" does - and, unlike it, leaves this session
|
||||
// in place for the connection's next message (see MailFrom).
|
||||
//
|
||||
// go-milter v0.4.1, session.go, case CodeEOB: Body(). Postfix 3.7.11,
|
||||
// go-milter v0.4.1, session.go, case CodeEOB: Body(). Postfix 3.10.13,
|
||||
// src/global/mail_params.h: DEF_MILT_EOD_MACROS "i", which
|
||||
// src/cleanup/cleanup_milter.c, cleanup_milter_eval(), answers with the queue
|
||||
// id. src/milter/milter8.c, milter8_event(): SMFIR_CONTINUE returns the
|
||||
@@ -198,7 +198,7 @@ func (s *session) Body(m *milter.Modifier) (milter.Response, error) {
|
||||
// Postfix rejecting the message for its own reasons). No send-log row will be
|
||||
// written, so the level-2 slots this message held must go back.
|
||||
//
|
||||
// Postfix 3.7.11, src/smtpd/smtpd.c: rset_cmd() and the refusals call
|
||||
// Postfix 3.10.13, src/smtpd/smtpd.c: rset_cmd() and the refusals call
|
||||
// mail_reset(), which calls milter_abort() (src/milter/milter8.c,
|
||||
// milter8_abort(): SMFIC_ABORT); so do the end of every transaction and the
|
||||
// end of the session in smtpd_proto().
|
||||
@@ -214,7 +214,7 @@ func (s *session) Abort(m *milter.Modifier) error {
|
||||
// single-character names (e.g. i) arrive bare. go-milter stores whatever name
|
||||
// Postfix sends verbatim, so a lookup must try both forms.
|
||||
//
|
||||
// Postfix 3.7.11, src/milter/milter.c, milter_macro_lookup(): each name is
|
||||
// Postfix 3.10.13, src/milter/milter.c, milter_macro_lookup(): each name is
|
||||
// sent as milter_*_macros spells it. go-milter v0.4.1, session.go, case
|
||||
// CodeMacro: m.macros[name] = value, the name as received.
|
||||
func macro(m *milter.Modifier, name string) string {
|
||||
@@ -228,7 +228,7 @@ func macro(m *milter.Modifier, name string) string {
|
||||
// Postfix did not send one that reads as an address. An IPv6 address may come
|
||||
// in Sendmail's form, with "IPv6:" in front.
|
||||
//
|
||||
// Postfix 3.7.11, src/smtpd/smtpd_peer.c, smtpd_peer_sockaddr_to_hostaddr():
|
||||
// Postfix 3.10.13, src/smtpd/smtpd_peer.c, smtpd_peer_sockaddr_to_hostaddr():
|
||||
// rfc_addr is the dotted quad, "IPv6:" + the address for IPv6, a V4-mapped
|
||||
// address rewritten to IPv4, or "unknown".
|
||||
func clientAddr(m *milter.Modifier) string {
|
||||
@@ -270,7 +270,7 @@ func (s *session) record(queueID string) {
|
||||
}
|
||||
|
||||
// cleanAddress is an address as the milter gets it, without the angle
|
||||
// brackets: Postfix 3.7.11 hands the milter the command's argument as the
|
||||
// brackets: Postfix 3.10.13 hands the milter the command's argument as the
|
||||
// client wrote it, ESMTP parameters as separate strings (src/smtpd/smtpd.c,
|
||||
// mail_cmd()/rcpt_cmd(), milter_argv()), and go-milter v0.4.1 passes the first
|
||||
// with "<>" trimmed (session.go, case CodeMail/CodeRcpt). A quoted local part
|
||||
@@ -280,7 +280,7 @@ func cleanAddress(a string) string {
|
||||
}
|
||||
|
||||
// recipientAsLogged is a recipient in the form Postfix writes it in "to=<..>"
|
||||
// and "orig_to=<..>", so a delivery line finds its row. Postfix 3.7.11 keeps
|
||||
// and "orig_to=<..>", so a delivery line finds its row. Postfix 3.10.13 keeps
|
||||
// the address in internal form - a quoted local part unquoted, a backslash
|
||||
// dropped before the character it escapes, a blank in quotes made a space
|
||||
// (src/smtpd/smtpd.c, extract_addr(), over src/global/tok822_parse.c,
|
||||
@@ -315,7 +315,7 @@ func recipientAsLogged(a string) string {
|
||||
return quoteLocalPart(local) + domain
|
||||
}
|
||||
|
||||
// quoteLocalPart is quote_822_local() of Postfix 3.7.11
|
||||
// quoteLocalPart is quote_822_local() of Postfix 3.10.13
|
||||
// (src/global/quote_822_local.c, with QUOTE_FLAG_8BITCLEAN, the default): a
|
||||
// local part that is a dot-string - atoms of no blank, control character or
|
||||
// one of ()<>@,;:\"[], joined by single dots, none first or last - is left as
|
||||
@@ -366,7 +366,7 @@ func domainOf(addr string) string {
|
||||
// gets a fresh session bound to rec. It returns nil on a clean shutdown.
|
||||
//
|
||||
// go-milter v0.4.1, server.go: Close() closes the listener and Serve() then
|
||||
// returns ErrServerClosed. Postfix 3.7.11, src/milter/milter8.c,
|
||||
// returns ErrServerClosed. Postfix 3.10.13, src/milter/milter8.c,
|
||||
// milter8_message(): SMFIP_NOBODY leaves out only the body chunks - headers,
|
||||
// end-of-headers and end-of-body (milter8_eob()) still go; milter8_event()
|
||||
// takes a reply code (SMFIR_REPLYCODE) whatever the action mask.
|
||||
|
||||
+13
-13
@@ -39,7 +39,7 @@ import (
|
||||
// it up (Bindings). The send-log row of a refusal is written by another
|
||||
// goroutine and is not waited for.
|
||||
//
|
||||
// Postfix 3.7.11, src/smtpd/smtpd_check.c, reject_auth_sender_login_mismatch():
|
||||
// Postfix 3.10.13, src/smtpd/smtpd_check.c, reject_auth_sender_login_mismatch():
|
||||
// the SASL login is compared with an owner by strcasecmp_utf8();
|
||||
// src/milter/milter8.c, milter8_comm_error(): default_action=tempfail answers
|
||||
// "451 4.7.1" for a milter that does not answer. OpenDKIM 2.11.0~beta2,
|
||||
@@ -103,7 +103,7 @@ func (b *Bindings) fresh() error {
|
||||
return b.broken
|
||||
}
|
||||
|
||||
// parseSenderMap reads the lines of a sender_login_maps file as Postfix 3.7.11
|
||||
// parseSenderMap reads the lines of a sender_login_maps file as Postfix 3.10.13
|
||||
// reads a texthash table (src/util/dict_thash.c, dict_thash_open(), over
|
||||
// src/util/readlline.c, readllines()):
|
||||
// - a line that starts with a blank continues the one before; an empty
|
||||
@@ -112,8 +112,8 @@ func (b *Bindings) fresh() error {
|
||||
// escaping the next character; a line with an unbalanced quote, or
|
||||
// without a key or a value, is ignored (with a warning, in Postfix);
|
||||
// - the key is folded to lower case (DICT_FLAG_FOLD_FIX, which
|
||||
// src/smtpd/smtpd_check.c, pre_jail_init(), gives
|
||||
// smtpd_sender_login_maps);
|
||||
// src/smtpd/smtpd_check.c, smtpd_check_init(), called from
|
||||
// src/smtpd/smtpd.c, pre_jail_init(), gives smtpd_sender_login_maps);
|
||||
// - a key given twice makes the whole table unusable: no DICT_FLAG_DUP_*
|
||||
// flag is given, so dict_thash_open() returns a surrogate that fails
|
||||
// every lookup, and smtpd answers 451 (reject_server_error()). The check
|
||||
@@ -194,7 +194,7 @@ func splitTableLine(line string) (key, value string, ok bool) {
|
||||
}
|
||||
|
||||
// Allowed reports whether login may send as addr - the lookup Postfix makes
|
||||
// for the envelope sender. Postfix 3.7.11, src/smtpd/smtpd_check.c,
|
||||
// for the envelope sender. Postfix 3.10.13, src/smtpd/smtpd_check.c,
|
||||
// reject_auth_sender_login_mismatch(), takes the owners of the first key
|
||||
// mail_addr_find() finds (src/global/mail_addr_find.c, mail_addr_find_opt()
|
||||
// with MA_FIND_DEFAULT): the address, then the address without its
|
||||
@@ -242,7 +242,7 @@ const extensionDelimiter = "+"
|
||||
// follows its first delimiter. "user+tag@example.org" is "user@example.org";
|
||||
// an address whose local part begins with the delimiter has no extension.
|
||||
//
|
||||
// Postfix 3.7.11, src/global/strip_addr.c, strip_addr_internal(), and
|
||||
// Postfix 3.10.13, src/global/strip_addr.c, strip_addr_internal(), and
|
||||
// split_addr.c, split_addr_internal(): the local part, up to the last "@", is
|
||||
// cut at its first delimiter, unless that is its first character.
|
||||
func withoutExtension(addr string) string {
|
||||
@@ -322,7 +322,7 @@ func (s *senderSession) Header(name, value string, m *milter.Modifier) (milter.R
|
||||
|
||||
// Headers is the end of the headers, where the message is judged.
|
||||
//
|
||||
// go-milter v0.4.1, session.go, case CodeEOH: Headers(). Postfix 3.7.11,
|
||||
// go-milter v0.4.1, session.go, case CodeEOH: Headers(). Postfix 3.10.13,
|
||||
// src/milter/milter8.c, milter8_event(), SMFIR_REPLYCODE: a "4"/"5" reply
|
||||
// whose enhanced code starts with the same digit is the message's reply;
|
||||
// src/cleanup/cleanup_milter.c, cleanup_milter_apply(): a "5" rejects the
|
||||
@@ -347,7 +347,7 @@ func (s *senderSession) Headers(h textproto.MIMEHeader, m *milter.Modifier) (mil
|
||||
// cleanup has given the message a queue id by the end of its headers
|
||||
// (milter_end_of_header_macros has {i}); Postfix's lines about it - the
|
||||
// refusal among them - are found by it on the message's page.
|
||||
// Postfix 3.7.11, src/global/mail_params.h: DEF_MILT_EOH_MACROS "i",
|
||||
// Postfix 3.10.13, src/global/mail_params.h: DEF_MILT_EOH_MACROS "i",
|
||||
// answered by src/cleanup/cleanup_milter.c, cleanup_milter_eval().
|
||||
s.record(shown, macro(m, "i"))
|
||||
// A reply code of its own, so that the application is told what is wrong
|
||||
@@ -367,7 +367,7 @@ func (s *senderSession) judge() (shown, why string, err error) {
|
||||
if s.login == "" {
|
||||
// Not reachable while the submission ports demand authentication; a
|
||||
// message nobody answers for is not signed either way.
|
||||
// Postfix 3.7.11, src/smtpd/smtpd_check.c, smtpd_check_rcpt(): with
|
||||
// Postfix 3.10.13, src/smtpd/smtpd_check.c, smtpd_check_rcpt(): with
|
||||
// smtpd_delay_reject (default yes) smtpd_client_restrictions
|
||||
// (permit_sasl_authenticated,reject on 465 and 587) refuse every RCPT;
|
||||
// src/smtpd/smtpd.c, data_cmd(): no valid recipients, no message.
|
||||
@@ -416,7 +416,7 @@ func (s *senderSession) judge() (shown, why string, err error) {
|
||||
// line must also be one address in RFC 5322's grammar (net/mail), at the
|
||||
// domain OpenDKIM signs for; a quoted display name may say anything.
|
||||
// And that address, its local part unquoted as Postfix holds the
|
||||
// envelope's (Postfix 3.7.11, src/global/tok822_parse.c), is the one
|
||||
// envelope's (Postfix 3.10.13, src/global/tok822_parse.c), is the one
|
||||
// held against the bindings: "x"@mine.com is x@mine.com, which may be
|
||||
// another application's (review of stage 2c, F1, F2).
|
||||
list, perr := fromParser.ParseList(unfold(raw))
|
||||
@@ -504,7 +504,7 @@ func (s *senderSession) record(shown, queueID string) {
|
||||
// holds against nobody, the domain the login is bound to. Without it the row
|
||||
// would belong to no domain and its administrator would never see it.
|
||||
//
|
||||
// Postfix 3.7.11, src/smtpd/smtpd_check.c, generic_checks():
|
||||
// Postfix 3.10.13, src/smtpd/smtpd_check.c, generic_checks():
|
||||
// reject_*_sender_login_mismatch run only "if (state->sender &&
|
||||
// *state->sender)".
|
||||
func (s *senderSession) domain() string {
|
||||
@@ -518,7 +518,7 @@ func (s *senderSession) domain() string {
|
||||
// characters that mean something in an SMTP reply or a log line, and cuts it:
|
||||
// it is said back to the client, logged and stored.
|
||||
//
|
||||
// Postfix 3.7.11, src/milter/milter8.c, milter8_event(), SMFIR_REPLYCODE:
|
||||
// Postfix 3.10.13, src/milter/milter8.c, milter8_event(), SMFIR_REPLYCODE:
|
||||
// "%%" becomes "%" and a single "%" is dropped; src/cleanup/cleanup_milter.c,
|
||||
// cleanup_milter_apply(), logs "<id>: milter-reject: END-OF-MESSAGE from
|
||||
// <client>: <text>; from=<...> to=<...> ...".
|
||||
@@ -573,7 +573,7 @@ func ServeSender(ctx context.Context, ln net.Listener, bind *Bindings, rec Refus
|
||||
// The headers decide; and each header value with its leading space,
|
||||
// as OpenDKIM asks for it (opendkim.c, mlfi_negotiate(),
|
||||
// SMFIP_HDR_LEADSPC), so that both read the same bytes. Postfix
|
||||
// 3.7.11, src/milter/milter8.c: milter8_negotiate() keeps the event
|
||||
// 3.10.13, src/milter/milter8.c: milter8_negotiate() keeps the event
|
||||
// mask a milter of any version asks for (go-milter v0.4.1 says
|
||||
// version 2), and milter8_header() drops the space only for a milter
|
||||
// without SMFIP_HDR_LEADSPC.
|
||||
|
||||
@@ -230,7 +230,7 @@ func TestBindingsFollowTheFile(t *testing.T) {
|
||||
|
||||
// The owners of the first key Postfix finds decide, not any key that lists
|
||||
// the login: an address bound to one application is not open to another that
|
||||
// holds its whole domain (Postfix 3.7.11, smtpd_check.c,
|
||||
// holds its whole domain (Postfix 3.10.13, smtpd_check.c,
|
||||
// reject_auth_sender_login_mismatch(), over mail_addr_find(); assumptions
|
||||
// B-PS1). Composed by hand in internal/postfix's format.
|
||||
func TestBindingsFirstKeyWins(t *testing.T) {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* test/upstream/mailparse-diff.sh <opendkim source dir>
|
||||
*
|
||||
* builds it in debian:bookworm and runs TestMailParseMatchesOpenDKIM with it.
|
||||
* builds it in debian:trixie and runs TestMailParseMatchesOpenDKIM with it.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Reference in New Issue
Block a user