everything: use libgudev instead of HAL; merge NM and nm-system-settings

The only thing that doesn't work yet is the system-settings service's
"auto eth" connections for ethernet devices that don't have an existing
connection.  Might also have issues with unmanaged devices that can't
provide a MAC address until they are brought up, but we'll see.
This commit is contained in:
Dan Williams
2009-06-11 00:39:12 -04:00
parent 69eccdae34
commit c9067d8fed
71 changed files with 2975 additions and 4486 deletions

View File

@@ -204,10 +204,6 @@ else
fi fi
AM_CONDITIONAL(NO_GIO, test x"$have_gio" == "xno") AM_CONDITIONAL(NO_GIO, test x"$have_gio" == "xno")
PKG_CHECK_MODULES(HAL, hal >= 0.5.0)
AC_SUBST(HAL_CFLAGS)
AC_SUBST(HAL_LIBS)
PKG_CHECK_MODULES(LIBNL, libnl-1 >= 1.0-pre8) PKG_CHECK_MODULES(LIBNL, libnl-1 >= 1.0-pre8)
AC_SUBST(LIBNL_CFLAGS) AC_SUBST(LIBNL_CFLAGS)
AC_SUBST(LIBNL_LIBS) AC_SUBST(LIBNL_LIBS)
@@ -447,6 +443,7 @@ src/ppp-manager/Makefile
src/dnsmasq-manager/Makefile src/dnsmasq-manager/Makefile
src/modem-manager/Makefile src/modem-manager/Makefile
src/bluez-manager/Makefile src/bluez-manager/Makefile
src/system-settings/Makefile
src/backends/Makefile src/backends/Makefile
libnm-util/libnm-util.pc libnm-util/libnm-util.pc
libnm-util/Makefile libnm-util/Makefile
@@ -459,7 +456,6 @@ gfilemonitor/Makefile
callouts/Makefile callouts/Makefile
tools/Makefile tools/Makefile
system-settings/Makefile system-settings/Makefile
system-settings/src/Makefile
system-settings/plugins/Makefile system-settings/plugins/Makefile
system-settings/plugins/ifupdown/Makefile system-settings/plugins/ifupdown/Makefile
system-settings/plugins/ifcfg-rh/Makefile system-settings/plugins/ifcfg-rh/Makefile

View File

@@ -2,9 +2,9 @@
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> <node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.Device"> <interface name="org.freedesktop.NetworkManager.Device">
<property name="Udi" type="s" access="read"> <property name="Path" type="s" access="read">
<tp:docstring> <tp:docstring>
HAL UDI for the device. Udev path of the device in sysfs.
</tp:docstring> </tp:docstring>
</property> </property>
<property name="Interface" type="s" access="read"> <property name="Interface" type="s" access="read">

View File

@@ -44,12 +44,6 @@
</tp:docstring> </tp:docstring>
</property> </property>
<property name="UnmanagedDevices" type="ao" access="read">
<tp:docstring>
The list of HAL UDIs of devices that should not be managed by NetworkManager.
</tp:docstring>
</property>
<signal name="PropertiesChanged"> <signal name="PropertiesChanged">
<arg name="properties" type="a{sv}" tp:type="String_Variant_Map"> <arg name="properties" type="a{sv}" tp:type="String_Variant_Map">
<tp:docstring> <tp:docstring>

View File

@@ -11,7 +11,7 @@ VOID:UINT,UINT,UINT
VOID:STRING,STRING VOID:STRING,STRING
VOID:STRING,UCHAR VOID:STRING,UCHAR
VOID:STRING,OBJECT VOID:STRING,OBJECT
VOID:STRING,STRING,POINTER,POINTER VOID:POINTER,POINTER
VOID:STRING,STRING,STRING,UINT VOID:STRING,STRING,STRING,UINT
VOID:OBJECT,UINT,UINT VOID:OBJECT,UINT,UINT
VOID:STRING,INT VOID:STRING,INT
@@ -20,3 +20,5 @@ VOID:OBJECT,OBJECT,ENUM
VOID:POINTER,STRING VOID:POINTER,STRING
POINTER:POINTER POINTER:POINTER
VOID:STRING,BOXED VOID:STRING,BOXED
BOOLEAN:POINTER,STRING,BOOLEAN,UINT,STRING,STRING

View File

@@ -8,6 +8,7 @@ SUBDIRS= \
dnsmasq-manager \ dnsmasq-manager \
modem-manager \ modem-manager \
bluez-manager \ bluez-manager \
system-settings \
. \ . \
tests tests
@@ -21,7 +22,9 @@ INCLUDES = -I${top_srcdir} \
-I${top_srcdir}/src/dnsmasq-manager \ -I${top_srcdir}/src/dnsmasq-manager \
-I${top_srcdir}/src/modem-manager \ -I${top_srcdir}/src/modem-manager \
-I$(top_srcdir)/src/bluez-manager \ -I$(top_srcdir)/src/bluez-manager \
-I$(top_srcdir)/src/system-settings \
-I${top_srcdir}/libnm-util \ -I${top_srcdir}/libnm-util \
-I${top_srcdir}/libnm-glib \
-I${top_srcdir}/callouts -I${top_srcdir}/callouts
########################################### ###########################################
@@ -71,14 +74,14 @@ NetworkManager_SOURCES = \
NetworkManagerAP.h \ NetworkManagerAP.h \
nm-dbus-manager.h \ nm-dbus-manager.h \
nm-dbus-manager.c \ nm-dbus-manager.c \
nm-hal-manager.c \
nm-hal-manager.h \
nm-udev-manager.c \ nm-udev-manager.c \
nm-udev-manager.h \ nm-udev-manager.h \
nm-hostname-provider.c \ nm-hostname-provider.c \
nm-hostname-provider.h \ nm-hostname-provider.h \
nm-ip4-config.c \ nm-ip4-config.c \
nm-ip4-config.h \ nm-ip4-config.h \
nm-secrets-provider-interface.c \
nm-secrets-provider-interface.h \
nm-active-connection.h \ nm-active-connection.h \
nm-active-connection.c \ nm-active-connection.c \
NetworkManager.c \ NetworkManager.c \
@@ -150,6 +153,7 @@ NetworkManager_CPPFLAGS = \
$(GUDEV_CFLAGS) \ $(GUDEV_CFLAGS) \
$(OPENSSL_CFLAGS) \ $(OPENSSL_CFLAGS) \
$(LIBNL_CFLAGS) \ $(LIBNL_CFLAGS) \
$(GMODULE_CFLAGS) \
-DG_DISABLE_DEPRECATED \ -DG_DISABLE_DEPRECATED \
-DBINDIR=\"$(bindir)\" \ -DBINDIR=\"$(bindir)\" \
-DSBINDIR=\"$(sbindir)\" \ -DSBINDIR=\"$(sbindir)\" \
@@ -167,6 +171,7 @@ NetworkManager_LDADD = \
$(HAL_LIBS) \ $(HAL_LIBS) \
$(GUDEV_LIBS) \ $(GUDEV_LIBS) \
$(LIBNL_LIBS) \ $(LIBNL_LIBS) \
$(GMODULE_LIBS) \
$(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/marshallers/libmarshallers.la \
./named-manager/libnamed-manager.la \ ./named-manager/libnamed-manager.la \
./vpn-manager/libvpn-manager.la \ ./vpn-manager/libvpn-manager.la \
@@ -176,6 +181,7 @@ NetworkManager_LDADD = \
./ppp-manager/libppp-manager.la \ ./ppp-manager/libppp-manager.la \
./modem-manager/libmodem-manager.la \ ./modem-manager/libmodem-manager.la \
./bluez-manager/libbluez-manager.la \ ./bluez-manager/libbluez-manager.la \
./system-settings/libsystem-settings.la \
./backends/libnmbackend.la \ ./backends/libnmbackend.la \
$(top_builddir)/libnm-util/libnm-util.la $(top_builddir)/libnm-util/libnm-util.la

View File

@@ -36,6 +36,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <gmodule.h>
#include <string.h> #include <string.h>
#include "NetworkManager.h" #include "NetworkManager.h"
@@ -243,6 +244,30 @@ write_pidfile (const char *pidfile)
nm_warning ("Closing %s failed: %s", pidfile, strerror (errno)); nm_warning ("Closing %s failed: %s", pidfile, strerror (errno));
} }
static gboolean
parse_config_file (const char *filename, char **plugins, GError **error)
{
GKeyFile *config;
config = g_key_file_new ();
if (!config) {
g_set_error (error, 0, 0,
"Not enough memory to load config file.");
return FALSE;
}
g_key_file_set_list_separator (config, ',');
if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, error))
return FALSE;
*plugins = g_key_file_get_value (config, "main", "plugins", error);
if (*error)
return FALSE;
g_key_file_free (config);
return TRUE;
}
/* /*
* main * main
* *
@@ -251,10 +276,10 @@ int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
GOptionContext *opt_ctx = NULL; GOptionContext *opt_ctx = NULL;
gboolean become_daemon = FALSE; gboolean become_daemon = FALSE;
gboolean g_fatal_warnings = FALSE; gboolean g_fatal_warnings = FALSE;
char * pidfile = NULL; char *pidfile = NULL, *user_pidfile = NULL;
char * user_pidfile = NULL; char *config = NULL, *plugins = NULL;
gboolean success; gboolean success;
NMPolicy *policy = NULL; NMPolicy *policy = NULL;
NMVPNManager *vpn_manager = NULL; NMVPNManager *vpn_manager = NULL;
@@ -262,11 +287,14 @@ main (int argc, char *argv[])
NMDBusManager *dbus_mgr = NULL; NMDBusManager *dbus_mgr = NULL;
NMSupplicantManager *sup_mgr = NULL; NMSupplicantManager *sup_mgr = NULL;
NMDHCPManager *dhcp_mgr = NULL; NMDHCPManager *dhcp_mgr = NULL;
GError *error = NULL;
GOptionEntry options[] = { GOptionEntry options[] = {
{"no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, "Don't become a daemon", NULL}, { "no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, "Don't become a daemon", NULL },
{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL }, { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL },
{"pid-file", 0, 0, G_OPTION_ARG_FILENAME, &user_pidfile, "Specify the location of a PID file", "filename"}, { "pid-file", 0, 0, G_OPTION_ARG_FILENAME, &user_pidfile, "Specify the location of a PID file", "filename" },
{ "config", 0, 0, G_OPTION_ARG_FILENAME, &config, "Config file location", "/path/to/config.file" },
{ "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ,", "plugin1,plugin2" },
{NULL} {NULL}
}; };
@@ -275,6 +303,11 @@ main (int argc, char *argv[])
exit (1); exit (1);
} }
if (!g_module_supported ()) {
g_printerr ("GModules are not supported on your platform!");
exit (1);
}
bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE); textdomain (GETTEXT_PACKAGE);
@@ -297,6 +330,14 @@ main (int argc, char *argv[])
exit (1); exit (1);
} }
/* Parse the config file */
if (config) {
if (!parse_config_file (config, &plugins, &error)) {
g_warning ("Config file %s invalid: %s.", config, error->message);
exit (1);
}
}
pidfile = g_strdup (user_pidfile ? user_pidfile : NM_DEFAULT_PID_FILE); pidfile = g_strdup (user_pidfile ? user_pidfile : NM_DEFAULT_PID_FILE);
/* Tricky: become_daemon is FALSE by default, so unless it's TRUE because /* Tricky: become_daemon is FALSE by default, so unless it's TRUE because
@@ -358,9 +399,16 @@ main (int argc, char *argv[])
goto done; goto done;
} }
manager = nm_manager_get (); named_mgr = nm_named_manager_get ();
if (!named_mgr) {
nm_warning ("Failed to start the named manager.");
goto done;
}
manager = nm_manager_get (plugins, &error);
if (manager == NULL) { if (manager == NULL) {
nm_error ("Failed to initialize the network manager."); nm_error ("Failed to initialize the network manager: %s",
error && error->message ? error->message : "(unknown)");
goto done; goto done;
} }
@@ -377,12 +425,6 @@ main (int argc, char *argv[])
goto done; goto done;
} }
named_mgr = nm_named_manager_get ();
if (!named_mgr) {
nm_warning ("Failed to start the named manager.");
goto done;
}
dhcp_mgr = nm_dhcp_manager_get (); dhcp_mgr = nm_dhcp_manager_get ();
if (!dhcp_mgr) { if (!dhcp_mgr) {
nm_warning ("Failed to start the DHCP manager."); nm_warning ("Failed to start the DHCP manager.");
@@ -397,6 +439,8 @@ main (int argc, char *argv[])
goto done; goto done;
} }
nm_manager_start (manager);
/* Bring up the loopback interface. */ /* Bring up the loopback interface. */
nm_system_enable_loopback (); nm_system_enable_loopback ();

View File

@@ -4,7 +4,10 @@
<busconfig> <busconfig>
<policy user="root"> <policy user="root">
<allow own="org.freedesktop.NetworkManager"/> <allow own="org.freedesktop.NetworkManager"/>
<allow own="org.freedesktop.NetworkManagerSystemSettings"/>
<allow send_destination="org.freedesktop.NetworkManager"/> <allow send_destination="org.freedesktop.NetworkManager"/>
<allow send_destination="org.freedesktop.NetworkManagerSystemSettings"/>
<allow send_destination="org.freedesktop.NetworkManager" <allow send_destination="org.freedesktop.NetworkManager"
send_interface="org.freedesktop.NetworkManager.PPP"/> send_interface="org.freedesktop.NetworkManager.PPP"/>
@@ -56,7 +59,14 @@
</policy> </policy>
<policy context="default"> <policy context="default">
<deny own="org.freedesktop.NetworkManager"/> <deny own="org.freedesktop.NetworkManager"/>
<deny own="org.freedesktop.NetworkManagerSystemSettings"/>
<deny send_destination="org.freedesktop.NetworkManager"/> <deny send_destination="org.freedesktop.NetworkManager"/>
<allow send_destination="org.freedesktop.NetworkManagerSystemSettings"/>
<!-- The org.freedesktop.NetworkManagerSettings.Connection.Secrets
interface is secured via PolicyKit.
-->
</policy> </policy>
<limit name="max_replies_per_connection">512</limit> <limit name="max_replies_per_connection">512</limit>

View File

@@ -648,7 +648,7 @@ auto_activate_device (gpointer user_data)
GError *error = NULL; GError *error = NULL;
const char *device_path; const char *device_path;
device_path = nm_device_get_udi (data->device); device_path = nm_device_get_path (data->device);
if (!nm_manager_activate_connection (policy->manager, if (!nm_manager_activate_connection (policy->manager,
best_connection, best_connection,
specific_object, specific_object,

View File

@@ -366,7 +366,7 @@ nm_utils_call_dispatcher (const char *action,
/* state */ /* state */
value_hash_add_uint (device_props, NMD_DEVICE_PROPS_STATE, nm_device_get_state (device)); value_hash_add_uint (device_props, NMD_DEVICE_PROPS_STATE, nm_device_get_state (device));
value_hash_add_object_path (device_props, NMD_DEVICE_PROPS_PATH, nm_device_get_udi (device)); value_hash_add_object_path (device_props, NMD_DEVICE_PROPS_PATH, nm_device_get_path (device));
} }
dbus_g_proxy_call_no_reply (proxy, "Action", dbus_g_proxy_call_no_reply (proxy, "Action",
@@ -383,6 +383,32 @@ nm_utils_call_dispatcher (const char *action,
g_object_unref (dbus_mgr); g_object_unref (dbus_mgr);
} }
gboolean
nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr)
{
const GSList *iter;
char *hwaddr_match, *p;
g_return_val_if_fail (hwaddr != NULL, FALSE);
p = hwaddr_match = g_strdup_printf ("mac:%s", hwaddr);
while (*p) {
*p = g_ascii_tolower (*p);
p++;
}
for (iter = specs; iter; iter = g_slist_next (iter)) {
if (!strcmp ((const char *) iter->data, hwaddr_match)) {
g_free (hwaddr_match);
return TRUE;
}
}
g_free (hwaddr_match);
return FALSE;
}
/*********************************/ /*********************************/
static void static void
@@ -449,3 +475,4 @@ value_hash_add_uint (GHashTable *hash,
value_hash_add (hash, key, value); value_hash_add (hash, key, value);
} }

View File

@@ -46,6 +46,8 @@ void nm_utils_call_dispatcher (const char *action,
NMDevice *device, NMDevice *device,
const char *vpn_iface); const char *vpn_iface);
gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr);
GHashTable *value_hash_create (void); GHashTable *value_hash_create (void);
void value_hash_add (GHashTable *hash, void value_hash_add (GHashTable *hash,

View File

@@ -129,12 +129,12 @@ stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_d
if (required_secret) { if (required_secret) {
nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
nm_act_request_request_connection_secrets (nm_device_get_act_request (device), nm_act_request_get_secrets (nm_device_get_act_request (device),
NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_SETTING_NAME,
retry_secret, retry_secret,
SECRETS_CALLER_GSM, SECRETS_CALLER_GSM,
required_secret, required_secret,
NULL); NULL);
} else } else
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, translate_mm_error (error)); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, translate_mm_error (error));
@@ -237,12 +237,12 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), GSM_SECRETS_TRIES)); tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), GSM_SECRETS_TRIES));
nm_act_request_request_connection_secrets (req, nm_act_request_get_secrets (req,
setting_name, setting_name,
tries ? TRUE : FALSE, tries ? TRUE : FALSE,
SECRETS_CALLER_GSM, SECRETS_CALLER_GSM,
hint1, hint1,
hint2); hint2);
g_object_set_data (G_OBJECT (connection), GSM_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); g_object_set_data (G_OBJECT (connection), GSM_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
if (hints) if (hints)

View File

@@ -36,9 +36,12 @@
#include "nm-active-connection.h" #include "nm-active-connection.h"
#include "nm-dbus-glib-types.h" #include "nm-dbus-glib-types.h"
#include "nm-manager.h" /* FIXME! */
G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT) static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class);
G_DEFINE_TYPE_EXTENDED (NMActRequest, nm_act_request, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE,
secrets_provider_interface_init))
#define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACT_REQUEST, NMActRequestPrivate)) #define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACT_REQUEST, NMActRequestPrivate))
@@ -61,7 +64,7 @@ typedef struct {
gboolean disposed; gboolean disposed;
NMConnection *connection; NMConnection *connection;
DBusGProxyCall *secrets_call; guint32 secrets_call_id;
char *specific_object; char *specific_object;
NMDevice *device; NMDevice *device;
@@ -177,24 +180,6 @@ nm_act_request_init (NMActRequest *req)
g_object_unref (dbus_mgr); g_object_unref (dbus_mgr);
} }
static void
cleanup_secrets_dbus_call (NMActRequest *self)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
DBusGProxy *proxy;
g_return_if_fail (priv->connection != NULL);
g_return_if_fail (NM_IS_CONNECTION (priv->connection));
proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG);
g_assert (proxy);
if (priv->secrets_call) {
dbus_g_proxy_cancel_call (proxy, priv->secrets_call);
priv->secrets_call = NULL;
}
}
static void static void
dispose (GObject *object) dispose (GObject *object)
{ {
@@ -212,8 +197,6 @@ dispose (GObject *object)
G_CALLBACK (device_state_changed), G_CALLBACK (device_state_changed),
NM_ACT_REQUEST (object)); NM_ACT_REQUEST (object));
cleanup_secrets_dbus_call (NM_ACT_REQUEST (object));
/* Clear any share rules */ /* Clear any share rules */
nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE); nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE);
@@ -275,7 +258,7 @@ get_property (GObject *object, guint prop_id,
break; break;
case PROP_DEVICES: case PROP_DEVICES:
devices = g_ptr_array_sized_new (1); devices = g_ptr_array_sized_new (1);
g_ptr_array_add (devices, g_strdup (nm_device_get_udi (priv->device))); g_ptr_array_add (devices, g_strdup (nm_device_get_path (priv->device)));
g_value_take_boxed (value, devices); g_value_take_boxed (value, devices);
break; break;
case PROP_STATE: case PROP_STATE:
@@ -363,7 +346,7 @@ nm_act_request_class_init (NMActRequestClass *req_class)
g_signal_new ("connection-secrets-updated", g_signal_new ("connection-secrets-updated",
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMActRequestClass, connection_secrets_updated), G_STRUCT_OFFSET (NMActRequestClass, secrets_updated),
NULL, NULL, NULL, NULL,
_nm_marshal_VOID__OBJECT_POINTER_UINT, _nm_marshal_VOID__OBJECT_POINTER_UINT,
G_TYPE_NONE, 3, G_TYPE_NONE, 3,
@@ -373,7 +356,7 @@ nm_act_request_class_init (NMActRequestClass *req_class)
g_signal_new ("connection-secrets-failed", g_signal_new ("connection-secrets-failed",
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMActRequestClass, connection_secrets_failed), G_STRUCT_OFFSET (NMActRequestClass, secrets_failed),
NULL, NULL, NULL, NULL,
_nm_marshal_VOID__OBJECT_STRING_UINT, _nm_marshal_VOID__OBJECT_STRING_UINT,
G_TYPE_NONE, 3, G_TYPE_NONE, 3,
@@ -386,30 +369,17 @@ nm_act_request_class_init (NMActRequestClass *req_class)
nm_active_connection_install_type_info (object_class); nm_active_connection_install_type_info (object_class);
} }
typedef struct GetSecretsInfo { static gboolean
NMActRequest *req; secrets_update_setting (NMSecretsProviderInterface *interface,
char *setting_name; const char *setting_name,
RequestSecretsCaller caller; GHashTable *new)
} GetSecretsInfo;
static void
free_get_secrets_info (gpointer data)
{ {
GetSecretsInfo *info = (GetSecretsInfo *) data; NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (interface);
g_free (info->setting_name);
g_free (info);
}
static void
update_one_setting (const char* setting_name,
GHashTable *setting_hash,
NMConnection *connection,
GSList **updated)
{
GType type;
NMSetting *setting = NULL; NMSetting *setting = NULL;
GError *error = NULL; GError *error = NULL;
GType type;
g_return_val_if_fail (priv->connection != NULL, FALSE);
/* Check whether a complete & valid NMSetting object was returned. If /* Check whether a complete & valid NMSetting object was returned. If
* yes, replace the setting object in the connection. If not, just try * yes, replace the setting object in the connection. If not, just try
@@ -417,9 +387,9 @@ update_one_setting (const char* setting_name,
*/ */
type = nm_connection_lookup_setting_type (setting_name); type = nm_connection_lookup_setting_type (setting_name);
if (type == 0) if (type == 0)
return; return FALSE;
setting = nm_setting_new_from_hash (type, setting_hash); setting = nm_setting_new_from_hash (type, new);
if (setting) { if (setting) {
NMSetting *s_8021x = NULL; NMSetting *s_8021x = NULL;
GSList *all_settings = NULL; GSList *all_settings = NULL;
@@ -427,7 +397,7 @@ update_one_setting (const char* setting_name,
/* The wireless-security setting might need the 802.1x setting in /* The wireless-security setting might need the 802.1x setting in
* the all_settings argument of the verify function. Ugh. * the all_settings argument of the verify function. Ugh.
*/ */
s_8021x = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); s_8021x = nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_802_1X);
if (s_8021x) if (s_8021x)
all_settings = g_slist_append (all_settings, s_8021x); all_settings = g_slist_append (all_settings, s_8021x);
@@ -441,9 +411,9 @@ update_one_setting (const char* setting_name,
} }
if (setting) if (setting)
nm_connection_add_setting (connection, setting); nm_connection_add_setting (priv->connection, setting);
else { else {
if (!nm_connection_update_secrets (connection, setting_name, setting_hash, &error)) { if (!nm_connection_update_secrets (priv->connection, setting_name, new, &error)) {
nm_warning ("Failed to update connection secrets: %d %s", nm_warning ("Failed to update connection secrets: %d %s",
error ? error->code : -1, error ? error->code : -1,
error && error->message ? error->message : "(none)"); error && error->message ? error->message : "(none)");
@@ -451,166 +421,56 @@ update_one_setting (const char* setting_name,
} }
} }
*updated = g_slist_append (*updated, (gpointer) setting_name); return TRUE;
} }
static void static void
add_one_key_to_list (gpointer key, gpointer data, gpointer user_data) secrets_result (NMSecretsProviderInterface *interface,
const char *setting_name,
RequestSecretsCaller caller,
const GSList *updated,
GError *error)
{ {
GSList **list = (GSList **) user_data; NMActRequest *self = NM_ACT_REQUEST (interface);
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
*list = g_slist_append (*list, key); g_return_if_fail (priv->connection != NULL);
}
static gint if (error) {
settings_order_func (gconstpointer a, gconstpointer b) g_signal_emit (self, signals[CONNECTION_SECRETS_FAILED], 0,
{ priv->connection, setting_name, caller);
/* Just ensure the 802.1x setting gets processed _before_ the
* wireless-security one.
*/
if ( !strcmp (a, NM_SETTING_802_1X_SETTING_NAME)
&& !strcmp (b, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME))
return -1;
if ( !strcmp (a, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)
&& !strcmp (b, NM_SETTING_802_1X_SETTING_NAME))
return 1;
return 0;
}
static void
get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
{
GetSecretsInfo *info = (GetSecretsInfo *) user_data;
GError *err = NULL;
GHashTable *settings = NULL;
NMActRequestPrivate *priv = NULL;
GSList *keys = NULL, *iter;
GSList *updated = NULL;
g_return_if_fail (info != NULL);
g_return_if_fail (info->req);
g_return_if_fail (info->setting_name);
priv = NM_ACT_REQUEST_GET_PRIVATE (info->req);
g_return_if_fail (call == priv->secrets_call);
priv->secrets_call = NULL;
if (!dbus_g_proxy_end_call (proxy, call, &err,
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings,
G_TYPE_INVALID)) {
nm_warning ("Couldn't get connection secrets: %s.", err->message);
g_error_free (err);
g_signal_emit (info->req,
signals[CONNECTION_SECRETS_FAILED],
0,
priv->connection,
info->setting_name,
info->caller);
return;
}
if (g_hash_table_size (settings) == 0) {
// FIXME: some better way to handle invalid message?
nm_warning ("GetSecrets call returned but no secrets were found.");
goto out;
}
g_hash_table_foreach (settings, add_one_key_to_list, &keys);
keys = g_slist_sort (keys, settings_order_func);
for (iter = keys; iter; iter = g_slist_next (iter)) {
GHashTable *setting_hash;
setting_hash = g_hash_table_lookup (settings, iter->data);
if (setting_hash) {
update_one_setting ((const char *) iter->data,
setting_hash,
priv->connection,
&updated);
} else
nm_warning ("Couldn't get setting secrets for '%s'", (const char *) iter->data);
}
g_slist_free (keys);
if (g_slist_length (updated)) {
g_signal_emit (info->req,
signals[CONNECTION_SECRETS_UPDATED],
0,
priv->connection,
updated,
info->caller);
} else { } else {
nm_warning ("No secrets updated because not valid settings were received!"); g_signal_emit (self, signals[CONNECTION_SECRETS_UPDATED], 0,
priv->connection, updated, caller);
} }
}
out: static void
g_slist_free (updated); secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class)
g_hash_table_destroy (settings); {
/* interface implementation */
sp_interface_class->update_setting = secrets_update_setting;
sp_interface_class->result = secrets_result;
} }
gboolean gboolean
nm_act_request_request_connection_secrets (NMActRequest *self, nm_act_request_get_secrets (NMActRequest *self,
const char *setting_name, const char *setting_name,
gboolean request_new, gboolean request_new,
RequestSecretsCaller caller, RequestSecretsCaller caller,
const char *hint1, const char *hint1,
const char *hint2) const char *hint2)
{ {
DBusGProxy *secrets_proxy; g_return_val_if_fail (self, FALSE);
GetSecretsInfo *info = NULL;
NMActRequestPrivate *priv = NULL;
GPtrArray *hints = NULL;
g_return_val_if_fail (NM_IS_ACT_REQUEST (self), FALSE); g_return_val_if_fail (NM_IS_ACT_REQUEST (self), FALSE);
g_return_val_if_fail (setting_name != NULL, FALSE);
priv = NM_ACT_REQUEST_GET_PRIVATE (self); return nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self),
nm_act_request_get_connection (self),
cleanup_secrets_dbus_call (self); setting_name,
request_new,
info = g_malloc0 (sizeof (GetSecretsInfo)); caller,
g_return_val_if_fail (info != NULL, FALSE); hint1,
hint2);
info->req = self;
info->caller = caller;
info->setting_name = g_strdup (setting_name);
/* Empty for now */
hints = g_ptr_array_sized_new (2);
if (hint1)
g_ptr_array_add (hints, g_strdup (hint1));
if (hint2)
g_ptr_array_add (hints, g_strdup (hint2));
secrets_proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG);
g_assert (secrets_proxy);
priv->secrets_call = dbus_g_proxy_begin_call_with_timeout (secrets_proxy, "GetSecrets",
get_secrets_cb,
info,
free_get_secrets_info,
G_MAXINT32,
G_TYPE_STRING, setting_name,
DBUS_TYPE_G_ARRAY_OF_STRING, hints,
G_TYPE_BOOLEAN, request_new,
G_TYPE_INVALID);
g_ptr_array_free (hints, TRUE);
if (!priv->secrets_call) {
nm_warning ("Could not call get secrets");
goto error;
}
return TRUE;
error:
if (info)
free_get_secrets_info (info);
cleanup_secrets_dbus_call (self);
return FALSE;
} }
NMConnection * NMConnection *

View File

@@ -25,6 +25,7 @@
#include <glib-object.h> #include <glib-object.h>
#include "nm-connection.h" #include "nm-connection.h"
#include "nm-active-connection.h" #include "nm-active-connection.h"
#include "nm-secrets-provider-interface.h"
#define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ()) #define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ())
#define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest)) #define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest))
@@ -37,27 +38,18 @@ typedef struct {
GObject parent; GObject parent;
} NMActRequest; } NMActRequest;
typedef enum {
SECRETS_CALLER_NONE = 0,
SECRETS_CALLER_ETHERNET,
SECRETS_CALLER_WIFI,
SECRETS_CALLER_GSM,
SECRETS_CALLER_CDMA,
SECRETS_CALLER_PPP
} RequestSecretsCaller;
typedef struct { typedef struct {
GObjectClass parent; GObjectClass parent;
/* Signals */ /* Signals */
void (*connection_secrets_updated) (NMActRequest *req, void (*secrets_updated) (NMActRequest *req,
NMConnection *connection, NMConnection *connection,
GSList *updated_settings, GSList *updated_settings,
RequestSecretsCaller caller); RequestSecretsCaller caller);
void (*connection_secrets_failed) (NMActRequest *req, void (*secrets_failed) (NMActRequest *req,
NMConnection *connection, NMConnection *connection,
const char *setting, const char *setting,
RequestSecretsCaller caller); RequestSecretsCaller caller);
void (*properties_changed) (NMActRequest *req, GHashTable *properties); void (*properties_changed) (NMActRequest *req, GHashTable *properties);
} NMActRequestClass; } NMActRequestClass;
@@ -70,12 +62,6 @@ NMActRequest *nm_act_request_new (NMConnection *connection,
gpointer *device); /* An NMDevice */ gpointer *device); /* An NMDevice */
NMConnection *nm_act_request_get_connection (NMActRequest *req); NMConnection *nm_act_request_get_connection (NMActRequest *req);
gboolean nm_act_request_request_connection_secrets (NMActRequest *req,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2);
const char * nm_act_request_get_specific_object (NMActRequest *req); const char * nm_act_request_get_specific_object (NMActRequest *req);
void nm_act_request_set_specific_object (NMActRequest *req, void nm_act_request_set_specific_object (NMActRequest *req,
@@ -99,4 +85,12 @@ void nm_act_request_add_share_rule (NMActRequest *req,
GObject * nm_act_request_get_device (NMActRequest *req); GObject * nm_act_request_get_device (NMActRequest *req);
gboolean nm_act_request_get_secrets (NMActRequest *req,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2);
#endif /* NM_ACTIVATION_REQUEST_H */ #endif /* NM_ACTIVATION_REQUEST_H */

View File

@@ -339,6 +339,24 @@ nm_dbus_manager_start_service (NMDBusManager *self)
return FALSE; return FALSE;
} }
if (!dbus_g_proxy_call (priv->proxy, "RequestName", &err,
G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS,
G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
G_TYPE_INVALID,
G_TYPE_UINT, &result,
G_TYPE_INVALID)) {
g_warning ("Could not acquire the NetworkManagerSystemSettings service.\n"
" Message: '%s'", err->message);
g_error_free (err);
return FALSE;
}
if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
g_warning ("Could not acquire the NetworkManagerSystemSettings service "
"as it is already taken.");
return FALSE;
}
priv->started = TRUE; priv->started = TRUE;
return priv->started; return priv->started;
} }

View File

@@ -104,6 +104,7 @@ typedef struct {
struct ether_addr hw_addr; struct ether_addr hw_addr;
gboolean carrier; gboolean carrier;
guint32 ifindex;
guint state_to_disconnected_id; guint state_to_disconnected_id;
char * carrier_file_path; char * carrier_file_path;
@@ -131,6 +132,7 @@ enum {
PROP_HW_ADDRESS, PROP_HW_ADDRESS,
PROP_SPEED, PROP_SPEED,
PROP_CARRIER, PROP_CARRIER,
PROP_IFINDEX,
LAST_PROP LAST_PROP
}; };
@@ -386,7 +388,7 @@ NMDeviceEthernet *
nm_device_ethernet_new (const char *udi, nm_device_ethernet_new (const char *udi,
const char *iface, const char *iface,
const char *driver, const char *driver,
gboolean managed) guint32 ifindex)
{ {
g_return_val_if_fail (udi != NULL, NULL); g_return_val_if_fail (udi != NULL, NULL);
g_return_val_if_fail (iface != NULL, NULL); g_return_val_if_fail (iface != NULL, NULL);
@@ -396,7 +398,7 @@ nm_device_ethernet_new (const char *udi,
NM_DEVICE_INTERFACE_UDI, udi, NM_DEVICE_INTERFACE_UDI, udi,
NM_DEVICE_INTERFACE_IFACE, iface, NM_DEVICE_INTERFACE_IFACE, iface,
NM_DEVICE_INTERFACE_DRIVER, driver, NM_DEVICE_INTERFACE_DRIVER, driver,
NM_DEVICE_INTERFACE_MANAGED, managed, NM_DEVICE_ETHERNET_IFINDEX, ifindex,
NULL); NULL);
} }
@@ -427,6 +429,14 @@ nm_device_ethernet_get_carrier (NMDeviceEthernet *self)
return NM_DEVICE_ETHERNET_GET_PRIVATE (self)->carrier; return NM_DEVICE_ETHERNET_GET_PRIVATE (self)->carrier;
} }
guint32
nm_device_ethernet_get_ifindex (NMDeviceEthernet *self)
{
g_return_val_if_fail (self != NULL, FALSE);
return NM_DEVICE_ETHERNET_GET_PRIVATE (self)->ifindex;
}
/* Returns speed in Mb/s */ /* Returns speed in Mb/s */
static guint32 static guint32
nm_device_ethernet_get_speed (NMDeviceEthernet *self) nm_device_ethernet_get_speed (NMDeviceEthernet *self)
@@ -801,8 +811,12 @@ link_timeout_cb (gpointer user_data)
supplicant_interface_release (self); supplicant_interface_release (self);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_request_connection_secrets (req, setting_name, TRUE, nm_act_request_get_secrets (req,
SECRETS_CALLER_ETHERNET, NULL, NULL); setting_name,
TRUE,
SECRETS_CALLER_ETHERNET,
NULL,
NULL);
return FALSE; return FALSE;
@@ -1078,8 +1092,12 @@ handle_auth_or_fail (NMDeviceEthernet *self,
* only ask for new secrets after the first failure. * only ask for new secrets after the first failure.
*/ */
get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE); get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE);
nm_act_request_request_connection_secrets (req, setting_name, get_new, nm_act_request_get_secrets (req,
SECRETS_CALLER_ETHERNET, NULL, NULL); setting_name,
get_new,
SECRETS_CALLER_ETHERNET,
NULL,
NULL);
g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
} else } else
@@ -1445,6 +1463,21 @@ real_check_connection_compatible (NMDevice *device,
return TRUE; return TRUE;
} }
static gboolean
spec_match_list (NMDevice *device, const GSList *specs)
{
struct ether_addr ether;
char *hwaddr;
gboolean matched;
nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), &ether);
hwaddr = nm_ether_ntop (&ether);
matched = nm_match_spec_hwaddr (specs, hwaddr);
g_free (hwaddr);
return matched;
}
static void static void
nm_device_ethernet_dispose (GObject *object) nm_device_ethernet_dispose (GObject *object)
{ {
@@ -1512,12 +1545,31 @@ get_property (GObject *object, guint prop_id,
case PROP_CARRIER: case PROP_CARRIER:
g_value_set_boolean (value, nm_device_ethernet_get_carrier (device)); g_value_set_boolean (value, nm_device_ethernet_get_carrier (device));
break; break;
case PROP_IFINDEX:
g_value_set_uint (value, nm_device_ethernet_get_ifindex (device));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
} }
} }
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object);
switch (prop_id) {
case PROP_IFINDEX:
/* construct-only */
priv->ifindex = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void static void
nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
@@ -1531,6 +1583,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
object_class->constructor = constructor; object_class->constructor = constructor;
object_class->dispose = nm_device_ethernet_dispose; object_class->dispose = nm_device_ethernet_dispose;
object_class->get_property = get_property; object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->finalize = nm_device_ethernet_finalize; object_class->finalize = nm_device_ethernet_finalize;
parent_class->get_generic_capabilities = real_get_generic_capabilities; parent_class->get_generic_capabilities = real_get_generic_capabilities;
@@ -1550,6 +1603,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
parent_class->act_stage2_config = real_act_stage2_config; parent_class->act_stage2_config = real_act_stage2_config;
parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
parent_class->deactivate_quickly = real_deactivate_quickly; parent_class->deactivate_quickly = real_deactivate_quickly;
parent_class->spec_match_list = spec_match_list;
/* properties */ /* properties */
g_object_class_install_property g_object_class_install_property
@@ -1576,6 +1630,14 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
FALSE, FALSE,
G_PARAM_READABLE)); G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_IFINDEX,
g_param_spec_uint (NM_DEVICE_ETHERNET_IFINDEX,
"Ifindex",
"Interface index",
0, G_MAXUINT32, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/* Signals */ /* Signals */
signals[PROPERTIES_CHANGED] = signals[PROPERTIES_CHANGED] =
nm_properties_changed_signal_new (object_class, nm_properties_changed_signal_new (object_class,

View File

@@ -39,6 +39,7 @@ G_BEGIN_DECLS
#define NM_DEVICE_ETHERNET_HW_ADDRESS "hw-address" #define NM_DEVICE_ETHERNET_HW_ADDRESS "hw-address"
#define NM_DEVICE_ETHERNET_SPEED "speed" #define NM_DEVICE_ETHERNET_SPEED "speed"
#define NM_DEVICE_ETHERNET_CARRIER "carrier" #define NM_DEVICE_ETHERNET_CARRIER "carrier"
#define NM_DEVICE_ETHERNET_IFINDEX "ifindex"
typedef struct { typedef struct {
NMDevice parent; NMDevice parent;
@@ -56,15 +57,17 @@ GType nm_device_ethernet_get_type (void);
NMDeviceEthernet *nm_device_ethernet_new (const char *udi, NMDeviceEthernet *nm_device_ethernet_new (const char *udi,
const char *iface, const char *iface,
const char *driver, const char *driver,
gboolean managed); guint32 ifindex);
void nm_device_ethernet_get_address (NMDeviceEthernet *dev, void nm_device_ethernet_get_address (NMDeviceEthernet *dev,
struct ether_addr *addr); struct ether_addr *addr);
gboolean nm_device_ethernet_get_carrier (NMDeviceEthernet *dev); gboolean nm_device_ethernet_get_carrier (NMDeviceEthernet *dev);
guint32 nm_device_ethernet_get_ifindex (NMDeviceEthernet *dev);
G_END_DECLS G_END_DECLS
#endif /* NM_DEVICE_ETHERNET_H */ #endif /* NM_DEVICE_ETHERNET_H */

View File

@@ -70,8 +70,8 @@ nm_device_interface_init (gpointer g_iface)
g_object_interface_install_property g_object_interface_install_property
(g_iface, (g_iface,
g_param_spec_string (NM_DEVICE_INTERFACE_UDI, g_param_spec_string (NM_DEVICE_INTERFACE_UDI,
"Udi", "UDI",
"HAL Udi", "Unique Device Identifier",
NULL, NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
@@ -143,7 +143,7 @@ nm_device_interface_init (gpointer g_iface)
(g_iface, g_param_spec_boolean (NM_DEVICE_INTERFACE_MANAGED, (g_iface, g_param_spec_boolean (NM_DEVICE_INTERFACE_MANAGED,
"Managed", "Managed",
"Managed", "Managed",
TRUE, FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/* Signals */ /* Signals */
@@ -270,3 +270,12 @@ nm_device_interface_get_state (NMDeviceInterface *device)
return state; return state;
} }
gboolean
nm_device_interface_spec_match_list (NMDeviceInterface *device,
const GSList *specs)
{
if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->spec_match_list)
return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->spec_match_list (device, specs);
return FALSE;
}

View File

@@ -41,16 +41,16 @@ typedef enum
#define NM_DEVICE_INTERFACE_ERROR (nm_device_interface_error_quark ()) #define NM_DEVICE_INTERFACE_ERROR (nm_device_interface_error_quark ())
#define NM_TYPE_DEVICE_INTERFACE_ERROR (nm_device_interface_error_get_type ()) #define NM_TYPE_DEVICE_INTERFACE_ERROR (nm_device_interface_error_get_type ())
#define NM_DEVICE_INTERFACE_UDI "udi" #define NM_DEVICE_INTERFACE_UDI "udi"
#define NM_DEVICE_INTERFACE_IFACE "interface" #define NM_DEVICE_INTERFACE_IFACE "interface"
#define NM_DEVICE_INTERFACE_DRIVER "driver" #define NM_DEVICE_INTERFACE_DRIVER "driver"
#define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities" #define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities"
#define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4-address" #define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4-address"
#define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config" #define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config"
#define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config" #define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config"
#define NM_DEVICE_INTERFACE_STATE "state" #define NM_DEVICE_INTERFACE_STATE "state"
#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ #define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */
#define NM_DEVICE_INTERFACE_MANAGED "managed" #define NM_DEVICE_INTERFACE_MANAGED "managed"
typedef enum { typedef enum {
NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000, NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000,
@@ -84,6 +84,8 @@ struct _NMDeviceInterface {
void (*deactivate) (NMDeviceInterface *device, NMDeviceStateReason reason); void (*deactivate) (NMDeviceInterface *device, NMDeviceStateReason reason);
gboolean (*spec_match_list) (NMDeviceInterface *device, const GSList *specs);
/* Signals */ /* Signals */
void (*state_changed) (NMDeviceInterface *device, void (*state_changed) (NMDeviceInterface *device,
NMDeviceState new_state, NMDeviceState new_state,
@@ -108,4 +110,7 @@ void nm_device_interface_deactivate (NMDeviceInterface *device, NMDeviceStateRea
NMDeviceState nm_device_interface_get_state (NMDeviceInterface *device); NMDeviceState nm_device_interface_get_state (NMDeviceInterface *device);
gboolean nm_device_interface_spec_match_list (NMDeviceInterface *device,
const GSList *specs);
#endif /* NM_DEVICE_INTERFACE_H */ #endif /* NM_DEVICE_INTERFACE_H */

View File

@@ -81,6 +81,7 @@ enum {
PROP_BITRATE, PROP_BITRATE,
PROP_ACTIVE_ACCESS_POINT, PROP_ACTIVE_ACCESS_POINT,
PROP_CAPABILITIES, PROP_CAPABILITIES,
PROP_IFINDEX,
LAST_PROP LAST_PROP
}; };
@@ -138,6 +139,7 @@ struct _NMDeviceWifiPrivate {
gboolean dispose_has_run; gboolean dispose_has_run;
struct ether_addr hw_addr; struct ether_addr hw_addr;
guint32 ifindex;
GByteArray * ssid; GByteArray * ssid;
gint8 invalid_strength_counter; gint8 invalid_strength_counter;
@@ -2136,8 +2138,12 @@ link_timeout_cb (gpointer user_data)
" asking for new key.", nm_device_get_iface (dev)); " asking for new key.", nm_device_get_iface (dev));
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_request_connection_secrets (req, setting_name, TRUE, nm_act_request_get_secrets (req,
SECRETS_CALLER_WIFI, NULL, NULL); setting_name,
TRUE,
SECRETS_CALLER_WIFI,
NULL,
NULL);
return FALSE; return FALSE;
} }
@@ -2495,8 +2501,12 @@ handle_auth_or_fail (NMDeviceWifi *self,
* only ask for new secrets after the first failure. * only ask for new secrets after the first failure.
*/ */
get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE); get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE);
nm_act_request_request_connection_secrets (req, setting_name, get_new, nm_act_request_get_secrets (req,
SECRETS_CALLER_WIFI, NULL, NULL); setting_name,
get_new,
SECRETS_CALLER_WIFI,
NULL,
NULL);
g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
} else { } else {
@@ -2671,10 +2681,10 @@ build_supplicant_config (NMDeviceWifi *self,
s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
if (s_wireless_sec) { if (s_wireless_sec) {
DBusGProxy *proxy = g_object_get_data (G_OBJECT (connection), NM_MANAGER_CONNECTION_PROXY_TAG);
const char *con_path = dbus_g_proxy_get_path (proxy);
NMSetting8021x *s_8021x; NMSetting8021x *s_8021x;
const char *con_path = nm_connection_get_path (connection);
g_assert (con_path);
s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
if (!nm_supplicant_config_add_setting_wireless_security (config, if (!nm_supplicant_config_add_setting_wireless_security (config,
s_wireless_sec, s_wireless_sec,
@@ -3209,6 +3219,21 @@ nm_device_wifi_dispose (GObject *object)
G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object); G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object);
} }
static gboolean
spec_match_list (NMDevice *device, const GSList *specs)
{
struct ether_addr ether;
char *hwaddr;
gboolean matched;
nm_device_wifi_get_address (NM_DEVICE_WIFI (device), &ether);
hwaddr = nm_ether_ntop (&ether);
matched = nm_match_spec_hwaddr (specs, hwaddr);
g_free (hwaddr);
return matched;
}
static void static void
get_property (GObject *object, guint prop_id, get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec) GValue *value, GParamSpec *pspec)
@@ -3237,12 +3262,33 @@ get_property (GObject *object, guint prop_id,
else else
g_value_set_boxed (value, "/"); g_value_set_boxed (value, "/");
break; break;
case PROP_IFINDEX:
g_value_set_uint (value, nm_device_wifi_get_ifindex (device));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
} }
} }
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
switch (prop_id) {
case PROP_IFINDEX:
/* construct-only */
priv->ifindex = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void static void
nm_device_wifi_class_init (NMDeviceWifiClass *klass) nm_device_wifi_class_init (NMDeviceWifiClass *klass)
{ {
@@ -3253,6 +3299,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
object_class->constructor = constructor; object_class->constructor = constructor;
object_class->get_property = get_property; object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->dispose = nm_device_wifi_dispose; object_class->dispose = nm_device_wifi_dispose;
parent_class->get_type_capabilities = real_get_type_capabilities; parent_class->get_type_capabilities = real_get_type_capabilities;
@@ -3276,6 +3323,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->deactivate = real_deactivate; parent_class->deactivate = real_deactivate;
parent_class->deactivate_quickly = real_deactivate_quickly; parent_class->deactivate_quickly = real_deactivate_quickly;
parent_class->can_interrupt_activation = real_can_interrupt_activation; parent_class->can_interrupt_activation = real_can_interrupt_activation;
parent_class->spec_match_list = spec_match_list;
/* Properties */ /* Properties */
g_object_class_install_property (object_class, PROP_HW_ADDRESS, g_object_class_install_property (object_class, PROP_HW_ADDRESS,
@@ -3315,6 +3363,13 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE,
G_PARAM_READABLE)); G_PARAM_READABLE));
g_object_class_install_property (object_class, PROP_IFINDEX,
g_param_spec_uint (NM_DEVICE_WIFI_IFINDEX,
"Ifindex",
"Interface index",
0, G_MAXUINT32, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/* Signals */ /* Signals */
signals[ACCESS_POINT_ADDED] = signals[ACCESS_POINT_ADDED] =
g_signal_new ("access-point-added", g_signal_new ("access-point-added",
@@ -3435,7 +3490,7 @@ NMDeviceWifi *
nm_device_wifi_new (const char *udi, nm_device_wifi_new (const char *udi,
const char *iface, const char *iface,
const char *driver, const char *driver,
gboolean managed) guint32 ifindex)
{ {
GObject *obj; GObject *obj;
@@ -3447,7 +3502,7 @@ nm_device_wifi_new (const char *udi,
NM_DEVICE_INTERFACE_UDI, udi, NM_DEVICE_INTERFACE_UDI, udi,
NM_DEVICE_INTERFACE_IFACE, iface, NM_DEVICE_INTERFACE_IFACE, iface,
NM_DEVICE_INTERFACE_DRIVER, driver, NM_DEVICE_INTERFACE_DRIVER, driver,
NM_DEVICE_INTERFACE_MANAGED, managed, NM_DEVICE_WIFI_IFINDEX, ifindex,
NULL); NULL);
if (obj == NULL) if (obj == NULL)
return NULL; return NULL;
@@ -3457,6 +3512,14 @@ nm_device_wifi_new (const char *udi,
return NM_DEVICE_WIFI (obj); return NM_DEVICE_WIFI (obj);
} }
guint32
nm_device_wifi_get_ifindex (NMDeviceWifi *self)
{
g_return_val_if_fail (self != NULL, FALSE);
return NM_DEVICE_WIFI_GET_PRIVATE (self)->ifindex;
}
NMAccessPoint * NMAccessPoint *
nm_device_wifi_get_activation_ap (NMDeviceWifi *self) nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
{ {

View File

@@ -42,11 +42,12 @@ G_BEGIN_DECLS
#define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) #define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass))
#define NM_DEVICE_WIFI_HW_ADDRESS "hw-address" #define NM_DEVICE_WIFI_HW_ADDRESS "hw-address"
#define NM_DEVICE_WIFI_MODE "mode" #define NM_DEVICE_WIFI_MODE "mode"
#define NM_DEVICE_WIFI_BITRATE "bitrate" #define NM_DEVICE_WIFI_BITRATE "bitrate"
#define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point" #define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point"
#define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities" #define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities"
#define NM_DEVICE_WIFI_IFINDEX "ifindex"
#ifndef NM_DEVICE_WIFI_DEFINED #ifndef NM_DEVICE_WIFI_DEFINED
#define NM_DEVICE_WIFI_DEFINED #define NM_DEVICE_WIFI_DEFINED
@@ -79,9 +80,9 @@ struct _NMDeviceWifiClass
GType nm_device_wifi_get_type (void); GType nm_device_wifi_get_type (void);
NMDeviceWifi *nm_device_wifi_new (const char *udi, NMDeviceWifi *nm_device_wifi_new (const char *udi,
const char *iface, const char *iface,
const char *driver, const char *driver,
gboolean managed); guint32 ifindex);
void nm_device_wifi_get_address (NMDeviceWifi *dev, void nm_device_wifi_get_address (NMDeviceWifi *dev,
struct ether_addr *addr); struct ether_addr *addr);
@@ -100,6 +101,8 @@ NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self);
void nm_device_wifi_set_enabled (NMDeviceWifi *self, gboolean enabled); void nm_device_wifi_set_enabled (NMDeviceWifi *self, gboolean enabled);
guint32 nm_device_wifi_get_ifindex (NMDeviceWifi *self);
G_END_DECLS G_END_DECLS
#endif /* NM_DEVICE_WIFI_H */ #endif /* NM_DEVICE_WIFI_H */

View File

@@ -66,12 +66,12 @@ struct _NMDevicePrivate
{ {
gboolean dispose_has_run; gboolean dispose_has_run;
gboolean initialized; gboolean initialized;
guint start_timer;
NMDeviceState state; NMDeviceState state;
guint failed_to_disconnected_id; guint failed_to_disconnected_id;
char * udi; char * udi;
char * path;
char * iface; /* may change, could be renamed by user */ char * iface; /* may change, could be renamed by user */
char * ip_iface; char * ip_iface;
NMDeviceType type; NMDeviceType type;
@@ -109,13 +109,13 @@ struct _NMDevicePrivate
static gboolean check_connection_compatible (NMDeviceInterface *device, static gboolean check_connection_compatible (NMDeviceInterface *device,
NMConnection *connection, NMConnection *connection,
GError **error); GError **error);
static gboolean nm_device_activate (NMDeviceInterface *device, static gboolean nm_device_activate (NMDeviceInterface *device,
NMActRequest *req, NMActRequest *req,
GError **error); GError **error);
static void nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason);
static gboolean nm_device_spec_match_list (NMDeviceInterface *device, const GSList *specs);
static void nm_device_activate_schedule_stage5_ip_config_commit (NMDevice *self); static void nm_device_activate_schedule_stage5_ip_config_commit (NMDevice *self);
static void nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason);
static void nm_device_take_down (NMDevice *dev, gboolean wait, NMDeviceStateReason reason); static void nm_device_take_down (NMDevice *dev, gboolean wait, NMDeviceStateReason reason);
@@ -131,6 +131,7 @@ device_interface_init (NMDeviceInterface *device_interface_class)
device_interface_class->check_connection_compatible = check_connection_compatible; device_interface_class->check_connection_compatible = check_connection_compatible;
device_interface_class->activate = nm_device_activate; device_interface_class->activate = nm_device_activate;
device_interface_class->deactivate = nm_device_deactivate; device_interface_class->deactivate = nm_device_deactivate;
device_interface_class->spec_match_list = nm_device_spec_match_list;
} }
@@ -144,19 +145,6 @@ nm_device_init (NMDevice * self)
self->priv->state = NM_DEVICE_STATE_UNMANAGED; self->priv->state = NM_DEVICE_STATE_UNMANAGED;
} }
static gboolean
device_start (gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
self->priv->start_timer = 0;
if (self->priv->managed)
nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
else
nm_info ("(%s): now unmanaged", nm_device_get_iface (self));
return FALSE;
}
static GObject* static GObject*
constructor (GType type, constructor (GType type,
guint n_construct_params, guint n_construct_params,
@@ -191,13 +179,10 @@ constructor (GType type,
goto error; goto error;
} }
nm_print_device_capabilities (dev); if (NM_DEVICE_GET_CLASS (dev)->update_hw_address)
NM_DEVICE_GET_CLASS (dev)->update_hw_address (dev);
/* Delay transition from UNMANAGED to UNAVAILABLE until we've given the nm_print_device_capabilities (dev);
* system settings service a chance to figure out whether the device is
* managed or not.
*/
priv->start_timer = g_timeout_add_seconds (4, device_start, dev);
priv->initialized = TRUE; priv->initialized = TRUE;
return object; return object;
@@ -224,6 +209,22 @@ real_get_generic_capabilities (NMDevice *dev)
return 0; return 0;
} }
void
nm_device_set_path (NMDevice *self, const char *path)
{
g_return_if_fail (self != NULL);
g_return_if_fail (self->priv->path == NULL);
self->priv->path = g_strdup (path);
}
const char *
nm_device_get_path (NMDevice *self)
{
g_return_val_if_fail (self != NULL, NULL);
return self->priv->path;
}
const char * const char *
nm_device_get_udi (NMDevice *self) nm_device_get_udi (NMDevice *self)
@@ -2161,11 +2162,6 @@ nm_device_dispose (GObject *object)
self->priv->dispose_has_run = TRUE; self->priv->dispose_has_run = TRUE;
if (self->priv->start_timer) {
g_source_remove (self->priv->start_timer);
self->priv->start_timer = 0;
}
if (self->priv->failed_to_disconnected_id) { if (self->priv->failed_to_disconnected_id) {
g_source_remove (self->priv->failed_to_disconnected_id); g_source_remove (self->priv->failed_to_disconnected_id);
self->priv->failed_to_disconnected_id = 0; self->priv->failed_to_disconnected_id = 0;
@@ -2497,11 +2493,6 @@ nm_device_set_managed (NMDevice *device,
priv->managed = managed; priv->managed = managed;
nm_info ("(%s): now %s", nm_device_get_iface (device), managed ? "managed" : "unmanaged"); nm_info ("(%s): now %s", nm_device_get_iface (device), managed ? "managed" : "unmanaged");
if (priv->start_timer) {
g_source_remove (priv->start_timer);
priv->start_timer = 0;
}
g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_MANAGED); g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_MANAGED);
/* If now managed, jump to unavailable */ /* If now managed, jump to unavailable */
@@ -2511,3 +2502,17 @@ nm_device_set_managed (NMDevice *device,
nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, reason); nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, reason);
} }
static gboolean
nm_device_spec_match_list (NMDeviceInterface *device, const GSList *specs)
{
NMDevice *self;
g_return_val_if_fail (device != NULL, FALSE);
self = NM_DEVICE (device);
if (NM_DEVICE_GET_CLASS (self)->spec_match_list)
return NM_DEVICE_GET_CLASS (self)->spec_match_list (self, specs);
return FALSE;
}

View File

@@ -113,11 +113,16 @@ struct _NMDeviceClass
void (* deactivate_quickly) (NMDevice *self); void (* deactivate_quickly) (NMDevice *self);
gboolean (* can_interrupt_activation) (NMDevice *self); gboolean (* can_interrupt_activation) (NMDevice *self);
gboolean (* spec_match_list) (NMDevice *self, const GSList *specs);
}; };
GType nm_device_get_type (void); GType nm_device_get_type (void);
const char * nm_device_get_path (NMDevice *dev);
void nm_device_set_path (NMDevice *dev, const char *path);
const char * nm_device_get_udi (NMDevice *dev); const char * nm_device_get_udi (NMDevice *dev);
const char * nm_device_get_iface (NMDevice *dev); const char * nm_device_get_iface (NMDevice *dev);
const char * nm_device_get_ip_iface (NMDevice *dev); const char * nm_device_get_ip_iface (NMDevice *dev);

View File

@@ -1,600 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
* Copyright (C) 2007 - 2008 Red Hat, Inc.
*/
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <libhal.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "nm-glib-compat.h"
#include "nm-hal-manager.h"
#include "nm-marshal.h"
#include "nm-dbus-manager.h"
#include "nm-utils.h"
#include "nm-device-wifi.h"
#include "nm-device-ethernet.h"
#define HAL_DBUS_SERVICE "org.freedesktop.Hal"
typedef struct {
LibHalContext *hal_ctx;
NMDBusManager *dbus_mgr;
GSList *device_creators;
gboolean disposed;
} NMHalManagerPrivate;
#define NM_HAL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_HAL_MANAGER, NMHalManagerPrivate))
G_DEFINE_TYPE (NMHalManager, nm_hal_manager, G_TYPE_OBJECT)
enum {
UDI_ADDED,
UDI_REMOVED,
HAL_REAPPEARED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
/* Device creators */
typedef struct {
GType device_type;
char *capability_str;
char *category;
gboolean (*is_device_fn) (NMHalManager *self, const char *udi);
NMDeviceCreatorFn creator_fn;
} DeviceCreator;
static DeviceCreator *
get_creator (NMHalManager *self, const char *udi)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
DeviceCreator *creator;
GSList *iter;
for (iter = priv->device_creators; iter; iter = g_slist_next (iter)) {
creator = (DeviceCreator *) iter->data;
if (libhal_device_query_capability (priv->hal_ctx, udi, creator->capability_str, NULL) &&
creator->is_device_fn (self, udi))
return creator;
}
return NULL;
}
/* end of device creators */
/* Common helpers for built-in device creators */
static char *
hal_get_subsystem (LibHalContext *ctx, const char *udi)
{
char *subsys;
subsys = libhal_device_get_property_string (ctx, udi, "info.subsystem", NULL);
if (!subsys) {
/* info.bus is deprecated */
subsys = libhal_device_get_property_string (ctx, udi, "info.bus", NULL);
}
return subsys;
}
static char *
nm_get_device_driver_name (LibHalContext *ctx, const char *origdev_udi)
{
char *driver_name = NULL, *subsystem, *drv, *od_parent = NULL;
if (!origdev_udi)
return NULL;
/* s390 driver name is on the grandparent of the net device */
subsystem = hal_get_subsystem (ctx, origdev_udi);
if (subsystem && !strcmp (subsystem, "ibmebus")) {
od_parent = libhal_device_get_property_string (ctx, origdev_udi, "info.parent", NULL);
origdev_udi = (const char *) od_parent;
}
drv = libhal_device_get_property_string (ctx, origdev_udi, "info.linux.driver", NULL);
if (drv)
driver_name = g_strdup (drv);
libhal_free_string (drv);
libhal_free_string (od_parent);
libhal_free_string (subsystem);
return driver_name;
}
/* Wired device creator */
static gboolean
is_wired_device (NMHalManager *self, const char *udi)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
char *category;
gboolean is_wired = FALSE;
if (libhal_device_property_exists (priv->hal_ctx, udi, "net.linux.ifindex", NULL) &&
libhal_device_property_exists (priv->hal_ctx, udi, "info.category", NULL)) {
category = libhal_device_get_property_string (priv->hal_ctx, udi, "info.category", NULL);
if (category) {
is_wired = strcmp (category, "net.80203") == 0;
libhal_free_string (category);
}
}
return is_wired;
}
static GObject *
wired_device_creator (NMHalManager *self,
const char *udi,
const char *origdev_udi,
gboolean managed)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
GObject *device;
char *iface;
char *driver;
iface = libhal_device_get_property_string (priv->hal_ctx, udi, "net.interface", NULL);
if (!iface) {
nm_warning ("Couldn't get interface for %s, ignoring.", udi);
return NULL;
}
driver = nm_get_device_driver_name (priv->hal_ctx, origdev_udi);
device = (GObject *) nm_device_ethernet_new (udi, iface, driver, managed);
libhal_free_string (iface);
g_free (driver);
return device;
}
/* Wireless device creator */
static gboolean
is_wireless_device (NMHalManager *self, const char *udi)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
char *category;
gboolean is_wireless = FALSE;
if (libhal_device_property_exists (priv->hal_ctx, udi, "net.linux.ifindex", NULL) &&
libhal_device_property_exists (priv->hal_ctx, udi, "info.category", NULL)) {
category = libhal_device_get_property_string (priv->hal_ctx, udi, "info.category", NULL);
if (category) {
is_wireless = strcmp (category, "net.80211") == 0;
libhal_free_string (category);
}
}
return is_wireless;
}
static GObject *
wireless_device_creator (NMHalManager *self,
const char *udi,
const char *origdev_udi,
gboolean managed)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
GObject *device;
char *iface;
char *driver;
iface = libhal_device_get_property_string (priv->hal_ctx, udi, "net.interface", NULL);
if (!iface) {
nm_warning ("Couldn't get interface for %s, ignoring.", udi);
return NULL;
}
driver = nm_get_device_driver_name (priv->hal_ctx, origdev_udi);
device = (GObject *) nm_device_wifi_new (udi, iface, driver, managed);
libhal_free_string (iface);
g_free (driver);
return device;
}
static void
register_built_in_creators (NMHalManager *self)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
DeviceCreator *creator;
/* Wired device */
creator = g_slice_new0 (DeviceCreator);
creator->device_type = NM_TYPE_DEVICE_ETHERNET;
creator->capability_str = g_strdup ("net.80203");
creator->category = g_strdup ("net");
creator->is_device_fn = is_wired_device;
creator->creator_fn = wired_device_creator;
priv->device_creators = g_slist_append (priv->device_creators, creator);
/* Wireless device */
creator = g_slice_new0 (DeviceCreator);
creator->device_type = NM_TYPE_DEVICE_WIFI;
creator->capability_str = g_strdup ("net.80211");
creator->category = g_strdup ("net");
creator->is_device_fn = is_wireless_device;
creator->creator_fn = wireless_device_creator;
priv->device_creators = g_slist_append (priv->device_creators, creator);
}
static void
emit_udi_added (NMHalManager *self, const char *udi, DeviceCreator *creator)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
char *od, *tmp;
g_return_if_fail (self != NULL);
g_return_if_fail (udi != NULL);
g_return_if_fail (creator != NULL);
tmp = g_strdup_printf ("%s.originating_device", creator->category);
od = libhal_device_get_property_string (priv->hal_ctx, udi, tmp, NULL);
g_free (tmp);
if (!od) {
/* Older HAL uses 'physical_device' */
tmp = g_strdup_printf ("%s.physical_device", creator->category);
od = libhal_device_get_property_string (priv->hal_ctx, udi, tmp, NULL);
g_free (tmp);
}
g_signal_emit (self, signals[UDI_ADDED], 0,
udi,
od,
GSIZE_TO_POINTER (creator->device_type),
creator->creator_fn);
libhal_free_string (od);
}
static void
device_added (LibHalContext *ctx, const char *udi)
{
NMHalManager *self = NM_HAL_MANAGER (libhal_ctx_get_user_data (ctx));
DeviceCreator *creator;
/* If not all the device's properties are set up yet (like net.interface),
* the device will actually get added later when HAL signals new device
* capabilties.
*/
creator = get_creator (self, udi);
if (creator)
emit_udi_added (self, udi, creator);
}
static void
device_removed (LibHalContext *ctx, const char *udi)
{
NMHalManager *self = NM_HAL_MANAGER (libhal_ctx_get_user_data (ctx));
g_signal_emit (self, signals[UDI_REMOVED], 0, udi);
}
static void
device_new_capability (LibHalContext *ctx, const char *udi, const char *capability)
{
NMHalManager *self = NM_HAL_MANAGER (libhal_ctx_get_user_data (ctx));
DeviceCreator *creator;
creator = get_creator (self, udi);
if (creator)
emit_udi_added (self, udi, creator);
}
static void
add_initial_devices (NMHalManager *self)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
DeviceCreator *creator;
GSList *iter;
char **devices;
int num_devices;
int i;
DBusError err;
for (iter = priv->device_creators; iter; iter = g_slist_next (iter)) {
creator = (DeviceCreator *) iter->data;
dbus_error_init (&err);
devices = libhal_find_device_by_capability (priv->hal_ctx,
creator->capability_str,
&num_devices,
&err);
if (dbus_error_is_set (&err)) {
nm_warning ("could not find existing devices: %s", err.message);
dbus_error_free (&err);
continue;
}
if (!devices)
continue;
for (i = 0; i < num_devices; i++) {
if (creator->is_device_fn (self, devices[i]))
emit_udi_added (self, devices[i], creator);
}
libhal_free_string_array (devices);
}
}
static gboolean
hal_init (NMHalManager *self)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
DBusError error;
DBusGConnection *connection;
priv->hal_ctx = libhal_ctx_new ();
if (!priv->hal_ctx) {
nm_warning ("Could not get connection to the HAL service.");
return FALSE;
}
connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
libhal_ctx_set_dbus_connection (priv->hal_ctx,
dbus_g_connection_get_connection (connection));
dbus_error_init (&error);
if (!libhal_ctx_init (priv->hal_ctx, &error)) {
nm_warning ("libhal_ctx_init() failed: %s\n"
"Make sure the hal daemon is running?",
error.message);
goto error;
}
libhal_ctx_set_user_data (priv->hal_ctx, self);
libhal_ctx_set_device_added (priv->hal_ctx, device_added);
libhal_ctx_set_device_removed (priv->hal_ctx, device_removed);
libhal_ctx_set_device_new_capability (priv->hal_ctx, device_new_capability);
libhal_device_property_watch_all (priv->hal_ctx, &error);
if (dbus_error_is_set (&error)) {
nm_error ("libhal_device_property_watch_all(): %s", error.message);
libhal_ctx_shutdown (priv->hal_ctx, NULL);
goto error;
}
return TRUE;
error:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
if (priv->hal_ctx) {
libhal_ctx_free (priv->hal_ctx);
priv->hal_ctx = NULL;
}
return FALSE;
}
static void
hal_deinit (NMHalManager *self)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
DBusError error;
if (!priv->hal_ctx)
return;
dbus_error_init (&error);
libhal_ctx_shutdown (priv->hal_ctx, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("libhal shutdown failed - %s", error.message);
dbus_error_free (&error);
}
libhal_ctx_free (priv->hal_ctx);
priv->hal_ctx = NULL;
}
static void
name_owner_changed (NMDBusManager *dbus_mgr,
const char *name,
const char *old,
const char *new,
gpointer user_data)
{
NMHalManager *self = NM_HAL_MANAGER (user_data);
gboolean old_owner_good = (old && (strlen (old) > 0));
gboolean new_owner_good = (new && (strlen (new) > 0));
/* Only care about signals from HAL */
if (strcmp (name, HAL_DBUS_SERVICE))
return;
if (!old_owner_good && new_owner_good) {
nm_info ("HAL re-appeared");
/* HAL just appeared */
if (!hal_init (self))
nm_warning ("Could not re-connect to HAL!!");
else
g_signal_emit (self, signals[HAL_REAPPEARED], 0);
} else if (old_owner_good && !new_owner_good) {
/* HAL went away. Bad HAL. */
nm_info ("HAL disappeared");
hal_deinit (self);
}
}
static void
connection_changed (NMDBusManager *dbus_mgr,
DBusGConnection *connection,
gpointer user_data)
{
NMHalManager *self = NM_HAL_MANAGER (user_data);
if (!connection) {
hal_deinit (self);
return;
}
if (nm_dbus_manager_name_has_owner (dbus_mgr, HAL_DBUS_SERVICE)) {
if (!hal_init (self))
nm_warning ("Could not re-connect to HAL!!");
}
}
void
nm_hal_manager_query_devices (NMHalManager *self)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
/* Find hardware we care about */
if (priv->hal_ctx)
add_initial_devices (self);
}
gboolean
nm_hal_manager_udi_exists (NMHalManager *self, const char *udi)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
return libhal_device_property_exists (priv->hal_ctx, udi, "info.udi", NULL);
}
NMHalManager *
nm_hal_manager_new (void)
{
NMHalManager *self;
NMHalManagerPrivate *priv;
self = NM_HAL_MANAGER (g_object_new (NM_TYPE_HAL_MANAGER, NULL));
priv = NM_HAL_MANAGER_GET_PRIVATE (self);
if (!nm_dbus_manager_name_has_owner (priv->dbus_mgr, HAL_DBUS_SERVICE)) {
nm_info ("Waiting for HAL to start...");
return self;
}
if (!hal_init (self)) {
g_object_unref (self);
self = NULL;
}
return self;
}
static void
nm_hal_manager_init (NMHalManager *self)
{
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
priv->dbus_mgr = nm_dbus_manager_get ();
register_built_in_creators (self);
g_signal_connect (priv->dbus_mgr,
"name-owner-changed",
G_CALLBACK (name_owner_changed),
self);
g_signal_connect (priv->dbus_mgr,
"dbus-connection-changed",
G_CALLBACK (connection_changed),
self);
}
static void
destroy_creator (gpointer data, gpointer user_data)
{
DeviceCreator *creator = (DeviceCreator *) data;
g_free (creator->capability_str);
g_free (creator->category);
g_slice_free (DeviceCreator, data);
}
static void
dispose (GObject *object)
{
NMHalManager *self = NM_HAL_MANAGER (object);
NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
if (priv->disposed) {
G_OBJECT_CLASS (nm_hal_manager_parent_class)->dispose (object);
return;
}
priv->disposed = TRUE;
g_object_unref (priv->dbus_mgr);
g_slist_foreach (priv->device_creators, destroy_creator, NULL);
g_slist_free (priv->device_creators);
hal_deinit (self);
G_OBJECT_CLASS (nm_hal_manager_parent_class)->dispose (object);
}
static void
nm_hal_manager_class_init (NMHalManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (NMHalManagerPrivate));
/* virtual methods */
object_class->dispose = dispose;
/* Signals */
signals[UDI_ADDED] =
g_signal_new ("udi-added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMHalManagerClass, udi_added),
NULL, NULL,
_nm_marshal_VOID__STRING_STRING_POINTER_POINTER,
G_TYPE_NONE, 4,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER);
signals[UDI_REMOVED] =
g_signal_new ("udi-removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMHalManagerClass, udi_removed),
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1,
G_TYPE_STRING);
signals[HAL_REAPPEARED] =
g_signal_new ("hal-reappeared",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMHalManagerClass, hal_reappeared),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}

View File

@@ -1,67 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
* Copyright (C) 2007 - 2008 Red Hat, Inc.
*/
#ifndef NM_HAL_MANAGER_H
#define NM_HAL_MANAGER_H
#include <glib.h>
#include <glib-object.h>
G_BEGIN_DECLS
#define NM_TYPE_HAL_MANAGER (nm_hal_manager_get_type ())
#define NM_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_HAL_MANAGER, NMHalManager))
#define NM_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_HAL_MANAGER, NMHalManagerClass))
#define NM_IS_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_HAL_MANAGER))
#define NM_IS_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_HAL_MANAGER))
#define NM_HAL_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_HAL_MANAGER, NMHalManagerClass))
typedef struct {
GObject parent;
} NMHalManager;
typedef GObject *(*NMDeviceCreatorFn) (NMHalManager *manager,
const char *udi,
const char *origdev_udi,
gboolean managed);
typedef struct {
GObjectClass parent;
/* Virtual functions */
void (*udi_added) (NMHalManager *manager,
const char *udi,
const char *originating_device,
gpointer general_device_type,
NMDeviceCreatorFn creator_fn);
void (*udi_removed) (NMHalManager *manager, const char *udi);
void (*hal_reappeared) (NMHalManager *manager);
} NMHalManagerClass;
GType nm_hal_manager_get_type (void);
NMHalManager *nm_hal_manager_new (void);
void nm_hal_manager_query_devices (NMHalManager *manager);
gboolean nm_hal_manager_udi_exists (NMHalManager *manager, const char *udi);
#endif /* NM_HAL_MANAGER_H */

File diff suppressed because it is too large Load Diff

View File

@@ -43,9 +43,6 @@
/* Not exported */ /* Not exported */
#define NM_MANAGER_HOSTNAME "hostname" #define NM_MANAGER_HOSTNAME "hostname"
#define NM_MANAGER_CONNECTION_PROXY_TAG "dbus-proxy"
#define NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG "dbus-secrets-proxy"
typedef struct { typedef struct {
GObject parent; GObject parent;
} NMManager; } NMManager;
@@ -76,7 +73,9 @@ typedef struct {
GType nm_manager_get_type (void); GType nm_manager_get_type (void);
NMManager *nm_manager_get (void); NMManager *nm_manager_get (const char *plugins, GError **error);
void nm_manager_start (NMManager *manager);
/* Device handling */ /* Device handling */

View File

@@ -0,0 +1,224 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 Red Hat, Inc.
*/
#include <string.h>
#include "nm-marshal.h"
#include "nm-secrets-provider-interface.h"
#include <nm-setting-8021x.h>
#include <nm-setting-wireless-security.h>
#include "nm-utils.h"
static void
nm_secrets_provider_interface_init (gpointer g_iface)
{
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
static gboolean initialized = FALSE;
if (initialized)
return;
initialized = TRUE;
/* Signals */
g_signal_new ("manager-get-secrets",
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_get_secrets),
NULL, NULL,
_nm_marshal_BOOLEAN__POINTER_STRING_BOOLEAN_UINT_STRING_STRING,
G_TYPE_BOOLEAN, 6,
G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
g_signal_new ("manager-cancel-secrets",
iface_type,
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_cancel_secrets),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
GType
nm_secrets_provider_interface_get_type (void)
{
static GType interface_type = 0;
if (!interface_type) {
const GTypeInfo interface_info = {
sizeof (NMSecretsProviderInterface), /* class_size */
nm_secrets_provider_interface_init, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
0,
0, /* n_preallocs */
NULL
};
interface_type = g_type_register_static (G_TYPE_INTERFACE,
"NMSecretsProviderInterface",
&interface_info, 0);
g_type_interface_add_prerequisite (interface_type, G_TYPE_OBJECT);
}
return interface_type;
}
gboolean
nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self,
NMConnection *connection,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2)
{
guint success = FALSE;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self), FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
g_return_val_if_fail (setting_name != NULL, FALSE);
nm_secrets_provider_interface_cancel_get_secrets (self);
g_signal_emit_by_name (self, "manager-get-secrets",
connection, setting_name, request_new, caller, hint1, hint2,
&success);
if (!success) {
nm_warning ("failed to get connection secrets.");
return FALSE;
}
return TRUE;
}
void
nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self)
{
g_return_if_fail (self != NULL);
g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self));
g_signal_emit_by_name (self, "manager-cancel-secrets");
}
static void
add_one_key_to_list (gpointer key, gpointer data, gpointer user_data)
{
GSList **list = (GSList **) user_data;
*list = g_slist_append (*list, key);
}
static gint
settings_order_func (gconstpointer a, gconstpointer b)
{
/* Just ensure the 802.1x setting gets processed _before_ the
* wireless-security one.
*/
if ( !strcmp (a, NM_SETTING_802_1X_SETTING_NAME)
&& !strcmp (b, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME))
return -1;
if ( !strcmp (a, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)
&& !strcmp (b, NM_SETTING_802_1X_SETTING_NAME))
return 1;
return 0;
}
void
nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self,
const char *setting_name,
RequestSecretsCaller caller,
GHashTable *settings,
GError *error)
{
GSList *keys = NULL, *iter;
GSList *updated = NULL;
GError *tmp_error = NULL;
g_return_if_fail (self != NULL);
g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self));
if (error) {
NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
setting_name,
caller,
NULL,
error);
return;
}
if (g_hash_table_size (settings) == 0) {
g_set_error (&tmp_error, 0, 0, "%s", "no secrets were received!");
NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
setting_name,
caller,
NULL,
tmp_error);
g_clear_error (&tmp_error);
return;
}
g_hash_table_foreach (settings, add_one_key_to_list, &keys);
keys = g_slist_sort (keys, settings_order_func);
for (iter = keys; iter; iter = g_slist_next (iter)) {
GHashTable *hash;
const char *name = (const char *) iter->data;
hash = g_hash_table_lookup (settings, name);
if (!hash) {
nm_warning ("couldn't get setting secrets for '%s'", name);
continue;
}
if (NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->update_setting (self, name, hash))
updated = g_slist_append (updated, (gpointer) setting_name);
}
g_slist_free (keys);
if (g_slist_length (updated)) {
NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
setting_name,
caller,
updated,
NULL);
} else {
g_set_error (&tmp_error, 0, 0, "%s", "no secrets updated because no valid "
"settings were received!");
NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
setting_name,
caller,
NULL,
tmp_error);
g_clear_error (&tmp_error);
}
g_slist_free (updated);
}

View File

@@ -0,0 +1,91 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 Red Hat, Inc.
*/
#ifndef NM_SECRETS_PROVIDER_INTERFACE_H
#define NM_SECRETS_PROVIDER_INTERFACE_H
#include <glib-object.h>
#include <nm-connection.h>
typedef enum {
SECRETS_CALLER_NONE = 0,
SECRETS_CALLER_ETHERNET,
SECRETS_CALLER_WIFI,
SECRETS_CALLER_GSM,
SECRETS_CALLER_CDMA,
SECRETS_CALLER_PPP,
SECRETS_CALLER_VPN
} RequestSecretsCaller;
#define NM_TYPE_SECRETS_PROVIDER_INTERFACE (nm_secrets_provider_interface_get_type ())
#define NM_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface))
#define NM_IS_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE))
#define NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface))
typedef struct _NMSecretsProviderInterface NMSecretsProviderInterface;
struct _NMSecretsProviderInterface {
GTypeInterface g_iface;
/* Methods */
void (*result) (NMSecretsProviderInterface *self,
const char *setting_name,
RequestSecretsCaller caller,
const GSList *updated,
GError *error);
gboolean (*update_setting) (NMSecretsProviderInterface *self,
const char *setting_name,
GHashTable *new);
/* Signals */
void (*manager_get_secrets) (NMSecretsProviderInterface *self,
NMConnection *connection,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2);
void (*manager_cancel_secrets) (NMSecretsProviderInterface *self);
};
GType nm_secrets_provider_interface_get_type (void);
/* For callers */
gboolean nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self,
NMConnection *connection,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2);
void nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self);
/* For NMManager */
void nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self,
const char *setting_name,
RequestSecretsCaller caller,
GHashTable *settings,
GError *error);
#endif /* NM_SECRETS_PROVIDER_INTERFACE_H */

View File

@@ -21,6 +21,12 @@
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "wireless-helper.h"
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE #define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h> #include <gudev/gudev.h>
@@ -28,12 +34,14 @@
#include "nm-udev-manager.h" #include "nm-udev-manager.h"
#include "nm-marshal.h" #include "nm-marshal.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "NetworkManagerUtils.h"
#include "nm-device-wifi.h"
#include "nm-device-ethernet.h"
typedef struct { typedef struct {
GUdevClient *client; GUdevClient *client;
/* Authoritative rfkill state (RFKILL_* enum) /* Authoritative rfkill state (RFKILL_* enum) */
*/
RfKillState rfkill_state; RfKillState rfkill_state;
GSList *killswitches; GSList *killswitches;
@@ -45,6 +53,8 @@ typedef struct {
G_DEFINE_TYPE (NMUdevManager, nm_udev_manager, G_TYPE_OBJECT) G_DEFINE_TYPE (NMUdevManager, nm_udev_manager, G_TYPE_OBJECT)
enum { enum {
DEVICE_ADDED,
DEVICE_REMOVED,
RFKILL_CHANGED, RFKILL_CHANGED,
LAST_SIGNAL LAST_SIGNAL
@@ -197,6 +207,161 @@ add_one_killswitch (NMUdevManager *self, GUdevDevice *device)
ks->driver ? ks->driver : "<unknown>"); ks->driver ? ks->driver : "<unknown>");
} }
static void
rfkill_add (NMUdevManager *self, GUdevDevice *device)
{
const char *name;
g_return_if_fail (device != NULL);
name = g_udev_device_get_name (device);
g_return_if_fail (name != NULL);
if (!killswitch_find_by_name (self, name))
add_one_killswitch (self, device);
}
static void
rfkill_remove (NMUdevManager *self,
GUdevDevice *device)
{
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
GSList *iter;
const char *name;
g_return_if_fail (device != NULL);
name = g_udev_device_get_name (device);
g_return_if_fail (name != NULL);
for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) {
Killswitch *ks = iter->data;
if (!strcmp (ks->name, name)) {
nm_info ("Radio killswitch %s disappeared", ks->path);
priv->killswitches = g_slist_remove (priv->killswitches, iter);
killswitch_destroy (iter->data);
g_slist_free (iter);
break;
}
}
}
static gboolean
is_wireless (GUdevDevice *device)
{
char phy80211_path[255];
struct stat s;
int fd;
struct iwreq iwr;
const char *ifname, *path;
gboolean is_wifi = FALSE;
ifname = g_udev_device_get_name (device);
g_assert (ifname);
fd = socket (PF_INET, SOCK_DGRAM, 0);
strncpy (iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ);
path = g_udev_device_get_sysfs_path (device);
snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", path);
if ( (ioctl (fd, SIOCGIWNAME, &iwr) == 0)
|| (stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR)))
is_wifi = TRUE;
close (fd);
return is_wifi;
}
static GObject *
device_creator (NMUdevManager *manager,
GUdevDevice *udev_device,
gboolean sleeping)
{
GObject *device = NULL;
const char *ifname, *driver, *path;
GUdevDevice *parent;
gint ifindex;
ifname = g_udev_device_get_name (udev_device);
g_assert (ifname);
path = g_udev_device_get_sysfs_path (udev_device);
if (!path) {
nm_warning ("couldn't determine device path; ignoring...");
return NULL;
}
driver = g_udev_device_get_driver (udev_device);
if (!driver) {
/* Try the parent */
parent = g_udev_device_get_parent (udev_device);
if (parent) {
driver = g_udev_device_get_driver (parent);
g_object_unref (parent);
}
}
if (!driver) {
nm_warning ("%s: couldn't determine device driver; ignoring...", path);
return NULL;
}
ifindex = g_udev_device_get_sysfs_attr_as_int (udev_device, "ifindex");
if (ifindex <= 0) {
nm_warning ("%s: device had invalid ifindex %d; ignoring...", path, (guint32) ifindex);
return NULL;
}
if (is_wireless (udev_device))
device = (GObject *) nm_device_wifi_new (path, ifname, driver, ifindex);
else
device = (GObject *) nm_device_ethernet_new (path, ifname, driver, ifindex);
return device;
}
static void
net_add (NMUdevManager *self, GUdevDevice *device)
{
gint devtype;
const char *iface;
g_return_if_fail (device != NULL);
devtype = g_udev_device_get_sysfs_attr_as_int (device, "type");
if (devtype != 1)
return; /* Not using ethernet encapsulation, don't care */
iface = g_udev_device_get_name (device);
if (!iface)
return;
g_signal_emit (self, signals[DEVICE_ADDED], 0, device, device_creator);
}
static void
net_remove (NMUdevManager *self, GUdevDevice *device)
{
g_signal_emit (self, signals[DEVICE_REMOVED], 0, device);
}
void
nm_udev_manager_query_devices (NMUdevManager *self)
{
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
GList *devices, *iter;
g_return_if_fail (self != NULL);
g_return_if_fail (NM_IS_UDEV_MANAGER (self));
devices = g_udev_client_query_by_subsystem (priv->client, "net");
for (iter = devices; iter; iter = g_list_next (iter)) {
net_add (self, G_UDEV_DEVICE (iter->data));
g_object_unref (G_UDEV_DEVICE (iter->data));
}
g_list_free (devices);
}
static void static void
handle_uevent (GUdevClient *client, handle_uevent (GUdevClient *client,
const char *action, const char *action,
@@ -204,39 +369,28 @@ handle_uevent (GUdevClient *client,
gpointer user_data) gpointer user_data)
{ {
NMUdevManager *self = NM_UDEV_MANAGER (user_data); NMUdevManager *self = NM_UDEV_MANAGER (user_data);
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self); const char *subsys;
const char *name, *subsys;
g_return_if_fail (action != NULL); g_return_if_fail (action != NULL);
name = g_udev_device_get_name (device);
g_return_if_fail (name != NULL);
/* A bit paranoid */ /* A bit paranoid */
subsys = g_udev_device_get_subsystem (device); subsys = g_udev_device_get_subsystem (device);
g_return_if_fail (subsys && !strcmp (subsys, "rfkill")); g_return_if_fail (subsys != NULL);
g_return_if_fail (!strcmp (subsys, "rfkill") || !strcmp (subsys, "net"));
if (!strcmp (action, "add")) { if (!strcmp (action, "add")) {
if (!killswitch_find_by_name (self, name)) if (!strcmp (subsys, "rfkill"))
add_one_killswitch (self, device); rfkill_add (self, device);
else if (!strcmp (subsys, "net"))
net_add (self, device);
} else if (!strcmp (action, "remove")) { } else if (!strcmp (action, "remove")) {
GSList *iter; if (!strcmp (subsys, "rfkill"))
rfkill_remove (self, device);
for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) { else if (!strcmp (subsys, "net"))
Killswitch *ks = iter->data; net_remove (self, device);
if (!strcmp (ks->name, name)) {
nm_info ("Radio killswitch %s disappeared", ks->path);
priv->killswitches = g_slist_remove (priv->killswitches, iter);
killswitch_destroy (iter->data);
g_slist_free (iter);
break;
}
}
} }
// FIXME: check sequence #s to ensure events don't arrive out of order
recheck_killswitches (self); recheck_killswitches (self);
} }
@@ -244,7 +398,7 @@ static void
nm_udev_manager_init (NMUdevManager *self) nm_udev_manager_init (NMUdevManager *self)
{ {
NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self); NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
const char *subsys[2] = { "rfkill", NULL }; const char *subsys[3] = { "rfkill", "net", NULL };
GList *switches, *iter; GList *switches, *iter;
priv->rfkill_state = RFKILL_UNBLOCKED; priv->rfkill_state = RFKILL_UNBLOCKED;
@@ -292,6 +446,24 @@ nm_udev_manager_class_init (NMUdevManagerClass *klass)
object_class->dispose = dispose; object_class->dispose = dispose;
/* Signals */ /* Signals */
signals[DEVICE_ADDED] =
g_signal_new ("device-added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMUdevManagerClass, device_added),
NULL, NULL,
_nm_marshal_VOID__POINTER_POINTER,
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
signals[DEVICE_REMOVED] =
g_signal_new ("device-removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMUdevManagerClass, device_removed),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
signals[RFKILL_CHANGED] = signals[RFKILL_CHANGED] =
g_signal_new ("rfkill-changed", g_signal_new ("rfkill-changed",
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),

View File

@@ -25,6 +25,9 @@
#include <glib.h> #include <glib.h>
#include <glib-object.h> #include <glib-object.h>
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h>
typedef enum { typedef enum {
RFKILL_UNBLOCKED = 0, RFKILL_UNBLOCKED = 0,
RFKILL_SOFT_BLOCKED = 1, RFKILL_SOFT_BLOCKED = 1,
@@ -44,16 +47,30 @@ typedef struct {
GObject parent; GObject parent;
} NMUdevManager; } NMUdevManager;
typedef GObject *(*NMDeviceCreatorFn) (NMUdevManager *manager,
GUdevDevice *device,
gboolean sleeping);
typedef struct { typedef struct {
GObjectClass parent; GObjectClass parent;
/* Virtual functions */ /* Virtual functions */
void (*device_added) (NMUdevManager *manager,
GUdevDevice *device,
NMDeviceCreatorFn creator_fn);
void (*device_removed) (NMUdevManager *manager, GUdevDevice *device);
void (*rfkill_changed) (NMUdevManager *manager, RfKillState state); void (*rfkill_changed) (NMUdevManager *manager, RfKillState state);
} NMUdevManagerClass; } NMUdevManagerClass;
GType nm_udev_manager_get_type (void); GType nm_udev_manager_get_type (void);
NMUdevManager *nm_udev_manager_new (void); NMUdevManager *nm_udev_manager_new (void);
void nm_udev_manager_query_devices (NMUdevManager *manager);
RfKillState nm_udev_manager_get_rfkill_state (NMUdevManager *manager); RfKillState nm_udev_manager_get_rfkill_state (NMUdevManager *manager);
#endif /* NM_UDEV_MANAGER_H */ #endif /* NM_UDEV_MANAGER_H */

View File

@@ -408,12 +408,12 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager,
* servers (T-Mobile USA) appear to ask a few times when they actually don't * servers (T-Mobile USA) appear to ask a few times when they actually don't
* even care what you pass back. * even care what you pass back.
*/ */
nm_act_request_request_connection_secrets (priv->act_req, nm_act_request_get_secrets (priv->act_req,
setting_name, setting_name,
tries > 1 ? TRUE : FALSE, tries > 1 ? TRUE : FALSE,
SECRETS_CALLER_PPP, SECRETS_CALLER_PPP,
hint1, hint1,
hint2); hint2);
g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, GUINT_TO_POINTER (++tries)); g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, GUINT_TO_POINTER (++tries));
priv->pending_secrets_context = context; priv->pending_secrets_context = context;

View File

@@ -2,17 +2,17 @@ INCLUDES = -I${top_srcdir} \
-I${top_srcdir}/include \ -I${top_srcdir}/include \
-I${top_srcdir}/libnm-util \ -I${top_srcdir}/libnm-util \
-I${top_srcdir}/libnm-glib \ -I${top_srcdir}/libnm-glib \
-I${top_srcdir}/src \
-I${top_builddir}/marshallers -I${top_builddir}/marshallers
sbin_PROGRAMS = nm-system-settings noinst_LTLIBRARIES = libsystem-settings.la
BUILT_SOURCES = \ BUILT_SOURCES = \
nm-settings-system-glue.h nm-settings-system-glue.h
nm_system_settings_SOURCES = \ libsystem_settings_la_SOURCES = \
dbus-settings.c \ nm-sysconfig-settings.c \
dbus-settings.h \ nm-sysconfig-settings.h \
main.c \
nm-inotify-helper.c \ nm-inotify-helper.c \
nm-inotify-helper.h \ nm-inotify-helper.h \
nm-polkit-helpers.c \ nm-polkit-helpers.c \
@@ -21,14 +21,12 @@ nm_system_settings_SOURCES = \
nm-system-config-error.h \ nm-system-config-error.h \
nm-system-config-interface.c \ nm-system-config-interface.c \
nm-system-config-interface.h \ nm-system-config-interface.h \
nm-system-config-hal-manager.c \
nm-system-config-hal-manager.h \
nm-sysconfig-connection.c \ nm-sysconfig-connection.c \
nm-sysconfig-connection.h \ nm-sysconfig-connection.h \
nm-default-wired-connection.c \ nm-default-wired-connection.c \
nm-default-wired-connection.h nm-default-wired-connection.h
nm_system_settings_CPPFLAGS = \ libsystem_settings_la_CPPFLAGS = \
$(DBUS_CFLAGS) \ $(DBUS_CFLAGS) \
$(GLIB_CFLAGS) \ $(GLIB_CFLAGS) \
$(GMODULE_CFLAGS) \ $(GMODULE_CFLAGS) \
@@ -43,7 +41,7 @@ nm_system_settings_CPPFLAGS = \
-DGNOMELOCALEDIR=\"$(datadir)/locale\" \ -DGNOMELOCALEDIR=\"$(datadir)/locale\" \
-DPLUGINDIR=\"$(pkglibdir)\" -DPLUGINDIR=\"$(pkglibdir)\"
nm_system_settings_LDADD = \ libsystem_settings_la_LIBADD = \
$(DBUS_LIBS) \ $(DBUS_LIBS) \
$(GLIB_LIBS) \ $(GLIB_LIBS) \
$(GMODULE_LIBS) \ $(GMODULE_LIBS) \
@@ -52,33 +50,11 @@ nm_system_settings_LDADD = \
$(top_builddir)/libnm-glib/libnm_glib.la \ $(top_builddir)/libnm-glib/libnm_glib.la \
$(top_builddir)/marshallers/libmarshallers.la $(top_builddir)/marshallers/libmarshallers.la
nm_system_settings_LDFLAGS = -rdynamic libsystem_settings_la_LDFLAGS = -rdynamic
nm-settings-system-glue.h: $(top_srcdir)/introspection/nm-settings-system.xml nm-settings-system-glue.h: $(top_srcdir)/introspection/nm-settings-system.xml
dbus-binding-tool --prefix=nm_settings_system --mode=glib-server --output=$@ $< dbus-binding-tool --prefix=nm_settings_system --mode=glib-server --output=$@ $<
dbusservicedir = $(DBUS_SYS_DIR)
dbusservice_DATA = nm-system-settings.conf
dbusactivationdir = $(datadir)/dbus-1/system-services
dbusactivation_in_files = org.freedesktop.NetworkManagerSystemSettings.service.in
dbusactivation_DATA = $(dbusactivation_in_files:.service.in=.service)
%service: %service.in
$(edit) $< >$@
edit = @sed \
-e 's|@sbindir[@]|$(sbindir)|g' \
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
-e 's|@localstatedir[@]|$(localstatedir)|g' \
-e 's|@libexecdir[@]|$(libexecdir)|g'
EXTRA_DIST = \
$(dbusservice_DATA) \
$(dbusactivation_in_files)
CLEANFILES = \ CLEANFILES = \
$(BUILT_SOURCES) \ $(BUILT_SOURCES)
$(dbusactivation_DATA)

View File

@@ -26,7 +26,9 @@
G_DEFINE_ABSTRACT_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_EXPORTED_CONNECTION) G_DEFINE_ABSTRACT_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_EXPORTED_CONNECTION)
#define NM_SYSCONFIG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionPrivate)) #define NM_SYSCONFIG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SYSCONFIG_CONNECTION, \
NMSysconfigConnectionPrivate))
typedef struct { typedef struct {
DBusGConnection *dbus_connection; DBusGConnection *dbus_connection;
@@ -116,12 +118,12 @@ destroy_gvalue (gpointer data)
g_slice_free (GValue, value); g_slice_free (GValue, value);
} }
static GHashTable * GHashTable *
real_get_secrets (NMSysconfigConnection *self, nm_sysconfig_connection_get_secrets (NMSysconfigConnection *self,
const gchar *setting_name, const gchar *setting_name,
const gchar **hints, const gchar **hints,
gboolean request_new, gboolean request_new,
GError **error) GError **error)
{ {
NMConnection *connection; NMConnection *connection;
GHashTable *settings = NULL; GHashTable *settings = NULL;
@@ -208,7 +210,7 @@ get_unix_user_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
goto error; goto error;
} }
secrets = real_get_secrets (self, info->setting_name, NULL, FALSE, &error); secrets = nm_sysconfig_connection_get_secrets (self, info->setting_name, NULL, FALSE, &error);
if (secrets) { if (secrets) {
/* success; return secrets to caller */ /* success; return secrets to caller */
dbus_g_method_return (info->context, secrets); dbus_g_method_return (info->context, secrets);

View File

@@ -42,6 +42,13 @@ typedef struct {
GType nm_sysconfig_connection_get_type (void); GType nm_sysconfig_connection_get_type (void);
/* Only for internal NM usage */
GHashTable *nm_sysconfig_connection_get_secrets (NMSysconfigConnection *self,
const gchar *setting_name,
const gchar **hints,
gboolean request_new,
GError **error);
G_END_DECLS G_END_DECLS
#endif /* NM_SYSCONFIG_CONNECTION_H */ #endif /* NM_SYSCONFIG_CONNECTION_H */

View File

@@ -25,6 +25,7 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <gmodule.h>
#include <NetworkManager.h> #include <NetworkManager.h>
#include <nm-connection.h> #include <nm-connection.h>
@@ -32,11 +33,27 @@
#include <nm-setting-connection.h> #include <nm-setting-connection.h>
#include "nm-dbus-glib-types.h" #include "nm-dbus-glib-types.h"
#include "dbus-settings.h" #include "nm-sysconfig-settings.h"
#include "nm-sysconfig-connection.h"
#include "nm-dbus-manager.h"
#include "nm-polkit-helpers.h" #include "nm-polkit-helpers.h"
#include "nm-system-config-error.h" #include "nm-system-config-error.h"
#include "nm-utils.h" #include "nm-utils.h"
/* LINKER CRACKROCK */
#define EXPORT(sym) void * __export_##sym = &sym;
#include "nm-inotify-helper.h"
EXPORT(nm_inotify_helper_get_type)
EXPORT(nm_inotify_helper_get)
EXPORT(nm_inotify_helper_add_watch)
EXPORT(nm_inotify_helper_remove_watch)
EXPORT(nm_sysconfig_connection_get_type)
/* END LINKER CRACKROCK */
static gboolean static gboolean
impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, DBusGMethodInvocation *context); impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, DBusGMethodInvocation *context);
@@ -48,14 +65,13 @@ impl_settings_save_hostname (NMSysconfigSettings *self, const char *hostname, DB
static void unmanaged_devices_changed (NMSystemConfigInterface *config, gpointer user_data); static void unmanaged_devices_changed (NMSystemConfigInterface *config, gpointer user_data);
typedef struct { typedef struct {
DBusGConnection *g_connection; NMDBusManager *dbus_mgr;
PolKitContext *pol_ctx; PolKitContext *pol_ctx;
NMSystemConfigHalManager *hal_mgr;
GSList *plugins; GSList *plugins;
gboolean connections_loaded; gboolean connections_loaded;
GHashTable *connections; GHashTable *connections;
GHashTable *unmanaged_devices; GSList *unmanaged_specs;
char *orig_hostname; char *orig_hostname;
} NMSysconfigSettingsPrivate; } NMSysconfigSettingsPrivate;
@@ -73,7 +89,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum { enum {
PROP_0, PROP_0,
PROP_UNMANAGED_DEVICES, PROP_UNMANAGED_SPECS,
PROP_HOSTNAME, PROP_HOSTNAME,
PROP_CAN_MODIFY, PROP_CAN_MODIFY,
@@ -120,10 +136,9 @@ hash_keys_to_slist (gpointer key, gpointer val, gpointer user_data)
*list = g_slist_prepend (*list, key); *list = g_slist_prepend (*list, key);
} }
static GSList * GSList *
list_connections (NMSettings *settings) nm_sysconfig_settings_list_connections (NMSysconfigSettings *self)
{ {
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (settings);
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GSList *list = NULL; GSList *list = NULL;
@@ -134,14 +149,68 @@ list_connections (NMSettings *settings)
return list; return list;
} }
static GSList *
list_connections (NMSettings *settings)
{
return nm_sysconfig_settings_list_connections (NM_SYSCONFIG_SETTINGS (settings));
}
typedef struct {
const char *path;
NMSysconfigConnection *found;
} FindConnectionInfo;
static void static void
settings_finalize (GObject *object) find_by_path (gpointer key, gpointer data, gpointer user_data)
{
FindConnectionInfo *info = user_data;
NMSysconfigConnection *exported = NM_SYSCONFIG_CONNECTION (data);
const char *path;
if (!info->found) {
NMConnection *connection;
connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (exported));
g_assert (connection);
path = nm_connection_get_path (connection);
g_assert (path);
if (!strcmp (path, info->path))
info->found = exported;
}
}
NMSysconfigConnection *
nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self,
const char *path)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
FindConnectionInfo info;
info.path = path;
info.found = NULL;
g_hash_table_foreach (priv->connections, find_by_path, &info);
return info.found;
}
static void
clear_unmanaged_specs (NMSysconfigSettings *self)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
g_slist_foreach (priv->unmanaged_specs, (GFunc) g_free, NULL);
g_slist_free (priv->unmanaged_specs);
priv->unmanaged_specs = NULL;
}
static void
finalize (GObject *object)
{ {
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
g_hash_table_destroy (priv->connections); g_hash_table_destroy (priv->connections);
g_hash_table_destroy (priv->unmanaged_devices);
clear_unmanaged_specs (self);
g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL); g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
g_slist_free (priv->plugins); g_slist_free (priv->plugins);
@@ -149,22 +218,13 @@ settings_finalize (GObject *object)
if (priv->pol_ctx) if (priv->pol_ctx)
polkit_context_unref (priv->pol_ctx); polkit_context_unref (priv->pol_ctx);
g_object_unref (priv->hal_mgr); g_object_unref (priv->dbus_mgr);
dbus_g_connection_unref (priv->g_connection);
g_free (priv->orig_hostname); g_free (priv->orig_hostname);
G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object); G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object);
} }
static void
add_one_unmanaged_device (gpointer key, gpointer data, gpointer user_data)
{
GPtrArray *devices = (GPtrArray *) user_data;
g_ptr_array_add (devices, g_strdup (key));
}
static char* static char*
uscore_to_wincaps (const char *uscore) uscore_to_wincaps (const char *uscore)
{ {
@@ -210,17 +270,13 @@ notify (GObject *object, GParamSpec *pspec)
g_slice_free (GValue, value); g_slice_free (GValue, value);
} }
static GPtrArray * const GSList *
get_unmanaged_devices (NMSysconfigSettings *self) nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self)
{ {
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GPtrArray *devices;
load_connections (self); load_connections (self);
return priv->unmanaged_specs;
devices = g_ptr_array_sized_new (3);
g_hash_table_foreach (priv->unmanaged_devices, (GHFunc) add_one_unmanaged_device, devices);
return devices;
} }
NMSystemConfigInterface * NMSystemConfigInterface *
@@ -244,41 +300,52 @@ nm_sysconfig_settings_get_plugin (NMSysconfigSettings *self,
return NULL; return NULL;
} }
char *
nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GSList *iter;
char *hostname = NULL;
/* Hostname returned is the hostname returned from the first plugin
* that provides one.
*/
for (iter = priv->plugins; iter; iter = iter->next) {
NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL);
if (hostname && strlen (hostname))
return hostname;
g_free (hostname);
}
}
/* If no plugin provided a hostname, try the original hostname of the machine */
if (priv->orig_hostname)
hostname = g_strdup (priv->orig_hostname);
return hostname;
}
static void static void
get_property (GObject *object, guint prop_id, get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec) GValue *value, GParamSpec *pspec)
{ {
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); const GSList *specs, *iter;
GSList *iter; GSList *copy = NULL;
switch (prop_id) { switch (prop_id) {
case PROP_UNMANAGED_DEVICES: case PROP_UNMANAGED_SPECS:
g_value_take_boxed (value, get_unmanaged_devices (self)); specs = nm_sysconfig_settings_get_unmanaged_specs (self);
for (iter = specs; iter; iter = g_slist_next (iter))
copy = g_slist_append (copy, g_strdup (iter->data));
g_value_take_boxed (value, copy);
break; break;
case PROP_HOSTNAME: case PROP_HOSTNAME:
/* Hostname returned is the hostname returned from the first plugin g_value_take_string (value, nm_sysconfig_settings_get_hostname (self));
* that provides one.
*/
for (iter = priv->plugins; iter; iter = iter->next) {
NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
char *hostname = NULL;
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL);
if (hostname && strlen (hostname)) {
g_value_take_string (value, hostname);
break;
}
}
}
/* If no plugin provided a hostname, try the original hostname of the machine */
if (!g_value_get_string (value) && priv->orig_hostname)
g_value_set_string (value, priv->orig_hostname);
/* Don't ever pass NULL through D-Bus */ /* Don't ever pass NULL through D-Bus */
if (!g_value_get_string (value)) if (!g_value_get_string (value))
@@ -304,16 +371,16 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class)
/* virtual methods */ /* virtual methods */
object_class->notify = notify; object_class->notify = notify;
object_class->get_property = get_property; object_class->get_property = get_property;
object_class->finalize = settings_finalize; object_class->finalize = finalize;
settings_class->list_connections = list_connections; settings_class->list_connections = list_connections;
/* properties */ /* properties */
g_object_class_install_property g_object_class_install_property
(object_class, PROP_UNMANAGED_DEVICES, (object_class, PROP_UNMANAGED_SPECS,
g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES, g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS,
"Unamanged devices", "Unamanged device specs",
"Unmanaged devices", "Unmanaged device specs",
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, DBUS_TYPE_G_LIST_OF_STRING,
G_PARAM_READABLE)); G_PARAM_READABLE));
g_object_class_install_property g_object_class_install_property
@@ -358,7 +425,6 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self)
GError *error = NULL; GError *error = NULL;
priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
priv->unmanaged_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
priv->pol_ctx = create_polkit_context (&error); priv->pol_ctx = create_polkit_context (&error);
if (!priv->pol_ctx) { if (!priv->pol_ctx) {
@@ -376,25 +442,6 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self)
} }
} }
NMSysconfigSettings *
nm_sysconfig_settings_new (DBusGConnection *g_conn, NMSystemConfigHalManager *hal_mgr)
{
NMSysconfigSettings *settings;
NMSysconfigSettingsPrivate *priv;
g_return_val_if_fail (g_conn != NULL, NULL);
g_return_val_if_fail (hal_mgr != NULL, NULL);
settings = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, NULL);
dbus_g_connection_register_g_object (g_conn, NM_DBUS_PATH_SETTINGS, G_OBJECT (settings));
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings);
priv->g_connection = dbus_g_connection_ref (g_conn);
priv->hal_mgr = g_object_ref (hal_mgr);
return settings;
}
static void static void
plugin_connection_added (NMSystemConfigInterface *config, plugin_connection_added (NMSystemConfigInterface *config,
NMExportedConnection *connection, NMExportedConnection *connection,
@@ -403,34 +450,45 @@ plugin_connection_added (NMSystemConfigInterface *config,
nm_sysconfig_settings_add_connection (NM_SYSCONFIG_SETTINGS (user_data), connection, TRUE); nm_sysconfig_settings_add_connection (NM_SYSCONFIG_SETTINGS (user_data), connection, TRUE);
} }
static gboolean
find_unmanaged_device (NMSysconfigSettings *self, const char *needle)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GSList *iter;
for (iter = priv->unmanaged_specs; iter; iter = g_slist_next (iter)) {
if (!strcmp ((const char *) iter->data, needle))
return TRUE;
}
return FALSE;
}
static void static void
unmanaged_devices_changed (NMSystemConfigInterface *config, unmanaged_devices_changed (NMSystemConfigInterface *config,
gpointer user_data) gpointer user_data)
{ {
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data); NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data);
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GSList *iter; GSList *iter;
g_hash_table_remove_all (priv->unmanaged_devices); clear_unmanaged_specs (self);
/* Ask all the plugins for their unmanaged devices */ /* Ask all the plugins for their unmanaged devices */
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
GSList *udis = nm_system_config_interface_get_unmanaged_devices (NM_SYSTEM_CONFIG_INTERFACE (iter->data)); GSList *specs, *specs_iter;
GSList *udi_iter;
for (udi_iter = udis; udi_iter; udi_iter = udi_iter->next) { specs = nm_system_config_interface_get_unmanaged_specs (NM_SYSTEM_CONFIG_INTERFACE (iter->data));
if (!g_hash_table_lookup (priv->unmanaged_devices, udi_iter->data)) { for (specs_iter = specs; specs_iter; specs_iter = specs_iter->next) {
g_hash_table_insert (priv->unmanaged_devices, if (!find_unmanaged_device (self, (const char *) specs_iter->data)) {
udi_iter->data, priv->unmanaged_specs = g_slist_prepend (priv->unmanaged_specs, specs_iter->data);
GUINT_TO_POINTER (1));
} else } else
g_free (udi_iter->data); g_free (specs_iter->data);
} }
g_slist_free (udis); g_slist_free (specs);
} }
g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES); g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS);
} }
static void static void
@@ -441,9 +499,8 @@ hostname_changed (NMSystemConfigInterface *config,
g_object_notify (G_OBJECT (user_data), NM_SYSCONFIG_SETTINGS_HOSTNAME); g_object_notify (G_OBJECT (user_data), NM_SYSCONFIG_SETTINGS_HOSTNAME);
} }
void static void
nm_sysconfig_settings_add_plugin (NMSysconfigSettings *self, add_plugin (NMSysconfigSettings *self, NMSystemConfigInterface *plugin)
NMSystemConfigInterface *plugin)
{ {
NMSysconfigSettingsPrivate *priv; NMSysconfigSettingsPrivate *priv;
char *pname = NULL; char *pname = NULL;
@@ -460,7 +517,7 @@ nm_sysconfig_settings_add_plugin (NMSysconfigSettings *self,
g_signal_connect (plugin, "unmanaged-devices-changed", G_CALLBACK (unmanaged_devices_changed), self); g_signal_connect (plugin, "unmanaged-devices-changed", G_CALLBACK (unmanaged_devices_changed), self);
g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self); g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self);
nm_system_config_interface_init (plugin, priv->hal_mgr); nm_system_config_interface_init (plugin, NULL);
g_object_get (G_OBJECT (plugin), g_object_get (G_OBJECT (plugin),
NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname, NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname,
@@ -472,6 +529,106 @@ nm_sysconfig_settings_add_plugin (NMSysconfigSettings *self,
g_free (pinfo); g_free (pinfo);
} }
static GObject *
find_plugin (GSList *list, const char *pname)
{
GSList *iter;
GObject *obj = NULL;
g_return_val_if_fail (pname != NULL, FALSE);
for (iter = list; iter && !obj; iter = g_slist_next (iter)) {
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
char *list_pname = NULL;
g_object_get (G_OBJECT (plugin),
NM_SYSTEM_CONFIG_INTERFACE_NAME,
&list_pname,
NULL);
if (list_pname && !strcmp (pname, list_pname))
obj = G_OBJECT (plugin);
g_free (list_pname);
}
return obj;
}
static gboolean
load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error)
{
GSList *list = NULL;
char **plist;
char **iter;
gboolean success = TRUE;
plist = g_strsplit (plugins, ",", 0);
if (!plist)
return FALSE;
for (iter = plist; *iter; iter++) {
GModule *plugin;
char *full_name, *path;
const char *pname = *iter;
GObject *obj;
GObject * (*factory_func) (void);
/* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */
if (!strcmp (pname, "ifcfg-fedora"))
pname = "ifcfg-rh";
obj = find_plugin (list, pname);
if (obj)
continue;
full_name = g_strdup_printf ("nm-settings-plugin-%s", pname);
path = g_module_build_path (PLUGINDIR, full_name);
plugin = g_module_open (path, G_MODULE_BIND_LOCAL);
if (!plugin) {
g_set_error (error, 0, 0,
"Could not load plugin '%s': %s",
pname, g_module_error ());
g_free (full_name);
g_free (path);
success = FALSE;
break;
}
g_free (full_name);
g_free (path);
if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) {
g_set_error (error, 0, 0,
"Could not find plugin '%s' factory function.",
pname);
success = FALSE;
break;
}
obj = (*factory_func) ();
if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) {
g_set_error (error, 0, 0,
"Plugin '%s' returned invalid system config object.",
pname);
success = FALSE;
break;
}
g_module_make_resident (plugin);
g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin);
add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (obj));
list = g_slist_append (list, obj);
}
g_strfreev (plist);
g_slist_foreach (list, (GFunc) g_object_unref, NULL);
g_slist_free (list);
return success;
}
static void static void
connection_removed (NMExportedConnection *connection, connection_removed (NMExportedConnection *connection,
gpointer user_data) gpointer user_data)
@@ -499,7 +656,10 @@ nm_sysconfig_settings_add_connection (NMSysconfigSettings *self,
g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self); g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self);
if (do_export) { if (do_export) {
nm_exported_connection_register_object (connection, NM_CONNECTION_SCOPE_SYSTEM, priv->g_connection); DBusGConnection *g_connection;
g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
nm_exported_connection_register_object (connection, NM_CONNECTION_SCOPE_SYSTEM, g_connection);
nm_settings_signal_new_connection (NM_SETTINGS (self), connection); nm_settings_signal_new_connection (NM_SETTINGS (self), connection);
} }
} }
@@ -520,23 +680,6 @@ nm_sysconfig_settings_remove_connection (NMSysconfigSettings *self,
} }
} }
gboolean
nm_sysconfig_settings_is_device_managed (NMSysconfigSettings *self,
const char *udi)
{
NMSysconfigSettingsPrivate *priv;
g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), FALSE);
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
load_connections (self);
if (g_hash_table_lookup (priv->unmanaged_devices, udi))
return FALSE;
return TRUE;
}
gboolean gboolean
nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self, nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self,
GHashTable *hash, GHashTable *hash,
@@ -594,6 +737,7 @@ impl_settings_add_connection (NMSysconfigSettings *self,
DBusGMethodInvocation *context) DBusGMethodInvocation *context)
{ {
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
DBusGConnection *g_connection;
GError *err = NULL; GError *err = NULL;
/* Do any of the plugins support adding? */ /* Do any of the plugins support adding? */
@@ -604,7 +748,8 @@ impl_settings_add_connection (NMSysconfigSettings *self,
goto out; goto out;
} }
if (!check_polkit_privileges (priv->g_connection, priv->pol_ctx, context, &err)) g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
if (!check_polkit_privileges (g_connection, priv->pol_ctx, context, &err))
goto out; goto out;
nm_sysconfig_settings_add_new_connection (self, hash, &err); nm_sysconfig_settings_add_new_connection (self, hash, &err);
@@ -629,6 +774,7 @@ impl_settings_save_hostname (NMSysconfigSettings *self,
GError *err = NULL; GError *err = NULL;
GSList *iter; GSList *iter;
gboolean success = FALSE; gboolean success = FALSE;
DBusGConnection *g_connection;
/* Do any of the plugins support setting the hostname? */ /* Do any of the plugins support setting the hostname? */
if (!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) { if (!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) {
@@ -638,7 +784,8 @@ impl_settings_save_hostname (NMSysconfigSettings *self,
goto out; goto out;
} }
if (!check_polkit_privileges (priv->g_connection, priv->pol_ctx, context, &err)) g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
if (!check_polkit_privileges (g_connection, priv->pol_ctx, context, &err))
goto out; goto out;
/* Set the hostname in all plugins */ /* Set the hostname in all plugins */
@@ -669,3 +816,33 @@ impl_settings_save_hostname (NMSysconfigSettings *self,
} }
} }
NMSysconfigSettings *
nm_sysconfig_settings_new (const char *plugins, GError **error)
{
NMSysconfigSettings *self;
NMSysconfigSettingsPrivate *priv;
DBusGConnection *g_connection;
self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, NULL);
if (!self)
return NULL;
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
priv->dbus_mgr = nm_dbus_manager_get ();
g_assert (priv->dbus_mgr);
g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
dbus_g_connection_register_g_object (g_connection, NM_DBUS_PATH_SETTINGS, G_OBJECT (self));
if (plugins) {
/* Load the plugins; fail if a plugin is not found. */
if (!load_plugins (self, plugins, error)) {
g_object_unref (self);
return NULL;
}
}
return self;
}

View File

@@ -19,18 +19,18 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* (C) Copyright 2007 - 2008 Red Hat, Inc. * (C) Copyright 2007 - 2009 Red Hat, Inc.
* (C) Copyright 2008 Novell, Inc. * (C) Copyright 2008 Novell, Inc.
*/ */
#ifndef __DBUS_SETTINGS_H__ #ifndef __NM_SYSCONFIG_SETTINGS_H__
#define __DBUS_SETTINGS_H__ #define __NM_SYSCONFIG_SETTINGS_H__
#include <nm-connection.h> #include <nm-connection.h>
#include <nm-settings.h> #include <nm-settings.h>
#include "nm-sysconfig-connection.h"
#include "nm-system-config-interface.h" #include "nm-system-config-interface.h"
#include "nm-system-config-hal-manager.h"
typedef struct _NMSysconfigSettings NMSysconfigSettings; typedef struct _NMSysconfigSettings NMSysconfigSettings;
typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass; typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass;
@@ -42,7 +42,7 @@ typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass;
#define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS)) #define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS))
#define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) #define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass))
#define NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES "unmanaged-devices" #define NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS "unmanaged-specs"
#define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname" #define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname"
#define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify" #define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify"
@@ -61,11 +61,7 @@ struct _NMSysconfigSettingsClass
GType nm_sysconfig_settings_get_type (void); GType nm_sysconfig_settings_get_type (void);
NMSysconfigSettings *nm_sysconfig_settings_new (DBusGConnection *g_conn, NMSysconfigSettings *nm_sysconfig_settings_new (const char *plugins, GError **error);
NMSystemConfigHalManager *hal_mgr);
void nm_sysconfig_settings_add_plugin (NMSysconfigSettings *settings,
NMSystemConfigInterface *plugin);
/* Registers an exising connection with the settings service */ /* Registers an exising connection with the settings service */
void nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings, void nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings,
@@ -76,12 +72,6 @@ void nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings,
NMExportedConnection *connection, NMExportedConnection *connection,
gboolean do_signal); gboolean do_signal);
void nm_sysconfig_settings_update_unamanged_devices (NMSysconfigSettings *settings,
GSList *new_list);
gboolean nm_sysconfig_settings_is_device_managed (NMSysconfigSettings *settings,
const char *udi);
NMSystemConfigInterface *nm_sysconfig_settings_get_plugin (NMSysconfigSettings *self, NMSystemConfigInterface *nm_sysconfig_settings_get_plugin (NMSysconfigSettings *self,
guint32 capability); guint32 capability);
@@ -92,4 +82,13 @@ gboolean nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self,
GHashTable *hash, GHashTable *hash,
GError **error); GError **error);
#endif /* __DBUS_SETTINGS_H__ */ const GSList *nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self);
char *nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self);
GSList *nm_sysconfig_settings_list_connections (NMSysconfigSettings *self);
NMSysconfigConnection *nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self,
const char *path);
#endif /* __NM_SYSCONFIG_SETTINGS_H__ */

View File

@@ -118,12 +118,12 @@ nm_system_config_interface_get_type (void)
void void
nm_system_config_interface_init (NMSystemConfigInterface *config, nm_system_config_interface_init (NMSystemConfigInterface *config,
NMSystemConfigHalManager *hal_manager) gpointer unused)
{ {
g_return_if_fail (config != NULL); g_return_if_fail (config != NULL);
if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init) if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init)
NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init (config, hal_manager); NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init (config);
} }
GSList * GSList *
@@ -137,12 +137,12 @@ nm_system_config_interface_get_connections (NMSystemConfigInterface *config)
} }
GSList * GSList *
nm_system_config_interface_get_unmanaged_devices (NMSystemConfigInterface *config) nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config)
{ {
g_return_val_if_fail (config != NULL, NULL); g_return_val_if_fail (config != NULL, NULL);
if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_devices) if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_specs)
return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_devices (config); return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_specs (config);
return NULL; return NULL;
} }

View File

@@ -27,8 +27,6 @@
#include <nm-connection.h> #include <nm-connection.h>
#include <nm-settings.h> #include <nm-settings.h>
#include "nm-system-config-hal-manager.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define PLUGIN_PRINT(pname, fmt, args...) \ #define PLUGIN_PRINT(pname, fmt, args...) \
@@ -87,7 +85,7 @@ struct _NMSystemConfigInterface {
GTypeInterface g_iface; GTypeInterface g_iface;
/* Called when the plugin is loaded to initialize it */ /* Called when the plugin is loaded to initialize it */
void (*init) (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager); void (*init) (NMSystemConfigInterface *config);
/* Returns the plugins currently known list of connections. The returned /* Returns the plugins currently known list of connections. The returned
* list is freed by the system settings service. * list is freed by the system settings service.
@@ -95,11 +93,18 @@ struct _NMSystemConfigInterface {
GSList * (*get_connections) (NMSystemConfigInterface *config); GSList * (*get_connections) (NMSystemConfigInterface *config);
/* /*
* Return a list of HAL UDIs of devices which NetworkManager should not * Return a string list of specifications of devices which NetworkManager
* manage. Returned list will be freed by the system settings service, and * should not manage. Returned list will be freed by the system settings
* each element must be allocated using g_malloc() or its variants. * service, and each element must be allocated using g_malloc() or its
* variants (g_strdup, g_strdup_printf, etc).
*
* Each string in the list must follow the format <method>:<data>, where
* the method and data are one of the following:
*
* Method: mac Data: device MAC address formatted with leading zeros and
* lowercase letters, like 00:0a:0b:0c:0d:0e
*/ */
GSList * (*get_unmanaged_devices) (NMSystemConfigInterface *config); GSList * (*get_unmanaged_specs) (NMSystemConfigInterface *config);
/* /*
* Add a new connection. * Add a new connection.
@@ -118,11 +123,11 @@ struct _NMSystemConfigInterface {
GType nm_system_config_interface_get_type (void); GType nm_system_config_interface_get_type (void);
void nm_system_config_interface_init (NMSystemConfigInterface *config, void nm_system_config_interface_init (NMSystemConfigInterface *config,
NMSystemConfigHalManager *hal_manager); gpointer unused);
GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *config); GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *config);
GSList *nm_system_config_interface_get_unmanaged_devices (NMSystemConfigInterface *config); GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config);
gboolean nm_system_config_interface_add_connection (NMSystemConfigInterface *config, gboolean nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
NMConnection *connection, NMConnection *connection,

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright (C) 2005 - 2008 Red Hat, Inc. * Copyright (C) 2005 - 2009 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc. * Copyright (C) 2006 - 2008 Novell, Inc.
*/ */
@@ -49,13 +49,16 @@
#include "nm-vpn-connection-glue.h" #include "nm-vpn-connection-glue.h"
G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT) static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class);
G_DEFINE_TYPE_EXTENDED (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE,
secrets_provider_interface_init))
typedef struct { typedef struct {
gboolean disposed; gboolean disposed;
NMConnection *connection; NMConnection *connection;
DBusGProxyCall *secrets_call;
NMActRequest *act_request; NMActRequest *act_request;
char *ac_path; char *ac_path;
@@ -221,31 +224,31 @@ nm_vpn_connection_new (NMConnection *connection,
NMActRequest *act_request, NMActRequest *act_request,
NMDevice *parent_device) NMDevice *parent_device)
{ {
NMVPNConnection *vpn_connection; NMVPNConnection *self;
NMVPNConnectionPrivate *priv; NMVPNConnectionPrivate *priv;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL); g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL);
g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL); g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
vpn_connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL); self = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL);
if (!vpn_connection) if (!self)
return NULL; return NULL;
priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection); priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
priv->connection = g_object_ref (connection); priv->connection = g_object_ref (connection);
priv->act_request = g_object_ref (act_request);
priv->parent_dev = g_object_ref (parent_device); priv->parent_dev = g_object_ref (parent_device);
priv->act_request = g_object_ref (act_request);
priv->device_monitor = g_signal_connect (parent_device, "state-changed", priv->device_monitor = g_signal_connect (parent_device, "state-changed",
G_CALLBACK (device_state_changed), G_CALLBACK (device_state_changed),
vpn_connection); self);
priv->device_ip4 = g_signal_connect (parent_device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG, priv->device_ip4 = g_signal_connect (parent_device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG,
G_CALLBACK (device_ip4_config_changed), G_CALLBACK (device_ip4_config_changed),
vpn_connection); self);
return vpn_connection; return self;
} }
static const char * static const char *
@@ -741,147 +744,55 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection,
/******************************************************************************/ /******************************************************************************/
static void static gboolean
cleanup_secrets_dbus_call (NMVPNConnection *self) secrets_update_setting (NMSecretsProviderInterface *interface,
const char *setting_name,
GHashTable *new)
{ {
NMVPNConnection *self = NM_VPN_CONNECTION (interface);
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
DBusGProxy *proxy;
g_return_if_fail (priv->connection != NULL);
g_return_if_fail (NM_IS_CONNECTION (priv->connection));
proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG);
g_assert (proxy);
if (priv->secrets_call) {
dbus_g_proxy_cancel_call (proxy, priv->secrets_call);
priv->secrets_call = NULL;
}
}
typedef struct GetSecretsInfo {
NMVPNConnection *vpn_connection;
char *setting_name;
} GetSecretsInfo;
static void
free_get_secrets_info (gpointer data)
{
GetSecretsInfo * info = (GetSecretsInfo *) data;
g_free (info->setting_name);
if (info->vpn_connection)
g_object_unref (info->vpn_connection);
g_slice_free (GetSecretsInfo, info);
}
static void
update_vpn_properties_secrets (gpointer key, gpointer data, gpointer user_data)
{
NMConnection *connection = NM_CONNECTION (user_data);
GHashTable *secrets = (GHashTable *) data;
GError *error = NULL; GError *error = NULL;
if (strcmp (key, NM_SETTING_VPN_SETTING_NAME)) g_return_val_if_fail (priv->connection != NULL, FALSE);
return;
if (!nm_connection_update_secrets (connection, NM_SETTING_VPN_SETTING_NAME, secrets, &error)) { if (strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME))
return FALSE;
if (!nm_connection_update_secrets (priv->connection, NM_SETTING_VPN_SETTING_NAME, new, &error)) {
nm_warning ("Failed to update VPN secrets: %d %s", nm_warning ("Failed to update VPN secrets: %d %s",
error ? error->code : -1, error ? error->code : -1,
error && error->message ? error->message : "(none)"); error && error->message ? error->message : "(none)");
g_clear_error (&error); g_clear_error (&error);
return FALSE;
} }
return TRUE;
} }
static void static void
get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) secrets_result (NMSecretsProviderInterface *interface,
const char *setting_name,
RequestSecretsCaller caller,
const GSList *updated,
GError *error)
{ {
GetSecretsInfo *info = (GetSecretsInfo *) user_data; NMVPNConnection *self = NM_VPN_CONNECTION (interface);
NMVPNConnectionPrivate *priv; NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
GError *err = NULL;
GHashTable *settings = NULL;
if (!info || !info->vpn_connection || !info->setting_name) g_return_if_fail (priv->connection != NULL);
goto error; g_return_if_fail (caller == SECRETS_CALLER_VPN);
priv = NM_VPN_CONNECTION_GET_PRIVATE (info->vpn_connection); if (error)
nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
priv->secrets_call = NULL; else
really_activate (self);
if (!dbus_g_proxy_end_call (proxy, call, &err,
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings,
G_TYPE_INVALID)) {
nm_warning ("Couldn't get connection secrets: %s.", err->message);
g_error_free (err);
goto error;
}
if (g_hash_table_size (settings) == 0) {
// FIXME: some better way to handle invalid message?
nm_warning ("GetSecrets call returned but no secrets were found.");
goto error;
}
g_hash_table_foreach (settings, update_vpn_properties_secrets, priv->connection);
g_hash_table_destroy (settings);
really_activate (info->vpn_connection);
return;
error:
nm_vpn_connection_fail (info->vpn_connection, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
} }
static gboolean static void
get_connection_secrets (NMVPNConnection *vpn_connection, secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class)
const char *setting_name,
gboolean request_new)
{ {
NMVPNConnectionPrivate *priv; /* interface implementation */
DBusGProxy *secrets_proxy; sp_interface_class->update_setting = secrets_update_setting;
GetSecretsInfo *info = NULL; sp_interface_class->result = secrets_result;
GPtrArray *hints;
g_return_val_if_fail (vpn_connection != NULL, FALSE);
g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn_connection), FALSE);
g_return_val_if_fail (setting_name != NULL, FALSE);
priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection);
g_assert (priv->connection);
secrets_proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG);
g_assert (secrets_proxy);
info = g_slice_new0 (GetSecretsInfo);
g_return_val_if_fail (info != NULL, FALSE);
info->setting_name = g_strdup (setting_name);
info->vpn_connection = g_object_ref (vpn_connection);
/* Empty for now... */
hints = g_ptr_array_new ();
/* use ..._with_timeout to give the user time to enter secrets */
priv->secrets_call = dbus_g_proxy_begin_call_with_timeout (secrets_proxy, "GetSecrets",
get_secrets_cb,
info,
free_get_secrets_info,
G_MAXINT32,
G_TYPE_STRING, setting_name,
DBUS_TYPE_G_ARRAY_OF_STRING, hints,
G_TYPE_BOOLEAN, request_new,
G_TYPE_INVALID);
g_ptr_array_free (hints, TRUE);
if (!priv->secrets_call) {
nm_warning ("Could not call GetSecrets");
goto error;
}
return TRUE;
error:
if (info)
free_get_secrets_info (info);
cleanup_secrets_dbus_call (vpn_connection);
return FALSE;
} }
static void static void
@@ -890,25 +801,32 @@ connection_need_secrets_cb (DBusGProxy *proxy,
GError *error, GError *error,
gpointer user_data) gpointer user_data)
{ {
NMVPNConnection *vpn_connection = NM_VPN_CONNECTION (user_data); NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
cleanup_secrets_dbus_call (vpn_connection);
if (error) { if (error) {
g_warning ("%s.%d: NeedSecrets failed: %s %s", g_warning ("%s.%d: NeedSecrets failed: %s %s",
__FILE__, __LINE__, __FILE__, __LINE__,
g_quark_to_string (error->domain), error->message); g_quark_to_string (error->domain), error->message);
nm_vpn_connection_fail (vpn_connection, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
return; return;
} }
if (setting_name && strlen (setting_name)) { if (!setting_name || !strlen (setting_name)) {
if (!get_connection_secrets (vpn_connection, setting_name, FALSE)) /* No secrets required */
nm_vpn_connection_fail (vpn_connection, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); really_activate (self);
} else { return;
/* No secrets needed */
really_activate (vpn_connection);
} }
/* Get the secrets the VPN plugin wants */
if (!nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self),
priv->connection,
setting_name,
FALSE,
SECRETS_CALLER_VPN,
NULL,
NULL))
nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
} }
static void static void
@@ -985,7 +903,7 @@ connection_state_changed (NMVPNConnection *connection,
{ {
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
cleanup_secrets_dbus_call (connection); nm_secrets_provider_interface_cancel_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (priv->act_request));
switch (state) { switch (state) {
case NM_VPN_CONNECTION_STATE_NEED_AUTH: case NM_VPN_CONNECTION_STATE_NEED_AUTH:
@@ -1040,20 +958,16 @@ dispose (GObject *object)
} }
priv->disposed = TRUE; priv->disposed = TRUE;
cleanup_secrets_dbus_call (NM_VPN_CONNECTION (object));
if (priv->gw_route) if (priv->gw_route)
rtnl_route_put (priv->gw_route); rtnl_route_put (priv->gw_route);
if (priv->parent_dev) { if (priv->device_ip4)
if (priv->device_ip4) g_signal_handler_disconnect (priv->parent_dev, priv->device_ip4);
g_signal_handler_disconnect (priv->parent_dev, priv->device_ip4);
if (priv->device_monitor) if (priv->device_monitor)
g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor); g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor);
g_object_unref (priv->parent_dev); g_object_unref (priv->parent_dev);
}
if (priv->ip4_config) if (priv->ip4_config)
g_object_unref (priv->ip4_config); g_object_unref (priv->ip4_config);
@@ -1064,6 +978,7 @@ dispose (GObject *object)
if (priv->proxy) if (priv->proxy)
g_object_unref (priv->proxy); g_object_unref (priv->proxy);
g_object_unref (priv->act_request);
g_object_unref (priv->connection); g_object_unref (priv->connection);
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object); G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object);

View File

@@ -27,6 +27,7 @@
#include "NetworkManagerVPN.h" #include "NetworkManagerVPN.h"
#include "nm-device.h" #include "nm-device.h"
#include "nm-activation-request.h" #include "nm-activation-request.h"
#include "nm-secrets-provider-interface.h"
#define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ()) #define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ())
#define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection)) #define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection))
@@ -72,6 +73,6 @@ void nm_vpn_connection_disconnect (NMVPNConnection *connect
NMIP4Config * nm_vpn_connection_get_ip4_config (NMVPNConnection *connection); NMIP4Config * nm_vpn_connection_get_ip4_config (NMVPNConnection *connection);
const char * nm_vpn_connection_get_ip_iface (NMVPNConnection *connection); const char * nm_vpn_connection_get_ip_iface (NMVPNConnection *connection);
NMDevice * nm_vpn_connection_get_parent_device (NMVPNConnection *connection); NMDevice * nm_vpn_connection_get_parent_device (NMVPNConnection *connection);
guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection); guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection);
#endif /* NM_VPN_CONNECTION_H */ #endif /* NM_VPN_CONNECTION_H */

View File

@@ -160,7 +160,7 @@ connection_vpn_state_changed (NMVPNConnection *connection,
} }
} }
const char * NMVPNConnection *
nm_vpn_manager_activate_connection (NMVPNManager *manager, nm_vpn_manager_activate_connection (NMVPNManager *manager,
NMConnection *connection, NMConnection *connection,
NMActRequest *act_request, NMActRequest *act_request,
@@ -169,8 +169,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
{ {
NMSettingVPN *vpn_setting; NMSettingVPN *vpn_setting;
NMVPNService *service; NMVPNService *service;
char *path = NULL; NMVPNConnection *vpn = NULL;
NMVPNConnection *vpn;
const char *service_type; const char *service_type;
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
@@ -212,7 +211,6 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
if (service) { if (service) {
vpn = nm_vpn_service_activate (service, connection, act_request, device, error); vpn = nm_vpn_service_activate (service, connection, act_request, device, error);
if (vpn) { if (vpn) {
path = (char *) nm_vpn_connection_get_active_connection_path (vpn);
g_signal_connect (vpn, "vpn-state-changed", g_signal_connect (vpn, "vpn-state-changed",
G_CALLBACK (connection_vpn_state_changed), G_CALLBACK (connection_vpn_state_changed),
manager); manager);
@@ -223,7 +221,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
"%s", "The VPN service was invalid."); "%s", "The VPN service was invalid.");
} }
return path; return vpn;
} }
gboolean gboolean

View File

@@ -67,11 +67,11 @@ GType nm_vpn_manager_get_type (void);
NMVPNManager *nm_vpn_manager_get (void); NMVPNManager *nm_vpn_manager_get (void);
const char *nm_vpn_manager_activate_connection (NMVPNManager *manager, NMVPNConnection *nm_vpn_manager_activate_connection (NMVPNManager *manager,
NMConnection *connection, NMConnection *connection,
NMActRequest *act_request, NMActRequest *act_request,
NMDevice *device, NMDevice *device,
GError **error); GError **error);
gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager, gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager,
const char *path, const char *path,

View File

@@ -323,6 +323,7 @@ nm_vpn_service_activate (NMVPNService *service,
priv = NM_VPN_SERVICE_GET_PRIVATE (service); priv = NM_VPN_SERVICE_GET_PRIVATE (service);
g_message ("%s: new VPNConnection for %s", __func__, nm_connection_get_path (connection));
vpn = nm_vpn_connection_new (connection, act_request, device); vpn = nm_vpn_connection_new (connection, act_request, device);
g_signal_connect (vpn, "vpn-state-changed", g_signal_connect (vpn, "vpn-state-changed",
G_CALLBACK (connection_vpn_state_changed), G_CALLBACK (connection_vpn_state_changed),

View File

@@ -1,2 +1,2 @@
SUBDIRS=src plugins SUBDIRS=plugins

View File

@@ -20,13 +20,18 @@ libifcfg_rh_io_la_SOURCES = \
crypto.c \ crypto.c \
crypto.h crypto.h
INCLUDES = \
-I$(top_srcdir)/src/system-settings \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-glib \
-I$(top_srcdir)/libnm-util \
-I$(top_builddir)/marshallers
libifcfg_rh_io_la_CPPFLAGS = \ libifcfg_rh_io_la_CPPFLAGS = \
$(GLIB_CFLAGS) \ $(GLIB_CFLAGS) \
$(DBUS_CFLAGS) \ $(DBUS_CFLAGS) \
$(NSS_CFLAGS) \ $(NSS_CFLAGS) \
-DG_DISABLE_DEPRECATED \ -DG_DISABLE_DEPRECATED \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-util \
-DSYSCONFDIR=\"$(sysconfdir)\" -DSYSCONFDIR=\"$(sysconfdir)\"
libifcfg_rh_io_la_LIBADD = $(GLIB_LIBS) $(NSS_LIBS) libifcfg_rh_io_la_LIBADD = $(GLIB_LIBS) $(NSS_LIBS)
@@ -42,11 +47,6 @@ libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS = \
$(GMODULE_CFLAGS) \ $(GMODULE_CFLAGS) \
$(DBUS_CFLAGS) \ $(DBUS_CFLAGS) \
-DG_DISABLE_DEPRECATED \ -DG_DISABLE_DEPRECATED \
-I$(top_srcdir)/system-settings/src \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-glib \
-I$(top_srcdir)/libnm-util \
-I$(top_builddir)/marshallers \
-DSYSCONFDIR=\"$(sysconfdir)\" -DSYSCONFDIR=\"$(sysconfdir)\"
libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version

View File

@@ -36,7 +36,6 @@
#include "common.h" #include "common.h"
#include "nm-ifcfg-connection.h" #include "nm-ifcfg-connection.h"
#include "nm-system-config-hal-manager.h"
#include "reader.h" #include "reader.h"
#include "writer.h" #include "writer.h"
#include "nm-inotify-helper.h" #include "nm-inotify-helper.h"
@@ -55,11 +54,7 @@ typedef struct {
int keyfile_wd; int keyfile_wd;
char *udi; char *udi;
gboolean unmanaged; char *unmanaged;
NMSystemConfigHalManager *hal_mgr;
DBusGConnection *g_connection;
gulong daid;
} NMIfcfgConnectionPrivate; } NMIfcfgConnectionPrivate;
enum { enum {
@@ -79,150 +74,6 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 }; static guint signals[LAST_SIGNAL] = { 0 };
static char *
get_ether_device_udi (DBusGConnection *g_connection, const GByteArray *mac, GSList *devices)
{
GError *error = NULL;
GSList *iter;
char *udi = NULL;
if (!g_connection || !mac)
return NULL;
for (iter = devices; !udi && iter; iter = g_slist_next (iter)) {
DBusGProxy *dev_proxy;
char *address = NULL;
dev_proxy = dbus_g_proxy_new_for_name (g_connection,
"org.freedesktop.Hal",
iter->data,
"org.freedesktop.Hal.Device");
if (!dev_proxy)
continue;
if (dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyString", 10000, &error,
G_TYPE_STRING, "net.address", G_TYPE_INVALID,
G_TYPE_STRING, &address, G_TYPE_INVALID)) {
struct ether_addr *dev_mac;
if (address && strlen (address)) {
dev_mac = ether_aton (address);
if (!memcmp (dev_mac->ether_addr_octet, mac->data, ETH_ALEN))
udi = g_strdup (iter->data);
}
} else {
g_error_free (error);
error = NULL;
}
g_free (address);
g_object_unref (dev_proxy);
}
return udi;
}
static NMDeviceType
get_device_type_for_connection (NMConnection *connection)
{
NMDeviceType devtype = NM_DEVICE_TYPE_UNKNOWN;
NMSettingConnection *s_con;
const char *ctype;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
if (!s_con)
return NM_DEVICE_TYPE_UNKNOWN;
ctype = nm_setting_connection_get_connection_type (s_con);
if ( !strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME)
|| !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) {
if (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED))
devtype = NM_DEVICE_TYPE_ETHERNET;
} else if (!strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME)) {
if (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS))
devtype = NM_DEVICE_TYPE_WIFI;
} else if (!strcmp (ctype, NM_SETTING_GSM_SETTING_NAME)) {
if (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM))
devtype = NM_DEVICE_TYPE_GSM;
} else if (!strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME)) {
if (nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA))
devtype = NM_DEVICE_TYPE_CDMA;
}
return devtype;
}
static char *
get_udi_for_connection (NMConnection *connection,
DBusGConnection *g_connection,
NMSystemConfigHalManager *hal_mgr,
NMDeviceType devtype)
{
NMSettingWired *s_wired;
NMSettingWireless *s_wireless;
char *udi = NULL;
GSList *devices = NULL;
if (devtype == NM_DEVICE_TYPE_UNKNOWN)
devtype = get_device_type_for_connection (connection);
switch (devtype) {
case NM_DEVICE_TYPE_ETHERNET:
s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
if (s_wired) {
devices = nm_system_config_hal_manager_get_devices_of_type (hal_mgr, NM_DEVICE_TYPE_ETHERNET);
udi = get_ether_device_udi (g_connection, nm_setting_wired_get_mac_address (s_wired), devices);
}
break;
case NM_DEVICE_TYPE_WIFI:
s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
if (s_wireless) {
devices = nm_system_config_hal_manager_get_devices_of_type (hal_mgr, NM_DEVICE_TYPE_WIFI);
udi = get_ether_device_udi (g_connection, nm_setting_wireless_get_mac_address (s_wireless), devices);
}
break;
default:
break;
}
g_slist_foreach (devices, (GFunc) g_free, NULL);
g_slist_free (devices);
return udi;
}
static void
device_added_cb (NMSystemConfigHalManager *hal_mgr,
const char *udi,
NMDeviceType devtype,
gpointer user_data)
{
NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (user_data);
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
NMConnection *wrapped;
/* Should only be called when udi is NULL */
g_return_if_fail (priv->udi == NULL);
wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection));
if (devtype != get_device_type_for_connection (wrapped))
return;
priv->udi = get_udi_for_connection (wrapped, priv->g_connection, priv->hal_mgr, devtype);
if (!priv->udi)
return;
/* If the connection is unmanaged we have to tell the plugin */
if (priv->unmanaged)
g_object_notify (G_OBJECT (connection), NM_IFCFG_CONNECTION_UNMANAGED);
g_signal_handler_disconnect (G_OBJECT (hal_mgr), priv->daid);
priv->daid = 0;
}
static void static void
files_changed_cb (NMInotifyHelper *ih, files_changed_cb (NMInotifyHelper *ih,
struct inotify_event *evt, struct inotify_event *evt,
@@ -241,16 +92,13 @@ files_changed_cb (NMInotifyHelper *ih,
NMIfcfgConnection * NMIfcfgConnection *
nm_ifcfg_connection_new (const char *filename, nm_ifcfg_connection_new (const char *filename,
DBusGConnection *g_connection,
NMSystemConfigHalManager *hal_mgr,
GError **error, GError **error,
gboolean *ignore_error) gboolean *ignore_error)
{ {
GObject *object; GObject *object;
NMIfcfgConnectionPrivate *priv; NMIfcfgConnectionPrivate *priv;
NMConnection *wrapped; NMConnection *wrapped;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *udi;
char *keyfile = NULL; char *keyfile = NULL;
NMInotifyHelper *ih; NMInotifyHelper *ih;
@@ -260,12 +108,9 @@ nm_ifcfg_connection_new (const char *filename,
if (!wrapped) if (!wrapped)
return NULL; return NULL;
udi = get_udi_for_connection (wrapped, g_connection, hal_mgr, NM_DEVICE_TYPE_UNKNOWN);
object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION, object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION,
NM_IFCFG_CONNECTION_FILENAME, filename, NM_IFCFG_CONNECTION_FILENAME, filename,
NM_IFCFG_CONNECTION_UNMANAGED, unmanaged, NM_IFCFG_CONNECTION_UNMANAGED, unmanaged,
NM_IFCFG_CONNECTION_UDI, udi,
NM_EXPORTED_CONNECTION_CONNECTION, wrapped, NM_EXPORTED_CONNECTION_CONNECTION, wrapped,
NULL); NULL);
if (!object) if (!object)
@@ -273,12 +118,6 @@ nm_ifcfg_connection_new (const char *filename,
priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
if (!udi) {
priv->hal_mgr = g_object_ref (hal_mgr);
priv->g_connection = dbus_g_connection_ref (g_connection);
priv->daid = g_signal_connect (priv->hal_mgr, "device-added", G_CALLBACK (device_added_cb), object);
}
ih = nm_inotify_helper_get (); ih = nm_inotify_helper_get ();
priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), object); priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), object);
@@ -289,7 +128,6 @@ nm_ifcfg_connection_new (const char *filename,
out: out:
g_object_unref (wrapped); g_object_unref (wrapped);
g_free (udi);
return (NMIfcfgConnection *) object; return (NMIfcfgConnection *) object;
} }
@@ -302,15 +140,7 @@ nm_ifcfg_connection_get_filename (NMIfcfgConnection *self)
} }
const char * const char *
nm_ifcfg_connection_get_udi (NMIfcfgConnection *self) nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self)
{
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->udi;
}
gboolean
nm_ifcfg_connection_get_unmanaged (NMIfcfgConnection *self)
{ {
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), FALSE); g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), FALSE);
@@ -384,16 +214,6 @@ finalize (GObject *object)
if (priv->keyfile_wd >= 0) if (priv->keyfile_wd >= 0)
nm_inotify_helper_remove_watch (ih, priv->keyfile_wd); nm_inotify_helper_remove_watch (ih, priv->keyfile_wd);
if (priv->hal_mgr) {
if (priv->daid)
g_signal_handler_disconnect (G_OBJECT (priv->hal_mgr), priv->daid);
g_object_unref (priv->hal_mgr);
}
if (priv->g_connection)
dbus_g_connection_unref (priv->g_connection);
G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object); G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object);
} }
@@ -409,7 +229,7 @@ set_property (GObject *object, guint prop_id,
priv->filename = g_value_dup_string (value); priv->filename = g_value_dup_string (value);
break; break;
case PROP_UNMANAGED: case PROP_UNMANAGED:
priv->unmanaged = g_value_get_boolean (value); priv->unmanaged = g_value_dup_string (value);
break; break;
case PROP_UDI: case PROP_UDI:
/* Construct only */ /* Construct only */
@@ -432,7 +252,7 @@ get_property (GObject *object, guint prop_id,
g_value_set_string (value, priv->filename); g_value_set_string (value, priv->filename);
break; break;
case PROP_UNMANAGED: case PROP_UNMANAGED:
g_value_set_boolean (value, priv->unmanaged); g_value_set_string (value, priv->unmanaged);
break; break;
case PROP_UDI: case PROP_UDI:
g_value_set_string (value, priv->udi); g_value_set_string (value, priv->udi);
@@ -470,10 +290,10 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
g_object_class_install_property g_object_class_install_property
(object_class, PROP_UNMANAGED, (object_class, PROP_UNMANAGED,
g_param_spec_boolean (NM_IFCFG_CONNECTION_UNMANAGED, g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED,
"Unmanaged", "Unmanaged",
"Unmanaged", "Unmanaged",
FALSE, NULL,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property g_object_class_install_property

View File

@@ -25,7 +25,6 @@ G_BEGIN_DECLS
#include <NetworkManager.h> #include <NetworkManager.h>
#include <nm-sysconfig-connection.h> #include <nm-sysconfig-connection.h>
#include "nm-system-config-hal-manager.h"
#define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ()) #define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ())
#define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection)) #define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection))
@@ -49,16 +48,12 @@ typedef struct {
GType nm_ifcfg_connection_get_type (void); GType nm_ifcfg_connection_get_type (void);
NMIfcfgConnection *nm_ifcfg_connection_new (const char *filename, NMIfcfgConnection *nm_ifcfg_connection_new (const char *filename,
DBusGConnection *g_connection,
NMSystemConfigHalManager *hal_mgr,
GError **error, GError **error,
gboolean *ignore_error); gboolean *ignore_error);
const char *nm_ifcfg_connection_get_filename (NMIfcfgConnection *self); const char *nm_ifcfg_connection_get_filename (NMIfcfgConnection *self);
const char *nm_ifcfg_connection_get_udi (NMIfcfgConnection *self); const char *nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self);
gboolean nm_ifcfg_connection_get_unmanaged (NMIfcfgConnection *self);
gboolean nm_ifcfg_connection_update (NMIfcfgConnection *self, gboolean nm_ifcfg_connection_update (NMIfcfgConnection *self,
GHashTable *new_settings, GHashTable *new_settings,

View File

@@ -72,9 +72,6 @@ G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
typedef struct { typedef struct {
DBusGConnection *g_connection;
NMSystemConfigHalManager *hal_mgr;
GHashTable *connections; GHashTable *connections;
gulong ih_event_id; gulong ih_event_id;
@@ -86,40 +83,6 @@ typedef struct {
} SCPluginIfcfgPrivate; } SCPluginIfcfgPrivate;
static void
check_unmanaged (gpointer key, gpointer data, gpointer user_data)
{
GSList **list = (GSList **) user_data;
NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (data);
const char *udi;
GSList *iter;
if (!nm_ifcfg_connection_get_unmanaged (connection))
return;
udi = nm_ifcfg_connection_get_udi (connection);
if (!udi)
return;
/* Just return if the UDI is already in the list */
for (iter = *list; iter; iter = g_slist_next (iter)) {
if (!strcmp ((char *) iter->data, udi))
return;
}
*list = g_slist_prepend (*list, g_strdup (udi));
}
static GSList *
get_unmanaged_devices (NMSystemConfigInterface *config)
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
GSList *list = NULL;
g_hash_table_foreach (priv->connections, check_unmanaged, &list);
return list;
}
static void static void
connection_unmanaged_changed (NMIfcfgConnection *connection, connection_unmanaged_changed (NMIfcfgConnection *connection,
GParamSpec *pspec, GParamSpec *pspec,
@@ -152,7 +115,7 @@ read_one_connection (SCPluginIfcfg *plugin, const char *filename)
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", filename); PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", filename);
connection = nm_ifcfg_connection_new (filename, priv->g_connection, priv->hal_mgr, &error, &ignore_error); connection = nm_ifcfg_connection_new (filename, &error, &ignore_error);
if (connection) { if (connection) {
NMConnection *wrapped; NMConnection *wrapped;
NMSettingConnection *s_con; NMSettingConnection *s_con;
@@ -171,7 +134,7 @@ read_one_connection (SCPluginIfcfg *plugin, const char *filename)
g_object_ref (connection)); g_object_ref (connection));
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid); PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid);
if (nm_ifcfg_connection_get_unmanaged (connection)) { if (nm_ifcfg_connection_get_unmanaged_spec (connection)) {
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its " PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its "
"device because NM_CONTROLLED was false.", cid); "device because NM_CONTROLLED was false.", cid);
g_signal_emit_by_name (plugin, "unmanaged-devices-changed"); g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
@@ -271,11 +234,11 @@ connection_changed_handler (SCPluginIfcfg *plugin,
gboolean *do_remove, gboolean *do_remove,
gboolean *do_new) gboolean *do_new)
{ {
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
NMIfcfgConnection *tmp; NMIfcfgConnection *tmp;
GError *error = NULL; GError *error = NULL;
GHashTable *settings; GHashTable *settings;
gboolean new_unmanaged, old_unmanaged, ignore_error = FALSE; gboolean ignore_error = FALSE;
const char *new_unmanaged = NULL, *old_unmanaged = NULL;
g_return_if_fail (plugin != NULL); g_return_if_fail (plugin != NULL);
g_return_if_fail (path != NULL); g_return_if_fail (path != NULL);
@@ -285,10 +248,7 @@ connection_changed_handler (SCPluginIfcfg *plugin,
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path); PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path);
tmp = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, priv->g_connection, tmp = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, &error, &ignore_error);
priv->hal_mgr,
&error,
&ignore_error);
if (!tmp) { if (!tmp) {
/* errors reading connection; remove it */ /* errors reading connection; remove it */
if (!ignore_error) { if (!ignore_error) {
@@ -304,8 +264,8 @@ connection_changed_handler (SCPluginIfcfg *plugin,
/* Successfully read connection changes */ /* Successfully read connection changes */
old_unmanaged = nm_ifcfg_connection_get_unmanaged (NM_IFCFG_CONNECTION (connection)); old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection));
new_unmanaged = nm_ifcfg_connection_get_unmanaged (NM_IFCFG_CONNECTION (tmp)); new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (tmp));
if (new_unmanaged) { if (new_unmanaged) {
if (!old_unmanaged) { if (!old_unmanaged) {
@@ -318,7 +278,7 @@ connection_changed_handler (SCPluginIfcfg *plugin,
new_wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (tmp)); new_wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (tmp));
old_wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection)); old_wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection));
if (old_unmanaged) { /* no longer unmanaged */ if (old_unmanaged) { /* now managed */
NMSettingConnection *s_con; NMSettingConnection *s_con;
const char *cid; const char *cid;
@@ -364,11 +324,11 @@ handle_connection_remove_or_new (SCPluginIfcfg *plugin,
g_return_if_fail (path != NULL); g_return_if_fail (path != NULL);
if (do_remove) { if (do_remove) {
gboolean unmanaged; const char *unmanaged;
g_return_if_fail (connection != NULL); g_return_if_fail (connection != NULL);
unmanaged = nm_ifcfg_connection_get_unmanaged (connection); unmanaged = nm_ifcfg_connection_get_unmanaged_spec (connection);
g_hash_table_remove (priv->connections, path); g_hash_table_remove (priv->connections, path);
nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (connection)); nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (connection));
@@ -380,7 +340,7 @@ handle_connection_remove_or_new (SCPluginIfcfg *plugin,
if (do_new) { if (do_new) {
connection = read_one_connection (plugin, path); connection = read_one_connection (plugin, path);
if (connection) { if (connection) {
if (!nm_ifcfg_connection_get_unmanaged (NM_IFCFG_CONNECTION (connection))) if (!nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection)))
g_signal_emit_by_name (plugin, "connection-added", connection); g_signal_emit_by_name (plugin, "connection-added", connection);
} }
} }
@@ -454,7 +414,7 @@ hash_to_slist (gpointer key, gpointer value, gpointer user_data)
NMIfcfgConnection *exported = NM_IFCFG_CONNECTION (value); NMIfcfgConnection *exported = NM_IFCFG_CONNECTION (value);
GSList **list = (GSList **) user_data; GSList **list = (GSList **) user_data;
if (!nm_ifcfg_connection_get_unmanaged (exported)) if (!nm_ifcfg_connection_get_unmanaged_spec (exported))
*list = g_slist_prepend (*list, value); *list = g_slist_prepend (*list, value);
} }
@@ -475,6 +435,43 @@ get_connections (NMSystemConfigInterface *config)
return list; return list;
} }
static void
check_unmanaged (gpointer key, gpointer data, gpointer user_data)
{
GSList **list = (GSList **) user_data;
NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (data);
const char *unmanaged_spec;
GSList *iter;
unmanaged_spec = nm_ifcfg_connection_get_unmanaged_spec (connection);
if (!unmanaged_spec)
return;
/* Just return if the unmanaged spec is already in the list */
for (iter = *list; iter; iter = g_slist_next (iter)) {
if (!strcmp ((char *) iter->data, unmanaged_spec))
return;
}
*list = g_slist_prepend (*list, g_strdup (unmanaged_spec));
}
static GSList *
get_unmanaged_specs (NMSystemConfigInterface *config)
{
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
GSList *list = NULL;
if (!priv->connections) {
setup_ifcfg_monitoring (plugin);
read_connections (plugin);
}
g_hash_table_foreach (priv->connections, check_unmanaged, &list);
return list;
}
static gboolean static gboolean
add_connection (NMSystemConfigInterface *config, add_connection (NMSystemConfigInterface *config,
NMConnection *connection, NMConnection *connection,
@@ -560,28 +557,16 @@ sc_network_changed_cb (NMInotifyHelper *ih,
} }
static void static void
init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager) init (NMSystemConfigInterface *config)
{ {
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
priv->hal_mgr = g_object_ref (hal_manager);
} }
static void static void
sc_plugin_ifcfg_init (SCPluginIfcfg *plugin) sc_plugin_ifcfg_init (SCPluginIfcfg *plugin)
{ {
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
GError *error = NULL;
NMInotifyHelper *ih; NMInotifyHelper *ih;
priv->g_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (!priv->g_connection) {
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " dbus-glib error: %s",
error->message ? error->message : "(unknown)");
g_error_free (error);
}
ih = nm_inotify_helper_get (); ih = nm_inotify_helper_get ();
priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (sc_network_changed_cb), plugin); priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (sc_network_changed_cb), plugin);
priv->sc_network_wd = nm_inotify_helper_add_watch (ih, SC_NETWORK_FILE); priv->sc_network_wd = nm_inotify_helper_add_watch (ih, SC_NETWORK_FILE);
@@ -596,8 +581,6 @@ dispose (GObject *object)
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
NMInotifyHelper *ih; NMInotifyHelper *ih;
g_object_unref (priv->hal_mgr);
ih = nm_inotify_helper_get (); ih = nm_inotify_helper_get ();
g_signal_handler_disconnect (ih, priv->ih_event_id); g_signal_handler_disconnect (ih, priv->ih_event_id);
@@ -607,9 +590,6 @@ dispose (GObject *object)
g_free (priv->hostname); g_free (priv->hostname);
if (priv->g_connection)
dbus_g_connection_unref (priv->g_connection);
if (priv->connections) if (priv->connections)
g_hash_table_destroy (priv->connections); g_hash_table_destroy (priv->connections);
@@ -709,7 +689,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
/* interface implementation */ /* interface implementation */
system_config_interface_class->get_connections = get_connections; system_config_interface_class->get_connections = get_connections;
system_config_interface_class->add_connection = add_connection; system_config_interface_class->add_connection = add_connection;
system_config_interface_class->get_unmanaged_devices = get_unmanaged_devices; system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;
system_config_interface_class->init = init; system_config_interface_class->init = init;
} }

View File

@@ -1366,7 +1366,7 @@ fill_8021x (shvarFile *ifcfg,
char *lower = NULL; char *lower = NULL;
lower = g_ascii_strdown (*iter, -1); lower = g_ascii_strdown (*iter, -1);
while (*eap->method && !found) { while (eap->method && !found) {
if (strcmp (eap->method, lower)) if (strcmp (eap->method, lower))
goto next; goto next;
@@ -1602,7 +1602,8 @@ make_wireless_security_setting (shvarFile *ifcfg,
static NMSetting * static NMSetting *
make_wireless_setting (shvarFile *ifcfg, make_wireless_setting (shvarFile *ifcfg,
gboolean unmanaged, gboolean nm_controlled,
char **unmanaged,
GError **error) GError **error)
{ {
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
@@ -1614,6 +1615,14 @@ make_wireless_setting (shvarFile *ifcfg,
if (read_mac_address (ifcfg, &array, error)) { if (read_mac_address (ifcfg, &array, error)) {
if (array) { if (array) {
g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, array, NULL); g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, array, NULL);
/* A connection can only be unmanaged if we know the MAC address */
if (!nm_controlled) {
*unmanaged = g_strdup_printf ("mac:%02x:%02x:%02x:%02x:%02x:%02x",
array->data[0], array->data[1], array->data[2],
array->data[3], array->data[4], array->data[5]);
}
g_byte_array_free (array, TRUE); g_byte_array_free (array, TRUE);
} }
} else { } else {
@@ -1681,13 +1690,13 @@ make_wireless_setting (shvarFile *ifcfg,
g_free (value); g_free (value);
} else { } else {
/* Only fail on lack of SSID if device is managed */ /* Only fail on lack of SSID if device is managed */
if (!unmanaged) { if (nm_controlled) {
g_set_error (error, ifcfg_plugin_error_quark (), 0, "Missing SSID"); g_set_error (error, ifcfg_plugin_error_quark (), 0, "Missing SSID");
goto error; goto error;
} }
} }
if (unmanaged) if (!nm_controlled)
goto done; goto done;
value = svGetValue (ifcfg, "MODE", FALSE); value = svGetValue (ifcfg, "MODE", FALSE);
@@ -1778,7 +1787,8 @@ error:
static NMConnection * static NMConnection *
wireless_connection_from_ifcfg (const char *file, wireless_connection_from_ifcfg (const char *file,
shvarFile *ifcfg, shvarFile *ifcfg,
gboolean unmanaged, gboolean nm_controlled,
char **unmanaged,
GError **error) GError **error)
{ {
NMConnection *connection = NULL; NMConnection *connection = NULL;
@@ -1804,7 +1814,7 @@ wireless_connection_from_ifcfg (const char *file,
} }
/* Wireless */ /* Wireless */
wireless_setting = make_wireless_setting (ifcfg, unmanaged, error); wireless_setting = make_wireless_setting (ifcfg, nm_controlled, unmanaged, error);
if (!wireless_setting) { if (!wireless_setting) {
g_object_unref (connection); g_object_unref (connection);
return NULL; return NULL;
@@ -1817,7 +1827,7 @@ wireless_connection_from_ifcfg (const char *file,
else else
printable_ssid = g_strdup_printf ("unmanaged"); printable_ssid = g_strdup_printf ("unmanaged");
if (!unmanaged) { if (nm_controlled) {
mode = nm_setting_wireless_get_mode (NM_SETTING_WIRELESS (wireless_setting)); mode = nm_setting_wireless_get_mode (NM_SETTING_WIRELESS (wireless_setting));
if (mode && !strcmp (mode, "adhoc")) if (mode && !strcmp (mode, "adhoc"))
adhoc = TRUE; adhoc = TRUE;
@@ -1852,7 +1862,7 @@ wireless_connection_from_ifcfg (const char *file,
nm_connection_add_setting (connection, con_setting); nm_connection_add_setting (connection, con_setting);
/* Don't verify if unmanaged since we may not have an SSID or whatever */ /* Don't verify if unmanaged since we may not have an SSID or whatever */
if (!unmanaged) { if (nm_controlled) {
if (!nm_connection_verify (connection, error)) { if (!nm_connection_verify (connection, error)) {
g_object_unref (connection); g_object_unref (connection);
return NULL; return NULL;
@@ -1865,7 +1875,8 @@ wireless_connection_from_ifcfg (const char *file,
static NMSetting * static NMSetting *
make_wired_setting (shvarFile *ifcfg, make_wired_setting (shvarFile *ifcfg,
const char *file, const char *file,
gboolean unmanaged, gboolean nm_controlled,
char **unmanaged,
NMSetting8021x **s_8021x, NMSetting8021x **s_8021x,
GError **error) GError **error)
{ {
@@ -1891,6 +1902,14 @@ make_wired_setting (shvarFile *ifcfg,
if (read_mac_address (ifcfg, &mac, error)) { if (read_mac_address (ifcfg, &mac, error)) {
if (mac) { if (mac) {
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
/* A connection can only be unmanaged if we know the MAC address */
if (!nm_controlled) {
*unmanaged = g_strdup_printf ("mac:%02x:%02x:%02x:%02x:%02x:%02x",
mac->data[0], mac->data[1], mac->data[2],
mac->data[3], mac->data[4], mac->data[5]);
}
g_byte_array_free (mac, TRUE); g_byte_array_free (mac, TRUE);
} }
} else { } else {
@@ -1923,7 +1942,8 @@ error:
static NMConnection * static NMConnection *
wired_connection_from_ifcfg (const char *file, wired_connection_from_ifcfg (const char *file,
shvarFile *ifcfg, shvarFile *ifcfg,
gboolean unmanaged, gboolean nm_controlled,
char **unmanaged,
GError **error) GError **error)
{ {
NMConnection *connection = NULL; NMConnection *connection = NULL;
@@ -1950,7 +1970,7 @@ wired_connection_from_ifcfg (const char *file,
} }
nm_connection_add_setting (connection, con_setting); nm_connection_add_setting (connection, con_setting);
wired_setting = make_wired_setting (ifcfg, file, unmanaged, &s_8021x, error); wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error);
if (!wired_setting) { if (!wired_setting) {
g_object_unref (connection); g_object_unref (connection);
return NULL; return NULL;
@@ -2013,20 +2033,21 @@ NMConnection *
connection_from_file (const char *filename, connection_from_file (const char *filename,
const char *network_file, const char *network_file,
const char *test_type, /* for unit tests only */ const char *test_type, /* for unit tests only */
gboolean *ignored, char **unmanaged,
char **keyfile, char **keyfile,
GError **error, GError **error,
gboolean *ignore_error) gboolean *ignore_error)
{ {
NMConnection *connection = NULL; NMConnection *connection = NULL;
shvarFile *parsed; shvarFile *parsed;
char *type; char *type, *nmc = NULL;
char *nmc = NULL;
NMSetting *s_ip4; NMSetting *s_ip4;
char *ifcfg_name = NULL; char *ifcfg_name = NULL;
gboolean nm_controlled = TRUE;
g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (ignored != NULL, NULL); g_return_val_if_fail (unmanaged != NULL, NULL);
g_return_val_if_fail (*unmanaged == NULL, NULL);
g_return_val_if_fail (keyfile != NULL, NULL); g_return_val_if_fail (keyfile != NULL, NULL);
g_return_val_if_fail (*keyfile == NULL, NULL); g_return_val_if_fail (*keyfile == NULL, NULL);
@@ -2096,23 +2117,28 @@ connection_from_file (const char *filename,
g_free (nmc); g_free (nmc);
if (!strcmp (lower, "no") || !strcmp (lower, "n") || !strcmp (lower, "false")) if (!strcmp (lower, "no") || !strcmp (lower, "n") || !strcmp (lower, "false"))
*ignored = TRUE; nm_controlled = FALSE;
g_free (lower); g_free (lower);
} }
if (!strcasecmp (type, TYPE_ETHERNET)) if (!strcasecmp (type, TYPE_ETHERNET))
connection = wired_connection_from_ifcfg (filename, parsed, *ignored, error); connection = wired_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, error);
else if (!strcasecmp (type, TYPE_WIRELESS)) else if (!strcasecmp (type, TYPE_WIRELESS))
connection = wireless_connection_from_ifcfg (filename, parsed, *ignored, error); connection = wireless_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, error);
else { else {
g_set_error (error, ifcfg_plugin_error_quark (), 0, g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Unknown connection type '%s'", type); "Unknown connection type '%s'", type);
} }
if (nm_controlled) {
g_free (*unmanaged);
*unmanaged = NULL;
}
g_free (type); g_free (type);
/* Don't bother reading the connection fully if it's unmanaged */ /* Don't bother reading the connection fully if it's unmanaged */
if (!connection || *ignored) if (!connection || *unmanaged)
goto done; goto done;
s_ip4 = make_ip4_setting (parsed, network_file, error); s_ip4 = make_ip4_setting (parsed, network_file, error);

View File

@@ -29,7 +29,7 @@
NMConnection *connection_from_file (const char *filename, NMConnection *connection_from_file (const char *filename,
const char *network_file, const char *network_file,
const char *test_type, const char *test_type,
gboolean *ignored, char **unmanaged,
char **keyfile, char **keyfile,
GError **error, GError **error,
gboolean *ignore_error); gboolean *ignore_error);

View File

@@ -163,7 +163,7 @@ test_read_minimal (void)
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWired *s_wired; NMSettingWired *s_wired;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -286,7 +286,7 @@ test_read_unmanaged (void)
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWired *s_wired; NMSettingWired *s_wired;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -309,7 +309,10 @@ test_read_unmanaged (void)
ASSERT (nm_connection_verify (connection, &error), ASSERT (nm_connection_verify (connection, &error),
"unmanaged-verify", "failed to verify %s: %s", TEST_IFCFG_UNMANAGED, error->message); "unmanaged-verify", "failed to verify %s: %s", TEST_IFCFG_UNMANAGED, error->message);
ASSERT (unmanaged == TRUE, ASSERT (unmanaged != NULL,
"unmanaged-verify", "failed to verify %s: expected unmanaged", TEST_IFCFG_UNMANAGED);
ASSERT (strcmp (unmanaged, "mac:00:11:22:33:f8:9f") == 0,
"unmanaged-verify", "failed to verify %s: expected unmanaged", TEST_IFCFG_UNMANAGED); "unmanaged-verify", "failed to verify %s: expected unmanaged", TEST_IFCFG_UNMANAGED);
/* ===== CONNECTION SETTING ===== */ /* ===== CONNECTION SETTING ===== */
@@ -396,7 +399,7 @@ test_read_wired_static (void)
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWired *s_wired; NMSettingWired *s_wired;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = FALSE;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -593,7 +596,7 @@ test_read_wired_dhcp (void)
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWired *s_wired; NMSettingWired *s_wired;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -760,7 +763,7 @@ test_read_wired_global_gateway (void)
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWired *s_wired; NMSettingWired *s_wired;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -881,7 +884,7 @@ test_read_wired_never_default (void)
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWired *s_wired; NMSettingWired *s_wired;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -972,7 +975,7 @@ test_read_onboot_no (void)
{ {
NMConnection *connection; NMConnection *connection;
NMSettingConnection *s_con; NMSettingConnection *s_con;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -1022,7 +1025,7 @@ test_read_wired_8021x_peap_mschapv2 (void)
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
NMSetting8021x *s_8021x; NMSetting8021x *s_8021x;
NMSetting8021x *tmp_8021x; NMSetting8021x *tmp_8021x;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -1207,7 +1210,7 @@ test_read_wifi_open (void)
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -1379,7 +1382,7 @@ test_read_wifi_open_ssid_hex (void)
NMConnection *connection; NMConnection *connection;
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -1455,7 +1458,7 @@ static void
test_read_wifi_open_ssid_bad (const char *file, const char *test) test_read_wifi_open_ssid_bad (const char *file, const char *test)
{ {
NMConnection *connection; NMConnection *connection;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -1473,7 +1476,7 @@ test_read_wifi_open_ssid_quoted (void)
NMConnection *connection; NMConnection *connection;
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -1555,7 +1558,7 @@ test_read_wifi_wep (void)
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wsec; NMSettingWirelessSecurity *s_wsec;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -1815,7 +1818,7 @@ test_read_wifi_wep_adhoc (void)
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wsec; NMSettingWirelessSecurity *s_wsec;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -2073,7 +2076,7 @@ test_read_wifi_leap (void)
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wsec; NMSettingWirelessSecurity *s_wsec;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -2205,7 +2208,7 @@ test_read_wifi_wpa_psk (void)
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wsec; NMSettingWirelessSecurity *s_wsec;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -2515,7 +2518,7 @@ test_read_wifi_wpa_psk_adhoc (void)
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wsec; NMSettingWirelessSecurity *s_wsec;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -2698,7 +2701,7 @@ test_read_wifi_wpa_psk_hex (void)
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wsec; NMSettingWirelessSecurity *s_wsec;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -2847,7 +2850,7 @@ test_read_wifi_wpa_eap_tls (void)
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
NMSetting8021x *s_8021x; NMSetting8021x *s_8021x;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -2981,7 +2984,7 @@ test_read_wifi_wpa_eap_ttls_tls (void)
NMSettingWireless *s_wireless; NMSettingWireless *s_wireless;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
NMSetting8021x *s_8021x; NMSetting8021x *s_8021x;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -3137,7 +3140,7 @@ test_read_wifi_wep_eap_ttls_chap (void)
NMSettingWirelessSecurity *s_wsec; NMSettingWirelessSecurity *s_wsec;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
NMSetting8021x *s_8021x; NMSetting8021x *s_8021x;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GError *error = NULL; GError *error = NULL;
@@ -3307,7 +3310,7 @@ test_write_wired_static (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
@@ -3431,7 +3434,7 @@ test_write_wired_dhcp (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
@@ -3530,7 +3533,7 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
@@ -3651,7 +3654,7 @@ test_write_wifi_open (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GByteArray *ssid; GByteArray *ssid;
@@ -3771,7 +3774,7 @@ test_write_wifi_open_hex_ssid (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GByteArray *ssid; GByteArray *ssid;
@@ -3876,7 +3879,7 @@ test_write_wifi_wep (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GByteArray *ssid; GByteArray *ssid;
@@ -4012,7 +4015,7 @@ test_write_wifi_wep_adhoc (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GByteArray *ssid; GByteArray *ssid;
@@ -4160,7 +4163,7 @@ test_write_wifi_wpa_psk (const char *name,
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GByteArray *ssid; GByteArray *ssid;
@@ -4299,7 +4302,7 @@ test_write_wifi_wpa_psk_adhoc (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GByteArray *ssid; GByteArray *ssid;
@@ -4442,7 +4445,7 @@ test_write_wifi_wpa_eap_tls (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GByteArray *ssid; GByteArray *ssid;
@@ -4601,7 +4604,7 @@ test_write_wifi_wpa_eap_ttls_tls (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GByteArray *ssid; GByteArray *ssid;
@@ -4777,7 +4780,7 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void)
gboolean success; gboolean success;
GError *error = NULL; GError *error = NULL;
char *testfile = NULL; char *testfile = NULL;
gboolean unmanaged = FALSE; char *unmanaged = NULL;
char *keyfile = NULL; char *keyfile = NULL;
gboolean ignore_error = FALSE; gboolean ignore_error = FALSE;
GByteArray *ssid; GByteArray *ssid;

View File

@@ -16,8 +16,9 @@ libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS = \
$(GMODULE_CFLAGS) \ $(GMODULE_CFLAGS) \
$(DBUS_CFLAGS) \ $(DBUS_CFLAGS) \
$(POLKIT_CFLAGS) \ $(POLKIT_CFLAGS) \
$(GUDEV_CFLAGS) \
-DG_DISABLE_DEPRECATED \ -DG_DISABLE_DEPRECATED \
-I${top_srcdir}/system-settings/src \ -I${top_srcdir}/src/system-settings \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/libnm-util \
-I$(top_srcdir)/libnm-glib \ -I$(top_srcdir)/libnm-glib \
@@ -28,6 +29,7 @@ libnm_settings_plugin_ifcfg_suse_la_LIBADD = \
$(GLIB_LIBS) \ $(GLIB_LIBS) \
$(GMODULE_LIBS) \ $(GMODULE_LIBS) \
$(POLKIT_LIBS) \ $(POLKIT_LIBS) \
$(GUDEV_LIBS) \
$(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/libnm-glib/libnm_glib.la $(top_builddir)/libnm-glib/libnm_glib.la

View File

@@ -18,7 +18,8 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* (C) Copyright 2007 Red Hat, Inc. * (C) Copyright 2007 - 2009 Red Hat, Inc.
* (C) Copyright 2007 - 2008 Novell, Inc.
*/ */
#include <config.h> #include <config.h>
@@ -28,6 +29,9 @@
#include <string.h> #include <string.h>
#include <sys/inotify.h> #include <sys/inotify.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#ifndef NO_GIO #ifndef NO_GIO
#include <gio/gio.h> #include <gio/gio.h>
@@ -38,10 +42,14 @@
#include <nm-setting-connection.h> #include <nm-setting-connection.h>
#include <nm-setting-ip4-config.h> #include <nm-setting-ip4-config.h>
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h>
#include "plugin.h" #include "plugin.h"
#include "parser.h" #include "parser.h"
#include "nm-suse-connection.h" #include "nm-suse-connection.h"
#include "nm-system-config-interface.h" #include "nm-system-config-interface.h"
#include "wireless-helper.h"
#define IFCFG_PLUGIN_NAME "ifcfg-suse" #define IFCFG_PLUGIN_NAME "ifcfg-suse"
#define IFCFG_PLUGIN_INFO "(C) 2008 Novell, Inc. To report bugs please use the NetworkManager mailing list." #define IFCFG_PLUGIN_INFO "(C) 2008 Novell, Inc. To report bugs please use the NetworkManager mailing list."
@@ -50,8 +58,8 @@
static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0, G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
system_config_interface_init)) system_config_interface_init))
#define SC_PLUGIN_IFCFG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgPrivate)) #define SC_PLUGIN_IFCFG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgPrivate))
@@ -59,12 +67,11 @@ G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
#define IFCFG_FILE_PATH_TAG "ifcfg-file-path" #define IFCFG_FILE_PATH_TAG "ifcfg-file-path"
typedef struct { typedef struct {
DBusGConnection *dbus_connection; GUdevClient *client;
NMSystemConfigHalManager *hal_manager;
gboolean initialized; gboolean initialized;
GHashTable *connections; GHashTable *connections;
GHashTable *unmanaged_devices; GHashTable *unmanaged_specs;
guint32 default_gw; guint32 default_gw;
GFileMonitor *default_gw_monitor; GFileMonitor *default_gw_monitor;
@@ -163,114 +170,140 @@ monitor_routes (SCPluginIfcfg *self, const char *filename)
} }
} }
static char *
get_iface_by_udi (SCPluginIfcfg *self, const char *udi)
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
DBusGProxy *proxy;
char *iface = NULL;
proxy = dbus_g_proxy_new_for_name (priv->dbus_connection,
"org.freedesktop.Hal",
udi,
"org.freedesktop.Hal.Device");
dbus_g_proxy_call_with_timeout (proxy, "GetPropertyString", 10000, NULL,
G_TYPE_STRING, "net.interface", G_TYPE_INVALID,
G_TYPE_STRING, &iface, G_TYPE_INVALID);
g_object_unref (proxy);
return iface;
}
static void static void
read_connection (SCPluginIfcfg *self, const char *udi, NMDeviceType dev_type) read_connection (SCPluginIfcfg *self, GUdevDevice *device, NMDeviceType dev_type)
{ {
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
char *iface; const char *iface, *address;
guint32 ifindex;
iface = get_iface_by_udi (self, udi); iface = g_udev_device_get_name (device);
if (iface) { if (!iface)
if (parser_ignore_device (iface)) { return;
g_hash_table_insert (priv->unmanaged_devices, g_strdup (udi), GINT_TO_POINTER (1));
ifindex = (guint32) g_udev_device_get_property_as_uint64 (device, "IFINDEX");
if (parser_ignore_device (iface)) {
char *spec;
address = g_udev_device_get_sysfs_attr (device, "address");
if (address && (strlen (address) == 17)) {
spec = g_strdup_printf ("mac:%s", address);
g_hash_table_insert (priv->unmanaged_specs, GUINT_TO_POINTER (ifindex), spec);
g_signal_emit_by_name (self, "unmanaged-devices-changed"); g_signal_emit_by_name (self, "unmanaged-devices-changed");
} else { } else
NMSuseConnection *connection; PLUGIN_WARN (IFCFG_PLUGIN_NAME, " (%s) error getting hardware address", iface);
} else {
NMSuseConnection *connection;
connection = nm_suse_connection_new (iface, dev_type); connection = nm_suse_connection_new (iface, dev_type);
if (connection) { if (connection) {
g_hash_table_insert (priv->connections, g_strdup (udi), connection); g_hash_table_insert (priv->connections,
g_signal_emit_by_name (self, "connection-added", connection); GUINT_TO_POINTER (ifindex),
} connection);
g_signal_emit_by_name (self, "connection-added", connection);
} }
} }
g_free (iface);
} }
static void static void
read_connections_by_type (SCPluginIfcfg *self, NMDeviceType dev_type) read_connections_by_type (SCPluginIfcfg *self, NMDeviceType dev_type)
{ {
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
GSList *list; GList *devices, *iter;
GSList *iter;
list = nm_system_config_hal_manager_get_devices_of_type (priv->hal_manager, dev_type); if ( (dev_type != NM_DEVICE_TYPE_ETHERNET)
for (iter = list; iter; iter = iter->next) { && (dev_type != NM_DEVICE_TYPE_WIFI))
read_connection (self, (char *) iter->data, dev_type);
g_free (iter->data);
}
g_slist_free (list);
}
static void
device_added_cb (NMSystemConfigHalManager *hal_mgr,
const char *udi,
NMDeviceType dev_type,
gpointer user_data)
{
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
if (dev_type != NM_DEVICE_TYPE_ETHERNET && dev_type != NM_DEVICE_TYPE_WIFI)
return; return;
read_connection (self, udi, dev_type); devices = g_udev_client_query_by_subsystem (priv->client, "net");
for (iter = devices; iter; iter = g_list_next (iter)) {
read_connection (self, G_UDEV_DEVICE (iter->data), dev_type);
g_object_unref (G_UDEV_DEVICE (iter->data));
}
g_list_free (devices);
}
static gboolean
is_wireless (GUdevDevice *device)
{
char phy80211_path[255];
struct stat s;
int fd;
struct iwreq iwr;
const char *ifname, *path;
gboolean is_wifi = FALSE;
ifname = g_udev_device_get_name (device);
g_assert (ifname);
fd = socket (PF_INET, SOCK_DGRAM, 0);
strncpy (iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ);
path = g_udev_device_get_sysfs_path (device);
snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", path);
if ( (ioctl (fd, SIOCGIWNAME, &iwr) == 0)
|| (stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR)))
is_wifi = TRUE;
close (fd);
return is_wifi;
} }
static void static void
device_removed_cb (NMSystemConfigHalManager *hal_mgr, handle_uevent (GUdevClient *client,
const char *udi, const char *action,
NMDeviceType dev_type, GUdevDevice *device,
gpointer user_data) gpointer user_data)
{ {
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data); SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
NMExportedConnection *exported; const char *subsys;
gboolean wifi;
if (dev_type != NM_DEVICE_TYPE_ETHERNET && dev_type != NM_DEVICE_TYPE_WIFI) g_return_if_fail (action != NULL);
return;
if (g_hash_table_remove (priv->unmanaged_devices, udi)) /* A bit paranoid */
g_signal_emit_by_name (self, "unmanaged-devices-changed"); subsys = g_udev_device_get_subsystem (device);
g_return_if_fail (subsys != NULL);
g_return_if_fail (strcmp (subsys, "net") == 0);
exported = (NMExportedConnection *) g_hash_table_lookup (priv->connections, udi); wifi = is_wireless (device);
if (exported) {
nm_exported_connection_signal_removed (exported); if (!strcmp (action, "add")) {
g_hash_table_remove (priv->connections, udi); read_connection (self,
device,
wifi ? NM_DEVICE_TYPE_WIFI : NM_DEVICE_TYPE_ETHERNET);
} else if (!strcmp (action, "remove")) {
NMExportedConnection *exported;
guint32 ifindex;
ifindex = (guint32) g_udev_device_get_property_as_uint64 (device, "IFINDEX");
if (g_hash_table_remove (priv->unmanaged_specs, GUINT_TO_POINTER (ifindex)))
g_signal_emit_by_name (self, "unmanaged-devices-changed");
exported = (NMExportedConnection *) g_hash_table_lookup (priv->connections,
GUINT_TO_POINTER (ifindex));
if (exported) {
nm_exported_connection_signal_removed (exported);
g_hash_table_remove (priv->connections, GUINT_TO_POINTER (ifindex));
}
} }
} }
static void static void
init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager) init (NMSystemConfigInterface *config)
{ {
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config); SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
const char *subsys[2] = { "net", NULL };
priv->hal_manager = g_object_ref (hal_manager); priv->client = g_udev_client_new (subsys);
if (!priv->client) {
g_signal_connect (priv->hal_manager, "device-added", G_CALLBACK (device_added_cb), self); PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error initializing libgudev");
g_signal_connect (priv->hal_manager, "device-removed", G_CALLBACK (device_removed_cb), self); } else
g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
} }
static void static void
@@ -309,21 +342,21 @@ get_connections (NMSystemConfigInterface *config)
} }
static void static void
get_unamanged_devices_cb (gpointer key, gpointer val, gpointer user_data) add_one_unmanaged_spec (gpointer key, gpointer val, gpointer user_data)
{ {
GSList **list = (GSList **) key; GSList **list = (GSList **) key;
*list = g_slist_prepend (*list, g_strdup ((char *) key)); *list = g_slist_prepend (*list, g_strdup ((const char *) val));
} }
static GSList * static GSList *
get_unmanaged_devices (NMSystemConfigInterface *config) get_unmanaged_specs (NMSystemConfigInterface *config)
{ {
SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
GSList *list = NULL; GSList *list = NULL;
g_hash_table_foreach (SC_PLUGIN_IFCFG_GET_PRIVATE (config)->unmanaged_devices, g_hash_table_foreach (priv->unmanaged_specs, add_one_unmanaged_spec, &list);
get_unamanged_devices_cb, &list);
return list; return list;
} }
@@ -331,17 +364,9 @@ static void
sc_plugin_ifcfg_init (SCPluginIfcfg *self) sc_plugin_ifcfg_init (SCPluginIfcfg *self)
{ {
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
GError *err = NULL;
priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
priv->unmanaged_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); priv->unmanaged_specs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
if (!priv->dbus_connection) {
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " dbus-glib error: %s",
err->message ? err->message : "(unknown)");
g_error_free (err);
}
} }
static void static void
@@ -350,7 +375,7 @@ dispose (GObject *object)
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object);
g_hash_table_destroy (priv->connections); g_hash_table_destroy (priv->connections);
g_hash_table_destroy (priv->unmanaged_devices); g_hash_table_destroy (priv->unmanaged_specs);
if (priv->default_gw_monitor) { if (priv->default_gw_monitor) {
if (priv->default_gw_monitor_id) if (priv->default_gw_monitor_id)
@@ -360,10 +385,8 @@ dispose (GObject *object)
g_object_unref (priv->default_gw_monitor); g_object_unref (priv->default_gw_monitor);
} }
if (priv->hal_manager) if (priv->client)
g_object_unref (priv->hal_manager); g_object_unref (priv->client);
dbus_g_connection_unref (priv->dbus_connection);
G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object); G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
} }
@@ -423,7 +446,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
{ {
/* interface implementation */ /* interface implementation */
system_config_interface_class->get_connections = get_connections; system_config_interface_class->get_connections = get_connections;
system_config_interface_class->get_unmanaged_devices = get_unmanaged_devices; system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;
system_config_interface_class->init = init; system_config_interface_class->init = init;
} }

View File

@@ -1,29 +1,34 @@
INCLUDES = \ INCLUDES = \
-I${top_srcdir}/src -I$(top_srcdir)/src/system-settings \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-glib \
-I$(top_srcdir)/libnm-util
pkglib_LTLIBRARIES = libnm-settings-plugin-ifupdown.la pkglib_LTLIBRARIES = libnm-settings-plugin-ifupdown.la
libnm_settings_plugin_ifupdown_la_SOURCES = \ libnm_settings_plugin_ifupdown_la_SOURCES = \
interface_parser.c interface_parser.h \ interface_parser.c \
nm-ifupdown-connection.c nm-ifupdown-connection.h \ interface_parser.h \
parser.c parser.h \ nm-ifupdown-connection.c \
plugin.c plugin.h nm-ifupdown-connection.h \
parser.c \
parser.h \
plugin.c \
plugin.h
libnm_settings_plugin_ifupdown_la_CPPFLAGS = \ libnm_settings_plugin_ifupdown_la_CPPFLAGS = \
$(GLIB_CFLAGS) \ $(GLIB_CFLAGS) \
$(GMODULE_CFLAGS) \ $(GMODULE_CFLAGS) \
$(DBUS_CFLAGS) \ $(DBUS_CFLAGS) \
$(GUDEV_CFLAGS) \
-DG_DISABLE_DEPRECATED \ -DG_DISABLE_DEPRECATED \
-I${top_srcdir}/system-settings/src \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-glib \
-I$(top_srcdir)/libnm-util \
-DSYSCONFDIR=\"$(sysconfdir)\" -DSYSCONFDIR=\"$(sysconfdir)\"
libnm_settings_plugin_ifupdown_la_LDFLAGS = -module -avoid-version libnm_settings_plugin_ifupdown_la_LDFLAGS = -module -avoid-version
libnm_settings_plugin_ifupdown_la_LIBADD = \ libnm_settings_plugin_ifupdown_la_LIBADD = \
$(GLIB_LIBS) \ $(GLIB_LIBS) \
$(GMODULE_LIBS) \ $(GMODULE_LIBS) \
$(GUDEV_LIBS) \
$(top_builddir)/libnm-util/libnm-util.la $(top_builddir)/libnm-util/libnm-util.la

View File

@@ -22,7 +22,6 @@
#include "interface_parser.h" #include "interface_parser.h"
#include "NetworkManagerUtils.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service (ifupdown) /* NetworkManager system settings service (ifupdown)
* *
@@ -19,6 +19,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* (C) Copyright 2007,2008 Canonical Ltd. * (C) Copyright 2007,2008 Canonical Ltd.
* (C) Copyright 2009 Red Hat, Inc.
*/ */
#include <string.h> #include <string.h>
@@ -35,6 +36,7 @@
#include "interface_parser.h" #include "interface_parser.h"
#include "NetworkManager.h"
#include "nm-system-config-interface.h" #include "nm-system-config-interface.h"
#include "nm-setting-ip4-config.h" #include "nm-setting-ip4-config.h"
#include "nm-setting-wireless.h" #include "nm-setting-wireless.h"
@@ -50,6 +52,9 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h>
#define IFUPDOWN_PLUGIN_NAME "ifupdown" #define IFUPDOWN_PLUGIN_NAME "ifupdown"
#define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd. To report bugs please use the NetworkManager mailing list." #define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd. To report bugs please use the NetworkManager mailing list."
#define IFUPDOWN_SYSTEM_HOSTNAME_FILE "/etc/hostname" #define IFUPDOWN_SYSTEM_HOSTNAME_FILE "/etc/hostname"
@@ -65,14 +70,12 @@
#endif #endif
typedef struct { typedef struct {
GUdevClient *client;
DBusGConnection *g_connection;
NMSystemConfigHalManager *hal_mgr;
GHashTable *iface_connections; GHashTable *iface_connections;
gchar* hostname; gchar* hostname;
GHashTable *well_known_udis; GHashTable *well_known_ifaces;
gboolean unmanage_well_known; gboolean unmanage_well_known;
gulong inotify_event_id; gulong inotify_event_id;
@@ -92,8 +95,7 @@ static void
sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class); sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class);
static void static void
SCPluginIfupdown_init (NMSystemConfigInterface *config, SCPluginIfupdown_init (NMSystemConfigInterface *config);
NMSystemConfigHalManager *hal_manager);
/* Returns the plugins currently known list of connections. The returned /* Returns the plugins currently known list of connections. The returned
* list is freed by the system settings service. * list is freed by the system settings service.
@@ -102,12 +104,12 @@ static GSList*
SCPluginIfupdown_get_connections (NMSystemConfigInterface *config); SCPluginIfupdown_get_connections (NMSystemConfigInterface *config);
/* /*
* Return a list of HAL UDIs of devices which NetworkManager should not * Return a list of device specifications which NetworkManager should not
* manage. Returned list will be freed by the system settings service, and * manage. Returned list will be freed by the system settings service, and
* each element must be allocated using g_malloc() or its variants. * each element must be allocated using g_malloc() or its variants.
*/ */
static GSList* static GSList*
SCPluginIfupdown_get_unmanaged_devices (NMSystemConfigInterface *config); SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config);
/* GObject */ /* GObject */
@@ -142,7 +144,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
{ {
system_config_interface_class->init = SCPluginIfupdown_init; system_config_interface_class->init = SCPluginIfupdown_init;
system_config_interface_class->get_connections = SCPluginIfupdown_get_connections; system_config_interface_class->get_connections = SCPluginIfupdown_get_connections;
system_config_interface_class->get_unmanaged_devices = SCPluginIfupdown_get_unmanaged_devices; system_config_interface_class->get_unmanaged_specs = SCPluginIfupdown_get_unmanaged_specs;
} }
static void static void
@@ -174,329 +176,251 @@ sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class)
NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
} }
static GByteArray*
get_net_address_for_udi (DBusGConnection *g_connection,
const gchar* udi,
GError **error)
{
DBusGProxy *dev_proxy;
char *address = NULL;
GByteArray *mac_address = NULL;
dev_proxy = dbus_g_proxy_new_for_name (g_connection,
"org.freedesktop.Hal",
udi,
"org.freedesktop.Hal.Device");
if (!dev_proxy)
return NULL;
if (!dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyString", 10000, error,
G_TYPE_STRING, "net.address", G_TYPE_INVALID,
G_TYPE_STRING, &address, G_TYPE_INVALID)) {
goto out;
}
if (address && strlen (address)) {
struct ether_addr *dev_mac;
mac_address = g_byte_array_new();
dev_mac = ether_aton (address);
g_byte_array_append (mac_address, dev_mac->ether_addr_octet, ETH_ALEN);
}
out:
g_free(address);
g_object_unref (dev_proxy);
return mac_address;
}
static gchar*
get_iface_for_udi (DBusGConnection *g_connection,
const gchar* udi,
GError **error)
{
DBusGProxy *dev_proxy;
char *iface = NULL;
dev_proxy = dbus_g_proxy_new_for_name (g_connection,
"org.freedesktop.Hal",
udi,
"org.freedesktop.Hal.Device");
if (!dev_proxy)
return NULL;
if (dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyString", 10000, error,
G_TYPE_STRING, "net.interface", G_TYPE_INVALID,
G_TYPE_STRING, &iface, G_TYPE_INVALID)) {
g_object_unref (dev_proxy);
return iface;
}
g_object_unref (dev_proxy);
return NULL;
}
static void static void
bind_device_to_connection (NMSystemConfigInterface *config, bind_device_to_connection (SCPluginIfupdown *self,
DBusGConnection *g_connection, GUdevDevice *device,
const gchar* udi, NMExportedConnection *exported)
NMExportedConnection *exported_iface_connection)
{ {
GByteArray *mac_address; GByteArray *mac_address;
GError *error = NULL; NMConnection *connection;
NMConnection *iface_connection; NMSetting *s_wired = NULL;
NMSetting *wired_setting = NULL; NMSetting *s_wifi = NULL;
NMSetting *wireless_setting = NULL; const char *iface, *address;
struct ether_addr *tmp_mac;
iface_connection = nm_exported_connection_get_connection (exported_iface_connection); iface = g_udev_device_get_name (device);
if (!iface_connection) { if (!iface) {
nm_warning ("no device locking possible. NMExportedConnection doesnt have a real connection."); PLUGIN_WARN ("SCPluginIfupdown", "failed to get ifname for device.");
return; return;
} }
mac_address = get_net_address_for_udi (g_connection, udi, &error); connection = nm_exported_connection_get_connection (exported);
if (!connection) {
if(error) { PLUGIN_WARN ("SCPluginIfupdown", "no device locking possible. "
PLUGIN_PRINT ("SCPluginIfupdown", "getting mac address for managed device" "NMExportedConnection doesnt have a real connection.");
"failed: %s (%d)", error->message, error->code);
return; return;
} }
wired_setting = nm_connection_get_setting (iface_connection, address = g_udev_device_get_sysfs_attr (device, "address");
NM_TYPE_SETTING_WIRED); if (!address || !strlen (address)) {
wireless_setting = nm_connection_get_setting (iface_connection, PLUGIN_WARN ("SCPluginIfupdown", "failed to get MAC address for %s", iface);
NM_TYPE_SETTING_WIRELESS); return;
if (wired_setting) { }
tmp_mac = ether_aton (address);
if (!tmp_mac) {
PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s",
address, iface);
return;
}
mac_address = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (mac_address, &(tmp_mac->ether_addr_octet[0]), ETH_ALEN);
s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
s_wifi = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
if (s_wifi) {
PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting"); PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting");
g_object_set (wired_setting, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL);
} else if (wireless_setting) { } else if (s_wifi) {
PLUGIN_PRINT ("SCPluginIfupdown", "locking wireless connection setting"); PLUGIN_PRINT ("SCPluginIfupdown", "locking wireless connection setting");
g_object_set (wireless_setting, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL); g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL);
} }
if(mac_address) g_byte_array_free (mac_address, TRUE);
g_byte_array_free (mac_address, TRUE);
} }
static void static void
hal_device_added_cb (NMSystemConfigHalManager *hal_mgr, udev_device_added (SCPluginIfupdown *self, GUdevDevice *device)
const gchar* udi,
NMDeviceType devtype,
NMSystemConfigInterface *config)
{ {
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
gchar *iface = NULL; const char *iface, *path;
GError *error = NULL; NMExportedConnection *exported;
gpointer exported_iface_connection;
NMConnection *iface_connection = NULL;
iface = get_iface_for_udi (priv->g_connection, iface = g_udev_device_get_name (device);
udi, path = g_udev_device_get_sysfs_path (device);
&error); if (!iface || !path)
PLUGIN_PRINT("SCPlugin-Ifupdown",
"devices added (udi: %s, iface: %s)", udi, iface);
if(!iface)
return; return;
exported_iface_connection = PLUGIN_PRINT("SCPlugin-Ifupdown",
NM_EXPORTED_CONNECTION (g_hash_table_lookup (priv->iface_connections, iface)); "devices added (path: %s, iface: %s)", path, iface);
/* if we have a configured connection for this particular iface /* if we have a configured connection for this particular iface
* we want to either unmanage the device or lock it * we want to either unmanage the device or lock it
*/ */
if(!exported_iface_connection) exported = (NMExportedConnection *) g_hash_table_lookup (priv->iface_connections, iface);
goto out; if (!exported)
return;
iface_connection = nm_exported_connection_get_connection (exported_iface_connection); g_hash_table_insert (priv->well_known_ifaces, g_strdup (iface), g_object_ref (device));
if(!iface_connection)
goto out;
g_hash_table_insert (priv->well_known_udis, (gpointer)udi, "nothing");
if (ALWAYS_UNMANAGE || priv->unmanage_well_known) if (ALWAYS_UNMANAGE || priv->unmanage_well_known)
g_signal_emit_by_name (G_OBJECT(config), "unmanaged-devices-changed"); g_signal_emit_by_name (G_OBJECT (self), "unmanaged-devices-changed");
else else
bind_device_to_connection (config, priv->g_connection, udi, exported_iface_connection); bind_device_to_connection (self, device, exported);
out:
g_free (iface);
} }
static void static void
hal_device_removed_cb (NMSystemConfigHalManager *hal_mgr, udev_device_removed (SCPluginIfupdown *self, GUdevDevice *device)
const gchar* udi,
NMDeviceType devtype,
NMSystemConfigInterface *config)
{ {
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
const char *iface, *path;
iface = g_udev_device_get_name (device);
path = g_udev_device_get_sysfs_path (device);
if (!iface || !path)
return;
PLUGIN_PRINT("SCPlugin-Ifupdown", PLUGIN_PRINT("SCPlugin-Ifupdown",
"devices removed (udi: %s)", udi); "devices removed (path: %s, iface: %s)", path, iface);
if(!g_hash_table_remove (priv->well_known_udis, udi)) if (!g_hash_table_remove (priv->well_known_ifaces, iface))
return; return;
if (ALWAYS_UNMANAGE || priv->unmanage_well_known) if (ALWAYS_UNMANAGE || priv->unmanage_well_known)
g_signal_emit_by_name (G_OBJECT(config), "unmanaged-devices-changed"); g_signal_emit_by_name (G_OBJECT (self), "unmanaged-devices-changed");
} }
static void static void
hal_device_added_cb2 (gpointer data, handle_uevent (GUdevClient *client,
gpointer user_data) const char *action,
GUdevDevice *device,
gpointer user_data)
{ {
NMSystemConfigHalManager *hal_mgr = ((gpointer*)user_data)[0]; SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (user_data);
NMSystemConfigInterface *config = ((gpointer*)user_data)[1]; const char *subsys;
NMDeviceType devtype = GPOINTER_TO_INT(((gpointer*)user_data)[2]);
const gchar *udi = data;
hal_device_added_cb (hal_mgr, g_return_if_fail (action != NULL);
udi,
devtype, /* A bit paranoid */
config); subsys = g_udev_device_get_subsystem (device);
g_return_if_fail (subsys != NULL);
g_return_if_fail (strcmp (subsys, "net") == 0);
if (!strcmp (action, "add"))
udev_device_added (self, device);
else if (!strcmp (action, "remove"))
udev_device_removed (self, device);
} }
static void static void
SCPluginIfupdown_init (NMSystemConfigInterface *config, SCPluginIfupdown_init (NMSystemConfigInterface *config)
NMSystemConfigHalManager *hal_manager)
{ {
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (config);
GHashTable *auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal); SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
GHashTable *auto_ifaces;
if_block *block = NULL; if_block *block = NULL;
NMInotifyHelper *inotify_helper; NMInotifyHelper *inotify_helper;
GKeyFile* keyfile; GKeyFile* keyfile;
GError *error = NULL; GError *error = NULL;
GList *keys, *iter;
const char *subsys[2] = { "net", NULL };
auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal);
if(!priv->iface_connections) if(!priv->iface_connections)
priv->iface_connections = g_hash_table_new (g_str_hash, g_str_equal); priv->iface_connections = g_hash_table_new (g_str_hash, g_str_equal);
if(!priv->well_known_udis) if(!priv->well_known_ifaces)
priv->well_known_udis = g_hash_table_new (g_str_hash, g_str_equal); priv->well_known_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
PLUGIN_PRINT("SCPlugin-Ifupdown", "init!"); PLUGIN_PRINT("SCPlugin-Ifupdown", "init!");
priv->hal_mgr = g_object_ref (hal_manager);
g_signal_connect (G_OBJECT(hal_manager), priv->client = g_udev_client_new (subsys);
"device-added", if (!priv->client) {
G_CALLBACK(hal_device_added_cb), PLUGIN_WARN ("SCPlugin-Ifupdown", " error initializing libgudev");
config); } else
g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
g_signal_connect (G_OBJECT(hal_manager), priv->unmanage_well_known = IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT;
"device-removed",
G_CALLBACK(hal_device_removed_cb),
config);
inotify_helper = nm_inotify_helper_get (); inotify_helper = nm_inotify_helper_get ();
priv->inotify_event_id = g_signal_connect (inotify_helper, priv->inotify_event_id = g_signal_connect (inotify_helper,
"event", "event",
G_CALLBACK (update_system_hostname), G_CALLBACK (update_system_hostname),
config); config);
priv->inotify_system_hostname_wd = priv->inotify_system_hostname_wd =
nm_inotify_helper_add_watch (inotify_helper, IFUPDOWN_SYSTEM_HOSTNAME_FILE); nm_inotify_helper_add_watch (inotify_helper, IFUPDOWN_SYSTEM_HOSTNAME_FILE);
update_system_hostname(inotify_helper, NULL, NULL, config); update_system_hostname (inotify_helper, NULL, NULL, config);
ifparser_init(); /* Read in all the interfaces */
block = ifparser_getfirst(); ifparser_init ();
block = ifparser_getfirst ();
while (block) {
if(!strcmp ("auto", block->type))
g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1));
else if (!strcmp ("iface", block->type) && strcmp ("lo", block->name)) {
NMExportedConnection *exported;
while(block) {
if(!strcmp("auto", block->type)) {
g_hash_table_insert (auto_ifaces, block->name, "auto");
} else if (!strcmp ("iface", block->type) && strcmp ("lo", block->name)) {
NMExportedConnection *connection = g_hash_table_lookup(priv->iface_connections, block->name);
g_hash_table_remove (priv->iface_connections, block->name); g_hash_table_remove (priv->iface_connections, block->name);
connection = NM_EXPORTED_CONNECTION(nm_ifupdown_connection_new(block)); exported = NM_EXPORTED_CONNECTION (nm_ifupdown_connection_new (block));
ifupdown_update_connection_from_if_block (nm_exported_connection_get_connection(connection), ifupdown_update_connection_from_if_block (nm_exported_connection_get_connection (exported),
block); block);
g_hash_table_insert (priv->iface_connections, block->name, exported);
g_hash_table_insert (priv->iface_connections, block->name, connection);
} }
block = block -> next; block = block->next;
} }
{ /* Make 'auto' interfaces autoconnect=TRUE */
GList *keys = g_hash_table_get_keys (priv->iface_connections); keys = g_hash_table_get_keys (priv->iface_connections);
GList *key_it = keys; for (iter = keys; iter; iter = g_list_next (iter)) {
while(key_it) { NMExportedConnection *exported;
gpointer val = g_hash_table_lookup(auto_ifaces, key_it->data); NMConnection *wrapped;
if(val) { NMSetting *setting;
NMExportedConnection *connection =
g_hash_table_lookup(priv->iface_connections, key_it->data); if (!g_hash_table_lookup (auto_ifaces, iter->data))
NMConnection *wrapped = NULL; continue;
NMSetting *setting;
g_object_get(connection, exported = g_hash_table_lookup (priv->iface_connections, iter->data);
NM_EXPORTED_CONNECTION_CONNECTION, &wrapped, NULL); wrapped = nm_exported_connection_get_connection (exported);
setting = NM_SETTING(nm_connection_get_setting setting = NM_SETTING (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
(wrapped, NM_TYPE_SETTING_CONNECTION)); g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL);
g_object_set (setting, PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect");
"autoconnect", TRUE, }
NULL); g_list_free (keys);
PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect"); g_hash_table_destroy (auto_ifaces);
}
key_it = key_it -> next;
}
}
priv->unmanage_well_known = IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT;
keyfile = g_key_file_new (); keyfile = g_key_file_new ();
if (!g_key_file_load_from_file (keyfile, if (!g_key_file_load_from_file (keyfile,
IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE,
G_KEY_FILE_NONE, G_KEY_FILE_NONE,
&error)) { &error)) {
nm_info ("loading system config file (%s) caused error: %s (%d)", nm_info ("loading system config file (%s) caused error: (%d) %s",
IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE,
error->message, error ? error->code : -1,
error->code); error && error->message ? error->message : "(unknown)");
} else { } else {
gboolean manage_well_known; gboolean manage_well_known;
error = NULL; error = NULL;
manage_well_known = g_key_file_get_boolean (keyfile, manage_well_known = g_key_file_get_boolean (keyfile,
IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_GROUP,
IFUPDOWN_KEY_FILE_KEY_MANAGED, IFUPDOWN_KEY_FILE_KEY_MANAGED,
&error); &error);
if (error) { if (error) {
nm_info ("getting keyfile key '%s' in group '%s' failed: %s (%d)", nm_info ("getting keyfile key '%s' in group '%s' failed: (%d) %s",
IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_GROUP,
IFUPDOWN_KEY_FILE_KEY_MANAGED, IFUPDOWN_KEY_FILE_KEY_MANAGED,
error->message, error ? error->code : -1,
error->code); error && error->message ? error->message : "(unknown)");
} else { } else
priv->unmanage_well_known = !manage_well_known; priv->unmanage_well_known = !manage_well_known;
}
} }
PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed"); PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed");
if (keyfile) if (keyfile)
g_key_file_free (keyfile); g_key_file_free (keyfile);
{ /* Add well-known interfaces */
/* init well_known_udis */ keys = g_udev_client_query_by_subsystem (priv->client, "net");
GSList *wired_devices = nm_system_config_hal_manager_get_devices_of_type (hal_manager, NM_DEVICE_TYPE_ETHERNET); for (iter = keys; iter; iter = g_list_next (iter)) {
GSList *wifi_devices = nm_system_config_hal_manager_get_devices_of_type (hal_manager, NM_DEVICE_TYPE_WIFI); udev_device_added (self, G_UDEV_DEVICE (iter->data));
gpointer *user_data; g_object_unref (G_UDEV_DEVICE (iter->data));
}
g_list_free (keys);
/* 3g in /etc/network/interfaces? no clue if thats mappable
GSList *gsm_devices = nm_system_config_hal_manager_get_devices_of_type (hal_manager, NM_DEVICE_TYPE_GSM);
GSList *cdma_devices = nm_system_config_hal_manager_get_devices_of_type (hal_manager, NM_DEVICE_TYPE_CDMA);
*/
user_data = g_new0 (gpointer, 3);
user_data[0] = hal_manager;
user_data[1] = config;
user_data[2] = GINT_TO_POINTER (NM_DEVICE_TYPE_ETHERNET);
g_slist_foreach (wired_devices, hal_device_added_cb2, user_data);
user_data[0] = hal_manager;
user_data[1] = config;
user_data[2] = GINT_TO_POINTER (NM_DEVICE_TYPE_ETHERNET);
g_slist_foreach (wifi_devices, hal_device_added_cb2, user_data);
}
g_hash_table_unref(auto_ifaces);
PLUGIN_PRINT("SCPlugin-Ifupdown", "end _init."); PLUGIN_PRINT("SCPlugin-Ifupdown", "end _init.");
} }
@@ -523,27 +447,37 @@ SCPluginIfupdown_get_connections (NMSystemConfigInterface *config)
} }
/* /*
* Return a list of HAL UDIs of devices which NetworkManager should not * Return a list of device specifications which NetworkManager should not
* manage. Returned list will be freed by the system settings service, and * manage. Returned list will be freed by the system settings service, and
* each element must be allocated using g_malloc() or its variants. * each element must be allocated using g_malloc() or its variants.
*/ */
static GSList* static GSList*
SCPluginIfupdown_get_unmanaged_devices (NMSystemConfigInterface *config) SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config)
{ {
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
GList *keys; GList *keys, *iter;
GSList *udis = NULL; GSList *specs = NULL;
if (!ALWAYS_UNMANAGE && !priv->unmanage_well_known) if (!ALWAYS_UNMANAGE && !priv->unmanage_well_known)
return NULL; return NULL;
keys = g_hash_table_get_keys (priv->well_known_udis); keys = g_hash_table_get_keys (priv->well_known_ifaces);
PLUGIN_PRINT("Ifupdown", "get unmanaged devices count: %d", g_list_length(keys)); PLUGIN_PRINT("Ifupdown", "get unmanaged devices count: %d", g_list_length (keys));
while(keys) {
udis = g_slist_append(udis, g_strdup(keys->data)); for (iter = keys; iter; iter = g_list_next (iter)) {
keys = g_list_next(keys); GUdevDevice *device = G_UDEV_DEVICE (iter->data);
const char *address;
char *spec;
address = g_udev_device_get_sysfs_attr (device, "address");
if (!address)
continue;
spec = g_strdup_printf ("mac:%s", address);
specs = g_slist_append (specs, spec);
} }
return udis; g_list_free (keys);
return specs;
} }
@@ -615,15 +549,6 @@ write_system_hostname(NMSystemConfigInterface *config,
static void static void
sc_plugin_ifupdown_init (SCPluginIfupdown *plugin) sc_plugin_ifupdown_init (SCPluginIfupdown *plugin)
{ {
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (plugin);
GError *error = NULL;
priv->g_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (!priv->g_connection) {
PLUGIN_PRINT ("SCPlugin-Ifupdown", " dbus-glib error: %s",
error->message ? error->message : "(unknown)");
g_error_free (error);
}
} }
static void static void
@@ -685,10 +610,12 @@ GObject__dispose (GObject *object)
if (priv->inotify_system_hostname_wd >= 0) if (priv->inotify_system_hostname_wd >= 0)
nm_inotify_helper_remove_watch (inotify_helper, priv->inotify_system_hostname_wd); nm_inotify_helper_remove_watch (inotify_helper, priv->inotify_system_hostname_wd);
if (priv->well_known_udis) if (priv->well_known_ifaces)
g_hash_table_destroy(priv->well_known_udis); g_hash_table_destroy(priv->well_known_ifaces);
if (priv->client)
g_object_unref (priv->client);
g_object_unref (priv->hal_mgr);
G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->dispose (object); G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->dispose (object);
} }

View File

@@ -1,7 +1,7 @@
SUBDIRS=io tests SUBDIRS=io tests
INCLUDES = \ INCLUDES = \
-I$(top_srcdir)/system-settings/src \ -I$(top_srcdir)/src/system-settings \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/libnm-util \
-I$(top_srcdir)/libnm-glib \ -I$(top_srcdir)/libnm-glib \

View File

@@ -354,10 +354,10 @@ add_connection (NMSystemConfigInterface *config,
} }
static GSList * static GSList *
get_unmanaged_devices (NMSystemConfigInterface *config) get_unmanaged_specs (NMSystemConfigInterface *config)
{ {
GKeyFile *key_file; GKeyFile *key_file;
GSList *unmanaged_devices = NULL; GSList *specs = NULL;
GError *error = NULL; GError *error = NULL;
key_file = g_key_file_new (); key_file = g_key_file_new ();
@@ -373,7 +373,7 @@ get_unmanaged_devices (NMSystemConfigInterface *config)
g_free (str); g_free (str);
for (i = 0; udis[i] != NULL; i++) for (i = 0; udis[i] != NULL; i++)
unmanaged_devices = g_slist_append (unmanaged_devices, udis[i]); specs = g_slist_append (specs, udis[i]);
g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */ g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */
} }
@@ -384,7 +384,7 @@ get_unmanaged_devices (NMSystemConfigInterface *config)
g_key_file_free (key_file); g_key_file_free (key_file);
return unmanaged_devices; return specs;
} }
static char * static char *
@@ -567,7 +567,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
/* interface implementation */ /* interface implementation */
system_config_interface_class->get_connections = get_connections; system_config_interface_class->get_connections = get_connections;
system_config_interface_class->add_connection = add_connection; system_config_interface_class->add_connection = add_connection;
system_config_interface_class->get_unmanaged_devices = get_unmanaged_devices; system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;
} }
G_MODULE_EXPORT GObject * G_MODULE_EXPORT GObject *

View File

@@ -1,900 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* Søren Sandmann <sandmann@daimi.au.dk>
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2007 - 2008 Red Hat, Inc.
*/
#include <syslog.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
#include <signal.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gmodule.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <nm-connection.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
#include <nm-setting-pppoe.h>
#include <nm-settings.h>
#include <nm-utils.h>
#include <NetworkManager.h>
#include "nm-glib-compat.h"
#include "dbus-settings.h"
#include "nm-system-config-hal-manager.h"
#include "nm-system-config-interface.h"
#include "nm-default-wired-connection.h"
#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default"
static GMainLoop *loop = NULL;
static gboolean debug = FALSE;
typedef struct {
DBusConnection *connection;
DBusGConnection *g_connection;
DBusGProxy *bus_proxy;
NMSystemConfigHalManager *hal_mgr;
NMSysconfigSettings *settings;
GHashTable *wired_devices;
const char *config;
} Application;
NMSystemConfigHalManager *nm_system_config_hal_manager_get (DBusGConnection *g_connection);
void nm_system_config_hal_manager_shutdown (NMSystemConfigHalManager *self);
static gboolean dbus_init (Application *app);
static gboolean start_dbus_service (Application *app);
static void destroy_cb (DBusGProxy *proxy, gpointer user_data);
static void device_added_cb (DBusGProxy *proxy, const char *udi, NMDeviceType devtype, gpointer user_data);
static GQuark
plugins_error_quark (void)
{
static GQuark error_quark = 0;
if (G_UNLIKELY (error_quark == 0))
error_quark = g_quark_from_static_string ("plugins-error-quark");
return error_quark;
}
static GObject *
find_plugin (GSList *list, const char *pname)
{
GSList *iter;
GObject *obj = NULL;
g_return_val_if_fail (pname != NULL, FALSE);
for (iter = list; iter && !obj; iter = g_slist_next (iter)) {
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
char *list_pname = NULL;
g_object_get (G_OBJECT (plugin),
NM_SYSTEM_CONFIG_INTERFACE_NAME,
&list_pname,
NULL);
if (list_pname && !strcmp (pname, list_pname))
obj = G_OBJECT (plugin);
g_free (list_pname);
}
return obj;
}
static gboolean
load_plugins (Application *app, const char *plugins, GError **error)
{
GSList *list = NULL;
char **plist;
char **iter;
plist = g_strsplit (plugins, ",", 0);
if (!plist)
return FALSE;
for (iter = plist; *iter; iter++) {
GModule *plugin;
char *full_name, *path;
const char *pname = *iter;
GObject *obj;
GObject * (*factory_func) (void);
/* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */
if (!strcmp (pname, "ifcfg-fedora"))
pname = "ifcfg-rh";
obj = find_plugin (list, pname);
if (obj)
continue;
full_name = g_strdup_printf ("nm-settings-plugin-%s", pname);
path = g_module_build_path (PLUGINDIR, full_name);
plugin = g_module_open (path, G_MODULE_BIND_LOCAL);
if (!plugin) {
g_set_error (error, plugins_error_quark (), 0,
"Could not load plugin '%s': %s",
pname, g_module_error ());
g_free (full_name);
g_free (path);
break;
}
g_free (full_name);
g_free (path);
if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) {
g_set_error (error, plugins_error_quark (), 0,
"Could not find plugin '%s' factory function.",
pname);
break;
}
obj = (*factory_func) ();
if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) {
g_set_error (error, plugins_error_quark (), 0,
"Plugin '%s' returned invalid system config object.",
pname);
break;
}
g_module_make_resident (plugin);
g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin);
nm_sysconfig_settings_add_plugin (app->settings, NM_SYSTEM_CONFIG_INTERFACE (obj));
list = g_slist_append (list, obj);
}
g_strfreev (plist);
g_slist_foreach (list, (GFunc) g_object_unref, NULL);
g_slist_free (list);
return TRUE;
}
static gboolean
load_stuff (gpointer user_data)
{
Application *app = (Application *) user_data;
GSList *devs, *iter;
/* Grab wired devices to make default DHCP connections for them if needed */
devs = nm_system_config_hal_manager_get_devices_of_type (app->hal_mgr, NM_DEVICE_TYPE_ETHERNET);
for (iter = devs; iter; iter = g_slist_next (iter)) {
device_added_cb (NULL, (const char *) iter->data, NM_DEVICE_TYPE_ETHERNET, app);
g_free (iter->data);
}
g_slist_free (devs);
if (!start_dbus_service (app)) {
g_main_loop_quit (loop);
return FALSE;
}
return FALSE;
}
typedef struct {
Application *app;
NMDefaultWiredConnection *connection;
guint add_id;
guint updated_id;
guint deleted_id;
char *udi;
} WiredDeviceInfo;
static void
wired_device_info_destroy (gpointer user_data)
{
WiredDeviceInfo *info = (WiredDeviceInfo *) user_data;
if (info->add_id)
g_source_remove (info->add_id);
if (info->updated_id)
g_source_remove (info->updated_id);
if (info->deleted_id)
g_source_remove (info->deleted_id);
if (info->connection) {
nm_sysconfig_settings_remove_connection (info->app->settings,
NM_EXPORTED_CONNECTION (info->connection),
TRUE);
g_object_unref (info->connection);
}
g_free (info);
}
static char *
get_details_for_udi (Application *app, const char *udi, struct ether_addr *mac)
{
DBusGProxy *dev_proxy = NULL;
char *address = NULL;
char *iface = NULL;
struct ether_addr *temp;
GError *error = NULL;
g_return_val_if_fail (app != NULL, FALSE);
g_return_val_if_fail (udi != NULL, FALSE);
g_return_val_if_fail (mac != NULL, FALSE);
dev_proxy = dbus_g_proxy_new_for_name (app->g_connection,
"org.freedesktop.Hal",
udi,
"org.freedesktop.Hal.Device");
if (!dev_proxy)
goto out;
if (!dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyString", 5000, &error,
G_TYPE_STRING, "net.address", G_TYPE_INVALID,
G_TYPE_STRING, &address, G_TYPE_INVALID)) {
g_message ("Error getting hardware address for %s: (%d) %s",
udi, error->code, error->message);
g_error_free (error);
goto out;
}
if (!address && !strlen (address))
goto out;
temp = ether_aton (address);
if (!temp)
goto out;
memcpy (mac, temp, sizeof (struct ether_addr));
if (!dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyString", 5000, &error,
G_TYPE_STRING, "net.interface", G_TYPE_INVALID,
G_TYPE_STRING, &iface, G_TYPE_INVALID)) {
g_message ("Error getting interface name for %s: (%d) %s",
udi, error->code, error->message);
g_error_free (error);
}
out:
g_free (address);
if (dev_proxy)
g_object_unref (dev_proxy);
return iface;
}
static gboolean
have_connection_for_device (Application *app, GByteArray *mac)
{
GSList *list, *iter;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
const GByteArray *setting_mac;
gboolean ret = FALSE;
g_return_val_if_fail (app != NULL, FALSE);
g_return_val_if_fail (mac != NULL, FALSE);
/* Find a wired connection locked to the given MAC address, if any */
list = nm_settings_list_connections (NM_SETTINGS (app->settings));
for (iter = list; iter; iter = g_slist_next (iter)) {
NMExportedConnection *exported = NM_EXPORTED_CONNECTION (iter->data);
NMConnection *connection;
const char *connection_type;
connection = nm_exported_connection_get_connection (exported);
if (!connection)
continue;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
connection_type = nm_setting_connection_get_connection_type (s_con);
if ( strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME)
&& strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
continue;
s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
/* No wired setting; therefore the PPPoE connection applies to any device */
if (!s_wired && !strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
ret = TRUE;
break;
}
setting_mac = nm_setting_wired_get_mac_address (s_wired);
if (setting_mac) {
/* A connection mac-locked to this device */
if (!memcmp (setting_mac->data, mac->data, ETH_ALEN)) {
ret = TRUE;
break;
}
} else {
/* A connection that applies to any wired device */
ret = TRUE;
break;
}
}
g_slist_free (list);
return ret;
}
/* Search through the list of blacklisted MAC addresses in the config file. */
static gboolean
is_mac_auto_wired_blacklisted (const GByteArray *mac, const char *filename)
{
GKeyFile *config;
char **list, **iter;
gboolean found = FALSE;
g_return_val_if_fail (mac != NULL, FALSE);
g_return_val_if_fail (filename != NULL, FALSE);
config = g_key_file_new ();
if (!config) {
g_warning ("%s: not enough memory to load config file.", __func__);
return FALSE;
}
g_key_file_set_list_separator (config, ',');
if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, NULL))
goto out;
list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL);
for (iter = list; iter && *iter; iter++) {
struct ether_addr *candidate;
candidate = ether_aton (*iter);
if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) {
found = TRUE;
break;
}
}
if (list)
g_strfreev (list);
out:
g_key_file_free (config);
return found;
}
static void
default_wired_deleted (NMDefaultWiredConnection *wired,
const GByteArray *mac,
WiredDeviceInfo *info)
{
NMConnection *wrapped;
NMSettingConnection *s_con;
char *tmp;
GKeyFile *config;
char **list, **iter, **updated;
gboolean found = FALSE;
gsize len = 0;
char *data;
/* If there was no config file specified, there's nothing to do */
if (!info->app->config)
goto cleanup;
/* When the default wired connection is removed (either deleted or saved
* to a new persistent connection by a plugin), write the MAC address of
* the wired device to the config file and don't create a new default wired
* connection for that device again.
*/
wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (wired));
g_assert (wrapped);
s_con = (NMSettingConnection *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
/* Ignore removals of read-only connections, since they couldn't have
* been removed by the user.
*/
if (nm_setting_connection_get_read_only (s_con))
goto cleanup;
config = g_key_file_new ();
if (!config)
goto cleanup;
g_key_file_set_list_separator (config, ',');
g_key_file_load_from_file (config, info->app->config, G_KEY_FILE_KEEP_COMMENTS, NULL);
list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL);
/* Traverse entire list to get count of # items */
for (iter = list; iter && *iter; iter++) {
struct ether_addr *candidate;
candidate = ether_aton (*iter);
if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN))
found = TRUE;
}
/* Add this device's MAC to the list */
if (!found) {
tmp = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x",
mac->data[0], mac->data[1], mac->data[2],
mac->data[3], mac->data[4], mac->data[5]);
updated = g_malloc0 (sizeof (char*) * (len + 2));
if (list && len)
memcpy (updated, list, len);
updated[len] = tmp;
g_key_file_set_string_list (config,
"main", CONFIG_KEY_NO_AUTO_DEFAULT,
(const char **) updated,
len + 1);
/* g_free() not g_strfreev() since 'updated' isn't a deep-copy */
g_free (updated);
g_free (tmp);
data = g_key_file_to_data (config, &len, NULL);
if (data) {
g_file_set_contents (info->app->config, data, len, NULL);
g_free (data);
}
}
if (list)
g_strfreev (list);
g_key_file_free (config);
cleanup:
/* Clear the connection first so that a 'removed' signal doesn't get emitted
* during wired_device_info_destroy(), becuase this connection removal
* is expected and already handled.
*/
g_object_unref (wired);
info->connection = NULL;
g_hash_table_remove (info->app->wired_devices, info->udi);
}
static GError *
default_wired_try_update (NMDefaultWiredConnection *wired,
GHashTable *new_settings,
WiredDeviceInfo *info)
{
GError *error = NULL;
NMConnection *wrapped;
NMSettingConnection *s_con;
const char *id;
/* Try to move this default wired conneciton to a plugin so that it has
* persistent storage.
*/
wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (wired));
g_assert (wrapped);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
id = nm_setting_connection_get_id (s_con);
g_assert (id);
nm_sysconfig_settings_remove_connection (info->app->settings, NM_EXPORTED_CONNECTION (wired), FALSE);
if (nm_sysconfig_settings_add_new_connection (info->app->settings, new_settings, &error)) {
g_message ("Saved default wired connection '%s' to persistent storage", id);
return NULL;
}
g_warning ("%s: couldn't save default wired connection '%s': %d / %s",
__func__, id, error ? error->code : -1,
(error && error->message) ? error->message : "(unknown)");
/* If there was an error, don't destroy the default wired connection,
* but add it back to the system settings service. Connection is already
* exported on the bus, don't export it again, thus do_export == FALSE.
*/
nm_sysconfig_settings_add_connection (info->app->settings, NM_EXPORTED_CONNECTION (wired), FALSE);
return error;
}
static gboolean
add_default_wired_connection (gpointer user_data)
{
WiredDeviceInfo *info = (WiredDeviceInfo *) user_data;
GByteArray *mac = NULL;
struct ether_addr tmp;
char *iface = NULL;
NMSettingConnection *s_con;
NMConnection *wrapped;
gboolean read_only = TRUE;
const char *id;
info->add_id = 0;
g_assert (info->connection == NULL);
/* If the device isn't managed, ignore it */
if (!nm_sysconfig_settings_is_device_managed (info->app->settings, info->udi))
goto ignore;
iface = get_details_for_udi (info->app, info->udi, &tmp);
if (!iface)
goto ignore;
mac = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (mac, tmp.ether_addr_octet, ETH_ALEN);
if (have_connection_for_device (info->app, mac))
goto ignore;
if (info->app->config && is_mac_auto_wired_blacklisted (mac, info->app->config))
goto ignore;
if (nm_sysconfig_settings_get_plugin (info->app->settings, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS))
read_only = FALSE;
info->connection = nm_default_wired_connection_new (mac, iface, read_only);
if (!info->connection)
goto ignore;
wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (info->connection));
g_assert (wrapped);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
id = nm_setting_connection_get_id (s_con);
g_assert (id);
g_message ("Added default wired connection '%s' for %s", id, info->udi);
info->updated_id = g_signal_connect (info->connection, "try-update",
(GCallback) default_wired_try_update, info);
info->deleted_id = g_signal_connect (info->connection, "deleted",
(GCallback) default_wired_deleted, info);
nm_sysconfig_settings_add_connection (info->app->settings,
NM_EXPORTED_CONNECTION (info->connection),
TRUE);
return FALSE;
ignore:
if (mac)
g_byte_array_free (mac, TRUE);
g_free (iface);
g_hash_table_remove (info->app->wired_devices, info->udi);
return FALSE;
}
static void
device_added_cb (DBusGProxy *proxy, const char *udi, NMDeviceType devtype, gpointer user_data)
{
Application *app = (Application *) user_data;
WiredDeviceInfo *info;
if (devtype != NM_DEVICE_TYPE_ETHERNET)
return;
/* Wait for a plugin to figure out if the device should be managed or not */
info = g_malloc0 (sizeof (WiredDeviceInfo));
info->app = app;
info->add_id = g_timeout_add_seconds (4, add_default_wired_connection, info);
info->udi = g_strdup (udi);
g_hash_table_insert (app->wired_devices, info->udi, info);
}
static void
device_removed_cb (DBusGProxy *proxy, const char *udi, NMDeviceType devtype, gpointer user_data)
{
Application *app = (Application *) user_data;
g_hash_table_remove (app->wired_devices, udi);
}
/******************************************************************/
static void
dbus_cleanup (Application *app)
{
if (app->g_connection) {
dbus_g_connection_unref (app->g_connection);
app->g_connection = NULL;
app->connection = NULL;
}
if (app->bus_proxy) {
g_signal_handlers_disconnect_by_func (app->bus_proxy, destroy_cb, app);
g_object_unref (app->bus_proxy);
app->bus_proxy = NULL;
}
}
static void
destroy_cb (DBusGProxy *proxy, gpointer user_data)
{
/* Clean up existing connection */
g_warning ("disconnected from the system bus, exiting.");
g_main_loop_quit (loop);
}
static gboolean
start_dbus_service (Application *app)
{
int request_name_result;
GError *err = NULL;
if (!dbus_g_proxy_call (app->bus_proxy, "RequestName", &err,
G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS,
G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
G_TYPE_INVALID,
G_TYPE_UINT, &request_name_result,
G_TYPE_INVALID)) {
g_warning ("Could not acquire the NetworkManagerSystemSettings service.\n"
" Message: '%s'", err->message);
g_error_free (err);
return FALSE;
}
if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
g_warning ("Could not acquire the NetworkManagerSystemSettings service "
"as it is already taken. Return: %d",
request_name_result);
return FALSE;
}
return TRUE;
}
static gboolean
dbus_init (Application *app)
{
GError *err = NULL;
dbus_connection_set_change_sigpipe (TRUE);
app->g_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
if (!app->g_connection) {
g_warning ("Could not get the system bus. Make sure "
"the message bus daemon is running! Message: %s",
err->message);
g_error_free (err);
return FALSE;
}
app->connection = dbus_g_connection_get_connection (app->g_connection);
dbus_connection_set_exit_on_disconnect (app->connection, FALSE);
app->bus_proxy = dbus_g_proxy_new_for_name (app->g_connection,
"org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus");
if (!app->bus_proxy) {
g_warning ("Could not get the DBus object!");
return FALSE;
}
g_signal_connect (app->bus_proxy, "destroy", G_CALLBACK (destroy_cb), app);
return TRUE;
}
static gboolean
parse_config_file (const char *filename, char **plugins, GError **error)
{
GKeyFile *config;
config = g_key_file_new ();
if (!config) {
g_set_error (error, plugins_error_quark (), 0,
"Not enough memory to load config file.");
return FALSE;
}
g_key_file_set_list_separator (config, ',');
if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, error))
return FALSE;
*plugins = g_key_file_get_value (config, "main", "plugins", error);
if (*error)
return FALSE;
g_key_file_free (config);
return TRUE;
}
static void
log_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer ignored)
{
int syslog_priority;
switch (log_level) {
case G_LOG_LEVEL_ERROR:
syslog_priority = LOG_CRIT;
break;
case G_LOG_LEVEL_CRITICAL:
syslog_priority = LOG_ERR;
break;
case G_LOG_LEVEL_WARNING:
syslog_priority = LOG_WARNING;
break;
case G_LOG_LEVEL_MESSAGE:
syslog_priority = LOG_NOTICE;
break;
case G_LOG_LEVEL_DEBUG:
syslog_priority = LOG_DEBUG;
break;
case G_LOG_LEVEL_INFO:
default:
syslog_priority = LOG_INFO;
break;
}
syslog (syslog_priority, "%s", message);
}
static void
logging_setup (void)
{
openlog (G_LOG_DOMAIN, LOG_CONS, LOG_DAEMON);
g_log_set_handler (G_LOG_DOMAIN,
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
log_handler,
NULL);
}
static void
logging_shutdown (void)
{
closelog ();
}
static void
signal_handler (int signo)
{
if (signo == SIGINT || signo == SIGTERM) {
if (debug)
g_message ("Caught signal %d, shutting down...", signo);
g_main_loop_quit (loop);
}
}
static void
setup_signals (void)
{
struct sigaction action;
sigset_t mask;
sigemptyset (&mask);
action.sa_handler = signal_handler;
action.sa_mask = mask;
action.sa_flags = 0;
sigaction (SIGTERM, &action, NULL);
sigaction (SIGINT, &action, NULL);
}
int
main (int argc, char **argv)
{
Application *app = g_new0 (Application, 1);
GOptionContext *opt_ctx;
GError *error = NULL;
char *plugins = NULL;
char *config = NULL;
GOptionEntry entries[] = {
{ "config", 0, 0, G_OPTION_ARG_FILENAME, &config, "Config file location", "/path/to/config.file" },
{ "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ,", "plugin1,plugin2" },
{ "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Output to console rather than syslog", NULL },
{ NULL }
};
opt_ctx = g_option_context_new (NULL);
g_option_context_set_summary (opt_ctx, "Provides system network settings to NetworkManager.");
g_option_context_add_main_entries (opt_ctx, entries, NULL);
if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) {
g_warning ("%s\n", error->message);
g_error_free (error);
return 1;
}
g_option_context_free (opt_ctx);
if (config) {
app->config = config;
if (!parse_config_file (app->config, &plugins, &error)) {
g_warning ("Invalid config file: %s.", error->message);
return 1;
}
}
if (!plugins) {
g_warning ("No plugins were specified.");
return 1;
}
g_type_init ();
if (!g_module_supported ()) {
g_warning ("GModules are not supported on your platform!");
return 1;
}
loop = g_main_loop_new (NULL, FALSE);
if (!debug)
logging_setup ();
if (!dbus_init (app))
return -1;
app->hal_mgr = nm_system_config_hal_manager_get (app->g_connection);
app->settings = nm_sysconfig_settings_new (app->g_connection, app->hal_mgr);
app->wired_devices = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, wired_device_info_destroy);
g_signal_connect (G_OBJECT (app->hal_mgr), "device-added",
G_CALLBACK (device_added_cb), app);
g_signal_connect (G_OBJECT (app->hal_mgr), "device-removed",
G_CALLBACK (device_removed_cb), app);
/* Load the plugins; fail if a plugin is not found. */
load_plugins (app, plugins, &error);
if (error) {
g_warning ("Error: %d - %s", error->code, error->message);
return -1;
}
g_free (plugins);
setup_signals ();
g_idle_add (load_stuff, app);
g_main_loop_run (loop);
nm_system_config_hal_manager_shutdown (app->hal_mgr);
g_object_unref (app->hal_mgr);
g_hash_table_destroy (app->wired_devices);
g_object_unref (app->settings);
dbus_cleanup (app);
if (!debug)
logging_shutdown ();
return 0;
}

View File

@@ -1,388 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*/
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include "nm-marshal.h"
#include "nm-dbus-glib-types.h"
#include "nm-system-config-hal-manager.h"
NMSystemConfigHalManager *nm_system_config_hal_manager_get (DBusGConnection *g_connection);
void nm_system_config_hal_manager_shutdown (NMSystemConfigHalManager *self);
#define NUM_DEVICE_TYPES NM_DEVICE_TYPE_CDMA
typedef struct {
DBusGConnection *g_connection;
DBusGProxy *proxy;
GHashTable *devices;
} NMSystemConfigHalManagerPrivate;
#define NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, \
NMSystemConfigHalManagerPrivate))
G_DEFINE_TYPE (NMSystemConfigHalManager, nm_system_config_hal_manager, G_TYPE_OBJECT)
enum {
DEVICE_ADDED,
DEVICE_REMOVED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
static NMDeviceType
get_type_for_udi (NMSystemConfigHalManager *manager, const char *udi)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
NMDeviceType devtype = NM_DEVICE_TYPE_UNKNOWN;
DBusGProxy *dev_proxy;
GError *error = NULL;
GSList *capabilities = NULL, *iter;
dev_proxy = dbus_g_proxy_new_for_name (priv->g_connection,
"org.freedesktop.Hal",
udi,
"org.freedesktop.Hal.Device");
if (!dev_proxy)
return NM_DEVICE_TYPE_UNKNOWN;
if (!dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyStringList", 10000, &error,
G_TYPE_STRING, "info.capabilities", G_TYPE_INVALID,
DBUS_TYPE_G_LIST_OF_STRING, &capabilities, G_TYPE_INVALID)) {
g_error_free (error);
goto out;
}
if (!g_slist_length (capabilities))
goto out;
for (iter = capabilities; iter && (devtype == NM_DEVICE_TYPE_UNKNOWN); iter = g_slist_next (iter)) {
if (!strcmp (iter->data, "net.80203"))
devtype = NM_DEVICE_TYPE_ETHERNET;
else if (!strcmp (iter->data, "net.80211"))
devtype = NM_DEVICE_TYPE_WIFI;
else if (!strcmp (iter->data, "modem")) {
GSList *csets = NULL, *elt;
if (dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyStringList", 10000, &error,
G_TYPE_STRING, "modem.command_sets", G_TYPE_INVALID,
DBUS_TYPE_G_LIST_OF_STRING, &csets, G_TYPE_INVALID)) {
for (elt = csets; elt && (devtype == NM_DEVICE_TYPE_UNKNOWN); elt = g_slist_next (elt)) {
if (!strcmp (elt->data, "GSM-07.07"))
devtype = NM_DEVICE_TYPE_GSM;
else if (!strcmp (elt->data, "IS-707-A"))
devtype = NM_DEVICE_TYPE_CDMA;
}
g_slist_foreach (csets, (GFunc) g_free, NULL);
g_slist_free (csets);
}
}
}
g_boxed_free (DBUS_TYPE_G_LIST_OF_STRING, capabilities);
out:
g_object_unref (dev_proxy);
return devtype;
}
static void
device_added_cb (DBusGProxy *proxy, const char *udi, gpointer user_data)
{
NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data);
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
NMDeviceType devtype;
if (!g_hash_table_lookup (priv->devices, udi)) {
devtype = get_type_for_udi (manager, udi);
if (devtype != NM_DEVICE_TYPE_UNKNOWN) {
g_hash_table_insert (priv->devices, g_strdup (udi), GUINT_TO_POINTER (devtype));
g_signal_emit (manager, signals[DEVICE_ADDED], 0, udi, devtype);
}
}
}
static void
device_removed_cb (DBusGProxy *proxy, const char *udi, gpointer user_data)
{
NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data);
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
NMDeviceType devtype;
devtype = GPOINTER_TO_UINT (g_hash_table_lookup (priv->devices, udi));
if (devtype != NM_DEVICE_TYPE_UNKNOWN) {
g_signal_emit (manager, signals[DEVICE_REMOVED], 0, udi, devtype);
g_hash_table_remove (priv->devices, udi);
}
}
static void
device_new_capability_cb (DBusGProxy *proxy,
const char *udi,
const char *capability,
gpointer user_data)
{
NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data);
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
NMDeviceType devtype;
if (!g_hash_table_lookup (priv->devices, udi)) {
devtype = get_type_for_udi (manager, udi);
if (devtype != NM_DEVICE_TYPE_UNKNOWN) {
g_hash_table_insert (priv->devices, g_strdup (udi), GUINT_TO_POINTER (devtype));
g_signal_emit (manager, signals[DEVICE_ADDED], 0, udi, devtype);
}
}
}
static void
initial_add_devices_of_type (NMSystemConfigHalManager *manager, const char *capability)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
GSList *devices = NULL, *iter;
GError *error = NULL;
if (!dbus_g_proxy_call_with_timeout (priv->proxy,
"FindDeviceByCapability", 10000, &error,
G_TYPE_STRING, capability, G_TYPE_INVALID,
DBUS_TYPE_G_LIST_OF_STRING, &devices, G_TYPE_INVALID)) {
g_warning ("%s: could not get device from HAL: %s (%d).",
__func__, error->message, error->code);
g_error_free (error);
return;
}
for (iter = devices; iter; iter = g_slist_next (iter))
device_added_cb (priv->proxy, (const char *) iter->data, manager);
if (devices)
g_boxed_free (DBUS_TYPE_G_LIST_OF_STRING, devices);
}
static gboolean
init_dbus (NMSystemConfigHalManager *manager, DBusGConnection *g_connection)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
priv->g_connection = g_connection;
priv->proxy = dbus_g_proxy_new_for_name (priv->g_connection,
"org.freedesktop.Hal",
"/org/freedesktop/Hal/Manager",
"org.freedesktop.Hal.Manager");
if (!priv->proxy) {
g_warning ("Could not get the HAL object!");
priv->g_connection = NULL;
return FALSE;
}
dbus_g_proxy_add_signal (priv->proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "DeviceAdded", G_CALLBACK (device_added_cb), manager, NULL);
dbus_g_proxy_add_signal (priv->proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "DeviceRemoved", G_CALLBACK (device_removed_cb), manager, NULL);
dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING,
G_TYPE_NONE,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_INVALID);
dbus_g_proxy_add_signal (priv->proxy, "NewCapability", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "NewCapability", G_CALLBACK (device_new_capability_cb), manager, NULL);
initial_add_devices_of_type (manager, "net.80203");
initial_add_devices_of_type (manager, "net.80211");
initial_add_devices_of_type (manager, "modem");
return TRUE;
}
static NMSystemConfigHalManager *
nm_system_config_hal_manager_new (DBusGConnection *g_connection)
{
NMSystemConfigHalManager *manager;
g_return_val_if_fail (g_connection != NULL, NULL);
manager = g_object_new (NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NULL);
if (!init_dbus (manager, g_connection)) {
g_object_unref (manager);
return NULL;
}
return manager;
}
NMSystemConfigHalManager *
nm_system_config_hal_manager_get (DBusGConnection *g_connection)
{
static NMSystemConfigHalManager *singleton = NULL;
if (!singleton)
singleton = nm_system_config_hal_manager_new (g_connection);
else
g_object_ref (singleton);
return singleton;
}
static void
nm_system_config_hal_manager_init (NMSystemConfigHalManager *manager)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
static void
signal_removed (gpointer key, gpointer data, gpointer user_data)
{
NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data);
g_signal_emit (manager, signals[DEVICE_REMOVED], 0, key, GPOINTER_TO_UINT (data));
}
void
nm_system_config_hal_manager_shutdown (NMSystemConfigHalManager *self)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (self);
g_hash_table_foreach (priv->devices, (GHFunc) signal_removed, self);
g_hash_table_remove_all (priv->devices);
}
static void
dispose (GObject *object)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (object);
if (priv->devices) {
g_hash_table_remove_all (priv->devices);
g_hash_table_destroy (priv->devices);
}
if (priv->proxy) {
g_object_unref (priv->proxy);
priv->proxy = NULL;
}
priv->g_connection = NULL;
G_OBJECT_CLASS (nm_system_config_hal_manager_parent_class)->dispose (object);
}
static void
nm_system_config_hal_manager_class_init (NMSystemConfigHalManagerClass *manager_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
g_type_class_add_private (manager_class, sizeof (NMSystemConfigHalManagerPrivate));
/* virtual methods */
object_class->dispose = dispose;
/* signals */
signals[DEVICE_ADDED] =
g_signal_new ("device-added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSystemConfigHalManagerClass, device_added),
NULL, NULL,
_nm_marshal_VOID__STRING_UINT,
G_TYPE_NONE, 2,
G_TYPE_STRING,
G_TYPE_UINT);
signals[DEVICE_REMOVED] =
g_signal_new ("device-removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSystemConfigHalManagerClass, device_removed),
NULL, NULL,
_nm_marshal_VOID__STRING_UINT,
G_TYPE_NONE, 2,
G_TYPE_STRING,
G_TYPE_UINT);
}
typedef struct {
NMDeviceType devtype;
GSList **list;
} GetDeviceInfo;
static void
add_devices_of_type (gpointer key, gpointer data, gpointer user_data)
{
GetDeviceInfo *info = (GetDeviceInfo *) user_data;
if (GPOINTER_TO_UINT (data) == info->devtype)
*(info->list) = g_slist_append (*(info->list), g_strdup (key));
}
GSList *
nm_system_config_hal_manager_get_devices_of_type (NMSystemConfigHalManager *manager,
NMDeviceType devtype)
{
NMSystemConfigHalManagerPrivate *priv;
GetDeviceInfo info;
GSList *list = NULL;
g_return_val_if_fail (NM_IS_SYSTEM_CONFIG_HAL_MANAGER (manager), NULL);
g_return_val_if_fail (devtype <= NUM_DEVICE_TYPES, NULL);
priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
info.devtype = devtype;
info.list = &list;
g_hash_table_foreach (priv->devices, (GHFunc) add_devices_of_type, &info);
return list;
}
NMDeviceType
nm_system_config_hal_manager_get_type_for_udi (NMSystemConfigHalManager *manager,
const char *udi)
{
NMSystemConfigHalManagerPrivate *priv;
g_return_val_if_fail (NM_IS_SYSTEM_CONFIG_HAL_MANAGER (manager), NM_DEVICE_TYPE_UNKNOWN);
g_return_val_if_fail (udi != NULL, NM_DEVICE_TYPE_UNKNOWN);
priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
return GPOINTER_TO_UINT (g_hash_table_lookup (priv->devices, udi));
}
DBusGProxy *
nm_system_config_hal_manager_get_hal_proxy (NMSystemConfigHalManager *manager)
{
g_return_val_if_fail (NM_IS_SYSTEM_CONFIG_HAL_MANAGER (manager), NULL);
return NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager)->proxy;
}

View File

@@ -1,58 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*/
#ifndef NM_SYSTEM_CONFIG_HAL_MANAGER_H
#define NM_SYSTEM_CONFIG_HAL_MANAGER_H
#include <glib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include "NetworkManager.h"
#define NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER (nm_system_config_hal_manager_get_type ())
#define NM_SYSTEM_CONFIG_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NMSystemConfigHalManager))
#define NM_SYSTEM_CONFIG_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NMSystemConfigHalManagerClass))
#define NM_IS_SYSTEM_CONFIG_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER))
#define NM_IS_SYSTEM_CONFIG_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER))
#define NM_SYSTEM_CONFIG_HAL_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NMSystemConfigHalManagerClass))
typedef struct {
GObject parent;
} NMSystemConfigHalManager;
typedef struct {
GObjectClass parent;
/* Signals */
void (*device_added) (NMSystemConfigHalManager *manager, const char *udi, NMDeviceType type);
void (*device_removed) (NMSystemConfigHalManager *manager, const char *udi, NMDeviceType type);
} NMSystemConfigHalManagerClass;
GType nm_system_config_hal_manager_get_type (void);
/* Returned list is allocated and must be freed by caller */
GSList *nm_system_config_hal_manager_get_devices_of_type (NMSystemConfigHalManager *manager, NMDeviceType devtype);
NMDeviceType nm_system_config_hal_manager_get_type_for_udi (NMSystemConfigHalManager *manager, const char *udi);
DBusGProxy *nm_system_config_hal_manager_get_hal_proxy (NMSystemConfigHalManager *manager);
#endif /* NM_SYSTEM_CONFIG_HAL_MANAGER_H */

View File

@@ -1,22 +0,0 @@
<!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.NetworkManagerSystemSettings"/>
<allow send_destination="org.freedesktop.NetworkManagerSystemSettings"/>
</policy>
<policy context="default">
<deny own="org.freedesktop.NetworkManagerSystemSettings"/>
<allow send_destination="org.freedesktop.NetworkManagerSystemSettings"/>
<!-- The org.freedesktop.NetworkManagerSettings.Connection.Secrets
interface is secured via PolicyKit.
-->
</policy>
<limit name="max_replies_per_connection">512</limit>
</busconfig>

View File

@@ -1,5 +0,0 @@
[D-BUS Service]
Name=org.freedesktop.NetworkManagerSystemSettings
Exec=@sbindir@/nm-system-settings --config /etc/NetworkManager/nm-system-settings.conf
User=root