[network-manager-openswan/dcbw/cleanups: 17/17] core: rework connect process and subprocess handling
- From: Dan Williams <dcbw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openswan/dcbw/cleanups: 17/17] core: rework connect process and subprocess handling
- Date: Thu, 7 Aug 2014 22:52:37 +0000 (UTC)
commit 09e8be26a2b0050b5b01e214aff8650d306a968a
Author: Dan Williams <dcbw redhat com>
Date: Thu Aug 7 17:50:42 2014 -0500
core: rework connect process and subprocess handling
src/Makefile.am | 7 +-
src/nm-openswan-service.c | 563 +++++++++++++++++++++++++++++++++------------
2 files changed, 419 insertions(+), 151 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 9ee7f06..9029570 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,9 +22,10 @@ nm_openswan_service_SOURCES = \
nm-openswan-service.h
nm_openswan_service_LDADD = \
- $(DBUS_LIBS) \
- $(GLIB_LIBS) \
- $(NM_LIBS)
+ $(DBUS_LIBS) \
+ $(GLIB_LIBS) \
+ $(NM_LIBS) \
+ -lutil
nm_openswan_service_helper_SOURCES = \
nm-openswan-service-helper.c
diff --git a/src/nm-openswan-service.c b/src/nm-openswan-service.c
index ecba977..edb9c48 100644
--- a/src/nm-openswan-service.c
+++ b/src/nm-openswan-service.c
@@ -30,6 +30,7 @@
#include <errno.h>
#include <locale.h>
#include <stdarg.h>
+#include <pty.h>
#include <glib/gi18n.h>
@@ -48,15 +49,41 @@ GMainLoop *loop = NULL;
G_DEFINE_TYPE (NMOPENSWANPlugin, nm_openswan_plugin, NM_TYPE_VPN_PLUGIN)
+typedef enum {
+ CONNECT_STEP_FIRST,
+ CONNECT_STEP_IPSEC_START,
+ CONNECT_STEP_CONFIG_ADD,
+ CONNECT_STEP_CONNECT,
+ CONNECT_STEP_LAST
+} ConnectStep;
+
typedef struct {
- GPid pid;
+ const char *ipsec_path;
char *secrets_path;
+
+ GPid pid;
+ guint watch_id;
+ ConnectStep connect_step;
+ NMConnection *connection;
+
+ GIOChannel *channel;
+ guint io_id;
+ char *password;
} NMOPENSWANPluginPrivate;
#define NM_OPENSWAN_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_OPENSWAN_PLUGIN,
NMOPENSWANPluginPrivate))
#define NM_OPENSWAN_HELPER_PATH LIBEXECDIR"/nm-openswan-service-helper"
+#define DEBUG(...) \
+ G_STMT_START { \
+ if (debug) { \
+ g_message (__VA_ARGS__); \
+ } \
+ } G_STMT_END
+
+/****************************************************************/
+
typedef struct {
const char *name;
GType type;
@@ -199,6 +226,8 @@ nm_openswan_secrets_validate (NMSettingVPN *s_vpn, GError **error)
/****************************************************************/
+static gboolean connect_step (NMOPENSWANPlugin *self, GError **error);
+
static const char *ipsec_paths[] =
{
"/usr/sbin/ipsec",
@@ -225,54 +254,127 @@ find_ipsec (GError **error)
}
static void
+connect_cleanup (NMOPENSWANPlugin *self)
+{
+ NMOPENSWANPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (self);
+
+ priv->connect_step = CONNECT_STEP_FIRST;
+
+ /* Don't remove the child watch since it needs to reap the child */
+ priv->watch_id = 0;
+
+ if (priv->pid) {
+ kill (priv->pid, SIGTERM);
+ priv->pid = 0;
+ }
+
+ if (priv->io_id) {
+ g_source_remove (priv->io_id);
+ priv->io_id = 0;
+ }
+ g_clear_pointer (&priv->channel, g_io_channel_unref);
+
+ if (priv->password) {
+ memset (priv->password, 0, strlen (priv->password));
+ g_free (priv->password);
+ priv->password = NULL;
+ }
+
+ g_clear_object (&priv->connection);
+}
+
+static void
+delete_secrets_file (NMOPENSWANPlugin *self)
+{
+ NMOPENSWANPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (self);
+
+ if (priv->secrets_path) {
+ unlink (priv->secrets_path);
+ g_clear_pointer (&priv->secrets_path, g_free);
+ }
+}
+
+static gboolean
+ipsec_stop (NMOPENSWANPlugin *self, GError **error)
+{
+ NMOPENSWANPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (self);
+ const char *argv[4] = { priv->ipsec_path, "setup", "stop", NULL };
+
+ delete_secrets_file (self);
+ return g_spawn_sync (NULL, (char **) argv, NULL, 0, NULL, NULL, NULL, NULL, NULL, error);
+}
+
+static void
+connect_failed (NMOPENSWANPlugin *self, gboolean do_stop, GError *error)
+{
+ if (error) {
+ g_warning ("Connect failed: (%s/%d) %s",
+ g_quark_to_string (error->domain),
+ error->code,
+ error->message);
+ }
+
+ connect_cleanup (self);
+ if (do_stop)
+ ipsec_stop (self, NULL);
+ nm_vpn_plugin_failure (NM_VPN_PLUGIN (self), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
+}
+
+static void
pluto_watch_cb (GPid pid, gint status, gpointer user_data)
{
- NMOPENSWANPlugin *plugin = NM_OPENSWAN_PLUGIN (user_data);
- NMOPENSWANPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (plugin);
- guint error = 0;
+ NMOPENSWANPlugin *self = NM_OPENSWAN_PLUGIN (user_data);
+ NMOPENSWANPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (self);
+ guint ret = 0;
+ GError *error = NULL;
+ gboolean do_stop = FALSE;
- if (debug)
- g_message ("pluto_watch: current child pid = %d, pluto pid=%d", pid, priv->pid);
+ if (priv->watch_id == 0)
+ return;
+ if (priv->pid != pid) {
+ waitpid (pid, NULL, WNOHANG);
+ return;
+ }
+
+ priv->watch_id = 0;
+ priv->pid = 0;
+
+ DEBUG ("Spawn: child %d exited", pid);
if (WIFEXITED (status)) {
- error = WEXITSTATUS (status);
- if (error != 0) {
- g_warning ("pluto_watch: pluto exited with error code %d", error);
- nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
- }
- } else if (WIFSTOPPED (status))
- g_warning ("pluto_watch: pluto stopped unexpectedly with signal %d", WSTOPSIG (status));
- else if (WIFSIGNALED (status))
- g_warning ("pluto_watch: pluto died with signal %d", WTERMSIG (status));
- else
- g_warning ("pluto_watch: pluto died from an unknown cause");
+ ret = WEXITSTATUS (status);
+ if (ret)
+ g_warning ("Spawn: child %d exited with error code %d", pid, ret);
+ } else
+ g_warning ("Spawn: child %d died unexpectedly", pid);
- /* Reap child if needed. */
+ /* Reap child */
waitpid (pid, NULL, WNOHANG);
- if (pid == priv->pid) {
- priv->pid = 0;
- if (debug)
- g_message ("pluto_watch: nm pluto service is stopping");
- } else {
- if (debug)
- g_message ("pluto_watch: nm pluto service will continue after reaping a child");
+ if (ret == 0) {
+ /* Success; do the next connect step */
+ do_stop = TRUE;
+ priv->connect_step++;
+ if (!connect_step (self, &error))
+ ret = 1;
}
- g_spawn_close_pid (pid);
+ if (ret != 0)
+ connect_failed (self, do_stop, error);
+ g_clear_error (&error);
}
-static gboolean do_spawn (gboolean reap_child,
- GPid *out_pid,
+static gboolean do_spawn (GPid *out_pid,
int *out_stdin,
+ int *out_stderr,
GError **error,
const char *progname,
...) G_GNUC_NULL_TERMINATED;
static gboolean
-do_spawn (gboolean reap_child,
- GPid *out_pid,
+do_spawn (GPid *out_pid,
int *out_stdin,
+ int *out_stderr,
GError **error,
const char *progname,
...)
@@ -282,6 +384,7 @@ do_spawn (gboolean reap_child,
GPtrArray *argv;
char *cmdline, *arg;
gboolean success;
+ GPid pid = 0;
argv = g_ptr_array_sized_new (10);
g_ptr_array_add (argv, (char *) progname);
@@ -294,91 +397,36 @@ do_spawn (gboolean reap_child,
if (debug) {
cmdline = g_strjoinv (" ", (char **) argv->pdata);
- g_message ("Spawning: %s", cmdline);
+ g_message ("Spawn: %s", cmdline);
g_free (cmdline);
}
- if (out_stdin) {
+ if (out_stdin || out_stderr) {
success = g_spawn_async_with_pipes (NULL, (char **) argv->pdata, NULL,
- reap_child ? G_SPAWN_DO_NOT_REAP_CHILD : 0,
- NULL, NULL, out_pid, out_stdin,
- NULL, NULL, &local);
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, &pid, out_stdin,
+ NULL, out_stderr, &local);
} else {
success = g_spawn_async (NULL, (char **) argv->pdata, NULL,
- reap_child ? G_SPAWN_DO_NOT_REAP_CHILD : 0,
- NULL, NULL, out_pid, &local);
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, &pid, &local);
}
- if (!success) {
+ if (success) {
+ DEBUG ("Spawn: child process %d", pid);
+ } else {
g_warning ("Spawn failed: (%s/%d) %s",
g_quark_to_string (local->domain),
local->code, local->message);
g_propagate_error (error, local);
}
+ if (out_pid)
+ *out_pid = pid;
+
g_ptr_array_free (argv, TRUE);
return success;
}
-static gint
-nm_openswan_start_openswan_binary (NMOPENSWANPlugin *plugin,
- const char *uuid,
- GError **error)
-{
- NMOPENSWANPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (plugin);
- const char *ipsec_binary;
- gint stdin_fd = -1;
- GPid pid_auto;
-
- ipsec_binary = find_ipsec (error);
- if (!ipsec_binary)
- return -1;
-
- /* Start the IPSec service */
- if (!do_spawn (TRUE, &priv->pid, NULL, error, ipsec_binary, "setup", "start", NULL))
- return -1;
-
- g_message ("ipsec/pluto started with pid %d", priv->pid);
- g_child_watch_add (priv->pid, (GChildWatchFunc) pluto_watch_cb, plugin);
- sleep (2);
-
- /* Start the helper we write the connection configuration to */
- if (!do_spawn (TRUE, &pid_auto, &stdin_fd, error,
- ipsec_binary, "auto", "--add", "--config", "-", uuid, NULL)) {
- return -1;
- }
-
- if (debug)
- g_message ("pluto auto started with pid %d", pid_auto);
-
- g_child_watch_add (pid_auto, (GChildWatchFunc) pluto_watch_cb, plugin);
-
- return stdin_fd;
-}
-
-static gint
-nm_openswan_start_openswan_connection (NMOPENSWANPlugin *plugin,
- const char *uuid,
- GError **error)
-{
- GPid pid;
- const char *ipsec_binary;
- gint stdin_fd = -1;
-
- ipsec_binary = find_ipsec (error);
- if (!ipsec_binary)
- return -1;
-
- if (!do_spawn (TRUE, &pid, &stdin_fd, error, ipsec_binary, "auto", "--up", uuid, NULL))
- return -1;
-
- if (debug)
- g_message ("pluto up started with pid %d", pid);
-
- g_child_watch_add (pid, (GChildWatchFunc) pluto_watch_cb, plugin);
-
- return stdin_fd;
-}
-
static inline void
write_config_option (int fd, const char *format, ...)
{
@@ -398,18 +446,19 @@ write_config_option (int fd, const char *format, ...)
va_end (args);
}
-static gboolean
-nm_openswan_config_write (gint fd,
- const char *uuid,
- NMSettingVPN *s_vpn,
- GError **error)
+static void
+nm_openswan_config_write (gint fd, NMConnection *connection, GError **error)
{
+ NMSettingVPN *s_vpn = nm_connection_get_setting_vpn (connection);
+ const char *uuid = nm_connection_get_uuid (connection);
const char *props_username;
const char *default_username;
const char *phase1_alg_str;
const char *phase2_alg_str;
g_assert (fd >= 0);
+ g_assert (s_vpn);
+ g_assert (uuid);
write_config_option (fd, "conn %s\n", uuid);
write_config_option (fd, " aggrmode=yes\n");
@@ -450,8 +499,6 @@ nm_openswan_config_write (gint fd,
write_config_option (fd, " ikelifetime=24h\n");
write_config_option (fd, " keyingtries=1\n");
write_config_option (fd, " auto=add\n");
-
- return TRUE;
}
static gboolean
@@ -491,17 +538,250 @@ nm_openswan_config_psk_write (NMSettingVPN *s_vpn,
return TRUE;
}
-static void
-delete_secrets_file (NMOPENSWANPlugin *self)
+/****************************************************************/
+
+static gboolean spawn_pty (int *out_stdout,
+ int *out_stderr,
+ int *out_ptyin,
+ GPid *out_pid,
+ GError **error,
+ const char *progname,
+ ...) G_GNUC_NULL_TERMINATED;
+
+static gboolean
+spawn_pty (int *out_stdout,
+ int *out_stderr,
+ int *out_ptyin,
+ GPid *out_pid,
+ GError **error,
+ const char *progname,
+ ...)
+{
+ int pty_master_fd, md;
+ int stdout_pipe[2], stderr_pipe[2];
+ pid_t child_pid;
+ struct termios termios_flags;
+ va_list ap;
+ GPtrArray *argv;
+ char *cmdline, *arg;
+
+ argv = g_ptr_array_sized_new (10);
+ g_ptr_array_add (argv, (char *) progname);
+
+ va_start (ap, progname);
+ while ((arg = va_arg (ap, char *)))
+ g_ptr_array_add (argv, arg);
+ va_end (ap);
+ g_ptr_array_add (argv, NULL);
+
+ if (debug) {
+ cmdline = g_strjoinv (" ", (char **) argv->pdata);
+ g_message ("PTY spawn: %s", cmdline);
+ g_free (cmdline);
+ }
+
+ /* The pipes */
+ pipe (stderr_pipe);
+ pipe (stdout_pipe);
+
+ /* Fork the command */
+ child_pid = forkpty (&pty_master_fd, NULL, NULL, NULL);
+ if (child_pid == 0) {
+ /* in the child */
+
+ close (2);
+ dup (stderr_pipe[1]);
+ close (1);
+ dup (stdout_pipe[1]);
+
+ /* Close unnecessary pipes */
+ close (stderr_pipe[0]);
+ close (stdout_pipe[0]);
+
+ if ((md = fcntl (stdout_pipe[1], F_GETFL)) != -1)
+ fcntl (stdout_pipe[1], F_SETFL, O_SYNC | md);
+ if ((md = fcntl (stderr_pipe[1], F_GETFL)) != -1)
+ fcntl (stderr_pipe[1], F_SETFL, O_SYNC | md);
+
+ execvp (argv->pdata[0], (char * const*) argv->pdata);
+ g_error ("PTY spawn: cannot exec '%s'", (char *) argv->pdata[0]);
+ _exit (-1);
+ }
+ g_ptr_array_free (argv, TRUE);
+
+ /* Close parent's side pipes */
+ close (stderr_pipe[1]);
+ close (stdout_pipe[1]);
+
+ if (child_pid < 0) {
+ /* Close parent's side pipes */
+ close (stderr_pipe[0]);
+ close (stdout_pipe[0]);
+ g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+ "PTY spawn failed for '%s' (%d)",
+ (char *) argv->pdata[0], child_pid);
+ return FALSE;
+ }
+
+ /* Set pipes none blocking, so we can read big buffers
+ * in the callback without having to use FIONREAD
+ * to make sure the callback doesn't block.
+ */
+ if ((md = fcntl (stdout_pipe[0], F_GETFL)) != -1)
+ fcntl (stdout_pipe[0], F_SETFL, O_NONBLOCK | md);
+ if ((md = fcntl (stderr_pipe[0], F_GETFL)) != -1)
+ fcntl (stderr_pipe[0], F_SETFL, O_NONBLOCK | md);
+ if ((md = fcntl (pty_master_fd, F_GETFL)) != -1)
+ fcntl (pty_master_fd, F_SETFL, O_NONBLOCK | md);
+
+if (0) {
+ tcgetattr (pty_master_fd, &termios_flags);
+ termios_flags.c_iflag &= ~(IGNPAR | INPCK | INLCR | IGNCR | ICRNL | IXON | IXOFF | ISTRIP);
+ termios_flags.c_iflag |= IGNBRK | BRKINT | IMAXBEL | IXANY;
+ termios_flags.c_oflag &= ~OPOST;
+ termios_flags.c_cflag &= ~(CSTOPB | PARENB | HUPCL);
+ termios_flags.c_cflag |= CS8 | CLOCAL;
+ termios_flags.c_lflag &= ~(ECHOKE | ECHOE | ECHO | ECHONL | ECHOCTL | ISIG | ICANON | IEXTEN | NOFLSH
| TOSTOP);
+ termios_flags.c_cc[VMIN] = 0;
+ cfsetospeed (&termios_flags, __MAX_BAUD);
+ tcsetattr (pty_master_fd, TCSANOW, &termios_flags);
+}
+
+ if (out_stdout)
+ *out_stdout = stdout_pipe[0];
+ if (out_stderr)
+ *out_stderr = stderr_pipe[0];
+ if (out_ptyin)
+ *out_ptyin = pty_master_fd;
+ if (out_pid)
+ *out_pid = child_pid;
+
+ return TRUE;
+}
+
+/****************************************************************/
+
+static gboolean
+io_cb (GIOChannel *source, GIOCondition condition, gpointer user_data)
{
+ NMOPENSWANPlugin *self = NM_OPENSWAN_PLUGIN (user_data);
NMOPENSWANPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (self);
+ char buf[256];
+ GIOStatus status;
+ gsize bytes_read = 0;
+ gboolean ret = G_SOURCE_CONTINUE;
+
+ if (condition & G_IO_ERR) {
+ g_warning ("PTY spawn: pipe error!");
+ ret = G_SOURCE_REMOVE;
+ goto done;
+ }
+ g_assert (condition & G_IO_IN);
- if (priv->secrets_path) {
- unlink (priv->secrets_path);
- g_clear_pointer (&priv->secrets_path, g_free);
+ status = g_io_channel_read_chars (source, buf, sizeof (buf) - 1, &bytes_read, NULL);
+ if (status != G_IO_STATUS_NORMAL || bytes_read == 0)
+ return G_SOURCE_CONTINUE;
+
+ buf[bytes_read] = 0;
+ DEBUG ("VPN request '%s'", buf);
+
+ if (strcmp (buf, "Enter passphrase: ") == 0) {
+ GError *error = NULL;
+ gsize bytes_written;
+ const char *password = priv->password;
+
+ if (!password) {
+ /* FIXME: request new password interactively */
+ g_warning ("Password required but not provided!");
+ ret = G_SOURCE_REMOVE;
+ goto done;
+ }
+
+ do {
+ g_io_channel_write_chars (source, password, -1, &bytes_written, &error);
+ g_io_channel_flush (source, NULL);
+ if (error) {
+ g_warning ("Failed to write password to ipsec!");
+ ret = G_SOURCE_REMOVE;
+ goto done;
+ }
+ password += bytes_written;
+ } while (*password);
+
+ g_io_channel_write_chars (source, "\n", -1, NULL, NULL);
+ g_io_channel_flush (source, NULL);
+
+ DEBUG ("Wrote: '%s'", priv->password);
+ }
+
+done:
+ if (ret == G_SOURCE_REMOVE) {
+ priv->io_id = 0;
+ connect_failed (self, TRUE, NULL);
}
+ return ret;
}
+static gboolean
+connect_step (NMOPENSWANPlugin *self, GError **error)
+{
+ NMOPENSWANPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (self);
+ const char *uuid;
+ int fd = -1, up_stdout = -1, up_stderr = -1, up_pty = -1;
+
+ g_warn_if_fail (priv->watch_id == 0);
+ priv->watch_id = 0;
+ g_warn_if_fail (priv->pid == 0);
+ priv->pid = 0;
+
+ DEBUG ("Connect: step %d", priv->connect_step);
+
+ uuid = nm_connection_get_uuid (priv->connection);
+ g_assert (uuid);
+
+ switch (priv->connect_step) {
+ case CONNECT_STEP_FIRST:
+ /* fall through */
+ priv->connect_step++;
+
+ case CONNECT_STEP_IPSEC_START:
+ /* Start the IPSec service */
+ if (!do_spawn (&priv->pid, NULL, NULL, error, priv->ipsec_path, "setup", "start", NULL))
+ return FALSE;
+ priv->watch_id = g_child_watch_add (priv->pid, pluto_watch_cb, self);
+ return TRUE;
+
+ case CONNECT_STEP_CONFIG_ADD:
+ if (!do_spawn (&priv->pid, &fd, NULL, error, priv->ipsec_path,
+ "auto", "--add", "--config", "-", uuid, NULL))
+ return FALSE;
+ priv->watch_id = g_child_watch_add (priv->pid, pluto_watch_cb, self);
+ nm_openswan_config_write (fd, priv->connection, error);
+ close (fd);
+ return TRUE;
+
+ case CONNECT_STEP_CONNECT:
+ if (!spawn_pty (&up_stdout, &up_stderr, &up_pty, &priv->pid, error,
+ priv->ipsec_path, "auto", "--up", uuid, NULL))
+ return FALSE;
+ priv->watch_id = g_child_watch_add (priv->pid, pluto_watch_cb, self);
+
+ /* Wait for the password request */
+ priv->channel = g_io_channel_unix_new (up_pty);
+ g_io_channel_set_encoding (priv->channel, NULL, NULL);
+ g_io_channel_set_buffered (priv->channel, FALSE);
+ priv->io_id = g_io_add_watch (priv->channel, G_IO_IN | G_IO_ERR, io_cb, self);
+ return TRUE;
+
+ case CONNECT_STEP_LAST:
+ /* Everything successfully set up */
+ priv->pid = 0;
+ connect_cleanup (self);
+ return TRUE;
+ }
+
+ g_assert_not_reached ();
+}
static gboolean
real_connect (NMVPNPlugin *plugin,
@@ -512,7 +792,11 @@ real_connect (NMVPNPlugin *plugin,
NMOPENSWANPluginPrivate *priv = NM_OPENSWAN_PLUGIN_GET_PRIVATE (self);
NMSettingVPN *s_vpn;
const char *uuid = nm_connection_get_uuid (connection);
- gint fd = -1;
+
+ if (debug)
+ nm_connection_dump (connection);
+
+ ipsec_stop (self, NULL);
s_vpn = nm_connection_get_setting_vpn (connection);
g_assert (s_vpn);
@@ -523,40 +807,29 @@ real_connect (NMVPNPlugin *plugin,
if (!nm_openswan_secrets_validate (s_vpn, error))
return FALSE;
- /* Write the IPSec secret (group password) */
- priv->secrets_path = g_strdup_printf (SYSCONFDIR "/ipsec.d/ipsec-%s.secrets", uuid);
- if (!nm_openswan_config_psk_write (s_vpn, priv->secrets_path, error))
+ if (priv->connect_step != CONNECT_STEP_FIRST) {
+ g_set_error_literal (error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+ "Already connecting!");
return FALSE;
+ }
- fd = nm_openswan_start_openswan_binary (self, uuid, error);
- if (fd < 0)
- goto error;
-
- if (debug)
- nm_connection_dump (connection);
+ priv->ipsec_path = find_ipsec (error);
+ if (!priv->ipsec_path)
+ return FALSE;
- /* Start the IPSec service */
- sleep (1);
- if (!nm_openswan_config_write (fd, uuid, s_vpn, error))
- goto error;
- sleep (3);
- close (fd);
+ priv->password = g_strdup (nm_setting_vpn_get_secret (s_vpn, NM_OPENSWAN_XAUTH_PASSWORD));
- /* Start the actual IPSec connection */
- fd = nm_openswan_start_openswan_connection (self, uuid, error);
- if (fd < 0)
- goto error;
+ /* Write the IPSec secret (group password) */
+ priv->secrets_path = g_strdup_printf (SYSCONFDIR "/ipsec.d/ipsec-%s.secrets", uuid);
+ if (!nm_openswan_config_psk_write (s_vpn, priv->secrets_path, error))
+ return FALSE;
- /* Write the user password */
- write_config_option (fd, "%s", nm_setting_vpn_get_secret (s_vpn, NM_OPENSWAN_XAUTH_PASSWORD));
- close (fd);
- return TRUE;
+ priv->connection = g_object_ref (connection);
-error:
- if (fd >= 0)
- close (fd);
- delete_secrets_file (self);
- return FALSE;
+ /* Start the connection process */
+ return connect_step (self, error);
}
static gboolean
@@ -602,15 +875,8 @@ real_need_secrets (NMVPNPlugin *plugin,
static gboolean
real_disconnect (NMVPNPlugin *plugin, GError **error)
{
- const char *ipsec_binary;
-
- delete_secrets_file (NM_OPENSWAN_PLUGIN (plugin));
-
- ipsec_binary = find_ipsec (error);
- if (!ipsec_binary)
- return FALSE;
-
- return do_spawn (FALSE, NULL, NULL, error, ipsec_binary, "setup", "stop", NULL);
+ connect_cleanup (NM_OPENSWAN_PLUGIN (plugin));
+ return ipsec_stop (NM_OPENSWAN_PLUGIN (plugin), error);
}
static void
@@ -622,6 +888,7 @@ static void
finalize (GObject *object)
{
delete_secrets_file (NM_OPENSWAN_PLUGIN (object));
+ connect_cleanup (NM_OPENSWAN_PLUGIN (object));
G_OBJECT_CLASS (nm_openswan_plugin_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]