From 099d576466a124e19c3fda8541cd887b65b9d2cb Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 30 Aug 2006 17:33:46 +0000 Subject: - Added support for setting the REMOTE variable when an XFORWARD command is seen. --- ChangeLog | 6 ++++- common/smtppass.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- common/smtppass.h | 5 +++-- configure.in | 4 ++-- doc/proxsmtpd.8 | 8 +++++++ 5 files changed, 81 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index a5f46e9..488063b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -1.4 [???] +1.5 ???? + - Added support for setting the REMOTE variable when an XFORWARD + command is seen. + +1.4 [2006-08-10] - Fix crasher after connection closes unexpectedly. - Fix problem with waiting for processes [Jeff Fisher] - Better message for 'busy' [Akihiro Sagawa] diff --git a/common/smtppass.c b/common/smtppass.c index 7844879..a783bac 100644 --- a/common/smtppass.c +++ b/common/smtppass.c @@ -123,6 +123,7 @@ spthread_t; #define STARTTLS_CMD "STARTTLS" #define BDAT_CMD "BDAT" #define XCLIENT_CMD "XCLIENT" +#define XFORWARD_CMD "XFORWARD" #define DATA_END_SIG "." CRLF @@ -201,6 +202,7 @@ static int make_connections(spctx_t* ctx, int client); static int read_server_response(spctx_t* ctx); static int parse_config_file(const char* configfile); static char* parse_address(char* line); +static char* parse_xforward(char* line, const char* part); static const char* get_successful_rsp(const char* line, int* cont); static void do_server_noop(spctx_t* ctx); @@ -648,6 +650,12 @@ static void cleanup_context(spctx_t* ctx) ctx->sender = NULL; } + if(ctx->xforwardaddr) + { + free(ctx->xforwardaddr); + ctx->xforwardaddr = NULL; + } + ctx->logline[0] = 0; } @@ -883,7 +891,7 @@ static int smtp_passthru(spctx_t* ctx) RETURN(-1); /* - * Now go into avcheck mode. This also handles the eventual + * Now go into scan mode. This also handles the eventual * sending of the data to the server, making the av check * transparent */ @@ -1069,7 +1077,7 @@ static int smtp_passthru(spctx_t* ctx) } } - /* MAIL FROM */ + /* MAIL FROM (that the server accepted) */ if((r = check_first_word(C_LINE, FROM_CMD, KL(FROM_CMD), SMTP_DELIMS)) > 0) { t = parse_address(C_LINE + r); @@ -1081,7 +1089,7 @@ static int smtp_passthru(spctx_t* ctx) strcpy(ctx->sender, t); } - /* RCPT TO */ + /* RCPT TO (that the server accepted) */ else if((r = check_first_word(C_LINE, TO_CMD, KL(TO_CMD), SMTP_DELIMS)) > 0) { t = parse_address(C_LINE + r); @@ -1102,6 +1110,21 @@ static int smtp_passthru(spctx_t* ctx) } } + /* + * If the client sends an XFORWARD, and the server accepted it, + * we store address for use in our forked process environment + * variables (see sp_setup_forked). + */ + else if(is_first_word(C_LINE, XFORWARD_CMD, KL(XFORWARD_CMD))) + { + if((t = parse_xforward (C_LINE + KL(XFORWARD_CMD), "ADDR"))) + { + ctx->xforwardaddr = (char*)reallocf(ctx->xforwardaddr, strlen(t) + 1); + if(ctx->xforwardaddr) + strcpy(ctx->xforwardaddr, t); + } + } + /* RSET */ else if(is_first_word(C_LINE, RSET_CMD, KL(RSET_CMD))) { @@ -1154,6 +1177,40 @@ static char* parse_address(char* line) return trim_end(line); } +static char* parse_xforward(char* line, const char* part) +{ + char* t; + char* e; + + t = strcasestr(line, part); + if(!t) + return NULL; + + /* equals sign and surrounding */ + t = trim_start(t + strlen(part)); + if(*t != '=') + return NULL; + t = trim_start(t + 1); + if(!*t) + return NULL; + + /* Find the end of the thingy */ + if(*t == '[') + { + t++; + e = strchr(t, ']'); + } + else + { + e = t + strcspn(t, " \t"); + } + + if(!e) + return NULL; + *e = 0; + return t; +} + static const char* get_successful_rsp(const char* line, int* cont) { /* @@ -1704,6 +1761,9 @@ void sp_setup_forked(spctx_t* ctx, int file) if(spio_valid(&(ctx->client))) setenv("CLIENT", ctx->client.peername, 1); + if(ctx->xforwardaddr) + setenv("REMOTE", ctx->xforwardaddr, 1); + if(spio_valid(&(ctx->server))) setenv("SERVER", ctx->server.peername, 1); diff --git a/common/smtppass.h b/common/smtppass.h index 7c76225..8ca86ca 100644 --- a/common/smtppass.h +++ b/common/smtppass.h @@ -129,8 +129,9 @@ typedef struct spctx char cachename[MAXPATHLEN]; /* The name of the file that we cache into */ char logline[SP_LOG_LINE_LEN]; /* Log line */ - char* sender; /* The email of the sender */ - char* recipients; /* The email of the recipients */ + char* sender; /* The email of the sender */ + char* recipients; /* The email of the recipients */ + char* xforwardaddr; /* The IP address proxied for */ int _crlf; /* Private data */ } diff --git a/configure.in b/configure.in index a073cff..91f9f42 100644 --- a/configure.in +++ b/configure.in @@ -36,8 +36,8 @@ dnl Nate Nielsen dnl dnl Process this file with autoconf to produce a configure script. -AC_INIT(proxsmtp, 1.3.92, nielsen@memberwebs.com) -AM_INIT_AUTOMAKE(proxsmtp, 1.3.92) +AC_INIT(proxsmtp, 1.4.90, nielsen@memberwebs.com) +AM_INIT_AUTOMAKE(proxsmtp, 1.4.90) LDFLAGS="$LDFLAGS -L/usr/local/lib" CFLAGS="$CFLAGS -I/usr/local/include" diff --git a/doc/proxsmtpd.8 b/doc/proxsmtpd.8 index 9f9f9d0..d19acad 100644 --- a/doc/proxsmtpd.8 +++ b/doc/proxsmtpd.8 @@ -130,6 +130,14 @@ option is set to 'file', this specifies the file that the email was saved to. .It Ar RECIPIENTS The email addresses of the email recipients. These are specified one per line, in standard address format. +.It Ar REMOTE +If +.Nm +is being used to filter email between SMTP servers, then this is the +IP address of the original client. In order for this information to be present +(a) the SMTP client (sending server) must an send an XFORWARD command and (b) +the SMTP server (receiving server) must accept that XFORWARD command without +error. .It Ar SENDER The email address for the sender of the email. .It Ar SERVER -- cgit v1.2.3