/* return value must be freed by caller with g_free() */ static gchar * get_mac_address_of_connection (NMConnection *connection) { const GByteArray *mac = NULL; if (!connection) return NULL; /* check the connection type */ if (nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)) { /* check wireless settings */ NMSettingWireless *s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) return NULL; mac = nm_setting_wireless_get_mac_address (s_wireless); if (mac) return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER); } else if (nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) { /* check wired settings */ NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) return NULL; mac = nm_setting_wired_get_mac_address (s_wired); if (mac) return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER); } else if (nm_connection_is_type (connection, NM_SETTING_WIMAX_SETTING_NAME)) { /* check wimax settings */ NMSettingWimax *s_wimax = nm_connection_get_setting_wimax (connection); if (!s_wimax) return NULL; mac = nm_setting_wimax_get_mac_address (s_wimax); if (mac) return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER); } else if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { /* check infiniband settings */ NMSettingInfiniband *s_infiniband = \ nm_connection_get_setting_infiniband (connection); if (!s_infiniband) return NULL; mac = nm_setting_infiniband_get_mac_address (s_infiniband); if (mac) return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_INFINIBAND); } /* no MAC address found */ return NULL; }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMSettingWireless *setting = NM_SETTING_WIRELESS (object); switch (prop_id) { case PROP_SSID: g_value_set_boxed (value, nm_setting_wireless_get_ssid (setting)); break; case PROP_MODE: g_value_set_string (value, nm_setting_wireless_get_mode (setting)); break; case PROP_BAND: g_value_set_string (value, nm_setting_wireless_get_band (setting)); break; case PROP_CHANNEL: g_value_set_uint (value, nm_setting_wireless_get_channel (setting)); break; case PROP_BSSID: g_value_set_boxed (value, nm_setting_wireless_get_bssid (setting)); break; case PROP_RATE: g_value_set_uint (value, nm_setting_wireless_get_rate (setting)); break; case PROP_TX_POWER: g_value_set_uint (value, nm_setting_wireless_get_tx_power (setting)); break; case PROP_MAC_ADDRESS: g_value_set_boxed (value, nm_setting_wireless_get_mac_address (setting)); break; case PROP_CLONED_MAC_ADDRESS: g_value_set_boxed (value, nm_setting_wireless_get_cloned_mac_address (setting)); break; case PROP_MAC_ADDRESS_BLACKLIST: g_value_set_boxed (value, nm_setting_wireless_get_mac_address_blacklist (setting)); break; case PROP_MTU: g_value_set_uint (value, nm_setting_wireless_get_mtu (setting)); break; case PROP_SEEN_BSSIDS: g_value_set_boxed (value, NM_SETTING_WIRELESS_GET_PRIVATE (setting)->seen_bssids); break; case PROP_SEC: g_value_set_string (value, NM_SETTING_WIRELESS_GET_PRIVATE (setting)->security); break; case PROP_HIDDEN: g_value_set_boolean (value, nm_setting_wireless_get_hidden (setting)); break; case PROP_POWERSAVE: g_value_set_uint (value, nm_setting_wireless_get_powersave (setting)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean check_wifi_compatible (NMDeviceWifi *device, NMConnection *connection, GError **error) { NMSettingConnection *s_con; NMSettingWireless *s_wireless; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME)) { g_set_error (error, 0, 0, "The connection was not a WiFi connection."); return FALSE; } s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); if (!s_wireless) { g_set_error (error, 0, 0, "The connection was not a valid WiFi connection."); return FALSE; } if (s_wireless) { const GByteArray *mac; const char *device_mac_str; struct ether_addr *device_mac; device_mac_str = nm_device_wifi_get_hw_address (device); device_mac = ether_aton (device_mac_str); if (!device_mac) { g_set_error (error, 0, 0, "Invalid device MAC address."); return FALSE; } mac = nm_setting_wireless_get_mac_address (s_wireless); if (mac && memcmp (mac->data, device_mac->ether_addr_octet, ETH_ALEN)) { g_set_error (error, 0, 0, "The connection's MAC address did not match this device."); return FALSE; } } // FIXME: check channel/freq/band against bands the hardware supports // FIXME: check encryption against device capabilities // FIXME: check bitrate against device capabilities return TRUE; }
static void connect_wifi_page (CEPageWifi *page) { NMSettingConnection *sc; GtkWidget *widget; const GByteArray *ssid; gchar *utf8_ssid; GPtrArray *bssid_array; gchar **bssid_list; const GByteArray *s_bssid; gchar *s_bssid_str; gchar **mac_list; const GByteArray *s_mac; gchar *s_mac_str; gint i; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_ssid")); ssid = nm_setting_wireless_get_ssid (page->setting); if (ssid) utf8_ssid = nm_utils_ssid_to_utf8 (ssid); else utf8_ssid = g_strdup (""); gtk_entry_set_text (GTK_ENTRY (widget), utf8_ssid); g_free (utf8_ssid); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_bssid")); bssid_array = g_ptr_array_new (); for (i = 0; i < nm_setting_wireless_get_num_seen_bssids (page->setting); i++) { g_ptr_array_add (bssid_array, g_strdup (nm_setting_wireless_get_seen_bssid (page->setting, i))); } g_ptr_array_add (bssid_array, NULL); bssid_list = (gchar **) g_ptr_array_free (bssid_array, FALSE); s_bssid = nm_setting_wireless_get_bssid (page->setting); s_bssid_str = s_bssid ? nm_utils_hwaddr_ntoa (s_bssid->data, ARPHRD_ETHER) : NULL; ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_bssid_str, bssid_list); g_free (s_bssid_str); g_strfreev (bssid_list); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac")); mac_list = ce_page_get_mac_list (CE_PAGE (page)->client, NM_TYPE_DEVICE_WIFI, NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS); s_mac = nm_setting_wireless_get_mac_address (page->setting); s_mac_str = s_mac ? nm_utils_hwaddr_ntoa (s_mac->data, ARPHRD_ETHER) : NULL; ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_mac_str, mac_list); g_free (s_mac_str); g_strfreev (mac_list); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac")); ce_page_mac_to_entry (nm_setting_wireless_get_cloned_mac_address (page->setting), ARPHRD_ETHER, GTK_ENTRY (widget)); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_connect_check")); sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection); g_object_bind_property (sc, "autoconnect", widget, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "all_user_check")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), nm_setting_connection_get_num_permissions (sc) == 0); g_signal_connect (widget, "toggled", G_CALLBACK (all_user_changed), page); g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_zone")); firewall_ui_setup (sc, widget, CE_PAGE (page)->cancellable); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); }
static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; const char *ctype; const char *hwaddr, *setting_hwaddr; NMDeviceWifiCapabilities wifi_caps; const char *key_mgmt; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); ctype = nm_setting_connection_get_connection_type (s_con); if (strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME) != 0) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_NOT_WIFI_CONNECTION, "The connection was not a Wi-Fi connection."); return FALSE; } s_wifi = nm_connection_get_setting_wireless (connection); if (!s_wifi) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_INVALID_WIFI_CONNECTION, "The connection was not a valid Wi-Fi connection."); return FALSE; } /* Check MAC address */ hwaddr = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device)); if (hwaddr) { if (!nm_utils_hwaddr_valid (hwaddr, ETH_ALEN)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_INVALID_DEVICE_MAC, "Invalid device MAC address."); return FALSE; } setting_hwaddr = nm_setting_wireless_get_mac_address (s_wifi); if (setting_hwaddr && !nm_utils_hwaddr_matches (setting_hwaddr, -1, hwaddr, -1)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_MAC_MISMATCH, "The MACs of the device and the connection didn't match."); return FALSE; } } /* Check device capabilities; we assume all devices can do WEP at least */ wifi_caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device)); s_wsec = nm_connection_get_setting_wireless_security (connection); if (s_wsec) { /* Connection has security, verify it against the device's capabilities */ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); if ( !g_strcmp0 (key_mgmt, "wpa-none") || !g_strcmp0 (key_mgmt, "wpa-psk") || !g_strcmp0 (key_mgmt, "wpa-eap")) { /* Is device only WEP capable? */ if (!(wifi_caps & WPA_CAPS)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_MISSING_DEVICE_WPA_CAPS, "The device missed WPA capabilities required by the connection."); return FALSE; } /* Make sure WPA2/RSN-only connections don't get chosen for WPA-only cards */ if (has_proto (s_wsec, "rsn") && !has_proto (s_wsec, "wpa") && !(wifi_caps & RSN_CAPS)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_MISSING_DEVICE_RSN_CAPS, "The device missed WPA2/RSN capabilities required by the connection."); return FALSE; } } } return NM_DEVICE_CLASS (nm_device_wifi_parent_class)->connection_compatible (device, connection, error); }
static void populate_ui (CEPageWifi *self) { CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self); NMSettingWireless *setting = priv->setting; GBytes *ssid; const char *mode; const char *band; int band_idx = 0; int rate_def; int tx_power_def; int mtu_def; char *utf8_ssid; const char *s_ifname, *s_mac, *s_bssid; GPtrArray *bssid_array; char **bssid_list; guint32 idx; rate_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_RATE); g_signal_connect (priv->rate, "output", G_CALLBACK (ce_spin_output_with_automatic), GINT_TO_POINTER (rate_def)); g_signal_connect_swapped (priv->rate, "value-changed", G_CALLBACK (ce_page_changed), self); tx_power_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_TX_POWER); g_signal_connect (priv->tx_power, "output", G_CALLBACK (ce_spin_output_with_automatic), GINT_TO_POINTER (tx_power_def)); g_signal_connect_swapped (priv->tx_power, "value-changed", G_CALLBACK (ce_page_changed), self); mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_MTU); g_signal_connect (priv->mtu, "output", G_CALLBACK (ce_spin_output_with_automatic), GINT_TO_POINTER (mtu_def)); g_signal_connect_swapped (priv->mtu, "value-changed", G_CALLBACK (ce_page_changed), self); ssid = nm_setting_wireless_get_ssid (setting); mode = nm_setting_wireless_get_mode (setting); band = nm_setting_wireless_get_band (setting); if (ssid) utf8_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); else utf8_ssid = g_strdup (""); gtk_entry_set_text (priv->ssid, utf8_ssid); g_signal_connect_swapped (priv->ssid, "changed", G_CALLBACK (ce_page_changed), self); g_free (utf8_ssid); /* Default to Infrastructure */ gtk_combo_box_set_active (priv->mode, 0); if (!g_strcmp0 (mode, "ap")) gtk_combo_box_set_active (priv->mode, 1); if (!g_strcmp0 (mode, "adhoc")) gtk_combo_box_set_active (priv->mode, 2); mode_combo_changed_cb (priv->mode, self); g_signal_connect (priv->mode, "changed", G_CALLBACK (mode_combo_changed_cb), self); g_signal_connect (priv->channel, "output", G_CALLBACK (channel_spin_output_cb), self); g_signal_connect (priv->channel, "input", G_CALLBACK (channel_spin_input_cb), self); gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), FALSE); if (band) { if (!strcmp (band, "a")) { band_idx = 1; gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), TRUE); } else if (!strcmp (band, "bg")) { band_idx = 2; gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), TRUE); } } gtk_combo_box_set_active (priv->band, band_idx); g_signal_connect (priv->band, "changed", G_CALLBACK (band_value_changed_cb), self); /* Update the channel _after_ the band has been set so that it gets * the right values */ priv->last_channel = nm_setting_wireless_get_channel (setting); gtk_spin_button_set_value (priv->channel, (gdouble) priv->last_channel); g_signal_connect_swapped (priv->channel, "value-changed", G_CALLBACK (ce_page_changed), self); /* BSSID */ bssid_array = g_ptr_array_new (); for (idx = 0; idx < nm_setting_wireless_get_num_seen_bssids (setting); idx++) g_ptr_array_add (bssid_array, g_strdup (nm_setting_wireless_get_seen_bssid (setting, idx))); g_ptr_array_add (bssid_array, NULL); bssid_list = (char **) g_ptr_array_free (bssid_array, FALSE); s_bssid = nm_setting_wireless_get_bssid (setting); ce_page_setup_mac_combo (CE_PAGE (self), GTK_COMBO_BOX (priv->bssid), s_bssid, bssid_list); g_strfreev (bssid_list); g_signal_connect_swapped (priv->bssid, "changed", G_CALLBACK (ce_page_changed), self); /* Device MAC address */ s_ifname = nm_connection_get_interface_name (CE_PAGE (self)->connection); s_mac = nm_setting_wireless_get_mac_address (setting); ce_page_setup_device_combo (CE_PAGE (self), GTK_COMBO_BOX (priv->device_combo), NM_TYPE_DEVICE_WIFI, s_ifname, s_mac, NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, TRUE); g_signal_connect_swapped (priv->device_combo, "changed", G_CALLBACK (ce_page_changed), self); /* Cloned MAC address */ s_mac = nm_setting_wireless_get_cloned_mac_address (setting); if (s_mac) gtk_entry_set_text (priv->cloned_mac, s_mac); g_signal_connect_swapped (priv->cloned_mac, "changed", G_CALLBACK (ce_page_changed), self); gtk_spin_button_set_value (priv->rate, (gdouble) nm_setting_wireless_get_rate (setting)); gtk_spin_button_set_value (priv->tx_power, (gdouble) nm_setting_wireless_get_tx_power (setting)); gtk_spin_button_set_value (priv->mtu, (gdouble) nm_setting_wireless_get_mtu (setting)); }
static void populate_ui (CEPageWireless *self) { CEPageWirelessPrivate *priv = CE_PAGE_WIRELESS_GET_PRIVATE (self); NMSettingWireless *setting = priv->setting; const GByteArray *ssid = NULL; const char *mode = NULL; const char *band = NULL; int band_idx = 0; int rate_def; int tx_power_def; int mtu_def; char *utf8_ssid; rate_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_RATE); g_signal_connect (priv->rate, "output", G_CALLBACK (ce_spin_output_with_default), GINT_TO_POINTER (rate_def)); g_signal_connect_swapped (priv->rate, "value-changed", G_CALLBACK (ce_page_changed), self); tx_power_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_TX_POWER); g_signal_connect (priv->tx_power, "output", G_CALLBACK (ce_spin_output_with_default), GINT_TO_POINTER (tx_power_def)); g_signal_connect_swapped (priv->tx_power, "value-changed", G_CALLBACK (ce_page_changed), self); mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_MTU); g_signal_connect (priv->mtu, "output", G_CALLBACK (ce_spin_output_with_default), GINT_TO_POINTER (mtu_def)); g_signal_connect_swapped (priv->mtu, "value-changed", G_CALLBACK (ce_page_changed), self); g_object_get (setting, NM_SETTING_WIRELESS_SSID, &ssid, NM_SETTING_WIRELESS_MODE, &mode, NM_SETTING_WIRELESS_BAND, &band, NULL); if (ssid) utf8_ssid = nm_utils_ssid_to_utf8 ((const char *) ssid->data, ssid->len); else utf8_ssid = g_strdup (""); gtk_entry_set_text (priv->ssid, utf8_ssid); g_signal_connect_swapped (priv->ssid, "changed", G_CALLBACK (ce_page_changed), self); g_free (utf8_ssid); /* Default to Infrastructure */ gtk_combo_box_set_active (priv->mode, 0); if (mode && !strcmp (mode, "adhoc")) gtk_combo_box_set_active (priv->mode, 1); g_signal_connect_swapped (priv->mode, "changed", G_CALLBACK (ce_page_changed), self); g_signal_connect (priv->channel, "output", G_CALLBACK (channel_spin_output_cb), self); g_signal_connect (priv->channel, "input", G_CALLBACK (channel_spin_input_cb), self); gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), FALSE); if (band) { if (!strcmp (band ? band : "", "a")) { band_idx = 1; gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), TRUE); } else if (!strcmp (band ? band : "", "bg")) { band_idx = 2; gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), TRUE); } } gtk_combo_box_set_active (priv->band, band_idx); g_signal_connect (priv->band, "changed", G_CALLBACK (band_value_changed_cb), self); /* Update the channel _after_ the band has been set so that it gets * the right values */ priv->last_channel = nm_setting_wireless_get_channel (setting); gtk_spin_button_set_value (priv->channel, (gdouble) priv->last_channel); g_signal_connect_swapped (priv->channel, "value-changed", G_CALLBACK (ce_page_changed), self); /* BSSID */ ce_page_mac_to_entry (nm_setting_wireless_get_bssid (setting), priv->bssid); g_signal_connect_swapped (priv->bssid, "changed", G_CALLBACK (ce_page_changed), self); /* MAC address */ ce_page_mac_to_entry (nm_setting_wireless_get_mac_address (setting), priv->mac); g_signal_connect_swapped (priv->mac, "changed", G_CALLBACK (ce_page_changed), self); gtk_spin_button_set_value (priv->rate, (gdouble) nm_setting_wireless_get_rate (setting)); gtk_spin_button_set_value (priv->tx_power, (gdouble) nm_setting_wireless_get_tx_power (setting)); gtk_spin_button_set_value (priv->mtu, (gdouble) nm_setting_wireless_get_mtu (setting)); }