2005-04-15 Dan Williams <dcbw@redhat.com>

Initial VPN Support
		- supports 'vpnc'
		- reworks device IP configuration, backend files have changed and will need
			to be updated for all distributions.  I will try to do what I can for
			them, but I cannot test them.

	- Move named directory to src/named-manager
	- Make backends directory self-contained


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@571 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2005-04-15 15:43:42 +00:00
parent 498d1b6495
commit de1d417198
62 changed files with 5981 additions and 632 deletions

View File

@@ -1,3 +1,14 @@
2005-04-15 Dan Williams <dcbw@redhat.com>
Initial VPN Support
- supports 'vpnc'
- reworks device IP configuration, backend files have changed and will need
to be updated for all distributions. I will try to do what I can for
them, but I cannot test them.
- Move named directory to src/named-manager
- Make backends directory self-contained
2005-04-06 Dan Williams <dcbw@redhat.com> 2005-04-06 Dan Williams <dcbw@redhat.com>
Add debug code for socket/file descriptor leaks. We register every socket Add debug code for socket/file descriptor leaks. We register every socket

View File

@@ -1,4 +1,4 @@
SUBDIRS = utils dhcpcd named src libnm_glib dispatcher-daemon $(notification_icon_dir) info-daemon initscript test po SUBDIRS = utils dhcpcd src libnm_glib dispatcher-daemon $(notification_icon_dir) info-daemon vpn-daemons initscript test po
EXTRA_DIST = CONTRIBUTING NetworkManager.pc.in NetworkManager.h EXTRA_DIST = CONTRIBUTING NetworkManager.pc.in NetworkManager.h

View File

@@ -33,6 +33,8 @@
#define NM_DBUS_INTERFACE_DEVICES "org.freedesktop.NetworkManager.Devices" #define NM_DBUS_INTERFACE_DEVICES "org.freedesktop.NetworkManager.Devices"
#define NM_DBUS_PATH_DHCP "/org/freedesktop/NetworkManager/DhcpOptions" #define NM_DBUS_PATH_DHCP "/org/freedesktop/NetworkManager/DhcpOptions"
#define NM_DBUS_INTERFACE_DHCP "org.freedesktop.NetworkManager.DhcpOptions" #define NM_DBUS_INTERFACE_DHCP "org.freedesktop.NetworkManager.DhcpOptions"
#define NM_DBUS_PATH_VPN "/org/freedesktop/NetworkManager/VPNConnections"
#define NM_DBUS_INTERFACE_VPN "org.freedesktop.NetworkManager.VPNConnections"
#define NMI_DBUS_SERVICE "org.freedesktop.NetworkManagerInfo" #define NMI_DBUS_SERVICE "org.freedesktop.NetworkManagerInfo"
#define NMI_DBUS_PATH "/org/freedesktop/NetworkManagerInfo" #define NMI_DBUS_PATH "/org/freedesktop/NetworkManagerInfo"
@@ -46,6 +48,21 @@
#define NM_DBUS_NO_ACTIVE_DEVICE_ERROR "org.freedesktop.NetworkManager.NoActiveDevice" #define NM_DBUS_NO_ACTIVE_DEVICE_ERROR "org.freedesktop.NetworkManager.NoActiveDevice"
#define NM_DBUS_NO_NETWORKS_ERROR "org.freedesktop.NetworkManager.NoNetworks" #define NM_DBUS_NO_NETWORKS_ERROR "org.freedesktop.NetworkManager.NoNetworks"
#define NM_DBUS_NO_ACTIVE_VPN_CONNECTION "org.freedesktop.NetworkManager.VPNConnections.NoActiveVPNConnection"
#define NM_DBUS_NO_VPN_CONNECTIONS "org.freedesktop.NetworkManager.VPNConnections.NoVPNConnections"
#define NM_DBUS_VPN_STARTING_IN_PROGRESS "StartingInProgress"
#define NM_DBUS_VPN_ALREADY_STARTED "AlreadyStarted"
#define NM_DBUS_VPN_STOPPING_IN_PROGRESS "StoppingInProgress"
#define NM_DBUS_VPN_ALREADY_STOPPED "AlreadyStopped"
#define NM_DBUS_VPN_WRONG_STATE "WrongState"
#define NM_DBUS_VPN_BAD_ARGUMENTS "BadArguments"
#define NM_DBUS_VPN_SIGNAL_LOGIN_FAILED "LoginFailed"
#define NM_DBUS_VPN_SIGNAL_CONFIG_BAD "ConfigurationBad"
#define NM_DBUS_VPN_SIGNAL_STATE_CHANGE "StateChange"
#define NM_DBUS_VPN_SIGNAL_IP4_CONFIG "IP4Config"
/* /*
* Types of NetworkManager devices * Types of NetworkManager devices
@@ -130,6 +147,21 @@ typedef enum NMDeviceAuthMethod
} NMDeviceAuthMethod; } NMDeviceAuthMethod;
/*
* VPN daemon states
*/
typedef enum NMVPNState
{
NM_VPN_STATE_ERROR = 0,
NM_VPN_STATE_INIT,
NM_VPN_STATE_SHUTDOWN,
NM_VPN_STATE_STARTING,
NM_VPN_STATE_STARTED,
NM_VPN_STATE_STOPPING,
NM_VPN_STATE_STOPPED
} NMVPNState;
/* /*
* Info-daemon specific preference locations * Info-daemon specific preference locations
*/ */

View File

@@ -169,6 +169,10 @@ PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0)
AC_SUBST(LIBGNOMEUI_CFLAGS) # is this even needed? it was typed incorrectly before AC_SUBST(LIBGNOMEUI_CFLAGS) # is this even needed? it was typed incorrectly before
AC_SUBST(LIBGNOMEUI_LIBS) AC_SUBST(LIBGNOMEUI_LIBS)
PKG_CHECK_MODULES(GNOMEKEYRING, gnome-keyring-1)
AC_SUBST(GNOMEKEYRING_CFLAGS) # is this even needed? it was typed incorrectly before
AC_SUBST(GNOMEKEYRING_LIBS)
AC_ARG_WITH(dbus-sys, AC_HELP_STRING([--with-dbus-sys=DIR], [where D-BUS system.d directory is])) AC_ARG_WITH(dbus-sys, AC_HELP_STRING([--with-dbus-sys=DIR], [where D-BUS system.d directory is]))
if ! test -z "$with_dbus_sys" ; then if ! test -z "$with_dbus_sys" ; then
@@ -266,11 +270,13 @@ AC_OUTPUT([
Makefile Makefile
utils/Makefile utils/Makefile
src/Makefile src/Makefile
src/named-manager/Makefile
src/vpn-manager/Makefile
src/backends/Makefile
dispatcher-daemon/Makefile dispatcher-daemon/Makefile
info-daemon/Makefile info-daemon/Makefile
panel-applet/Makefile panel-applet/Makefile
panel-applet/icons/Makefile panel-applet/icons/Makefile
named/Makefile
dhcpcd/Makefile dhcpcd/Makefile
libnm_glib/Makefile libnm_glib/Makefile
test/Makefile test/Makefile
@@ -282,6 +288,8 @@ initscript/Slackware/Makefile
po/Makefile.in po/Makefile.in
NetworkManager.pc NetworkManager.pc
libnm_glib/libnm_glib.pc libnm_glib/libnm_glib.pc
vpn-daemons/Makefile
vpn-daemons/vpnc/Makefile
]) ])
echo echo

View File

@@ -49,12 +49,12 @@ static void nmi_spawn_notification_icon (NMIAppInfo *info);
/* /*
* nmi_gconf_notify_callback * nmi_gconf_networks_notify_callback
* *
* Callback from gconf when wireless networking key/values have changed. * Callback from gconf when wireless networking key/values have changed.
* *
*/ */
void nmi_gconf_notify_callback (GConfClient *client, guint connection_id, GConfEntry *entry, gpointer user_data) static void nmi_gconf_networks_notify_callback (GConfClient *client, guint connection_id, GConfEntry *entry, gpointer user_data)
{ {
NMIAppInfo *info = (NMIAppInfo *)user_data; NMIAppInfo *info = (NMIAppInfo *)user_data;
const char *key = NULL; const char *key = NULL;
@@ -88,6 +88,46 @@ void nmi_gconf_notify_callback (GConfClient *client, guint connection_id, GConfE
} }
/*
* nmi_gconf_vpn_connections_notify_callback
*
* Callback from gconf when VPN connection values have changed.
*
*/
static void nmi_gconf_vpn_connections_notify_callback (GConfClient *client, guint connection_id, GConfEntry *entry, gpointer user_data)
{
NMIAppInfo *info = (NMIAppInfo *)user_data;
const char *key = NULL;
g_return_if_fail (client != NULL);
g_return_if_fail (entry != NULL);
g_return_if_fail (info != NULL);
if ((key = gconf_entry_get_key (entry)))
{
int path_len = strlen (NMI_GCONF_VPN_CONNECTIONS_PATH) + 1;
if (strncmp (NMI_GCONF_VPN_CONNECTIONS_PATH"/", key, path_len) == 0)
{
char *name = g_strdup ((key + path_len));
char *slash_pos;
char *unescaped_name;
/* If its a key under the the VPN name, zero out the slash so we
* are left with only the VPN name.
*/
unescaped_name = gconf_unescape_key (name, strlen (name));
if ((slash_pos = strchr (unescaped_name, '/')))
*slash_pos = '\0';
nmi_dbus_signal_update_vpn_connection (info->connection, unescaped_name);
g_free (unescaped_name);
g_free (name);
}
}
}
#ifdef BUILD_NOTIFICATION_ICON #ifdef BUILD_NOTIFICATION_ICON
static void static void
on_icon_exit_callback (GPid pid, int status, gpointer data) on_icon_exit_callback (GPid pid, int status, gpointer data)
@@ -238,7 +278,9 @@ int main( int argc, char *argv[] )
gconf_client_add_dir (app_info->gconf_client, NMI_GCONF_WIRELESS_NETWORKS_PATH, gconf_client_add_dir (app_info->gconf_client, NMI_GCONF_WIRELESS_NETWORKS_PATH,
GCONF_CLIENT_PRELOAD_NONE, NULL); GCONF_CLIENT_PRELOAD_NONE, NULL);
notify_id = gconf_client_notify_add (app_info->gconf_client, NMI_GCONF_WIRELESS_NETWORKS_PATH, notify_id = gconf_client_notify_add (app_info->gconf_client, NMI_GCONF_WIRELESS_NETWORKS_PATH,
nmi_gconf_notify_callback, app_info, NULL, NULL); nmi_gconf_networks_notify_callback, app_info, NULL, NULL);
notify_id = gconf_client_notify_add (app_info->gconf_client, NMI_GCONF_VPN_CONNECTIONS_PATH,
nmi_gconf_vpn_connections_notify_callback, app_info, NULL, NULL);
/* Create our own dbus service */ /* Create our own dbus service */
err = nmi_dbus_service_init (dbus_connection, app_info); err = nmi_dbus_service_init (dbus_connection, app_info);

View File

@@ -32,6 +32,8 @@
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
#include <gconf/gconf-client.h> #include <gconf/gconf-client.h>
#define NMI_GCONF_VPN_CONNECTIONS_PATH "/system/networking/vpn_connections"
struct NMIAppInfo struct NMIAppInfo
{ {
GladeXML *passphrase_dialog; GladeXML *passphrase_dialog;

View File

@@ -35,7 +35,6 @@
#include "NetworkManagerInfoVPN.h" #include "NetworkManagerInfoVPN.h"
#include "nm-utils.h" #include "nm-utils.h"
/* /*
* nmi_show_warning_dialog * nmi_show_warning_dialog
* *
@@ -332,7 +331,7 @@ static DBusMessage *nmi_dbus_get_networks (NMIAppInfo *info, DBusMessage *messag
/* /*
* nmi_dbus_get_network * nmi_dbus_get_network_properties
* *
* Returns the properties of a specific wireless network from gconf * Returns the properties of a specific wireless network from gconf
* *
@@ -499,6 +498,279 @@ static DBusMessage *nmi_dbus_get_network_properties (NMIAppInfo *info, DBusMessa
} }
/*
* nmi_dbus_signal_update_vpn_connection
*
* Signal NetworkManager that it needs to update info associated with a particular
* VPN connection.
*
*/
void nmi_dbus_signal_update_vpn_connection (DBusConnection *connection, const char *name)
{
DBusMessage *message;
g_return_if_fail (connection != NULL);
g_return_if_fail (name != NULL);
if (!(message = dbus_message_new_signal (NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "VPNConnectionUpdate")))
{
nm_warning ("nmi_dbus_signal_update_vpn_connection(): Not enough memory for new dbus message!");
return;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
if (!dbus_connection_send (connection, message, NULL))
nm_warning ("nmi_dbus_signal_update_vpn_connection(): Could not raise the 'VPNConnectionUpdate' signal!");
dbus_message_unref (message);
}
/*
* nmi_dbus_get_vpn_connections
*
* Grab a list of VPN connections from GConf and return it in the form
* of a string array in a dbus message.
*
*/
static DBusMessage *nmi_dbus_get_vpn_connections (NMIAppInfo *info, DBusMessage *message)
{
GSList *dir_list = NULL;
GSList *element = NULL;
DBusError error;
DBusMessage *reply_message = NULL;
DBusMessageIter iter;
DBusMessageIter iter_array;
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
dbus_error_init (&error);
/* List all VPN connections that gconf knows about */
element = dir_list = gconf_client_all_dirs (info->gconf_client, NMI_GCONF_VPN_CONNECTIONS_PATH, NULL);
if (!dir_list)
{
reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "NoVPNConnections",
"There are no VPN connections stored.");
}
else
{
gboolean value_added = FALSE;
reply_message = dbus_message_new_method_return (message);
dbus_message_iter_init_append (reply_message, &iter);
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_array);
/* Append the essid of every allowed or ignored access point we know of
* to a string array in the dbus message.
*/
while (element)
{
char key[100];
GConfValue *value;
g_snprintf (&key[0], 99, "%s/name", (char *)(element->data));
value = gconf_client_get (info->gconf_client, key, NULL);
if (value && gconf_value_get_string (value))
{
const gchar *essid;
essid = gconf_value_get_string (value);
dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &essid);
value_added = TRUE;
gconf_value_free (value);
}
g_free (element->data);
element = element->next;
}
g_slist_free (dir_list);
dbus_message_iter_close_container (&iter, &iter_array);
if (!value_added)
{
dbus_message_unref (reply_message);
reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "NoVPNConnections",
"There are no VPN connections stored.");
}
}
return (reply_message);
}
/*
* nmi_dbus_get_vpn_connection_properties
*
* Returns the properties of a specific VPN connection from gconf
*
*/
static DBusMessage *nmi_dbus_get_vpn_connection_properties (NMIAppInfo *info, DBusMessage *message)
{
DBusMessage *reply = NULL;
gchar *gconf_key = NULL;
char *vpn_connection = NULL;
GConfValue *value;
DBusError error;
char *escaped_name;
char *name = NULL;
char *service_name = NULL;
char *user_name = NULL;
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
dbus_error_init (&error);
if ( !dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &vpn_connection, DBUS_TYPE_INVALID)
|| (strlen (vpn_connection) <= 0))
{
reply = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "InvalidArguments",
"NetworkManagerInfo::getVPNConnectionProperties called with invalid arguments.");
return (reply);
}
escaped_name = gconf_escape_key (vpn_connection, strlen (vpn_connection));
/* User-visible name of connection */
gconf_key = g_strdup_printf ("%s/%s/name", NMI_GCONF_VPN_CONNECTIONS_PATH, escaped_name);
if ((value = gconf_client_get (info->gconf_client, gconf_key, NULL)))
{
name = g_strdup (gconf_value_get_string (value));
gconf_value_free (value);
}
g_free (gconf_key);
/* Service name of connection */
gconf_key = g_strdup_printf ("%s/%s/service_name", NMI_GCONF_VPN_CONNECTIONS_PATH, escaped_name);
if ((value = gconf_client_get (info->gconf_client, gconf_key, NULL)))
{
service_name = g_strdup (gconf_value_get_string (value));
gconf_value_free (value);
}
g_free (gconf_key);
/* User name of connection */
gconf_key = g_strdup_printf ("%s/%s/user_name", NMI_GCONF_VPN_CONNECTIONS_PATH, escaped_name);
if ((value = gconf_client_get (info->gconf_client, gconf_key, NULL)))
{
user_name = g_strdup (gconf_value_get_string (value));
gconf_value_free (value);
}
g_free (gconf_key);
if (!name)
{
reply = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "BadVPNConnectionData",
"NetworkManagerInfo::getVPNConnectionProperties could not access the name for connection '%s'", vpn_connection);
}
else if (!service_name)
{
reply = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "BadVPNConnectionData",
"NetworkManagerInfo::getVPNConnectionProperties could not access the service name for connection '%s'", vpn_connection);
}
else if (!user_name)
{
reply = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "BadVPNConnectionData",
"NetworkManagerInfo::getVPNConnectionProperties could not access the user name for connection '%s'", vpn_connection);
}
else
{
DBusMessageIter iter, array_iter;
reply = dbus_message_new_method_return (message);
dbus_message_iter_init_append (reply, &iter);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &user_name);
}
g_free (user_name);
g_free (service_name);
g_free (name);
g_free (escaped_name);
return (reply);
}
/*
* nmi_dbus_get_vpn_connection_vpn_data
*
* Returns vpn-daemon specific properties for a particular VPN connection.
*
*/
static DBusMessage *nmi_dbus_get_vpn_connection_vpn_data (NMIAppInfo *info, DBusMessage *message)
{
DBusMessage *reply = NULL;
gchar *gconf_key = NULL;
char *name = NULL;
GConfValue *vpn_data_value = NULL;
GConfValue *value = NULL;
DBusError error;
char *escaped_name;
DBusMessageIter iter, array_iter;
GSList *elt;
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
dbus_error_init (&error);
if ( !dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)
|| (strlen (name) <= 0))
{
reply = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "InvalidArguments",
"NetworkManagerInfo::getVPNConnectionVPNData called with invalid arguments.");
return reply;
}
escaped_name = gconf_escape_key (name, strlen (name));
/* User-visible name of connection */
gconf_key = g_strdup_printf ("%s/%s/name", NMI_GCONF_VPN_CONNECTIONS_PATH, escaped_name);
if (!(value = gconf_client_get (info->gconf_client, gconf_key, NULL)))
{
reply = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "BadVPNConnectionData",
"NetworkManagerInfo::getVPNConnectionVPNData could not access the name for connection '%s'", name);
return reply;
}
gconf_value_free (value);
g_free (gconf_key);
/* Grab vpn-daemon specific data */
gconf_key = g_strdup_printf ("%s/%s/vpn_data", NMI_GCONF_VPN_CONNECTIONS_PATH, escaped_name);
if (!(vpn_data_value = gconf_client_get (info->gconf_client, gconf_key, NULL))
|| !(vpn_data_value->type == GCONF_VALUE_LIST)
|| !(gconf_value_get_list_type (vpn_data_value) == GCONF_VALUE_STRING))
{
reply = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "BadVPNConnectionData",
"NetworkManagerInfo::getVPNConnectionVPNData could not access the VPN data for connection '%s'", name);
if (vpn_data_value)
gconf_value_free (vpn_data_value);
return reply;
}
g_free (gconf_key);
reply = dbus_message_new_method_return (message);
dbus_message_iter_init_append (reply, &iter);
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter);
for (elt = gconf_value_get_list (vpn_data_value); elt; elt = g_slist_next (elt))
{
const char *string = gconf_value_get_string ((GConfValue *)elt->data);
if (string)
dbus_message_iter_append_basic (&array_iter, DBUS_TYPE_STRING, &string);
}
dbus_message_iter_close_container (&iter, &array_iter);
gconf_value_free (vpn_data_value);
g_free (escaped_name);
return (reply);
}
/* /*
* nmi_dbus_update_network_auth_method * nmi_dbus_update_network_auth_method
* *
@@ -707,6 +979,12 @@ static DBusHandlerResult nmi_dbus_nmi_message_handler (DBusConnection *connectio
nmi_dbus_update_network_auth_method (info, message); nmi_dbus_update_network_auth_method (info, message);
else if (strcmp ("addNetworkAddress", method) == 0) else if (strcmp ("addNetworkAddress", method) == 0)
nmi_dbus_add_network_address (info, message); nmi_dbus_add_network_address (info, message);
else if (strcmp ("getVPNConnections", method) == 0)
reply_message = nmi_dbus_get_vpn_connections (info, message);
else if (strcmp ("getVPNConnectionProperties", method) == 0)
reply_message = nmi_dbus_get_vpn_connection_properties (info, message);
else if (strcmp ("getVPNConnectionVPNData", method) == 0)
reply_message = nmi_dbus_get_vpn_connection_vpn_data (info, message);
else else
{ {
reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "UnknownMethod", reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_INTERFACE, "UnknownMethod",

View File

@@ -43,4 +43,6 @@ void nmi_dbus_return_vpn_password (DBusConnection *connection, DBusMessage *me
void nmi_dbus_signal_update_network (DBusConnection *connection, const char *network, NMNetworkType 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 #endif

View File

@@ -1,15 +0,0 @@
namedconf_DATA = named.conf
namedconfdir = $(pkgdatadir)
EXTRA_DIST = $(namedconf_DATA)
INCLUDES = -I${top_srcdir}/utils
noinst_LTLIBRARIES = libnamed.la
libnamed_la_SOURCES = nm-named-manager.h nm-named-manager.c
libnamed_la_CPPFLAGS = $(DBUS_CFLAGS) $(GTHREAD_CFLAGS) -DNM_PKGDATADIR=\"$(pkgdatadir)\" -DNM_LOCALSTATEDIR=\"$(localstatedir)\"
libnamed_la_LIBADD = $(DBUS_LIBS) $(GTHREAD_LIBS)

View File

@@ -20,6 +20,7 @@ libnm_notification_applet_la_CPPFLAGS = \
$(GCONF_CFLAGS) \ $(GCONF_CFLAGS) \
$(LIBGNOMEUI_CFLAGS) \ $(LIBGNOMEUI_CFLAGS) \
$(PANEL_APPLET_CFLAGS) \ $(PANEL_APPLET_CFLAGS) \
$(GNOMEKEYRING_CFLAGS) \
-DICONDIR=\""$(datadir)/pixmaps"\" \ -DICONDIR=\""$(datadir)/pixmaps"\" \
-DGLADEDIR=\""$(gladedir)"\" \ -DGLADEDIR=\""$(gladedir)"\" \
-DDBUS_API_SUBJECT_TO_CHANGE \ -DDBUS_API_SUBJECT_TO_CHANGE \
@@ -43,6 +44,10 @@ libnm_notification_applet_la_SOURCES = \
gtkcellview.h \ gtkcellview.h \
gtkcellrendererprogress.c \ gtkcellrendererprogress.c \
gtkcellrendererprogress.h \ gtkcellrendererprogress.h \
nmwa-vpn-password-dialog.c \
nmwa-vpn-password-dialog.h \
nmwa-vpn-connection.c \
nmwa-vpn-connection.h \
$(NULL) $(NULL)
libnm_notification_applet_la_SOURCES += \ libnm_notification_applet_la_SOURCES += \
@@ -59,6 +64,7 @@ libnm_notification_applet_la_LIBADD = \
$(GTK_LIBS) \ $(GTK_LIBS) \
$(GCONF_LIBS) \ $(GCONF_LIBS) \
$(LIBGNOMEUI_LIBS) \ $(LIBGNOMEUI_LIBS) \
$(GNOMEKEYRING_LIBS) \
$(NULL) $(NULL)
libexec_PROGRAMS = NetworkManagerNotification libexec_PROGRAMS = NetworkManagerNotification

View File

@@ -56,6 +56,8 @@
#include "NMWirelessAppletDbus.h" #include "NMWirelessAppletDbus.h"
#include "NMWirelessAppletOtherNetworkDialog.h" #include "NMWirelessAppletOtherNetworkDialog.h"
#include "menu-info.h" #include "menu-info.h"
#include "nmwa-vpn-password-dialog.h"
#include "nmwa-vpn-connection.h"
#define CFG_UPDATE_INTERVAL 1 #define CFG_UPDATE_INTERVAL 1
#define NMWA_GCONF_PATH "/apps/NetworkManagerNotification" #define NMWA_GCONF_PATH "/apps/NetworkManagerNotification"
@@ -176,6 +178,119 @@ void nmwa_about_cb (NMWirelessApplet *applet)
#endif #endif
} }
static void vpn_login_failure_dialog_close_cb (GtkWidget *dialog, gpointer user_data)
{
char *message;
if ((message = g_object_get_data (G_OBJECT (dialog), "message")))
{
g_object_set_data (G_OBJECT (dialog), "message", NULL);
g_free (message);
}
gtk_widget_destroy (dialog);
}
/*
* nmwa_show_vpn_login_failure_dialog
*
* Present the VPN login failure dialog.
*
*/
static gboolean nmwa_show_vpn_login_failure_dialog (char *message)
{
GtkWidget *dialog;
g_return_val_if_fail (message != NULL, FALSE);
dialog = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, message, NULL);
g_signal_connect (dialog, "response", G_CALLBACK (vpn_login_failure_dialog_close_cb), NULL);
g_signal_connect (dialog, "close", G_CALLBACK (vpn_login_failure_dialog_close_cb), NULL);
g_object_set_data (G_OBJECT (dialog), "message", message);
gtk_widget_show_all (dialog);
return FALSE;
}
/*
* nmwa_schedule_vpn_login_failure_dialog
*
* Schedule display of the VPN Login Failure dialog.
*
*/
void nmwa_schedule_vpn_login_failure_dialog (NMWirelessApplet *applet, const char *vpn_name, const char *error_msg)
{
char *msg;
g_return_if_fail (applet != NULL);
g_return_if_fail (vpn_name != NULL);
g_return_if_fail (error_msg != NULL);
msg = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">VPN Login Failure</span>\n\nCould not connection to the"
"VPN connection '%s' due to a login failure.\n\nThe VPN service said: \"%s\""), vpn_name, error_msg);
g_idle_add ((GSourceFunc) nmwa_show_vpn_login_failure_dialog, msg);
}
static void vpn_login_banner_dialog_close_cb (GtkWidget *dialog, gpointer user_data)
{
char *message;
if ((message = g_object_get_data (G_OBJECT (dialog), "message")))
{
g_object_set_data (G_OBJECT (dialog), "message", NULL);
g_free (message);
}
gtk_widget_destroy (dialog);
}
/*
* nmwa_show_vpn_login_banner_dialog
*
* Present the VPN login banner dialog.
*
*/
static gboolean nmwa_show_vpn_login_banner_dialog (char *message)
{
GtkWidget *dialog;
g_return_val_if_fail (message != NULL, FALSE);
dialog = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, message, NULL);
g_signal_connect (dialog, "response", G_CALLBACK (vpn_login_failure_dialog_close_cb), NULL);
g_signal_connect (dialog, "close", G_CALLBACK (vpn_login_failure_dialog_close_cb), NULL);
g_object_set_data (G_OBJECT (dialog), "message", message);
gtk_widget_show_all (dialog);
return FALSE;
}
/*
* nmwa_schedule_vpn_login_banner_dialog
*
* Schedule display of the VPN Login Banner dialog.
*
*/
void nmwa_schedule_vpn_login_banner_dialog (NMWirelessApplet *applet, const char *vpn_name, const char *banner)
{
char *msg;
g_return_if_fail (applet != NULL);
g_return_if_fail (vpn_name != NULL);
g_return_if_fail (banner != NULL);
msg = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">VPN Login Message</span>\n\n"
"VPN connection '%s' said:\n\n\"%s\""), vpn_name, banner);
g_idle_add ((GSourceFunc) nmwa_show_vpn_login_failure_dialog, msg);
}
/* /*
* nmwa_driver_notify_get_ignored_list * nmwa_driver_notify_get_ignored_list
* *
@@ -501,6 +616,29 @@ out:
} }
static void nmwa_set_icon (NMWirelessApplet *applet, GdkPixbuf *new_icon)
{
GdkPixbuf *composite;
g_return_if_fail (applet != NULL);
g_return_if_fail (new_icon != NULL);
composite = gdk_pixbuf_copy (new_icon);
if (applet->gui_active_vpn)
{
int dest_x = gdk_pixbuf_get_width (new_icon) - gdk_pixbuf_get_width (applet->vpn_lock_icon);
int dest_y = gdk_pixbuf_get_height (new_icon) - gdk_pixbuf_get_height (applet->vpn_lock_icon) - 2;
gdk_pixbuf_composite (applet->vpn_lock_icon, composite, dest_x, dest_y, gdk_pixbuf_get_width (applet->vpn_lock_icon),
gdk_pixbuf_get_height (applet->vpn_lock_icon), dest_x, dest_y, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
}
gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), composite);
g_object_unref (composite);
}
static gboolean static gboolean
animation_timeout (NMWirelessApplet *applet) animation_timeout (NMWirelessApplet *applet)
{ {
@@ -509,16 +647,14 @@ animation_timeout (NMWirelessApplet *applet)
case (APPLET_STATE_WIRED_CONNECTING): case (APPLET_STATE_WIRED_CONNECTING):
if (applet->animation_step >= NUM_WIRED_CONNECTING_FRAMES) if (applet->animation_step >= NUM_WIRED_CONNECTING_FRAMES)
applet->animation_step = 0; applet->animation_step = 0;
gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), nmwa_set_icon (applet, applet->wired_connecting_icons[applet->animation_step]);
applet->wired_connecting_icons[applet->animation_step]);
applet->animation_step ++; applet->animation_step ++;
break; break;
case (APPLET_STATE_WIRELESS_CONNECTING): case (APPLET_STATE_WIRELESS_CONNECTING):
if (applet->animation_step >= NUM_WIRELESS_CONNECTING_FRAMES) if (applet->animation_step >= NUM_WIRELESS_CONNECTING_FRAMES)
applet->animation_step = 0; applet->animation_step = 0;
gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), nmwa_set_icon (applet, applet->wireless_connecting_icons[applet->animation_step]);
applet->wireless_connecting_icons[applet->animation_step]);
applet->animation_step ++; applet->animation_step ++;
break; break;
@@ -529,8 +665,7 @@ animation_timeout (NMWirelessApplet *applet)
case (APPLET_STATE_WIRELESS_SCANNING): case (APPLET_STATE_WIRELESS_SCANNING):
if (applet->animation_step >= NUM_WIRELESS_SCANNING_FRAMES) if (applet->animation_step >= NUM_WIRELESS_SCANNING_FRAMES)
applet->animation_step = 0; applet->animation_step = 0;
gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), nmwa_set_icon (applet, applet->wireless_scanning_icons[applet->animation_step]);
applet->wireless_scanning_icons[applet->animation_step]);
applet->animation_step ++; applet->animation_step ++;
break; break;
@@ -580,11 +715,11 @@ inline void print_state (AppletState state)
* and what our icon on the panel should look like for each type. * and what our icon on the panel should look like for each type.
* *
*/ */
static void static void nmwa_update_state (NMWirelessApplet *applet)
nmwa_update_state (NMWirelessApplet *applet)
{ {
gboolean show_applet = TRUE; gboolean show_applet = TRUE;
gboolean need_animation = FALSE; gboolean need_animation = FALSE;
gboolean active_vpn = FALSE;
GdkPixbuf *pixbuf = NULL; GdkPixbuf *pixbuf = NULL;
gint strength = -1; gint strength = -1;
char *tip = NULL; char *tip = NULL;
@@ -702,7 +837,7 @@ nmwa_update_state (NMWirelessApplet *applet)
if (need_animation) if (need_animation)
applet->animation_id = g_timeout_add (100, (GSourceFunc) (animation_timeout), applet); applet->animation_id = g_timeout_add (100, (GSourceFunc) (animation_timeout), applet);
else else
gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), pixbuf); nmwa_set_icon (applet, pixbuf);
} }
@@ -950,6 +1085,55 @@ static void nmwa_menu_item_activate (GtkMenuItem *item, gpointer user_data)
} }
/*
* nmwa_menu_vpn_item_activate
*
* Signal function called when user clicks on a VPN menu item
*
*/
static void nmwa_menu_vpn_item_activate (GtkMenuItem *item, gpointer user_data)
{
NMWirelessApplet *applet = (NMWirelessApplet *)user_data;
char *tag;
g_return_if_fail (item != NULL);
g_return_if_fail (applet != NULL);
if ((tag = g_object_get_data (G_OBJECT (item), "vpn")))
{
VPNConnection *vpn = (VPNConnection *)tag;
const char *name = nmwa_vpn_connection_get_name (vpn);
char *password = NULL;
if (vpn != applet->gui_active_vpn)
{
if ((password = nmwa_vpn_request_password (applet, name, nmwa_vpn_connection_get_user_name (vpn), FALSE)))
{
nmwa_dbus_vpn_activate_connection (applet->connection, name, password);
g_free (password);
}
}
}
}
/*
* nmwa_menu_disconnect_vpn_item_activate
*
* Signal function called when user clicks on a VPN menu item
*
*/
static void nmwa_menu_disconnect_vpn_item_activate (GtkMenuItem *item, gpointer user_data)
{
NMWirelessApplet *applet = (NMWirelessApplet *)user_data;
g_return_if_fail (item != NULL);
g_return_if_fail (applet != NULL);
nmwa_dbus_vpn_deactivate_connection (applet->connection);
}
/* /*
* nmwa_menu_add_separator_item * nmwa_menu_add_separator_item
* *
@@ -1117,13 +1301,62 @@ static void nmwa_menu_device_add_networks (GtkWidget *menu, NetworkDevice *dev,
g_object_set_data (G_OBJECT (gtk_item), "network", g_strdup (net->essid)); g_object_set_data (G_OBJECT (gtk_item), "network", g_strdup (net->essid));
g_object_set_data (G_OBJECT (gtk_item), "nm_device", g_strdup (dev->nm_device)); g_object_set_data (G_OBJECT (gtk_item), "nm_device", g_strdup (dev->nm_device));
g_object_set_data (G_OBJECT (gtk_item), "nm-item-data", item); g_object_set_data (G_OBJECT (gtk_item), "nm-item-data", item);
g_signal_connect(G_OBJECT (gtk_item), "activate", G_CALLBACK (nmwa_menu_item_activate), applet); g_signal_connect (G_OBJECT (gtk_item), "activate", G_CALLBACK (nmwa_menu_item_activate), applet);
gtk_widget_show (GTK_WIDGET (gtk_item)); gtk_widget_show (GTK_WIDGET (gtk_item));
} }
} }
/*
* nmwa_menu_add_devices
*
*/
static void nmwa_menu_add_vpn_menu (GtkWidget *menu, NMWirelessApplet *applet)
{
GtkMenuItem *item;
GtkMenu *vpn_menu;
GtkMenuItem *other_item;
GSList *elt;
g_return_if_fail (menu != NULL);
g_return_if_fail (applet != NULL);
item = GTK_MENU_ITEM (gtk_menu_item_new_with_label (_("VPN Connections")));
vpn_menu = GTK_MENU (gtk_menu_new ());
for (elt = applet->gui_vpn_connections; elt; elt = g_slist_next (elt))
{
GtkCheckMenuItem *vpn_item;
VPNConnection *vpn = elt->data;
const char *vpn_name = nmwa_vpn_connection_get_name (vpn);
vpn_item = GTK_CHECK_MENU_ITEM (gtk_check_menu_item_new_with_label (vpn_name));
nmwa_vpn_connection_ref (vpn, __FUNCTION__);
g_object_set_data (G_OBJECT (vpn_item), "vpn", vpn);
if (applet->gui_active_vpn && (strcmp (vpn_name, nmwa_vpn_connection_get_name (applet->gui_active_vpn)) == 0))
gtk_check_menu_item_set_active (vpn_item, TRUE);
g_signal_connect (G_OBJECT (vpn_item), "activate", G_CALLBACK (nmwa_menu_vpn_item_activate), applet);
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (vpn_item));
}
other_item = GTK_MENU_ITEM (gtk_separator_menu_item_new ());
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (other_item));
other_item = GTK_MENU_ITEM (gtk_menu_item_new_with_label (_("Disconnect VPN...")));
g_signal_connect (G_OBJECT (other_item), "activate", G_CALLBACK (nmwa_menu_disconnect_vpn_item_activate), applet);
if (!applet->gui_active_vpn)
gtk_widget_set_sensitive (GTK_WIDGET (other_item), FALSE);
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (other_item));
gtk_menu_item_set_submenu (item, GTK_WIDGET (vpn_menu));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (item));
gtk_widget_show_all (GTK_WIDGET (item));
}
/* /*
* nmwa_menu_add_devices * nmwa_menu_add_devices
* *
@@ -1184,6 +1417,9 @@ static void nmwa_menu_add_devices (GtkWidget *menu, NMWirelessApplet *applet)
} }
} }
nmwa_menu_add_separator_item (menu);
nmwa_menu_add_vpn_menu (menu, applet);
if (n_wireless_interfaces > 0) if (n_wireless_interfaces > 0)
{ {
/* Add the "Other wireless network..." entry */ /* Add the "Other wireless network..." entry */
@@ -1220,13 +1456,11 @@ static void nmwa_set_wireless_enabled_cb (GtkWidget *widget, NMWirelessApplet *a
static void nmwa_menu_item_data_free (GtkWidget *menu_item, gpointer data) static void nmwa_menu_item_data_free (GtkWidget *menu_item, gpointer data)
{ {
char *tag; char *tag;
GtkWidget *menu; GtkMenu *menu;
g_return_if_fail (menu_item != NULL); g_return_if_fail (menu_item != NULL);
g_return_if_fail (data != NULL); g_return_if_fail (data != NULL);
menu = GTK_WIDGET(data);
if ((tag = g_object_get_data (G_OBJECT (menu_item), "network"))) if ((tag = g_object_get_data (G_OBJECT (menu_item), "network")))
{ {
g_object_set_data (G_OBJECT (menu_item), "network", NULL); g_object_set_data (G_OBJECT (menu_item), "network", NULL);
@@ -1251,6 +1485,21 @@ static void nmwa_menu_item_data_free (GtkWidget *menu_item, gpointer data)
g_free (tag); g_free (tag);
} }
if ((tag = g_object_get_data (G_OBJECT (menu_item), "vpn")))
{
g_object_set_data (G_OBJECT (menu_item), "vpn", NULL);
nmwa_vpn_connection_unref ((VPNConnection *)tag, __FUNCTION__);
}
if ((tag = g_object_get_data (G_OBJECT (menu_item), "disconnect")))
{
g_object_set_data (G_OBJECT (menu_item), "disconnect", NULL);
g_free (tag);
}
if ((menu = GTK_MENU (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item)))))
gtk_container_foreach (GTK_CONTAINER (menu), nmwa_menu_item_data_free, menu);
gtk_widget_destroy (menu_item); gtk_widget_destroy (menu_item);
} }
@@ -1665,6 +1914,7 @@ nmwa_icons_free (NMWirelessApplet *applet)
g_object_unref (applet->wireless_connecting_icons[i]); g_object_unref (applet->wireless_connecting_icons[i]);
for (i = 0; i < NUM_WIRELESS_SCANNING_FRAMES; i++) for (i = 0; i < NUM_WIRELESS_SCANNING_FRAMES; i++)
g_object_unref (applet->wireless_scanning_icons[i]); g_object_unref (applet->wireless_scanning_icons[i]);
g_object_unref (applet->vpn_lock_icon);
} }
static void static void
@@ -1720,6 +1970,7 @@ nmwa_icons_load_from_disk (NMWirelessApplet *applet, GtkIconTheme *icon_theme)
applet->wireless_scanning_icons[13] = gtk_icon_theme_load_icon (icon_theme, "nm-detect14", icon_size, 0, NULL); applet->wireless_scanning_icons[13] = gtk_icon_theme_load_icon (icon_theme, "nm-detect14", icon_size, 0, NULL);
applet->wireless_scanning_icons[14] = gtk_icon_theme_load_icon (icon_theme, "nm-detect15", icon_size, 0, NULL); applet->wireless_scanning_icons[14] = gtk_icon_theme_load_icon (icon_theme, "nm-detect15", icon_size, 0, NULL);
applet->wireless_scanning_icons[15] = gtk_icon_theme_load_icon (icon_theme, "nm-detect16", icon_size, 0, NULL); applet->wireless_scanning_icons[15] = gtk_icon_theme_load_icon (icon_theme, "nm-detect16", icon_size, 0, NULL);
applet->vpn_lock_icon = gtk_icon_theme_load_icon (icon_theme, "nm-vpn-lock", icon_size, 0, NULL);
} }
static void static void

View File

@@ -80,6 +80,10 @@ typedef struct
GSList *networks; GSList *networks;
} NetworkDevice; } NetworkDevice;
typedef struct VPNConnection VPNConnection;
#ifdef BUILD_NOTIFICATION_ICON #ifdef BUILD_NOTIFICATION_ICON
#define NM_TYPE_WIRELESS_APPLET (nmwa_get_type()) #define NM_TYPE_WIRELESS_APPLET (nmwa_get_type())
@@ -126,10 +130,14 @@ typedef struct
GSList *gui_device_list; GSList *gui_device_list;
NetworkDevice *gui_active_device; NetworkDevice *gui_active_device;
char *gui_nm_status; char *gui_nm_status;
GSList *gui_vpn_connections;
VPNConnection *gui_active_vpn;
GSList *dbus_device_list; GSList *dbus_device_list;
NetworkDevice *dbus_active_device; NetworkDevice *dbus_active_device;
char *dbus_nm_status; char *dbus_nm_status;
GSList *dbus_vpn_connections;
VPNConnection *dbus_active_vpn;
GdkPixbuf *no_nm_icon; GdkPixbuf *no_nm_icon;
GdkPixbuf *no_connection_icon; GdkPixbuf *no_connection_icon;
@@ -146,6 +154,7 @@ typedef struct
GdkPixbuf *wireless_connecting_icons[NUM_WIRELESS_CONNECTING_FRAMES]; GdkPixbuf *wireless_connecting_icons[NUM_WIRELESS_CONNECTING_FRAMES];
#define NUM_WIRELESS_SCANNING_FRAMES 16 #define NUM_WIRELESS_SCANNING_FRAMES 16
GdkPixbuf *wireless_scanning_icons[NUM_WIRELESS_SCANNING_FRAMES]; GdkPixbuf *wireless_scanning_icons[NUM_WIRELESS_SCANNING_FRAMES];
GdkPixbuf *vpn_lock_icon;
/* Animation stuff */ /* Animation stuff */
int animation_step; int animation_step;
@@ -155,6 +164,7 @@ typedef struct
GtkWidget *pixmap; GtkWidget *pixmap;
GtkWidget *top_menu_item; GtkWidget *top_menu_item;
GtkWidget *dropdown_menu; GtkWidget *dropdown_menu;
GtkWidget *vpn_menu;
GtkWidget *event_box; GtkWidget *event_box;
GtkSizeGroup *encryption_size_group; GtkSizeGroup *encryption_size_group;
GtkTooltips *tooltips; GtkTooltips *tooltips;
@@ -172,11 +182,13 @@ typedef struct
GladeXML *xml; GladeXML *xml;
} DriverNotifyCBData; } DriverNotifyCBData;
NetworkDevice *nmwa_get_device_for_nm_device (GSList *dev_list, const char *nm_dev); NetworkDevice * nmwa_get_device_for_nm_device (GSList *dev_list, const char *nm_dev);
WirelessNetwork *nmwa_get_net_for_nm_net (NetworkDevice *dev, const char *net_path); WirelessNetwork * nmwa_get_net_for_nm_net (NetworkDevice *dev, const char *net_path);
WirelessNetwork *nmwa_get_net_by_essid (NetworkDevice *dev, const char *essid); WirelessNetwork * nmwa_get_net_by_essid (NetworkDevice *dev, const char *essid);
NMWirelessApplet *nmwa_new (void); NMWirelessApplet * nmwa_new (void);
void show_warning_dialog (gboolean error, gchar *mesg, ...); void show_warning_dialog (gboolean error, gchar *mesg, ...);
gboolean nmwa_driver_notify (gpointer user_data); gboolean nmwa_driver_notify (gpointer user_data);
void nmwa_schedule_vpn_login_failure_dialog (NMWirelessApplet *applet, const char *vpn_name, const char *error_msg);
void nmwa_schedule_vpn_login_banner_dialog (NMWirelessApplet *applet, const char *vpn_name, const char *banner);
#endif #endif

View File

@@ -29,6 +29,7 @@
#include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus-glib-lowlevel.h>
#include "NMWirelessAppletDbus.h" #include "NMWirelessAppletDbus.h"
#include "NMWirelessApplet.h" #include "NMWirelessApplet.h"
#include "nmwa-vpn-connection.h"
#include "nm-utils.h" #include "nm-utils.h"
@@ -118,6 +119,10 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons
ret = RETURN_SUCCESS; ret = RETURN_SUCCESS;
else if (!strcmp (error.name, NM_DBUS_NO_NETWORKS_ERROR)) else if (!strcmp (error.name, NM_DBUS_NO_NETWORKS_ERROR))
ret = RETURN_SUCCESS; ret = RETURN_SUCCESS;
else if (!strcmp (error.name, NM_DBUS_NO_ACTIVE_VPN_CONNECTION))
ret = RETURN_SUCCESS;
else if (!strcmp (error.name, NM_DBUS_NO_VPN_CONNECTIONS))
ret = RETURN_SUCCESS;
if ((ret != RETURN_SUCCESS) && (ret != RETURN_NO_NM)) if ((ret != RETURN_SUCCESS) && (ret != RETURN_NO_NM))
fprintf (stderr, "nmwa_dbus_call_nm_method(): %s raised on method '%s':\n %s\n\n", error.name, method, error.message); fprintf (stderr, "nmwa_dbus_call_nm_method(): %s raised on method '%s':\n %s\n\n", error.name, method, error.message);
@@ -258,6 +263,30 @@ static char * nmwa_dbus_get_active_network (NMWirelessApplet *applet, char *dev_
} }
/*
* nmwa_dbus_get_active_vpn_connection
*
* Return the name of the currently active VPN connection.
*
*/
static char * nmwa_dbus_get_active_vpn_connection (NMWirelessApplet *applet)
{
char *name = NULL;
switch (nmwa_dbus_call_nm_method (applet->connection, NM_DBUS_PATH_VPN, "getActiveVPNConnection", DBUS_TYPE_STRING, (void **)(&name), NULL))
{
case (RETURN_NO_NM):
applet->applet_state = APPLET_STATE_NO_NM;
break;
default:
break;
}
return (name);
}
/* /*
* nmwa_dbus_get_device_type * nmwa_dbus_get_device_type
* *
@@ -580,6 +609,35 @@ static char **nmwa_dbus_get_device_networks (NMWirelessApplet *applet, char *pat
} }
/*
* nmwa_dbus_get_vpn_connections
*
* Returns an array of wireless networks that the specified device knows about.
*
*/
static char **nmwa_dbus_get_vpn_connections (NMWirelessApplet *applet, int *num_items)
{
char **array = NULL;
int items;
switch (nmwa_dbus_call_nm_method (applet->connection, NM_DBUS_PATH_VPN, "getVPNConnections", NM_DBUS_TYPE_STRING_ARRAY, (void **)(&array), &items))
{
case (RETURN_NO_NM):
applet->applet_state = APPLET_STATE_NO_NM;
break;
case (RETURN_SUCCESS):
*num_items = items;
break;
default:
break;
}
return (array);
}
/* /*
* nmwa_dbus_get_hal_device_string_property * nmwa_dbus_get_hal_device_string_property
* *
@@ -704,6 +762,54 @@ void nmwa_dbus_set_device (DBusConnection *connection, const NetworkDevice *dev,
} }
/*
* nmwa_dbus_vpn_activate_connection
*
* Tell NetworkManager to activate a particular VPN connection.
*
*/
void nmwa_dbus_vpn_activate_connection (DBusConnection *connection, const char *name, const char *password)
{
DBusMessage *message;
g_return_if_fail (connection != NULL);
g_return_if_fail (name != NULL);
g_return_if_fail (password != NULL);
if ((message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH_VPN, NM_DBUS_INTERFACE_VPN, "activateVPNConnection")))
{
fprintf (stderr, "Activating VPN connection '%s'.\n", name);
dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &password, DBUS_TYPE_INVALID);
dbus_connection_send (connection, message, NULL);
}
else
fprintf (stderr, "nmwa_dbus_activate_vpn_connection(): Couldn't allocate the dbus message\n");
}
/*
* nmwa_dbus_deactivate_vpn_connection
*
* Tell NetworkManager to deactivate the currently active VPN connection.
*
*/
void nmwa_dbus_vpn_deactivate_connection (DBusConnection *connection)
{
DBusMessage *message;
g_return_if_fail (connection != NULL);
if ((message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH_VPN, NM_DBUS_INTERFACE_VPN, "deactivateVPNConnection")))
{
fprintf (stderr, "Deactivating the current VPN connection.\n");
dbus_connection_send (connection, message, NULL);
}
else
fprintf (stderr, "nmwa_dbus_activate_vpn_connection(): Couldn't allocate the dbus message\n");
}
/* /*
* nmwa_dbus_create_network * nmwa_dbus_create_network
* *
@@ -1149,6 +1255,17 @@ void nmwa_free_gui_data_model (NMWirelessApplet *applet)
g_free (applet->gui_nm_status); g_free (applet->gui_nm_status);
applet->gui_nm_status = NULL; applet->gui_nm_status = NULL;
} }
if (applet->gui_active_vpn)
nmwa_vpn_connection_unref (applet->gui_active_vpn, __FUNCTION__);
applet->gui_active_vpn = NULL;
if (applet->gui_vpn_connections)
{
g_slist_foreach (applet->gui_vpn_connections, (GFunc) nmwa_vpn_connection_unref, (gpointer)__FUNCTION__);
g_slist_free (applet->gui_vpn_connections);
applet->gui_vpn_connections = NULL;
}
} }
@@ -1172,6 +1289,17 @@ void nmwa_free_dbus_data_model (NMWirelessApplet *applet)
g_free (applet->dbus_nm_status); g_free (applet->dbus_nm_status);
applet->dbus_nm_status = NULL; applet->dbus_nm_status = NULL;
} }
if (applet->dbus_active_vpn)
nmwa_vpn_connection_unref (applet->dbus_active_vpn, __FUNCTION__);
applet->dbus_active_vpn = NULL;
if (applet->dbus_vpn_connections)
{
g_slist_foreach (applet->dbus_vpn_connections, (GFunc) nmwa_vpn_connection_unref, (gpointer)__FUNCTION__);
g_slist_free (applet->dbus_vpn_connections);
applet->dbus_vpn_connections = NULL;
}
} }
@@ -1214,6 +1342,23 @@ void nmwa_copy_data_model (NMWirelessApplet *applet)
/* active_device is just a pointer into the device list, no need to deep-copy it */ /* active_device is just a pointer into the device list, no need to deep-copy it */
applet->gui_active_device = act_dev; applet->gui_active_device = act_dev;
applet->gui_nm_status = g_strdup (applet->dbus_nm_status); applet->gui_nm_status = g_strdup (applet->dbus_nm_status);
/* Deep-copy VPN connections to GUI data model */
for (elt = applet->dbus_vpn_connections; elt; elt = g_slist_next (elt))
{
VPNConnection *src_vpn = elt->data;
VPNConnection *new_vpn = nmwa_vpn_connection_copy (src_vpn, __FUNCTION__);
if (new_vpn)
{
applet->gui_vpn_connections = g_slist_append (applet->gui_vpn_connections, new_vpn);
if (applet->dbus_active_vpn == src_vpn)
{
nmwa_vpn_connection_ref (new_vpn, __FUNCTION__);
applet->gui_active_vpn = new_vpn;
}
}
}
} }
@@ -1470,6 +1615,17 @@ sort_devices_function (gconstpointer a, gconstpointer b)
} }
static void nmwa_dbus_lock_and_copy_data_model (NMWirelessApplet *applet)
{
g_return_if_fail (applet != NULL);
/* Now copy the data over to the GUI side */
g_mutex_lock (applet->data_mutex);
nmwa_copy_data_model (applet);
g_mutex_unlock (applet->data_mutex);
}
/* /*
* nmwa_dbus_update_devices * nmwa_dbus_update_devices
* *
@@ -1484,6 +1640,8 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
gboolean adhoc = FALSE; gboolean adhoc = FALSE;
char *nm_act_dev; char *nm_act_dev;
char *nm_status; char *nm_status;
gboolean scanning_enabled;
gboolean wireless_enabled;
g_return_if_fail (applet->data_mutex != NULL); g_return_if_fail (applet->data_mutex != NULL);
@@ -1560,15 +1718,124 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
/* Notify user of issues with certain cards/drivers */ /* Notify user of issues with certain cards/drivers */
nmwa_dbus_check_drivers (applet); nmwa_dbus_check_drivers (applet);
/* Now copy the data over to the GUI side */
g_mutex_lock (applet->data_mutex);
nmwa_copy_data_model (applet);
applet->is_adhoc = adhoc; applet->is_adhoc = adhoc;
applet->scanning_enabled = nmwa_dbus_get_scanning_enabled (applet); applet->scanning_enabled = nmwa_dbus_get_scanning_enabled (applet);
applet->wireless_enabled = nmwa_dbus_get_wireless_enabled (applet); applet->wireless_enabled = nmwa_dbus_get_wireless_enabled (applet);
}
g_mutex_unlock (applet->data_mutex);
/*
* nmwa_dbus_update_one_vpn_connection
*
* Grab properties of one VPN connection from NetworkManager.
*
*/
void nmwa_dbus_update_one_vpn_connection (DBusConnection *connection, const char *name, NMWirelessApplet *applet, gboolean is_active)
{
DBusMessage *message;
DBusError error;
DBusMessage *reply;
const char *user_name = NULL;
DBusMessageIter iter;
g_return_if_fail (connection != NULL);
g_return_if_fail (applet != NULL);
g_return_if_fail (name != NULL);
if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH_VPN, NM_DBUS_INTERFACE_VPN, "getVPNConnectionProperties")))
{
nm_warning ("Couldn't allocate the dbus message");
return;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
/* Send message and get properties back from NetworkManager */
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
dbus_message_unref (message);
if (dbus_error_is_set (&error))
{
nm_warning ("nmwa_dbus_update_one_vpn_connection(): %s raised %s", error.name, error.message);
goto out;
}
else if (!reply)
goto out;
else
{
VPNConnection *vpn;
dbus_message_iter_init (reply, &iter);
/* Skip name, we already know it */
dbus_message_iter_next (&iter);
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
{
nm_warning ("Reply had wrong arguments: "
"(expected %u, got %u)\n", DBUS_TYPE_STRING,
dbus_message_iter_get_arg_type (&iter));
goto out;
}
dbus_message_iter_get_basic (&iter, &user_name);
if (!(vpn = nmwa_vpn_connection_find_by_name (applet->dbus_vpn_connections, name)))
{
vpn = nmwa_vpn_connection_new (name, __FUNCTION__);
nmwa_vpn_connection_set_user_name (vpn, user_name);
applet->dbus_vpn_connections = g_slist_append (applet->dbus_vpn_connections, vpn);
}
else
nmwa_vpn_connection_set_user_name (vpn, user_name);
if (is_active)
{
nmwa_vpn_connection_ref (vpn, __FUNCTION__);
applet->dbus_active_vpn = vpn;
}
}
out:
if (reply)
dbus_message_unref (reply);
}
/*
* nmwa_dbus_update_vpn_connections
*
* Grab a list of all VPN connections from NetworkManager.
*
*/
static void nmwa_dbus_update_vpn_connections (NMWirelessApplet *applet)
{
char **names;
int num_items = 0;
char *active;
g_return_if_fail (applet != NULL);
g_slist_foreach (applet->dbus_vpn_connections, (GFunc) nmwa_vpn_connection_unref, (gpointer)__FUNCTION__);
g_slist_free (applet->dbus_vpn_connections);
applet->dbus_vpn_connections = NULL;
if (applet->dbus_active_vpn)
nmwa_vpn_connection_unref (applet->dbus_active_vpn, __FUNCTION__);
applet->dbus_active_vpn = NULL;
active = nmwa_dbus_get_active_vpn_connection (applet);
if ((names = nmwa_dbus_get_vpn_connections (applet, &num_items)))
{
int i;
for (i = 0; i < num_items; i++)
{
gboolean is_active = active ? (strcmp (active, names[i]) == 0) : FALSE;
nmwa_dbus_update_one_vpn_connection (applet->connection, names[i], applet, is_active);
}
g_strfreev (names);
}
g_free (active);
} }
@@ -1594,11 +1861,11 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa
char *old_owner; char *old_owner;
char *new_owner; char *new_owner;
if ( dbus_message_get_args (message, &error, if (dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &service,
DBUS_TYPE_STRING, &old_owner, DBUS_TYPE_STRING, &old_owner,
DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_STRING, &new_owner,
DBUS_TYPE_INVALID)) DBUS_TYPE_INVALID))
{ {
gboolean old_owner_good = (old_owner && (strlen (old_owner) > 0)); gboolean old_owner_good = (old_owner && (strlen (old_owner) > 0));
gboolean new_owner_good = (new_owner && (strlen (new_owner) > 0)); gboolean new_owner_good = (new_owner && (strlen (new_owner) > 0));
@@ -1621,6 +1888,16 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa
} }
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkUpdate")) else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkUpdate"))
nmwa_dbus_device_update_one_network (applet, message); nmwa_dbus_device_update_one_network (applet, message);
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionUpdate"))
{
char *name;
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
{
nmwa_dbus_update_one_vpn_connection (applet->connection, name, applet, FALSE);
nmwa_dbus_lock_and_copy_data_model (applet);
}
}
else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNowActive") else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNowActive")
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNoLongerActive") || dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNoLongerActive")
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceActivating") || dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceActivating")
@@ -1628,6 +1905,29 @@ static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessa
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DevicesChanged")) || dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DevicesChanged"))
{ {
nmwa_dbus_update_devices (applet); nmwa_dbus_update_devices (applet);
nmwa_dbus_update_vpn_connections (applet);
nmwa_dbus_lock_and_copy_data_model (applet);
}
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionChange"))
{
nmwa_dbus_update_vpn_connections (applet);
nmwa_dbus_lock_and_copy_data_model (applet);
}
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNLoginFailed"))
{
char *vpn_name;
char *error_msg;
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_STRING, &error_msg, DBUS_TYPE_INVALID))
nmwa_schedule_vpn_login_failure_dialog (applet, vpn_name, error_msg);
}
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNLoginBanner"))
{
char *vpn_name;
char *banner;
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_STRING, &banner, DBUS_TYPE_INVALID))
nmwa_schedule_vpn_login_banner_dialog (applet, vpn_name, banner);
} }
else else
handled = FALSE; handled = FALSE;
@@ -1706,6 +2006,15 @@ static DBusConnection * nmwa_dbus_init (NMWirelessApplet *applet, GMainContext *
if (dbus_error_is_set (&error)) if (dbus_error_is_set (&error))
dbus_error_free (&error); dbus_error_free (&error);
dbus_bus_add_match(connection,
"type='signal',"
"interface='" NM_DBUS_INTERFACE_VPN "',"
"path='" NM_DBUS_PATH_VPN "',"
"sender='" NM_DBUS_SERVICE "'",
&error);
if (dbus_error_is_set (&error))
dbus_error_free (&error);
return (connection); return (connection);
} }
@@ -1731,6 +2040,8 @@ static gboolean nmwa_dbus_timeout_worker (gpointer user_data)
{ {
applet->applet_state = APPLET_STATE_NO_CONNECTION; applet->applet_state = APPLET_STATE_NO_CONNECTION;
nmwa_dbus_update_devices (applet); nmwa_dbus_update_devices (applet);
nmwa_dbus_update_vpn_connections (applet);
nmwa_dbus_lock_and_copy_data_model (applet);
} }
} }
@@ -1776,6 +2087,8 @@ gpointer nmwa_dbus_worker (gpointer user_data)
{ {
applet->applet_state = APPLET_STATE_NO_CONNECTION; applet->applet_state = APPLET_STATE_NO_CONNECTION;
nmwa_dbus_update_devices (applet); nmwa_dbus_update_devices (applet);
nmwa_dbus_update_vpn_connections (applet);
nmwa_dbus_lock_and_copy_data_model (applet);
} }
else else
applet->applet_state = APPLET_STATE_NO_NM; applet->applet_state = APPLET_STATE_NO_NM;

View File

@@ -59,5 +59,7 @@ void network_device_unref (NetworkDevice *dev);
void nmwa_free_gui_data_model (NMWirelessApplet *applet); void nmwa_free_gui_data_model (NMWirelessApplet *applet);
void nmwa_free_dbus_data_model (NMWirelessApplet *applet); void nmwa_free_dbus_data_model (NMWirelessApplet *applet);
void nmwa_dbus_vpn_activate_connection (DBusConnection *connection, const char *name, const char *password);
void nmwa_dbus_vpn_deactivate_connection(DBusConnection *connection);
#endif #endif

View File

@@ -42,6 +42,7 @@ smallicon_DATA= \
nm-signal-50.png \ nm-signal-50.png \
nm-signal-75.png \ nm-signal-75.png \
nm-signal-100.png \ nm-signal-100.png \
nm-vpn-lock.png \
$(NULL) $(NULL)
EXTRA_DIST=\ EXTRA_DIST=\

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

View File

@@ -0,0 +1,138 @@
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#include <string.h>
#include "nmwa-vpn-connection.h"
struct VPNConnection
{
int refcount;
char *name;
char *user_name;
};
VPNConnection *nmwa_vpn_connection_new (const char *name, const char *func)
{
VPNConnection *vpn;
g_return_val_if_fail (name != NULL, NULL);
vpn = g_malloc0 (sizeof (VPNConnection));
vpn->refcount = 1;
vpn->name = g_strdup (name);
return vpn;
}
VPNConnection *nmwa_vpn_connection_copy (VPNConnection *src_vpn, const char *func)
{
VPNConnection *dst_vpn;
g_return_val_if_fail (src_vpn != NULL, NULL);
dst_vpn = g_malloc0 (sizeof (VPNConnection));
dst_vpn->refcount = 1;
dst_vpn->name = g_strdup (src_vpn->name);
dst_vpn->user_name = src_vpn->user_name ? g_strdup (src_vpn->user_name) : NULL;
return dst_vpn;
}
void nmwa_vpn_connection_ref (VPNConnection *vpn, const char *func)
{
g_return_if_fail (vpn != NULL);
vpn->refcount++;
}
void nmwa_vpn_connection_unref (VPNConnection *vpn, const char *func)
{
g_return_if_fail (vpn != NULL);
vpn->refcount--;
if (vpn->refcount <= 0)
{
g_free (vpn->name);
g_free (vpn->user_name);
memset (vpn, 0, sizeof (VPNConnection));
g_free (vpn);
}
}
const char *nmwa_vpn_connection_get_name (VPNConnection *vpn)
{
g_return_val_if_fail (vpn != NULL, NULL);
return vpn->name;
}
const char *nmwa_vpn_connection_get_user_name (VPNConnection *vpn)
{
g_return_val_if_fail (vpn != NULL, NULL);
return vpn->user_name;
}
void nmwa_vpn_connection_set_user_name (VPNConnection *vpn, const char *user_name)
{
g_return_if_fail (vpn != NULL);
g_return_if_fail (user_name != NULL);
g_free (vpn->user_name);
vpn->user_name = g_strdup (user_name);
}
static int is_same_name (VPNConnection *vpn, const char *name)
{
if (!vpn || !name || !nmwa_vpn_connection_get_name (vpn))
return -1;
return strcmp (nmwa_vpn_connection_get_name (vpn), name);
}
VPNConnection *nmwa_vpn_connection_find_by_name (GSList *list, const char *name)
{
GSList *elt;
VPNConnection *vpn = NULL;
g_return_val_if_fail (name != NULL, NULL);
if (!list)
return NULL;
if ((elt = g_slist_find_custom (list, name, (GCompareFunc) is_same_name)))
vpn = elt->data;
return vpn;
}

View File

@@ -0,0 +1,39 @@
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#ifndef NMWA_VPN_CONNECTION_H
#define NMWA_VPN_CONNECTION_H
#include "NMWirelessApplet.h"
VPNConnection * nmwa_vpn_connection_new (const char *name, const char *func);
VPNConnection * nmwa_vpn_connection_copy (VPNConnection *vpn, const char *func);
void nmwa_vpn_connection_ref (VPNConnection *vpn, const char *func);
void nmwa_vpn_connection_unref (VPNConnection *vpn, const char *func);
const char * nmwa_vpn_connection_get_name (VPNConnection *vpn);
const char * nmwa_vpn_connection_get_user_name (VPNConnection *vpn);
void nmwa_vpn_connection_set_user_name (VPNConnection *vpn, const char *user_name);
VPNConnection * nmwa_vpn_connection_find_by_name (GSList *list, const char *name);
#endif

View File

@@ -0,0 +1,134 @@
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#include <config.h>
#include <libintl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <gnome-keyring.h>
#include <libgnomeui/gnome-password-dialog.h>
#ifndef _
#define _(x) dgettext (GETTEXT_PACKAGE, x)
#define N_(x) x
#endif
#include "NMWirelessApplet.h"
#include "nmwa-vpn-password-dialog.h"
#include "nm-utils.h"
static gboolean lookup_pass (const char *vpn, const char *username, char **password)
{
GList *result;
if (gnome_keyring_find_network_password_sync (username,
NULL,
vpn,
NULL,
"vpn",
NULL,
0,
&result) != GNOME_KEYRING_RESULT_OK)
return FALSE;
if (result)
{
GnomeKeyringNetworkPasswordData *data = result->data;
*password = g_strdup (data->password);
gnome_keyring_network_password_list_free (result);
return TRUE;
}
return FALSE;
}
static void save_vpn_password (const char *vpn, const char *keyring, const char *username, const char *password)
{
guint32 item_id;
GnomeKeyringResult keyring_result;
keyring_result = gnome_keyring_set_network_password_sync (NULL,
username,
NULL,
vpn,
NULL,
"vpn",
NULL,
0,
password,
&item_id);
if (keyring_result != GNOME_KEYRING_RESULT_OK)
{
nm_warning ("Couldn't store password in keyring, code %d",
(int) keyring_result);
}
}
char *nmwa_vpn_request_password (NMWirelessApplet *applet, const char *vpn, const char *username, gboolean retry)
{
GtkWidget *dialog;
char *prompt;
char *password = NULL;
g_return_val_if_fail (applet != NULL, NULL);
g_return_val_if_fail (vpn != NULL, NULL);
g_return_val_if_fail (username != NULL, NULL);
/* Use the system user name, since the VPN might have a different user name */
if (!retry && lookup_pass (vpn, g_get_user_name (), &password))
return password;
prompt = g_strdup_printf (_("You must log in to access the Virtual Private Network '%s'."), vpn);
dialog = gnome_password_dialog_new ("", prompt, username, NULL, FALSE);
g_free (prompt);
gnome_password_dialog_set_show_username (GNOME_PASSWORD_DIALOG (dialog), TRUE);
gnome_password_dialog_set_readonly_username (GNOME_PASSWORD_DIALOG (dialog), TRUE);
gnome_password_dialog_set_show_userpass_buttons (GNOME_PASSWORD_DIALOG (dialog), FALSE);
gnome_password_dialog_set_show_domain (GNOME_PASSWORD_DIALOG (dialog), FALSE);
gnome_password_dialog_set_show_remember (GNOME_PASSWORD_DIALOG (dialog), TRUE);
gtk_widget_show (dialog);
if (gnome_password_dialog_run_and_block (GNOME_PASSWORD_DIALOG (dialog)))
{
password = gnome_password_dialog_get_password (GNOME_PASSWORD_DIALOG (dialog));
switch (gnome_password_dialog_get_remember (GNOME_PASSWORD_DIALOG (dialog)))
{
case GNOME_PASSWORD_DIALOG_REMEMBER_SESSION:
save_vpn_password (vpn, "session", username, password);
break;
case GNOME_PASSWORD_DIALOG_REMEMBER_FOREVER:
save_vpn_password (vpn, NULL, username, password);
break;
default:
break;
}
}
gtk_widget_destroy (dialog);
return password;
}

View File

@@ -0,0 +1,29 @@
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#ifndef NMWA_VPN_PASSWORD_DIALOG_H
#define NMWA_VPN_PASSWORD_DIALOG_H
#include "NMWirelessApplet.h"
char *nmwa_vpn_request_password (NMWirelessApplet *applet, const char *vpn, const char *username, gboolean retry);
#endif

View File

@@ -1,9 +1,9 @@
INCLUDES = -I${top_srcdir} -I${top_srcdir}/named -I${top_srcdir}/utils SUBDIRS=named-manager vpn-manager backends
INCLUDES = -I${top_srcdir} -I./named-manager -I./vpn-manager -I${top_srcdir}/utils
bin_PROGRAMS = NetworkManager bin_PROGRAMS = NetworkManager
noinst_LTLIBRARIES = libnmbackend.la
NetworkManager_SOURCES = \ NetworkManager_SOURCES = \
NetworkManagerAP.c \ NetworkManagerAP.c \
NetworkManagerAP.h \ NetworkManagerAP.h \
@@ -28,6 +28,8 @@ NetworkManager_SOURCES = \
NetworkManagerDevice.c \ NetworkManagerDevice.c \
NetworkManagerDevice.h \ NetworkManagerDevice.h \
NetworkManagerDevicePrivate.h \ NetworkManagerDevicePrivate.h \
nm-ip4-config.c \
nm-ip4-config.h \
NetworkManager.c \ NetworkManager.c \
NetworkManagerMain.h \ NetworkManagerMain.h \
NetworkManagerPolicy.c \ NetworkManagerPolicy.c \
@@ -53,6 +55,7 @@ NetworkManager_CPPFLAGS = \
-DG_DISABLE_DEPRECATED \ -DG_DISABLE_DEPRECATED \
-DBINDIR=\"$(bindir)\" \ -DBINDIR=\"$(bindir)\" \
-DDATADIR=\"$(datadir)\" \ -DDATADIR=\"$(datadir)\" \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DARP_DEBUG -DARP_DEBUG
if WITH_GCRYPT if WITH_GCRYPT
NetworkManager_CPPFLAGS += $(LIBGCRYPT_CFLAGS) NetworkManager_CPPFLAGS += $(LIBGCRYPT_CFLAGS)
@@ -63,41 +66,21 @@ if !WITH_GCRYPT
NetworkManager_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h NetworkManager_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h
endif endif
NetworkManager_LDADD = \ NetworkManager_LDADD = \
$(DBUS_LIBS) \ $(DBUS_LIBS) \
$(GTHREAD_LIBS) \ $(GTHREAD_LIBS) \
$(HAL_LIBS) \ $(HAL_LIBS) \
$(IWLIB) \ $(IWLIB) \
libnmbackend.la \
$(top_builddir)/utils/libnmutils.la \ $(top_builddir)/utils/libnmutils.la \
../dhcpcd/libdhcpc.a \ ../dhcpcd/libdhcpc.a \
../named/libnamed.la ./named-manager/libnamed-manager.la \
./vpn-manager/libvpn-manager.la \
./backends/libnmbackend.la
if WITH_GCRYPT if WITH_GCRYPT
NetworkManager_LDADD += $(LIBGCRYPT_LIBS) NetworkManager_LDADD += $(LIBGCRYPT_LIBS)
endif endif
libnmbackend_la_SOURCES =
if TARGET_REDHAT
libnmbackend_la_SOURCES += backends/NetworkManagerRedHat.c \
backends/shvar.c \
backends/shvar.h
endif
if TARGET_GENTOO
libnmbackend_la_SOURCES += backends/NetworkManagerGentoo.c
endif
if TARGET_DEBIAN
libnmbackend_la_SOURCES += backends/NetworkManagerDebian.c \
backends/interface_parser.c \
backends/interface_parser.h
endif
if TARGET_SLACKWARE
libnmbackend_la_SOURCES += backends/NetworkManagerSlackware.c
endif
libnmbackend_la_LIBADD = $(DBUS_LIBS) $(GTHREAD_LIBS)
libnmbackend_la_CFLAGS = $(NetworkManager_CPPFLAGS)
dbusservicedir = $(DBUS_SYS_DIR) dbusservicedir = $(DBUS_SYS_DIR)
dbusservice_DATA = NetworkManager.conf dbusservice_DATA = NetworkManager.conf

View File

@@ -44,6 +44,7 @@
#include "NetworkManagerAPList.h" #include "NetworkManagerAPList.h"
#include "NetworkManagerSystem.h" #include "NetworkManagerSystem.h"
#include "nm-named-manager.h" #include "nm-named-manager.h"
#include "nm-dbus-vpn.h"
#include "nm-netlink-monitor.h" #include "nm-netlink-monitor.h"
#define NM_WIRELESS_LINK_STATE_POLL_INTERVAL (5 * 1000) #define NM_WIRELESS_LINK_STATE_POLL_INTERVAL (5 * 1000)
@@ -512,7 +513,9 @@ static void nm_data_free (NMData *data)
{ {
g_return_if_fail (data != NULL); g_return_if_fail (data != NULL);
nm_vpn_manager_dispose (data->vpn_manager);
g_object_unref (data->named); g_object_unref (data->named);
nm_device_unref (data->active_device); nm_device_unref (data->active_device);
g_slist_foreach (data->dev_list, (GFunc) nm_device_unref, NULL); g_slist_foreach (data->dev_list, (GFunc) nm_device_unref, NULL);
@@ -844,10 +847,14 @@ int main( int argc, char *argv[] )
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
/* If NMI is running, grab allowed wireless network lists from it ASAP nm_data->vpn_manager = nm_vpn_manager_new (nm_data);
*/
/* If NMI is running, grab allowed wireless network lists from it ASAP */
if (nm_dbus_is_info_daemon_running (nm_data->dbus_connection)) if (nm_dbus_is_info_daemon_running (nm_data->dbus_connection))
{
nm_policy_schedule_allowed_ap_list_update (nm_data); nm_policy_schedule_allowed_ap_list_update (nm_data);
nm_dbus_vpn_schedule_vpn_connections_update (nm_data);
}
/* Right before we init hal, we have to make sure our mainloop /* Right before we init hal, we have to make sure our mainloop
* integration function knows about our GMainContext. HAL doesn't give * integration function knows about our GMainContext. HAL doesn't give
@@ -865,7 +872,7 @@ int main( int argc, char *argv[] )
nm_hal_mainloop_integration (ctx, nm_data->dbus_connection); nm_hal_mainloop_integration (ctx, nm_data->dbus_connection);
libhal_ctx_set_dbus_connection (ctx, nm_data->dbus_connection); libhal_ctx_set_dbus_connection (ctx, nm_data->dbus_connection);
dbus_error_init (&dbus_error); dbus_error_init (&dbus_error);
if(!libhal_ctx_init (ctx, &dbus_error)) { if(!libhal_ctx_init (ctx, &dbus_error)) {
@@ -929,7 +936,6 @@ int main( int argc, char *argv[] )
/* Cleanup */ /* Cleanup */
libhal_ctx_shutdown (nm_data->hal_ctx, &dbus_error); libhal_ctx_shutdown (nm_data->hal_ctx, &dbus_error);
if (dbus_error_is_set (&dbus_error)) { if (dbus_error_is_set (&dbus_error)) {
nm_warning ("libhal shutdown failed - %s", nm_warning ("libhal shutdown failed - %s",
dbus_error.message); dbus_error.message);

View File

@@ -37,169 +37,33 @@
extern gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip); extern gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip);
static void set_nameservers (NMDevice *dev, void *data, int len)
{
int i;
GList *elt;
GError *error = NULL;
/* Reset our nameserver list */
for (elt = dev->app_data->nameserver_ids; elt; elt = elt->next)
{
if (!nm_named_manager_remove_nameserver_ipv4 (dev->app_data->named,
GPOINTER_TO_UINT (elt->data),
&error))
{
nm_warning ("Couldn't remove nameserver: %s", error->message);
g_clear_error (&error);
}
}
g_list_free (dev->app_data->nameserver_ids);
dev->app_data->nameserver_ids = NULL;
for (i = 0; data && (i < len-3); i += 4)
{
char *nameserver;
guint id;
nameserver = g_strdup_printf ("%u.%u.%u.%u",
((unsigned char *)data)[i],
((unsigned char *)data)[i+1],
((unsigned char *)data)[i+2],
((unsigned char *)data)[i+3]);
nm_info ("Adding nameserver: %s", nameserver);
if ((id = nm_named_manager_add_nameserver_ipv4 (dev->app_data->named,
nameserver,
&error)))
dev->app_data->nameserver_ids = g_list_prepend (dev->app_data->nameserver_ids,
GUINT_TO_POINTER (id));
else
{
nm_warning ("Couldn't add nameserver: %s\n", error->message);
g_clear_error (&error);
}
g_free (nameserver);
}
}
static void set_domain_searches (NMDevice *dev, const char *searches_str)
{
GError *error = NULL;
GList *elt;
char **searches, **s;
/* Reset our domain search list */
for (elt = dev->app_data->domain_search_ids; elt; elt = elt->next)
{
if (!nm_named_manager_remove_domain_search (dev->app_data->named,
GPOINTER_TO_UINT (elt->data),
&error))
{
nm_warning ("Couldn't remove domain search: %s\n", error->message);
g_clear_error (&error);
}
}
g_list_free (dev->app_data->domain_search_ids);
dev->app_data->domain_search_ids = NULL;
searches = g_strsplit (searches_str, " ", 0);
for (s = searches; *s; s++)
{
const char *search_elt = *s;
guint id;
nm_warning ("Adding domain search: %s\n", search_elt);
if ((id = nm_named_manager_add_domain_search (dev->app_data->named,
search_elt,
&error)))
dev->app_data->domain_search_ids = g_list_append (dev->app_data->domain_search_ids, GUINT_TO_POINTER (id));
else
{
nm_warning ("Couldn't add domain search: %s\n", error->message);
g_clear_error (&error);
}
}
g_strfreev (searches);
}
/* /*
* nm_device_dhcp_configure * nm_device_new_ip4_autoip_config
* *
* Using the results of a DHCP request, configure the device. * Build up an IP config with a Link Local address
* *
*/ */
static void nm_device_dhcp_configure (NMDevice *dev) NMIP4Config *nm_device_new_ip4_autoip_config (NMDevice *dev)
{
int temp;
g_return_if_fail (dev != NULL);
g_return_if_fail (dev->dhcp_iface != NULL);
/* DHCP sets up a default route for the device, we need to remove that. */
nm_system_device_flush_routes (dev);
/* Replace basic info */
nm_system_device_set_ip4_address (dev, dev->dhcp_iface->ciaddr);
if (dhcp_interface_option_present (dev->dhcp_iface, subnetMask))
{
memcpy (&temp, dhcp_interface_option_payload (dev->dhcp_iface, subnetMask), dhcp_option_element_len (subnetMask));
nm_system_device_set_ip4_netmask (dev, temp);
}
if (dhcp_interface_option_present (dev->dhcp_iface, broadcastAddr))
{
memcpy (&temp, dhcp_interface_option_payload (dev->dhcp_iface, broadcastAddr), dhcp_option_element_len (broadcastAddr));
nm_system_device_set_ip4_broadcast (dev, temp);
}
/* Default route */
if (dhcp_interface_option_present (dev->dhcp_iface, routersOnSubnet))
{
memcpy (&temp, dhcp_interface_option_payload (dev->dhcp_iface, routersOnSubnet), dhcp_option_element_len (routersOnSubnet));
nm_system_device_set_ip4_default_route (dev, temp);
}
/* Update /etc/resolv.conf */
if (dhcp_interface_option_present (dev->dhcp_iface, dns))
set_nameservers (dev, dhcp_interface_option_payload (dev->dhcp_iface, dns), dhcp_interface_option_len (dev->dhcp_iface, dns));
if (dhcp_interface_option_present (dev->dhcp_iface, domainName))
set_domain_searches (dev, dhcp_interface_option_payload (dev->dhcp_iface, domainName));
}
/*
* nm_device_do_autoip
*
* Get and assign a Link Local Address.
*
*/
gboolean nm_device_do_autoip (NMDevice *dev)
{ {
struct in_addr ip; struct in_addr ip;
gboolean success = FALSE; NMIP4Config * config = NULL;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, NULL);
if ((success = get_autoip (dev, &ip))) if (get_autoip (dev, &ip))
{ {
#define LINKLOCAL_BCAST 0xa9feffff #define LINKLOCAL_BCAST 0xa9feffff
int temp = ip.s_addr; int temp = ip.s_addr;
nm_system_device_set_ip4_address (dev, temp); config = nm_ip4_config_new ();
temp = ntohl (0xFFFF0000);
nm_system_device_set_ip4_netmask (dev, temp);
temp = ntohl (LINKLOCAL_BCAST);
nm_system_device_set_ip4_broadcast (dev, temp);
/* Set all traffic to go through the device */ nm_ip4_config_set_address (config, (guint32)(ip.s_addr));
nm_system_flush_loopback_routes (); nm_ip4_config_set_netmask (config, (guint32)(ntohl (0xFFFF0000)));
nm_system_device_add_default_route_via_device (dev); nm_ip4_config_set_broadcast (config, (guint32)(ntohl (LINKLOCAL_BCAST)));
nm_ip4_config_set_gateway (config, 0);
} }
return (success); return config;
} }
@@ -209,7 +73,7 @@ gboolean nm_device_do_autoip (NMDevice *dev)
* Start a DHCP transaction on particular device. * Start a DHCP transaction on particular device.
* *
*/ */
int nm_device_dhcp_request (NMDevice *dev) static int nm_device_dhcp_request (NMDevice *dev)
{ {
dhcp_client_options opts; dhcp_client_options opts;
int err; int err;
@@ -232,18 +96,84 @@ int nm_device_dhcp_request (NMDevice *dev)
* and settings. * and settings.
*/ */
if ((err = dhcp_init (dev->dhcp_iface)) == RET_DHCP_BOUND) if ((err = dhcp_init (dev->dhcp_iface)) == RET_DHCP_BOUND)
{
nm_device_dhcp_configure (dev);
nm_device_update_ip4_address (dev);
nm_device_dhcp_setup_timeouts (dev); nm_device_dhcp_setup_timeouts (dev);
}
else else
{ {
dhcp_interface_free (dev->dhcp_iface); dhcp_interface_free (dev->dhcp_iface);
dev->dhcp_iface = NULL; dev->dhcp_iface = NULL;
} }
return (err); return err;
}
/*
* nm_device_new_ip4_dhcp_config
*
* Get IPv4 configuration info via DHCP, running the DHCP
* transaction if necessary.
*
*/
NMIP4Config *nm_device_new_ip4_dhcp_config (NMDevice *dev)
{
NMIP4Config * config = NULL;
int err;
dhcp_interface *dhcp_info = NULL;
g_return_val_if_fail (dev != NULL, NULL);
err = nm_device_dhcp_request (dev);
dhcp_info = dev->dhcp_iface;
if ((err == RET_DHCP_BOUND) && dev->dhcp_iface)
{
guint32 temp;
config = nm_ip4_config_new ();
nm_ip4_config_set_address (config, dhcp_info->ciaddr);
if (dhcp_interface_option_present (dhcp_info, subnetMask))
{
memcpy (&temp, dhcp_interface_option_payload (dhcp_info, subnetMask), dhcp_option_element_len (subnetMask));
nm_ip4_config_set_netmask (config, temp);
}
if (dhcp_interface_option_present (dhcp_info, broadcastAddr))
{
memcpy (&temp, dhcp_interface_option_payload (dhcp_info, broadcastAddr), dhcp_option_element_len (broadcastAddr));
nm_ip4_config_set_broadcast (config, temp);
}
/* Default route */
if (dhcp_interface_option_present (dhcp_info, routersOnSubnet))
{
memcpy (&temp, dhcp_interface_option_payload (dhcp_info, routersOnSubnet), dhcp_option_element_len (routersOnSubnet));
nm_ip4_config_set_gateway (config, temp);
}
/* Update /etc/resolv.conf */
if (dhcp_interface_option_present (dhcp_info, dns))
{
guint32 *data = dhcp_interface_option_payload (dhcp_info, dns);
int len = dhcp_interface_option_len (dhcp_info, dns) / sizeof (guint32);
for (temp = 0; temp < len; temp++)
nm_ip4_config_add_nameserver (config, data[temp]);
}
if (dhcp_interface_option_present (dhcp_info, domainName))
{
char **searches = g_strsplit (dhcp_interface_option_payload (dev->dhcp_iface, domainName), " ", 0);
char **s;
for (s = searches; *s; s++)
nm_ip4_config_add_domain (config, *s);
g_strfreev (searches);
}
}
return config;
} }
@@ -348,7 +278,7 @@ gboolean nm_device_dhcp_renew (gpointer user_data)
/* If the T1 renewal fails, then we wait around until T2 /* If the T1 renewal fails, then we wait around until T2
* for rebind. * for rebind.
*/ */
return (FALSE); return FALSE;
} }
else else
{ {
@@ -359,7 +289,7 @@ gboolean nm_device_dhcp_renew (gpointer user_data)
/* Always return false to remove ourselves, since we just /* Always return false to remove ourselves, since we just
* set up another timeout above. * set up another timeout above.
*/ */
return (FALSE); return FALSE;
} }
@@ -392,7 +322,7 @@ gboolean nm_device_dhcp_rebind (gpointer user_data)
dhcp_interface_free (dev->dhcp_iface); dhcp_interface_free (dev->dhcp_iface);
dev->dhcp_iface = NULL; dev->dhcp_iface = NULL;
return (FALSE); return FALSE;
} }
else else
{ {
@@ -403,6 +333,6 @@ gboolean nm_device_dhcp_rebind (gpointer user_data)
/* Always return false to remove ourselves, since we just /* Always return false to remove ourselves, since we just
* set up another timeout above. * set up another timeout above.
*/ */
return (FALSE); return FALSE;
} }

View File

@@ -24,12 +24,14 @@
#include "../dhcpcd/dhcpcd.h" #include "../dhcpcd/dhcpcd.h"
int nm_device_dhcp_request (NMDevice *dev);
void nm_device_dhcp_cease (NMDevice *dev); void nm_device_dhcp_cease (NMDevice *dev);
gboolean nm_device_dhcp_setup_timeouts (NMDevice *dev); gboolean nm_device_dhcp_setup_timeouts (NMDevice *dev);
void nm_device_dhcp_remove_timeouts(NMDevice *dev); void nm_device_dhcp_remove_timeouts(NMDevice *dev);
gboolean nm_device_dhcp_renew (gpointer user_data); gboolean nm_device_dhcp_renew (gpointer user_data);
gboolean nm_device_dhcp_rebind (gpointer user_data); gboolean nm_device_dhcp_rebind (gpointer user_data);
gboolean nm_device_do_autoip (NMDevice *dev);
NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *dev);
NMIP4Config * nm_device_new_ip4_dhcp_config (NMDevice *dev);
#endif #endif

View File

@@ -40,6 +40,7 @@
#include "nm-dbus-device.h" #include "nm-dbus-device.h"
#include "nm-dbus-net.h" #include "nm-dbus-net.h"
#include "nm-dbus-dhcp.h" #include "nm-dbus-dhcp.h"
#include "nm-dbus-vpn.h"
#include "nm-utils.h" #include "nm-utils.h"
@@ -201,7 +202,6 @@ void nm_dbus_schedule_network_not_found_signal (NMData *data, const char *networ
} }
/*-------------------------------------------------------------*/ /*-------------------------------------------------------------*/
/* Handler code */ /* Handler code */
/*-------------------------------------------------------------*/ /*-------------------------------------------------------------*/
@@ -459,7 +459,7 @@ void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevic
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "WirelessNetworkUpdate"); message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "WirelessNetworkUpdate");
if (!message) if (!message)
{ {
nm_warning ("nm_dbus_signal_wireless_network_appeared(): Not enough memory for new dbus message!"); nm_warning ("nm_dbus_signal_wireless_network_change(): Not enough memory for new dbus message!");
g_free (dev_path); g_free (dev_path);
g_free (ap_path); g_free (ap_path);
return; return;
@@ -478,7 +478,7 @@ void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevic
dbus_message_append_args (message, DBUS_TYPE_INT32, &strength, DBUS_TYPE_INVALID); dbus_message_append_args (message, DBUS_TYPE_INT32, &strength, DBUS_TYPE_INVALID);
if (!dbus_connection_send (connection, message, NULL)) if (!dbus_connection_send (connection, message, NULL))
nm_warning ("nnm_dbus_signal_wireless_network_appeared(): Could not raise the WirelessNetworkAppeared signal!"); nm_warning ("nm_dbus_signal_wireless_network_change(): Could not raise the WirelessNetworkAppeared signal!");
dbus_message_unref (message); dbus_message_unref (message);
} }
@@ -952,12 +952,12 @@ gboolean nm_dbus_nmi_is_running (DBusConnection *connection)
/* /*
* nm_dbus_nmi_filter * nm_dbus_signal_filter
* *
* Respond to NetworkManagerInfo signals about changing Allowed Networks * Respond to NetworkManagerInfo signals about changing Allowed Networks
* *
*/ */
static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMessage *message, void *user_data) static DBusHandlerResult nm_dbus_signal_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
{ {
NMData *data = (NMData *)user_data; NMData *data = (NMData *)user_data;
const char *object_path; const char *object_path;
@@ -990,26 +990,53 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes
handled = TRUE; handled = TRUE;
} }
} }
else if ( (strcmp (object_path, NMI_DBUS_PATH) == 0)
&& dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "VPNConnectionUpdate"))
{
char *name = NULL;
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
{
NMVPNConnection *vpn;
/* Update a single VPN connection's data */
nm_debug ("NetworkManagerInfo triggered update of VPN connection '%s'", name);
vpn = nm_dbus_vpn_add_one_connection (data->dbus_connection, name, data->vpn_manager);
if (vpn)
nm_dbus_vpn_signal_vpn_connection_update (data->dbus_connection, vpn);
handled = TRUE;
}
}
else if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) else if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
{ {
char *service; char *service;
char *old_owner; char *old_owner;
char *new_owner; char *new_owner;
if ( dbus_message_get_args (message, &error, if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &old_owner,
DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID))
DBUS_TYPE_STRING, &old_owner,
DBUS_TYPE_STRING, &new_owner,
DBUS_TYPE_INVALID)
&& (strcmp (service, NMI_DBUS_SERVICE) == 0))
{ {
gboolean old_owner_good = (old_owner && (strlen (old_owner) > 0)); if (strcmp (service, NMI_DBUS_SERVICE) == 0)
gboolean new_owner_good = (new_owner && (strlen (new_owner) > 0)); {
gboolean old_owner_good = (old_owner && (strlen (old_owner) > 0));
gboolean new_owner_good = (new_owner && (strlen (new_owner) > 0));
if (!old_owner_good && new_owner_good) if (!old_owner_good && new_owner_good) /* NMI just appeared */
nm_policy_schedule_allowed_ap_list_update (data); {
nm_policy_schedule_allowed_ap_list_update (data);
nm_dbus_vpn_schedule_vpn_connections_update (data);
}
}
else if (nm_vpn_manager_process_name_owner_changed (data->vpn_manager, service, old_owner, new_owner) == TRUE)
{
/* Processed by the VPN manager */
}
} }
} }
else if (nm_vpn_manager_process_signal (data->vpn_manager, message) == TRUE)
{
/* Processed by the VPN manager */
}
if (dbus_error_is_set (&error)) if (dbus_error_is_set (&error))
dbus_error_free (&error); dbus_error_free (&error);
@@ -1070,10 +1097,7 @@ static DBusHandlerResult nm_dbus_devices_message_handler (DBusConnection *connec
path = dbus_message_get_path (message); path = dbus_message_get_path (message);
if (!(dev = nm_dbus_get_device_from_object_path (data, path))) if (!(dev = nm_dbus_get_device_from_object_path (data, path)))
{ reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound", "The requested network device does not exist.");
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
"The requested network device does not exist.");
}
else else
{ {
char *object_path, *escaped_object_path; char *object_path, *escaped_object_path;
@@ -1139,6 +1163,38 @@ static DBusHandlerResult nm_dbus_dhcp_message_handler (DBusConnection *connectio
} }
/*
* nm_dbus_vpn_message_handler
*
* Dispatch messages against our NetworkManager VPNConnections object
*
*/
static DBusHandlerResult nm_dbus_vpn_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
{
NMData *data = (NMData *)user_data;
gboolean handled = TRUE;
DBusMessage *reply = NULL;
NMDbusCBData cb_data;
g_return_val_if_fail (data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (data->vpn_methods != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
cb_data.data = data;
cb_data.dev = NULL;
cb_data.opt_id = -1;
handled = nm_dbus_method_dispatch (data->vpn_methods, connection, message, &cb_data, &reply);
if (reply)
{
dbus_connection_send (connection, reply, NULL);
dbus_message_unref (reply);
}
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
/* /*
* nm_dbus_is_info_daemon_running * nm_dbus_is_info_daemon_running
* *
@@ -1173,6 +1229,7 @@ DBusConnection *nm_dbus_init (NMData *data)
DBusObjectPathVTable nm_vtable = {NULL, &nm_dbus_nm_message_handler, NULL, NULL, NULL, NULL}; DBusObjectPathVTable nm_vtable = {NULL, &nm_dbus_nm_message_handler, NULL, NULL, NULL, NULL};
DBusObjectPathVTable devices_vtable = {NULL, &nm_dbus_devices_message_handler, NULL, NULL, NULL, NULL}; DBusObjectPathVTable devices_vtable = {NULL, &nm_dbus_devices_message_handler, NULL, NULL, NULL, NULL};
DBusObjectPathVTable dhcp_vtable = {NULL, &nm_dbus_dhcp_message_handler, NULL, NULL, NULL, NULL}; DBusObjectPathVTable dhcp_vtable = {NULL, &nm_dbus_dhcp_message_handler, NULL, NULL, NULL, NULL};
DBusObjectPathVTable vpn_vtable = {NULL, &nm_dbus_vpn_message_handler, NULL, NULL, NULL, NULL};
dbus_connection_set_change_sigpipe (TRUE); dbus_connection_set_change_sigpipe (TRUE);
@@ -1192,17 +1249,19 @@ DBusConnection *nm_dbus_init (NMData *data)
data->device_methods = nm_dbus_device_methods_setup (); data->device_methods = nm_dbus_device_methods_setup ();
data->net_methods = nm_dbus_net_methods_setup (); data->net_methods = nm_dbus_net_methods_setup ();
data->dhcp_methods = nm_dbus_dhcp_methods_setup (); data->dhcp_methods = nm_dbus_dhcp_methods_setup ();
data->vpn_methods = nm_dbus_vpn_methods_setup ();
if ( !dbus_connection_register_object_path (connection, NM_DBUS_PATH, &nm_vtable, data) if ( !dbus_connection_register_object_path (connection, NM_DBUS_PATH, &nm_vtable, data)
|| !dbus_connection_register_fallback (connection, NM_DBUS_PATH_DEVICES, &devices_vtable, data) || !dbus_connection_register_fallback (connection, NM_DBUS_PATH_DEVICES, &devices_vtable, data)
|| !dbus_connection_register_object_path (connection, NM_DBUS_PATH_DHCP, &dhcp_vtable, data)) || !dbus_connection_register_object_path (connection, NM_DBUS_PATH_DHCP, &dhcp_vtable, data)
|| !dbus_connection_register_object_path (connection, NM_DBUS_PATH_VPN, &vpn_vtable, data))
{ {
nm_error ("nm_dbus_init() could not register D-BUS handlers. Cannot continue."); nm_error ("nm_dbus_init() could not register D-BUS handlers. Cannot continue.");
connection = NULL; connection = NULL;
goto out; goto out;
} }
if (!dbus_connection_add_filter (connection, nm_dbus_nmi_filter, data, NULL)) if (!dbus_connection_add_filter (connection, nm_dbus_signal_filter, data, NULL))
{ {
nm_error ("nm_dbus_init() could not attach a dbus message filter. The NetworkManager dbus security policy may not be loaded. Restart dbus?"); nm_error ("nm_dbus_init() could not attach a dbus message filter. The NetworkManager dbus security policy may not be loaded. Restart dbus?");
connection = NULL; connection = NULL;

View File

@@ -77,4 +77,6 @@ NMDevice * nm_dbus_get_device_from_object_path (NMData *data, const char *path);
char * nm_dbus_network_status_from_data (NMData *data); char * nm_dbus_network_status_from_data (NMData *data);
DBusMessage * nm_dbus_create_error_message (DBusMessage *message, const char *exception_namespace, const char *exception, const char *format, ...);
#endif #endif

View File

@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* *
* (C) Copyright 2004 Red Hat, Inc. * (C) Copyright 2005 Red Hat, Inc.
*/ */
#include <errno.h> #include <errno.h>
@@ -38,7 +38,8 @@
#include "NetworkManagerAPList.h" #include "NetworkManagerAPList.h"
#include "NetworkManagerSystem.h" #include "NetworkManagerSystem.h"
#include "NetworkManagerDHCP.h" #include "NetworkManagerDHCP.h"
#include "nm-ip4-config.h"
#include "nm-vpn-manager.h"
#include "nm-utils.h" #include "nm-utils.h"
/* Local static prototypes */ /* Local static prototypes */
@@ -289,6 +290,7 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
dev->iface = g_strdup (iface); dev->iface = g_strdup (iface);
dev->test_device = test_dev; dev->test_device = test_dev;
nm_device_set_udi (dev, udi); nm_device_set_udi (dev, udi);
dev->use_dhcp = TRUE;
/* Real hardware devices are probed for their type, test devices must have /* Real hardware devices are probed for their type, test devices must have
* their type specified. * their type specified.
@@ -378,7 +380,7 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
nm_device_update_hw_address (dev); nm_device_update_hw_address (dev);
/* Grab IP config data for this device from the system configuration files */ /* Grab IP config data for this device from the system configuration files */
nm_system_device_update_config_info (dev); dev->system_config_data = nm_system_device_get_system_config (dev);
} }
if (!g_thread_create (nm_device_worker, dev, FALSE, &error)) if (!g_thread_create (nm_device_worker, dev, FALSE, &error))
@@ -456,6 +458,10 @@ gboolean nm_device_unref (NMDevice *dev)
dev->dhcp_iface = NULL; dev->dhcp_iface = NULL;
} }
nm_system_device_free_system_config (dev, dev->system_config_data);
if (dev->ip4_config)
nm_ip4_config_unref (dev->ip4_config);
g_free (dev->udi); g_free (dev->udi);
g_free (dev->iface); g_free (dev->iface);
memset (dev, 0, sizeof (NMDevice)); memset (dev, 0, sizeof (NMDevice));
@@ -503,7 +509,7 @@ static gpointer nm_device_worker (gpointer user_data)
g_main_loop_run (dev->loop); g_main_loop_run (dev->loop);
/* Remove any DHCP timeouts that might have been running */ /* Remove any DHCP timeouts that might have been running */
if (nm_device_config_get_use_dhcp (dev)) if (nm_device_get_use_dhcp (dev))
nm_device_dhcp_remove_timeouts (dev); nm_device_dhcp_remove_timeouts (dev);
g_main_loop_unref (dev->loop); g_main_loop_unref (dev->loop);
@@ -1509,11 +1515,6 @@ void nm_device_update_hw_address (NMDevice *dev)
*/ */
static void nm_device_set_up_down (NMDevice *dev, gboolean up) static void nm_device_set_up_down (NMDevice *dev, gboolean up)
{ {
struct ifreq ifr;
NMSock *sk;
int err;
guint32 flags = up ? IFF_UP : ~IFF_UP;
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
/* Test devices do whatever we tell them to do */ /* Test devices do whatever we tell them to do */
@@ -1523,34 +1524,13 @@ static void nm_device_set_up_down (NMDevice *dev, gboolean up)
return; return;
} }
if ((sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL)) == NULL) nm_system_device_set_up_down (dev, up);
return;
/* Get flags already there */ /* Make sure we have a valid MAC address, some cards reload firmware when they
strcpy (ifr.ifr_name, nm_device_get_iface (dev)); * are brought up.
err = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFFLAGS, &ifr); */
if (!err) if (!nm_ethernet_address_is_valid ((struct ether_addr *)dev->hw_addr))
{ nm_device_update_hw_address (dev);
/* If the interface doesn't have those flags already,
* set them on it.
*/
if ((ifr.ifr_flags^flags) & IFF_UP)
{
ifr.ifr_flags &= ~IFF_UP;
ifr.ifr_flags |= IFF_UP & flags;
if ((err = ioctl (nm_dev_sock_get_fd (sk), SIOCSIFFLAGS, &ifr)))
nm_warning ("nm_device_set_up_down() could not bring device %s %s. errno = %d", nm_device_get_iface (dev), (up ? "up" : "down"), errno );
}
/* Make sure we have a valid MAC address, some cards reload firmware when they
* are brought up.
*/
if (!nm_ethernet_address_is_valid((struct ether_addr *)dev->hw_addr))
nm_device_update_hw_address(dev);
}
else
nm_warning ("nm_device_set_up_down() could not get flags for device %s. errno = %d", nm_device_get_iface (dev), errno );
nm_dev_sock_close (sk);
} }
@@ -2580,51 +2560,48 @@ out:
*/ */
static gboolean nm_device_activation_configure_ip (NMDevice *dev, gboolean do_only_autoip) static gboolean nm_device_activation_configure_ip (NMDevice *dev, gboolean do_only_autoip)
{ {
gboolean success = FALSE; NMIP4Config * ip4_config;
gboolean success = FALSE;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
nm_system_delete_default_route ();
if (do_only_autoip) if (do_only_autoip)
{ ip4_config = nm_device_new_ip4_autoip_config (dev);
success = nm_device_do_autoip (dev); else if (nm_device_get_use_dhcp (dev))
} ip4_config = nm_device_new_ip4_dhcp_config (dev);
else if (nm_device_config_get_use_dhcp (dev)) else
{ ip4_config = nm_system_device_new_ip4_system_config (dev);
int err;
err = nm_device_dhcp_request (dev); if (ip4_config)
if (err == RET_DHCP_BOUND) {
success = TRUE; /* Set IP4Config on the device */
else nm_device_set_ip4_config (dev, ip4_config);
if ((success = nm_system_device_set_from_ip4_config (dev)))
{ {
/* Interfaces cannot be down if they are the active interface, if (do_only_autoip)
* otherwise we cannot use them for scanning or link detection. nm_system_flush_loopback_routes ();
*/
if (nm_device_is_wireless (dev))
{
nm_device_set_essid (dev, "");
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
}
if (!nm_device_is_up (dev)) nm_device_update_ip4_address (dev);
nm_device_bring_up (dev); nm_system_device_add_ip6_link_address (dev);
nm_system_restart_mdns_responder ();
} }
} }
else else
{ {
/* Manually set up the device */ /* Interfaces cannot be down if they are the active interface,
success = nm_system_device_setup_static_ip4_config (dev); * otherwise we cannot use them for scanning or link detection.
*/
if (nm_device_is_wireless (dev))
{
nm_device_set_essid (dev, "");
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
}
if (!nm_device_is_up (dev))
nm_device_bring_up (dev);
} }
if (success) return success;
{
nm_system_device_add_ip6_link_address (dev);
nm_system_flush_arp_cache ();
nm_system_restart_mdns_responder ();
}
return (success);
} }
@@ -2792,6 +2769,8 @@ void nm_device_activation_cancel (NMDevice *dev)
*/ */
gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added) gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
{ {
NMIP4Config *config;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (dev->app_data != NULL, FALSE); g_return_val_if_fail (dev->app_data != NULL, FALSE);
@@ -2801,9 +2780,19 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
return (TRUE); return (TRUE);
/* Remove any DHCP timeouts that might have been running */ /* Remove any DHCP timeouts that might have been running */
if (nm_device_config_get_use_dhcp (dev)) if (nm_device_get_use_dhcp (dev))
nm_device_dhcp_remove_timeouts (dev); nm_device_dhcp_remove_timeouts (dev);
nm_vpn_manager_deactivate_vpn_connection (dev->app_data->vpn_manager);
/* Remove any device nameservers and domains */
if ((config = nm_device_get_ip4_config (dev)))
{
nm_system_remove_ip4_config_nameservers (dev->app_data->named, config);
nm_system_remove_ip4_config_search_domains (dev->app_data->named, config);
nm_device_set_ip4_config (dev, NULL);
}
/* Take out any entries in the routing table and any IP address the device had. */ /* Take out any entries in the routing table and any IP address the device had. */
nm_system_device_flush_routes (dev); nm_system_device_flush_routes (dev);
nm_system_device_flush_addresses (dev); nm_system_device_flush_addresses (dev);
@@ -3825,75 +3814,57 @@ reschedule:
} }
/* System config data accessors */ /* IP Configuration stuff */
gboolean nm_device_config_get_use_dhcp (NMDevice *dev) gboolean nm_device_get_use_dhcp (NMDevice *dev)
{ {
g_return_val_if_fail (dev != NULL, 0); g_return_val_if_fail (dev != NULL, FALSE);
return (dev->config_info.use_dhcp); return dev->use_dhcp;
} }
void nm_device_config_set_use_dhcp (NMDevice *dev, gboolean use_dhcp) void nm_device_set_use_dhcp (NMDevice *dev, gboolean use_dhcp)
{ {
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
dev->config_info.use_dhcp = use_dhcp; dev->use_dhcp = use_dhcp;
} }
guint32 nm_device_config_get_ip4_address (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, 0);
return (dev->config_info.ip4_address); NMIP4Config *nm_device_get_ip4_config (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, NULL);
return dev->ip4_config;
} }
void nm_device_config_set_ip4_address (NMDevice *dev, guint32 addr)
void nm_device_set_ip4_config (NMDevice *dev, NMIP4Config *config)
{ {
NMIP4Config *old_config;
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
dev->config_info.ip4_address = addr; old_config = dev->ip4_config;
if (config)
nm_ip4_config_ref (config);
dev->ip4_config = config;
if (old_config)
nm_ip4_config_unref (old_config);
} }
guint32 nm_device_config_get_ip4_gateway (NMDevice *dev)
/*
* nm_device_get_system_config_data
*
* Return distro-specific system configuration data for this device.
*
*/
void *nm_device_get_system_config_data (NMDevice *dev)
{ {
g_return_val_if_fail (dev != NULL, 0); g_return_val_if_fail (dev != NULL, NULL);
return (dev->config_info.ip4_gateway); return dev->system_config_data;
}
void nm_device_config_set_ip4_gateway (NMDevice *dev, guint32 gateway)
{
g_return_if_fail (dev != NULL);
dev->config_info.ip4_gateway = gateway;
}
guint32 nm_device_config_get_ip4_netmask (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, 0);
return (dev->config_info.ip4_netmask);
}
void nm_device_config_set_ip4_netmask (NMDevice *dev, guint32 netmask)
{
g_return_if_fail (dev != NULL);
dev->config_info.ip4_netmask = netmask;
}
guint32 nm_device_config_get_ip4_broadcast (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, 0);
return (dev->config_info.ip4_broadcast);
}
void nm_device_config_set_ip4_broadcast (NMDevice *dev, guint32 broadcast)
{
g_return_if_fail (dev != NULL);
dev->config_info.ip4_broadcast = broadcast;
} }
@@ -4008,3 +3979,4 @@ gboolean nm_device_is_test_device (NMDevice *dev)
return (dev->test_device); return (dev->test_device);
} }

View File

@@ -26,10 +26,12 @@
#include <iwlib.h> #include <iwlib.h>
#include "NetworkManager.h" #include "NetworkManager.h"
#include "NetworkManagerMain.h" #include "NetworkManagerMain.h"
#include "nm-ip4-config.h"
typedef struct NMDevice NMDevice; typedef struct NMDevice NMDevice;
NMDevice * nm_device_new (const char *iface, const char *udi, gboolean test_device, NMDevice * nm_device_new (const char *iface, const char *udi, gboolean test_device,
NMDeviceType test_dev_type, NMData *app_data); NMDeviceType test_dev_type, NMData *app_data);
@@ -123,17 +125,13 @@ NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *ess
NMAccessPoint *nm_device_ap_list_get_ap_by_address(NMDevice *dev, const struct ether_addr *addr); NMAccessPoint *nm_device_ap_list_get_ap_by_address(NMDevice *dev, const struct ether_addr *addr);
void nm_device_copy_allowed_to_dev_list (NMDevice *dev, struct NMAccessPointList *allowed_list); void nm_device_copy_allowed_to_dev_list (NMDevice *dev, struct NMAccessPointList *allowed_list);
/* System config data accessors */ gboolean nm_device_get_use_dhcp (NMDevice *dev);
gboolean nm_device_config_get_use_dhcp (NMDevice *dev); void nm_device_set_use_dhcp (NMDevice *dev, gboolean use_dhcp);
void nm_device_config_set_use_dhcp (NMDevice *dev, gboolean use_dhcp);
guint32 nm_device_config_get_ip4_address (NMDevice *dev); NMIP4Config * nm_device_get_ip4_config (NMDevice *dev);
void nm_device_config_set_ip4_address (NMDevice *dev, guint32 addr); void nm_device_set_ip4_config (NMDevice *dev, NMIP4Config *config);
guint32 nm_device_config_get_ip4_gateway (NMDevice *dev);
void nm_device_config_set_ip4_gateway (NMDevice *dev, guint32 gateway); void * nm_device_get_system_config_data (NMDevice *dev);
guint32 nm_device_config_get_ip4_netmask (NMDevice *dev);
void nm_device_config_set_ip4_netmask (NMDevice *dev, guint32 netmask);
guint32 nm_device_config_get_ip4_broadcast (NMDevice *dev);
void nm_device_config_set_ip4_broadcast (NMDevice *dev, guint32 broadcast);
/* Utility routines */ /* Utility routines */
NMDevice * nm_get_device_by_udi (NMData *data, const char *udi); NMDevice * nm_get_device_by_udi (NMData *data, const char *udi);

View File

@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* *
* (C) Copyright 2004 Red Hat, Inc. * (C) Copyright 2005 Red Hat, Inc.
*/ */
#include <errno.h> #include <errno.h>
@@ -65,6 +65,7 @@ typedef struct NMDeviceWiredOptions
gboolean has_carrier_detect; gboolean has_carrier_detect;
} NMDeviceWiredOptions; } NMDeviceWiredOptions;
/* General options structure */
typedef union NMDeviceOptions typedef union NMDeviceOptions
{ {
NMDeviceWirelessOptions wireless; NMDeviceWirelessOptions wireless;
@@ -72,16 +73,6 @@ typedef union NMDeviceOptions
} NMDeviceOptions; } NMDeviceOptions;
typedef struct NMDeviceConfigInfo
{
gboolean use_dhcp;
guint32 ip4_gateway;
guint32 ip4_address;
guint32 ip4_netmask;
guint32 ip4_broadcast;
/* FIXME: ip6 stuff */
} NMDeviceConfigInfo;
/* /*
* NetworkManager device structure * NetworkManager device structure
*/ */
@@ -101,8 +92,12 @@ struct NMDevice
unsigned char hw_addr[ETH_ALEN]; unsigned char hw_addr[ETH_ALEN];
NMData *app_data; NMData *app_data;
NMDeviceOptions options; NMDeviceOptions options;
NMDeviceConfigInfo config_info;
struct dhcp_interface *dhcp_iface; /* IP configuration info */
void * system_config_data; /* Distro-specific config data (parsed config file, etc) */
gboolean use_dhcp;
NMIP4Config * ip4_config; /* Config from DHCP, PPP, or system config files */
struct dhcp_interface * dhcp_iface;
GMainContext *context; GMainContext *context;
GMainLoop *loop; GMainLoop *loop;

View File

@@ -32,26 +32,27 @@
#include "nm-named-manager.h" #include "nm-named-manager.h"
typedef struct NMDbusMethodList NMDbusMethodList; typedef struct NMDbusMethodList NMDbusMethodList;
typedef struct NMVPNManager NMVPNManager;
typedef struct NMData typedef struct NMData
{ {
GIOChannel *sigterm_iochannel; GIOChannel *sigterm_iochannel;
int sigterm_pipe[2]; int sigterm_pipe[2];
LibHalContext *hal_ctx; LibHalContext *hal_ctx;
NmNetlinkMonitor *netlink_monitor; NmNetlinkMonitor *netlink_monitor;
NMNamedManager *named; NMNamedManager *named;
GList *nameserver_ids; /* For now these are global instead of per-device */ NMVPNManager *vpn_manager;
GList *domain_search_ids;
DBusConnection *dbus_connection; DBusConnection *dbus_connection;
NMDbusMethodList *nm_methods; NMDbusMethodList *nm_methods;
NMDbusMethodList *device_methods; NMDbusMethodList *device_methods;
NMDbusMethodList *net_methods; NMDbusMethodList *net_methods;
NMDbusMethodList *dhcp_methods; NMDbusMethodList *dhcp_methods;
NMDbusMethodList *vpn_methods;
GMainContext *main_context; GMainContext *main_context;
GMainLoop *main_loop; GMainLoop *main_loop;

View File

@@ -516,7 +516,7 @@ static gboolean nm_policy_allowed_ap_list_update (gpointer user_data)
else else
nm_device_copy_allowed_to_dev_list (dev, data->allowed_ap_list); nm_device_copy_allowed_to_dev_list (dev, data->allowed_ap_list);
} }
} }
/* If the active device doesn't have a best_ap already, make it update to /* If the active device doesn't have a best_ap already, make it update to
* get the new data. * get the new data.

View File

@@ -29,6 +29,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <net/route.h> #include <net/route.h>
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <arpa/inet.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -44,27 +45,288 @@
#include "NetworkManagerUtils.h" #include "NetworkManagerUtils.h"
#include "nm-utils.h" #include "nm-utils.h"
gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address)
static gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address);
static gboolean nm_system_device_set_ip4_address_with_iface (NMDevice *dev, const char *iface, int ip4_address);
static gboolean nm_system_device_set_ip4_ptp_address (NMDevice *dev, int ip4_ptp_address);
static gboolean nm_system_device_set_ip4_ptp_address_with_iface (NMDevice *dev, const char *iface, int ip4_ptp_address);
static gboolean nm_system_device_set_ip4_netmask (NMDevice *dev, int ip4_netmask);
static gboolean nm_system_device_set_ip4_netmask_with_iface (NMDevice *dev, const char *iface, int ip4_netmask);
static gboolean nm_system_device_set_ip4_broadcast (NMDevice *dev, int ip4_broadcast);
static gboolean nm_system_device_set_ip4_broadcast_with_iface (NMDevice *dev, const char *iface, int ip4_broadcast);
static gboolean nm_system_device_set_ip4_route (NMDevice *dev, int ip4_gateway, int ip4_dest, int ip4_netmask);
static gboolean nm_system_device_set_ip4_route_with_iface (NMDevice *dev, const char *iface, int ip4_gateway, int ip4_dest, int ip4_netmask);
/*
* nm_system_remove_ip4_config_nameservers
*
* Remove an IPv4 Config's nameservers from the name service.
*
*/
void nm_system_remove_ip4_config_nameservers (NMNamedManager *named, NMIP4Config *config)
{
GError *error = NULL;
int i, len;
g_return_if_fail (config != NULL);
len = nm_ip4_config_get_num_nameservers (config);
for (i = 0; i < len; i++)
{
guint id = nm_ip4_config_get_nameserver_id (config, i);
if ((id != 0) && !nm_named_manager_remove_nameserver_ipv4 (named, id, &error))
{
nm_warning ("Couldn't remove nameserver: %s", error->message);
g_clear_error (&error);
}
else
nm_ip4_config_set_nameserver_id (config, i, 0);
}
}
static void set_nameservers (NMNamedManager *named, NMIP4Config *config)
{
GError *error = NULL;
int i, len;
g_return_if_fail (config != NULL);
len = nm_ip4_config_get_num_nameservers (config);
for (i = 0; i < len; i++)
{
guint id;
guint ns_addr = nm_ip4_config_get_nameserver (config, i);
struct in_addr temp_addr;
char * nameserver;
temp_addr.s_addr = ns_addr;
nameserver = g_strdup (inet_ntoa (temp_addr));
nm_info ("Adding nameserver: %s", nameserver);
if ((id = nm_named_manager_add_nameserver_ipv4 (named, nameserver, &error)))
nm_ip4_config_set_nameserver_id (config, i, id);
else
{
nm_warning ("Couldn't add nameserver: %s", error->message);
g_clear_error (&error);
}
g_free (nameserver);
}
}
/*
* nm_system_remove_ip4_config_search_domains
*
* Remove an IPv4 Config's search domains from the name service.
*
*/
void nm_system_remove_ip4_config_search_domains (NMNamedManager *named, NMIP4Config *config)
{
GError *error = NULL;
int i, len;
g_return_if_fail (config != NULL);
len = nm_ip4_config_get_num_domains (config);
for (i = 0; i < len; i++)
{
guint id = nm_ip4_config_get_domain_id (config, i);
if ((id != 0) && !nm_named_manager_remove_domain_search (named, id, &error))
{
nm_warning ("Couldn't remove domain search: %s", error->message);
g_clear_error (&error);
}
else
nm_ip4_config_set_domain_id (config, i, 0);
}
}
static void set_search_domains (NMNamedManager *named, NMIP4Config *config)
{
GError *error = NULL;
int i, len;
g_return_if_fail (config != NULL);
len = nm_ip4_config_get_num_domains (config);
for (i = 0; i < len; i++)
{
const char * domain = nm_ip4_config_get_domain (config, i);
guint id;
nm_info ("Adding domain search: %s", domain);
if ((id = nm_named_manager_add_domain_search (named, domain, &error)))
nm_ip4_config_set_domain_id (config, i, id);
else
{
nm_warning ("Couldn't add domain search: %s", error->message);
g_clear_error (&error);
}
}
}
/*
* nm_system_device_set_from_ip4_config
*
* Set IPv4 configuration of the device from an NMIP4Config object.
*
*/
gboolean nm_system_device_set_from_ip4_config (NMDevice *dev)
{
NMData * app_data;
NMIP4Config * config;
gboolean success = FALSE;
g_return_val_if_fail (dev != NULL, FALSE);
app_data = nm_device_get_app_data (dev);
g_return_val_if_fail (app_data != NULL, FALSE);
config = nm_device_get_ip4_config (dev);
g_return_val_if_fail (config != NULL, FALSE);
nm_system_delete_default_route ();
nm_system_device_flush_addresses (dev);
nm_system_device_flush_routes (dev);
nm_system_flush_arp_cache ();
nm_system_device_set_ip4_address (dev, nm_ip4_config_get_address (config));
nm_system_device_set_ip4_netmask (dev, nm_ip4_config_get_netmask (config));
nm_system_device_set_ip4_broadcast (dev, nm_ip4_config_get_broadcast (config));
sleep (1);
nm_system_device_set_ip4_route (dev, nm_ip4_config_get_gateway (config), 0, 0);
set_nameservers (app_data->named, config);
set_search_domains (app_data->named, config);
return TRUE;
}
/*
* nm_system_vpn_device_set_from_ip4_config
*
* Set IPv4 configuration of a VPN device from an NMIP4Config object.
*
*/
gboolean nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config)
{
gboolean success = FALSE;
NMIP4Config * ad_config = NULL;
g_return_val_if_fail (iface != NULL, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
if (active_device && (ad_config = nm_device_get_ip4_config (active_device)))
{
nm_system_remove_ip4_config_nameservers (named, ad_config);
nm_system_remove_ip4_config_search_domains (named, ad_config);
nm_system_device_set_ip4_route (active_device, nm_ip4_config_get_gateway (ad_config), nm_ip4_config_get_gateway (config), 0xFFFFFFFF);
}
nm_system_device_set_up_down_with_iface (NULL, iface, TRUE);
nm_system_device_set_ip4_address_with_iface (NULL, iface, nm_ip4_config_get_address (config));
nm_system_device_set_ip4_ptp_address_with_iface (NULL, iface, nm_ip4_config_get_address (config));
nm_system_device_set_ip4_netmask_with_iface (NULL, iface, nm_ip4_config_get_netmask (config));
sleep (1);
nm_system_delete_default_route ();
nm_system_device_flush_routes_with_iface (iface);
nm_system_device_add_default_route_via_device_with_iface (iface);
set_nameservers (named, config);
set_search_domains (named, config);
return TRUE;
}
/*
* nm_system_device_set_up_down
*
* Mark the device as up or down.
*
*/
gboolean nm_system_device_set_up_down (NMDevice *dev, gboolean up)
{
g_return_val_if_fail (dev != NULL, FALSE);
return nm_system_device_set_up_down_with_iface (dev, nm_device_get_iface (dev), up);
}
gboolean nm_system_device_set_up_down_with_iface (NMDevice *dev, const char *iface, gboolean up)
{
struct ifreq ifr;
guint32 flags = up ? IFF_UP : ~IFF_UP;
NMSock * sk;
gboolean success = FALSE;
g_return_val_if_fail (iface != NULL, FALSE);
if ((sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL)) == NULL)
return FALSE;
/* Get flags already there */
memset (&ifr, 0, sizeof (struct ifreq));
memcpy (ifr.ifr_name, iface, strlen (iface));
if (!ioctl (nm_dev_sock_get_fd (sk), SIOCGIFFLAGS, &ifr))
{
/* If the interface doesn't have those flags already, set them on it. */
if ((ifr.ifr_flags^flags) & IFF_UP)
{
ifr.ifr_flags &= ~IFF_UP;
ifr.ifr_flags |= IFF_UP & flags;
if (ioctl (nm_dev_sock_get_fd (sk), SIOCSIFFLAGS, &ifr))
nm_warning ("nm_system_device_set_up_down_with_iface() could not bring device %s %s. errno = %d", iface, (up ? "up" : "down"), errno);
}
}
else
nm_warning ("nm_system_device_set_up_down_with_iface() could not get flags for device %s. errno = %d", iface, errno );
nm_dev_sock_close (sk);
return success;
}
/*
* nm_system_device_set_ip4_address
*
* Set the device's IPv4 address.
*
*/
static gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address)
{
g_return_val_if_fail (dev != NULL, FALSE);
return nm_system_device_set_ip4_address_with_iface (dev, nm_device_get_iface (dev), ip4_address);
}
static gboolean nm_system_device_set_ip4_address_with_iface (NMDevice *dev, const char *iface, int ip4_address)
{ {
struct ifreq ifr; struct ifreq ifr;
const char *iface;
NMSock *sk; NMSock *sk;
gboolean success = FALSE; gboolean success = FALSE;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr); struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (iface != NULL, FALSE);
if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL) if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL)
return FALSE; return FALSE;
memset (&ifr, 0, sizeof(struct ifreq)); memset (&ifr, 0, sizeof (struct ifreq));
iface = nm_device_get_iface (dev);
memcpy (ifr.ifr_name, iface, strlen (iface)); memcpy (ifr.ifr_name, iface, strlen (iface));
p->sin_family = AF_INET; p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_address; p->sin_addr.s_addr = ip4_address;
if (ioctl (nm_dev_sock_get_fd (sk), SIOCSIFADDR, &ifr) == -1) if (ioctl (nm_dev_sock_get_fd (sk), SIOCSIFADDR, &ifr) == -1)
nm_warning ("nm_system_device_set_ip4_address (%s): failed to set IPv4 address!", iface); nm_warning ("nm_system_device_set_ip4_address_by_iface (%s): failed to set IPv4 address!", iface);
else else
{ {
success = TRUE; success = TRUE;
@@ -78,22 +340,94 @@ gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address)
} }
gboolean nm_system_device_set_ip4_netmask (NMDevice *dev, int ip4_netmask) /*
* nm_system_device_set_ip4_ptp_address
*
* Set the device's IPv4 point-to-point address.
*
*/
static gboolean nm_system_device_set_ip4_ptp_address (NMDevice *dev, int ip4_ptp_address)
{
g_return_val_if_fail (dev != NULL, FALSE);
return nm_system_device_set_ip4_ptp_address_with_iface (dev, nm_device_get_iface (dev), ip4_ptp_address);
}
static gboolean nm_system_device_set_ip4_ptp_address_with_iface (NMDevice *dev, const char *iface, int ip4_ptp_address)
{ {
struct ifreq ifr; struct ifreq ifr;
const char *iface;
NMSock *sk; NMSock *sk;
gboolean success = FALSE; gboolean success = FALSE;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr); struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (iface != NULL, FALSE);
if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL) if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL)
return FALSE; return FALSE;
memset (&ifr, 0, sizeof(struct ifreq)); memset (&ifr, 0, sizeof (struct ifreq));
memcpy (ifr.ifr_name, iface, strlen (iface));
p->sin_family = AF_INET;
p->sin_port = 0;
p->sin_addr.s_addr = ip4_ptp_address;
iface = nm_device_get_iface (dev); if (ioctl (nm_dev_sock_get_fd (sk), SIOCSIFDSTADDR, &ifr) == -1)
nm_warning ("nm_system_device_set_ip4_ptp_address (%s): failed to set IPv4 point-to-point address!", iface);
else
{
struct ifreq ifr2;
memset (&ifr2, 0, sizeof (struct ifreq));
memcpy (ifr2.ifr_name, iface, strlen (iface));
if (ioctl (nm_dev_sock_get_fd (sk), SIOCGIFFLAGS, &ifr2) >= 0)
{
memcpy (ifr2.ifr_name, iface, strlen (iface));
ifr2.ifr_flags |= IFF_POINTOPOINT;
if (ioctl (nm_dev_sock_get_fd (sk), SIOCSIFFLAGS, &ifr2) >= 0)
{
success = TRUE;
nm_info ("Your Point-to-Point IP address = %u.%u.%u.%u",
((unsigned char *)&ip4_ptp_address)[0], ((unsigned char *)&ip4_ptp_address)[1],
((unsigned char *)&ip4_ptp_address)[2], ((unsigned char *)&ip4_ptp_address)[3]);
}
else
nm_warning ("nm_system_device_set_ip4_ptp_address (%s): failed to set POINTOPOINT flag on device!", iface);
}
else
nm_warning ("nm_system_device_set_ip4_ptp_address (%s): failed to get interface flags!", iface);
}
nm_dev_sock_close (sk);
return (success);
}
/*
* nm_system_device_set_ip4_netmask
*
* Set the IPv4 netmask on a device.
*
*/
static gboolean nm_system_device_set_ip4_netmask (NMDevice *dev, int ip4_netmask)
{
g_return_val_if_fail (dev != NULL, FALSE);
return nm_system_device_set_ip4_netmask_with_iface (dev, nm_device_get_iface (dev), ip4_netmask);
}
static gboolean nm_system_device_set_ip4_netmask_with_iface (NMDevice *dev, const char *iface, int ip4_netmask)
{
struct ifreq ifr;
NMSock *sk;
gboolean success = FALSE;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
g_return_val_if_fail (iface != NULL, FALSE);
if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL)
return FALSE;
memset (&ifr, 0, sizeof (struct ifreq));
memcpy (ifr.ifr_name, iface, strlen (iface)); memcpy (ifr.ifr_name, iface, strlen (iface));
p->sin_family = AF_INET; p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_netmask; p->sin_addr.s_addr = ip4_netmask;
@@ -107,21 +441,32 @@ gboolean nm_system_device_set_ip4_netmask (NMDevice *dev, int ip4_netmask)
} }
gboolean nm_system_device_set_ip4_broadcast (NMDevice *dev, int ip4_broadcast) /*
* nm_system_device_set_ip4_broadcast
*
* Set the IPv4 broadcast address on a device.
*
*/
static gboolean nm_system_device_set_ip4_broadcast (NMDevice *dev, int ip4_broadcast)
{
g_return_val_if_fail (dev != NULL, FALSE);
return nm_system_device_set_ip4_broadcast_with_iface (dev, nm_device_get_iface (dev), ip4_broadcast);
}
static gboolean nm_system_device_set_ip4_broadcast_with_iface (NMDevice *dev, const char *iface, int ip4_broadcast)
{ {
struct ifreq ifr; struct ifreq ifr;
const char *iface;
NMSock *sk; NMSock *sk;
gboolean success = FALSE; gboolean success = FALSE;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr); struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (iface != NULL, FALSE);
if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL) if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL)
return FALSE; return FALSE;
memset (&ifr, 0, sizeof(struct ifreq)); memset (&ifr, 0, sizeof(struct ifreq));
iface = nm_device_get_iface (dev);
memcpy (ifr.ifr_name, iface, strlen (iface)); memcpy (ifr.ifr_name, iface, strlen (iface));
p->sin_family = AF_INET; p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_broadcast; p->sin_addr.s_addr = ip4_broadcast;
@@ -135,48 +480,58 @@ gboolean nm_system_device_set_ip4_broadcast (NMDevice *dev, int ip4_broadcast)
} }
gboolean nm_system_device_set_ip4_default_route (NMDevice *dev, int ip4_def_route) /*
* nm_system_device_set_ip4_broadcast
*
* Set the IPv4 broadcast address on a device.
*
*/
static gboolean nm_system_device_set_ip4_route (NMDevice *dev, int ip4_gateway, int ip4_dest, int ip4_netmask)
{ {
const char *iface;
NMSock *sk;
gboolean success = FALSE;
struct rtentry rtent;
struct sockaddr_in *p;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
return nm_system_device_set_ip4_route_with_iface (dev, nm_device_get_iface (dev), ip4_gateway, ip4_dest, ip4_netmask);
}
static gboolean nm_system_device_set_ip4_route_with_iface (NMDevice *dev, const char *iface, int ip4_gateway, int ip4_dest, int ip4_netmask)
{
NMSock * sk;
gboolean success = FALSE;
struct rtentry rtent;
struct sockaddr_in *p;
g_return_val_if_fail (iface != NULL, FALSE);
if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL) if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL)
return FALSE; return FALSE;
iface = nm_device_get_iface (dev);
memset (&rtent, 0, sizeof (struct rtentry)); memset (&rtent, 0, sizeof (struct rtentry));
p = (struct sockaddr_in *)&rtent.rt_dst; p = (struct sockaddr_in *)&rtent.rt_dst;
p->sin_family = AF_INET; p->sin_family = AF_INET;
p->sin_addr.s_addr = 0; p->sin_addr.s_addr = ip4_dest;
p = (struct sockaddr_in *)&rtent.rt_gateway; p = (struct sockaddr_in *)&rtent.rt_gateway;
p->sin_family = AF_INET; p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_def_route; p->sin_addr.s_addr = ip4_gateway;
p = (struct sockaddr_in *)&rtent.rt_genmask; p = (struct sockaddr_in *)&rtent.rt_genmask;
p->sin_family = AF_INET; p->sin_family = AF_INET;
p->sin_addr.s_addr = 0; p->sin_addr.s_addr = ip4_netmask;
rtent.rt_dev = (char *)iface; rtent.rt_dev = (char *)iface;
rtent.rt_metric = 1; rtent.rt_metric = 1;
rtent.rt_window = 0; rtent.rt_window = 0;
rtent.rt_flags = RTF_UP | RTF_GATEWAY | ( rtent.rt_window ? RTF_WINDOW : 0); rtent.rt_flags = RTF_UP | RTF_GATEWAY | (rtent.rt_window ? RTF_WINDOW : 0);
if (ioctl (nm_dev_sock_get_fd (sk), SIOCADDRT, &rtent) == -1) if (ioctl (nm_dev_sock_get_fd (sk), SIOCADDRT, &rtent) == -1)
{ {
if (errno == ENETUNREACH) /* possibly gateway is over the bridge */ if (errno == ENETUNREACH) /* possibly gateway is over the bridge */
{ /* try adding a route to gateway first */ { /* try adding a route to gateway first */
struct rtentry rtent2; struct rtentry rtent2;
memset (&rtent2, 0, sizeof(struct rtentry)); memset (&rtent2, 0, sizeof(struct rtentry));
p = (struct sockaddr_in *)&rtent2.rt_dst; p = (struct sockaddr_in *)&rtent2.rt_dst;
p->sin_family = AF_INET; p->sin_family = AF_INET;
p = (struct sockaddr_in *)&rtent2.rt_gateway; p = (struct sockaddr_in *)&rtent2.rt_gateway;
p->sin_family = AF_INET; p->sin_family = AF_INET;
p->sin_addr.s_addr = ip4_def_route; p->sin_addr.s_addr = ip4_gateway;
p = (struct sockaddr_in *)&rtent2.rt_genmask; p = (struct sockaddr_in *)&rtent2.rt_genmask;
p->sin_family = AF_INET; p->sin_family = AF_INET;
p->sin_addr.s_addr = 0xffffffff; p->sin_addr.s_addr = 0xffffffff;

View File

@@ -32,10 +32,16 @@
void nm_system_init (void); void nm_system_init (void);
gboolean nm_system_device_has_active_routes (NMDevice *dev); gboolean nm_system_device_has_active_routes (NMDevice *dev);
void nm_system_device_flush_routes (NMDevice *dev); void nm_system_device_flush_routes (NMDevice *dev);
void nm_system_device_flush_routes_with_iface (const char *iface);
void nm_system_device_add_default_route_via_device(NMDevice *dev); void nm_system_device_add_default_route_via_device(NMDevice *dev);
void nm_system_device_add_default_route_via_device_with_iface(const char *iface);
void nm_system_device_flush_addresses (NMDevice *dev); void nm_system_device_flush_addresses (NMDevice *dev);
void nm_system_device_update_config_info (NMDevice *dev); void nm_system_device_flush_addresses_with_iface (const char *iface);
gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev); gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev);
void nm_system_enable_loopback (void); void nm_system_enable_loopback (void);
void nm_system_flush_loopback_routes (void); void nm_system_flush_loopback_routes (void);
@@ -47,11 +53,22 @@ void nm_system_load_device_modules (void);
void nm_system_restart_mdns_responder (void); void nm_system_restart_mdns_responder (void);
void nm_system_device_add_ip6_link_address (NMDevice *dev); void nm_system_device_add_ip6_link_address (NMDevice *dev);
/* Prototyps for system-layer network functions (ie setting IP address, etc) */ void * nm_system_device_get_system_config (NMDevice *dev);
gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address); void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data);
gboolean nm_system_device_set_ip4_netmask (NMDevice *dev, int ip4_netmask); NMIP4Config * nm_system_device_new_ip4_system_config (NMDevice *dev);
gboolean nm_system_device_set_ip4_broadcast (NMDevice *dev, int ip4_broadcast);
gboolean nm_system_device_set_ip4_default_route (NMDevice *dev, int ip4_def_route); gboolean nm_system_device_get_use_dhcp (NMDevice *dev);
/* Prototypes for system-layer network functions (ie setting IP address, etc) */
void nm_system_remove_ip4_config_nameservers (NMNamedManager *named, NMIP4Config *config);
void nm_system_remove_ip4_config_search_domains (NMNamedManager *named, NMIP4Config *config);
gboolean nm_system_device_set_from_ip4_config (NMDevice *dev);
gboolean nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config);
gboolean nm_system_device_set_up_down (NMDevice *dev, gboolean up);
gboolean nm_system_device_set_up_down_with_iface (NMDevice *dev, const char *iface, gboolean up);
gboolean nm_system_device_update_resolv_conf (void *data, int len, const char *domain_name); gboolean nm_system_device_update_resolv_conf (void *data, int len, const char *domain_name);
#endif #endif

View File

@@ -1 +1,3 @@
.dirstamp .dirstamp
Makefile
Makefile.in

30
src/backends/Makefile.am Normal file
View File

@@ -0,0 +1,30 @@
INCLUDES = -I${top_srcdir} -I./named-manager -I./vpn-manager -I${top_srcdir}/utils
noinst_LTLIBRARIES = libnmbackend.la
libnmbackend_la_SOURCES =
if TARGET_REDHAT
libnmbackend_la_SOURCES += NetworkManagerRedHat.c \
shvar.c \
shvar.h
endif
if TARGET_GENTOO
libnmbackend_la_SOURCES += NetworkManagerGentoo.c
endif
if TARGET_DEBIAN
libnmbackend_la_SOURCES += NetworkManagerDebian.c \
interface_parser.c \
interface_parser.h
endif
if TARGET_SLACKWARE
libnmbackend_la_SOURCES += NetworkManagerSlackware.c
endif
libnmbackend_la_LIBADD = $(DBUS_LIBS) $(GTHREAD_LIBS)
libnmbackend_la_CFLAGS = $(NetworkManager_CPPFLAGS)

View File

@@ -39,10 +39,6 @@ void nm_system_init (void)
{ {
/* Kill any dhclients lying around */ /* Kill any dhclients lying around */
nm_system_kill_all_dhcp_daemons (); nm_system_kill_all_dhcp_daemons ();
/* Stop nifd since we respawn mDNSResponder ourselves */
if (nm_spawn_process ("/etc/init.d/nifd status") != 0)
nm_spawn_process ("/etc/init.d/nifd stop");
} }
@@ -54,16 +50,30 @@ void nm_system_init (void)
*/ */
void nm_system_device_flush_routes (NMDevice *dev) void nm_system_device_flush_routes (NMDevice *dev)
{ {
char *buf;
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
/* Not really applicable for test devices */ /* Not really applicable for test devices */
if (nm_device_is_test_device (dev)) if (nm_device_is_test_device (dev))
return; return;
nm_system_device_flush_routes_with_iface (nm_device_get_iface (dev));
}
/*
* nm_system_device_flush_routes_with_iface
*
* Flush all routes associated with a network device
*
*/
void nm_system_device_flush_routes_with_iface (const char *iface)
{
char *buf;
g_return_if_fail (iface != NULL);
/* Remove routing table entries */ /* Remove routing table entries */
buf = g_strdup_printf ("/sbin/ip route flush dev %s", nm_device_get_iface (dev)); buf = g_strdup_printf ("/sbin/ip route flush dev %s", iface);
nm_spawn_process (buf); nm_spawn_process (buf);
g_free (buf); g_free (buf);
} }
@@ -72,21 +82,35 @@ void nm_system_device_flush_routes (NMDevice *dev)
/* /*
* nm_system_device_add_default_route_via_device * nm_system_device_add_default_route_via_device
* *
* Flush all routes associated with a network device * Add default route to the given device
* *
*/ */
void nm_system_device_add_default_route_via_device (NMDevice *dev) void nm_system_device_add_default_route_via_device (NMDevice *dev)
{ {
char *buf;
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
/* Not really applicable for test devices */ /* Not really applicable for test devices */
if (nm_device_is_test_device (dev)) if (nm_device_is_test_device (dev))
return; return;
/* Remove routing table entries */ nm_system_device_add_default_route_via_device_with_iface (nm_device_get_iface (dev));
buf = g_strdup_printf ("/sbin/ip route add default dev %s", nm_device_get_iface (dev)); }
/*
* nm_system_device_add_default_route_via_device_with_iface
*
* Add default route to the given device
*
*/
void nm_system_device_add_default_route_via_device_with_iface (const char *iface)
{
char *buf;
g_return_if_fail (iface != NULL);
/* Add default gateway */
buf = g_strdup_printf ("/sbin/ip route add default dev %s", iface);
nm_spawn_process (buf); nm_spawn_process (buf);
g_free (buf); g_free (buf);
} }
@@ -113,82 +137,36 @@ gboolean nm_system_device_has_active_routes (NMDevice *dev)
*/ */
void nm_system_device_flush_addresses (NMDevice *dev) void nm_system_device_flush_addresses (NMDevice *dev)
{ {
char *buf;
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
/* Not really applicable for test devices */ /* Not really applicable for test devices */
if (nm_device_is_test_device (dev)) if (nm_device_is_test_device (dev))
return; return;
nm_system_device_flush_addresses_with_iface (nm_device_get_iface (dev));
}
/*
* nm_system_device_flush_addresses_with_iface
*
* Flush all network addresses associated with a network device
*
*/
void nm_system_device_flush_addresses_with_iface (const char *iface)
{
char *buf;
g_return_if_fail (iface != NULL);
/* Remove all IP addresses for a device */ /* Remove all IP addresses for a device */
buf = g_strdup_printf ("/sbin/ip address flush dev %s", nm_device_get_iface (dev)); buf = g_strdup_printf ("/sbin/ip address flush dev %s", iface);
nm_spawn_process (buf); nm_spawn_process (buf);
g_free (buf); g_free (buf);
} }
/* #if 0
* nm_system_device_setup_static_ip4_config
*
* Set up the device with a particular IPv4 address/netmask/gateway.
*
* Returns: TRUE on success
* FALSE on error
*
*/
gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev)
{
#define IPBITS (sizeof (guint32) * 8)
struct in_addr temp_addr;
struct in_addr temp_addr2;
char *s_tmp;
char *s_tmp2;
int i;
guint32 addr;
guint32 netmask;
guint32 prefix = IPBITS; /* initialize with # bits in ip4 address */
guint32 broadcast;
char *buf;
int err;
const char *iface;
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (!nm_device_config_get_use_dhcp (dev), FALSE);
addr = nm_device_config_get_ip4_address (dev);
netmask = nm_device_config_get_ip4_netmask (dev);
iface = nm_device_get_iface (dev);
broadcast = nm_device_config_get_ip4_broadcast (dev);
/* Calculate the prefix (# bits stripped off by the netmask) */
for (i = 0; i < IPBITS; i++)
{
if (!(ntohl (netmask) & ((2 << i) - 1)))
prefix--;
}
/* Calculate the broadcast address if the user didn't specify one */
if (!broadcast)
broadcast = ((addr & (int)netmask) | ~(int)netmask);
/* FIXME: what if some other device is already using our IP address? */
/* Set our IP address */
temp_addr.s_addr = addr;
temp_addr2.s_addr = broadcast;
s_tmp = g_strdup (inet_ntoa (temp_addr));
s_tmp2 = g_strdup (inet_ntoa (temp_addr2));
buf = g_strdup_printf ("/sbin/ip addr add %s/%d brd %s dev %s label %s", s_tmp, prefix, s_tmp2, iface, iface);
g_free (s_tmp);
g_free (s_tmp2);
if ((err = nm_spawn_process (buf)))
{
nm_warning ("Error: could not set network configuration for device '%s' using command:\n '%s'", iface, buf);
goto error;
}
g_free (buf);
/* Alert other computers of our new address */ /* Alert other computers of our new address */
temp_addr.s_addr = addr; temp_addr.s_addr = addr;
buf = g_strdup_printf ("/sbin/arping -q -A -c 1 -I %s %s", iface, inet_ntoa (temp_addr)); buf = g_strdup_printf ("/sbin/arping -q -A -c 1 -I %s %s", iface, inet_ntoa (temp_addr));
@@ -198,24 +176,7 @@ gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev)
buf = g_strdup_printf ("/sbin/arping -q -U -c 1 -I %s %s", iface, inet_ntoa (temp_addr)); buf = g_strdup_printf ("/sbin/arping -q -U -c 1 -I %s %s", iface, inet_ntoa (temp_addr));
nm_spawn_process (buf); nm_spawn_process (buf);
g_free (buf); g_free (buf);
#endif
/* Set the default route to be this device's gateway */
temp_addr.s_addr = nm_device_config_get_ip4_gateway (dev);
buf = g_strdup_printf ("/sbin/ip route replace default via %s dev %s", inet_ntoa (temp_addr), iface);
if ((err = nm_spawn_process (buf)))
{
nm_warning ("Error: could not set default route using command\n '%s'", buf);
goto error;
}
g_free (buf);
return (TRUE);
error:
g_free (buf);
nm_system_device_flush_addresses (dev);
nm_system_device_flush_routes (dev);
return (FALSE);
}
/* /*
@@ -294,7 +255,7 @@ void nm_system_update_dns (void)
if (nm_spawn_process ("/etc/init.d/nscd status") != 0) if (nm_spawn_process ("/etc/init.d/nscd status") != 0)
nm_spawn_process ("/etc/init.d/nscd restart"); nm_spawn_process ("/etc/init.d/nscd restart");
nm_warning ("Clearing nscd hosts cache."); nm_info ("Clearing nscd hosts cache.");
nm_spawn_process ("/usr/sbin/nscd -i hosts"); nm_spawn_process ("/usr/sbin/nscd -i hosts");
#else #else
nm_spawn_process ("/usr/bin/killall -q nscd"); nm_spawn_process ("/usr/bin/killall -q nscd");
@@ -368,47 +329,44 @@ void nm_system_device_add_ip6_link_address (NMDevice *dev)
} }
typedef struct RHSystemConfigData
{
NMIP4Config * config;
gboolean use_dhcp;
} RHSystemConfigData;
/* /*
* nm_system_device_update_config_info * nm_system_device_get_system_config
* *
* Retrieve any relevant configuration info for a particular device * Read in the config file for a device.
* from the system network configuration information. Clear out existing
* info before setting stuff too.
* *
*/ */
void nm_system_device_update_config_info (NMDevice *dev) void *nm_system_device_get_system_config (NMDevice *dev)
{ {
char *cfg_file_path = NULL; char * cfg_file_path = NULL;
shvarFile *file; shvarFile * file;
char *buf = NULL; char * buf = NULL;
gboolean use_dhcp = TRUE; RHSystemConfigData * sys_data = NULL;
guint32 ip4_address = 0; gboolean error = FALSE;
guint32 ip4_netmask = 0;
guint32 ip4_gateway = 0;
guint32 ip4_broadcast = 0;
g_return_if_fail (dev != NULL); g_return_val_if_fail (dev != NULL, NULL);
/* We use DHCP on an interface unless told not to */
nm_device_config_set_use_dhcp (dev, TRUE);
nm_device_config_set_ip4_address (dev, 0);
nm_device_config_set_ip4_gateway (dev, 0);
nm_device_config_set_ip4_netmask (dev, 0);
nm_device_config_set_ip4_broadcast (dev, 0);
/* Red Hat/Fedora Core systems store this information in /* Red Hat/Fedora Core systems store this information in
* /etc/sysconfig/network-scripts/ifcfg-* where * is the interface * /etc/sysconfig/network-scripts/ifcfg-* where * is the interface
* name. * name.
*/ */
sys_data = g_malloc0 (sizeof (RHSystemConfigData));
sys_data->use_dhcp = TRUE;
cfg_file_path = g_strdup_printf ("/etc/sysconfig/network-scripts/ifcfg-%s", nm_device_get_iface (dev)); cfg_file_path = g_strdup_printf ("/etc/sysconfig/network-scripts/ifcfg-%s", nm_device_get_iface (dev));
if (!cfg_file_path) if (!cfg_file_path)
return; return sys_data;
if (!(file = svNewFile (cfg_file_path))) if (!(file = svNewFile (cfg_file_path)))
{ {
g_free (cfg_file_path); g_free (cfg_file_path);
return; return sys_data;
} }
g_free (cfg_file_path); g_free (cfg_file_path);
@@ -420,82 +378,148 @@ void nm_system_device_update_config_info (NMDevice *dev)
goto out; goto out;
} }
buf = svGetValue (file, "BOOTPROTO"); if ((buf = svGetValue (file, "BOOTPROTO")))
if (buf)
{ {
if (strcmp (buf, "dhcp")) if (strcasecmp (buf, "dhcp"))
use_dhcp = FALSE; sys_data->use_dhcp = FALSE;
free (buf); free (buf);
} }
buf = svGetValue (file, "IPADDR"); sys_data->config = nm_ip4_config_new ();
if (buf)
{
ip4_address = inet_addr (buf);
free (buf);
}
buf = svGetValue (file, "GATEWAY"); if (!(sys_data->use_dhcp))
if (buf)
{ {
ip4_gateway = inet_addr (buf); if ((buf = svGetValue (file, "IPADDR")))
free (buf);
}
buf = svGetValue (file, "NETMASK");
if (buf)
{
ip4_netmask = inet_addr (buf);
free (buf);
}
else
{
/* Make a default netmask if we have an IP address */
if (ip4_address)
{ {
if (((ntohl (ip4_address) & 0xFF000000) >> 24) <= 127) nm_ip4_config_set_address (sys_data->config, inet_addr (buf));
ip4_netmask = htonl (0xFF000000); free (buf);
else if (((ntohl (ip4_address) & 0xFF000000) >> 24) <= 191) }
ip4_netmask = htonl (0xFFFF0000); else
{
nm_warning ("Network configuration for device '%s' was invalid (non-DHCP configuration, "
"but no IP address specified. Will use DHCP instead.", nm_device_get_iface (dev));
error = TRUE;
goto out;
}
if ((buf = svGetValue (file, "GATEWAY")))
{
nm_ip4_config_set_gateway (sys_data->config, inet_addr (buf));
free (buf);
}
else
{
nm_warning ("Network configuration for device '%s' was invalid (non-DHCP configuration, "
"but no gateway specified. Will use DHCP instead.", nm_device_get_iface (dev));
error = TRUE;
goto out;
}
if ((buf = svGetValue (file, "NETMASK")))
{
nm_ip4_config_set_netmask (sys_data->config, inet_addr (buf));
free (buf);
}
else
{
guint32 addr = nm_ip4_config_get_address (sys_data->config);
/* Make a default netmask if we have an IP address */
if (((ntohl (addr) & 0xFF000000) >> 24) <= 127)
nm_ip4_config_set_netmask (sys_data->config, htonl (0xFF000000));
else if (((ntohl (addr) & 0xFF000000) >> 24) <= 191)
nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFF0000));
else else
ip4_netmask = htonl (0xFFFFFF00); nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFFFF00));
}
if ((buf = svGetValue (file, "BROADCAST")))
{
nm_ip4_config_set_broadcast (sys_data->config, inet_addr (buf));
free (buf);
}
else
{
guint32 broadcast = ((nm_ip4_config_get_address (sys_data->config) & nm_ip4_config_get_netmask (sys_data->config))
| ~nm_ip4_config_get_netmask (sys_data->config));
nm_ip4_config_set_broadcast (sys_data->config, broadcast);
} }
} }
buf = svGetValue (file, "BROADCAST");
if (buf)
{
ip4_broadcast = inet_addr (buf);
free (buf);
}
if (!use_dhcp && (!ip4_address || !ip4_gateway || !ip4_netmask))
{
nm_warning ("Error: network configuration for device '%s' was invalid (non-DCHP configuration,"
" but no address/gateway specificed). Will use DHCP instead.\n", nm_device_get_iface (dev));
use_dhcp = TRUE;
}
/* If successful, set values on the device */
nm_device_config_set_use_dhcp (dev, use_dhcp);
if (ip4_address)
nm_device_config_set_ip4_address (dev, ip4_address);
if (ip4_gateway)
nm_device_config_set_ip4_gateway (dev, ip4_gateway);
if (ip4_netmask)
nm_device_config_set_ip4_netmask (dev, ip4_netmask);
if (ip4_broadcast)
nm_device_config_set_ip4_broadcast (dev, ip4_broadcast);
#if 0 #if 0
nm_debug ("------ Config (%s)", nm_device_get_iface (dev)); nm_debug ("------ Config (%s)", nm_device_get_iface (dev));
nm_debug (" DHCP=%d\n", use_dhcp); nm_debug (" DHCP=%d\n", sys_data->use_dhcp);
nm_debug (" ADDR=%d\n", ip4_address); nm_debug (" ADDR=%d\n", nm_ip4_config_get_address (sys_data->config));
nm_debug (" GW=%d\n", ip4_gateway); nm_debug (" GW=%d\n", nm_ip4_config_get_gateway (sys_data->config));
nm_debug (" NM=%d\n", ip4_netmask); nm_debug (" NM=%d\n", nm_ip4_config_get_netmask (sys_data->config));
nm_debug ("---------------------\n"); nm_debug ("---------------------\n");
#endif #endif
out: out:
svCloseFile (file); svCloseFile (file);
if (error)
{
sys_data->use_dhcp = TRUE;
/* Clear out the config */
nm_ip4_config_unref (sys_data->config);
sys_data->config = NULL;
}
return (void *)sys_data;
} }
/*
* nm_system_device_free_system_config
*
* Free stored system config data
*
*/
void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data)
{
RHSystemConfigData *sys_data = (RHSystemConfigData *)system_config_data;
g_return_if_fail (dev != NULL);
if (!sys_data)
return;
if (sys_data->config)
nm_ip4_config_unref (sys_data->config);
}
/*
* nm_system_device_get_use_dhcp
*
* Return whether the distro-specific system config tells us to use
* dhcp for this device.
*
*/
gboolean nm_system_device_get_use_dhcp (NMDevice *dev)
{
RHSystemConfigData *sys_data;
g_return_val_if_fail (dev != NULL, TRUE);
if ((sys_data = nm_device_get_system_config_data (dev)))
return sys_data->use_dhcp;
return TRUE;
}
NMIP4Config *nm_system_device_new_ip4_system_config (NMDevice *dev)
{
RHSystemConfigData *sys_data;
NMIP4Config *new_config = NULL;
g_return_val_if_fail (dev != NULL, NULL);
if ((sys_data = nm_device_get_system_config_data (dev)))
new_config = nm_ip4_config_copy (sys_data->config);
return new_config;
}

View File

@@ -0,0 +1,14 @@
namedconf_DATA = named.conf
namedconfdir = $(pkgdatadir)
EXTRA_DIST = $(namedconf_DATA)
INCLUDES = -I${top_srcdir}/utils
noinst_LTLIBRARIES = libnamed-manager.la
libnamed_manager_la_SOURCES = nm-named-manager.h nm-named-manager.c
libnamed_manager_la_CPPFLAGS = $(DBUS_CFLAGS) $(GTHREAD_CFLAGS) -DNM_PKGDATADIR=\"$(pkgdatadir)\" -DNM_LOCALSTATEDIR=\"$(localstatedir)\"
libnamed_manager_la_LIBADD = $(DBUS_LIBS) $(GTHREAD_LIBS)

307
src/nm-ip4-config.c Normal file
View File

@@ -0,0 +1,307 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2005 Red Hat, Inc.
*/
#include <glib.h>
#include <stdio.h>
#include <string.h>
#include "NetworkManager.h"
#include "nm-ip4-config.h"
typedef struct NamserverID
{
guint32 ns_address;
guint32 ns_id;
} NameserverID;
typedef struct DomainID
{
char * domain;
guint32 domain_id;
} DomainID;
struct NMIP4Config
{
guint refcount;
guint32 ip4_address;
guint32 ip4_gateway;
guint32 ip4_netmask;
guint32 ip4_broadcast;
GSList *nameservers;
GSList *domains;
};
static void domain_id_free (DomainID *did);
static void nameserver_id_free (NameserverID *ns);
NMIP4Config *nm_ip4_config_new (void)
{
NMIP4Config *config = g_malloc0 (sizeof (NMIP4Config));
config->refcount = 1;
return config;
}
NMIP4Config *nm_ip4_config_copy (NMIP4Config *src_config)
{
NMIP4Config * dst_config;
int i, len;
g_return_val_if_fail (src_config != NULL, NULL);
dst_config = g_malloc0 (sizeof (NMIP4Config));
dst_config->refcount = 1;
dst_config->ip4_address = nm_ip4_config_get_address (src_config);
dst_config->ip4_gateway = nm_ip4_config_get_gateway (src_config);
dst_config->ip4_netmask = nm_ip4_config_get_netmask (src_config);
dst_config->ip4_broadcast = nm_ip4_config_get_broadcast (src_config);
len = nm_ip4_config_get_num_nameservers (src_config);
for (i = 0; i < len; i++)
nm_ip4_config_add_nameserver (dst_config, nm_ip4_config_get_nameserver (src_config, i));
len = nm_ip4_config_get_num_domains (src_config);
for (i = 0; i < len; i++)
nm_ip4_config_add_domain (dst_config, nm_ip4_config_get_domain (src_config, i));
return dst_config;
}
void nm_ip4_config_ref (NMIP4Config *config)
{
g_return_if_fail (config != NULL);
config->refcount++;
}
void nm_ip4_config_unref (NMIP4Config *config)
{
g_return_if_fail (config != NULL);
config->refcount--;
if (config->refcount <= 0)
{
g_slist_foreach (config->nameservers, (GFunc) nameserver_id_free, NULL);
g_slist_free (config->nameservers);
g_slist_foreach (config->domains, (GFunc) domain_id_free, NULL);
g_slist_free (config->domains);
memset (config, 0, sizeof (NMIP4Config));
g_free (config);
}
}
guint32 nm_ip4_config_get_address (NMIP4Config *config)
{
g_return_val_if_fail (config != NULL, 0);
return config->ip4_address;
}
void nm_ip4_config_set_address (NMIP4Config *config, guint32 addr)
{
g_return_if_fail (config != NULL);
config->ip4_address = addr;
}
guint32 nm_ip4_config_get_gateway (NMIP4Config *config)
{
g_return_val_if_fail (config != NULL, 0);
return config->ip4_gateway;
}
void nm_ip4_config_set_gateway (NMIP4Config *config, guint32 gateway)
{
g_return_if_fail (config != NULL);
config->ip4_gateway = gateway;
}
guint32 nm_ip4_config_get_netmask (NMIP4Config *config)
{
g_return_val_if_fail (config != NULL, 0);
return config->ip4_netmask;
}
void nm_ip4_config_set_netmask (NMIP4Config *config, guint32 netmask)
{
g_return_if_fail (config != NULL);
config->ip4_netmask = netmask;
}
guint32 nm_ip4_config_get_broadcast (NMIP4Config *config)
{
g_return_val_if_fail (config != NULL, 0);
return config->ip4_broadcast;
}
void nm_ip4_config_set_broadcast (NMIP4Config *config, guint32 broadcast)
{
g_return_if_fail (config != NULL);
config->ip4_broadcast = broadcast;
}
static NameserverID *nameserver_id_new (guint32 nameserver)
{
NameserverID *ns = g_malloc0 (sizeof (NameserverID));
ns->ns_address = nameserver;
return ns;
}
static void nameserver_id_free (NameserverID *ns)
{
g_free (ns);
}
void nm_ip4_config_add_nameserver (NMIP4Config *config, guint32 nameserver)
{
g_return_if_fail (config != NULL);
config->nameservers = g_slist_append (config->nameservers, nameserver_id_new (nameserver));
}
guint32 nm_ip4_config_get_nameserver (NMIP4Config *config, guint index)
{
NameserverID *ns;
g_return_val_if_fail (config != NULL, 0);
g_return_val_if_fail (index < g_slist_length (config->nameservers), 0);
if ((ns = g_slist_nth_data (config->nameservers, index)))
return ns->ns_address;
return 0;
}
guint32 nm_ip4_config_get_nameserver_id (NMIP4Config *config, guint index)
{
NameserverID *ns;
g_return_val_if_fail (config != NULL, 0);
g_return_val_if_fail (index < g_slist_length (config->nameservers), 0);
if ((ns = g_slist_nth_data (config->nameservers, index)))
return ns->ns_id;
return 0;
}
void nm_ip4_config_set_nameserver_id (NMIP4Config *config, guint index, guint32 id)
{
NameserverID *ns;
g_return_if_fail (config != NULL);
g_return_if_fail (index < g_slist_length (config->nameservers));
if ((ns = g_slist_nth_data (config->nameservers, index)))
ns->ns_id = id;
}
guint32 nm_ip4_config_get_num_nameservers (NMIP4Config *config)
{
g_return_val_if_fail (config != NULL, 0);
return (g_slist_length (config->nameservers));
}
static DomainID *domain_id_new (const char *domain)
{
DomainID *did = g_malloc0 (sizeof (DomainID));
did->domain = g_strdup (domain);
return did;
}
static void domain_id_free (DomainID *did)
{
if (!did)
return;
g_free (did->domain);
g_free (did);
}
void nm_ip4_config_add_domain (NMIP4Config *config, const char *domain)
{
g_return_if_fail (config != NULL);
g_return_if_fail (domain != NULL);
if (!strlen (domain))
return;
config->domains = g_slist_append (config->domains, domain_id_new (domain));
}
const char *nm_ip4_config_get_domain (NMIP4Config *config, guint index)
{
DomainID *did;
g_return_val_if_fail (config != NULL, NULL);
g_return_val_if_fail (index < g_slist_length (config->domains), NULL);
if ((did = g_slist_nth_data (config->domains, index)))
return did->domain;
return NULL;
}
guint32 nm_ip4_config_get_domain_id (NMIP4Config *config, guint index)
{
DomainID *did;
g_return_val_if_fail (config != NULL, 0);
g_return_val_if_fail (index < g_slist_length (config->domains), 0);
if ((did = g_slist_nth_data (config->domains, index)))
return did->domain_id;
return 0;
}
void nm_ip4_config_set_domain_id (NMIP4Config *config, guint index, guint32 id)
{
DomainID *did;
g_return_if_fail (config != NULL);
g_return_if_fail (index < g_slist_length (config->domains));
if ((did = g_slist_nth_data (config->domains, index)))
did->domain_id = id;
}
guint32 nm_ip4_config_get_num_domains (NMIP4Config *config)
{
g_return_val_if_fail (config != NULL, 0);
return (g_slist_length (config->domains));
}

59
src/nm-ip4-config.h Normal file
View File

@@ -0,0 +1,59 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#ifndef NM_IP4_CONFIG_H
#define NM_IP4_CONFIG_H
#include <glib.h>
typedef struct NMIP4Config NMIP4Config;
NMIP4Config * nm_ip4_config_new (void);
NMIP4Config * nm_ip4_config_copy (NMIP4Config *config);
void nm_ip4_config_ref (NMIP4Config *config);
void nm_ip4_config_unref (NMIP4Config *config);
guint32 nm_ip4_config_get_address (NMIP4Config *config);
void nm_ip4_config_set_address (NMIP4Config *config, guint32 addr);
guint32 nm_ip4_config_get_gateway (NMIP4Config *config);
void nm_ip4_config_set_gateway (NMIP4Config *config, guint32 gateway);
guint32 nm_ip4_config_get_netmask (NMIP4Config *config);
void nm_ip4_config_set_netmask (NMIP4Config *config, guint32 netmask);
guint32 nm_ip4_config_get_broadcast (NMIP4Config *config);
void nm_ip4_config_set_broadcast (NMIP4Config *config, guint32 broadcast);
void nm_ip4_config_add_nameserver (NMIP4Config *config, guint32 nameserver);
guint32 nm_ip4_config_get_nameserver (NMIP4Config *config, guint index);
guint32 nm_ip4_config_get_nameserver_id (NMIP4Config *config, guint index);
void nm_ip4_config_set_nameserver_id (NMIP4Config *config, guint index, guint32 id);
guint32 nm_ip4_config_get_num_nameservers (NMIP4Config *config);
void nm_ip4_config_add_domain (NMIP4Config *config, const char *domain);
const char * nm_ip4_config_get_domain (NMIP4Config *config, guint index);
guint32 nm_ip4_config_get_domain_id (NMIP4Config *config, guint index);
void nm_ip4_config_set_domain_id (NMIP4Config *config, guint index, guint32 id);
guint32 nm_ip4_config_get_num_domains (NMIP4Config *config);
#endif

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,26 @@
INCLUDES = -I${top_srcdir}/utils -I${top_srcdir}/src -I${top_srcdir}/src/named-manager
noinst_LTLIBRARIES = libvpn-manager.la
libvpn_manager_la_SOURCES = nm-dbus-vpn.c \
nm-dbus-vpn.h \
nm-vpn-connection.c \
nm-vpn-connection.h \
nm-vpn-manager.c \
nm-vpn-manager.h \
nm-vpn-service.c \
nm-vpn-service.h
libvpn_manager_la_CPPFLAGS = $(DBUS_CFLAGS) \
$(GTHREAD_CFLAGS) \
$(HAL_CFLAGS) \
-g \
-Wall \
-DDBUS_API_SUBJECT_TO_CHANGE \
-DG_DISABLE_DEPRECATED \
-DBINDIR=\"$(bindir)\" \
-DDATADIR=\"$(datadir)\" \
-DSYSCONFDIR=\"$(sysconfdir)\"
libvpn_manager_la_LIBADD = $(DBUS_LIBS) $(GTHREAD_LIBS)

View File

@@ -0,0 +1,594 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2005 Red Hat, Inc.
*/
#include <glib.h>
#include <dbus/dbus.h>
#include "NetworkManagerMain.h"
#include "NetworkManagerDevice.h"
#include "NetworkManagerDbus.h"
#include "NetworkManagerUtils.h"
#include "nm-dbus-vpn.h"
#include "nm-vpn-manager.h"
#include "nm-vpn-connection.h"
#include "nm-utils.h"
/*
* nm_dbus_vpn_signal_vpn_connection_update
*
* Notifies the bus that a VPN connection has been added, deleted, or
* changed properties.
*
*/
void nm_dbus_vpn_signal_vpn_connection_update (DBusConnection *con, NMVPNConnection *vpn)
{
DBusMessage *message;
const char *vpn_name;
g_return_if_fail (con != NULL);
g_return_if_fail (vpn != NULL);
if (!(message = dbus_message_new_signal (NM_DBUS_PATH_VPN, NM_DBUS_INTERFACE_VPN, "VPNConnectionUpdate")))
{
nm_warning ("Not enough memory for new dbus message!");
return;
}
vpn_name = nm_vpn_connection_get_name (vpn);
dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_INVALID);
if (!dbus_connection_send (con, message, NULL))
nm_warning ("Could not raise the VPNConnectionUpdate signal!");
dbus_message_unref (message);
}
/*
* nm_dbus_vpn_signal_vpn_connection_change
*
* Notifies the bus that the current VPN connection, if any, has changed.
*
*/
void nm_dbus_vpn_signal_vpn_connection_change (DBusConnection *con, NMVPNConnection *vpn)
{
DBusMessage *message;
const char *vpn_name;
g_return_if_fail (con != NULL);
if (!(message = dbus_message_new_signal (NM_DBUS_PATH_VPN, NM_DBUS_INTERFACE_VPN, "VPNConnectionChange")))
{
nm_warning ("Not enough memory for new dbus message!");
return;
}
if (vpn)
vpn_name = nm_vpn_connection_get_name (vpn);
else
vpn_name = "";
dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_INVALID);
if (!dbus_connection_send (con, message, NULL))
nm_warning ("Could not raise the VPNConnectionChange signal!");
dbus_message_unref (message);
}
/*
* nnm_dbus_vpn_signal_vpn_login_failed
*
* Pass the VPN Login Failure message from the daemon to the bus.
*
*/
void nm_dbus_vpn_signal_vpn_login_failed (DBusConnection *con, NMVPNConnection *vpn, const char *error_msg)
{
DBusMessage *message;
const char *vpn_name;
g_return_if_fail (con != NULL);
g_return_if_fail (vpn != NULL);
g_return_if_fail (error_msg != NULL);
if (!(message = dbus_message_new_signal (NM_DBUS_PATH_VPN, NM_DBUS_INTERFACE_VPN, "VPNLoginFailed")))
{
nm_warning ("Not enough memory for new dbus message!");
return;
}
vpn_name = nm_vpn_connection_get_name (vpn);
dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_STRING, &error_msg, DBUS_TYPE_INVALID);
if (!dbus_connection_send (con, message, NULL))
nm_warning ("Could not raise the VPNLoginFailed signal!");
dbus_message_unref (message);
}
/*
* nnm_dbus_vpn_signal_vpn_login_banner
*
* Pass the VPN's login banner message to the bus if anyone wants to use it.
*
*/
void nm_dbus_vpn_signal_vpn_login_banner (DBusConnection *con, NMVPNConnection *vpn, const char *banner)
{
DBusMessage *message;
const char *vpn_name;
g_return_if_fail (con != NULL);
g_return_if_fail (vpn != NULL);
g_return_if_fail (banner != NULL);
if (!(message = dbus_message_new_signal (NM_DBUS_PATH_VPN, NM_DBUS_INTERFACE_VPN, "VPNLoginBanner")))
{
nm_warning ("Not enough memory for new dbus message!");
return;
}
vpn_name = nm_vpn_connection_get_name (vpn);
dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_STRING, &banner, DBUS_TYPE_INVALID);
if (!dbus_connection_send (con, message, NULL))
nm_warning ("Could not raise the VPNLoginBanner signal!");
dbus_message_unref (message);
}
/*
* nm_dbus_vpn_get_vpn_data
*
* Get VPN specific data from NMI for a vpn connection
*
* NOTE: caller MUST free returned value using g_strfreev()
*
*/
static char ** nm_dbus_vpn_get_vpn_data (DBusConnection *connection, NMVPNConnection *vpn, int *num_items)
{
DBusMessage *message;
DBusError error;
DBusMessage *reply;
char **data_items = NULL;
const char *vpn_name;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (vpn != NULL, NULL);
g_return_val_if_fail (num_items != NULL, NULL);
*num_items = -1;
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getVPNConnectionVPNData")))
{
nm_warning ("nm_dbus_vpn_get_vpn_data(): Couldn't allocate the dbus message");
return (NULL);
}
vpn_name = nm_vpn_connection_get_name (vpn);
dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_INVALID);
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
dbus_message_unref (message);
if (dbus_error_is_set (&error))
nm_warning ("nm_dbus_vpn_get_vpn_data(): %s raised %s", error.name, error.message);
else if (!reply)
nm_info ("nm_dbus_vpn_get_vpn_data(): reply was NULL.");
else
{
DBusMessageIter iter, array_iter;
GArray *buffer;
dbus_message_iter_init (reply, &iter);
dbus_message_iter_recurse (&iter, &array_iter);
buffer = g_array_new (TRUE, TRUE, sizeof (gchar *));
if (buffer == NULL)
return NULL;
while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING)
{
const char *value;
char *str;
dbus_message_iter_get_basic (&array_iter, &value);
str = g_strdup (value);
if (str == NULL)
{
g_array_free (buffer, TRUE);
return NULL;
}
g_array_append_val (buffer, str);
dbus_message_iter_next (&array_iter);
}
data_items = (gchar **)(buffer->data);
*num_items = buffer->len;
g_array_free (buffer, FALSE);
}
if (reply)
dbus_message_unref (reply);
return (data_items);
}
/*
* nm_dbus_vpn_add_one_connection
*
* Retrieve and add to our VPN Manager one VPN connection from NMI.
*
*/
NMVPNConnection *nm_dbus_vpn_add_one_connection (DBusConnection *con, const char *name, NMVPNManager *vpn_manager)
{
DBusMessage *message;
DBusError error;
DBusMessage *reply;
const char *con_name = NULL;
const char *service_name = NULL;
const char *user_name = NULL;
DBusMessageIter iter;
NMVPNConnection *vpn = NULL;
g_return_val_if_fail (con != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (vpn_manager != NULL, NULL);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getVPNConnectionProperties")))
{
nm_warning ("Couldn't allocate the dbus message");
return NULL;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
/* Send message and get properties back from NetworkManagerInfo */
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (con, message, -1, &error);
dbus_message_unref (message);
if (dbus_error_is_set (&error))
{
nm_warning ("nm_dbus_add_one_vpn_connections(): %s raised %s", error.name, error.message);
goto out;
}
if (!reply)
goto out;
dbus_error_init (&error);
if (dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &con_name, DBUS_TYPE_STRING, &service_name,
DBUS_TYPE_STRING, &user_name, DBUS_TYPE_INVALID))
{
vpn = nm_vpn_manager_add_connection (vpn_manager, con_name, service_name, user_name);
}
dbus_message_unref (reply);
out:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
return vpn;
}
/*
* nm_dbus_vpn_connections_update
*
* Update VPN connections from NetworkManagerInfo.
*
*/
gboolean nm_dbus_vpn_connections_update (NMData *data)
{
DBusMessage *message;
DBusError error;
DBusMessage *reply;
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (data->dbus_connection != NULL, FALSE);
g_return_val_if_fail (data->vpn_manager != NULL, FALSE);
/* Clear all existing connections in preparation for new ones */
nm_vpn_manager_clear_connections (data->vpn_manager);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getVPNConnections")))
{
nm_warning ("nm_dbus_vpn_connections_update (): Couldn't allocate the dbus message");
return FALSE;
}
/* Send message and get essid back from NetworkManagerInfo */
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (data->dbus_connection, message, -1, &error);
dbus_message_unref (message);
if (dbus_error_is_set (&error))
nm_warning ("nm_dbus_vpn_connections_update(): %s raised %s", error.name, error.message);
else if (!reply)
nm_info ("nm_dbus_vpn_connections_update(): reply was NULL.");
else
{
DBusMessageIter iter, array_iter;
dbus_message_iter_init (reply, &iter);
dbus_message_iter_recurse (&iter, &array_iter);
while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING)
{
const char *value;
NMVPNConnection *vpn;
dbus_message_iter_get_basic (&array_iter, &value);
if ((vpn = nm_dbus_vpn_add_one_connection (data->dbus_connection, value, data->vpn_manager)))
nm_dbus_vpn_signal_vpn_connection_update (data->dbus_connection, vpn);
dbus_message_iter_next(&array_iter);
}
}
if (reply)
dbus_message_unref (reply);
return FALSE;
}
/*
* nm_dbus_vpn_schedule_vpn_connections_update
*
* Schedule an update of VPN connections in the main thread
*
*/
void nm_dbus_vpn_schedule_vpn_connections_update (NMData *app_data)
{
GSource *source = NULL;
g_return_if_fail (app_data != NULL);
g_return_if_fail (app_data->main_context != NULL);
source = g_idle_source_new ();
/* We want this idle source to run before any other idle source */
g_source_set_priority (source, G_PRIORITY_HIGH_IDLE);
g_source_set_callback (source, (GSourceFunc) nm_dbus_vpn_connections_update, app_data, NULL);
g_source_attach (source, app_data->main_context);
g_source_unref (source);
}
/*
* nm_dbus_vpn_get_vpn_connections
*
* Returns a string array of VPN connection names.
*
*/
static DBusMessage *nm_dbus_vpn_get_vpn_connections (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
DBusMessage *reply = NULL;
DBusMessageIter iter;
DBusMessageIter iter_array;
char **vpn_names = NULL;
int num_names;
int i;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
if (!data->data->vpn_manager)
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE_VPN, "NoVPNConnections", "There are no available VPN connections.");
goto out;
}
vpn_names = nm_vpn_manager_get_connection_names (data->data->vpn_manager);
num_names = vpn_names ? g_strv_length (vpn_names) : 0;
if (num_names == 0)
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE_VPN, "NoVPNConnections", "There are no available VPN connections.");
goto out;
}
if (!(reply = dbus_message_new_method_return (message)))
goto out;
dbus_message_iter_init_append (reply, &iter);
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_array);
for (i = 0; i < num_names; i++)
{
dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &vpn_names[i]);
}
dbus_message_iter_close_container (&iter, &iter_array);
out:
if (vpn_names)
g_strfreev (vpn_names);
return (reply);
}
/*
* nm_dbus_vpn_get_vpn_connection_properties
*
* Grab properties of a VPN connection
*
*/
static DBusMessage *nm_dbus_vpn_get_vpn_connection_properties (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
DBusMessage *reply = NULL;
DBusError error;
const char *name;
const char *user_name;
gboolean good = FALSE;
NMVPNConnection *vpn_con;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
/* Check for no VPN Manager */
if (!data->data->vpn_manager)
return nm_dbus_create_error_message (message, NM_DBUS_INTERFACE_VPN, "NoVPNConnections", "There are no available VPN connections.");
if (!(reply = dbus_message_new_method_return (message)))
return NULL;
dbus_error_init (&error);
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
{
if ((vpn_con = nm_vpn_manager_find_connection_by_name (data->data->vpn_manager, name)))
{
const char *user_name = nm_vpn_connection_get_user_name (vpn_con);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &user_name, DBUS_TYPE_INVALID);
good = TRUE;
}
}
if (!good)
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE_VPN, "InvalidVPNConnections", "No VPN connection with that name was found.");
return reply;
}
/*
* nm_dbus_vpn_get_active_vpn_connection
*
* Return the name of the currently active VPN connection.
*
*/
static DBusMessage *nm_dbus_vpn_get_active_vpn_connection (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
DBusMessage *reply = NULL;
const char *name;
NMVPNConnection *vpn = NULL;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
/* Check for no VPN Manager */
if (!data->data->vpn_manager)
return nm_dbus_create_error_message (message, NM_DBUS_INTERFACE_VPN, "NoVPNConnections", "There are no available VPN connections.");
if (!(vpn = nm_vpn_manager_get_active_vpn_connection (data->data->vpn_manager)))
return nm_dbus_create_error_message (message, NM_DBUS_INTERFACE_VPN, "NoActiveVPNConnection", "There is no active VPN connection.");
if (!(reply = dbus_message_new_method_return (message)))
return NULL;
name = nm_vpn_connection_get_name (vpn);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
return reply;
}
/*
* nm_dbus_vpn_activate_connection
*
* Activate a specific VPN connection.
*
*/
static DBusMessage *nm_dbus_vpn_activate_connection (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
DBusMessage *reply = NULL;
DBusError error;
const char *name;
const char *password;
NMVPNConnection *vpn;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
dbus_error_init (&error);
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &password, DBUS_TYPE_INVALID))
{
if ((vpn = nm_vpn_manager_find_connection_by_name (data->data->vpn_manager, name)))
{
int item_count = -1;
char **items;
if ((items = nm_dbus_vpn_get_vpn_data (connection, vpn, &item_count)))
{
char *joined_string = g_strjoinv (" / ", items);
NMVPNService *service = nm_vpn_connection_get_service (vpn);;
nm_info ("Will activate VPN connection '%s', service '%s', user_name '%s', vpn_data '%s'.",
name, nm_vpn_service_get_name (service), nm_vpn_connection_get_user_name (vpn), joined_string);
nm_vpn_manager_activate_vpn_connection (data->data->vpn_manager, vpn, password, items, item_count);
g_free (joined_string);
g_strfreev (items);
}
}
}
return NULL;
}
/*
* nm_dbus_vpn_deactivate_connection
*
* Deactivate the active VPN connection, if any.
*
*/
static DBusMessage *nm_dbus_vpn_deactivate_connection (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
NMVPNConnection *vpn_con;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
nm_info ("Will deactivate the current VPN connection.");
nm_vpn_manager_deactivate_vpn_connection (data->data->vpn_manager);
return NULL;
}
/*
* nm_dbus_vpn_methods_setup
*
* Register handlers for dbus methods on the
* org.freedesktop.NetworkManager.VPNConnections object.
*
*/
NMDbusMethodList *nm_dbus_vpn_methods_setup (void)
{
NMDbusMethodList *list = nm_dbus_method_list_new (NULL);
nm_dbus_method_list_add_method (list, "getVPNConnections", nm_dbus_vpn_get_vpn_connections);
nm_dbus_method_list_add_method (list, "getVPNConnectionProperties", nm_dbus_vpn_get_vpn_connection_properties);
nm_dbus_method_list_add_method (list, "getActiveVPNConnection", nm_dbus_vpn_get_active_vpn_connection);
nm_dbus_method_list_add_method (list, "activateVPNConnection", nm_dbus_vpn_activate_connection);
nm_dbus_method_list_add_method (list, "deactivateVPNConnection", nm_dbus_vpn_deactivate_connection);
return (list);
}

View File

@@ -0,0 +1,40 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2005 Red Hat, Inc.
*/
#ifndef NM_DBUS_VPN_H
#define NM_DBUS_VPN_H
#include "NetworkManagerDbusUtils.h"
#include "nm-vpn-manager.h"
#include "nm-vpn-connection.h"
NMVPNConnection * nm_dbus_vpn_add_one_connection (DBusConnection *con, const char *name, NMVPNManager *vpn_manager);
void nm_dbus_vpn_schedule_vpn_connections_update (NMData *app_data);
void nm_dbus_vpn_signal_vpn_connection_update (DBusConnection *con, NMVPNConnection *vpn);
void nm_dbus_vpn_signal_vpn_connection_change (DBusConnection *con, NMVPNConnection *vpn);
void nm_dbus_vpn_signal_vpn_login_failed (DBusConnection *con, NMVPNConnection *vpn, const char *error_msg);
void nm_dbus_vpn_signal_vpn_login_banner (DBusConnection *con, NMVPNConnection *vpn, const char *banner);
NMDbusMethodList * nm_dbus_vpn_methods_setup (void);
#endif

View File

@@ -0,0 +1,101 @@
/* nm-vpn-connection.c - handle a single VPN connections within NetworkManager's framework
*
* Copyright (C) 2005 Dan Williams
*
* 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, or (at your option)
* any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "config.h"
#include <glib.h>
#include <string.h>
#include "nm-vpn-connection.h"
struct NMVPNConnection
{
int refcount;
char *name;
char *user_name;
NMVPNService *service;
};
NMVPNConnection *nm_vpn_connection_new (const char *name, const char *user_name, NMVPNService *service)
{
NMVPNConnection *connection;
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (user_name != NULL, NULL);
g_return_val_if_fail (service != NULL, NULL);
connection = g_malloc0 (sizeof (NMVPNConnection));
connection->refcount = 1;
connection->name = g_strdup (name);
connection->user_name = g_strdup (user_name);
nm_vpn_service_ref (service);
connection->service = service;
return connection;
}
void nm_vpn_connection_ref (NMVPNConnection *connection)
{
g_return_if_fail (connection != NULL);
connection->refcount++;
}
void nm_vpn_connection_unref (NMVPNConnection *connection)
{
g_return_if_fail (connection != NULL);
connection->refcount--;
if (connection->refcount <= 0)
{
g_free (connection->name);
g_free (connection->user_name);
nm_vpn_service_unref (connection->service);
memset (connection, 0, sizeof (NMVPNConnection));
g_free (connection);
}
}
const char *nm_vpn_connection_get_name (NMVPNConnection *connection)
{
g_return_val_if_fail (connection != NULL, NULL);
return connection->name;
}
const char *nm_vpn_connection_get_user_name (NMVPNConnection *connection)
{
g_return_val_if_fail (connection != NULL, NULL);
return connection->user_name;
}
NMVPNService *nm_vpn_connection_get_service (NMVPNConnection *connection)
{
g_return_val_if_fail (connection != NULL, NULL);
return connection->service;
}

View File

@@ -0,0 +1,36 @@
/* nm-vpn-connection.h - handle a single VPN connection within NetworkManager's framework
*
* Copyright (C) 2005 Dan Williams
*
* 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, or (at your option)
* any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef NM_VPN_CONNECTION_H
#define NM_VPN_CONNECTION_H
#include "nm-vpn-service.h"
typedef struct NMVPNConnection NMVPNConnection;
NMVPNConnection *nm_vpn_connection_new (const char *name, const char *user_name, NMVPNService *service);
void nm_vpn_connection_ref (NMVPNConnection *connection);
void nm_vpn_connection_unref (NMVPNConnection *connection);
const char * nm_vpn_connection_get_name (NMVPNConnection *connection);
const char * nm_vpn_connection_get_user_name (NMVPNConnection *connection);
NMVPNService * nm_vpn_connection_get_service (NMVPNConnection *connection);
#endif /* NM_VPN_MANAGER_H */

View File

@@ -0,0 +1,837 @@
/* nm-vpn-manager.c - handle VPN connections within NetworkManager's framework
*
* Copyright (C) 2005 Dan Williams
*
* 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, or (at your option)
* any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <glib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dbus/dbus.h>
#include "nm-vpn-manager.h"
#include "NetworkManager.h"
#include "NetworkManagerMain.h"
#include "NetworkManagerDbus.h"
#include "NetworkManagerSystem.h"
#include "nm-vpn-connection.h"
#include "nm-vpn-service.h"
#include "nm-dbus-vpn.h"
#include "nm-utils.h"
#define VPN_SERVICE_FILE_PATH SYSCONFDIR"/NetworkManager/VPN"
struct NMVPNManager
{
NMData * app_data;
GSList * services;
GSList * connections;
NMVPNConnection * active;
char * active_device;
NMIP4Config * active_config;
};
static GSList * nm_vpn_manager_load_services (void);
static void nm_vpn_manager_set_active_vpn_connection (NMVPNManager *manager, NMVPNConnection *con);
/*
* nm_vpn_manager_new
*
* Create a new VPN manager instance.
*
*/
NMVPNManager *nm_vpn_manager_new (NMData *app_data)
{
NMVPNManager *manager;
g_return_val_if_fail (app_data != NULL, NULL);
manager = g_malloc0 (sizeof (NMVPNManager));
manager->services = nm_vpn_manager_load_services ();
manager->app_data = app_data;
return manager;
}
/*
* nm_vpn_manager_dispose
*
* Release the VPN manager and all its data.
*
*/
void nm_vpn_manager_dispose (NMVPNManager *manager)
{
g_return_if_fail (manager != NULL);
nm_vpn_manager_set_active_vpn_connection (manager, NULL);
if (manager->active_device)
g_free (manager->active_device);
if (manager->active_config)
{
nm_system_remove_ip4_config_nameservers (manager->app_data->named, manager->active_config);
nm_system_remove_ip4_config_search_domains (manager->app_data->named, manager->active_config);
nm_ip4_config_unref (manager->active_config);
}
g_slist_foreach (manager->connections, (GFunc) nm_vpn_connection_unref, NULL);
g_slist_free (manager->connections);
g_slist_foreach (manager->services, (GFunc) nm_vpn_service_unref, NULL);
g_slist_free (manager->services);
memset (manager, 0, sizeof (NMVPNManager));
g_free (manager);
}
/*
* nm_vpn_manager_clear_connections
*
* Dispose of all the VPN connections the manager knows about.
*
*/
void nm_vpn_manager_clear_connections (NMVPNManager *manager)
{
g_return_if_fail (manager != NULL);
g_slist_foreach (manager->connections, (GFunc)nm_vpn_connection_unref, NULL);
}
/*
* find_vpn_service
*
* Return the VPN Service for a given vpn service name.
*
*/
static NMVPNService *find_service_by_name (NMVPNManager *manager, const char *service_name)
{
NMVPNService *service = NULL;
GSList *elt;
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (service_name != NULL, NULL);
for (elt = manager->services; elt; elt = g_slist_next (elt))
{
if ((service = (NMVPNService *)(elt->data)))
{
const char *search_name = nm_vpn_service_get_name (service);
if (search_name && (strcmp (service_name, search_name) == 0))
break;
}
service = NULL;
}
return service;
}
/*
* nm_vpn_manager_find_connection_by_name
*
* Return the NMVPNConnection object associated with a particular name.
*
*/
NMVPNConnection *nm_vpn_manager_find_connection_by_name (NMVPNManager *manager, const char *con_name)
{
NMVPNConnection *con = NULL;
GSList *elt;
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (con_name != NULL, NULL);
for (elt = manager->connections; elt; elt = g_slist_next (elt))
{
if ((con = (NMVPNConnection *)(elt->data)))
{
const char *search_name = nm_vpn_connection_get_name (con);
if (search_name && (strcmp (con_name, search_name) == 0))
break;
}
con = NULL;
}
return con;
}
/*
* nm_vpn_manager_set_active_vpn_connection
*
* Sets the active connection and adds a dbus signal filter for that
* connection's service name.
*
*/
static void nm_vpn_manager_set_active_vpn_connection (NMVPNManager *manager, NMVPNConnection *con)
{
char *match_string = NULL;
const char *service_name = NULL;
NMVPNConnection *active;
NMVPNService *service;
g_return_if_fail (manager != NULL);
if ((active = nm_vpn_manager_get_active_vpn_connection (manager)))
{
service = nm_vpn_connection_get_service (active);
if (service && (service_name = nm_vpn_service_get_name (service)))
{
/* Remove any previous watch on this VPN connection's service name */
match_string = g_strdup_printf ("type='signal',"
"interface='%s',"
"sender='%s'", service_name, service_name);
dbus_bus_remove_match (manager->app_data->dbus_connection, match_string, NULL);
g_free (match_string);
}
nm_vpn_connection_unref (active);
}
manager->active = NULL;
if (manager->active_config)
{
nm_system_remove_ip4_config_nameservers (manager->app_data->named, manager->active_config);
nm_system_remove_ip4_config_search_domains (manager->app_data->named, manager->active_config);
nm_ip4_config_unref (manager->active_config);
manager->active_config = NULL;
}
if (manager->active_device)
{
nm_info ("Clearing active VPN device '%s'.", manager->active_device);
nm_system_device_set_up_down_with_iface (NULL, manager->active_device, FALSE);
nm_system_device_flush_routes_with_iface (manager->active_device);
nm_system_device_flush_addresses_with_iface (manager->active_device);
g_free (manager->active_device);
manager->active_device = NULL;
}
nm_dbus_vpn_signal_vpn_connection_change (manager->app_data->dbus_connection, con);
/* If passed NULL (clear active connection) there's nothing more to do */
if (!con)
return;
service = nm_vpn_connection_get_service (con);
if (!service || !(service_name = nm_vpn_service_get_name (service)))
{
nm_warning ("VPN connection could not be set active because it didn't have a VPN service.");
return;
}
nm_vpn_connection_ref (con);
manager->active = con;
/* Add a dbus filter for this connection's service name so its signals
* get delivered to us.
*/
match_string = g_strdup_printf ("type='signal',"
"interface='%s',"
"sender='%s'", service_name, service_name);
dbus_bus_add_match (manager->app_data->dbus_connection, match_string, NULL);
g_free (match_string);
}
/*
* nm_vpn_manager_add_connection
*
* Add a new VPN connection if none already exits, otherwise update the existing one.
*
*/
NMVPNConnection *nm_vpn_manager_add_connection (NMVPNManager *manager, const char *name, const char *service_name, const char *user_name)
{
NMVPNConnection *connection = NULL;
NMVPNService *service;
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (service_name != NULL, NULL);
g_return_val_if_fail (user_name != NULL, NULL);
/* Verify that the service name we are adding is in our allowed list */
service = find_service_by_name (manager, service_name);
if (service && (connection = nm_vpn_connection_new (name, user_name, service)))
{
gboolean found = FALSE;
GSList *elt;
/* Remove the existing connection if found */
for (elt = manager->connections; elt; elt = g_slist_next (elt))
{
NMVPNConnection *con = (NMVPNConnection *)(elt->data);
if (con && nm_vpn_connection_get_name (con) && (strcmp (nm_vpn_connection_get_name (con), name) == 0))
{
manager->connections = g_slist_remove_link (manager->connections, elt);
nm_vpn_connection_unref (con);
g_slist_free (elt);
}
}
/* Add in the updated connection */
manager->connections = g_slist_append (manager->connections, connection);
}
return connection;
}
/*
* Prints config returned from vpnc-helper
*/
static void print_vpn_config (guint32 ip4_vpn_gateway,
const char *tundev,
guint32 ip4_internal_address,
gint32 ip4_internal_netmask,
guint32 *ip4_internal_dns,
guint32 ip4_internal_dns_len,
guint32 *ip4_internal_nbns,
guint32 ip4_internal_nbns_len,
const char *dns_domain,
const char *login_banner)
{
struct in_addr temp_addr;
guint32 i;
temp_addr.s_addr = ip4_vpn_gateway;
nm_info ("VPN Gateway: %s", inet_ntoa (temp_addr));
nm_info ("Tunnel Device: %s", tundev);
temp_addr.s_addr = ip4_internal_address;
nm_info ("Internal IP4 Address: %s", inet_ntoa (temp_addr));
temp_addr.s_addr = ip4_internal_netmask;
nm_info ("Internal IP4 Netmask: %s", inet_ntoa (temp_addr));
for (i = 0; i < ip4_internal_dns_len; i++)
{
if (ip4_internal_dns[i] != 0)
{
temp_addr.s_addr = ip4_internal_dns[i];
nm_info ("Internal IP4 DNS: %s", inet_ntoa (temp_addr));
}
}
for (i = 0; i < ip4_internal_nbns_len; i++)
{
if (ip4_internal_nbns[i] != 0)
{
temp_addr.s_addr = ip4_internal_nbns[i];
nm_info ("Internal IP4 NBNS: %s", inet_ntoa (temp_addr));
}
}
nm_info ("DNS Domain: '%s'", dns_domain);
nm_info ("Login Banner:");
nm_info ("-----------------------------------------");
nm_info ("%s", login_banner);
nm_info ("-----------------------------------------");
}
/*
* nm_vpn_manager_handle_ip4_config_signal
*
* Configure a device with IPv4 config info in response the the VPN daemon.
*
*/
void nm_vpn_manager_handle_ip4_config_signal (NMVPNManager *manager, DBusMessage *message, NMVPNService *service, NMVPNConnection *con)
{
guint32 ip4_vpn_gateway;
char * tundev;
guint32 ip4_internal_address;
guint32 ip4_internal_netmask;
guint32 * ip4_internal_dns;
guint32 ip4_internal_dns_len;
guint32 * ip4_internal_nbns;
guint32 ip4_internal_nbns_len;
char * dns_domain;
char * login_banner;
g_return_if_fail (manager != NULL);
g_return_if_fail (message != NULL);
g_return_if_fail (service != NULL);
g_return_if_fail (con != NULL);
if (dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &ip4_vpn_gateway,
DBUS_TYPE_STRING, &tundev,
DBUS_TYPE_UINT32, &ip4_internal_address,
DBUS_TYPE_UINT32, &ip4_internal_netmask,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &ip4_internal_dns, &ip4_internal_dns_len,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &ip4_internal_nbns, &ip4_internal_nbns_len,
DBUS_TYPE_STRING, &dns_domain,
DBUS_TYPE_STRING, &login_banner, DBUS_TYPE_INVALID))
{
NMIP4Config * config;
NMDevice * vpn_dev;
guint32 i;
guint32 broadcast;
#if 0
print_vpn_config (ip4_vpn_gateway, tundev, ip4_internal_address, ip4_internal_netmask,
ip4_internal_dns, ip4_internal_dns_len, ip4_internal_nbns, ip4_internal_nbns_len,
dns_domain, login_banner);
#endif
config = nm_ip4_config_new ();
nm_ip4_config_set_address (config, ip4_internal_address);
if (ip4_internal_netmask)
nm_ip4_config_set_netmask (config, ip4_internal_netmask);
else
nm_ip4_config_set_netmask (config, 0x00FF); /* Class C */
nm_ip4_config_set_gateway (config, ip4_vpn_gateway);
if (strlen (dns_domain))
nm_ip4_config_add_domain (config, dns_domain);
for (i = 0; i < ip4_internal_dns_len; i++)
{
if (ip4_internal_dns[i] != 0)
nm_ip4_config_add_nameserver (config, ip4_internal_dns[i]);
}
manager->active_device = g_strdup (tundev);
manager->active_config = config;
nm_system_vpn_device_set_from_ip4_config (manager->app_data->named, manager->app_data->active_device,
manager->active_device, manager->active_config);
if (login_banner && strlen (login_banner))
nm_dbus_vpn_signal_vpn_login_banner (manager->app_data->dbus_connection, con, login_banner);
}
}
/*
* nm_vpn_manager_get_connection_names
*
* Return an array of strings of all the VPN Connection names
* we know about.
*
*/
char **nm_vpn_manager_get_connection_names (NMVPNManager *manager)
{
char **names = NULL;
GSList *elt;
int i;
g_return_val_if_fail (manager != NULL, NULL);
names = g_malloc0 ((g_slist_length (manager->connections) + 1) * sizeof (char *));
for (elt = manager->connections, i = 0; elt; elt = g_slist_next (elt), i++)
{
NMVPNConnection *vpn_con = (NMVPNConnection *)(elt->data);
if (vpn_con)
names[i] = g_strdup (nm_vpn_connection_get_name (vpn_con));
}
return names;
}
/*
* nm_vpn_manager_get_active_vpn_connection
*
* Return the active VPN connection, if any.
*
*/
NMVPNConnection *nm_vpn_manager_get_active_vpn_connection (NMVPNManager *manager)
{
g_return_val_if_fail (manager != NULL, NULL);
return manager->active;
}
/*
* construct_op_from_service_name
*
* Construct an object path from a dbus service name by replacing
* all "." in the service with "/" and prepending a "/" to the
* object path.
*
*/
static char *construct_op_from_service_name (const char *service_name)
{
char **split = NULL;
char *temp1;
char *temp2;
g_return_val_if_fail (service_name != NULL, NULL);
if (!(split = g_strsplit (service_name, ".", 0)))
return NULL;
temp1 = g_strjoinv ("/", split);
g_strfreev (split);
temp2 = g_strdup_printf ("/%s", temp1);
g_free (temp1);
if (!temp2 || !strlen (temp2))
{
g_free (temp2);
temp2 = NULL;
}
return temp2;
}
/*
* nm_vpn_manager_process_signal
*
* Possibly process a signal from the bus, if it comes from the currently
* active VPN daemon, if any. Return TRUE if processed, FALSE if not.
*
*/
gboolean nm_vpn_manager_process_signal (NMVPNManager *manager, DBusMessage *message)
{
const char *object_path;
const char *temp_op;
NMVPNConnection *active;
NMVPNService *service;
const char *service_name;
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (message != NULL, FALSE);
if (!(object_path = dbus_message_get_path (message)))
return FALSE;
if (!(active = nm_vpn_manager_get_active_vpn_connection (manager)))
return FALSE;
service = nm_vpn_connection_get_service (active);
if (!service || !(service_name = nm_vpn_service_get_name (service)))
return FALSE;
temp_op = construct_op_from_service_name (service_name);
if (!temp_op || (strcmp (object_path, temp_op) != 0))
return FALSE;
if (dbus_message_is_signal (message, service_name, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED))
{
char *error_msg;
char *blank_msg = "";
if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &error_msg, DBUS_TYPE_INVALID))
error_msg = blank_msg;
nm_warning ("VPN Login failed for service '%s' with message '%s'.", service_name, error_msg);
nm_dbus_vpn_signal_vpn_login_failed (manager->app_data->dbus_connection, active, error_msg);
}
else if (dbus_message_is_signal (message, service_name, NM_DBUS_VPN_SIGNAL_STATE_CHANGE))
{
NMVPNState old_state;
NMVPNState new_state;
if (dbus_message_get_args (message, NULL, DBUS_TYPE_UINT32, &old_state, DBUS_TYPE_UINT32, &new_state, DBUS_TYPE_INVALID))
{
nm_info ("VPN service '%s' signaled new state %d, old state %d.", service_name, new_state, old_state);
nm_vpn_service_set_state (service, new_state);
/* If the VPN daemon state is now stopped and it was starting, clear the active connection */
if (((new_state == NM_VPN_STATE_STOPPED) || (new_state == NM_VPN_STATE_SHUTDOWN) || (new_state == NM_VPN_STATE_STOPPING))
&& ((old_state == NM_VPN_STATE_STARTED) || (old_state == NM_VPN_STATE_STARTING)))
{
nm_vpn_manager_set_active_vpn_connection (manager, NULL);
}
}
}
else if (dbus_message_is_signal (message, service_name, NM_DBUS_VPN_SIGNAL_IP4_CONFIG))
nm_vpn_manager_handle_ip4_config_signal (manager, message, service, active);
return TRUE;
}
/*
* nm_vpn_manager_process_name_owner_changed
*
* Respond to "service created"/"service deleted" signals from dbus for our active VPN daemon.
*
*/
gboolean nm_vpn_manager_process_name_owner_changed (NMVPNManager *manager, const char *changed_service_name, const char *old_owner, const char *new_owner)
{
NMVPNService *service;
NMVPNConnection *active;
gboolean old_owner_good = (old_owner && strlen (old_owner));
gboolean new_owner_good = (new_owner && strlen (new_owner));
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (changed_service_name != NULL, FALSE);
if (!(active = nm_vpn_manager_get_active_vpn_connection (manager)))
return FALSE;
nm_vpn_connection_ref (active);
if (!(service = nm_vpn_connection_get_service (active)))
{
nm_vpn_connection_unref (active);
return FALSE;
}
/* Can't handle the signal if its not from our active VPN service */
if (strcmp (nm_vpn_service_get_name (service), changed_service_name) != 0)
{
nm_vpn_connection_unref (active);
return FALSE;
}
if (!old_owner_good && new_owner_good)
{
/* VPN service got created. */
}
else if (old_owner_good && !new_owner_good)
{
/* VPN service went away. */
nm_vpn_service_set_state (service, NM_VPN_STATE_SHUTDOWN);
nm_vpn_manager_set_active_vpn_connection (manager, NULL);
nm_dbus_vpn_signal_vpn_connection_change (manager->app_data->dbus_connection, active);
}
nm_vpn_connection_unref (active);
return TRUE;
}
/*
* nm_vpn_manager_activate_vpn_connection
*
* Signal the VPN service daemon to activate a particular VPN connection,
* launching that daemon if necessary.
*
*/
void nm_vpn_manager_activate_vpn_connection (NMVPNManager *manager, NMVPNConnection *vpn, const char *password, char **data_items, int count)
{
DBusMessage *message;
DBusMessage *reply;
char *op;
NMVPNService *service;
const char *service_name;
const char *name;
const char *user_name;
DBusMessageIter iter, array_iter;
int i, len;
DBusError error;
g_return_if_fail (manager != NULL);
g_return_if_fail (manager->app_data != NULL);
g_return_if_fail (manager->app_data->dbus_connection != NULL);
g_return_if_fail (vpn != NULL);
g_return_if_fail (password != NULL);
g_return_if_fail (data_items != NULL);
nm_vpn_manager_set_active_vpn_connection (manager, NULL);
/* Construct a new method call with the correct service and object path */
if (!(service = nm_vpn_connection_get_service (vpn)) || !(service_name = nm_vpn_service_get_name (service)))
return;
nm_vpn_manager_set_active_vpn_connection (manager, vpn);
/* Start the daemon if its not already running */
if (!dbus_bus_name_has_owner (manager->app_data->dbus_connection, service_name, NULL))
{
if (!nm_vpn_service_exec_daemon (service))
{
nm_vpn_manager_set_active_vpn_connection (manager, NULL);
return;
}
}
/* Send the activate request to the daemon */
op = construct_op_from_service_name (service_name);
message = dbus_message_new_method_call (service_name, op, service_name, "startConnection");
g_free (op);
if (!message)
{
nm_warning ("Couldn't allocate dbus message.");
nm_vpn_manager_set_active_vpn_connection (manager, NULL);
return;
}
name = nm_vpn_connection_get_name (vpn);
user_name = nm_vpn_connection_get_user_name (vpn);
dbus_message_append_args (message, DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &user_name,
DBUS_TYPE_STRING, &password,
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &data_items, count,
DBUS_TYPE_INVALID);
/* Send the message to the daemon again, now that its running. */
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (manager->app_data->dbus_connection, message, -1, &error);
dbus_message_unref (message);
if (dbus_error_is_set (&error))
{
nm_warning ("Could not activate the VPN service. dbus says: '%s' '%s'.", error.name, error.message);
dbus_error_free (&error);
nm_vpn_manager_set_active_vpn_connection (manager, NULL);
return;
}
if (reply)
dbus_message_unref (reply);
}
/*
* nm_vpn_manager_deactivate_vpn_connection
*
* Signal the VPN service daemon to deactivate a particular VPN connection.
*
*/
void nm_vpn_manager_deactivate_vpn_connection (NMVPNManager *manager)
{
DBusMessage *message;
char *op;
NMVPNService *service;
const char *service_name;
NMVPNConnection *active;
NMIP4Config *config;
g_return_if_fail (manager != NULL);
if (!(active = nm_vpn_manager_get_active_vpn_connection (manager)))
return;
nm_vpn_connection_ref (active);
/* Construct a new method call with the correct service and object path */
service = nm_vpn_connection_get_service (active);
service_name = nm_vpn_service_get_name (service);
op = construct_op_from_service_name (service_name);
message = dbus_message_new_method_call (service_name, op, service_name, "stopConnection");
g_free (op);
if (!message)
{
nm_warning ("Couldn't allocate dbus message.");
goto out;
}
/* Call the specific VPN service, let dbus activate it if needed */
dbus_connection_send (manager->app_data->dbus_connection, message, NULL);
dbus_message_unref (message);
out:
nm_vpn_manager_set_active_vpn_connection (manager, NULL);
nm_dbus_vpn_signal_vpn_connection_change (manager->app_data->dbus_connection, NULL);
nm_vpn_connection_unref (active);
if (manager->app_data->active_device)
nm_system_device_set_from_ip4_config (manager->app_data->active_device);
}
/*********************************************************************/
static GSList *nm_vpn_manager_load_services (void)
{
GSList *list = NULL;
GDir *vpn_dir;
/* Load allowed service names */
if ((vpn_dir = g_dir_open (VPN_SERVICE_FILE_PATH, 0, NULL)))
{
const char *file_name;
while ((file_name = g_dir_read_name (vpn_dir)))
{
char *file_path = g_strdup_printf (VPN_SERVICE_FILE_PATH"/%s", file_name);
char *contents;
if (g_file_get_contents (file_path, &contents, NULL, NULL) && (contents != NULL))
{
char **split_contents = g_strsplit (contents, "\n", 0);
if (split_contents)
{
int i, len;
NMVPNService *service = nm_vpn_service_new ();
gboolean have_name = FALSE;
gboolean have_program = FALSE;
len = g_strv_length (split_contents);
for (i = 0; i < len; i++)
{
char *line = split_contents[i];
#define SERVICE_TAG "service="
#define PROGRAM_TAG "program="
if (!line || !strlen (line)) continue;
/* Comment lines begin with # */
if (line[0] == '#') continue;
if (strlen (line) > 8)
{
if ((strncmp (line, SERVICE_TAG, strlen (SERVICE_TAG)) == 0) && !have_name)
{
char *service_name = g_strdup (line+strlen (SERVICE_TAG));
/* Deny the load if the service name is NetworkManager or NetworkManagerInfo. */
if (strcmp (service_name, NM_DBUS_SERVICE) && strcmp (service_name, NM_DBUS_SERVICE))
nm_vpn_service_set_name (service, (const char *)service_name);
else
nm_warning ("VPN service name matched NetworkManager or NetworkManagerInfo service names, "
"which is not allowed and might be malicious.");
g_free (service_name);
have_name = TRUE;
}
else if ((strncmp (line, PROGRAM_TAG, strlen (PROGRAM_TAG)) == 0) && !have_program)
{
gboolean program_ok = FALSE;
if ((strlen (line) >= strlen (PROGRAM_TAG) + 1))
{
if ((*(line+strlen (PROGRAM_TAG)) == '/') && (*(line+strlen (line)-1) != '/'))
{
nm_vpn_service_set_program (service, (const char *)(line+strlen (PROGRAM_TAG)));
program_ok = TRUE;
}
}
if (!program_ok)
nm_warning ("WARNING: VPN program '%s' invalid in file '%s'", line, file_path);
have_program = TRUE;
}
}
}
g_strfreev (split_contents);
if (nm_vpn_service_get_name (service) && nm_vpn_service_get_program (service))
{
nm_info ("Adding VPN service '%s' with program '%s'", nm_vpn_service_get_name (service),
nm_vpn_service_get_program (service));
list = g_slist_append (list, service);
}
else
nm_vpn_service_unref (service);
}
g_free (contents);
}
g_free (file_path);
}
g_dir_close (vpn_dir);
}
return list;
}

View File

@@ -0,0 +1,44 @@
/* nm-vpn-manager.h - handle VPN connections within NetworkManager's framework
*
* Copyright (C) 2005 Dan Williams
*
* 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, or (at your option)
* any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef NM_VPN_MANAGER_H
#define NM_VPN_MANAGER_H
#include <dbus/dbus.h>
#include "NetworkManagerMain.h"
#include "nm-vpn-connection.h"
NMVPNManager * nm_vpn_manager_new (NMData *app_data);
void nm_vpn_manager_clear_connections (NMVPNManager *manager);
NMVPNConnection * nm_vpn_manager_add_connection (NMVPNManager *manager, const char *name, const char *service_name, const char *user_name);
char ** nm_vpn_manager_get_connection_names (NMVPNManager *manager);
void nm_vpn_manager_dispose (NMVPNManager *manager);
NMVPNConnection * nm_vpn_manager_get_active_vpn_connection (NMVPNManager *manager);
void nm_vpn_manager_activate_vpn_connection (NMVPNManager *manager, NMVPNConnection *vpn, const char *password, char **data_items, int count);
void nm_vpn_manager_deactivate_vpn_connection (NMVPNManager *manager);
NMVPNConnection * nm_vpn_manager_find_connection_by_name (NMVPNManager *manager, const char *con_name);
gboolean nm_vpn_manager_process_signal (NMVPNManager *manager, DBusMessage *signal);
gboolean nm_vpn_manager_process_name_owner_changed (NMVPNManager *manager, const char *service, const char *old_owner, const char *new_owner);
#endif /* NM_VPN_MANAGER_H */

View File

@@ -0,0 +1,154 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2005 Red Hat, Inc.
*/
#include <glib.h>
#include <dbus/dbus.h>
#include "nm-dbus-vpn.h"
#include "nm-vpn-service.h"
#include "nm-utils.h"
struct NMVPNService
{
int refcount;
char *name;
char *program;
NMVPNState state;
};
NMVPNService *nm_vpn_service_new (void)
{
NMVPNService *service = g_malloc0 (sizeof (NMVPNService));
service->refcount = 1;
service->state = NM_VPN_STATE_SHUTDOWN;
return service;
}
void nm_vpn_service_ref (NMVPNService *service)
{
g_return_if_fail (service != NULL);
service->refcount++;
}
void nm_vpn_service_unref (NMVPNService *service)
{
g_return_if_fail (service != NULL);
service->refcount--;
if (service->refcount <= 0)
{
g_free (service->name);
g_free (service->program);
memset (service, 0, sizeof (NMVPNService));
g_free (service);
}
}
const char *nm_vpn_service_get_name (NMVPNService *service)
{
g_return_val_if_fail (service != NULL, NULL);
return service->name;
}
void nm_vpn_service_set_name (NMVPNService *service, const char *name)
{
g_return_if_fail (service != NULL);
if (service->name)
g_free (service->name);
service->name = g_strdup (name);
}
const char *nm_vpn_service_get_program (NMVPNService *service)
{
g_return_val_if_fail (service != NULL, NULL);
return service->program;
}
void nm_vpn_service_set_program (NMVPNService *service, const char *program)
{
g_return_if_fail (service != NULL);
if (service->program)
g_free (service->program);
service->program = g_strdup (program);
}
NMVPNState nm_vpn_service_get_state (NMVPNService *service)
{
g_return_val_if_fail (service != NULL, NM_VPN_STATE_ERROR);
return service->state;
}
void nm_vpn_service_set_state (NMVPNService *service, const NMVPNState state)
{
g_return_if_fail (service != NULL);
service->state = state;
}
gboolean nm_vpn_service_exec_daemon (NMVPNService *service)
{
GPtrArray *vpn_argv;
GError *error = NULL;
GPid pid;
g_return_val_if_fail (service != NULL, FALSE);
if (!nm_vpn_service_get_program (service))
return FALSE;
vpn_argv = g_ptr_array_new ();
g_ptr_array_add (vpn_argv, (char *) nm_vpn_service_get_program (service));
g_ptr_array_add (vpn_argv, NULL);
if (!g_spawn_async (NULL, (char **) vpn_argv->pdata, NULL, 0, NULL, NULL, &pid, &error))
{
g_ptr_array_free (vpn_argv, TRUE);
nm_warning ("Could not activate the VPN service '%s'. error: '%s'.", nm_vpn_service_get_name (service), error->message);
g_error_free (error);
return FALSE;
}
g_ptr_array_free (vpn_argv, TRUE);
nm_info ("Activated the VPN service '%s' with PID %d.", nm_vpn_service_get_name (service), pid);
/* Wait a bit for the daemon to start up */
/* FIXME: don't sleep, keep retrying dbus message or something */
sleep (1);
return TRUE;
}

View File

@@ -0,0 +1,48 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2005 Red Hat, Inc.
*/
#ifndef NM_VPN_SERVICE_H
#define NM_VPN_SERVICE_H
#include <dbus/dbus.h>
#include "NetworkManager.h"
typedef struct NMVPNService NMVPNService;
NMVPNService * nm_vpn_service_new (void);
void nm_vpn_service_ref (NMVPNService *service);
void nm_vpn_service_unref (NMVPNService *service);
const char * nm_vpn_service_get_name (NMVPNService *service);
void nm_vpn_service_set_name (NMVPNService *service, const char *name);
const char * nm_vpn_service_get_program (NMVPNService *service);
void nm_vpn_service_set_program (NMVPNService *service, const char *program);
NMVPNState nm_vpn_service_get_state (NMVPNService *service);
void nm_vpn_service_set_state (NMVPNService *service, const NMVPNState state);
gboolean nm_vpn_service_exec_daemon (NMVPNService *service);
#endif

2
vpn-daemons/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

2
vpn-daemons/Makefile.am Normal file
View File

@@ -0,0 +1,2 @@
SUBDIRS = vpnc

View File

@@ -0,0 +1,4 @@
Makefile
Makefile.in
nm-vpnc-service
nm-vpnc-service-vpnc-helper

View File

@@ -0,0 +1,45 @@
INCLUDES = -I${top_srcdir} -I${top_srcdir}/utils
AM_CPPFLAGS = \
$(DBUS_CFLAGS) \
$(GTHREAD_CFLAGS) \
-Wall \
-DDBUS_API_SUBJECT_TO_CHANGE \
-DG_DISABLE_DEPRECATED \
-DBINDIR=\"$(bindir)\" \
-DPREFIX=\""$(prefix)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DVERSION="\"$(VERSION)\"" \
-DLIBDIR=\""$(libdir)"\" \
-DLIBEXECDIR=\""$(libexecdir)"\" \
-DLOCALSTATEDIR=\""$(localstatedir)"\" \
-DDATADIR=\"$(datadir)\"
bin_PROGRAMS = nm-vpnc-service nm-vpnc-service-vpnc-helper
nm_vpnc_service_SOURCES = \
nm-vpnc-service.c
nm_vpnc_service_LDADD = \
$(DBUS_LIBS) \
$(GTHREAD_LIBS) \
$(top_builddir)/utils/libnmutils.la
nm_vpnc_service_vpnc_helper_SOURCES = \
nm-vpnc-service-vpnc-helper.c
nm_vpnc_service_vpnc_helper_LDADD = \
$(DBUS_LIBS) \
$(GTHREAD_LIBS) \
$(top_builddir)/utils/libnmutils.la
dbusservicedir = $(DBUS_SYS_DIR)
dbusservice_DATA = nm-vpnc-service.conf
nmvpnservicedir = $(sysconfdir)/NetworkManager/VPN
nmvpnservice_DATA = nm-vpnc-service.name
EXTRA_DIST = $(dbusservice_DATA) $(nmvpnservice_DATA)

View File

@@ -0,0 +1,319 @@
/* nm-vpnc-service - vpnc integration with NetworkManager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2005 Red Hat, Inc.
*/
#include <glib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include "NetworkManager.h"
#include "nm-vpnc-service.h"
#include "nm-utils.h"
/*
* send_config_error
*
* Notify nm-vpnc-service of a config error from 'vpnc'.
*
*/
static void send_config_error (DBusConnection *con, const char *item)
{
DBusMessage *message;
g_return_if_fail (con != NULL);
g_return_if_fail (item != NULL);
if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE_VPNC, NM_DBUS_PATH_VPNC, NM_DBUS_INTERFACE_VPNC, "signalConfigError")))
{
nm_warning ("send_config_error(): Couldn't allocate the dbus message");
return;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, &item, DBUS_TYPE_INVALID);
if (!dbus_connection_send (con, message, NULL))
nm_warning ("send_config_error(): could not send dbus message");
dbus_message_unref (message);
}
/*
* send_config_info
*
* Send IP config info to nm-vpnc-service
*
*/
static gboolean send_config_info (DBusConnection *con, const char *str_vpn_gateway,
const char *tundev,
const char *str_internal_ip4_address,
const char *str_internal_ip4_netmask,
const char *str_internal_ip4_dns,
const char *str_internal_ip4_nbns,
const char *cisco_def_domain,
const char *cisco_banner)
{
DBusMessage * message;
struct in_addr temp_addr;
guint32 uint_vpn_gateway = 0;
guint32 uint_internal_ip4_address = 0;
guint32 uint_internal_ip4_netmask = 0xFFFFFFFF; /* Default mask of 255.255.255.255 */
guint32 * uint_internal_ip4_dns = NULL;
guint32 uint_internal_ip4_dns_len = 0;
guint32 * uint_internal_ip4_nbns = NULL;
guint32 uint_internal_ip4_nbns_len = 0;
char ** split;
char ** item;
guint32 num_valid = 0, i;
gboolean success = FALSE;
g_return_val_if_fail (con != NULL, FALSE);
if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE_VPNC, NM_DBUS_PATH_VPNC, NM_DBUS_INTERFACE_VPNC, "signalIP4Config")))
{
nm_warning ("send_config_error(): Couldn't allocate the dbus message");
return FALSE;
}
/* Convert IPv4 address arguments from strings into numbers */
if (!inet_aton (str_vpn_gateway, &temp_addr))
{
nm_warning ("nm-vpnc-service-vpnc-helper didn't receive a valid VPN Gateway from vpnc.");
send_config_error (con, "VPN Gateway");
goto out;
}
uint_vpn_gateway = temp_addr.s_addr;
if (!inet_aton (str_internal_ip4_address, &temp_addr))
{
nm_warning ("nm-vpnc-service-vpnc-helper didn't receive a valid Internal IP4 Address from vpnc.");
send_config_error (con, "IP4 Address");
goto out;
}
uint_internal_ip4_address = temp_addr.s_addr;
if (strlen (str_internal_ip4_netmask) && inet_aton (str_internal_ip4_netmask, &temp_addr))
uint_internal_ip4_netmask = temp_addr.s_addr;
if (strlen (str_internal_ip4_dns))
{
if ((split = g_strsplit (str_internal_ip4_dns, " ", -1)))
{
/* Pass over the array first to determine how many valid entries there are */
num_valid = 0;
for (item = split; *item; item++)
if (inet_aton (*item, &temp_addr))
num_valid++;
/* Do the actual string->int conversion and assign to the array. */
if (num_valid > 0)
{
uint_internal_ip4_dns = g_new0 (guint32, num_valid);
for (item = split, i = 0; *item; item++, i++)
if (inet_aton (*item, &temp_addr))
uint_internal_ip4_dns[i] = temp_addr.s_addr;
}
g_strfreev (split);
uint_internal_ip4_dns_len = num_valid;
}
}
if (!uint_internal_ip4_dns)
{
uint_internal_ip4_dns = g_malloc0 (sizeof (guint32));
uint_internal_ip4_dns[0] = 0;
uint_internal_ip4_dns_len = 1;
}
if (strlen (str_internal_ip4_nbns))
{
if ((split = g_strsplit (str_internal_ip4_nbns, " ", -1)))
{
/* Pass over the array first to determine how many valid entries there are */
num_valid = 0;
for (item = split; *item; item++)
if (inet_aton (*item, &temp_addr))
num_valid++;
/* Do the actual string->int conversion and assign to the array. */
if (num_valid > 0)
{
uint_internal_ip4_nbns = g_new0 (guint32, num_valid);
for (item = split, i = 0; *item; item++, i++)
if (inet_aton (*item, &temp_addr))
uint_internal_ip4_nbns[i] = temp_addr.s_addr;
}
g_strfreev (split);
uint_internal_ip4_nbns_len = num_valid;
}
}
if (!uint_internal_ip4_nbns)
{
uint_internal_ip4_nbns = g_malloc0 (sizeof (guint32));
uint_internal_ip4_nbns[0] = 0;
uint_internal_ip4_nbns_len = 1;
}
dbus_message_append_args (message, DBUS_TYPE_UINT32, &uint_vpn_gateway,
DBUS_TYPE_STRING, &tundev,
DBUS_TYPE_UINT32, &uint_internal_ip4_address,
DBUS_TYPE_UINT32, &uint_internal_ip4_netmask,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &uint_internal_ip4_dns, uint_internal_ip4_dns_len,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &uint_internal_ip4_nbns, uint_internal_ip4_nbns_len,
DBUS_TYPE_STRING, &cisco_def_domain,
DBUS_TYPE_STRING, &cisco_banner, DBUS_TYPE_INVALID);
if (dbus_connection_send (con, message, NULL))
success = TRUE;
else
nm_warning ("send_config_error(): could not send dbus message");
dbus_message_unref (message);
out:
return success;
}
/*
* Environment variables passed back from 'vpnc':
*
* VPNGATEWAY -- vpn gateway address (always present)
* TUNDEV -- tunnel device (always present)
* INTERNAL_IP4_ADDRESS -- address (always present)
* INTERNAL_IP4_NETMASK -- netmask (often unset)
* INTERNAL_IP4_DNS -- list of dns serverss
* INTERNAL_IP4_NBNS -- list of wins servers
* CISCO_DEF_DOMAIN -- default domain name
* CISCO_BANNER -- banner from server
*
*/
/*
* main
*
*/
int main( int argc, char *argv[] )
{
DBusConnection * con;
DBusError error;
char * vpn_gateway = NULL;
char * tundev = NULL;
char * internal_ip4_address = NULL;
char * internal_ip4_netmask = NULL;
char * internal_ip4_dns = NULL;
char * internal_ip4_nbns = NULL;
char * cisco_def_domain = NULL;
char * cisco_banner = NULL;
g_type_init ();
if (!g_thread_supported ())
g_thread_init (NULL);
dbus_error_init (&error);
con = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
if ((con == NULL) || dbus_error_is_set (&error))
{
nm_warning ("Could not get the system bus. Make sure the message bus daemon is running?");
exit (1);
}
dbus_connection_set_exit_on_disconnect (con, FALSE);
vpn_gateway = getenv ("VPNGATEWAY");
tundev = getenv ("TUNDEV");
internal_ip4_address = getenv ("INTERNAL_IP4_ADDRESS");
internal_ip4_netmask = getenv ("INTERNAL_IP4_NETMASK");
internal_ip4_dns = getenv ("INTERNAL_IP4_DNS");
internal_ip4_nbns = getenv ("INTERNAL_IP4_NBNS");
cisco_def_domain = getenv ("CISCO_DEF_DOMAIN");
cisco_banner = getenv ("CISCO_BANNER");
#if 0
file = fopen ("/tmp/vpnstuff", "w");
fprintf (file, "VPNGATEWAY: '%s'\n", vpn_gateway);
fprintf (file, "TUNDEF: '%s'\n", tundev);
fprintf (file, "INTERNAL_IP4_ADDRESS: '%s'\n", internal_ip4_address);
fprintf (file, "INTERNAL_IP4_NETMASK: '%s'\n", internal_ip4_netmask);
fprintf (file, "INTERNAL_IP4_DNS: '%s'\n", internal_ip4_dns);
fprintf (file, "INTERNAL_IP4_NBNS: '%s'\n", internal_ip4_nbns);
fprintf (file, "CISCO_DEF_DOMAIN: '%s'\n", cisco_def_domain);
fprintf (file, "CISCO_BANNER: '%s'\n", cisco_banner);
fclose (file);
#endif
if (!vpn_gateway)
{
nm_warning ("nm-vpnc-service-vpnc-helper didn't receive a VPN Gateway from vpnc.");
send_config_error (con, "VPN Gateway");
exit (1);
}
if (!tundev || !g_utf8_validate (tundev, -1, NULL))
{
nm_warning ("nm-vpnc-service-vpnc-helper didn't receive a Tunnel Device from vpnc, or the tunnel device was not valid UTF-8.");
send_config_error (con, "Tunnel Device");
exit (1);
}
if (!internal_ip4_address)
{
nm_warning ("nm-vpnc-service-vpnc-helper didn't receive an Internal IP4 Address from vpnc.");
send_config_error (con, "IP4 Address");
exit (1);
}
if (!internal_ip4_netmask)
internal_ip4_netmask = g_strdup ("");
if (!internal_ip4_dns)
internal_ip4_dns = g_strdup ("");
if (!internal_ip4_nbns)
internal_ip4_nbns = g_strdup ("");
/* Ensure strings from network are UTF-8 */
if (cisco_def_domain && !g_utf8_validate (cisco_def_domain, -1, NULL))
{
if (!(cisco_def_domain = g_convert (cisco_def_domain, -1, "ISO-8859-1", "UTF-8", NULL, NULL, NULL)))
cisco_def_domain = g_convert (cisco_def_domain, -1, "C", "UTF-8", NULL, NULL, NULL);
}
if (!cisco_def_domain)
cisco_def_domain = g_strdup ("");
if (cisco_banner && !g_utf8_validate (cisco_banner, -1, NULL))
{
if (!(cisco_banner = g_convert (cisco_banner, -1, "ISO-8859-1", "UTF-8", NULL, NULL, NULL)))
cisco_banner = g_convert (cisco_banner, -1, "C", "UTF-8", NULL, NULL, NULL);
}
if (!cisco_banner)
cisco_banner = g_strdup ("");
/* Send the config info to nm-vpnc-service */
if (!send_config_info (con, vpn_gateway, tundev, internal_ip4_address, internal_ip4_netmask,
internal_ip4_dns, internal_ip4_nbns, cisco_def_domain, cisco_banner))
{
exit (1);
}
exit (0);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
<allow own="org.freedesktop.vpnc"/>
<allow send_destination="org.freedesktop.vpnc"/>
<allow send_interface="org.freedesktop.vpnc"/>
</policy>
<policy context="default">
<deny own="org.freedesktop.vpnc"/>
<deny send_destination="org.freedesktop.vpnc"/>
<deny send_interface="org.freedesktop.vpnc"/>
</policy>
</busconfig>

View File

@@ -0,0 +1,29 @@
/* nm-vpnc-service - vpnc integration with NetworkManager
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2005 Red Hat, Inc.
*/
#ifndef NM_VPNC_SERVICE_H
#define NM_VPNC_SERVICE_H
#define NM_DBUS_SERVICE_VPNC "org.freedesktop.vpnc"
#define NM_DBUS_INTERFACE_VPNC "org.freedesktop.vpnc"
#define NM_DBUS_PATH_VPNC "/org/freedesktop/vpnc"
#endif

View File

@@ -0,0 +1,2 @@
service=org.freedesktop.vpnc
program=/usr/bin/nm-vpnc-service