Re: [exim] Problems with colons in addresses

Top Page
Delete this message
Reply to this message
Author: W B Hacker
Date:  
To: exim users
Subject: Re: [exim] Problems with colons in addresses
Jim Cheetham wrote:
> On 08/06/11 02:14, W B Hacker wrote:
>> jh@??? wrote:
>>> Jim Cheetham, 2011-06-07 11:55:
>>>> A user managed to submit an email to a local_part beginning with a colon
>>>> (:info@domain)
>>>>
>>>> Normally this would be rejected early on, but their mail client managed
>>>> to sneak the offending character in by wrapping it in double quotes ...
>>>> (":info"@domain)
>>>
>>> That's not sneaking in, it's just quoting. His MUA probably dit it for
>>> him.
>
> Very well -- then why does Exim reject the first form, but leave it up
> to my configuration to reject the second form?
>
>>>> This then caused a paniclog entry, because I was using $local_part in a
>>>
>>> Big mistake. You should always quote variables you use for SQL lookups,
>
> OK, that's fair. However, I am using sqlite, and according to the
> documentation "The only character affected by the quote_sqlite operator
> is a single quote, which it doubles".


Yes - but that is seriously important in SQL-land.

It prevents an intentionally munged input being seen as a command as
well as (or even instead of) a query.

Artificial case, as I've no time to research a real one, but what
happens if $local part were to include DROP, GRANT or INSERT

>
>> One can further protect by doing a router-walk recipient verification
>> BEFORE the SQL is actioned at all. Useful if, for example, all users are
>> in the DB *except* certain otherwise-valid system aliases.
>> ...
>>   # RCPT_4: IF not a valid recipient, THEN deny
>>   #
>>    deny
>>      !verify     = recipient
>>      message     = Mis-typed or Invalid address or Format.
>>      log_message = $acl_m2 $local_part@$domain invalid address

>>
>>    # RCPT_5: IF address in our domain AND active AND valid user
>>    # THEN flag for later acceptance
>>    #
>>    warn
>>      set acl_m10  = ${lookup pgsql{SELECT pg_active from mailprof \
>>                    WHERE pg_active AND \
>>            pg_domain='${quote_pgsql:$domain}' \
>>                    AND pg_local_part='${quote_pgsql:$local_part}'}}
>>      log_message = R5 $local_part@$domain is a valid recipient
>> ...
>> acl__m10 boolean 't' or 'f' is then used in subsequent tests which
>> generally lead to acceptance within acl_smtp_rcpt.

>
> Generally I have all users in the db for this system, so that might be
> useful.


Likewise - even 'postmaster@' .. but can always be temporary aliases et
al, changes to where cron'ed reports are sent, temporary redirecting, to
name a few.

> Testing by SQL lookup for a valid recipient during _rcpt would
> help me, I'm not currently doing that.


CAN save time and cycles. Depends on what else is where, so no
guarantees. In our case, we run mirrored servers for failover coverage.
The DB already knows about those it might have taken up to cover its
offline twin. DNS keeps them from even arriving until the IP is taken
over, but once that happens, it already knows who is 'family' and where
they are to eat and sleep.

> But I'm sorry to say that I don't
> understand how your RCPT_4 is protecting me from doing a SQL lookup in
> RCPT_5 ... ? Perhaps I don't understand the implications of verify
> correctly.



!verify = recipient

means trigger the verb on *failure* (...to verify)

As it is a 'deny' class verb , it bails out 'at once' - before the SQL
in RCPT_5 is even reached.

I plead guilty to preferring negated conditionals as they make
multiple-conditional flow easier for an old Forth coder to grok.

WHEN there are multiple conditionals, the most likely to cut short the
work ELSE the cheapest to do are placed first so as shortcut more
expensive/slower parsing.

>
>>>> I tried playing with a test in acl_test_rcpt for this on a scratch
>>>> system, but didn't manage to get it right, even though I remembered to
>>>> double the colons :-)
>>>>
>>>>> deny    message     = Restricted characters in address
>>>>>           local_parts = ^[./|] : ^.*[::@%!] : ^.*/\\.\\./

>>>
>>> This works here. Run a test session with "exim -d+expand -bh
>>> some.ip.add.ress" to see what goes wrong.
>
> I'll be able to test the system again in a few hours. I look forward to
> working out some way to make the system better as a result of this :-)
>
> -jim
>


'one hand washes the other'

Bill

--
韓家標