Hi! I have observed a problem with opensmptd which I consider a bug in the implementation. I already tried to submit a report via b...@opensmtpd.org, but apart from a bounce due to some incorrect setup of this alias I did not receive any reply.
Maybe someone on this list can point me into the right direction. :) I am a relatively new user of opensmtpd (portable, v6.8.0-p2) on FreeBSD. After looking through the code I believe that the problem is also present in OpenBSD's version. But let's start from the beginning. The server hosting my mailboxes has the following configuration: > table aliases "..." > srs key "secret" > > action "local" mbox alias <aliases> > action "relay" relay host smtp+tls://mx.example.com srs > > match from any for domain "example.com" action "local" > match from local for any action "relay" Note that I setup SRS for mails that are relayed after aliases are expanded and senders are expanded. My problem is now that opensmptd is not accepting bounces for SRS sender addresses it generates. Let's assume my aliases looks like this: > iwillbounce nonexist...@nonexample.com When I now send mail to `iwillbou...@example.com` the sender address is correctly rewritten to `SRS0=...@example.com`. The original sender address is encoded in this SRS address. If on its following path the mail bounces, opensmtpd is not accepting bounces for this address. The SMTP session then looks like this: > HELO test > [...] > MAIL FROM:<> > [...] > RCPT TO:<SRS0=...@example.com> > 550 Invalid recipient: <SRS0=...@example.com> I was investigating the code for SRS-recipient handling (lka_session.c): > /* handle SRS */ > if (env->sc_srs_key != NULL && > ep.sender.user[0] == '\0' && > (strncasecmp(ep.rcpt.user, "SRS0=", 5) == 0 || > strncasecmp(ep.rcpt.user, "SRS1=", 5) == 0)) { > srs_decoded = srs_decode(mailaddr_to_text(&ep.rcpt)); > if (srs_decoded && > text_to_mailaddr(&ep.rcpt, srs_decoded)) { > /* flag envelope internal and override rcpt */ > ep.flags |= EF_INTERNAL; > xn->u.mailaddr = ep.rcpt; > lks->envelope = ep; > } > else { > log_warn("SRS failed to decode: %s", > mailaddr_to_text(&ep.rcpt)); > } > } > > /* Pass the node through the ruleset */ > rule = ruleset_match(&ep); > if (rule == NULL || rule->reject) { > lks->error = (errno == EAGAIN) ? > LKA_TEMPFAIL : LKA_PERMFAIL; > break; > } If the mail server sends an `MAIL FROM:<>` and `RCPT TO:<SRS0=...@example.com>` the code path is triggered and the SRS address is rewritten. Note that `text_to_mailaddr(&ep.rcpt, srs_decoded)` sets the recipient address of the envelope, but leaves the destination address alone. In my case the recipient address is the original sender address of the initial mail. The destination address is still `SRS0=...@example.com`. For this rewritten internal envelope all rules in the `smtpd.conf` file are evaluated, as per `rule = ruleset_match(&ep)`. I think the problem is now that in ruleset.c there is: > static int > ruleset_match_to(struct rule *r, const struct envelope *evp) > { > int ret; > struct table *table; > enum table_service service = K_DOMAIN; > > if (!r->flag_for) > return 1; > > if (r->flag_for_regex) > service = K_REGEX; > > table = table_find(env, r->table_for); > ret = table_match(table, service, evp->dest.domain); > > return MATCH_RESULT(ret, r->flag_for); > } Note that `table_match(table, service, evp->dest.domain)` looks at the destination address (still @example.com!) and not the recipient address (srs decoded, original sender). In the end the first rule is matched (local delivery). If no local user with the same name exists, the mail is rejected (otherwise it is delivered to the wrong user). The intended goal is obviously to relay the bounce notification to the original sender (second rule). I patched my local version of opensmtpd to also replace the destination address (`text_to_mailaddr(&ep.dest, srs_decoded)`) and now bounces to SRS address are relayed correctly to the original sender. Reason for this is that opensmtpd recognizes that the SRS decoded address is not local anymore, the first rule does not match and the relay option is chosen. To be honest, I am still a bit confused about the difference of recipient and destination address. I don't know when opensmtpd uses one or the other. Is it safe to rewrite both addresses in the SRS decoding case? It would be great if someone could look into this issue. Of course I am also interested if the conclusions of my debugging session are correct. :) Best regards, Stefan Haller