diff options
Diffstat (limited to 'src/supplicant/nm-supplicant-settings-verify.c')
| -rw-r--r-- | src/supplicant/nm-supplicant-settings-verify.c | 370 |
1 files changed, 213 insertions, 157 deletions
diff --git a/src/supplicant/nm-supplicant-settings-verify.c b/src/supplicant/nm-supplicant-settings-verify.c index 58dbd73a..954a4649 100644 --- a/src/supplicant/nm-supplicant-settings-verify.c +++ b/src/supplicant/nm-supplicant-settings-verify.c @@ -11,131 +11,154 @@ #include <stdlib.h> struct Opt { - const char * key; - const OptType type; - const gint32 int_low; /* Inclusive */ - const gint32 int_high; /* Inclusive; max length for strings */ - const gboolean str_allowed_multiple; + const char *key; const char *const*str_allowed; + const NMSupplOptType type; + const guint32 int_low; /* Inclusive */ + const guint32 int_high; /* Inclusive; max length for strings */ }; -static gboolean validate_type_int (const struct Opt * opt, - const char * value, - const guint32 len); +typedef gboolean (*validate_func) (const struct Opt *, const char *, const guint32); -static gboolean validate_type_bytes (const struct Opt * opt, - const char * value, - const guint32 len); - -static gboolean validate_type_utf8 (const struct Opt *opt, - const char * value, - const guint32 len); - -static gboolean validate_type_keyword (const struct Opt * opt, - const char * value, - const guint32 len); - -typedef gboolean (*validate_func)(const struct Opt *, const char *, const guint32); - -struct validate_entry { - const OptType type; - const validate_func func; -}; - -static const struct validate_entry validate_table[] = { - { TYPE_INT, validate_type_int }, - { TYPE_BYTES, validate_type_bytes }, - { TYPE_UTF8, validate_type_utf8 }, - { TYPE_KEYWORD, validate_type_keyword }, -}; - -static const char *const pairwise_allowed[] = { "CCMP", "TKIP", "NONE", NULL }; -static const char *const group_allowed[] = { "CCMP", "TKIP", "WEP104", "WEP40", NULL }; -static const char *const proto_allowed[] = { "WPA", "RSN", NULL }; -static const char *const key_mgmt_allowed[] = { "WPA-PSK", "WPA-PSK-SHA256", "FT-PSK", - "WPA-EAP", "WPA-EAP-SHA256", "FT-EAP", "FT-EAP-SHA384", - "FILS-SHA256", "FILS-SHA384", - "IEEE8021X", "SAE", "FT-SAE", - "OWE", "NONE", NULL }; -static const char *const auth_alg_allowed[] = { "OPEN", "SHARED", "LEAP", NULL }; -static const char *const eap_allowed[] = { "LEAP", "MD5", "TLS", "PEAP", "TTLS", "SIM", - "PSK", "FAST", "PWD", NULL }; - -static const char *const phase1_allowed[] = { "peapver=0", "peapver=1", "peaplabel=1", - "peap_outer_success=0", "include_tls_length=1", - "sim_min_num_chal=3", "fast_provisioning=0", - "fast_provisioning=1", "fast_provisioning=2", - "fast_provisioning=3", "tls_disable_tlsv1_0=0", - "tls_disable_tlsv1_0=1", "tls_disable_tlsv1_1=0", - "tls_disable_tlsv1_1=1", "tls_disable_tlsv1_2=0", - "tls_disable_tlsv1_2=1", NULL }; -static const char *const phase2_allowed[] = { "auth=PAP", "auth=CHAP", "auth=MSCHAP", - "auth=MSCHAPV2", "auth=GTC", "auth=OTP", - "auth=MD5", "auth=TLS", "autheap=MD5", - "autheap=MSCHAPV2", "autheap=OTP", - "autheap=GTC", "autheap=TLS", NULL }; +#define OPT_INT( _key, _int_low, _int_high) { .key = _key, .type = NM_SUPPL_OPT_TYPE_INT, .int_high = _int_high, .int_low = _int_low, } +#define OPT_BYTES( _key, _int_high) { .key = _key, .type = NM_SUPPL_OPT_TYPE_BYTES, .int_high = _int_high, } +#define OPT_UTF8( _key, _int_high) { .key = _key, .type = NM_SUPPL_OPT_TYPE_UTF8, .int_high = _int_high, } +#define OPT_KEYWORD(_key, _str_allowed) { .key = _key, .type = NM_SUPPL_OPT_TYPE_KEYWORD, .str_allowed = _str_allowed, } static const struct Opt opt_table[] = { - { "ssid", TYPE_BYTES, 0, 32,FALSE, NULL }, - { "bssid", TYPE_KEYWORD, 0, 0, FALSE, NULL }, - { "scan_ssid", TYPE_INT, 0, 1, FALSE, NULL }, - { "frequency", TYPE_INT, 2412, 5825, FALSE, NULL }, - { "auth_alg", TYPE_KEYWORD, 0, 0, FALSE, auth_alg_allowed }, - { "psk", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "pairwise", TYPE_KEYWORD, 0, 0, FALSE, pairwise_allowed }, - { "group", TYPE_KEYWORD, 0, 0, FALSE, group_allowed }, - { "proto", TYPE_KEYWORD, 0, 0, FALSE, proto_allowed }, - { "key_mgmt", TYPE_KEYWORD, 0, 0, FALSE, key_mgmt_allowed }, - { "wep_key0", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "wep_key1", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "wep_key2", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "wep_key3", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "wep_tx_keyidx", TYPE_INT, 0, 3, FALSE, NULL }, - { "eapol_flags", TYPE_INT, 0, 3, FALSE, NULL }, - { "eap", TYPE_KEYWORD, 0, 0, FALSE, eap_allowed }, - { "identity", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "password", TYPE_UTF8, 0, 0, FALSE, NULL }, - { "ca_path", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "subject_match", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "altsubject_match", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "domain_suffix_match",TYPE_BYTES, 0, 0, FALSE, NULL }, - { "domain_match", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "ca_cert", TYPE_BYTES, 0, 65536, FALSE, NULL }, - { "client_cert", TYPE_BYTES, 0, 65536, FALSE, NULL }, - { "private_key", TYPE_BYTES, 0, 65536, FALSE, NULL }, - { "private_key_passwd", TYPE_BYTES, 0, 1024, FALSE, NULL }, - { "phase1", TYPE_KEYWORD, 0, 0, TRUE, phase1_allowed }, - { "phase2", TYPE_KEYWORD, 0, 0, TRUE, phase2_allowed }, - { "anonymous_identity", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "ca_path2", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "subject_match2", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "altsubject_match2", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "domain_suffix_match2", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "domain_match2", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "ca_cert2", TYPE_BYTES, 0, 65536, FALSE, NULL }, - { "client_cert2", TYPE_BYTES, 0, 65536, FALSE, NULL }, - { "private_key2", TYPE_BYTES, 0, 65536, FALSE, NULL }, - { "private_key2_passwd",TYPE_BYTES, 0, 1024, FALSE, NULL }, - { "pin", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "pcsc", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "nai", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "eappsk", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "pac_file", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "engine", TYPE_INT, 0, 1, FALSE, NULL }, - { "engine_id", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "key_id", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "fragment_size", TYPE_INT, 1, 2000, FALSE, NULL }, - { "proactive_key_caching", TYPE_INT, 0, 1, FALSE, NULL }, - { "bgscan", TYPE_BYTES, 0, 0, FALSE, NULL }, - { "pac_file", TYPE_BYTES, 0, 1024, FALSE, NULL }, - { "freq_list", TYPE_KEYWORD, 0, 0, FALSE, NULL }, - { "macsec_policy", TYPE_INT, 0, 1, FALSE, NULL }, - { "macsec_integ_only", TYPE_INT, 0, 1, FALSE, NULL }, - { "mka_cak", TYPE_BYTES, 0, 65536, FALSE, NULL }, - { "mka_ckn", TYPE_BYTES, 0, 65536, FALSE, NULL }, - { "macsec_port", TYPE_INT, 1, 65534, FALSE, NULL }, - { "ieee80211w", TYPE_INT, 0, 2, FALSE, NULL }, - { "ignore_broadcast_ssid", TYPE_INT, 0, 2, FALSE, NULL }, + OPT_BYTES ("altsubject_match", 0), + OPT_BYTES ("altsubject_match2", 0), + OPT_BYTES ("anonymous_identity", 0), + OPT_KEYWORD ("auth_alg", NM_MAKE_STRV ( + "OPEN", + "SHARED", + "LEAP", + )), + OPT_BYTES ("bgscan", 0), + OPT_KEYWORD ("bssid", NULL), + OPT_BYTES ("ca_cert", 65536), + OPT_BYTES ("ca_cert2", 65536), + OPT_BYTES ("ca_path", 0), + OPT_BYTES ("ca_path2", 0), + OPT_BYTES ("client_cert", 65536), + OPT_BYTES ("client_cert2", 65536), + OPT_BYTES ("domain_match", 0), + OPT_BYTES ("domain_match2", 0), + OPT_BYTES ("domain_suffix_match", 0), + OPT_BYTES ("domain_suffix_match2", 0), + OPT_KEYWORD ("eap", NM_MAKE_STRV ( + "LEAP", + "MD5", + "TLS", + "PEAP", + "TTLS", + "SIM", + "PSK", + "FAST", + "PWD", + )), + OPT_INT ("eapol_flags", 0, 3), + OPT_BYTES ("eappsk", 0), + OPT_INT ("engine", 0, 1), + OPT_BYTES ("engine_id", 0), + OPT_INT ("fragment_size", 1, 2000), + OPT_KEYWORD ("freq_list", NULL), + OPT_INT ("frequency", 2412, 5825), + OPT_KEYWORD ("group", NM_MAKE_STRV ( + "CCMP", + "TKIP", + "WEP104", + "WEP40", + )), + OPT_BYTES ("identity", 0), + OPT_INT ("ieee80211w", 0, 2), + OPT_INT ("ignore_broadcast_ssid", 0, 2), + OPT_BYTES ("key_id", 0), + OPT_KEYWORD ("key_mgmt", NM_MAKE_STRV ( + "WPA-PSK", + "WPA-PSK-SHA256", + "FT-PSK", + "WPA-EAP", + "WPA-EAP-SHA256", + "FT-EAP", + "FT-EAP-SHA384", + "FILS-SHA256", + "FILS-SHA384", + "FT-FILS-SHA256", + "FT-FILS-SHA384", + "IEEE8021X", + "SAE", + "FT-SAE", + "OWE", + "NONE", + )), + OPT_INT ("macsec_integ_only", 0, 1), + OPT_INT ("macsec_policy", 0, 1), + OPT_INT ("macsec_port", 1, 65534), + OPT_BYTES ("mka_cak", 65536), + OPT_BYTES ("mka_ckn", 65536), + OPT_BYTES ("nai", 0), + OPT_BYTES ("pac_file", 0), + OPT_KEYWORD ("pairwise", NM_MAKE_STRV ( + "CCMP", + "TKIP", + "NONE", + )), + OPT_UTF8 ("password", 0), + OPT_BYTES ("pcsc", 0), + OPT_KEYWORD ("phase1", NM_MAKE_STRV ( + "peapver=0", + "peapver=1", + "peaplabel=1", + "peap_outer_success=0", + "include_tls_length=1", + "sim_min_num_chal=3", + "fast_provisioning=0", + "fast_provisioning=1", + "fast_provisioning=2", + "fast_provisioning=3", + "tls_disable_tlsv1_0=0", + "tls_disable_tlsv1_0=1", + "tls_disable_tlsv1_1=0", + "tls_disable_tlsv1_1=1", + "tls_disable_tlsv1_2=0", + "tls_disable_tlsv1_2=1", + )), + OPT_KEYWORD ("phase2", NM_MAKE_STRV ( + "auth=PAP", + "auth=CHAP", + "auth=MSCHAP", + "auth=MSCHAPV2", + "auth=GTC", + "auth=OTP", + "auth=MD5", + "auth=TLS", + "autheap=MD5", + "autheap=MSCHAPV2", + "autheap=OTP", + "autheap=GTC", + "autheap=TLS", + )), + OPT_BYTES ("pin", 0), + OPT_BYTES ("private_key", 65536), + OPT_BYTES ("private_key2", 65536), + OPT_BYTES ("private_key2_passwd", 1024), + OPT_BYTES ("private_key_passwd", 1024), + OPT_INT ("proactive_key_caching", 0, 1), + OPT_KEYWORD ("proto", NM_MAKE_STRV ( + "WPA", + "RSN", + )), + OPT_BYTES ("psk", 0), + OPT_INT ("scan_ssid", 0, 1), + OPT_BYTES ("ssid", 32), + OPT_BYTES ("subject_match", 0), + OPT_BYTES ("subject_match2", 0), + OPT_BYTES ("wep_key0", 0), + OPT_BYTES ("wep_key1", 0), + OPT_BYTES ("wep_key2", 0), + OPT_BYTES ("wep_key3", 0), + OPT_INT ("wep_tx_keyidx", 0, 3), }; static gboolean @@ -145,8 +168,8 @@ validate_type_int (const struct Opt * opt, { gint64 v; - g_return_val_if_fail (opt != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); + nm_assert (opt); + nm_assert (value); v = _nm_utils_ascii_str_to_int64 (value, 10, opt->int_low, opt->int_high, G_MININT64); return v != G_MININT64 || errno == 0; @@ -159,8 +182,8 @@ validate_type_bytes (const struct Opt * opt, { guint32 check_len; - g_return_val_if_fail (opt != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); + nm_assert (opt); + nm_assert (value); check_len = opt->int_high ?: 255; if (len > check_len) @@ -176,8 +199,8 @@ validate_type_utf8 (const struct Opt *opt, { guint32 check_len; - g_return_val_if_fail (opt != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); + nm_assert (opt); + nm_assert (value); check_len = opt->int_high ?: 255; /* Note that we deliberately don't validate the UTF-8, because @@ -196,8 +219,8 @@ validate_type_keyword (const struct Opt * opt, { gs_free char *value_free = NULL; - g_return_val_if_fail (opt != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); + nm_assert (opt); + nm_assert (value); /* Allow everything */ if (!opt->str_allowed) @@ -232,41 +255,74 @@ validate_type_keyword (const struct Opt * opt, } } -OptType -nm_supplicant_settings_verify_setting (const char * key, - const char * value, +NMSupplOptType +nm_supplicant_settings_verify_setting (const char *key, + const char *value, const guint32 len) { - OptType type = TYPE_INVALID; - int opt_count = sizeof (opt_table) / sizeof (opt_table[0]); - int val_count = sizeof (validate_table) / sizeof (validate_table[0]); - int i, j; - - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - if (strcmp (key, "mode") == 0) { - if (len != 1) - return TYPE_INVALID; - if (!NM_IN_SET (value[0], '1', '2', '5')) - return TYPE_INVALID; - return TYPE_INT; + static const validate_func validate_table[_NM_SUPPL_OPT_TYPE_NUM - 1] = { + [NM_SUPPL_OPT_TYPE_INT - 1] = validate_type_int, + [NM_SUPPL_OPT_TYPE_BYTES - 1] = validate_type_bytes, + [NM_SUPPL_OPT_TYPE_UTF8 - 1] = validate_type_utf8, + [NM_SUPPL_OPT_TYPE_KEYWORD - 1] = validate_type_keyword, + }; + const struct Opt *opt; + gssize opt_idx; + + g_return_val_if_fail (key, FALSE); + g_return_val_if_fail (value, FALSE); + + if (NM_MORE_ASSERT_ONCE (5)) { + gsize i; + + for (i = 0; i < G_N_ELEMENTS (opt_table); i++) { + opt = &opt_table[i]; + + nm_assert (opt->key); + nm_assert (opt->type > NM_SUPPL_OPT_TYPE_INVALID); + nm_assert (opt->type < _NM_SUPPL_OPT_TYPE_NUM); + if (i > 0) + nm_assert (strcmp (opt[-1].key, opt->key) < 0); + nm_assert (validate_table[opt->type - 1]); + + nm_assert ( !opt->str_allowed + || (opt->type == NM_SUPPL_OPT_TYPE_KEYWORD)); + nm_assert ( !opt->str_allowed + || NM_PTRARRAY_LEN (opt->str_allowed) > 0); + + nm_assert ( opt->int_low == 0 + || opt->type == NM_SUPPL_OPT_TYPE_INT); + + nm_assert ( opt->int_high == 0 + || NM_IN_SET (opt->type, NM_SUPPL_OPT_TYPE_INT, + NM_SUPPL_OPT_TYPE_UTF8, + NM_SUPPL_OPT_TYPE_BYTES)); + + nm_assert ( opt->type != NM_SUPPL_OPT_TYPE_INT + || opt->int_low < opt->int_high); + } } - for (i = 0; i < opt_count; i++) { - if (strcmp (opt_table[i].key, key) != 0) - continue; - - for (j = 0; j < val_count; j++) { - if (validate_table[j].type == opt_table[i].type) { - if ((*(validate_table[j].func))(&opt_table[i], value, len)) { - type = opt_table[i].type; - break; - } - } + opt_idx = nm_utils_array_find_binary_search (opt_table, + sizeof (opt_table[0]), + G_N_ELEMENTS (opt_table), + &key, + nm_strcmp_p_with_data, + NULL); + if (opt_idx < 0) { + if (nm_streq (key, "mode")) { + if (len != 1) + return NM_SUPPL_OPT_TYPE_INVALID; + if (!NM_IN_SET (value[0], '1', '2', '5')) + return NM_SUPPL_OPT_TYPE_INVALID; + return NM_SUPPL_OPT_TYPE_INT; } + return NM_SUPPL_OPT_TYPE_INVALID; } - return type; -} + opt = &opt_table[opt_idx]; + if (!((validate_table[opt->type - 1]) (opt, value, len))) + return NM_SUPPL_OPT_TYPE_INVALID; + return opt->type; +} |