mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-09 18:45:54 +02:00
dma: update to 0.12
All of the dma patches in src/patches/ were merged into its upstream repository by now, thus becoming obsolete and deleted by this patch. Cc: Michael Tremer <michael.tremer@ipfire.org> Signed-off-by: Peter Müller <peter.mueller@ipfire.org> Reviewed-by: Michael Tremer <michael.tremer@ipfire.org> Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
This commit is contained in:
committed by
Arne Fitzenreiter
parent
2d599cca34
commit
59b2a70f7a
9
lfs/dma
9
lfs/dma
@@ -1,7 +1,7 @@
|
||||
###############################################################################
|
||||
# #
|
||||
# IPFire.org - A linux based firewall #
|
||||
# Copyright (C) 2007-2018 IPFire Team <info@ipfire.org> #
|
||||
# Copyright (C) 2007-2020 IPFire Team <info@ipfire.org> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
include Config
|
||||
|
||||
VER = 0.11
|
||||
VER = 0.12
|
||||
|
||||
THISAPP = dma-$(VER)
|
||||
DL_FILE = $(THISAPP).tar.gz
|
||||
@@ -40,7 +40,7 @@ objects = $(DL_FILE)
|
||||
|
||||
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
|
||||
|
||||
$(DL_FILE)_MD5 = 4090572921fc33be0977f4010881b501
|
||||
$(DL_FILE)_MD5 = 58cb2a286995381c92dc557e639622d6
|
||||
|
||||
install : $(TARGET)
|
||||
|
||||
@@ -73,9 +73,6 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
|
||||
mkdir -pv /var/ipfire/dma
|
||||
touch /var/ipfire/dma/mail.conf
|
||||
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dma-0.10-better-authentication.patch
|
||||
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dma-0.10-better-tls.patch
|
||||
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/dma-0.11-compile-fixes.patch
|
||||
cd $(DIR_APP) && sed -i '/PREFIX/s/usr\/local/usr/g' Makefile
|
||||
cd $(DIR_APP) && sed -i '/CONFDIR/s/etc\/dma/var\/ipfire\/dma/g' Makefile
|
||||
cd $(DIR_APP) && make
|
||||
|
||||
@@ -1,373 +0,0 @@
|
||||
From 1fa7a882dd22d5f619b3645c6597a419034e9b4e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Tremer <michael.tremer@ipfire.org>
|
||||
Date: Mon, 9 Nov 2015 21:52:08 +0000
|
||||
Subject: [PATCH] Implement better authentication
|
||||
|
||||
DMA tries to authenticate by simply trying various authentication
|
||||
mechanisms. This is obviously not conforming to RFC and some mail
|
||||
providers detect this is spam and reject all emails.
|
||||
|
||||
This patch parses the EHLO response and reads various keywords
|
||||
from it that can then later in the program be used to jump into
|
||||
certain code paths.
|
||||
|
||||
Currently this is used to only authenticate with CRAM-MD5 and/or
|
||||
LOGIN if the server supports one or both of these. The
|
||||
implementation can be easily be extended though.
|
||||
|
||||
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
|
||||
---
|
||||
crypto.c | 6 +-
|
||||
dma.h | 13 +++-
|
||||
net.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++----------------
|
||||
3 files changed, 181 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/crypto.c b/crypto.c
|
||||
index 897b55b..8048f20 100644
|
||||
--- a/crypto.c
|
||||
+++ b/crypto.c
|
||||
@@ -77,7 +77,7 @@ init_cert_file(SSL_CTX *ctx, const char *path)
|
||||
}
|
||||
|
||||
int
|
||||
-smtp_init_crypto(int fd, int feature)
|
||||
+smtp_init_crypto(int fd, int feature, struct smtp_features* features)
|
||||
{
|
||||
SSL_CTX *ctx = NULL;
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x00909000L)
|
||||
@@ -118,8 +118,7 @@ smtp_init_crypto(int fd, int feature)
|
||||
/* TLS init phase, disable SSL_write */
|
||||
config.features |= NOSSL;
|
||||
|
||||
- send_remote_command(fd, "EHLO %s", hostname());
|
||||
- if (read_remote(fd, 0, NULL) == 2) {
|
||||
+ if (perform_server_greeting(fd, features) == 0) {
|
||||
send_remote_command(fd, "STARTTLS");
|
||||
if (read_remote(fd, 0, NULL) != 2) {
|
||||
if ((feature & TLS_OPP) == 0) {
|
||||
@@ -131,6 +130,7 @@ smtp_init_crypto(int fd, int feature)
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
/* End of TLS init phase, enable SSL_write/read */
|
||||
config.features &= ~NOSSL;
|
||||
}
|
||||
diff --git a/dma.h b/dma.h
|
||||
index acf5e44..ee749d8 100644
|
||||
--- a/dma.h
|
||||
+++ b/dma.h
|
||||
@@ -51,6 +51,7 @@
|
||||
#define BUF_SIZE 2048
|
||||
#define ERRMSG_SIZE 200
|
||||
#define USERNAME_SIZE 50
|
||||
+#define EHLO_RESPONSE_SIZE BUF_SIZE
|
||||
#define MIN_RETRY 300 /* 5 minutes */
|
||||
#define MAX_RETRY (3*60*60) /* retry at least every 3 hours */
|
||||
#define MAX_TIMEOUT (5*24*60*60) /* give up after 5 days */
|
||||
@@ -160,6 +161,15 @@ struct mx_hostentry {
|
||||
struct sockaddr_storage sa;
|
||||
};
|
||||
|
||||
+struct smtp_auth_mechanisms {
|
||||
+ int cram_md5;
|
||||
+ int login;
|
||||
+};
|
||||
+
|
||||
+struct smtp_features {
|
||||
+ struct smtp_auth_mechanisms auth;
|
||||
+ int starttls;
|
||||
+};
|
||||
|
||||
/* global variables */
|
||||
extern struct aliases aliases;
|
||||
@@ -187,7 +197,7 @@ void parse_authfile(const char *);
|
||||
/* crypto.c */
|
||||
void hmac_md5(unsigned char *, int, unsigned char *, int, unsigned char *);
|
||||
int smtp_auth_md5(int, char *, char *);
|
||||
-int smtp_init_crypto(int, int);
|
||||
+int smtp_init_crypto(int, int, struct smtp_features*);
|
||||
|
||||
/* dns.c */
|
||||
int dns_get_mx_list(const char *, int, struct mx_hostentry **, int);
|
||||
@@ -196,6 +206,7 @@ int dns_get_mx_list(const char *, int, struct mx_hostentry **, int);
|
||||
char *ssl_errstr(void);
|
||||
int read_remote(int, int, char *);
|
||||
ssize_t send_remote_command(int, const char*, ...) __attribute__((__nonnull__(2), __format__ (__printf__, 2, 3)));
|
||||
+int perform_server_greeting(int, struct smtp_features*);
|
||||
int deliver_remote(struct qitem *);
|
||||
|
||||
/* base64.c */
|
||||
diff --git a/net.c b/net.c
|
||||
index 26935a8..33ff8f5 100644
|
||||
--- a/net.c
|
||||
+++ b/net.c
|
||||
@@ -247,64 +247,70 @@ read_remote(int fd, int extbufsize, char *extbuf)
|
||||
* Handle SMTP authentication
|
||||
*/
|
||||
static int
|
||||
-smtp_login(int fd, char *login, char* password)
|
||||
+smtp_login(int fd, char *login, char* password, const struct smtp_features* features)
|
||||
{
|
||||
char *temp;
|
||||
int len, res = 0;
|
||||
|
||||
- res = smtp_auth_md5(fd, login, password);
|
||||
- if (res == 0) {
|
||||
- return (0);
|
||||
- } else if (res == -2) {
|
||||
- /*
|
||||
- * If the return code is -2, then then the login attempt failed,
|
||||
- * do not try other login mechanisms
|
||||
- */
|
||||
- return (1);
|
||||
- }
|
||||
-
|
||||
- if ((config.features & INSECURE) != 0 ||
|
||||
- (config.features & SECURETRANS) != 0) {
|
||||
- /* Send AUTH command according to RFC 2554 */
|
||||
- send_remote_command(fd, "AUTH LOGIN");
|
||||
- if (read_remote(fd, 0, NULL) != 3) {
|
||||
- syslog(LOG_NOTICE, "remote delivery deferred:"
|
||||
- " AUTH login not available: %s",
|
||||
- neterr);
|
||||
+ // CRAM-MD5
|
||||
+ if (features->auth.cram_md5) {
|
||||
+ res = smtp_auth_md5(fd, login, password);
|
||||
+ if (res == 0) {
|
||||
+ return (0);
|
||||
+ } else if (res == -2) {
|
||||
+ /*
|
||||
+ * If the return code is -2, then then the login attempt failed,
|
||||
+ * do not try other login mechanisms
|
||||
+ */
|
||||
return (1);
|
||||
}
|
||||
+ }
|
||||
|
||||
- len = base64_encode(login, strlen(login), &temp);
|
||||
- if (len < 0) {
|
||||
+ // LOGIN
|
||||
+ if (features->auth.login) {
|
||||
+ if ((config.features & INSECURE) != 0 ||
|
||||
+ (config.features & SECURETRANS) != 0) {
|
||||
+ /* Send AUTH command according to RFC 2554 */
|
||||
+ send_remote_command(fd, "AUTH LOGIN");
|
||||
+ if (read_remote(fd, 0, NULL) != 3) {
|
||||
+ syslog(LOG_NOTICE, "remote delivery deferred:"
|
||||
+ " AUTH login not available: %s",
|
||||
+ neterr);
|
||||
+ return (1);
|
||||
+ }
|
||||
+
|
||||
+ len = base64_encode(login, strlen(login), &temp);
|
||||
+ if (len < 0) {
|
||||
encerr:
|
||||
- syslog(LOG_ERR, "can not encode auth reply: %m");
|
||||
- return (1);
|
||||
- }
|
||||
+ syslog(LOG_ERR, "can not encode auth reply: %m");
|
||||
+ return (1);
|
||||
+ }
|
||||
|
||||
- send_remote_command(fd, "%s", temp);
|
||||
- free(temp);
|
||||
- res = read_remote(fd, 0, NULL);
|
||||
- if (res != 3) {
|
||||
- syslog(LOG_NOTICE, "remote delivery %s: AUTH login failed: %s",
|
||||
- res == 5 ? "failed" : "deferred", neterr);
|
||||
- return (res == 5 ? -1 : 1);
|
||||
- }
|
||||
+ send_remote_command(fd, "%s", temp);
|
||||
+ free(temp);
|
||||
+ res = read_remote(fd, 0, NULL);
|
||||
+ if (res != 3) {
|
||||
+ syslog(LOG_NOTICE, "remote delivery %s: AUTH login failed: %s",
|
||||
+ res == 5 ? "failed" : "deferred", neterr);
|
||||
+ return (res == 5 ? -1 : 1);
|
||||
+ }
|
||||
|
||||
- len = base64_encode(password, strlen(password), &temp);
|
||||
- if (len < 0)
|
||||
- goto encerr;
|
||||
-
|
||||
- send_remote_command(fd, "%s", temp);
|
||||
- free(temp);
|
||||
- res = read_remote(fd, 0, NULL);
|
||||
- if (res != 2) {
|
||||
- syslog(LOG_NOTICE, "remote delivery %s: Authentication failed: %s",
|
||||
- res == 5 ? "failed" : "deferred", neterr);
|
||||
- return (res == 5 ? -1 : 1);
|
||||
+ len = base64_encode(password, strlen(password), &temp);
|
||||
+ if (len < 0)
|
||||
+ goto encerr;
|
||||
+
|
||||
+ send_remote_command(fd, "%s", temp);
|
||||
+ free(temp);
|
||||
+ res = read_remote(fd, 0, NULL);
|
||||
+ if (res != 2) {
|
||||
+ syslog(LOG_NOTICE, "remote delivery %s: Authentication failed: %s",
|
||||
+ res == 5 ? "failed" : "deferred", neterr);
|
||||
+ return (res == 5 ? -1 : 1);
|
||||
+ }
|
||||
+ } else {
|
||||
+ syslog(LOG_WARNING, "non-encrypted SMTP login is disabled in config, so skipping it. ");
|
||||
+ return (1);
|
||||
}
|
||||
- } else {
|
||||
- syslog(LOG_WARNING, "non-encrypted SMTP login is disabled in config, so skipping it. ");
|
||||
- return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
@@ -348,10 +354,115 @@ close_connection(int fd)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
+static void parse_auth_line(char* line, struct smtp_auth_mechanisms* auth) {
|
||||
+ // Skip the auth prefix
|
||||
+ line += strlen("AUTH ");
|
||||
+
|
||||
+ char* method = strtok(line, " ");
|
||||
+ while (method) {
|
||||
+ if (strcmp(method, "CRAM-MD5") == 0)
|
||||
+ auth->cram_md5 = 1;
|
||||
+
|
||||
+ else if (strcmp(method, "LOGIN") == 0)
|
||||
+ auth->login = 1;
|
||||
+
|
||||
+ method = strtok(NULL, " ");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int perform_server_greeting(int fd, struct smtp_features* features) {
|
||||
+ /*
|
||||
+ Send EHLO
|
||||
+ XXX allow HELO fallback
|
||||
+ */
|
||||
+ send_remote_command(fd, "EHLO %s", hostname());
|
||||
+
|
||||
+ char buffer[EHLO_RESPONSE_SIZE];
|
||||
+ memset(buffer, 0, sizeof(buffer));
|
||||
+
|
||||
+ int res = read_remote(fd, sizeof(buffer) - 1, buffer);
|
||||
+
|
||||
+ // Got an unexpected response
|
||||
+ if (res != 2)
|
||||
+ return -1;
|
||||
+
|
||||
+ // Reset all features
|
||||
+ memset(features, 0, sizeof(*features));
|
||||
+
|
||||
+ // Run through the buffer line by line
|
||||
+ char linebuffer[EHLO_RESPONSE_SIZE];
|
||||
+ char* p = buffer;
|
||||
+
|
||||
+ while (*p) {
|
||||
+ char* line = linebuffer;
|
||||
+ while (*p && *p != '\n') {
|
||||
+ *line++ = *p++;
|
||||
+ }
|
||||
+
|
||||
+ // p should never point to NULL after the loop
|
||||
+ // above unless we reached the end of the buffer.
|
||||
+ // In that case we will raise an error.
|
||||
+ if (!*p) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ // Otherwise p points to the newline character which
|
||||
+ // we will skip.
|
||||
+ p++;
|
||||
+
|
||||
+ // Terminte the string (and remove the carriage-return character)
|
||||
+ *--line = '\0';
|
||||
+ line = linebuffer;
|
||||
+
|
||||
+ // End main loop for empty lines
|
||||
+ if (*line == '\0')
|
||||
+ break;
|
||||
+
|
||||
+ // Process the line
|
||||
+ // - Must start with 250, followed by dash or space
|
||||
+ // - We won't check for the correct usage of space and dash because
|
||||
+ // that is already done in read_remote().
|
||||
+ if ((strncmp(line, "250-", 4) != 0) && (strncmp(line, "250 ", 4) != 0)) {
|
||||
+ syslog(LOG_ERR, "Invalid line: %s\n", line);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ // Skip the prefix
|
||||
+ line += 4;
|
||||
+
|
||||
+ // Check for STARTTLS
|
||||
+ if (strcmp(line, "STARTTLS") == 0)
|
||||
+ features->starttls = 1;
|
||||
+
|
||||
+ // Parse authentication mechanisms
|
||||
+ else if (strncmp(line, "AUTH ", 5) == 0)
|
||||
+ parse_auth_line(line, &features->auth);
|
||||
+ }
|
||||
+
|
||||
+ syslog(LOG_DEBUG, "Server greeting successfully completed");
|
||||
+
|
||||
+ // STARTTLS
|
||||
+ if (features->starttls)
|
||||
+ syslog(LOG_DEBUG, " Server supports STARTTLS");
|
||||
+ else
|
||||
+ syslog(LOG_DEBUG, " Server does not support STARTTLS");
|
||||
+
|
||||
+ // Authentication
|
||||
+ if (features->auth.cram_md5) {
|
||||
+ syslog(LOG_DEBUG, " Server supports CRAM-MD5 authentication");
|
||||
+ }
|
||||
+ if (features->auth.login) {
|
||||
+ syslog(LOG_DEBUG, " Server supports LOGIN authentication");
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
deliver_to_host(struct qitem *it, struct mx_hostentry *host)
|
||||
{
|
||||
struct authuser *a;
|
||||
+ struct smtp_features features;
|
||||
char line[1000];
|
||||
size_t linelen;
|
||||
int fd, error = 0, do_auth = 0, res = 0;
|
||||
@@ -389,7 +500,7 @@ deliver_to_host(struct qitem *it, struct mx_hostentry *host)
|
||||
}
|
||||
|
||||
if ((config.features & SECURETRANS) != 0) {
|
||||
- error = smtp_init_crypto(fd, config.features);
|
||||
+ error = smtp_init_crypto(fd, config.features, &features);
|
||||
if (error == 0)
|
||||
syslog(LOG_DEBUG, "SSL initialization successful");
|
||||
else
|
||||
@@ -399,10 +510,12 @@ deliver_to_host(struct qitem *it, struct mx_hostentry *host)
|
||||
READ_REMOTE_CHECK("connect", 2);
|
||||
}
|
||||
|
||||
- /* XXX allow HELO fallback */
|
||||
- /* XXX record ESMTP keywords */
|
||||
- send_remote_command(fd, "EHLO %s", hostname());
|
||||
- READ_REMOTE_CHECK("EHLO", 2);
|
||||
+ // Say EHLO
|
||||
+ if (perform_server_greeting(fd, &features) != 0) {
|
||||
+ syslog(LOG_ERR, "Could not perform server greeting at %s [%s]: %s",
|
||||
+ host->host, host->addr, neterr);
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Use SMTP authentication if the user defined an entry for the remote
|
||||
@@ -421,7 +534,7 @@ deliver_to_host(struct qitem *it, struct mx_hostentry *host)
|
||||
* encryption.
|
||||
*/
|
||||
syslog(LOG_INFO, "using SMTP authentication for user %s", a->login);
|
||||
- error = smtp_login(fd, a->login, a->password);
|
||||
+ error = smtp_login(fd, a->login, a->password, &features);
|
||||
if (error < 0) {
|
||||
syslog(LOG_ERR, "remote delivery failed:"
|
||||
" SMTP login failed: %m");
|
||||
@@ -1,26 +0,0 @@
|
||||
commit e94f50bbbe7318eec5b6b165ff73d94bbc9d20b0
|
||||
Author: Michael Tremer <michael.tremer@ipfire.org>
|
||||
Date: Sun Feb 11 11:05:43 2018 +0000
|
||||
|
||||
crypto: Don't limit to TLSv1 only
|
||||
|
||||
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
|
||||
|
||||
diff --git a/crypto.c b/crypto.c
|
||||
index 897b55bfdcfc..440c882880b5 100644
|
||||
--- a/crypto.c
|
||||
+++ b/crypto.c
|
||||
@@ -93,7 +93,12 @@ smtp_init_crypto(int fd, int feature)
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
|
||||
- meth = TLSv1_client_method();
|
||||
+ // Allow any possible version
|
||||
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
+ meth = TLS_client_method();
|
||||
+#else
|
||||
+ meth = SSLv23_client_method();
|
||||
+#endif
|
||||
|
||||
ctx = SSL_CTX_new(meth);
|
||||
if (ctx == NULL) {
|
||||
@@ -1,29 +0,0 @@
|
||||
From 60cf6f03a4b13ec0e491a282ab5233a1619a7a66 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Tremer <michael.tremer@ipfire.org>
|
||||
Date: Tue, 24 Apr 2018 12:30:13 +0100
|
||||
Subject: [PATCH] net.c: Include string.h
|
||||
|
||||
Various functions that have been used come from string.h. GCC compiled
|
||||
dma without this header, but unfortunately the binary segfaulted at random
|
||||
times.
|
||||
|
||||
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
|
||||
---
|
||||
net.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/net.c b/net.c
|
||||
index a1cc3e3bfd79..221dda131a23 100644
|
||||
--- a/net.c
|
||||
+++ b/net.c
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <netdb.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
+#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
--
|
||||
2.14.3
|
||||
|
||||
Reference in New Issue
Block a user