2005-05-20 Dan Williams <dcbw@redhat.com>

* NetworkManager.h
		- Differentiate VPN config signals between bad VPN config options
			and bad IP config

	* gnome/applet/applet-dbus-info.h
		- Add prototypes for wireless network and vpn connection update functions

	* gnome/applet/applet-dbus.c
		- (nmwa_dbus_filter): trap new VPN config error signals from NetworkManager

	* gnome/applet/applet.c
		- (nmwa_schedule_vpn_failure_dialog): new dialog text for new VPN config
			error signals
		- (nmwa_gconf_networks_notify_cb): re-enable wireless network change notify
			propogation to NetworkManager
		- (nmwa_gconf_vpn_connections_notify_cb): re-enable vpn connection change
			notify propogation to NetworkManager

	* src/NetworkManagerDbus.c
		- (nm_dbus_update_one_allowed_network): make sure to specify which AP list we
			are updating so a network can be removed from it if necessary

	* src/vpn-manager/nm-vpn-manager.c
		- (nm_vpn_manager_process_signal): trap new vpn config error signals

	* vpn-daemons/vpnc/nm-vpnc-service.c
		- (nm_vpnc_dbus_signal_failure): generalize function for all VPN error signals
		- (nm_vpnc_dbus_signal_launch_failed): remove
		- (nm_vpnc_dbus_signal_connect_failed): remove
		- (nm_vpnc_helper_timer_cb): update for new generalized error signal function
		- (nm_vpnc_schedule_helper_timer): increase timeout to 10s
		- (vpnc_watch_cb): don't whine about exit code if vpnc exited cleanly, update
			for new generalized error signal function, remove config file stuff
		- (nm_vpnc_start_vpnc_binary): grab a stdin pipe to vpnc after spawning it so
			we can write configuration options to it
		- (nm_vpnc_config_file_generate): removed
		- (nm_vpnc_config_write): write configuration options to the vpnc stdin pipe
		- (nm_vpnc_config_options_validate): validate the config options we receive
			from NetworkManager to block potential exploits
		- (nm_vpnc_dbus_handle_start_vpn): call option validation function before
			starting vpnc
		- (nm_vpnc_dbus_process_helper_config_error): actually propogate config error
			to NetworkManager


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@646 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2005-05-21 04:33:19 +00:00
parent f9c87f5575
commit 74a2ffa9b7
8 changed files with 263 additions and 144 deletions

View file

@ -1,3 +1,49 @@
2005-05-20 Dan Williams <dcbw@redhat.com>
* NetworkManager.h
- Differentiate VPN config signals between bad VPN config options
and bad IP config
* gnome/applet/applet-dbus-info.h
- Add prototypes for wireless network and vpn connection update functions
* gnome/applet/applet-dbus.c
- (nmwa_dbus_filter): trap new VPN config error signals from NetworkManager
* gnome/applet/applet.c
- (nmwa_schedule_vpn_failure_dialog): new dialog text for new VPN config
error signals
- (nmwa_gconf_networks_notify_cb): re-enable wireless network change notify
propogation to NetworkManager
- (nmwa_gconf_vpn_connections_notify_cb): re-enable vpn connection change
notify propogation to NetworkManager
* src/NetworkManagerDbus.c
- (nm_dbus_update_one_allowed_network): make sure to specify which AP list we
are updating so a network can be removed from it if necessary
* src/vpn-manager/nm-vpn-manager.c
- (nm_vpn_manager_process_signal): trap new vpn config error signals
* vpn-daemons/vpnc/nm-vpnc-service.c
- (nm_vpnc_dbus_signal_failure): generalize function for all VPN error signals
- (nm_vpnc_dbus_signal_launch_failed): remove
- (nm_vpnc_dbus_signal_connect_failed): remove
- (nm_vpnc_helper_timer_cb): update for new generalized error signal function
- (nm_vpnc_schedule_helper_timer): increase timeout to 10s
- (vpnc_watch_cb): don't whine about exit code if vpnc exited cleanly, update
for new generalized error signal function, remove config file stuff
- (nm_vpnc_start_vpnc_binary): grab a stdin pipe to vpnc after spawning it so
we can write configuration options to it
- (nm_vpnc_config_file_generate): removed
- (nm_vpnc_config_write): write configuration options to the vpnc stdin pipe
- (nm_vpnc_config_options_validate): validate the config options we receive
from NetworkManager to block potential exploits
- (nm_vpnc_dbus_handle_start_vpn): call option validation function before
starting vpnc
- (nm_vpnc_dbus_process_helper_config_error): actually propogate config error
to NetworkManager
2005-05-16 Dan Williams <dcbw@redhat.com>
* vpn-daemons/vpnc/nm-vpnc-service-vpnc-helper.c

View file

@ -68,7 +68,8 @@
#define NM_DBUS_VPN_SIGNAL_LOGIN_FAILED "LoginFailed"
#define NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED "LaunchFailed"
#define NM_DBUS_VPN_SIGNAL_CONNECT_FAILED "ConnectFailed"
#define NM_DBUS_VPN_SIGNAL_CONFIG_BAD "ConfigurationBad"
#define NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD "VPNConfigBad"
#define NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD "IPConfigBad"
#define NM_DBUS_VPN_SIGNAL_STATE_CHANGE "StateChange"
#define NM_DBUS_VPN_SIGNAL_IP4_CONFIG "IP4Config"

View file

@ -31,4 +31,8 @@ DBusHandlerResult nmi_dbus_info_message_handler (DBusConnection *connection,
void nmi_dbus_return_user_key (DBusConnection *connection, DBusMessage *message, const char *passphrase, const int key_type);
void nmi_dbus_signal_update_network (DBusConnection *connection, const char *network, NMNetworkType type);
void nmi_dbus_signal_update_vpn_connection (DBusConnection *connection, const char *name);
#endif

View file

@ -546,7 +546,9 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa
}
else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED)
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED)
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED))
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED)
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD)
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
{
char *vpn_name;
char *error_msg;

View file

@ -56,6 +56,7 @@
#include "applet-dbus.h"
#include "applet-dbus-devices.h"
#include "applet-dbus-vpn.h"
#include "applet-dbus-info.h"
#include "other-network-dialog.h"
#include "passphrase-dialog.h"
#include "menu-items.h"
@ -315,6 +316,17 @@ void nmwa_schedule_vpn_failure_dialog (NMWirelessApplet *applet, const char *mem
cb_data->msg = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">VPN Connect Failure</span>\n\nCould not start the "
"VPN connection '%s' due to a connection error.\n\nThe VPN service said: \"%s\""), vpn_name, error_msg);
}
else if (!strcmp (member, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD))
{
cb_data->msg = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">VPN Configuration Error</span>\n\nThe "
"VPN connection '%s' was not correctly configured.\n\nThe VPN service said: \"%s\""), vpn_name, error_msg);
}
else if (!strcmp (member, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
{
cb_data->msg = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">VPN Connect Failure</span>\n\nCould not start the "
"VPN connection '%s' because the VPN server did not return an adequate network configuration.\n\n"
"The VPN service said: \"%s\""), vpn_name, error_msg);
}
if (cb_data->msg)
g_idle_add ((GSourceFunc) nmwa_show_vpn_failure_dialog, cb_data);
@ -1847,7 +1859,7 @@ static void nmwa_gconf_networks_notify_callback (GConfClient *client, guint conn
if ((slash_pos = strchr (unescaped_network, '/')))
*slash_pos = '\0';
// nmi_dbus_signal_update_network (applet->connection, unescaped_network, NETWORK_TYPE_ALLOWED);
nmi_dbus_signal_update_network (applet->connection, unescaped_network, NETWORK_TYPE_ALLOWED);
g_free (unescaped_network);
g_free (network);
}
@ -1887,7 +1899,7 @@ static void nmwa_gconf_vpn_connections_notify_callback (GConfClient *client, gui
if ((slash_pos = strchr (unescaped_name, '/')))
*slash_pos = '\0';
// nmi_dbus_signal_update_vpn_connection (info->connection, unescaped_name);
nmi_dbus_signal_update_vpn_connection (applet->connection, unescaped_name);
g_free (unescaped_name);
g_free (name);
}

View file

@ -909,6 +909,7 @@ static void nm_dbus_update_one_allowed_network (DBusConnection *connection, cons
cb_data = g_malloc0 (sizeof (GetOneNetworkCBData));
cb_data->data = data;
cb_data->network = g_strdup (network);
cb_data->list = data->allowed_ap_list;
dbus_message_append_args (message, DBUS_TYPE_STRING, &network, DBUS_TYPE_INT32, &type_as_int32, DBUS_TYPE_INVALID);
dbus_connection_send_with_reply (connection, message, &pcall, -1);

View file

@ -561,7 +561,9 @@ gboolean nm_vpn_manager_process_signal (NMVPNManager *manager, DBusMessage *mess
if ( dbus_message_is_signal (message, service_name, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED)
|| dbus_message_is_signal (message, service_name, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED)
|| dbus_message_is_signal (message, service_name, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED))
|| dbus_message_is_signal (message, service_name, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED)
|| dbus_message_is_signal (message, service_name, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD)
|| dbus_message_is_signal (message, service_name, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
{
char *error_msg;
char *blank_msg = "";

View file

@ -34,6 +34,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include "NetworkManager.h"
#include "nm-vpnc-service.h"
@ -49,7 +50,6 @@ static char *vpnc_binary_paths[] =
#define NM_VPNC_HELPER_PATH BINDIR"/nm-vpnc-service-vpnc-helper"
#define NM_VPNC_PID_FILE_PATH LOCALSTATEDIR"/run/vpnc/pid"
#define NM_VPNC_CONFIG_FILE_PATH LOCALSTATEDIR"/run/vpnc/nm-vpnc-service-vpnc.conf"
typedef struct NmVpncData
{
@ -75,7 +75,7 @@ static DBusMessage *nm_dbus_create_error_message (DBusMessage *message, const ch
const char *exception, const char *format, ...)
{
char *exception_text;
DBusMessage *reply_message;
DBusMessage *reply;
va_list args;
char error_text[512];
@ -84,81 +84,42 @@ static DBusMessage *nm_dbus_create_error_message (DBusMessage *message, const ch
va_end (args);
exception_text = g_strdup_printf ("%s.%s", exception_namespace, exception);
reply_message = dbus_message_new_error (message, exception_text, error_text);
reply = dbus_message_new_error (message, exception_text, error_text);
g_free (exception_text);
return (reply_message);
return (reply);
}
/*
* nm_vpnc_dbus_signal_login_failed
* nm_vpnc_dbus_signal_failure
*
* Signal the bus that VPN login failed.
* Signal the bus that some VPN operation failed.
*
*/
static void nm_vpnc_dbus_signal_login_failed (NmVpncData *data)
static void nm_vpnc_dbus_signal_failure (NmVpncData *data, const char *signal)
{
DBusMessage *message;
const char *error_msg = "The VPN login failed because the user name and password were not accepted.";
const char *error_msg = NULL;
g_return_if_fail (data != NULL);
g_return_if_fail (signal != NULL);
if (!(message = dbus_message_new_signal (NM_DBUS_PATH_VPNC, NM_DBUS_INTERFACE_VPNC, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED)))
{
nm_warning ("Not enough memory for new dbus message!");
if (!strcmp (signal, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED))
error_msg = "The VPN login failed because the user name and password were not accepted.";
else if (!strcmp (signal, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED))
error_msg = "The VPN login failed because the VPN program could not be started.";
else if (!strcmp (signal, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED))
error_msg = "The VPN login failed because the VPN program could not connect to the VPN server.";
else if (!strcmp (signal, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD))
error_msg = "The VPN login failed because the VPN configuration options were invalid.";
else if (!strcmp (signal, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
error_msg = "The VPN login failed because the VPN program received an invalid configuration from the VPN server.";
if (!error_msg)
return;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, &error_msg, DBUS_TYPE_INVALID);
if (!dbus_connection_send (data->con, message, NULL))
nm_warning ("Could not raise the signal!");
dbus_message_unref (message);
}
/*
* nm_vpnc_dbus_signal_launch_failed
*
* Signal the bus that we couldn't launch the VPN daemon.
*
*/
static void nm_vpnc_dbus_signal_launch_failed (NmVpncData *data)
{
DBusMessage *message;
const char *error_msg = "The VPN login failed because the VPN program could not be started.";
g_return_if_fail (data != NULL);
if (!(message = dbus_message_new_signal (NM_DBUS_PATH_VPNC, NM_DBUS_INTERFACE_VPNC, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED)))
{
nm_warning ("Not enough memory for new dbus message!");
return;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, &error_msg, DBUS_TYPE_INVALID);
if (!dbus_connection_send (data->con, message, NULL))
nm_warning ("Could not raise the signal!");
dbus_message_unref (message);
}
/*
* nm_vpnc_dbus_signal_connect_failed
*
* Signal the bus that VPN daemon failed to connect to the VPN concentrator.
*
*/
static void nm_vpnc_dbus_signal_connect_failed (NmVpncData *data)
{
DBusMessage *message;
const char *error_msg = "The VPN login failed because the VPN program could not connect to the VPN server.";
g_return_if_fail (data != NULL);
if (!(message = dbus_message_new_signal (NM_DBUS_PATH_VPNC, NM_DBUS_INTERFACE_VPNC, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED)))
if (!(message = dbus_message_new_signal (NM_DBUS_PATH_VPNC, NM_DBUS_INTERFACE_VPNC, signal)))
{
nm_warning ("Not enough memory for new dbus message!");
return;
@ -279,7 +240,7 @@ static gboolean nm_vpnc_helper_timer_cb (NmVpncData *data)
g_return_val_if_fail (data != NULL, FALSE);
nm_vpnc_dbus_signal_connect_failed (data);
nm_vpnc_dbus_signal_failure (data, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED);
nm_vpnc_dbus_handle_stop_vpn (data);
return FALSE;
@ -299,7 +260,7 @@ static void nm_vpnc_schedule_helper_timer (NmVpncData *data)
g_return_if_fail (data != NULL);
if (data->helper_timer == 0)
data->helper_timer = g_timeout_add (7000, (GSourceFunc) nm_vpnc_helper_timer_cb, data);
data->helper_timer = g_timeout_add (10000, (GSourceFunc) nm_vpnc_helper_timer_cb, data);
}
@ -333,7 +294,8 @@ static void vpnc_watch_cb (GPid pid, gint status, gpointer user_data)
if (WIFEXITED (status))
{
error = WEXITSTATUS (status);
nm_warning ("vpnc exited with error code %d", error);
if (error != 0)
nm_warning ("vpnc exited with error code %d", error);
}
else if (WIFSTOPPED (status))
nm_warning ("vpnc stopped unexpectedly with signal %d", WSTOPSIG (status));
@ -350,11 +312,11 @@ static void vpnc_watch_cb (GPid pid, gint status, gpointer user_data)
switch (error)
{
case 2: /* Couldn't log in due to bad user/pass */
nm_vpnc_dbus_signal_login_failed (data);
nm_vpnc_dbus_signal_failure (data, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED);
break;
case 1: /* Other error (couldn't bind to address, etc) */
nm_vpnc_dbus_signal_connect_failed (data);
nm_vpnc_dbus_signal_failure (data, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED);
break;
case 0: /* Success, vpnc has daemonized */
@ -369,6 +331,8 @@ static void vpnc_watch_cb (GPid pid, gint status, gpointer user_data)
nm_info ("vpnc daemon's PID is %d\n", data->pid);
g_free (contents);
}
else
nm_warning ("Could not read vpnc daemon's PID file.");
}
break;
@ -376,8 +340,6 @@ static void vpnc_watch_cb (GPid pid, gint status, gpointer user_data)
break;
}
unlink (NM_VPNC_CONFIG_FILE_PATH);
/* If vpnc did not daemonize (due to errors), we quit after a bit */
if (data->pid <= 0)
{
@ -399,7 +361,7 @@ static void vpnc_watch_cb (GPid pid, gint status, gpointer user_data)
* Start the vpnc binary with a set of arguments and a config file.
*
*/
static gboolean nm_vpnc_start_vpnc_binary (NmVpncData *data)
static gint nm_vpnc_start_vpnc_binary (NmVpncData *data)
{
GPid pid;
char ** vpnc_binary = NULL;
@ -407,8 +369,9 @@ static gboolean nm_vpnc_start_vpnc_binary (NmVpncData *data)
GError * error = NULL;
gboolean success = FALSE;
GSource * vpnc_watch;
gint stdin_fd = -1;
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (data != NULL, -1);
data->pid = 0;
@ -426,25 +389,23 @@ static gboolean nm_vpnc_start_vpnc_binary (NmVpncData *data)
if (!*vpnc_binary)
{
nm_info ("Could not find vpnc binary.");
return FALSE;
return -1;
}
vpnc_argv = g_ptr_array_new ();
g_ptr_array_add (vpnc_argv, (char *) (*vpnc_binary));
g_ptr_array_add (vpnc_argv, "--script");
g_ptr_array_add (vpnc_argv, NM_VPNC_HELPER_PATH);
g_ptr_array_add (vpnc_argv, "--pid-file");
g_ptr_array_add (vpnc_argv, NM_VPNC_PID_FILE_PATH);
g_ptr_array_add (vpnc_argv, NM_VPNC_CONFIG_FILE_PATH);
g_ptr_array_add (vpnc_argv, "--non-inter");
g_ptr_array_add (vpnc_argv, "-");
g_ptr_array_add (vpnc_argv, NULL);
if (!g_spawn_async (NULL, (char **) vpnc_argv->pdata, NULL,
G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error))
if (!g_spawn_async_with_pipes (NULL, (char **) vpnc_argv->pdata, NULL,
G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &stdin_fd,
NULL, NULL, &error))
{
g_ptr_array_free (vpnc_argv, TRUE);
nm_warning ("vpnc failed to start. error: '%s'", error->message);
g_error_free(error);
return FALSE;
return -1;
}
g_ptr_array_free (vpnc_argv, TRUE);
@ -458,20 +419,19 @@ static gboolean nm_vpnc_start_vpnc_binary (NmVpncData *data)
nm_vpnc_schedule_helper_timer (data);
return TRUE;
return stdin_fd;
}
/*
* nm_vpnc_config_file_generate
* nm_vpnc_config_write
*
* Generate a vpnc config file.
* Write the vpnc config to the vpnc process' stdin pipe
*
*/
static gboolean nm_vpnc_config_file_generate (const char *user_name, const char *password, const char **data_items, const int num_items)
static gboolean nm_vpnc_config_write (guint vpnc_fd, const char *user_name, const char *password, char **data_items, const int num_items)
{
char * string;
int out_fd;
int i, x;
char * dirname;
char * cmd;
@ -481,74 +441,158 @@ static gboolean nm_vpnc_config_file_generate (const char *user_name, const char
g_return_val_if_fail (password != NULL, FALSE);
g_return_val_if_fail (data_items != NULL, FALSE);
/* Ensure that the config file's directory exists */
dirname = g_path_get_dirname (NM_VPNC_CONFIG_FILE_PATH);
if (!dirname || !strlen (dirname))
{
nm_warning ("Could not get dirname for vpnc config file path '%s'.", NM_VPNC_CONFIG_FILE_PATH);
return FALSE;
}
string = g_strdup ("Script " NM_VPNC_HELPER_PATH "\n");
x = write (vpnc_fd, string, strlen (string));
g_free (string);
cmd = g_strdup_printf ("/bin/mkdir -p -m 700 %s", dirname);
ret = system (cmd);
if ((ret == -1) || (WEXITSTATUS(ret) != 0))
{
nm_warning ("Could not create dirname for vpnc config file path '%s'.", NM_VPNC_CONFIG_FILE_PATH);
g_free (cmd);
g_free (dirname);
return FALSE;
}
g_free (cmd);
unlink (NM_VPNC_CONFIG_FILE_PATH);
out_fd = open (NM_VPNC_CONFIG_FILE_PATH, O_WRONLY|O_CREAT|O_TRUNC, 0600);
if (out_fd < 0)
{
nm_warning ("Could not create vpnc config file '%s'.", NM_VPNC_CONFIG_FILE_PATH);
return FALSE;
}
string = g_strdup ("Pidfile " NM_VPNC_PID_FILE_PATH "\n");
x = write (vpnc_fd, string, strlen (string));
g_free (string);
string = g_strdup_printf ("Xauth username %s\n", user_name);
x = write (out_fd, string, strlen (string));
x = write (vpnc_fd, string, strlen (string));
g_free (string);
string = g_strdup_printf ("Xauth password %s\n", password);
x = write (out_fd, string, strlen (string));
x = write (vpnc_fd, string, strlen (string));
g_free (string);
for (i = 0; i < num_items; i++)
for (i = 0; i < num_items; i += 2)
{
char *temp = g_strdup_printf ("%s\n", data_items[i]);
x = write (out_fd, temp, strlen (temp));
g_free (temp);
string++;
char *line = g_strdup_printf ("%s %s\n", data_items[i], data_items[i+1]);
x = write (vpnc_fd, line, strlen (line));
g_free (line);
}
close (out_fd);
return TRUE;
}
typedef enum OptType
{
OPT_TYPE_UNKNOWN = 0,
OPT_TYPE_ADDRESS,
OPT_TYPE_ASCII,
OPT_TYPE_NONE
} OptType;
typedef struct Option
{
const char *name;
OptType type;
} Option;
/*
* nm_vpnc_config_options_validate
*
* Make sure the config options are sane
*
*/
static gboolean nm_vpnc_config_options_validate (char **data_items, int num_items)
{
Option allowed_opts[] = { { "IPSec gateway", OPT_TYPE_ADDRESS },
{ "IPSec ID", OPT_TYPE_ASCII },
{ "IPSec secret", OPT_TYPE_ASCII },
{ "UDP Encapsulate", OPT_TYPE_NONE },
{ "Domain", OPT_TYPE_ASCII },
{ "IKE DH Group", OPT_TYPE_ASCII },
{ "Perfect Forward Secrecy", OPT_TYPE_ASCII },
{ "Application Version", OPT_TYPE_ASCII },
{ NULL, OPT_TYPE_UNKNOWN } };
char ** item;
unsigned int i;
g_return_val_if_fail (data_items != NULL, FALSE);
g_return_val_if_fail (num_items >= 2, FALSE);
/* Must be an even numbers of config options */
if ((num_items % 2) != 0)
{
nm_warning ("The number of VPN config options was not even.");
return FALSE;
}
for (i = 0; i < num_items; i += 2)
{
Option *opt = NULL;
unsigned int t, len;
char *opt_value;
struct in_addr addr;
if (!data_items[i] || !data_items[i+1])
return FALSE;
opt_value = data_items[i+1];
/* Find the option in the allowed list */
for (t = 0; t < sizeof (allowed_opts) / sizeof (Option); t++)
{
opt = &allowed_opts[t];
if (opt->name && !strcmp (opt->name, data_items[i]))
break;
}
if (!opt->name) /* not found */
{
nm_warning ("VPN option '%s' is not allowed.", data_items[i]);
return FALSE;
}
/* Don't allow control characters at all */
len = strlen (opt_value);
for (t = 0; t < len; t++)
{
if (iscntrl (opt_value[t]))
{
nm_warning ("There were invalid characters in the VPN option '%s' - '%s'.", data_items[i], opt_value);
return FALSE;
}
}
/* Validate the option's data */
switch (opt->type)
{
case OPT_TYPE_ASCII:
/* What other characters should we reject?? */
break;
case OPT_TYPE_NONE:
/* These have blank data */
break;
case OPT_TYPE_ADDRESS:
/* Can be any legal hostname or IP address */
break;
default:
return FALSE;
break;
}
}
return TRUE;
}
/*
* nm_vpnc_dbus_handle_start_vpn
*
* Parse message arguments and start the VPN connection.
*
*/
static gboolean nm_vpnc_dbus_handle_start_vpn (DBusMessage *message, DBusMessage **reply, NmVpncData *data)
static gboolean nm_vpnc_dbus_handle_start_vpn (DBusMessage *message, NmVpncData *data)
{
const char **data_items = NULL;
int num_items = -1;
const char *name = NULL;
const char *user_name = NULL;
const char *password = NULL;
DBusError error;
gboolean success = FALSE;
char ** data_items = NULL;
int num_items = -1;
const char * name = NULL;
const char * user_name = NULL;
const char * password = NULL;
DBusError error;
gboolean success = FALSE;
gint vpnc_fd = -1;
g_return_val_if_fail (message != NULL, FALSE);
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (reply != NULL, FALSE);
nm_vpnc_set_state (data, NM_VPN_STATE_STARTING);
dbus_error_init (&error);
if (!dbus_message_get_args (message, &error,
@ -559,23 +603,31 @@ static gboolean nm_vpnc_dbus_handle_start_vpn (DBusMessage *message, DBusMessage
DBUS_TYPE_INVALID))
{
nm_warning ("Could not process the request because its arguments were invalid. dbus said: '%s'", error.message);
nm_vpnc_dbus_signal_failure (data, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD);
dbus_error_free (&error);
*reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE_VPNC, NM_DBUS_VPN_BAD_ARGUMENTS,
"Could not process the request because its arguments were invalid.");
goto out;
}
if (!nm_vpnc_config_options_validate (data_items, num_items))
{
nm_vpnc_dbus_signal_failure (data, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD);
goto out;
}
/* Now we can finally try to activate the VPN */
nm_vpnc_set_state (data, NM_VPN_STATE_STARTING);
if (nm_vpnc_config_file_generate (user_name, password, data_items, num_items))
success = nm_vpnc_start_vpnc_binary (data);
if (!success)
if ((vpnc_fd = nm_vpnc_start_vpnc_binary (data)) >= 0)
{
nm_vpnc_dbus_signal_launch_failed (data);
nm_vpnc_set_state (data, NM_VPN_STATE_STOPPED);
if (nm_vpnc_config_write (vpnc_fd, user_name, password, data_items, num_items))
success = TRUE;
else
nm_vpnc_dbus_signal_failure (data, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED);
close (vpnc_fd);
}
out:
dbus_free_string_array (data_items);
if (!success)
nm_vpnc_set_state (data, NM_VPN_STATE_STOPPED);
return success;
}
@ -640,9 +692,8 @@ static DBusMessage *nm_vpnc_dbus_start_vpn (DBusConnection *con, DBusMessage *me
case NM_VPN_STATE_STOPPED:
nm_vpnc_cancel_quit_timer (data);
nm_vpnc_dbus_handle_start_vpn (message, &reply, data);
if (!reply)
reply = dbus_message_new_method_return (message);
nm_vpnc_dbus_handle_start_vpn (message, data);
reply = dbus_message_new_method_return (message);
break;
default:
@ -740,7 +791,7 @@ static void nm_vpnc_dbus_process_helper_config_error (DBusConnection *con, DBusM
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &error_item, DBUS_TYPE_INVALID))
{
nm_warning ("vpnc helper did not receive adequate configuration information from vpnc. It is missing '%s'.", error_item);
/* Signal NetworkManager */
nm_vpnc_dbus_signal_failure (data, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD);
}
nm_vpnc_cancel_helper_timer (data);