diff options
Diffstat (limited to 'src/ppp-manager/nm-ppp-manager.c')
-rw-r--r-- | src/ppp-manager/nm-ppp-manager.c | 296 |
1 files changed, 157 insertions, 139 deletions
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index aa03c82a5..e856fc195 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -52,32 +52,28 @@ #include "nm-setting-cdma.h" #include "nm-dbus-manager.h" #include "nm-logging.h" -#include "nm-marshal.h" #include "nm-posix-signals.h" static void impl_ppp_manager_need_secrets (NMPPPManager *manager, DBusGMethodInvocation *context); static gboolean impl_ppp_manager_set_state (NMPPPManager *manager, - guint32 state, - GError **err); + guint32 state, + GError **err); static gboolean impl_ppp_manager_set_ip4_config (NMPPPManager *manager, - GHashTable *config, - GError **err); + GHashTable *config, + GError **err); #include "nm-ppp-manager-glue.h" static void _ppp_cleanup (NMPPPManager *manager); -#define NM_PPPD_PLUGIN PLUGINDIR "/nm-pppd-plugin.so" +#define NM_PPPD_PLUGIN PPPD_PLUGIN_DIR "/nm-pppd-plugin.so" #define PPP_MANAGER_SECRET_TRIES "ppp-manager-secret-tries" typedef struct { - gboolean disposed; - GPid pid; - NMDBusManager *dbus_manager; char *dbus_path; char *parent_iface; @@ -85,6 +81,7 @@ typedef struct { NMActRequest *act_req; DBusGMethodInvocation *pending_secrets_context; guint32 secrets_id; + const char *secrets_setting_name; guint32 ppp_watch_id; guint32 ppp_timeout_handler; @@ -135,34 +132,18 @@ nm_ppp_manager_init (NMPPPManager *manager) { } -static GObject * -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) +static void +constructed (GObject *object) { - GObject *object; - NMPPPManagerPrivate *priv; + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object); DBusGConnection *connection; static guint32 counter = 0; - object = G_OBJECT_CLASS (nm_ppp_manager_parent_class)->constructor (type, - n_construct_params, - construct_params); - if (!object) - return NULL; - - priv = NM_PPP_MANAGER_GET_PRIVATE (object); - priv->dbus_manager = nm_dbus_manager_get (); - if (!priv->dbus_manager) { - g_object_unref (object); - return NULL; - } - - connection = nm_dbus_manager_get_connection (priv->dbus_manager); priv->dbus_path = g_strdup_printf (NM_DBUS_PATH "/PPP/%d", counter++); + connection = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); dbus_g_connection_register_g_object (connection, priv->dbus_path, object); - return object; + G_OBJECT_CLASS (nm_ppp_manager_parent_class)->constructed (object); } static void @@ -170,19 +151,9 @@ dispose (GObject *object) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object); - if (priv->disposed == FALSE) { - priv->disposed = TRUE; + _ppp_cleanup (NM_PPP_MANAGER (object)); - _ppp_cleanup (NM_PPP_MANAGER (object)); - - if (priv->act_req) { - g_object_unref (priv->act_req); - priv->act_req = NULL; - } - - g_object_unref (priv->dbus_manager); - priv->dbus_manager = NULL; - } + g_clear_object (&priv->act_req); G_OBJECT_CLASS (nm_ppp_manager_parent_class)->dispose (object); } @@ -200,7 +171,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object); @@ -217,7 +188,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object); @@ -238,7 +209,7 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) g_type_class_add_private (manager_class, sizeof (NMPPPManagerPrivate)); - object_class->constructor = constructor; + object_class->constructed = constructed; object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; @@ -248,45 +219,42 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) g_object_class_install_property (object_class, PROP_PARENT_IFACE, g_param_spec_string (NM_PPP_MANAGER_PARENT_IFACE, - "ParentIface", - "Parent interface", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + "ParentIface", + "Parent interface", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /* signals */ signals[STATE_CHANGED] = g_signal_new ("state-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMPPPManagerClass, state_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMPPPManagerClass, state_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_UINT); signals[IP4_CONFIG] = g_signal_new ("ip4-config", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMPPPManagerClass, ip4_config), - NULL, NULL, - _nm_marshal_VOID__STRING_OBJECT, - G_TYPE_NONE, 2, - G_TYPE_STRING, - G_TYPE_OBJECT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMPPPManagerClass, ip4_config), + NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_STRING, + G_TYPE_OBJECT); signals[STATS] = g_signal_new ("stats", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMPPPManagerClass, stats), - NULL, NULL, - _nm_marshal_VOID__UINT_UINT, - G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMPPPManagerClass, stats), + NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_UINT, G_TYPE_UINT); dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class), - &dbus_glib_nm_ppp_manager_object_info); + &dbus_glib_nm_ppp_manager_object_info); } NMPPPManager * @@ -363,36 +331,50 @@ cancel_get_secrets (NMPPPManager *self) nm_act_request_cancel_secrets (priv->act_req, priv->secrets_id); priv->secrets_id = 0; } + priv->secrets_setting_name = NULL; } static gboolean extract_details_from_connection (NMConnection *connection, + const char *secrets_setting_name, const char **username, const char **password, GError **error) { NMSettingConnection *s_con; NMSetting *setting; - const char *connection_type; + const char *setting_name; g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (username != NULL, FALSE); g_return_val_if_fail (password != NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - connection_type = nm_setting_connection_get_connection_type (s_con); - g_assert (connection_type); + if (secrets_setting_name) + setting_name = secrets_setting_name; + else { + /* Get the setting matching the connection type */ + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + setting_name = nm_setting_connection_get_connection_type (s_con); + g_assert (setting_name); + + /* In case of bluetooth connection, use GSM or CDMA setting */ + if (strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0) { + if (nm_connection_get_setting_gsm (connection)) + setting_name = NM_SETTING_GSM_SETTING_NAME; + else + setting_name = NM_SETTING_CDMA_SETTING_NAME; + } + } - setting = nm_connection_get_setting_by_name (connection, connection_type); + setting = nm_connection_get_setting_by_name (connection, setting_name); if (!setting) { g_set_error_literal (error, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN, "Missing type-specific setting; no secrets could be found."); return FALSE; } - /* FIXME: push this down to the settings and keep PPP manager generic */ if (NM_IS_SETTING_PPPOE (setting)) { *username = nm_setting_pppoe_get_username (NM_SETTING_PPPOE (setting)); *password = nm_setting_pppoe_get_password (NM_SETTING_PPPOE (setting)); @@ -433,7 +415,7 @@ ppp_secrets_cb (NMActRequest *req, goto out; } - if (!extract_details_from_connection (connection, &username, &password, &local)) { + if (!extract_details_from_connection (connection, priv->secrets_setting_name, &username, &password, &local)) { nm_log_warn (LOGD_PPP, "%s", local->message); dbus_g_method_return_error (priv->pending_secrets_context, local); g_clear_error (&local); @@ -448,9 +430,10 @@ ppp_secrets_cb (NMActRequest *req, */ dbus_g_method_return (priv->pending_secrets_context, username, password); -out: + out: priv->pending_secrets_context = NULL; priv->secrets_id = 0; + priv->secrets_setting_name = NULL; } static void @@ -459,7 +442,6 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); NMConnection *connection; - const char *setting_name; const char *username = NULL; const char *password = NULL; guint32 tries; @@ -470,10 +452,10 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, connection = nm_act_request_get_connection (priv->act_req); nm_connection_clear_secrets (connection); - setting_name = nm_connection_need_secrets (connection, &hints); - if (!setting_name) { + priv->secrets_setting_name = nm_connection_need_secrets (connection, &hints); + if (!priv->secrets_setting_name) { /* Use existing secrets from the connection */ - if (extract_details_from_connection (connection, &username, &password, &error)) { + if (extract_details_from_connection (connection, NULL, &username, &password, &error)) { /* Send existing secrets to the PPP plugin */ priv->pending_secrets_context = context; ppp_secrets_cb (priv->act_req, priv->secrets_id, connection, NULL, manager); @@ -494,7 +476,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_req, - setting_name, + priv->secrets_setting_name, flags, hints ? g_ptr_array_index (hints, 0) : NULL, ppp_secrets_cb, @@ -507,8 +489,8 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, } static gboolean impl_ppp_manager_set_state (NMPPPManager *manager, - guint32 state, - GError **err) + guint32 state, + GError **err) { g_signal_emit (manager, signals[STATE_CHANGED], 0, state); @@ -517,14 +499,14 @@ static gboolean impl_ppp_manager_set_state (NMPPPManager *manager, static gboolean impl_ppp_manager_set_ip4_config (NMPPPManager *manager, - GHashTable *config_hash, - GError **err) + GHashTable *config_hash, + GError **err) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); NMConnection *connection; NMSettingPPP *s_ppp; NMIP4Config *config; - NMIP4Address *addr; + NMPlatformIP4Address address; GValue *val; int i; @@ -533,28 +515,28 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, remove_timeout_handler (manager); config = nm_ip4_config_new (); - addr = nm_ip4_address_new (); - nm_ip4_address_set_prefix (addr, 32); + memset (&address, 0, sizeof (address)); + address.plen = 32; val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_GATEWAY); if (val) { - nm_ip4_address_set_gateway (addr, g_value_get_uint (val)); - nm_ip4_config_set_ptp_address (config, g_value_get_uint (val)); + nm_ip4_config_set_gateway (config, g_value_get_uint (val)); + address.peer_address = g_value_get_uint (val); } val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_ADDRESS); if (val) - nm_ip4_address_set_address (addr, g_value_get_uint (val)); + address.address = g_value_get_uint (val); val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_PREFIX); if (val) - nm_ip4_address_set_prefix (addr, g_value_get_uint (val)); + address.plen = g_value_get_uint (val); - if (nm_ip4_address_get_address (addr) && nm_ip4_address_get_prefix (addr)) { - nm_ip4_config_take_address (config, addr); + if (address.address && address.plen) { + address.source = NM_PLATFORM_SOURCE_PPP; + nm_ip4_config_add_address (config, &address); } else { nm_log_err (LOGD_PPP, "invalid IPv4 address received!"); - nm_ip4_address_unref (addr); goto out; } @@ -665,25 +647,34 @@ nm_cmd_line_add_int (NMCmdLine *cmd, int i) /*******************************************/ +static const char *pppd_binary_paths[] = { + PPPD_PATH, + "/usr/local/sbin/pppd", + "/usr/sbin/pppd", + "/sbin/pppd", + NULL +}; + +static const char *pppoe_binary_paths[] = { + PPPOE_PATH, + "/usr/local/sbin/pppoe", + "/usr/sbin/pppoe", + "/sbin/pppoe", + NULL +}; + static inline const char * -nm_find_pppd (void) +nm_find_binary (const char *paths[]) { - static const char *pppd_binary_paths[] = { - "/usr/local/sbin/pppd", - "/usr/sbin/pppd", - "/sbin/pppd", - NULL - }; - - const char **pppd_binary = pppd_binary_paths; + const char **binary = paths; - while (*pppd_binary != NULL) { - if (g_file_test (*pppd_binary, G_FILE_TEST_EXISTS)) + while (*binary != NULL) { + if (**binary && g_file_test (*binary, G_FILE_TEST_EXISTS)) break; - pppd_binary++; + binary++; } - return *pppd_binary; + return *binary; } static void @@ -805,22 +796,32 @@ create_pppd_cmd_line (NMPPPManager *self, GError **err) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); - const char *ppp_binary; + const char *pppd_binary, *pppoe_binary = NULL; NMCmdLine *cmd; gboolean ppp_debug; g_return_val_if_fail (setting != NULL, NULL); - ppp_binary = nm_find_pppd (); - if (!ppp_binary) { + pppd_binary = nm_find_binary (pppd_binary_paths); + if (!pppd_binary) { g_set_error (err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR, - "Could not find ppp binary."); + "Could not find pppd binary."); return NULL; } + if ( pppoe + || (adsl && strcmp (nm_setting_adsl_get_protocol (adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE))) { + pppoe_binary = nm_find_binary (pppoe_binary_paths); + if (!pppoe_binary) { + g_set_error (err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR, + "Could not find pppoe binary."); + return NULL; + } + } + /* Create pppd command line */ cmd = nm_cmd_line_new (); - nm_cmd_line_add_string (cmd, ppp_binary); + nm_cmd_line_add_string (cmd, pppd_binary); nm_cmd_line_add_string (cmd, "nodetach"); nm_cmd_line_add_string (cmd, "lock"); @@ -833,8 +834,7 @@ create_pppd_cmd_line (NMPPPManager *self, nm_cmd_line_add_string (cmd, ","); ppp_debug = !!getenv ("NM_PPP_DEBUG"); - if ( nm_logging_level_enabled (LOGL_DEBUG) - && nm_logging_domain_enabled (LOGD_PPP)) + if (nm_logging_enabled (LOGL_DEBUG, LOGD_PPP)) ppp_debug = TRUE; if (ppp_debug) @@ -846,21 +846,30 @@ create_pppd_cmd_line (NMPPPManager *self, } if (pppoe) { - char *dev_str; + GString *pppoe_arg; const char *pppoe_service; + char *quoted; - nm_cmd_line_add_string (cmd, "plugin"); - nm_cmd_line_add_string (cmd, "rp-pppoe.so"); + g_assert (pppoe_binary != NULL); + pppoe_arg = g_string_new (pppoe_binary); - dev_str = g_strdup_printf ("nic-%s", priv->parent_iface); - nm_cmd_line_add_string (cmd, dev_str); - g_free (dev_str); + g_string_append (pppoe_arg, " -I "); + quoted = g_shell_quote (priv->parent_iface); + g_string_append (pppoe_arg, quoted); + g_free (quoted); pppoe_service = nm_setting_pppoe_get_service (pppoe); if (pppoe_service) { - nm_cmd_line_add_string (cmd, "rp_pppoe_service"); - nm_cmd_line_add_string (cmd, pppoe_service); + g_string_append (pppoe_arg, " -S "); + quoted = g_shell_quote (pppoe_service); + g_string_append (pppoe_arg, quoted); + g_free (quoted); } + + nm_cmd_line_add_string (cmd, "pty"); + nm_cmd_line_add_string (cmd, pppoe_arg->str); + + g_string_free (pppoe_arg, TRUE); } else if (adsl) { const gchar *protocol = nm_setting_adsl_get_protocol (adsl); @@ -883,9 +892,14 @@ create_pppd_cmd_line (NMPPPManager *self, nm_cmd_line_add_string (cmd, "vc-encaps"); } else if (!strcmp (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)) { - nm_cmd_line_add_string (cmd, "plugin"); - nm_cmd_line_add_string (cmd, "rp-pppoe.so"); - nm_cmd_line_add_string (cmd, priv->parent_iface); + char *pppoe_arg; + + g_assert (pppoe_binary != NULL); + + pppoe_arg = g_strdup_printf ("%s -I %s", pppoe_binary, priv->parent_iface); + nm_cmd_line_add_string (cmd, "pty"); + nm_cmd_line_add_string (cmd, pppoe_arg); + g_free (pppoe_arg); } nm_cmd_line_add_string (cmd, "noipdefault"); @@ -950,6 +964,10 @@ create_pppd_cmd_line (NMPPPManager *self, nm_cmd_line_add_string (cmd, "lcp-echo-interval"); nm_cmd_line_add_int (cmd, nm_setting_ppp_get_lcp_echo_interval (setting)); + /* Avoid pppd to exit if no traffic going through */ + nm_cmd_line_add_string (cmd, "idle"); + nm_cmd_line_add_int (cmd, 0); + nm_cmd_line_add_string (cmd, "ipparam"); nm_cmd_line_add_string (cmd, priv->dbus_path); @@ -983,9 +1001,9 @@ pppoe_fill_defaults (NMSettingPPP *setting) g_object_set (setting, NM_SETTING_PPP_MRU, (guint32) 1492, NULL); g_object_set (setting, - NM_SETTING_PPP_NOAUTH, TRUE, - NM_SETTING_PPP_NODEFLATE, TRUE, - NULL); + NM_SETTING_PPP_NOAUTH, TRUE, + NM_SETTING_PPP_NODEFLATE, TRUE, + NULL); /* FIXME: These commented settings should be set as well, update NMSettingPPP first. */ #if 0 @@ -1070,9 +1088,9 @@ nm_ppp_manager_start (NMPPPManager *manager, priv->pid = 0; if (!g_spawn_async (NULL, (char **) ppp_cmd->array->pdata, NULL, - G_SPAWN_DO_NOT_REAP_CHILD, - pppd_child_setup, - NULL, &priv->pid, err)) { + G_SPAWN_DO_NOT_REAP_CHILD, + pppd_child_setup, + NULL, &priv->pid, err)) { goto out; } @@ -1082,7 +1100,7 @@ nm_ppp_manager_start (NMPPPManager *manager, priv->ppp_timeout_handler = g_timeout_add_seconds (timeout_secs, pppd_timed_out, manager); priv->act_req = g_object_ref (req); - out: +out: if (s_ppp_created) g_object_unref (s_ppp); |