guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self) { g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), 1); return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan; }
GHashTable * nm_supplicant_config_get_blobs (NMSupplicantConfig * self) { g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL); return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->blobs; }
gboolean nm_supplicant_config_fast_required (NMSupplicantConfig *self) { g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->fast_required; }
static gboolean nm_supplicant_config_add_option_with_type (NMSupplicantConfig *self, const char *key, const char *value, gint32 len, OptType opt_type, gboolean secret) { NMSupplicantConfigPrivate *priv; ConfigOption *old_opt; ConfigOption *opt; OptType type; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); if (len < 0) len = strlen (value); if (opt_type != TYPE_INVALID) type = opt_type; else { type = nm_supplicant_settings_verify_setting (key, value, len); if (type == TYPE_INVALID) { char buf[255]; memset (&buf[0], 0, sizeof (buf)); memcpy (&buf[0], value, len > 254 ? 254 : len); nm_log_warn (LOGD_SUPPLICANT, "Key '%s' and/or value '%s' invalid.", key, secret ? "<omitted>" : buf); return FALSE; } } old_opt = (ConfigOption *) g_hash_table_lookup (priv->config, key); if (old_opt) { nm_log_warn (LOGD_SUPPLICANT, "Key '%s' already in table.", key); return FALSE; } opt = g_slice_new0 (ConfigOption); opt->value = g_malloc0 ((sizeof (char) * len) + 1); memcpy (opt->value, value, len); opt->len = len; opt->type = type; { char buf[255]; memset (&buf[0], 0, sizeof (buf)); memcpy (&buf[0], opt->value, opt->len > 254 ? 254 : opt->len); nm_log_info (LOGD_SUPPLICANT, "Config: added '%s' value '%s'", key, secret ? "<omitted>" : &buf[0]); } g_hash_table_insert (priv->config, g_strdup (key), opt); return TRUE; }
void nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self, guint32 ap_scan) { g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self)); g_return_if_fail (ap_scan <= 2); NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan = ap_scan; }
static gboolean nm_supplicant_config_add_blob (NMSupplicantConfig *self, const char *key, GBytes *value, const char *blobid, GError **error) { NMSupplicantConfigPrivate *priv; ConfigOption *old_opt; ConfigOption *opt; OptType type; GByteArray *blob; const guint8 *data; gsize data_len; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); g_return_val_if_fail (blobid != NULL, FALSE); data = g_bytes_get_data (value, &data_len); g_return_val_if_fail (data_len > 0, FALSE); priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); type = nm_supplicant_settings_verify_setting (key, (const char *) data, data_len); if (type == TYPE_INVALID) { g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, "key '%s' and/or its contained value is invalid", key); return FALSE; } old_opt = (ConfigOption *) g_hash_table_lookup (priv->config, key); if (old_opt) { g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, "key '%s' already configured", key); return FALSE; } blob = g_byte_array_sized_new (data_len); g_byte_array_append (blob, data, data_len); opt = g_slice_new0 (ConfigOption); opt->value = g_strdup_printf ("blob://%s", blobid); opt->len = strlen (opt->value); opt->type = type; nm_log_info (LOGD_SUPPLICANT, "Config: added '%s' value '%s'", key, opt->value); g_hash_table_insert (priv->config, g_strdup (key), opt); g_hash_table_insert (priv->blobs, g_strdup (blobid), blob); return TRUE; }
static void nm_supplicant_config_init (NMSupplicantConfig * self) { NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); priv->config = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) config_option_free); priv->blobs = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) blob_free); priv->ap_scan = 1; priv->dispose_has_run = FALSE; }
GHashTable * nm_supplicant_config_get_hash (NMSupplicantConfig * self) { NMSupplicantConfigPrivate *priv; GHashTable *hash; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL); hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, destroy_hash_value); priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); g_hash_table_foreach (priv->config, get_hash_cb, hash); return hash; }
GVariant * nm_supplicant_config_to_variant (NMSupplicantConfig *self) { NMSupplicantConfigPrivate *priv; GVariantBuilder builder; GHashTableIter iter; ConfigOption *option; const char *key; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL); priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); g_hash_table_iter_init (&iter, priv->config); while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &option)) { switch (option->type) { case TYPE_INT: g_variant_builder_add (&builder, "{sv}", key, g_variant_new_int32 (atoi (option->value))); break; case TYPE_BYTES: case TYPE_UTF8: g_variant_builder_add (&builder, "{sv}", key, g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, option->value, option->len, 1)); break; case TYPE_KEYWORD: case TYPE_STRING: g_variant_builder_add (&builder, "{sv}", key, g_variant_new_string (option->value)); break; default: break; } } return g_variant_builder_end (&builder); }
gboolean nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, NMSetting8021x *setting, const char *con_uuid, guint32 mtu, gboolean wired, GError **error) { NMSupplicantConfigPrivate *priv; char *tmp; const char *peapver, *value, *path; gboolean added; GString *phase1, *phase2; GBytes *bytes; gboolean fast = FALSE; guint32 i, num_eap; gboolean fast_provisoning_allowed = FALSE; const char *ca_path_override = NULL, *ca_cert_override = NULL; guint32 frag, hdrs; gs_free char *frag_str = NULL; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); g_return_val_if_fail (con_uuid != NULL, FALSE); priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); value = nm_setting_802_1x_get_password (setting); if (value) { if (!add_string_val (self, value, "password", FALSE, TRUE, error)) return FALSE; } else { bytes = nm_setting_802_1x_get_password_raw (setting); if (bytes) { if (!nm_supplicant_config_add_option (self, "password", (const char *) g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), TRUE, error)) return FALSE; } } value = nm_setting_802_1x_get_pin (setting); if (!add_string_val (self, value, "pin", FALSE, TRUE, error)) return FALSE; if (wired) { if (!add_string_val (self, "IEEE8021X", "key_mgmt", FALSE, FALSE, error)) return FALSE; /* Wired 802.1x must always use eapol_flags=0 */ if (!add_string_val (self, "0", "eapol_flags", FALSE, FALSE, error)) return FALSE; priv->ap_scan = 0; } if (!ADD_STRING_LIST_VAL (self, setting, 802_1x, eap_method, eap_methods, "eap", ' ', TRUE, FALSE, error)) return FALSE; /* Check EAP method for special handling: PEAP + GTC, FAST */ num_eap = nm_setting_802_1x_get_num_eap_methods (setting); for (i = 0; i < num_eap; i++) { const char *method = nm_setting_802_1x_get_eap_method (setting, i); if (method && (strcasecmp (method, "fast") == 0)) { fast = TRUE; priv->fast_required = TRUE; } } /* Adjust the fragment size according to MTU, but do not set it higher than 1280-14 * for better compatibility */ hdrs = 14; /* EAPOL + EAP-TLS */ frag = 1280 - hdrs; if (mtu > hdrs) frag = CLAMP (mtu - hdrs, 100, frag); frag_str = g_strdup_printf ("%u", frag); if (!nm_supplicant_config_add_option (self, "fragment_size", frag_str, -1, FALSE, error)) return FALSE; phase1 = g_string_new (NULL); peapver = nm_setting_802_1x_get_phase1_peapver (setting); if (peapver) { if (!strcmp (peapver, "0")) g_string_append (phase1, "peapver=0"); else if (!strcmp (peapver, "1")) g_string_append (phase1, "peapver=1"); } if (nm_setting_802_1x_get_phase1_peaplabel (setting)) { if (phase1->len) g_string_append_c (phase1, ' '); g_string_append_printf (phase1, "peaplabel=%s", nm_setting_802_1x_get_phase1_peaplabel (setting)); } value = nm_setting_802_1x_get_phase1_fast_provisioning (setting); if (value) { if (phase1->len) g_string_append_c (phase1, ' '); g_string_append_printf (phase1, "fast_provisioning=%s", value); if (strcmp (value, "0") != 0) fast_provisoning_allowed = TRUE; } if (phase1->len) { if (!add_string_val (self, phase1->str, "phase1", FALSE, FALSE, error)) { g_string_free (phase1, TRUE); return FALSE; } } g_string_free (phase1, TRUE); phase2 = g_string_new (NULL); if (nm_setting_802_1x_get_phase2_auth (setting) && !fast_provisoning_allowed) { tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_auth (setting), -1); g_string_append_printf (phase2, "auth=%s", tmp); g_free (tmp); } if (nm_setting_802_1x_get_phase2_autheap (setting)) { if (phase2->len) g_string_append_c (phase2, ' '); tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_autheap (setting), -1); g_string_append_printf (phase2, "autheap=%s", tmp); g_free (tmp); } if (phase2->len) { if (!add_string_val (self, phase2->str, "phase2", FALSE, FALSE, error)) { g_string_free (phase2, TRUE); return FALSE; } } g_string_free (phase2, TRUE); /* PAC file */ path = nm_setting_802_1x_get_pac_file (setting); if (path) { if (!add_string_val (self, path, "pac_file", FALSE, FALSE, error)) return FALSE; } else { /* PAC file is not specified. * If provisioning is allowed, use an blob format. */ if (fast_provisoning_allowed) { gs_free char *blob_name = NULL; blob_name = g_strdup_printf ("blob://pac-blob-%s", con_uuid); if (!add_string_val (self, blob_name, "pac_file", FALSE, FALSE, error)) return FALSE; } else { /* This is only error for EAP-FAST; don't disturb other methods. */ if (fast) { g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, "EAP-FAST error: no PAC file provided and " "automatic PAC provisioning is disabled"); return FALSE; } } } /* If user wants to use system CA certs, either populate ca_path (if the path * is a directory) or ca_cert (the path is a file name) */ if (nm_setting_802_1x_get_system_ca_certs (setting)) { if (g_file_test (SYSTEM_CA_PATH, G_FILE_TEST_IS_DIR)) ca_path_override = SYSTEM_CA_PATH; else ca_cert_override = SYSTEM_CA_PATH; } /* CA path */ path = nm_setting_802_1x_get_ca_path (setting); path = ca_path_override ? ca_path_override : path; if (path) { if (!add_string_val (self, path, "ca_path", FALSE, FALSE, error)) return FALSE; } /* Phase2 CA path */ path = nm_setting_802_1x_get_phase2_ca_path (setting); path = ca_path_override ? ca_path_override : path; if (path) { if (!add_string_val (self, path, "ca_path2", FALSE, FALSE, error)) return FALSE; } /* CA certificate */ if (ca_cert_override) { if (!add_string_val (self, ca_cert_override, "ca_cert", FALSE, FALSE, error)) return FALSE; } else { switch (nm_setting_802_1x_get_ca_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_ca_cert_blob (setting); if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "ca_cert", con_uuid, error)) return FALSE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_ca_cert_path (setting); if (!add_string_val (self, path, "ca_cert", FALSE, FALSE, error)) return FALSE; break; default: break; } } /* Phase 2 CA certificate */ if (ca_cert_override) { if (!add_string_val (self, ca_cert_override, "ca_cert2", FALSE, FALSE, error)) return FALSE; } else { switch (nm_setting_802_1x_get_phase2_ca_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_phase2_ca_cert_blob (setting); if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "ca_cert2", con_uuid, error)) return FALSE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_ca_cert_path (setting); if (!add_string_val (self, path, "ca_cert2", FALSE, FALSE, error)) return FALSE; break; default: break; } } /* Subject match */ value = nm_setting_802_1x_get_subject_match (setting); if (!add_string_val (self, value, "subject_match", FALSE, FALSE, error)) return FALSE; value = nm_setting_802_1x_get_phase2_subject_match (setting); if (!add_string_val (self, value, "subject_match2", FALSE, FALSE, error)) return FALSE; /* altSubjectName match */ if (!ADD_STRING_LIST_VAL (self, setting, 802_1x, altsubject_match, altsubject_matches, "altsubject_match", ';', FALSE, FALSE, error)) return FALSE; if (!ADD_STRING_LIST_VAL (self, setting, 802_1x, phase2_altsubject_match, phase2_altsubject_matches, "altsubject_match2", ';', FALSE, FALSE, error)) return FALSE; /* Domain suffix match */ value = nm_setting_802_1x_get_domain_suffix_match (setting); if (!add_string_val (self, value, "domain_suffix_match", FALSE, FALSE, error)) return FALSE; value = nm_setting_802_1x_get_phase2_domain_suffix_match (setting); if (!add_string_val (self, value, "domain_suffix_match2", FALSE, FALSE, error)) return FALSE; /* Private key */ added = FALSE; switch (nm_setting_802_1x_get_private_key_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_private_key_blob (setting); if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "private_key", con_uuid, error)) return FALSE; added = TRUE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_private_key_path (setting); if (!add_string_val (self, path, "private_key", FALSE, FALSE, error)) return FALSE; added = TRUE; break; default: break; } if (added) { NMSetting8021xCKFormat format; NMSetting8021xCKScheme scheme; format = nm_setting_802_1x_get_private_key_format (setting); scheme = nm_setting_802_1x_get_private_key_scheme (setting); if ( scheme == NM_SETTING_802_1X_CK_SCHEME_PATH || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { /* Only add the private key password for PKCS#12 blobs and * all path schemes, since in both of these cases the private key * isn't decrypted at all. */ value = nm_setting_802_1x_get_private_key_password (setting); if (!add_string_val (self, value, "private_key_passwd", FALSE, TRUE, error)) return FALSE; } if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { /* Only add the client cert if the private key is not PKCS#12, as * wpa_supplicant configuration directs us to do. */ switch (nm_setting_802_1x_get_client_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_client_cert_blob (setting); if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "client_cert", con_uuid, error)) return FALSE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_client_cert_path (setting); if (!add_string_val (self, path, "client_cert", FALSE, FALSE, error)) return FALSE; break; default: break; } } } /* Phase 2 private key */ added = FALSE; switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_phase2_private_key_blob (setting); if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "private_key2", con_uuid, error)) return FALSE; added = TRUE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_private_key_path (setting); if (!add_string_val (self, path, "private_key2", FALSE, FALSE, error)) return FALSE; added = TRUE; break; default: break; } if (added) { NMSetting8021xCKFormat format; NMSetting8021xCKScheme scheme; format = nm_setting_802_1x_get_phase2_private_key_format (setting); scheme = nm_setting_802_1x_get_phase2_private_key_scheme (setting); if ( scheme == NM_SETTING_802_1X_CK_SCHEME_PATH || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { /* Only add the private key password for PKCS#12 blobs and * all path schemes, since in both of these cases the private key * isn't decrypted at all. */ value = nm_setting_802_1x_get_phase2_private_key_password (setting); if (!add_string_val (self, value, "private_key2_passwd", FALSE, TRUE, error)) return FALSE; } if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { /* Only add the client cert if the private key is not PKCS#12, as * wpa_supplicant configuration directs us to do. */ switch (nm_setting_802_1x_get_phase2_client_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_phase2_client_cert_blob (setting); if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "client_cert2", con_uuid, error)) return FALSE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_client_cert_path (setting); if (!add_string_val (self, path, "client_cert2", FALSE, FALSE, error)) return FALSE; break; default: break; } } } value = nm_setting_802_1x_get_identity (setting); if (!add_string_val (self, value, "identity", FALSE, FALSE, error)) return FALSE; value = nm_setting_802_1x_get_anonymous_identity (setting); if (!add_string_val (self, value, "anonymous_identity", FALSE, FALSE, error)) return FALSE; return TRUE; }
gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, NMSettingWireless * setting, guint32 fixed_freq, GError **error) { NMSupplicantConfigPrivate *priv; gboolean is_adhoc, is_ap; const char *mode, *band; guint32 channel; GBytes *ssid; const char *bssid; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); g_return_val_if_fail (!error || !*error, FALSE); priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); mode = nm_setting_wireless_get_mode (setting); is_adhoc = (mode && !strcmp (mode, "adhoc")) ? TRUE : FALSE; is_ap = (mode && !strcmp (mode, "ap")) ? TRUE : FALSE; if (is_adhoc || is_ap) priv->ap_scan = 2; else priv->ap_scan = 1; ssid = nm_setting_wireless_get_ssid (setting); if (!nm_supplicant_config_add_option (self, "ssid", (char *) g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), FALSE, error)) return FALSE; if (is_adhoc) { if (!nm_supplicant_config_add_option (self, "mode", "1", -1, FALSE, error)) return FALSE; } if (is_ap) { if (!nm_supplicant_config_add_option (self, "mode", "2", -1, FALSE, error)) return FALSE; } if ((is_adhoc || is_ap) && fixed_freq) { gs_free char *str_freq = NULL; str_freq = g_strdup_printf ("%u", fixed_freq); if (!nm_supplicant_config_add_option (self, "frequency", str_freq, -1, FALSE, error)) return FALSE; } /* Except for Ad-Hoc and Hotspot, request that the driver probe for the * specific SSID we want to associate with. */ if (!(is_adhoc || is_ap)) { if (!nm_supplicant_config_add_option (self, "scan_ssid", "1", -1, FALSE, error)) return FALSE; } bssid = nm_setting_wireless_get_bssid (setting); if (bssid) { if (!nm_supplicant_config_add_option (self, "bssid", bssid, strlen (bssid), FALSE, error)) return FALSE; } band = nm_setting_wireless_get_band (setting); channel = nm_setting_wireless_get_channel (setting); if (band) { if (channel) { guint32 freq; gs_free char *str_freq = NULL; freq = nm_utils_wifi_channel_to_freq (channel, band); str_freq = g_strdup_printf ("%u", freq); if (!nm_supplicant_config_add_option (self, "freq_list", str_freq, -1, FALSE, error)) return FALSE; } else { const char *freqs = NULL; if (!strcmp (band, "a")) freqs = wifi_freqs_to_string (FALSE); else if (!strcmp (band, "bg")) freqs = wifi_freqs_to_string (TRUE); if (freqs && !nm_supplicant_config_add_option (self, "freq_list", freqs, strlen (freqs), FALSE, error)) return FALSE; } } return TRUE; }
gboolean nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, NMSetting8021x *setting, const char *con_uuid, gboolean wired) { NMSupplicantConfigPrivate *priv; char *tmp; const char *peapver, *value, *path; gboolean success, added; GString *phase1, *phase2; GBytes *bytes; gboolean fast = FALSE; guint32 i, num_eap; gboolean fast_provisoning_allowed = FALSE; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); g_return_val_if_fail (con_uuid != NULL, FALSE); priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); value = nm_setting_802_1x_get_password (setting); if (value) { if (!add_string_val (self, value, "password", FALSE, TRUE)) return FALSE; } else { bytes = nm_setting_802_1x_get_password_raw (setting); if (bytes) { success = nm_supplicant_config_add_option (self, "password", (const char *) g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), TRUE); if (!success) { nm_log_warn (LOGD_SUPPLICANT, "Error adding password-raw to supplicant config."); return FALSE; } } } value = nm_setting_802_1x_get_pin (setting); if (!add_string_val (self, value, "pin", FALSE, TRUE)) return FALSE; if (wired) { if (!add_string_val (self, "IEEE8021X", "key_mgmt", FALSE, FALSE)) return FALSE; /* Wired 802.1x must always use eapol_flags=0 */ if (!add_string_val (self, "0", "eapol_flags", FALSE, FALSE)) return FALSE; nm_supplicant_config_set_ap_scan (self, 0); } ADD_STRING_LIST_VAL (setting, 802_1x, eap_method, eap_methods, "eap", ' ', TRUE, FALSE); /* Check EAP method for special handling: PEAP + GTC, FAST */ num_eap = nm_setting_802_1x_get_num_eap_methods (setting); for (i = 0; i < num_eap; i++) { const char *method = nm_setting_802_1x_get_eap_method (setting, i); if (method && (strcasecmp (method, "fast") == 0)) { fast = TRUE; priv->fast_required = TRUE; } } /* Drop the fragment size a bit for better compatibility */ if (!nm_supplicant_config_add_option (self, "fragment_size", "1300", -1, FALSE)) return FALSE; phase1 = g_string_new (NULL); peapver = nm_setting_802_1x_get_phase1_peapver (setting); if (peapver) { if (!strcmp (peapver, "0")) g_string_append (phase1, "peapver=0"); else if (!strcmp (peapver, "1")) g_string_append (phase1, "peapver=1"); } if (nm_setting_802_1x_get_phase1_peaplabel (setting)) { if (phase1->len) g_string_append_c (phase1, ' '); g_string_append_printf (phase1, "peaplabel=%s", nm_setting_802_1x_get_phase1_peaplabel (setting)); } value = nm_setting_802_1x_get_phase1_fast_provisioning (setting); if (value) { if (phase1->len) g_string_append_c (phase1, ' '); g_string_append_printf (phase1, "fast_provisioning=%s", value); if (strcmp (value, "0") != 0) fast_provisoning_allowed = TRUE; } if (phase1->len) { if (!add_string_val (self, phase1->str, "phase1", FALSE, FALSE)) { g_string_free (phase1, TRUE); return FALSE; } } g_string_free (phase1, TRUE); phase2 = g_string_new (NULL); if (nm_setting_802_1x_get_phase2_auth (setting) && !fast_provisoning_allowed) { tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_auth (setting), -1); g_string_append_printf (phase2, "auth=%s", tmp); g_free (tmp); } if (nm_setting_802_1x_get_phase2_autheap (setting)) { if (phase2->len) g_string_append_c (phase2, ' '); tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_autheap (setting), -1); g_string_append_printf (phase2, "autheap=%s", tmp); g_free (tmp); } if (phase2->len) { if (!add_string_val (self, phase2->str, "phase2", FALSE, FALSE)) { g_string_free (phase2, TRUE); return FALSE; } } g_string_free (phase2, TRUE); /* PAC file */ path = nm_setting_802_1x_get_pac_file (setting); if (path) { if (!add_string_val (self, path, "pac_file", FALSE, FALSE)) return FALSE; } else { /* PAC file is not specified. * If provisioning is allowed, use an blob format. */ if (fast_provisoning_allowed) { char *blob_name = g_strdup_printf ("blob://pac-blob-%s", con_uuid); if (!add_string_val (self, blob_name, "pac_file", FALSE, FALSE)) { g_free (blob_name); return FALSE; } g_free (blob_name); } else { /* This is only error for EAP-FAST; don't disturb other methods. */ if (fast) { nm_log_err (LOGD_SUPPLICANT, "EAP-FAST error: no PAC file provided and " "automatic PAC provisioning is disabled."); return FALSE; } } } /* CA path */ path = nm_setting_802_1x_get_ca_path (setting); if (nm_setting_802_1x_get_system_ca_certs (setting)) path = SYSTEM_CA_PATH; if (path) { if (!add_string_val (self, path, "ca_path", FALSE, FALSE)) return FALSE; } /* Phase2 CA path */ path = nm_setting_802_1x_get_phase2_ca_path (setting); if (nm_setting_802_1x_get_system_ca_certs (setting)) path = SYSTEM_CA_PATH; if (path) { if (!add_string_val (self, path, "ca_path2", FALSE, FALSE)) return FALSE; } /* CA certificate */ switch (nm_setting_802_1x_get_ca_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_ca_cert_blob (setting); ADD_BLOB_VAL (bytes, "ca_cert", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_ca_cert_path (setting); if (!add_string_val (self, path, "ca_cert", FALSE, FALSE)) return FALSE; break; default: break; } /* Phase 2 CA certificate */ switch (nm_setting_802_1x_get_phase2_ca_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_phase2_ca_cert_blob (setting); ADD_BLOB_VAL (bytes, "ca_cert2", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_ca_cert_path (setting); if (!add_string_val (self, path, "ca_cert2", FALSE, FALSE)) return FALSE; break; default: break; } /* Subject match */ value = nm_setting_802_1x_get_subject_match (setting); if (!add_string_val (self, value, "subject_match", FALSE, FALSE)) return FALSE; value = nm_setting_802_1x_get_phase2_subject_match (setting); if (!add_string_val (self, value, "subject_match2", FALSE, FALSE)) return FALSE; /* altSubjectName match */ ADD_STRING_LIST_VAL (setting, 802_1x, altsubject_match, altsubject_matches, "altsubject_match", ';', FALSE, FALSE); ADD_STRING_LIST_VAL (setting, 802_1x, phase2_altsubject_match, phase2_altsubject_matches, "altsubject_match2", ';', FALSE, FALSE); /* Private key */ added = FALSE; switch (nm_setting_802_1x_get_private_key_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_private_key_blob (setting); ADD_BLOB_VAL (bytes, "private_key", con_uuid); added = TRUE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_private_key_path (setting); if (!add_string_val (self, path, "private_key", FALSE, FALSE)) return FALSE; added = TRUE; break; default: break; } if (added) { NMSetting8021xCKFormat format; NMSetting8021xCKScheme scheme; format = nm_setting_802_1x_get_private_key_format (setting); scheme = nm_setting_802_1x_get_private_key_scheme (setting); if ( scheme == NM_SETTING_802_1X_CK_SCHEME_PATH || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { /* Only add the private key password for PKCS#12 blobs and * all path schemes, since in both of these cases the private key * isn't decrypted at all. */ value = nm_setting_802_1x_get_private_key_password (setting); if (!add_string_val (self, value, "private_key_passwd", FALSE, TRUE)) return FALSE; } if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { /* Only add the client cert if the private key is not PKCS#12, as * wpa_supplicant configuration directs us to do. */ switch (nm_setting_802_1x_get_client_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_client_cert_blob (setting); ADD_BLOB_VAL (bytes, "client_cert", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_client_cert_path (setting); if (!add_string_val (self, path, "client_cert", FALSE, FALSE)) return FALSE; break; default: break; } } } /* Phase 2 private key */ added = FALSE; switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_phase2_private_key_blob (setting); ADD_BLOB_VAL (bytes, "private_key2", con_uuid); added = TRUE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_private_key_path (setting); if (!add_string_val (self, path, "private_key2", FALSE, FALSE)) return FALSE; added = TRUE; break; default: break; } if (added) { NMSetting8021xCKFormat format; NMSetting8021xCKScheme scheme; format = nm_setting_802_1x_get_phase2_private_key_format (setting); scheme = nm_setting_802_1x_get_phase2_private_key_scheme (setting); if ( scheme == NM_SETTING_802_1X_CK_SCHEME_PATH || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { /* Only add the private key password for PKCS#12 blobs and * all path schemes, since in both of these cases the private key * isn't decrypted at all. */ value = nm_setting_802_1x_get_phase2_private_key_password (setting); if (!add_string_val (self, value, "private_key2_passwd", FALSE, TRUE)) return FALSE; } if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { /* Only add the client cert if the private key is not PKCS#12, as * wpa_supplicant configuration directs us to do. */ switch (nm_setting_802_1x_get_phase2_client_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: bytes = nm_setting_802_1x_get_phase2_client_cert_blob (setting); ADD_BLOB_VAL (bytes, "client_cert2", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_client_cert_path (setting); if (!add_string_val (self, path, "client_cert2", FALSE, FALSE)) return FALSE; break; default: break; } } } value = nm_setting_802_1x_get_identity (setting); if (!add_string_val (self, value, "identity", FALSE, FALSE)) return FALSE; value = nm_setting_802_1x_get_anonymous_identity (setting); if (!add_string_val (self, value, "anonymous_identity", FALSE, FALSE)) return FALSE; return TRUE; }
gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, NMSettingWireless * setting, guint32 fixed_freq) { NMSupplicantConfigPrivate *priv; gboolean is_adhoc, is_ap; const char *mode, *band; GBytes *ssid; const char *bssid; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); mode = nm_setting_wireless_get_mode (setting); is_adhoc = (mode && !strcmp (mode, "adhoc")) ? TRUE : FALSE; is_ap = (mode && !strcmp (mode, "ap")) ? TRUE : FALSE; if (is_adhoc || is_ap) priv->ap_scan = 2; else priv->ap_scan = 1; ssid = nm_setting_wireless_get_ssid (setting); if (!nm_supplicant_config_add_option (self, "ssid", (char *) g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), FALSE)) { nm_log_warn (LOGD_SUPPLICANT, "Error adding SSID to supplicant config."); return FALSE; } if (is_adhoc) { if (!nm_supplicant_config_add_option (self, "mode", "1", -1, FALSE)) { nm_log_warn (LOGD_SUPPLICANT, "Error adding mode=1 (adhoc) to supplicant config."); return FALSE; } } if (is_ap) { if (!nm_supplicant_config_add_option (self, "mode", "2", -1, FALSE)) { nm_log_warn (LOGD_SUPPLICANT, "Error adding mode=2 (ap) to supplicant config."); return FALSE; } } if ((is_adhoc || is_ap) && fixed_freq) { char *str_freq; str_freq = g_strdup_printf ("%u", fixed_freq); if (!nm_supplicant_config_add_option (self, "frequency", str_freq, -1, FALSE)) { g_free (str_freq); nm_log_warn (LOGD_SUPPLICANT, "Error adding Ad-Hoc/AP frequency to supplicant config."); return FALSE; } g_free (str_freq); } /* Except for Ad-Hoc and Hotspot, request that the driver probe for the * specific SSID we want to associate with. */ if (!(is_adhoc || is_ap)) { if (!nm_supplicant_config_add_option (self, "scan_ssid", "1", -1, FALSE)) return FALSE; } bssid = nm_setting_wireless_get_bssid (setting); if (bssid) { if (!nm_supplicant_config_add_option (self, "bssid", bssid, strlen (bssid), FALSE)) { nm_log_warn (LOGD_SUPPLICANT, "Error adding BSSID to supplicant config."); return FALSE; } } band = nm_setting_wireless_get_band (setting); if (band) { const char *freqs = NULL; if (!strcmp (band, "a")) freqs = FIVE_GHZ_FREQS; else if (!strcmp (band, "bg")) freqs = TWO_GHZ_FREQS; if (freqs && !nm_supplicant_config_add_option (self, "freq_list", freqs, strlen (freqs), FALSE)) { nm_log_warn (LOGD_SUPPLICANT, "Error adding frequency list/band to supplicant config."); return FALSE; } } // FIXME: channel config item return TRUE; }