From ce8c9c5544e5ea4eae5757b21a279a604ce6332e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 17 Oct 2003 23:45:48 +0000 Subject: New 'preconnect' keyword to execute a command prior to opening an SMTP connection (Daniel Richard G.). --- NEWS | 5 ++++- esmtprc.5 | 10 ++++++++++ lexer.l | 1 + parser.y | 3 ++- sample.esmtprc | 4 ++++ smtp.c | 38 ++++++++++++++++++++++++++++++++++++++ smtp.h | 5 +++++ 7 files changed, 64 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 11e06af..68f715e 100644 --- a/NEWS +++ b/NEWS @@ -3,12 +3,15 @@ News * Version 0.4.2 (under development): + * New 'preconnect' keyword to execute a command prior to opening an SMTP + connection (Daniel Richard G.). + * Fixed a bug which prevented to send mail when libesmtp had no openssl support (Tomas Kondor). * New 'default' keyword for identities (Vitezslav Batrla). - * Version 0.4.1 (2004-07-14): + * Version 0.4.1 (2003-07-14): * Packaging fixes. diff --git a/esmtprc.5 b/esmtprc.5 index 2bf6a01..b807bcb 100644 --- a/esmtprc.5 +++ b/esmtprc.5 @@ -68,6 +68,16 @@ It can be one of \fBenabled\fR, \fBdisabled\fR or \fBrequired\fR. It defaults to \fBcertificate_passphrase\fR Set the certificate passphrase for the StartTLS extension. +.TP +\fBpreconnect\fR +Shell command to execute prior to opening an SMTP connection. + +This may be useful in conjunction with application-level transports (e.g. +\fBssh\fR with its port-forwarding functionality) to secure the SMTP +connection. \fBEsmtp\fR will wait for the command to exit before +proceeding. If the command returns a non-zero status, delivery will be +aborted. + .TP \fBidentity\fR Define an identity. diff --git a/lexer.l b/lexer.l index 1a269f8..9529d0e 100644 --- a/lexer.l +++ b/lexer.l @@ -60,6 +60,7 @@ user(name)? { BEGIN(NAME); return USERNAME; } pass(word)? { BEGIN(NAME); return PASSWORD; } (start)?tls { return STARTTLS; } (certificate_)?passphrase { return CERTIFICATE_PASSPHRASE; } +preconnect { return PRECONNECT; } mda { return MDA; } = { return MAP; } diff --git a/parser.y b/parser.y index fdbb769..428e1c3 100644 --- a/parser.y +++ b/parser.y @@ -54,7 +54,7 @@ void yyerror (const char *s); char *sval; } -%token IDENTITY DEFAULT HOSTNAME USERNAME PASSWORD STARTTLS CERTIFICATE_PASSPHRASE MDA +%token IDENTITY DEFAULT HOSTNAME USERNAME PASSWORD STARTTLS CERTIFICATE_PASSPHRASE PRECONNECT MDA %token MAP @@ -100,6 +100,7 @@ statement : HOSTNAME map STRING { identity->host = xstrdup($3); SET_DEFAULT_IDEN | STARTTLS map ENABLED { identity->starttls = Starttls_ENABLED; SET_DEFAULT_IDENTITY; } | STARTTLS map REQUIRED { identity->starttls = Starttls_REQUIRED; SET_DEFAULT_IDENTITY; } | CERTIFICATE_PASSPHRASE map STRING { identity->certificate_passphrase = xstrdup($3); SET_DEFAULT_IDENTITY; } + | PRECONNECT map STRING { identity->preconnect = xstrdup($3); SET_DEFAULT_IDENTITY; } | MDA map STRING { mda = xstrdup($3); } | DEFAULT { default_identity = identity; } ; diff --git a/sample.esmtprc b/sample.esmtprc index f44db65..e1f1572 100644 --- a/sample.esmtprc +++ b/sample.esmtprc @@ -24,6 +24,10 @@ password = "PASSWORD" # #certificate_passphrase = "CERTIFICATE_PASSPHRASE" +# Command to run before contacting the SMTP server +# +#preconnect = "ssh -f -L 2025:mail.isp.com:25 user@shell.isp.com 'sleep 5'" + # Same as above but for a different identity which can be selected with the # '-f' flag. You can have as many you like. diff --git a/smtp.c b/smtp.c index 87b086b..f536cec 100644 --- a/smtp.c +++ b/smtp.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -429,6 +430,43 @@ void smtp_send(message_t *msg) goto failure; } + /* Execute pre-connect command if one was specified. */ + if (identity->preconnect) + { + int ret, exit_status; + + if (verbose) + fprintf (stdout, "Executing pre-connect command: %s\n", identity->preconnect); + + ret = system (identity->preconnect); + exit_status = WEXITSTATUS(ret); + + /* Check whether the child process caught a signal meant for us */ + if (WIFSIGNALED(ret)) + { + int sig = WTERMSIG(ret); + + if (sig == SIGINT || sig == SIGQUIT) + { + fprintf (stderr, "Pre-connect command received signal %d\n", sig); + exit (EX_SOFTWARE); + } + } + + if (ret == -1) + { + fputs ("Error executing pre-connect command\n", stderr); + exit (EX_OSERR); + } + + if (exit_status != 0) + { + fprintf (stderr, "Pre-connect command \"%s\" exited with non-zero status %d\n", + identity->preconnect, exit_status); + exit (EX_SOFTWARE); + } + } + /* Initiate a connection to the SMTP server and transfer the message. */ if (!smtp_start_session (session)) { diff --git a/smtp.h b/smtp.h index cc3fac8..5df10ca 100644 --- a/smtp.h +++ b/smtp.h @@ -38,6 +38,11 @@ typedef struct { enum starttls_option starttls; char *certificate_passphrase; /*@}*/ + + /** \name Pre-connect Command */ + /*@{*/ + char *preconnect; + /*@}*/ } identity_t; /** -- cgit v1.2.3