summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jrfonseca@users.sourceforge.net>2003-10-17 23:45:48 +0000
committerJosé Fonseca <jrfonseca@users.sourceforge.net>2003-10-17 23:45:48 +0000
commitce8c9c5544e5ea4eae5757b21a279a604ce6332e (patch)
treeeefaa8cdd47319e74aaeb9c893184a5480fb1586
parent3243d5d55f4124980caf911214b935d52d448ca3 (diff)
New 'preconnect' keyword to execute a command prior to opening an SMTP
connection (Daniel Richard G.).
-rw-r--r--NEWS5
-rw-r--r--esmtprc.510
-rw-r--r--lexer.l1
-rw-r--r--parser.y3
-rw-r--r--sample.esmtprc4
-rw-r--r--smtp.c38
-rw-r--r--smtp.h5
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
@@ -69,6 +69,16 @@ It can be one of \fBenabled\fR, \fBdisabled\fR or \fBrequired\fR. It defaults to
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 <string.h>
#include <signal.h>
#include <errno.h>
+#include <sys/wait.h>
#include <auth-client.h>
#include <libesmtp.h>
@@ -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;
/**