From 4bc7f5544d28e6b197d1bdfa5bed3fddb2a01c53 Mon Sep 17 00:00:00 2001 From: Brian Flachs Date: Tue, 29 Mar 2022 10:36:40 -0500 Subject: [PATCH] add sender configuration options for NAT masq --- esmtprc.5 | 14 +++++++++++ parser.y | 1 + smtp.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/esmtprc.5 b/esmtprc.5 index 415ce0e..3a78448 100644 --- a/esmtprc.5 +++ b/esmtprc.5 @@ -42,6 +42,20 @@ The host-port notation simplifies things for the application, the user can type "localhost:smtp" or "localhost:25" where the application expects a host name. +.TP +\fBsender\fR +Set the identity of the sender of the email. + +This is useful for systems behind a NAT firewall, when for example +the sender's email address should not have the hostname. Several +escape formatting codes are available: + + %u - user name of the sender + %h - hostname of the sending system + %d - domainname of the sending system + +So %u@%d might be a desirable identity from inside the local network. + .TP \fBusername\fR Set the username for authentication with the SMTP server. diff --git a/parser.y b/parser.y index b2c7a8f..4928f68 100644 --- a/parser.y +++ b/parser.y @@ -104,6 +104,7 @@ statement_list : statement /* future global options should also have the form SET optmap */ statement : HOSTNAME map STRING { identity->host = xstrdup($3); SET_DEFAULT_IDENTITY; } + | SENDER map STRING { identity->address = xstrdup($3); } | USERNAME map STRING { identity->user = xstrdup($3); SET_DEFAULT_IDENTITY; } | PASSWORD map STRING { identity->pass = xstrdup($3); SET_DEFAULT_IDENTITY; } | STARTTLS map DISABLED { identity->starttls = Starttls_DISABLED; SET_DEFAULT_IDENTITY; } diff --git a/smtp.c b/smtp.c index 796578d..11d4f4d 100644 --- a/smtp.c +++ b/smtp.c @@ -485,6 +485,67 @@ static char *escape_forced_address (char *mask) } +/* search for end of string */ +static inline char *eos(char *p) + { + while (*p) p++; + return p; + } + +/* substitute %codes in a string, + %u = get_username() + %h = gethostname() + %d = domainname (omit host. in host.domain.name from gethostname) + return the result in a newly malloced string +*/ +char *xstrsubst(char *pp,char *p) + { + char address[2048],*dp=address; + while (p) + { + strcpy(dp,pp); + dp += (p - pp); + switch (p[1]) + { + case 'u':; + strcpy(dp,get_username()); + dp = eos(dp); + p += 2; + break; + + case 'h':; + if(! gethostname(dp,sizeof(address)-(dp-address))) + dp = eos(dp); + p += 2; + break; + + case 'd': + if(! gethostname(dp,sizeof(address)-(dp-address))) + { + char *pt = strchr(dp,'.'); + if (pt++) + { + do { *dp++ = *pt++; } while (*pt); + } + else + dp = eos(dp); + } + + p += 2; + break; + + default: + fprintf(stderr,"unknown formatter in sender %s\n",p); + return 0; + } + pp = p; + p = strchr(pp,'%'); + } + + strcpy(dp,pp); + return xstrdup(address); + } + void smtp_send(message_t *msg, identity_t *identity) { smtp_session_t session; @@ -597,9 +658,17 @@ void smtp_send(message_t *msg, identity_t *identity) } else if(identity->address) { - /* Use the identity address as reverse path. */ - if(!smtp_set_reverse_path (message, identity->address)) - goto failure; + char *p=strchr(identity->address,'%'); + if (p) + { /* expand %codes in address */ + char *av = xstrsubst(identity->address,p); + if (! av) goto failure; + free(identity->address); + identity->address = av; + } + /* Use the identity address as reverse path. */ + if(!smtp_set_reverse_path (message, identity->address)) + goto failure; } else {