# sending a variable through a regex in exim



## dieselnutjob (Jul 4, 2021)

Hi folks.
I am a total beginner at regex.
I want to specify a variable in my exim config, and I want the variable to contain a domain if $header_from contains that domain from a choice of good domains.
So I could do 

```
myvariable = $header_from
```
so if the from address in an email is name@domain1.com then myvariable would contain name@domain1.com
I have been messing with some regex web sites and found that 

```
/(domain1)|(domain2)
```
would return "domain1" if the input contains "domain1" and "domain2" if the input contains "domain2".
How do I write the complete regex

```
myvariable = $header_from   filtered by  (domain1)|(domain2)
```
?
I would like the "myvariable" to contain either "domain1", "domain2", or nothing.

Basically I don't know how to feed one thing through another in an expression.

I know that there are corner cases like if someone has an email address domain1something@domain2 but I can live with that.

I am only using for my own email addresses so I can just make sure that doesn't happen.

thanks, DNJ


----------



## ccammack (Jul 5, 2021)

I don't know anything about exim, but this page indicates that it comes with a tool for testing regexes.



> A program called `pcretest' forms part of the PCRE distribution and is built with PCRE during the process of building Exim...The binary can be found in the `pcre' sub-directory of the Exim build directory.



I would run some tests with that to make sure your regex is absolutely correct before adding it to the configuration.

I think you should only use one set of () around both options because () captures whatever matches inside. I'm just guessing, but maybe try something like this to start:


```
re> /(amazon.com|google.com)/g
data> email@google.com
0: google.com

re> /(.+@amazon.com|.+@google.com)/g
data> email@google.com
0: email@google.com
```


----------



## dieselnutjob (Jul 5, 2021)

A specific example:
This works in my exim config

```
dkim_domain = ${sender_address_domain}
```
but I want to do something like this

```
dkim_domain = ${(domain1|domain2)$header_from}
```
but I think that the syntax is wrong
How do I get it to pass $header_from through the (domain1|domain2) filter?


----------



## SirDice (Jul 5, 2021)

What exactly do you want to accomplish? Because it sounds like we're hitting an XY problem here. If you explain what you're trying to do we might have a different or better solution to accomplish it.


----------



## hardworkingnewbie (Jul 5, 2021)

Exim has a really great Wiki containing much information about how to setup certain stuff. First you should look over there.

DKIM signing stuff: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-dkim_spf_and_dmarc.html

Aside that: personally I've been using Exim from maybe 1998 to 2004, or so. Then I switched to Postfix and never looked back. I really only can recommened to make that switch, because Exim's main problem is the outdated and monolithic design. It's one binary which does everything on its own. Postfix on the other hand has been designed and written by a well known security researcher with security in mind, and that really shows and bears fruits. For normal use cases there's almost nothing Postfix cannot do which Exim can.

So once in a while, around every 2-3 years with Exim a bug shows up which allows severe privilege escalation and definitely will bite you.

This is the CVE detail's list for Postfix since 2008, 8 entries: https://www.cvedetails.com/vulnerability-list/vendor_id-8450/product_id-14794/Postfix-Postfix.html

And this is Exim, 42 since 2010: https://www.cvedetails.com/vulnerability-list/vendor_id-10919/product_id-19563/Exim-Exim.html


----------



## dieselnutjob (Jul 5, 2021)

SirDice said:


> What exactly do you want to accomplish? Because it sounds like we're hitting an XY problem here. If you explain what you're trying to do we might have a different or better solution to accomplish it.


Pull the domain from the from_header and have exim use that for dkim_domain = and helo_data =
To be fair it isn't 100% clear in my mind if it's better to use from header or sender header.



hardworkingnewbie said:


> Then I switched to Postfix and never looked back.


I am using postfix on port 25 for inbound email, and exim on port 465 for authenticated clients (over ssl/tls) for outbound email


----------



## hardworkingnewbie (Jul 6, 2021)

dieselnutjob said:


> I am using postfix on port 25 for inbound email, and exim on port 465 for authenticated clients (over ssl/tls) for outbound email


Postfix is absolutely able to listen to more than one port. You just have to configure it that way.


----------



## SirDice (Jul 6, 2021)

So is exim. I don't see the point of having two different MTAs running, I would suggest using either exim or postfix, not both. At least not on the same machine. It's fine if you want to have one mailserver running on exim and another server on postfix. That's a better option if you're worried about a major bug in the system that would then take out your entire mail infrastructure. That could certainly happen in homogeneous environment.


----------



## dieselnutjob (Jul 6, 2021)

I would still like to learn regex though.  I would still like to understand how to write one function and pass the output through another function.
That's not an X-Y problem.
That's me wanting to learn something.
It's quite possible that how I have configured my mail servers isn't the best way, I have no problem with you saying it, but it isn't what I asked.
I still want to understand regex better, and I am sure I am not the only one.


----------



## hardworkingnewbie (Jul 6, 2021)

Maybe this here might be then interesting for you: RegexOne - learn regular expressions with simple, interactive exercises. https://regexone.com/


----------



## dieselnutjob (Jul 6, 2021)

Thank you.  Is it possible that someone could tell me how to have a function the output of which goes through another function?  without having to go through a tutorial?


----------



## dieselnutjob (Jul 6, 2021)

ok I think that the answer is here https://regexone.com/lesson/nested_groups


----------



## hardworkingnewbie (Jul 6, 2021)

Why don't you just tell us what you want to achieve, and we can evaluate on how to get you there? You still have never answered that really, you know.

From the bits and pieces you've given so far I am pretty certain that it has to do something with DKIM signing outbound mail traffic managed by Exim.

What do you want to achieve with that here?
`dkim_domain = ${(domain1|domain2)$header_from}`

If it should be multidomain DKIM signing with Exim, please have a look at that how to: https://www.ryanschulze.net/archives/1728


----------



## Tieks (Jul 6, 2021)

Need an example? Here is one.

```
#!/bin/sh
from_line="From: Mailer  <info@domain.org>"
domain=$(echo $from_line | sed -E 's/^From.+@(.+).+/\1/')
address=$(echo $from_line | sed -E 's/^From.+[ |<](.+)[.|>]/\1/')
echo Domain $domain, address $address
```
The regex is of type substitute (s), it picks the whole line, part to select is between parenthesis. That part can be referred to using \1 in the second part of the substitute.


----------



## dieselnutjob (Jul 6, 2021)

hardworkingnewbie said:


> If it should be multidomain DKIM signing with Exim, please have a look at that how to: https://www.ryanschulze.net/archives/1728



Yes I am trying to do that.  Thanks for the link. I will have a look at it.


----------



## hardworkingnewbie (Jul 6, 2021)

Great, please let us know how it worked for you! 

Talking about regular expressions in general one more word of advise if you want to learn them: there's more  than one implementation out there. The most commonly known is the one in the Perl language, but it is by far means not the only one. 

So different implementations, e.g. Perl compared to Python, most likely will have differences you should be aware about when moving one such thing to another. 

Exim itself uses its own implementation of regexes based on the PCRE library. This was created by Philip Hazel, who is also the original author of Exim, and based on the regular expression syntax implemented by Perl. On top of that though it has somre additions which Perl has not. 

Since Perl's view of regexes is so wide spread and common it is a good starting point to learn them.


----------



## dieselnutjob (Jul 6, 2021)

This is my current config, which does actually work

```
begin transports

remote_smtp:
## DKIM:
  driver = smtp
  helo_data = mail.${sender_address_domain}
  message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
  dkim_domain = ${sender_address_domain}
  dkim_selector = 12345678
  dkim_private_key = /usr/local/etc/exim/12345678.key
  dkim_canon = relaxed
```

I have a mail.domain set up for each of my domains in my DNS entries all pointing to this server.
Also I have SPF records for each domain and dkim public key for each domain as well.
With this config I am sharing the same key pair for all the domains, but it seems to work.

My only concern is if someone uses a client which doesn't use the sender address field then it's going to break.  Maybe that isn't a valid concern.


----------



## dieselnutjob (Jul 6, 2021)

another question

in this expression ${sender_address_domain}
what does the $ actually mean?

and why are some expressions ${a_thing} and others are {$a_thing}
?


----------



## hardworkingnewbie (Jul 6, 2021)

11. String expansions
					

Exim is a message transfer agent (MTA) developed at the University of Cambridge for use on Unix systems connected to the Internet.



					www.exim.org


----------

