Re: [exim] safe handling of $tls_sni

2016-10-19 Thread Mike Brudenell
Hah! That would be a good reason! :-)
And re-reading the *Specification* I now spot it saying "The string must
consist entirely of decimal digits." (Sigh!)

I was led astray because when I searched with Google I didn't find mention
of Base62 only converting numbers, and indeed I found a web page to convert
arbitrary text to Base 62.

Hmm… I wonder if it's only Exim's implementation of the base62 expansion
operator that imposes the numeric-only requirement, rather than the method
as a whole?

Cheers and apologies,
Mike B-)

On 19 October 2016 at 13:27, Felipe Gasper  wrote:

> base62 only encodes numerals, though.
>
> -FG
>
> > On Oct 19, 2016, at 4:16 AM, Mike Brudenell 
> wrote:
> >
> > Or perhaps just use Exim's existing base62 and base62d expansion
> operators?
> > :-)
> >
> > http://www.exim.org/exim-html-current/doc/html/spec_html/ch-
> string_expansions.html#SECTexpop
> >
> >
> > These:
> >
> >   - use the character set [A-Za-z0-9] on case-sensitive systems;
> >   - use base36 encoding using [A-Z0-9] instead on systems with
> >   case-insensitive file names;
> >   - are used by Exim to generate its message identifiers, and hence
> >   (presumably safe!) file names to store message data in the file system.
> >
> > Cheers,
> > Mike B-)
> >
> >
> > On 18 October 2016 at 22:21, Phil Pennock 
> wrote:
> >
> >> On 2016-10-18 at 08:28 +0200, Arkadiusz Miśkiewicz wrote:
> >>> On Monday 17 of October 2016, Phil Pennock wrote:
>  Or base64-encode it.
> >>>
> >>> "/" is part of base64 alphabet, so would have to replace that with
> other
> >>> character, too.
> >>
> >> You're quite right.  I was thinking of the `base64url` encoding from
> >> RFC4648; it's used so often that I forgot.
> >
> >
> > --
> > Systems Administrator & Change Manager
> > IT Services, University of York, Heslington, York YO10 5DD, UK
> > Tel: +44-(0)1904-323811
> >
> > Web: www.york.ac.uk/it-services
> > Disclaimer: www.york.ac.uk/docs/disclaimer/email.htm
> > --
> > ## List details at https://lists.exim.org/mailman/listinfo/exim-users
> > ## Exim details at http://www.exim.org/
> > ## Please use the Wiki with this list - http://wiki.exim.org/
>
>
> --
> ## List details at https://lists.exim.org/mailman/listinfo/exim-users
> ## Exim details at http://www.exim.org/
> ## Please use the Wiki with this list - http://wiki.exim.org/
>



-- 
Systems Administrator & Change Manager
IT Services, University of York, Heslington, York YO10 5DD, UK
Tel: +44-(0)1904-323811

Web: www.york.ac.uk/it-services
Disclaimer: www.york.ac.uk/docs/disclaimer/email.htm
-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Re: [exim] safe handling of $tls_sni

2016-10-19 Thread Felipe Gasper
base62 only encodes numerals, though.

-FG

> On Oct 19, 2016, at 4:16 AM, Mike Brudenell  wrote:
> 
> Or perhaps just use Exim's existing base62 and base62d expansion operators?
> :-)
> 
> http://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html#SECTexpop
> 
> 
> These:
> 
>   - use the character set [A-Za-z0-9] on case-sensitive systems;
>   - use base36 encoding using [A-Z0-9] instead on systems with
>   case-insensitive file names;
>   - are used by Exim to generate its message identifiers, and hence
>   (presumably safe!) file names to store message data in the file system.
> 
> Cheers,
> Mike B-)
> 
> 
> On 18 October 2016 at 22:21, Phil Pennock  wrote:
> 
>> On 2016-10-18 at 08:28 +0200, Arkadiusz Miśkiewicz wrote:
>>> On Monday 17 of October 2016, Phil Pennock wrote:
 Or base64-encode it.
>>> 
>>> "/" is part of base64 alphabet, so would have to replace that with other
>>> character, too.
>> 
>> You're quite right.  I was thinking of the `base64url` encoding from
>> RFC4648; it's used so often that I forgot.
> 
> 
> -- 
> Systems Administrator & Change Manager
> IT Services, University of York, Heslington, York YO10 5DD, UK
> Tel: +44-(0)1904-323811
> 
> Web: www.york.ac.uk/it-services
> Disclaimer: www.york.ac.uk/docs/disclaimer/email.htm
> -- 
> ## List details at https://lists.exim.org/mailman/listinfo/exim-users
> ## Exim details at http://www.exim.org/
> ## Please use the Wiki with this list - http://wiki.exim.org/


-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Re: [exim] safe handling of $tls_sni

2016-10-18 Thread Phil Pennock
On 2016-10-18 at 08:28 +0200, Arkadiusz Miśkiewicz wrote:
> On Monday 17 of October 2016, Phil Pennock wrote:
> > Or base64-encode it.
> 
> "/" is part of base64 alphabet, so would have to replace that with other 
> character, too.

You're quite right.  I was thinking of the `base64url` encoding from
RFC4648; it's used so often that I forgot.

Hrm, perhaps Exim should support that too.

> I wonder how big performance impact will be there on each connection when 
> using sha1. sha will be calculated even twice for single connection.

Your mail was delivered from the exim.org mail-handling host to my
mail-handling host using `TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256`.
Gmail's mail-servers record that when you uploaded it to them, your
system negotiated `version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256
bits=128/128`.

SHA1 is faster than the SHA2 family of hashes; if you're calculating
SHA2 hashes twice (for HMAC) for every block received over TLS, doing
SHA1 twice at the start should not be a concern.

-Phil

-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Re: [exim] safe handling of $tls_sni

2016-10-18 Thread Arkadiusz Miśkiewicz
On Monday 17 of October 2016, Phil Pennock wrote:
> On 2016-10-12 at 14:50 +0200, Arkadiusz Miśkiewicz wrote:
> > Docs say that $tls_sni has raw data from client:
> > 
> > "Great care should be taken to deal with matters of case, various
> > injection attacks in the string (../ or SQL), and ensuring that a valid
> > filename can always be referenced; it is important to remember that
> > $tls_sni is arbitrary unverified data provided prior to authentication."
> 
> Someone read the text I wrote!  Woohoo!
> 
> (It only took a few years ...)
> 
> > What is safest approach to handle $tls_sni when trying
> > to expand it to file on filesystem?
> 
> Use a cryptographic hash for the filename.  

Sounds smart.

> Or base64-encode it.

"/" is part of base64 alphabet, so would have to replace that with other 
character, too.

[...]

> exists{/etc/mail/ssl/${sha1:${lc:tls_sni}}.pem}{/etc/mail/ssl/${sha1:${lc:
> tls_sni}}.pem}{/etc/mail/default-cert.pem}

I wonder how big performance impact will be there on each connection when 
using sha1. sha will be calculated even twice for single connection.

I'm guessing no big impact as various hashing is already used in other places 
like SMTP AUTH etc.
 
> -Phil

Thanks,
-- 
Arkadiusz Miśkiewicz, arekm / ( maven.pl | pld-linux.org )

-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Re: [exim] safe handling of $tls_sni

2016-10-17 Thread Felipe Gasper
FWIW, I’d much rather that invalid characters in $tls_sni prompt an error.

There seems no reason to serve up meaningful content to someone who’s sending a 
malformed SNI header.

-Felipe Gasper
Mississauga, ON


> On Oct 17, 2016, at 11:42 PM, Jasen Betts  wrote:
> 
> On 2016-10-17, Mike Tubby  wrote:
>> 
>> Couldn't we have - per perhaps shouldn't we have - a "safe domain name" 
>> function in Exim that could be used for this and elsewhere where an 
>> untrusted domain name enters - it would:
>> 
>> * remove white space (tab, space, etc)
>> * remove non-printing chars
>> * remove 'quoting' and 'escaping'
>> * make it lower case
>> * only allow valid characters for a FQDN
> 
> why remove? why not just reject if it contains any badness?
> 
>> call it something like "safe_fqdn" and then you could do:
>> 
>> ${if 
>> exists{/etc/mail/ssl/${safe_fqdn:tls_sni}.pem}{/etc/mail/ssl/${safe_fqdn:tls_sni}.pem}{/etc/mail/default-cert.pem}
>> 
>> aren't computers are supposed to be doing the work for us...?
>> 
> This:
> 
> ${domain:a@$tls_sni}
> 
> will give the domain part if the $tls_sni is syntactically correct for a
> domain name else it will give the empty string.
> 
> Is that not good enough?
> 
> 
>   ${if exists{/etc/mail/ssl/${domain:a@$tls_sni}.pem}\
>{/etc/mail/ssl/${domain:a@$tls_sni}.pem}\
>{/etc/mail/default-cert.pem}\
>}
> 
> 
> it's going to try to use a file called /etc/mail/ssl/.pem if the sni
> is empty or contains garbage, probably not a problem. 
> 
> -- 
> This email has not been checked by half-arsed antivirus software 
> 
> -- 
> ## List details at https://lists.exim.org/mailman/listinfo/exim-users
> ## Exim details at http://www.exim.org/
> ## Please use the Wiki with this list - http://wiki.exim.org/


-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Re: [exim] safe handling of $tls_sni

2016-10-17 Thread Jasen Betts
On 2016-10-17, Mike Tubby  wrote:
>
> Couldn't we have - per perhaps shouldn't we have - a "safe domain name" 
> function in Exim that could be used for this and elsewhere where an 
> untrusted domain name enters - it would:
>
>  * remove white space (tab, space, etc)
>  * remove non-printing chars
>  * remove 'quoting' and 'escaping'
>  * make it lower case
>  * only allow valid characters for a FQDN

why remove? why not just reject if it contains any badness?

> call it something like "safe_fqdn" and then you could do:
>
>  ${if 
> exists{/etc/mail/ssl/${safe_fqdn:tls_sni}.pem}{/etc/mail/ssl/${safe_fqdn:tls_sni}.pem}{/etc/mail/default-cert.pem}
>
> aren't computers are supposed to be doing the work for us...?
>
This:

 ${domain:a@$tls_sni}
 
will give the domain part if the $tls_sni is syntactically correct for a
domain name else it will give the empty string.

Is that not good enough?


   ${if exists{/etc/mail/ssl/${domain:a@$tls_sni}.pem}\
{/etc/mail/ssl/${domain:a@$tls_sni}.pem}\
{/etc/mail/default-cert.pem}\
}


it's going to try to use a file called /etc/mail/ssl/.pem if the sni
is empty or contains garbage, probably not a problem. 

-- 
This email has not been checked by half-arsed antivirus software 

-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Re: [exim] safe handling of $tls_sni

2016-10-17 Thread Phil Pennock
On 2016-10-17 at 22:53 +0100, Mike Tubby wrote:
> Couldn't we have - per perhaps shouldn't we have - a "safe domain name"
> function in Exim that could be used for this and elsewhere where an
> untrusted domain name enters - it would:

Exim is a volunteer open source project.  Patches are welcome, as are
new contributors.  If this is the itch for you to scratch to get
involved, then take a look at src/expand.c

> * remove white space (tab, space, etc)
> * remove non-printing chars
> * remove 'quoting' and 'escaping'

Any security function should _whitelist_, not blacklist.

This is the advantage of hashing or base64-encoding: it moves the
character-set of files in the local filesystem to be guaranteed safe,
easily scriptable without having to worry about extra `$` signs or
backticks or other malarkey from remote data.

This is a pattern used in various secure designs.  I was asked for the
safest approach, so I gave the safest.  If instead you want an approach
which is "probably pretty safe, but still looks a bit like the original
name for most cases" then you can use escaping mechanisms and hope that
no corner cases were missed (empty string but present `$tls_sni` and so
forth).

> aren't computers are supposed to be doing the work for us...?

They do.  I provided an answer which matches the approach for handling
user-data which I've seen at some big sites.  Don't ever trust user-data
as safe for a filename on local disk.

Really, this goes in as a step in your configuration build process when
building the set of files to be deployed to the mail-server.  A
filename transform step is simple (as is having some symlinks for
user-friendliness if you have humans regularly logging in to look around).

-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Re: [exim] safe handling of $tls_sni

2016-10-17 Thread Brent Jones
I'd like that - and if we were at it, I'd want a safe $sender_host_address
so we can use RHS expansion without modifying the Makefile :)


On Mon, Oct 17, 2016 at 2:53 PM, Mike Tubby  wrote:

>
> Couldn't we have - per perhaps shouldn't we have - a "safe domain name"
> function in Exim that could be used for this and elsewhere where an
> untrusted domain name enters - it would:
>
> * remove white space (tab, space, etc)
> * remove non-printing chars
> * remove 'quoting' and 'escaping'
> * make it lower case
> * only allow valid characters for a FQDN
>
> call it something like "safe_fqdn" and then you could do:
>
> ${if exists{/etc/mail/ssl/${safe_fqdn:tls_sni}.pem}{/etc/mail/ssl
> /${safe_fqdn:tls_sni}.pem}{/etc/mail/default-cert.pem}
>
> aren't computers are supposed to be doing the work for us...?
>
>
> Mike
>
>
>
>
> On 10/17/2016 10:09 PM, Phil Pennock wrote:
>
>> On 2016-10-12 at 14:50 +0200, Arkadiusz Miśkiewicz wrote:
>>
>>> Docs say that $tls_sni has raw data from client:
>>>
>>> "Great care should be taken to deal with matters of case, various
>>> injection
>>> attacks in the string (../ or SQL), and ensuring that a valid filename
>>> can
>>> always be referenced; it is important to remember that $tls_sni is
>>> arbitrary
>>> unverified data provided prior to authentication."
>>>
>> Someone read the text I wrote!  Woohoo!
>>
>> (It only took a few years ...)
>>
>> What is safest approach to handle $tls_sni when trying
>>> to expand it to file on filesystem?
>>>
>> Use a cryptographic hash for the filename.  Or base64-encode it.
>> Use symlinks for human-convenience names and any aliases.
>>
>> Your trade-offs are:
>> * a cryptographically-skilled attacker might find a collision and ...
>>get you to issue, to _them_ (and only them) a certificate for a known
>>system, while on their side they should be looking to validate against
>>something else.  Woo, they just attacked themselves: on your side, you
>>don't need to care.
>> * A very long SNI with base64 might look up a very long filename on
>>disk.  Shouldn't be an issue, unless you're mass-hosting on an OS
>>which only maintains dir hashing for filenames up to a certain length
>>and need to accept customer-controlled SNI names.
>>Of course, the systems like that, if memory serves, broke at 32
>>characters long and a SHA1 hex digest is 40 characters long, so you'd
>>also want to use ${substr...} to take the first N characters.
>> * If you have a lot of similar names, sha1 will give you more
>>readily-distinct values which you can tell apart at a glance.
>>
>>> ${sha1:${lc:mx.spodhuis.org}}
>>F0DF49E8B2ACF84D5D290E89F9B673EF44B60E74
>>> ${str2b64:${lc:mx.spodhuis.org}}
>>bXguc3BvZGh1aXMub3Jn
>>
>> So, eg, `/etc/mail/ssl/bXguc3BvZGh1aXMub3Jn.pem` should exist for this
>> approach, to issue a cert for the name `mx.spodhuis.org`.
>>
>> Rule like:
>>> ${if exists{/etc/mail/ssl/${tls_sni}.pem}{/etc/mail/ssl/${tls_sni
>>> }.pem}{/etc/mail/default-cert.pem}
>>>
>> ${if exists{/etc/mail/ssl/${str2b64:${lc:tls_sni}}.pem}{/etc/
>> mail/ssl/${str2b64:${lc:tls_sni}}.pem}{/etc/mail/default-cert.pem}
>>OR
>> ${if exists{/etc/mail/ssl/${sha1:${lc:tls_sni}}.pem}{/etc/mail/ss
>> l/${sha1:${lc:tls_sni}}.pem}{/etc/mail/default-cert.pem}
>>
>> -Phil
>>
>>
>
> --
> ## List details at https://lists.exim.org/mailman/listinfo/exim-users
> ## Exim details at http://www.exim.org/
> ## Please use the Wiki with this list - http://wiki.exim.org/
>



-- 
Brent Jones
br...@brentrjones.com
-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Re: [exim] safe handling of $tls_sni

2016-10-17 Thread Mike Tubby


Couldn't we have - per perhaps shouldn't we have - a "safe domain name" 
function in Exim that could be used for this and elsewhere where an 
untrusted domain name enters - it would:


* remove white space (tab, space, etc)
* remove non-printing chars
* remove 'quoting' and 'escaping'
* make it lower case
* only allow valid characters for a FQDN

call it something like "safe_fqdn" and then you could do:

${if 
exists{/etc/mail/ssl/${safe_fqdn:tls_sni}.pem}{/etc/mail/ssl/${safe_fqdn:tls_sni}.pem}{/etc/mail/default-cert.pem}


aren't computers are supposed to be doing the work for us...?


Mike



On 10/17/2016 10:09 PM, Phil Pennock wrote:

On 2016-10-12 at 14:50 +0200, Arkadiusz Miśkiewicz wrote:

Docs say that $tls_sni has raw data from client:

"Great care should be taken to deal with matters of case, various injection
attacks in the string (../ or SQL), and ensuring that a valid filename can
always be referenced; it is important to remember that $tls_sni is arbitrary
unverified data provided prior to authentication."

Someone read the text I wrote!  Woohoo!

(It only took a few years ...)


What is safest approach to handle $tls_sni when trying
to expand it to file on filesystem?

Use a cryptographic hash for the filename.  Or base64-encode it.
Use symlinks for human-convenience names and any aliases.

Your trade-offs are:
* a cryptographically-skilled attacker might find a collision and ...
   get you to issue, to _them_ (and only them) a certificate for a known
   system, while on their side they should be looking to validate against
   something else.  Woo, they just attacked themselves: on your side, you
   don't need to care.
* A very long SNI with base64 might look up a very long filename on
   disk.  Shouldn't be an issue, unless you're mass-hosting on an OS
   which only maintains dir hashing for filenames up to a certain length
   and need to accept customer-controlled SNI names.
   Of course, the systems like that, if memory serves, broke at 32
   characters long and a SHA1 hex digest is 40 characters long, so you'd
   also want to use ${substr...} to take the first N characters.
* If you have a lot of similar names, sha1 will give you more
   readily-distinct values which you can tell apart at a glance.

   > ${sha1:${lc:mx.spodhuis.org}}
   F0DF49E8B2ACF84D5D290E89F9B673EF44B60E74
   > ${str2b64:${lc:mx.spodhuis.org}}
   bXguc3BvZGh1aXMub3Jn

So, eg, `/etc/mail/ssl/bXguc3BvZGh1aXMub3Jn.pem` should exist for this
approach, to issue a cert for the name `mx.spodhuis.org`.


Rule like:
${if 
exists{/etc/mail/ssl/${tls_sni}.pem}{/etc/mail/ssl/${tls_sni}.pem}{/etc/mail/default-cert.pem}

${if 
exists{/etc/mail/ssl/${str2b64:${lc:tls_sni}}.pem}{/etc/mail/ssl/${str2b64:${lc:tls_sni}}.pem}{/etc/mail/default-cert.pem}
   OR
${if 
exists{/etc/mail/ssl/${sha1:${lc:tls_sni}}.pem}{/etc/mail/ssl/${sha1:${lc:tls_sni}}.pem}{/etc/mail/default-cert.pem}

-Phil




--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Re: [exim] safe handling of $tls_sni

2016-10-17 Thread Phil Pennock
On 2016-10-12 at 14:50 +0200, Arkadiusz Miśkiewicz wrote:
> Docs say that $tls_sni has raw data from client:
> 
> "Great care should be taken to deal with matters of case, various injection
> attacks in the string (../ or SQL), and ensuring that a valid filename can
> always be referenced; it is important to remember that $tls_sni is arbitrary
> unverified data provided prior to authentication."

Someone read the text I wrote!  Woohoo!

(It only took a few years ...)

> What is safest approach to handle $tls_sni when trying
> to expand it to file on filesystem?

Use a cryptographic hash for the filename.  Or base64-encode it.
Use symlinks for human-convenience names and any aliases.

Your trade-offs are:
* a cryptographically-skilled attacker might find a collision and ...
  get you to issue, to _them_ (and only them) a certificate for a known
  system, while on their side they should be looking to validate against
  something else.  Woo, they just attacked themselves: on your side, you
  don't need to care.
* A very long SNI with base64 might look up a very long filename on
  disk.  Shouldn't be an issue, unless you're mass-hosting on an OS
  which only maintains dir hashing for filenames up to a certain length
  and need to accept customer-controlled SNI names.
  Of course, the systems like that, if memory serves, broke at 32
  characters long and a SHA1 hex digest is 40 characters long, so you'd
  also want to use ${substr...} to take the first N characters.
* If you have a lot of similar names, sha1 will give you more
  readily-distinct values which you can tell apart at a glance.

  > ${sha1:${lc:mx.spodhuis.org}}
  F0DF49E8B2ACF84D5D290E89F9B673EF44B60E74
  > ${str2b64:${lc:mx.spodhuis.org}}
  bXguc3BvZGh1aXMub3Jn

So, eg, `/etc/mail/ssl/bXguc3BvZGh1aXMub3Jn.pem` should exist for this
approach, to issue a cert for the name `mx.spodhuis.org`.

> Rule like:
> ${if 
> exists{/etc/mail/ssl/${tls_sni}.pem}{/etc/mail/ssl/${tls_sni}.pem}{/etc/mail/default-cert.pem}

${if 
exists{/etc/mail/ssl/${str2b64:${lc:tls_sni}}.pem}{/etc/mail/ssl/${str2b64:${lc:tls_sni}}.pem}{/etc/mail/default-cert.pem}
  OR
${if 
exists{/etc/mail/ssl/${sha1:${lc:tls_sni}}.pem}{/etc/mail/ssl/${sha1:${lc:tls_sni}}.pem}{/etc/mail/default-cert.pem}

-Phil

-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

[exim] safe handling of $tls_sni

2016-10-12 Thread Arkadiusz Miśkiewicz

Hi.

Docs say that $tls_sni has raw data from client:

"Great care should be taken to deal with matters of case, various injection
attacks in the string (../ or SQL), and ensuring that a valid filename can
always be referenced; it is important to remember that $tls_sni is arbitrary
unverified data provided prior to authentication."


What is safest approach to handle $tls_sni when trying
to expand it to file on filesystem?

Rule like:
${if 
exists{/etc/mail/ssl/${tls_sni}.pem}{/etc/mail/ssl/${tls_sni}.pem}{/etc/mail/default-cert.pem}
 

-- 
Arkadiusz Miśkiewicz, arekm / ( maven.pl | pld-linux.org )

-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/