I was rewrite this feature as plugin using your recommendations.

Info about plugin:

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.?


> For now,
> strongSwan supports some dpd actions such as 'clear', 'hold' and
> 'restart'. The patch implements new dpdaction named 'script'. It means
> that if no activity is detected, strongSwan executes external command
> with the dead peer passed as the argument for the command.

>>  I don't agree with this approach.  The actions are things to do with a
>> particular CHILD_SA/policy not unrelated things like calling a script to
>> email notifications.  Instead, I propose you write a plugin that hooks
>> the ALERT_RETRANSMIT_SEND_TIMEOUT alert to get notified after the last
>> retransmit has been sent and the peer is considered dead.  The plugin is
>> then free to do whatever it likes (e.g. calling a script).

>> Regards,
>> Tobias



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	2016-02-16 14:53:18.687943320 +0300
+++ strongswan-5.3.5/conf/Makefile.am	2016-02-16 14:56:51.266932642 +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	2016-02-16 14:56:51.266932642 +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	2016-02-16 14:56:51.266932642 +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	2016-02-16 14:53:18.686943320 +0300
+++ strongswan-5.3.5/configure.ac	2016-02-16 15:02:12.613916500 +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.])
@@ -908,6 +909,11 @@
 	AC_CHECK_HEADER([curl/curl.h],,[AC_MSG_ERROR([CURL header curl/curl.h not found!])])
 fi
 
+if test x$dead_peer_notify = xtrue; then
+	AC_CHECK_LIB([curl],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([CURL library curl not found])],[])
+	AC_CHECK_HEADER([curl/curl.h],,[AC_MSG_ERROR([CURL header curl/curl.h not found!])])
+fi
+
 if test x$unbound = xtrue; then
 	AC_HAVE_LIBRARY([ldns],[LIBS="$LIBS"],[AC_MSG_ERROR([UNBOUND library ldns not found])])
 	AC_CHECK_HEADER([ldns/ldns.h],,[AC_MSG_ERROR([UNBOUND header ldns/ldns.h not found!])])
@@ -1391,6 +1397,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 +1513,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 +1830,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	2016-02-16 14:53:18.645943322 +0300
+++ strongswan-5.3.5/src/libcharon/Makefile.am	2016-02-16 14:56:51.267932642 +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	2016-02-16 14:56:51.267932642 +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	2016-02-16 14:56:51.267932642 +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	2016-02-16 14:56:51.267932642 +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	2016-02-16 14:56:51.267932642 +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	2016-02-16 14:56:51.267932642 +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	2016-02-16 14:56:51.267932642 +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	2016-02-16 14:56:51.268932642 +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	2016-02-16 14:56:51.268932642 +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	2016-02-16 14:56:51.268932642 +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
Dev@lists.strongswan.org
https://lists.strongswan.org/mailman/listinfo/dev

Reply via email to