Accessing the sending user from a canonical(5) table

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
36 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Accessing the sending user from a canonical(5) table

Demi M. Obenour
When a message is submitted using postdrop, Postfix is obviously aware
of which user submitted it, as it includes the UID in the Received:
header.  Is it possible to use this information in a canonical(5)
table, or is a milter required?

Thank you,

Demi


signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Wietse Venema
Demi M. Obenour:

Checking application/pgp-signature: FAILURE
> When a message is submitted using postdrop, Postfix is obviously aware
> of which user submitted it, as it includes the UID in the Received:
> header.  Is it possible to use this information in a canonical(5)
> table, or is a milter required?
>
> Thank you,

You mean the numerical UID that that is shown in a comment:

Received: by mail.example.com (Postfix, from userid 1001)
        id 4C1dKq2WvyzJrNw; Wed, 30 Sep 2020 10:04:31 -0400 (EDT)

Postfix address rewriting is limited to headers that contain only
addresses: From:, To:, Cc:, Reply-To:, and the like. And address
rewriting never looks at the content of comments.

For everything else Postfix can only replace entire headers (through
header checks or milter header delete/insert actions).

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Demi M. Obenour
On 2020-09-30 10:08, Wietse Venema wrote:

> Demi M. Obenour:
>
> Checking application/pgp-signature: FAILURE
>> When a message is submitted using postdrop, Postfix is obviously aware
>> of which user submitted it, as it includes the UID in the Received:
>> header.  Is it possible to use this information in a canonical(5)
>> table, or is a milter required?
>>
>> Thank you,
>
> You mean the numerical UID that that is shown in a comment:
>
> Received: by mail.example.com (Postfix, from userid 1001)
>         id 4C1dKq2WvyzJrNw; Wed, 30 Sep 2020 10:04:31 -0400 (EDT)
>
> Postfix address rewriting is limited to headers that contain only
> addresses: From:, To:, Cc:, Reply-To:, and the like. And address
> rewriting never looks at the content of comments.
>
> For everything else Postfix can only replace entire headers (through
> header checks or milter header delete/insert actions).
>
> Wietse
Darn.  I was hoping that I could get by without a milter, but now it
is clear that a milter will be needed, at least with current Postfix.

How difficult would it be to implement this natively in Postfix?
More specifically:

- If a message arrives via the SMTPS or submission ports, I
  want to replace the address part of the user-supplied From:
  header with the envelope From: header.  This allows me to use
  reject-sender-login-mismatch to prevent users from sending messages
  with forged From: addresses.

- I want to create a table that maps the local user to the addresses
  that they can send mail through Postfix as.  As an example, I might
  want Alice to be able to send mail as anyone, while www-data can
  only send mail as majordomo, and everyone else can only send mail as
  themselves.  Ideally, this should work both for mail submitted with
  postdrop(1), and for mail submitted via SMTP over AF_UNIX sockets.

If this belongs in Postfix, then I would like to request it as a
feature.  However, a milter might be the best option, and that is
also fine.  I am no expert on mail servers.

Sincerely,

Demi


signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Demi M. Obenour
On 2020-09-30 12:18, @lbutlr wrote:
> On 30 Sep 2020, at 10:04, Demi M. Obenour <[hidden email]> wrote:
>> while www-data can only send mail as majordomo,
>
> That will simply brea mailing list. Look at the headers from this message, for example. Your policy on the postfox.org server would screw up this list.

My policy was meant as an example, not as one that should be put
into production.  Different sites will need different policies.
Sorry for the confusion.

Sincerely,

Demi


signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Wietse Venema
In reply to this post by Demi M. Obenour
Demi M. Obenour:

Checking application/pgp-signature: FAILURE
-- Start of PGP signed section.

> On 2020-09-30 10:08, Wietse Venema wrote:
> > Demi M. Obenour:
> >
> > Checking application/pgp-signature: FAILURE
> >> When a message is submitted using postdrop, Postfix is obviously aware
> >> of which user submitted it, as it includes the UID in the Received:
> >> header.  Is it possible to use this information in a canonical(5)
> >> table, or is a milter required?
> >>
> >> Thank you,
> >
> > You mean the numerical UID that that is shown in a comment:
> >
> > Received: by mail.example.com (Postfix, from userid 1001)
> >         id 4C1dKq2WvyzJrNw; Wed, 30 Sep 2020 10:04:31 -0400 (EDT)
> >
> > Postfix address rewriting is limited to headers that contain only
> > addresses: From:, To:, Cc:, Reply-To:, and the like. And address
> > rewriting never looks at the content of comments.
> >
> > For everything else Postfix can only replace entire headers (through
> > header checks or milter header delete/insert actions).
> >
> > Wietse
>
> Darn.  I was hoping that I could get by without a milter, but now it
> is clear that a milter will be needed, at least with current Postfix.
>
> How difficult would it be to implement this natively in Postfix?
> More specifically:
>
> - If a message arrives via the SMTPS or submission ports, I
>   want to replace the address part of the user-supplied From:
>   header with the envelope From: header.  This allows me to use
>   reject-sender-login-mismatch to prevent users from sending messages
>   with forged From: addresses.

There are two parts to this:

1) Locking down the envelope.from.

   With authenticated smtp submission, the envelope.from can be
   constrained by smtpd_sender_login_maps.

   With sendmail/postdrop submission the UNIX login name can be
   overidden with "sendmail -f". There is no code in Postfix to
   lock down "sendmail -f", and there is no 'plugin' interface that
   could do this, either. I don't like the idea of adding complex
   logic to the set-gid postdrop command to lock down "sendmail
   -f". Doing the lockdown in the pickup daemon would be more
   secure but has the problem that the 'reject' happens too late.

2) Locking down the header.from. based on rge envelope.from.

    You need a way to restrict the values of header.from that may
    be used with a given envelope.from. There is no such code
    Postfix, but this can be done with a plugin such as a Milter.

SO it looks pretty hopeless as a feature request to me.

    Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Jaroslaw Rafa
Dnia 30.09.2020 o godz. 16:35:37 Wietse Venema pisze:

>    With authenticated smtp submission, the envelope.from can be
>    constrained by smtpd_sender_login_maps.
>
>    With sendmail/postdrop submission the UNIX login name can be
>    overidden with "sendmail -f". There is no code in Postfix to
>    lock down "sendmail -f", and there is no 'plugin' interface that
>    could do this, either. I don't like the idea of adding complex
>    logic to the set-gid postdrop command to lock down "sendmail
>    -f". Doing the lockdown in the pickup daemon would be more
>    secure but has the problem that the 'reject' happens too late.

Slightly off topic, but the original sendmail when "-f" parameter was used
added the following header to the sent message:

X-Authentication-Warning: <hostname>: <original-username> set sender to
<sender-specified-with-f> using -f

<original-username> was of course the user who was calling
/usr/sbin/sendmail. Is Postfix able to do similar thing?
--
Regards,
   Jaroslaw Rafa
   [hidden email]
--
"In a million years, when kids go to school, they're gonna know: once there
was a Hushpuppy, and she lived with her daddy in the Bathtub."
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Demi M. Obenour
On 2020-09-30 20:32, Jaroslaw Rafa wrote:

> Dnia 30.09.2020 o godz. 16:35:37 Wietse Venema pisze:
>>    With authenticated smtp submission, the envelope.from can be
>>    constrained by smtpd_sender_login_maps.
>>
>>    With sendmail/postdrop submission the UNIX login name can be
>>    overidden with "sendmail -f". There is no code in Postfix to
>>    lock down "sendmail -f", and there is no 'plugin' interface that
>>    could do this, either. I don't like the idea of adding complex
>>    logic to the set-gid postdrop command to lock down "sendmail
>>    -f". Doing the lockdown in the pickup daemon would be more
>>    secure but has the problem that the 'reject' happens too late.
>
> Slightly off topic, but the original sendmail when "-f" parameter was used
> added the following header to the sent message:
>
> X-Authentication-Warning: <hostname>: <original-username> set sender to
> <sender-specified-with-f> using -f
>
> <original-username> was of course the user who was calling
> /usr/sbin/sendmail. Is Postfix able to do similar thing?
This would meet my requirements as well; my understanding is that
blocking a message containing a certain header is trivial.

Demi



signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Wietse Venema
In reply to this post by Jaroslaw Rafa
Jaroslaw Rafa:
> X-Authentication-Warning: <hostname>: <original-username> set sender to
> <sender-specified-with-f> using -f

If you're willing to parse headers, then all the information that
you need is already available. There is no need to add yet another
header with that stuff.

- You already have the numerical UID in the existing Received:
  header. Use a standard UNIX function to convert that to the login
  name.

- The envelope.from is already available.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Demi M. Obenour
In reply to this post by Wietse Venema
On 2020-09-30 16:35, Wietse Venema wrote:

> Demi M. Obenour:
>> - If a message arrives via the SMTPS or submission ports, I
>>   want to replace the address part of the user-supplied From:
>>   header with the envelope From: header.  This allows me to use
>>   reject-sender-login-mismatch to prevent users from sending messages
>>   with forged From: addresses.
>
> There are two parts to this:
>
> 1) Locking down the envelope.from.
>
>    With authenticated smtp submission, the envelope.from can be
>    constrained by smtpd_sender_login_maps.
>
>    With sendmail/postdrop submission the UNIX login name can be
>    overidden with "sendmail -f". There is no code in Postfix to
>    lock down "sendmail -f", and there is no 'plugin' interface that
>    could do this, either. I don't like the idea of adding complex
>    logic to the set-gid postdrop command to lock down "sendmail
>    -f". Doing the lockdown in the pickup daemon would be more
>    secure but has the problem that the 'reject' happens too late.
I looked at the postdrop source code to see what locking down "sendmail
-f" would entail. Checking that the current user can use `-f` seems
to be just looking up the current username in an ACL, which postdrop
already does for authorized_submit_users.  Checking that -f was not
passed looks to just be a string equality check, unless I am missing
something. Of course, converting the same UID to a username three
times is not a good idea performance-wise, but that can be fixed with
some minor refactoring.

Another option is to emit a good error message from sendmail, and then
do the security check in pickup.  If a user calls postdrop directly,
the reject will happen late, but my understanding is that this isn't
supported.

Would you be interested in a patch that implemented either of these
options?

> 2) Locking down the header.from. based on rge envelope.from.
>
>     You need a way to restrict the values of header.from that may
>     be used with a given envelope.from. There is no such code
>     Postfix, but this can be done with a plugin such as a Milter.

It looks like this can be implemented (without changes to Postfix
itself) by using header_checks(5) to ignore the From: header.
cleanup(8) will then insert its own From: header.

Is this a good idea?  It worked for me when I used sendmail(1).
Doing it on mails received via SMTP would not be a good idea, and I
don’t see a non_smtp_header_checks, but there might be an alternative
that I am missing.

Thank you for your time and effort.

Sincerely,

Demi


signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Wietse Venema
Demi M. Obenour:

Checking application/pgp-signature: FAILURE
-- Start of PGP signed section.

> On 2020-09-30 16:35, Wietse Venema wrote:
> > Demi M. Obenour:
> >> - If a message arrives via the SMTPS or submission ports, I
> >>   want to replace the address part of the user-supplied From:
> >>   header with the envelope From: header.  This allows me to use
> >>   reject-sender-login-mismatch to prevent users from sending messages
> >>   with forged From: addresses.
> >
> > There are two parts to this:
> >
> > 1) Locking down the envelope.from.
> >
> >    With authenticated smtp submission, the envelope.from can be
> >    constrained by smtpd_sender_login_maps.
> >
> >    With sendmail/postdrop submission the UNIX login name can be
> >    overidden with "sendmail -f". There is no code in Postfix to
> >    lock down "sendmail -f", and there is no 'plugin' interface that
> >    could do this, either. I don't like the idea of adding complex
> >    logic to the set-gid postdrop command to lock down "sendmail
> >    -f". Doing the lockdown in the pickup daemon would be more
> >    secure but has the problem that the 'reject' happens too late.
>
> I looked at the postdrop source code to see what locking down "sendmail
> -f" would entail. Checking that the current user can use `-f` seems
> to be just looking up the current username in an ACL, which postdrop
> already does for authorized_submit_users.  Checking that -f was not
> passed looks to just be a string equality check, unless I am missing
> something. Of course, converting the same UID to a username three
> times is not a good idea performance-wise, but that can be fixed with
> some minor refactoring.
>
> Another option is to emit a good error message from sendmail, and then
> do the security check in pickup.  If a user calls postdrop directly,
> the reject will happen late, but my understanding is that this isn't
> supported.
>
> Would you be interested in a patch that implemented either of these
> options?

I think that the envelope.from lockdown should be enforced in pickup
or before pickup but not both. If it is both then the code in the
pickup daemon will be a NOOP. WHen code is usually a NOOP no-one will
notice when they break it.

If a sender_login_maps feature can be implemented in postdrop
without giving an untrusted user control over the programn, then
let's try that.

Note that /usr/sbin/sendmail submission path has not been optimized
for performance, so adding another getpwuid() call should not be a
deal breaker.

> > 2) Locking down the header.from. based on rge envelope.from.
> >
> >     You need a way to restrict the values of header.from that may
> >     be used with a given envelope.from. There is no such code
> >     Postfix, but this can be done with a plugin such as a Milter.
>
> It looks like this can be implemented (without changes to Postfix
> itself) by using header_checks(5) to ignore the From: header.
> cleanup(8) will then insert its own From: header.
>
> Is this a good idea?  It worked for me when I used sendmail(1).

This will break email that legitmately overrides the envelope sender
address, such as mailing list managers.

You could specify "pickup -o cleanup_service=local_cleanup" and
define a custome cleanup service with a custom header_checks action.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Demi M. Obenour
On 2020-10-04 19:55, Wietse Venema wrote:

> Demi M. Obenour:
>
> Checking application/pgp-signature: FAILURE
> -- Start of PGP signed section.
>> On 2020-09-30 16:35, Wietse Venema wrote:
>>> Demi M. Obenour:
>>>> - If a message arrives via the SMTPS or submission ports, I
>>>>   want to replace the address part of the user-supplied From:
>>>>   header with the envelope From: header.  This allows me to use
>>>>   reject-sender-login-mismatch to prevent users from sending messages
>>>>   with forged From: addresses.
>>>
>>> There are two parts to this:
>>>
>>> 1) Locking down the envelope.from.
>>>
>>>    With authenticated smtp submission, the envelope.from can be
>>>    constrained by smtpd_sender_login_maps.
>>>
>>>    With sendmail/postdrop submission the UNIX login name can be
>>>    overidden with "sendmail -f". There is no code in Postfix to
>>>    lock down "sendmail -f", and there is no 'plugin' interface that
>>>    could do this, either. I don't like the idea of adding complex
>>>    logic to the set-gid postdrop command to lock down "sendmail
>>>    -f". Doing the lockdown in the pickup daemon would be more
>>>    secure but has the problem that the 'reject' happens too late.
>>
>> I looked at the postdrop source code to see what locking down "sendmail
>> -f" would entail. Checking that the current user can use `-f` seems
>> to be just looking up the current username in an ACL, which postdrop
>> already does for authorized_submit_users.  Checking that -f was not
>> passed looks to just be a string equality check, unless I am missing
>> something. Of course, converting the same UID to a username three
>> times is not a good idea performance-wise, but that can be fixed with
>> some minor refactoring.
>>
>> Another option is to emit a good error message from sendmail, and then
>> do the security check in pickup.  If a user calls postdrop directly,
>> the reject will happen late, but my understanding is that this isn't
>> supported.
>>
>> Would you be interested in a patch that implemented either of these
>> options?
>
> I think that the envelope.from lockdown should be enforced in pickup
> or before pickup but not both. If it is both then the code in the
> pickup daemon will be a NOOP. WHen code is usually a NOOP no-one will
> notice when they break it.
>
> If a sender_login_maps feature can be implemented in postdrop
> without giving an untrusted user control over the programn, then
> let's try that.
I would be willing to try, but I suggest we only support “simple”
maps here.  Postfix supports a wide variety of map types, and I would
rather not expose that much attack surface in postdrop.  Furthermore,
in all of the use cases I can think of, a simple policy is fine.

What about allowing everyone to send mail as themselves, and having
a list of users who can send mail as anyone?  That is what Sendmail
provides.  If a delimiter is specified in the configuration, it would
be honored.

> Note that /usr/sbin/sendmail submission path has not been optimized
> for performance, so adding another getpwuid() call should not be a
> deal breaker.
>
>>> 2) Locking down the header.from. based on rge envelope.from.
>>>
>>>     You need a way to restrict the values of header.from that may
>>>     be used with a given envelope.from. There is no such code
>>>     Postfix, but this can be done with a plugin such as a Milter.
>>
>> It looks like this can be implemented (without changes to Postfix
>> itself) by using header_checks(5) to ignore the From: header.
>> cleanup(8) will then insert its own From: header.
>>
>> Is this a good idea?  It worked for me when I used sendmail(1).
>
> This will break email that legitmately overrides the envelope sender
> address, such as mailing list managers.
Indeed it would, which is why I was hoping to only specify it for
mail submitted via the submission service, rather than mail coming on
port 25.  That said, for mail not generated locally, this might lose
phrases in From: headers.  OpenSMTPD can be configured to replace
the From: header address with the envelope MAIL FROM address, and
hopefully this would not be too hard to add to Postfix.

> You could specify "pickup -o cleanup_service=local_cleanup" and
> define a custome cleanup service with a custom header_checks action.

Good idea, thanks!

> Wietse
Thank you,

Demi


signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Wietse Venema
Demi M. Obenour:

> On 2020-10-04 19:55, Wietse Venema wrote:
> > Demi M. Obenour:
> >
> > Checking application/pgp-signature: FAILURE
> > -- Start of PGP signed section.
> >> On 2020-09-30 16:35, Wietse Venema wrote:
> >>> Demi M. Obenour:
> >>>> - If a message arrives via the SMTPS or submission ports, I
> >>>>   want to replace the address part of the user-supplied From:
> >>>>   header with the envelope From: header.  This allows me to use
> >>>>   reject-sender-login-mismatch to prevent users from sending messages
> >>>>   with forged From: addresses.
> >>>
> >>> There are two parts to this:
> >>>
> >>> 1) Locking down the envelope.from.
> >>>
> >>>    With authenticated smtp submission, the envelope.from can be
> >>>    constrained by smtpd_sender_login_maps.
> >>>
> >>>    With sendmail/postdrop submission the UNIX login name can be
> >>>    overidden with "sendmail -f". There is no code in Postfix to
> >>>    lock down "sendmail -f", and there is no 'plugin' interface that
> >>>    could do this, either. I don't like the idea of adding complex
> >>>    logic to the set-gid postdrop command to lock down "sendmail
> >>>    -f". Doing the lockdown in the pickup daemon would be more
> >>>    secure but has the problem that the 'reject' happens too late.
> >>
> >> I looked at the postdrop source code to see what locking down "sendmail
> >> -f" would entail. Checking that the current user can use `-f` seems
> >> to be just looking up the current username in an ACL, which postdrop
> >> already does for authorized_submit_users.  Checking that -f was not
> >> passed looks to just be a string equality check, unless I am missing
> >> something. Of course, converting the same UID to a username three
> >> times is not a good idea performance-wise, but that can be fixed with
> >> some minor refactoring.
> >>
> >> Another option is to emit a good error message from sendmail, and then
> >> do the security check in pickup.  If a user calls postdrop directly,
> >> the reject will happen late, but my understanding is that this isn't
> >> supported.
> >>
> >> Would you be interested in a patch that implemented either of these
> >> options?
> >
> > I think that the envelope.from lockdown should be enforced in pickup
> > or before pickup but not both. If it is both then the code in the
> > pickup daemon will be a NOOP. WHen code is usually a NOOP no-one will
> > notice when they break it.
> >
> > If a sender_login_maps feature can be implemented in postdrop
> > without giving an untrusted user control over the programn, then
> > let's try that.
>
> I would be willing to try, but I suggest we only support ?simple?
> maps here.  Postfix supports a wide variety of map types, and I would
> rather not expose that much attack surface in postdrop.  Furthermore,
> in all of the use cases I can think of, a simple policy is fine.

I have no idea what that means. Postfix has a separation between
lookup mechanisms (hash, pcre) and table-driven mechanisms
(access maps, smtp_sender_login_maps).

If you are thinking of skipping the Postfix dictionary API and
crafting your own table lookups, then that is definiitely
not going to happen.

> What about allowing everyone to send mail as themselves, and having
> a list of users who can send mail as anyone?  That is what Sendmail
> provides.  If a delimiter is specified in the configuration, it would
> be honored.

By default, a user can send mail as everyone, and that default
behavior cannot be changed. So the question becomes: what is the
behavior? I think it should behave like smtp_sender_login_maps,
because there is no reason to invent new behavior.

This means the search string is the UNIX username, and the lookup
result is a comma-separated list of things (usernames and/or email
addresses) that they may specify as the envelope sender address.

Your 'identity' mapping then looks like this:

/etc/postfix/main.cf:
    local_sender_login_maps =
        pcre:/etc/postfix/local_sender_logins

/etc/postfix/local_sender_logins
   /(.+)/ $1, $[hidden email]

I.e. a user can send mail only if the envelope sender equals their
login name, or [hidden email]. There will need to be a wildcard
pattern that allows all, as would be needed by a content filter
that re-injects mail using the Postfix sendmail command.

We just need to make sure that maps are opened after postdrop has
stripped the environment, set up signal handlers, and done other
steps against misuse. In that light, I'll move the existing
check_user_acl_byuid() call down, after the comment that says 'End
of initializations".

A note about etiquette: my posts clearly say "Reply-To:
[hidden email]". Please fix your MUA and stop sending
your response to my personal email address.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Accessing the sending user from a canonical(5) table

Demi M. Obenour
On 10/5/20 10:51 AM, Wietse Venema wrote:

> Demi M. Obenour:
>> On 2020-10-04 19:55, Wietse Venema wrote:
>>> Demi M. Obenour:
>>>
>>> Checking application/pgp-signature: FAILURE
>>> -- Start of PGP signed section.
>>>> On 2020-09-30 16:35, Wietse Venema wrote:
>>>>> Demi M. Obenour:
>>>>>> - If a message arrives via the SMTPS or submission ports, I
>>>>>>    want to replace the address part of the user-supplied From:
>>>>>>    header with the envelope From: header.  This allows me to use
>>>>>>    reject-sender-login-mismatch to prevent users from sending messages
>>>>>>    with forged From: addresses.
>>>>>
>>>>> There are two parts to this:
>>>>>
>>>>> 1) Locking down the envelope.from.
>>>>>
>>>>>     With authenticated smtp submission, the envelope.from can be
>>>>>     constrained by smtpd_sender_login_maps.
>>>>>
>>>>>     With sendmail/postdrop submission the UNIX login name can be
>>>>>     overidden with "sendmail -f". There is no code in Postfix to
>>>>>     lock down "sendmail -f", and there is no 'plugin' interface that
>>>>>     could do this, either. I don't like the idea of adding complex
>>>>>     logic to the set-gid postdrop command to lock down "sendmail
>>>>>     -f". Doing the lockdown in the pickup daemon would be more
>>>>>     secure but has the problem that the 'reject' happens too late.
>>>>
>>>> I looked at the postdrop source code to see what locking down "sendmail
>>>> -f" would entail. Checking that the current user can use `-f` seems
>>>> to be just looking up the current username in an ACL, which postdrop
>>>> already does for authorized_submit_users.  Checking that -f was not
>>>> passed looks to just be a string equality check, unless I am missing
>>>> something. Of course, converting the same UID to a username three
>>>> times is not a good idea performance-wise, but that can be fixed with
>>>> some minor refactoring.
>>>>
>>>> Another option is to emit a good error message from sendmail, and then
>>>> do the security check in pickup.  If a user calls postdrop directly,
>>>> the reject will happen late, but my understanding is that this isn't
>>>> supported.
>>>>
>>>> Would you be interested in a patch that implemented either of these
>>>> options?
>>>
>>> I think that the envelope.from lockdown should be enforced in pickup
>>> or before pickup but not both. If it is both then the code in the
>>> pickup daemon will be a NOOP. WHen code is usually a NOOP no-one will
>>> notice when they break it.
>>>
>>> If a sender_login_maps feature can be implemented in postdrop
>>> without giving an untrusted user control over the programn, then
>>> let's try that.
>>
>> I would be willing to try, but I suggest we only support ?simple?
>> maps here.  Postfix supports a wide variety of map types, and I would
>> rather not expose that much attack surface in postdrop.  Furthermore,
>> in all of the use cases I can think of, a simple policy is fine.
>
> I have no idea what that means. Postfix has a separation between
> lookup mechanisms (hash, pcre) and table-driven mechanisms
> (access maps, smtp_sender_login_maps).

There was a recent vulnerability in OpenBSD due to libc malfunctioning
in a set-uid-root program under very low resource limits.  I would
prefer to minimize the amount of third-party libraries that are used
by postdrop.  That said, another option would be to error out if the
resource limits are below what we consider a reasonable minimum.

> If you are thinking of skipping the Postfix dictionary API and
> crafting your own table lookups, then that is definiitely
> not going to happen.

Indeed that would be a bad idea.

>> What about allowing everyone to send mail as themselves, and having
>> a list of users who can send mail as anyone?  That is what Sendmail
>> provides.  If a delimiter is specified in the configuration, it would
>> be honored.
>
> By default, a user can send mail as everyone, and that default
> behavior cannot be changed. So the question becomes: what is the
> behavior? I think it should behave like smtp_sender_login_maps,
> because there is no reason to invent new behavior.

Agreed.  This also lets us use common code for both ACLs.

> This means the search string is the UNIX username, and the lookup
> result is a comma-separated list of things (usernames and/or email
> addresses) that they may specify as the envelope sender address.
>
> Your 'identity' mapping then looks like this:
>
> /etc/postfix/main.cf:
>      local_sender_login_maps =
> pcre:/etc/postfix/local_sender_logins
>
> /etc/postfix/local_sender_logins
>     /(.+)/ $1, $[hidden email]
>
> I.e. a user can send mail only if the envelope sender equals their
> login name, or [hidden email]. There will need to be a wildcard
> pattern that allows all, as would be needed by a content filter
> that re-injects mail using the Postfix sendmail command.

That looks good.  I do wish there was a way (other than allow
all) to express that Alice can send mail as [hidden email],
[hidden email], [hidden email], etc.  I might just
not know of such a method, however, and in any case that is not
related to the current project.

Is the code in smtpd_check.c a good place to start?

> We just need to make sure that maps are opened after postdrop has
> stripped the environment, set up signal handlers, and done other
> steps against misuse. In that light, I'll move the existing
> check_user_acl_byuid() call down, after the comment that says 'End
> of initializations".
>
> A note about etiquette: my posts clearly say "Reply-To:
> [hidden email]". Please fix your MUA and stop sending
> your response to my personal email address.

Sorry about that.  I was using "Reply All" instead of "Reply List"
in Thunderbird.

> Wietse

Demi



Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Wietse Venema
Demi M. Obenour:
> There was a recent vulnerability in OpenBSD due to libc malfunctioning
> in a set-uid-root program under very low resource limits.  I would
> prefer to minimize the amount of third-party libraries that are used
> by postdrop.  That said, another option would be to error out if the
> resource limits are below what we consider a reasonable minimum.

Another good reason for not using set-uid root programs...

I don't think it is practical for Postfix to have universal minimal
resource limts. You can add some custom OPENBSD code later.

> > If you are thinking of skipping the Postfix dictionary API and
> > crafting your own table lookups, then that is definiitely
> > not going to happen.
>
> Indeed that would be a bad idea.
>
> >> What about allowing everyone to send mail as themselves, and having
> >> a list of users who can send mail as anyone?  That is what Sendmail
> >> provides.  If a delimiter is specified in the configuration, it would
> >> be honored.
> >
> > By default, a user can send mail as everyone, and that default
> > behavior cannot be changed. So the question becomes: what is the
> > behavior? I think it should behave like smtp_sender_login_maps,
> > because there is no reason to invent new behavior.
>
> Agreed.  This also lets us use common code for both ACLs.
>
> > This means the search string is the UNIX username, and the lookup
> > result is a comma-separated list of things (usernames and/or email
> > addresses) that they may specify as the envelope sender address.
> >
> > Your 'identity' mapping then looks like this:
> >
> > /etc/postfix/main.cf:
> >      local_sender_login_maps =
> > pcre:/etc/postfix/local_sender_logins
> >
> > /etc/postfix/local_sender_logins
> >     /(.+)/ $1, $[hidden email]
> >
> > I.e. a user can send mail only if the envelope sender equals their
> > login name, or [hidden email]. There will need to be a wildcard
> > pattern that allows all, as would be needed by a content filter
> > that re-injects mail using the Postfix sendmail command.
>
> That looks good.  I do wish there was a way (other than allow
> all) to express that Alice can send mail as [hidden email],
> [hidden email], [hidden email], etc.  I might just
> not know of such a method, however, and in any case that is not
> related to the current project.

Surprise: Postfix has a strip_addr() function that can remove adress
extensions before enforcing the ACL.

> Is the code in smtpd_check.c a good place to start?

Yes. It also helps you to become familiar with Postfix's
approach to parsing.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Demi M. Obenour
On 10/5/20 6:15 PM, Wietse Venema wrote:
> Demi M. Obenour:
>> There was a recent vulnerability in OpenBSD due to libc malfunctioning
>> in a set-uid-root program under very low resource limits.  I would
>> prefer to minimize the amount of third-party libraries that are used
>> by postdrop.  That said, another option would be to error out if the
>> resource limits are below what we consider a reasonable minimum.
>
> Another good reason for not using set-uid root programs...

Indeed.

> I don't think it is practical for Postfix to have universal minimal
> resource limts. You can add some custom OPENBSD code later.

That makes sense.  The OpenBSD vulnerability has been fixed, and was
merely used as an example.  No OpenBSD-specific code will be needed,
at least not for this purpose.

> Surprise: Postfix has a strip_addr() function that can remove adress
> extensions before enforcing the ACL.

Good to know! That proved critical.

>> Is the code in smtpd_check.c a good place to start?
>
> Yes. It also helps you to become familiar with Postfix's
> approach to parsing.

Indeed it was helpful. Thanks for the tip!

Patch (made against 3.5.7) attached.  I lightly tested it locally and
it seems to work, but there could very well be bugs.  I am virtually
certain that I violated the Postfix coding style somewhere, sorry.
I can also send the patch inline if you prefer.

For what it is worth, I found the Postfix source code to be very clean
and easy to read.  Writing this patch probably took about four hours
of work, which is significantly less than I expected for a non-trivial
feature.  Thank you for all the work you have put into Postfix!

> Wietse
Thank you,

Demi

submit.diff (4K) Download Attachment
OpenPGP_0xB288B55FFF9C22C1.asc (3K) Download Attachment
OpenPGP_signature (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Wietse Venema
Demi M. Obenour:

Checking application/pgp-signature: FAILURE
-- Start of PGP signed section.

> On 10/5/20 6:15 PM, Wietse Venema wrote:
> > Demi M. Obenour:
> >> There was a recent vulnerability in OpenBSD due to libc malfunctioning
> >> in a set-uid-root program under very low resource limits.  I would
> >> prefer to minimize the amount of third-party libraries that are used
> >> by postdrop.  That said, another option would be to error out if the
> >> resource limits are below what we consider a reasonable minimum.
> >
> > Another good reason for not using set-uid root programs...
>
> Indeed.
>
> > I don't think it is practical for Postfix to have universal minimal
> > resource limts. You can add some custom OPENBSD code later.
>
> That makes sense.  The OpenBSD vulnerability has been fixed, and was
> merely used as an example.  No OpenBSD-specific code will be needed,
> at least not for this purpose.
>
> > Surprise: Postfix has a strip_addr() function that can remove adress
> > extensions before enforcing the ACL.
>
> Good to know! That proved critical.
>
> >> Is the code in smtpd_check.c a good place to start?
> >
> > Yes. It also helps you to become familiar with Postfix's
> > approach to parsing.
>
> Indeed it was helpful. Thanks for the tip!
>
> Patch (made against 3.5.7) attached.  I lightly tested it locally and
> it seems to work, but there could very well be bugs.  I am virtually
> certain that I violated the Postfix coding style somewhere, sorry.
> I can also send the patch inline if you prefer.

I can read it. I'll try to massage the code later this week (instead
of a dozen back-and-forth email messages about awkward details).

mail_addr_find -> maps_find
"+" -> var_rcpt_delim
allow 'not found' users, similar to smtpd_sender_login_maps
put the new code inside its own function, avoiding gotos

        Wietse

> For what it is worth, I found the Postfix source code to be very clean
> and easy to read.  Writing this patch probably took about four hours
> of work, which is significantly less than I expected for a non-trivial
> feature.  Thank you for all the work you have put into Postfix!
>
> > Wietse
> Thank you,
>
> Demi

[ Attachment, skipping... ]

[ Attachment, skipping... ]
-- End of PGP section, PGP failed!
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Demi M. Obenour
On 10/6/20 9:47 AM, Wietse Venema wrote:
> Demi M. Obenour:
>> Patch (made against 3.5.7) attached.  I lightly tested it locally and
>> it seems to work, but there could very well be bugs.  I am virtually
>> certain that I violated the Postfix coding style somewhere, sorry.
>> I can also send the patch inline if you prefer.
>
> I can read it. I'll try to massage the code later this week (instead
> of a dozen back-and-forth email messages about awkward details).

Thank you so much!  Should I look for it in a future unstable release?

> mail_addr_find -> maps_find
> "+" -> var_rcpt_delim

Good catch!  I knew I missed something there.

> allow 'not found' users, similar to smtpd_sender_login_maps

Would it be possible to make this configurable?  The documentation
seems to imply that reject_sender_login_mismatch considers “not
found” to be an error, while reject_known_sender_login_mismatch
does not.  On systems I administer, I would prefer for an unknown
user to not be allowed to submit mail, but I understand if this cannot
be the default.  The patch I submitted blocks “not found” users,
but the default local_sender_login_maps (static:*) matches every user,
so the default behavior is the same as now.

> put the new code inside its own function, avoiding gotos

Indeed that would be an improvement.

> Wietse

Demi


OpenPGP_0xB288B55FFF9C22C1.asc (3K) Download Attachment
OpenPGP_signature (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Wietse Venema
Demi M. Obenour:

Checking application/pgp-signature: FAILURE
-- Start of PGP signed section.

> On 10/6/20 9:47 AM, Wietse Venema wrote:
> > Demi M. Obenour:
> >> Patch (made against 3.5.7) attached.  I lightly tested it locally and
> >> it seems to work, but there could very well be bugs.  I am virtually
> >> certain that I violated the Postfix coding style somewhere, sorry.
> >> I can also send the patch inline if you prefer.
> >
> > I can read it. I'll try to massage the code later this week (instead
> > of a dozen back-and-forth email messages about awkward details).
>
> Thank you so much!  Should I look for it in a future unstable release?
>
> > mail_addr_find -> maps_find
> > "+" -> var_rcpt_delim
>
> Good catch!  I knew I missed something there.
>
> > allow 'not found' users, similar to smtpd_sender_login_maps
>
> Would it be possible to make this configurable?  The documentation
> seems to imply that reject_sender_login_mismatch considers ?not
> found? to be an error, while reject_known_sender_login_mismatch
> does not.  On systems I administer, I would prefer for an unknown
> user to not be allowed to submit mail, but I understand if this cannot
> be the default.  The patch I submitted blocks ?not found? users,
> but the default local_sender_login_maps (static:*) matches every user,
> so the default behavior is the same as now.

For me, 'not found' also includes the case that the user is not found
in the passwd file.

> > put the new code inside its own function, avoiding gotos
>
> Indeed that would be an improvement.

Generally, one function per concept.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Demi M. Obenour
On 10/6/20 12:46 PM, Wietse Venema wrote:

> Demi M. Obenour:
>> On 10/6/20 9:47 AM, Wietse Venema wrote:
>>> allow 'not found' users, similar to smtpd_sender_login_maps
>>
>> Would it be possible to make this configurable?  The documentation
>> seems to imply that reject_sender_login_mismatch considers ?not
>> found? to be an error, while reject_known_sender_login_mismatch
>> does not.  On systems I administer, I would prefer for an unknown
>> user to not be allowed to submit mail, but I understand if this cannot
>> be the default.  The patch I submitted blocks ?not found? users,
>> but the default local_sender_login_maps (static:*) matches every user,
>> so the default behavior is the same as now.
>
> For me, 'not found' also includes the case that the user is not found
> in the passwd file.
By "allow 'not found' users", do you mean that such users will
automatically be granted access, or that they will still be looked up
(perhaps by numeric UID) in local_sender_login_maps?

> Wietse

Demi

P.S.: I noticed that UTF-8 characters are getting mangled somewhere.
Is this intentional?

OpenPGP_0xB288B55FFF9C22C1.asc (3K) Download Attachment
OpenPGP_signature (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Accessing the sending user from a canonical(5) table

Wietse Venema
Demi M. Obenour:

> On 10/6/20 12:46 PM, Wietse Venema wrote:
> > Demi M. Obenour:
> >> On 10/6/20 9:47 AM, Wietse Venema wrote:
> >>> allow 'not found' users, similar to smtpd_sender_login_maps
> >>
> >> Would it be possible to make this configurable?  The documentation
> >> seems to imply that reject_sender_login_mismatch considers ?not
> >> found? to be an error, while reject_known_sender_login_mismatch
> >> does not.  On systems I administer, I would prefer for an unknown
> >> user to not be allowed to submit mail, but I understand if this cannot
> >> be the default.  The patch I submitted blocks ?not found? users,
> >> but the default local_sender_login_maps (static:*) matches every user,
> >> so the default behavior is the same as now.
> >
> > For me, 'not found' also includes the case that the user is not found
> > in the passwd file.
>
> By "allow 'not found' users", do you mean that such users will
> automatically be granted access, or that they will still be looked up
> (perhaps by numeric UID) in local_sender_login_maps?

Postfix sendmail looks up the username only if no sender was specified
with -f, and terminates if the username cannot be found. That behavior
should not change by default.

If the feature is turned on then there should probably be a
default action for users not listed in the table (deny or allow).
Its not going to be pretty when only the numerical UID is avaialble
(a 1:1 mapping username->sender would not make sense).

        Wietse
12