Dear developers,
We would like to propose a new plugin for strongSwan called dead-peer-notify.
After the last retransmit has been sent and the peer is considered dead (
plugin hooks ALERT_RETRANSMIT_SEND_TIMEOUT alert ), plugin sends an email with
notification, which contains a name and an ip address of the dead peer, or( and
) executes external command with two arguments: dead peer name and ip address.
System administrators may find it useful for configuring email alerts and
customizing other actions.
diff -Naur strongswan-5.3.5.orig/conf/Makefile.am strongswan-5.3.5/conf/Makefile.am
--- strongswan-5.3.5.orig/conf/Makefile.am 2015-08-31 17:15:51.000000000 +0300
+++ strongswan-5.3.5/conf/Makefile.am 2015-12-22 11:16:33.290852629 +0300
@@ -32,6 +32,7 @@
plugins/bliss.opt \
plugins/certexpire.opt \
plugins/coupling.opt \
+ plugins/dead-peer-notify.opt \
plugins/dhcp.opt \
plugins/dnscert.opt \
plugins/duplicheck.opt \
diff -Naur strongswan-5.3.5.orig/conf/plugins/dead-peer-notify.conf strongswan-5.3.5/conf/plugins/dead-peer-notify.conf
--- strongswan-5.3.5.orig/conf/plugins/dead-peer-notify.conf 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/conf/plugins/dead-peer-notify.conf 2015-12-22 11:16:33.295852629 +0300
@@ -0,0 +1,36 @@
+dead-peer-notify {
+
+ # Whether to load the plugin. Can also be an integer to increase the
+ # priority of this plugin.
+ load = yes
+
+ # Enable or disable sending notifications by email.
+ # send_email = no
+
+ # Sender's email address.
+ # mail_from =
+
+ # Recipient's email address.
+ # mail_to =
+
+ # Sender's SMTP user name.
+ # mail_username =
+
+ # Sender's SMTP password.
+ # mail_password =
+
+ # SMTP server url.
+ # smtp_url =
+
+ # Path to public certificate of the SMTP server.
+ # smtp_cacert =
+
+
+ # Enable or disable external command execution.
+ # run_command = no
+
+ # Path to external command.
+ # command_path =
+
+}
+
diff -Naur strongswan-5.3.5.orig/conf/plugins/dead-peer-notify.opt strongswan-5.3.5/conf/plugins/dead-peer-notify.opt
--- strongswan-5.3.5.orig/conf/plugins/dead-peer-notify.opt 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/conf/plugins/dead-peer-notify.opt 2015-12-22 11:16:33.295852629 +0300
@@ -0,0 +1,40 @@
+charon.plugins.dead-peer-notify.send_email = no
+ Enable or disable sending notifications by email.
+
+ Enable or disable sending notifications by email.
+ After the last retransmit has been sent and the peer is considered dead,
+ plugin sends an email with notification, which contains a name and an ip address of the dead peer.
+
+charon.plugins.dead-peer-notify.mail_from =
+ Sender's email address.
+
+charon.plugins.dead-peer-notify.mail_to =
+ Recipient's email address.
+
+charon.plugins.dead-peer-notify.mail_username =
+ Sender's SMTP user name.
+
+charon.plugins.dead-peer-notify.mail_password =
+ Sender's SMTP password.
+
+charon.plugins.dead-peer-notify.smtp_url =
+ SMTP server url.
+
+ SMTP server url. Format: smtp://host:port.
+ Plugin supports only SSL/TLS connections.
+ (e.g. smtp://smtp.example.com:587)
+
+charon.plugins.dead-peer-notify.smtp_cacert =
+ Path to public certificate of the SMTP server.
+ (e.g. /etc/certs/mta_ca.pem)
+
+charon.plugins.dead-peer-notify.run_command = no
+ Enable or disable external command execution.
+
+ Enable or disable external command execution.
+ After the last retransmit has been sent and the peer is considered dead,
+ plugin executes external command with two arguments: dead peer name and ip address.
+
+charon.plugins.dead-peer-notify.command_path =
+ Path to external command.
+ (e.g. /usr/local/bin/user_script.sh)
diff -Naur strongswan-5.3.5.orig/configure.ac strongswan-5.3.5/configure.ac
--- strongswan-5.3.5.orig/configure.ac 2015-11-26 12:38:10.000000000 +0300
+++ strongswan-5.3.5/configure.ac 2015-12-22 11:16:33.487852619 +0300
@@ -257,6 +257,7 @@
ARG_ENABL_SET([forecast], [enable forecast plugin forwarding broadcast/multicast messages.])
ARG_ENABL_SET([duplicheck], [advanced duplicate checking plugin using liveness checks.])
ARG_ENABL_SET([error-notify], [enable error notification plugin.])
+ARG_ENABL_SET([dead-peer-notify],[enable dead peer notification plugin.])
ARG_ENABL_SET([farp], [enable ARP faking plugin that responds to ARP requests to peers virtual IP])
ARG_ENABL_SET([ha], [enable high availability cluster plugin.])
ARG_ENABL_SET([led], [enable plugin to control LEDs on IKEv2 activity using the Linux kernel LED subsystem.])
@@ -1391,6 +1392,7 @@
ADD_PLUGIN([ext-auth], [c charon])
ADD_PLUGIN([lookip], [c charon])
ADD_PLUGIN([error-notify], [c charon])
+ADD_PLUGIN([dead-peer-notify], [c charon])
ADD_PLUGIN([certexpire], [c charon])
ADD_PLUGIN([systime-fix], [c charon])
ADD_PLUGIN([led], [c charon])
@@ -1506,6 +1508,7 @@
AM_CONDITIONAL(USE_EXT_AUTH, test x$ext_auth = xtrue)
AM_CONDITIONAL(USE_LOOKIP, test x$lookip = xtrue)
AM_CONDITIONAL(USE_ERROR_NOTIFY, test x$error_notify = xtrue)
+AM_CONDITIONAL(USE_DEAD_PEER_NOTIFY, test x$dead_peer_notify = xtrue)
AM_CONDITIONAL(USE_CERTEXPIRE, test x$certexpire = xtrue)
AM_CONDITIONAL(USE_SYSTIME_FIX, test x$systime_fix = xtrue)
AM_CONDITIONAL(USE_LED, test x$led = xtrue)
@@ -1822,6 +1825,7 @@
src/libcharon/plugins/ext_auth/Makefile
src/libcharon/plugins/lookip/Makefile
src/libcharon/plugins/error_notify/Makefile
+ src/libcharon/plugins/dead_peer_notify/Makefile
src/libcharon/plugins/certexpire/Makefile
src/libcharon/plugins/systime_fix/Makefile
src/libcharon/plugins/led/Makefile
diff -Naur strongswan-5.3.5.orig/src/libcharon/Makefile.am strongswan-5.3.5/src/libcharon/Makefile.am
--- strongswan-5.3.5.orig/src/libcharon/Makefile.am 2015-03-21 15:46:05.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/Makefile.am 2015-12-22 11:16:33.253852631 +0300
@@ -553,6 +553,13 @@
endif
endif
+if USE_DEAD_PEER_NOTIFY
+ SUBDIRS += plugins/dead_peer_notify
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/dead_peer_notify/libstrongswan-dead-peer-notify.la
+endif
+endif
+
if USE_CERTEXPIRE
SUBDIRS += plugins/certexpire
if MONOLITHIC
diff -Naur strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/Makefile.am strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/Makefile.am
--- strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/Makefile.am 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/Makefile.am 2015-12-22 11:16:33.248852631 +0300
@@ -0,0 +1,22 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-dead-peer-notify.la
+else
+plugin_LTLIBRARIES = libstrongswan-dead-peer-notify.la
+endif
+
+libstrongswan_dead_peer_notify_la_SOURCES = \
+ dead_peer_notify_plugin.h dead_peer_notify_plugin.c \
+ dead_peer_notify_listener.h dead_peer_notify_listener.c \
+ dead_peer_notify_mail.h dead_peer_notify_mail.c \
+ dead_peer_notify_exec.h dead_peer_notify_exec.c
+
+libstrongswan_dead_peer_notify_la_LDFLAGS = -module -avoid-version
+libstrongswan_dead_peer_notify_la_LIBADD = -lcurl
diff -Naur strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_exec.c strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_exec.c
--- strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_exec.c 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_exec.c 2015-12-22 11:16:33.248852631 +0300
@@ -0,0 +1,143 @@
+/* vim: set ts=4 sw=4 noexpandtab: */
+/*
+ * Copyright (C) 2015 Pavel Balaev.
+ * Copyright (C) 2015 InfoTeCS JSC.
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <daemon.h>
+#include "dead_peer_notify_exec.h"
+
+typedef struct private_dead_peer_notify_exec_t private_dead_peer_notify_exec_t;
+
+/**
+ * Private data of an dead_peer_notify_exec_t object.
+ */
+struct private_dead_peer_notify_exec_t {
+
+ /**
+ * Public dead_peer_notify_exec_t interface.
+ */
+ dead_peer_notify_exec_t public;
+
+ /**
+ * Enable/disable execute external command flag.
+ */
+ bool script_enabled;
+
+ /**
+ * External command path.
+ */
+ char *script_path;
+};
+
+METHOD(dead_peer_notify_exec_t, run, void,
+ private_dead_peer_notify_exec_t *this, const char *peer, const char *host)
+{
+ FILE *shell;
+ char command[1024];
+ int cmd_len;
+
+ memset(command, 0, sizeof(command));
+
+ if (!this->script_enabled)
+ {
+ return;
+ }
+
+ cmd_len = snprintf(command, sizeof(command), "%s '%s' '%s'",
+ this->script_path, peer, host);
+ if (cmd_len >= sizeof(command) || cmd_len < 0)
+ {
+ DBG1(DBG_LIB, "external script path was truncated due to length limitation "
+ "of %lu characters", sizeof(command));
+ DBG1(DBG_LIB, "could not execute external script");
+ return;
+ }
+ DBG2(DBG_LIB, "trying to run external script: '%s'...", command);
+
+ shell = popen(command, "r");
+ if (shell == NULL)
+ {
+ DBG1(DBG_LIB, "could not execute external script");
+ return;
+ }
+ if (pclose(shell) == -1)
+ {
+ DBG1(DBG_LIB, "pclose error: %s", strerror(errno));
+ }
+}
+
+METHOD(dead_peer_notify_exec_t, destroy, void,
+ private_dead_peer_notify_exec_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+dead_peer_notify_exec_t *dead_peer_notify_exec_create()
+{
+ private_dead_peer_notify_exec_t *this;
+ bool script_ok = true;
+ struct stat script_info;
+
+ INIT(this,
+ .public = {
+ .run = _run,
+ .destroy = _destroy,
+ },
+ );
+
+ this->script_enabled = lib->settings->get_bool(lib->settings,
+ "%s.plugins.dead-peer-notify.run_command", FALSE,
+ lib->ns);
+ if (this->script_enabled)
+ {
+ this->script_path = lib->settings->get_str(lib->settings,
+ "%s.plugins.dead-peer-notify.command_path", NULL,
+ lib->ns);
+
+ if (!this->script_path)
+ {
+ DBG1(DBG_CFG, "no exetrnal command path set");
+ script_ok = false;
+ }
+ else
+ {
+ if (stat(this->script_path, &script_info) == -1)
+ {
+ DBG1(DBG_CFG, "failed to read external command: %s", strerror(errno));
+ script_ok = false;
+ }
+ else if (!(script_info.st_mode & S_IXUSR))
+ {
+ DBG1(DBG_CFG, "script has no execute permission for owner");
+ script_ok = false;
+ }
+ }
+
+ if (!script_ok)
+ {
+ this->script_enabled = false;
+ DBG1(DBG_CFG, "execution of the external command is disabled");
+ }
+ }
+
+ return &this->public;
+}
diff -Naur strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_exec.h strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_exec.h
--- strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_exec.h 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_exec.h 2015-12-22 11:16:33.248852631 +0300
@@ -0,0 +1,51 @@
+/* vim: set ts=4 sw=4 noexpandtab: */
+/*
+ * Copyright (C) 2015 Pavel Balaev.
+ * Copyright (C) 2015 InfoTeCS JSC.
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup dead_peer_notify_exec dead_peer_notify_exec
+ * @{ @ingroup dead_peer_notify
+ */
+
+#ifndef DEAD_PEER_NOTIFY_EXEC_H_
+#define DEAD_PEER_NOTIFY_EXEC_H_
+
+typedef struct dead_peer_notify_exec_t dead_peer_notify_exec_t;
+
+/**
+ * Execute command interface.
+ */
+struct dead_peer_notify_exec_t {
+
+ /**
+ * Execute external command.
+ *
+ * @param peer peer name
+ * @param host host address
+ */
+ void (*run)(dead_peer_notify_exec_t *this, const char *peer, const char *host);
+
+ /**
+ * Destroy a dead_peer_notify_exec_t.
+ */
+ void (*destroy)(dead_peer_notify_exec_t *this);
+};
+
+/**
+ * Create a dead_peer_notify_exec instance.
+ */
+dead_peer_notify_exec_t *dead_peer_notify_exec_create();
+
+#endif /** DEAD_PEER_NOTIFY_EXEC_H_ @}*/
diff -Naur strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_listener.c strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_listener.c
--- strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_listener.c 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_listener.c 2015-12-22 11:16:33.248852631 +0300
@@ -0,0 +1,107 @@
+/* vim: set ts=4 sw=4 noexpandtab: */
+/*
+ * Copyright (C) 2015 Pavel Balaev.
+ * Copyright (C) 2015 InfoTeCS JSC.
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "dead_peer_notify_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_dead_peer_notify_listener_t private_dead_peer_notify_listener_t;
+
+/**
+ * Private data of an dead_peer_notify_listener_t object.
+ */
+struct private_dead_peer_notify_listener_t {
+
+ /**
+ * Public dead_peer_notify_listener_t interface.
+ */
+ dead_peer_notify_listener_t public;
+
+ /**
+ * Send email interface.
+ */
+ dead_peer_notify_mail_t *mail;
+
+ /**
+ * Execute external command interface.
+ */
+ dead_peer_notify_exec_t *script;
+};
+
+METHOD(listener_t, alert, bool,
+ private_dead_peer_notify_listener_t *this, ike_sa_t *ike_sa,
+ alert_t alert, va_list args)
+{
+ host_t *host;
+ peer_cfg_t *peer_cfg;
+ char host_str[64];
+
+ memset(host_str, 0, sizeof(host_str));
+
+ if (alert == ALERT_RETRANSMIT_SEND_TIMEOUT)
+ {
+ if (ike_sa)
+ {
+ peer_cfg = ike_sa->get_peer_cfg(ike_sa);
+ host = ike_sa->get_other_host(ike_sa);
+
+ if (!host->is_anyaddr(host))
+ {
+ snprintf(host_str, sizeof(host_str), "%#H", host);
+ }
+ else
+ {
+ snprintf(host_str, sizeof(host_str), "unknown");
+ }
+
+ if (peer_cfg)
+ {
+ this->mail->send_mail(this->mail, peer_cfg->get_name(peer_cfg), host_str);
+ this->script->run(this->script, peer_cfg->get_name(peer_cfg), host_str);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+METHOD(dead_peer_notify_listener_t, destroy, void,
+ private_dead_peer_notify_listener_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+dead_peer_notify_listener_t *dead_peer_notify_listener_create(dead_peer_notify_mail_t *m,
+ dead_peer_notify_exec_t *s)
+{
+ private_dead_peer_notify_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .alert = _alert,
+ },
+ .destroy = _destroy,
+ },
+ .mail = m,
+ .script = s,
+ );
+
+ return &this->public;
+}
diff -Naur strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_listener.h strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_listener.h
--- strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_listener.h 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_listener.h 2015-12-22 11:16:33.248852631 +0300
@@ -0,0 +1,53 @@
+/* vim: set ts=4 sw=4 noexpandtab: */
+/*
+ * Copyright (C) 2015 Pavel Balaev.
+ * Copyright (C) 2015 InfoTeCS JSC.
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup dead_peer_notify_listener dead_peer_notify_listener
+ * @{ @ingroup dead_peer_notify
+ */
+
+#ifndef DEAD_PEER_NOTIFY_LISTENER_H_
+#define DEAD_PEER_NOTIFY_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+#include "dead_peer_notify_mail.h"
+#include "dead_peer_notify_exec.h"
+
+typedef struct dead_peer_notify_listener_t dead_peer_notify_listener_t;
+
+/**
+ * Listener catching bus alerts.
+ */
+struct dead_peer_notify_listener_t {
+
+ /**
+ * Implements listener_t interface.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a dead_peer_notify_listener_t.
+ */
+ void (*destroy)(dead_peer_notify_listener_t *this);
+};
+
+/**
+ * Create a dead_peer_notify_listener instance.
+ */
+dead_peer_notify_listener_t *dead_peer_notify_listener_create(dead_peer_notify_mail_t *m,
+ dead_peer_notify_exec_t *s);
+
+#endif /** DEAD_PEER_NOTIFY_LISTENER_H_ @}*/
diff -Naur strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_mail.c strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_mail.c
--- strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_mail.c 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_mail.c 2015-12-22 11:16:33.248852631 +0300
@@ -0,0 +1,277 @@
+/* vim: set ts=4 sw=4 noexpandtab: */
+/*
+ * Copyright (C) 2015 Pavel Balaev.
+ * Copyright (C) 2015 InfoTeCS JSC.
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <curl/curl.h>
+
+#include <daemon.h>
+#include "dead_peer_notify_mail.h"
+
+#define CONNECT_TIMEOUT 10
+
+typedef struct private_dead_peer_notify_mail_t private_dead_peer_notify_mail_t;
+
+/**
+ * Private data of an dead_peer_notify_mail_t object.
+ */
+struct private_dead_peer_notify_mail_t {
+
+ /**
+ * Public dead_peer_notify_mail_t interface.
+ */
+ dead_peer_notify_mail_t public;
+
+ /**
+ * CURL handle
+ */
+ CURL* curl;
+
+ /**
+ * Enable/disable email reports flag
+ */
+ bool email_enabled;
+
+ /**
+ * Sender email address
+ */
+ char *mail_from;
+
+ /**
+ * Recipient email address
+ */
+ char *mail_to;
+
+ /**
+ * MTA url
+ */
+ char *smtp_url;
+
+ /**
+ * MTA CA certificate path
+ */
+ char *cacert_path;
+
+ /**
+ * Sender email user name
+ */
+ char *mail_user;
+
+ /**
+ * Sender email user password
+ */
+ char *mail_passwd;
+};
+
+/**
+ * Data to pass to curl callback
+ */
+typedef struct {
+ char *payload;
+ int len;
+ bool done;
+} cb_data_t;
+
+/**
+ * Curl callback function
+ */
+static size_t curl_cb(void *ptr, size_t size, size_t nmemb, cb_data_t *data)
+{
+ cb_data_t *mail = (cb_data_t *) data;
+
+ if (mail->len > size * nmemb || mail->len == 0)
+ {
+ return 0;
+ }
+
+ if (!mail->done)
+ {
+ memcpy(ptr, mail->payload, mail->len);
+ mail->done = true;
+ return mail->len;
+ }
+
+ return 0;
+}
+
+METHOD(dead_peer_notify_mail_t, send_mail, void,
+ private_dead_peer_notify_mail_t *this, const char *peer, const char *host)
+{
+ CURLcode res = CURLE_OK;
+ char error[CURL_ERROR_SIZE];
+ struct curl_slist *recipients = NULL;
+ char mail_payload[BUFSIZ];
+ cb_data_t data;
+ time_t time_raw;
+
+ if (!this->email_enabled)
+ {
+ return;
+ }
+
+ if (this->curl)
+ {
+ time(&time_raw);
+ memset(mail_payload, 0, sizeof(mail_payload));
+ data.len = snprintf(mail_payload, sizeof(mail_payload),
+ "%s<%s>\r\n%s<%s>\r\n%s\r\n\r\n%s (%s)%s%s\r\n\r\n%s\r\n",
+ "To: ", this->mail_to, "From: ", this->mail_from,
+ MAIL_SUBJ, peer, host, MAIL_BODY, ctime(&time_raw), MAIL_SIGN);
+
+ if (data.len < 0)
+ {
+ data.len = 0;
+ data.payload = 0;
+ }
+ else
+ {
+ data.payload = mail_payload;
+ }
+ data.done = false;
+
+ curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, error);
+ curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, FALSE);
+ curl_easy_setopt(this->curl, CURLOPT_USERNAME, this->mail_user);
+ curl_easy_setopt(this->curl, CURLOPT_PASSWORD, this->mail_passwd);
+ curl_easy_setopt(this->curl, CURLOPT_URL, this->smtp_url);
+ curl_easy_setopt(this->curl, CURLOPT_USE_SSL, (long) CURLUSESSL_ALL);
+ curl_easy_setopt(this->curl, CURLOPT_CAINFO, this->cacert_path);
+ curl_easy_setopt(this->curl, CURLOPT_MAIL_FROM, this->mail_from);
+ recipients = curl_slist_append(recipients, this->mail_to);
+ curl_easy_setopt(this->curl, CURLOPT_MAIL_RCPT, recipients);
+ curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, CONNECT_TIMEOUT);
+ curl_easy_setopt(this->curl, CURLOPT_READFUNCTION, (void *) curl_cb);
+ curl_easy_setopt(this->curl, CURLOPT_READDATA, &data);
+ curl_easy_setopt(this->curl, CURLOPT_UPLOAD, 1L);
+
+ DBG2(DBG_LIB, "trying to send email via '%s'...", this->smtp_url);
+ res = curl_easy_perform(this->curl);
+
+ if (res != CURLE_OK)
+ {
+ DBG1(DBG_LIB, "libcurl email send failed [%d]: %s", res, error);
+ }
+
+ curl_slist_free_all(recipients);
+ }
+}
+
+METHOD(dead_peer_notify_mail_t, destroy, void,
+ private_dead_peer_notify_mail_t *this)
+{
+ curl_easy_cleanup(this->curl);
+ free(this);
+}
+
+/**
+ * See header
+ */
+dead_peer_notify_mail_t *dead_peer_notify_mail_create()
+{
+ private_dead_peer_notify_mail_t *this;
+ bool email_ok = true;
+ struct stat cert_info;
+
+ INIT(this,
+ .public = {
+ .send_mail = _send_mail,
+ .destroy = _destroy,
+ },
+ .curl = curl_easy_init(),
+ );
+
+ this->email_enabled = lib->settings->get_bool(lib->settings,
+ "%s.plugins.dead-peer-notify.send_email", FALSE,
+ lib->ns);
+ if (this->email_enabled)
+ {
+ this->mail_from = lib->settings->get_str(lib->settings,
+ "%s.plugins.dead-peer-notify.mail_from", NULL,
+ lib->ns);
+ this->mail_to = lib->settings->get_str(lib->settings,
+ "%s.plugins.dead-peer-notify.mail_to", NULL,
+ lib->ns);
+ this->smtp_url = lib->settings->get_str(lib->settings,
+ "%s.plugins.dead-peer-notify.smtp_url", NULL,
+ lib->ns);
+ this->cacert_path = lib->settings->get_str(lib->settings,
+ "%s.plugins.dead-peer-notify.smtp_cacert", NULL,
+ lib->ns);
+ this->mail_user = lib->settings->get_str(lib->settings,
+ "%s.plugins.dead-peer-notify.mail_username", NULL,
+ lib->ns);
+ this->mail_passwd = lib->settings->get_str(lib->settings,
+ "%s.plugins.dead-peer-notify.mail_password", NULL,
+ lib->ns);
+ if (!this->mail_from)
+ {
+ DBG1(DBG_CFG, "no sender email address set");
+ email_ok = false;
+ }
+ if (!this->mail_to)
+ {
+ DBG1(DBG_CFG, "no recipient email address set");
+ email_ok = false;
+ }
+ if (!this->smtp_url)
+ {
+ DBG1(DBG_CFG, "no MTA url address set");
+ email_ok = false;
+ }
+ else
+ {
+ if (!strstr(this->smtp_url, "smtp://"))
+ {
+ DBG1(DBG_CFG, "invalid MTA url address format");
+ email_ok = false;
+ }
+ }
+ if (!this->cacert_path)
+ {
+ DBG1(DBG_CFG, "no MTA CA certificate path set");
+ email_ok = false;
+ }
+ else
+ {
+ if (stat(this->cacert_path, &cert_info) == -1)
+ {
+ DBG1(DBG_CFG, "error read MTA CA certificate: %s", strerror(errno));
+ email_ok = false;
+ }
+ }
+ if (!this->mail_user)
+ {
+ DBG1(DBG_CFG, "no sender email username set");
+ email_ok = false;
+ }
+ if (!this->mail_passwd)
+ {
+ DBG1(DBG_CFG, "no sender email password set");
+ email_ok = false;
+ }
+
+ if (!email_ok)
+ {
+ this->email_enabled = false;
+ DBG1(DBG_CFG, "email reports disabled");
+ }
+ }
+
+ return &this->public;
+}
diff -Naur strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_mail.h strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_mail.h
--- strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_mail.h 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_mail.h 2015-12-22 11:16:33.248852631 +0300
@@ -0,0 +1,55 @@
+/* vim: set ts=4 sw=4 noexpandtab: */
+/*
+ * Copyright (C) 2015 Pavel Balaev.
+ * Copyright (C) 2015 InfoTeCS JSC.
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup dead_peer_notify_mail dead_peer_notify_mail
+ * @{ @ingroup dead_peer_notify
+ */
+
+#ifndef DEAD_PEER_NOTIFY_MAIL_H_
+#define DEAD_PEER_NOTIFY_MAIL_H_
+
+#define MAIL_SUBJ "Subject: strongSwan notification"
+#define MAIL_BODY " shut down at "
+#define MAIL_SIGN "This message was sent by dead-peer-notify plugin"
+
+typedef struct dead_peer_notify_mail_t dead_peer_notify_mail_t;
+
+/**
+ * Send email interface.
+ */
+struct dead_peer_notify_mail_t {
+
+ /**
+ * Send a notification email.
+ *
+ * @param peer peer name
+ * @param host host address
+ */
+ void (*send_mail)(dead_peer_notify_mail_t *this, const char *peer, const char *host);
+
+ /**
+ * Destroy a dead_peer_notify_mail_t.
+ */
+ void (*destroy)(dead_peer_notify_mail_t *this);
+};
+
+/**
+ * Create a dead_peer_notify_mail instance.
+ */
+dead_peer_notify_mail_t *dead_peer_notify_mail_create();
+
+#endif /** DEAD_PEER_NOTIFY_MAIL_H_ @}*/
diff -Naur strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_plugin.c strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_plugin.c
--- strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_plugin.c 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_plugin.c 2015-12-22 11:16:33.248852631 +0300
@@ -0,0 +1,116 @@
+/* vim: set ts=4 sw=4 noexpandtab: */
+/*
+ * Copyright (C) 2015 Pavel Balaev.
+ * Copyright (C) 2015 InfoTeCS JSC.
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "dead_peer_notify_plugin.h"
+#include "dead_peer_notify_listener.h"
+#include "dead_peer_notify_mail.h"
+
+#include <daemon.h>
+
+typedef struct private_dead_peer_notify_plugin_t private_dead_peer_notify_plugin_t;
+
+/**
+ * private data of dead_peer_notify plugin
+ */
+struct private_dead_peer_notify_plugin_t {
+
+ /**
+ * Implements plugin interface
+ */
+ dead_peer_notify_plugin_t public;
+
+ /**
+ * Listener catching error alerts
+ */
+ dead_peer_notify_listener_t *listener;
+
+ /**
+ * Email send instance
+ */
+ dead_peer_notify_mail_t *mail;
+
+ /**
+ * External command instance
+ */
+ dead_peer_notify_exec_t *script;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_dead_peer_notify_plugin_t *this)
+{
+ return "dead-peer-notify";
+}
+
+/**
+ * Register listener
+ */
+static bool plugin_cb(private_dead_peer_notify_plugin_t *this,
+ plugin_feature_t *feature, bool reg, void *cb_data)
+{
+ if (reg)
+ {
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+ }
+ else
+ {
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ }
+ return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_dead_peer_notify_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "dead-peer-notify"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_dead_peer_notify_plugin_t *this)
+{
+ this->listener->destroy(this->listener);
+ this->mail->destroy(this->mail);
+ this->script->destroy(this->script);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *dead_peer_notify_plugin_create()
+{
+ private_dead_peer_notify_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ .mail = dead_peer_notify_mail_create(),
+ .script = dead_peer_notify_exec_create(),
+ );
+
+ this->listener = dead_peer_notify_listener_create(this->mail, this->script);
+
+ return &this->public.plugin;
+}
diff -Naur strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_plugin.h strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_plugin.h
--- strongswan-5.3.5.orig/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_plugin.h 1970-01-01 03:00:00.000000000 +0300
+++ strongswan-5.3.5/src/libcharon/plugins/dead_peer_notify/dead_peer_notify_plugin.h 2015-12-22 11:16:33.248852631 +0300
@@ -0,0 +1,43 @@
+/* vim: set ts=4 sw=4 noexpandtab: */
+/*
+ * Copyright (C) 2015 Pavel Balaev.
+ * Copyright (C) 2015 InfoTeCS JSC.
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup dead_peer_notify dead_peer_notify
+ * @ingroup cplugins
+ *
+ * @defgroup dead_peer_notify_plugin dead_peer_notify_plugin
+ * @{ @ingroup dead_peer_notify
+ */
+
+#ifndef DEAD_PEER_NOTIFY_PLUGIN_H_
+#define DEAD_PEER_NOTIFY_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct dead_peer_notify_plugin_t dead_peer_notify_plugin_t;
+
+/**
+ * Plugin sending error notifications over a UNIX socket.
+ */
+struct dead_peer_notify_plugin_t {
+
+ /**
+ * Implements plugin interface.
+ */
+ plugin_t plugin;
+};
+
+#endif /** DEAD_PEER_NOTIFY_PLUGIN_H_ @}*/
_______________________________________________
Dev mailing list
[email protected]
https://lists.strongswan.org/mailman/listinfo/dev