diff --git a/etc/templates/en/messages.txt b/etc/templates/en/messages.txt
index 726e027fc..b21af367c 100755
--- a/etc/templates/en/messages.txt
+++ b/etc/templates/en/messages.txt
@@ -41,6 +41,15 @@ yoursmtp="We found your SMTP server as"
usesmtp="Do you want to use it?"
usingsmtp="Using SMTP server: "
whatsmtp="What's your SMTP server ip/host?"
+useauthsmtp="Want to use authenticated SMTP?"
+
+noauthsmtp="SMTP authenticated not enabled"
+yesauthsmtp="SMTP authenticated enabled"
+userauthsmtp="Please, enter your SMTP username"
+passauthsmtp="Please, enter your SMTP password"
+usesecuresmtp="This server requires a secure connection (SSL)?"
+nosecuresmtp="SMTP with SSL disabled"
+yessecuresmtp="SMTP with SSL enabled"
# Part 3.1/agent
serveraddr="What's the IP Address or hostname of the OSSEC HIDS server?"
diff --git a/install.sh b/install.sh
index 32920ebf4..1e662818d 100755
--- a/install.sh
+++ b/install.sh
@@ -19,7 +19,6 @@
### Looking up for the execution directory
cd `dirname $0`
-
### Looking for echo -n
ECHO="echo -n"
hs=`echo -n "a"`
@@ -130,6 +129,8 @@ Install()
chmod 600 ${OSSEC_INIT}
cp -pr ${OSSEC_INIT} ${INSTALLDIR}${OSSEC_INIT}
chmod 640 ${INSTALLDIR}${OSSEC_INIT}
+ mkdir ${INSTALLDIR}/lib
+ cp -R /lib/* ${INSTALLDIR}/lib
# If update_rules is set, we need to tweak
@@ -241,7 +242,104 @@ UseRootcheck()
fi
}
+###############
+# UseSecureSMTP()
+###############
+UseSecureSMTP()
+{
+
+ # SMTP Authenticaction configuration (SSL)
+ echo ""
+ $ECHO " ${usesecuresmtp} ($yes/$no) [$yes]: "
+
+ if [ "X${USER_ENABLE_SECURESMTP}" = "X" ]; then
+ read ESS
+ else
+ ESS=${USER_ENABLE_SECURESMTP}
+ fi
+
+ echo ""
+ case $ESS in
+ $nomatch)
+ echo " - ${nosecuresmtp}."
+ ;;
+ *)
+ SECURESMTP="yes"
+ echo " - ${yessecuresmtp}."
+ ;;
+ esac
+
+ # Adding to the config file
+ if [ "X${SECURESMTP}" = "Xyes" ]; then
+ echo "" >> $NEWCONFIG
+ echo " yes" >> $NEWCONFIG
+ echo "" >> $NEWCONFIG
+ else
+ echo "" >> $NEWCONFIG
+ echo " no" >> $NEWCONFIG
+ echo "" >> $NEWCONFIG
+ fi
+}
+
+
+###############
+# UseAuthSMTP()
+###############
+UseAuthSMTP()
+{
+
+ # SMTP Authenticaction configuration
+ echo ""
+ $ECHO " ${useauthsmtp} ($yes/$no) [$yes]: "
+
+ if [ "X${USER_ENABLE_AUTHSMTP}" = "X" ]; then
+ read EAS
+ else
+ EAS=${USER_ENABLE_AUTHSMTP}
+ fi
+
+ echo ""
+ case $EAS in
+ $nomatch)
+ echo " - ${noauthsmtp}."
+ ;;
+ *)
+ AUTHSMTP="yes"
+ echo " - ${yesauthsmtp}."
+ ;;
+ esac
+
+ if [ "X${AUTHSMTP}" = "Xyes" ]; then
+ if [ "X${AUTHSMTP_USER}" = "X" ]; then
+ echo ""
+ $ECHO " ${userauthsmtp}: "
+ read AUTHSMTP_USER
+ fi
+
+ if [ "X${AUTHSMTP_PASS}" = "X" ]; then
+ echo ""
+ $ECHO " ${passauthsmtp}: "
+ stty -echo # turn off terminal echo to prevent peeping!
+ read AUTHSMTP_PASS
+ stty echo # turn on
+ echo ""
+ fi
+ fi
+ # Adding to the config file
+ if [ "X${AUTHSMTP}" = "Xyes" ]; then
+ echo "" >> $NEWCONFIG
+ echo " yes" >> $NEWCONFIG
+ echo " $AUTHSMTP_USER" >> $NEWCONFIG
+ echo " $AUTHSMTP_PASS" >> $NEWCONFIG
+ echo "" >> $NEWCONFIG
+ UseSecureSMTP
+ else
+ echo "" >> $NEWCONFIG
+ echo " no" >> $NEWCONFIG
+ echo "" >> $NEWCONFIG
+ fi
+}
##########
@@ -552,6 +650,8 @@ ConfigureServer()
echo " no" >> $NEWCONFIG
fi
+ UseAuthSMTP
+
echo " " >> $NEWCONFIG
echo "" >> $NEWCONFIG
@@ -817,6 +917,9 @@ checkDependencies()
PATH=$OLDOPATH
export PATH
+
+ # Re-export sendmail_curl if curl support should be compiled in
+ export SENDMAIL_CURL
}
##########
diff --git a/src/Makefile b/src/Makefile
index 3d3fa925b..788bbe915 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -51,6 +51,11 @@ endif
OSSEC_LDFLAGS=${LDFLAGS} -lm
+ifeq (${SENDMAIL_CURL},yes)
+ DEFINES +=-DSENDMAIL_CURL=\"1\"
+ OSSEC_LDFLAGS+=-lcurl
+endif
+
ifneq (${TARGET},winagent)
ifeq (${uname_S},Linux)
DEFINES+=-DINOTIFY_ENABLED
diff --git a/src/config/global-config.c b/src/config/global-config.c
index 345943a79..ad59c6feb 100644
--- a/src/config/global-config.c
+++ b/src/config/global-config.c
@@ -121,6 +121,11 @@ int Read_Global(XML_NODE node, void *configp, void *mailp)
const char *xml_heloserver = "helo_server";
const char *xml_mailmaxperhour = "email_maxperhour";
+ const char *xml_auth_smtp = "auth_smtp";
+ const char *xml_smtp_user = "smtp_user";
+ const char *xml_smtp_pass = "smtp_password";
+ const char *xml_secure_smtp = "secure_smtp";
+
#ifdef LIBGEOIP_ENABLED
const char *xml_geoip_db_path = "geoip_db_path";
const char *xml_geoip6_db_path = "geoip6_db_path";
@@ -201,6 +206,42 @@ int Read_Global(XML_NODE node, void *configp, void *mailp)
return (OS_INVALID);
}
}
+ /* SMTP Authentication */
+ else if(strcmp(node[i]->element, xml_auth_smtp) == 0)
+ {
+ if (strcmp(node[i]->content, "yes") == 0)
+ {
+ if (Config) Config->authsmtp = 1;
+ if (Mail) Mail->authsmtp = 1;
+ }
+ else if(strcmp(node[i]->content, "no") == 0)
+ {
+ if (Config) Config->authsmtp = 0;
+ if (Mail) Mail->authsmtp = 0;
+ }
+ else
+ {
+ return(OS_INVALID);
+ }
+ }
+ /* Secure SMTP (SSL) */
+ else if(strcmp(node[i]->element, xml_secure_smtp) == 0)
+ {
+ if (strcmp(node[i]->content, "yes") == 0)
+ {
+ if (Config) Config->securesmtp = 1;
+ if (Mail) Mail->securesmtp = 1;
+ }
+ else if(strcmp(node[i]->content, "no") == 0)
+ {
+ if (Config) Config->securesmtp = 0;
+ if (Mail) Mail->securesmtp = 0;
+ }
+ else
+ {
+ return(OS_INVALID);
+ }
+ }
/* Prelude support */
else if (strcmp(node[i]->element, xml_prelude) == 0) {
if (strcmp(node[i]->content, "yes") == 0) {
@@ -445,17 +486,39 @@ int Read_Global(XML_NODE node, void *configp, void *mailp)
}
os_strdup(node[i]->content, Mail->idsname);
}
+ } else if(strcmp(node[i]->element, xml_smtp_user) == 0) {
+ if(Mail && (Mail->authsmtp))
+ {
+ if(Mail->smtp_user)
+ {
+ free(Mail->smtp_user);
+ }
+ os_strdup(node[i]->content, Mail->smtp_user);
+ }
+ } else if(strcmp(node[i]->element, xml_smtp_pass) == 0) {
+ if(Mail && (Mail->authsmtp))
+ {
+ if(Mail->smtp_pass)
+ {
+ free(Mail->smtp_pass);
+ }
+ os_strdup(node[i]->content, Mail->smtp_pass);
+ }
} else if (strcmp(node[i]->element, xml_smtpserver) == 0) {
#ifndef WIN32
if (Mail && (Mail->mn)) {
if (node[i]->content[0] == '/') {
os_strdup(node[i]->content, Mail->smtpserver);
} else {
+#ifdef SENDMAIL_CURL
+ os_strdup(node[i]->content, Mail->smtpserver);
+#else
Mail->smtpserver = OS_GetHost(node[i]->content, 5);
if (!Mail->smtpserver) {
merror(INVALID_SMTP, __local_name, node[i]->content);
return (OS_INVALID);
}
+#endif
}
free(Mail->smtpserver);
os_strdup(node[i]->content, Mail->smtpserver);
diff --git a/src/config/global-config.h b/src/config/global-config.h
index 61a93cac1..1499d4469 100644
--- a/src/config/global-config.h
+++ b/src/config/global-config.h
@@ -50,6 +50,10 @@ typedef struct __Config {
/* Mail alerting */
short int mailnotify;
+ /* Mail smtp auth */
+ short int authsmtp;
+ short int securesmtp;
+
/* Custom Alert output*/
short int custom_alert_output;
char *custom_alert_output_format;
diff --git a/src/config/mail-config.h b/src/config/mail-config.h
index f6864dc2e..f548c7f00 100644
--- a/src/config/mail-config.h
+++ b/src/config/mail-config.h
@@ -27,6 +27,12 @@ typedef struct _MailConfig {
char *smtpserver;
char *heloserver;
+ /* auth smtp options */
+ int authsmtp;
+ char *smtp_user;
+ char *smtp_pass;
+ int securesmtp;
+
/* Granular e-mail options */
unsigned int *gran_level;
unsigned int **gran_id;
diff --git a/src/monitord/main.c b/src/monitord/main.c
index fdf18e684..d7bb46398 100644
--- a/src/monitord/main.c
+++ b/src/monitord/main.c
@@ -145,6 +145,7 @@ int main(int argc, char **argv)
mond.emailidsname = OS_GetOneContentforElement(&xml, xml_idsname);
if (tmpsmtp && mond.emailfrom) {
+#ifndef SENDMAIL_CURL
mond.smtpserver = OS_GetHost(tmpsmtp, 5);
if (!mond.smtpserver) {
merror(INVALID_SMTP, ARGV0, tmpsmtp);
@@ -154,6 +155,7 @@ int main(int argc, char **argv)
mond.emailfrom = NULL;
merror("%s: Invalid SMTP server. Disabling email reports.", ARGV0);
}
+#endif
} else {
if (tmpsmtp) {
free(tmpsmtp);
diff --git a/src/os_maild/config.c b/src/os_maild/config.c
index 13f2f2f6f..b299e26be 100644
--- a/src/os_maild/config.c
+++ b/src/os_maild/config.c
@@ -37,6 +37,11 @@ int MailConf(int test_config, const char *cfgfile, MailConfig *Mail)
Mail->gran_format = NULL;
Mail->groupping = 1;
Mail->strict_checking = 0;
+ Mail->authsmtp = -1;
+ Mail->smtp_user = NULL;
+ Mail->smtp_pass = NULL;
+ Mail->securesmtp = 0;
+
#ifdef LIBGEOIP_ENABLED
Mail->geoip = 0;
#endif
diff --git a/src/os_maild/curlmail.c b/src/os_maild/curlmail.c
new file mode 100644
index 000000000..67d3bdad8
--- /dev/null
+++ b/src/os_maild/curlmail.c
@@ -0,0 +1,122 @@
+/* Sendmail implementation using curl instead of writing it ourselves.
+ * Useful for sending SMTP traffic over authenticated hosts.
+ *
+ */
+
+#ifdef SENDMAIL_CURL
+#include
+#include "maild.h"
+#include "mail_list.h"
+
+struct upload_status {
+ int lines_read;
+};
+
+static char *payload_text[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp) {
+ struct upload_status *upload_ctx = (struct upload_status *)userp;
+ const char *data;
+
+ if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
+ return 0;
+ }
+
+ data = payload_text[upload_ctx->lines_read];
+
+ if(data) {
+ size_t len = strlen(data);
+ memcpy(ptr, data, len);
+ upload_ctx->lines_read++;
+
+ return len;
+ }
+
+ return 0;
+}
+
+int OS_Sendsms(MailConfig *mail, struct tm *p, MailMsg *msg) {
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+ struct curl_slist *recipients = NULL;
+ struct upload_status upload_ctx;
+
+ char hostname[1024];
+ gethostname(hostname, 1024);
+
+ char *messageId = NULL;
+ int i = 0;
+
+ for(i = 0; i<5; i++) {
+ if(!payload_text[i]) {
+ payload_text[i] = (char*)malloc(128);
+ }
+ }
+
+ strftime(payload_text[0], 127, "Date: %a, %d %b %Y %T %z\r\n", p);
+ sprintf(payload_text[1], "To: %s \r\n", mail->to[0]);
+ sprintf(payload_text[2], "From: %s \r\n", mail->from);
+ strftime(messageId, 127, "%a%d%b%Y%T%z", p);
+ sprintf(payload_text[3], "Message-ID: <%s@%s> \r\n", messageId, hostname);
+ sprintf(payload_text[4], "Subject: %s \r\n\r\n", msg->subject);
+
+ payload_text[5] = msg->body;
+
+ payload_text[6] = NULL;
+
+ upload_ctx.lines_read = 0;
+ curl = curl_easy_init();
+
+ if(curl) {
+ char errbuf[CURL_ERROR_SIZE];
+ errbuf[0] = 0;
+ fprintf(stderr, "curl_easy_setopt() URL: %s\n", mail->smtpserver);
+ curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/ssl/certs/cacert.pem");
+ curl_easy_setopt(curl, CURLOPT_URL, mail->smtpserver);
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
+ curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ if(mail->authsmtp) {
+ curl_easy_setopt(curl, CURLOPT_USERNAME, mail->smtp_user);
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, mail->smtp_pass);
+ }
+
+ if(mail->securesmtp) {
+ curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_TRY);
+ }
+
+ curl_easy_setopt(curl, CURLOPT_MAIL_FROM, mail->from);
+ recipients = curl_slist_append(recipients, mail->to[0]);
+
+ curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
+
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
+ curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+
+ res = curl_easy_perform(curl);
+
+ if(res != CURLE_OK) {
+ fprintf(stderr, "curl_easy_perform() failed: %s (%s)\n", curl_easy_strerror(res), errbuf);
+ }
+
+ curl_slist_free_all(recipients);
+
+ curl_easy_cleanup(curl);
+ }
+
+ return (int)res;
+}
+
+int OS_Sendmail(MailConfig *mail, struct tm *p) {
+ MailNode *mailmsg;
+ while((mailmsg = OS_PopLastMail()) != NULL) {
+ OS_Sendsms(mail, p, mailmsg->mail);
+ FreeMail(mailmsg);
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/src/os_maild/sendmail.c b/src/os_maild/sendmail.c
index f793c24d4..db1cd7884 100644
--- a/src/os_maild/sendmail.c
+++ b/src/os_maild/sendmail.c
@@ -9,6 +9,7 @@
/* Basic e-mailing operations */
+#ifndef SENDMAIL_CURL
#include "shared.h"
#include "os_net/os_net.h"
#include "maild.h"
@@ -623,3 +624,5 @@ int OS_Sendmail(MailConfig *mail, struct tm *p)
memset_secure(snd_msg, '\0', 128);
return (0);
}
+#endif
+