summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--common/smtppass.c66
-rw-r--r--common/smtppass.h5
-rw-r--r--configure.in4
-rw-r--r--doc/proxsmtpd.88
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 <nielsen@memberwebs.com>
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