[stunnel-users] [PATCH] SMTP server with PROXY
Michał Mirosław
mirq-linux at rere.qmqm.pl
Sat Apr 4 05:57:24 CEST 2020
Hi,
I've been using stunnel as a SSL frontend to an SMTP server. The server
usually has use for original client's address, so I made a patch that
adds PROXY protocol headers on backend (unwrapped) connection.
Best Regards,
Michał Mirosław
Index: stunnel4-5.56/src/protocol.c
===================================================================
--- stunnel4-5.56.orig/src/protocol.c
+++ stunnel4-5.56/src/protocol.c
@@ -58,7 +58,9 @@ NOEXPORT char *smtp_client(CLI *, SERVIC
NOEXPORT void smtp_client_negotiate(CLI *);
NOEXPORT void smtp_client_plain(CLI *, const char *, const char *);
NOEXPORT void smtp_client_login(CLI *, const char *, const char *);
+NOEXPORT void smtp_server_negotiate(CLI *, char *, int);
NOEXPORT char *smtp_server(CLI *, SERVICE_OPTIONS *, const PHASE);
+NOEXPORT char *smtp_proxy_server(CLI *, SERVICE_OPTIONS *, const PHASE);
NOEXPORT char *pop3_client(CLI *, SERVICE_OPTIONS *, const PHASE);
NOEXPORT char *pop3_server(CLI *, SERVICE_OPTIONS *, const PHASE);
NOEXPORT char *imap_client(CLI *, SERVICE_OPTIONS *, const PHASE);
@@ -97,6 +99,10 @@ char *protocol(CLI *c, SERVICE_OPTIONS *
return opt->option.client ?
pgsql_client(c, opt, phase) :
pgsql_server(c, opt, phase);
+ if(!strcasecmp(opt->protocol, "smtp+proxy"))
+ return opt->option.client ?
+ "The 'proxy' protocol is not supported in the client mode" :
+ smtp_proxy_server(c, opt, phase);
if(!strcasecmp(opt->protocol, "smtp"))
return opt->option.client ?
smtp_client(c, opt, phase) :
@@ -837,6 +843,12 @@ NOEXPORT void smtp_client_login(CLI *c,
NOEXPORT char *smtp_server(CLI *c, SERVICE_OPTIONS *opt, const PHASE phase) {
char *line, *domain, *greeting;
+ if (opt->protocol_domain) {
+ if(phase==PROTOCOL_EARLY)
+ smtp_server_negotiate(c, opt->protocol_domain, 1);
+ return NULL;
+ }
+
if(phase==PROTOCOL_CHECK)
opt->option.connect_before_ssl=1; /* c->remote_fd needed */
if(phase!=PROTOCOL_MIDDLE)
@@ -881,17 +893,32 @@ NOEXPORT char *smtp_server(CLI *c, SERVI
}
str_free(line);
+ smtp_server_negotiate(c, domain, 0);
+ return NULL;
+}
+
+NOEXPORT void smtp_server_negotiate(CLI *c, char *domain, int static_domain) {
+ char *line;
+
+ if (static_domain) {
+ if (!domain)
+ domain=(char *)"smtp.example.com";
+ fd_printf(c, c->local_wfd.fd, "220 %s stunnel", domain);
+ }
+
/* process client's EHLO */
line=fd_getline(c, c->local_rfd.fd);
if(!is_prefix(line, "EHLO ")) {
s_log(LOG_ERR, "Unknown client EHLO");
str_free(line);
- str_free(domain);
+ if (!static_domain)
+ str_free(domain);
throw_exception(c, 1);
}
str_free(line);
fd_printf(c, c->local_wfd.fd, "250-%s", domain);
- str_free(domain);
+ if (!static_domain)
+ str_free(domain);
fd_putline(c, c->local_wfd.fd, "250 STARTTLS");
/* process client's STARTTLS */
@@ -903,7 +930,13 @@ NOEXPORT char *smtp_server(CLI *c, SERVI
}
fd_putline(c, c->local_wfd.fd, "220 Go ahead");
str_free(line);
+}
+NOEXPORT char *smtp_proxy_server(CLI *c, SERVICE_OPTIONS *opt, const PHASE phase) {
+ if(phase==PROTOCOL_LATE)
+ return proxy_server(c, opt, phase);
+ if(phase==PROTOCOL_EARLY)
+ smtp_server_negotiate(c, opt->protocol_domain, 1);
return NULL;
}
More information about the stunnel-users
mailing list