supplicant: use binary search to lookup option in "nm-supplicant-settings-verify"
This commit is contained in:
@@ -13,67 +13,62 @@
|
||||
struct Opt {
|
||||
const char *key;
|
||||
const NMSupplOptType type;
|
||||
const gint32 int_low; /* Inclusive */
|
||||
const gint32 int_high; /* Inclusive; max length for strings */
|
||||
const guint32 int_low; /* Inclusive */
|
||||
const guint32 int_high; /* Inclusive; max length for strings */
|
||||
const char *const*str_allowed;
|
||||
};
|
||||
|
||||
static gboolean validate_type_int (const struct Opt * opt,
|
||||
const char * value,
|
||||
const guint32 len);
|
||||
|
||||
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 NMSupplOptType type;
|
||||
const validate_func func;
|
||||
};
|
||||
|
||||
static const struct validate_entry validate_table[] = {
|
||||
{ NM_SUPPL_OPT_TYPE_INT, validate_type_int },
|
||||
{ NM_SUPPL_OPT_TYPE_BYTES, validate_type_bytes },
|
||||
{ NM_SUPPL_OPT_TYPE_UTF8, validate_type_utf8 },
|
||||
{ NM_SUPPL_OPT_TYPE_KEYWORD, validate_type_keyword },
|
||||
};
|
||||
typedef gboolean (*validate_func) (const struct Opt *, const char *, const guint32);
|
||||
|
||||
static const struct Opt opt_table[] = {
|
||||
{ "ssid", NM_SUPPL_OPT_TYPE_BYTES, 0, 32, NULL },
|
||||
{ "bssid", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NULL },
|
||||
{ "scan_ssid", NM_SUPPL_OPT_TYPE_INT, 0, 1, NULL },
|
||||
{ "frequency", NM_SUPPL_OPT_TYPE_INT, 2412, 5825, NULL },
|
||||
{ "altsubject_match", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "altsubject_match2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "anonymous_identity", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "auth_alg", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"OPEN",
|
||||
"SHARED",
|
||||
"LEAP",
|
||||
) },
|
||||
{ "psk", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "pairwise", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"CCMP",
|
||||
"TKIP",
|
||||
"NONE",
|
||||
{ "bgscan", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "bssid", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NULL },
|
||||
{ "ca_cert", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "ca_cert2", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "ca_path", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "ca_path2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "client_cert", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "client_cert2", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "domain_match", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "domain_match2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "domain_suffix_match", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "domain_suffix_match2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "eap", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"LEAP",
|
||||
"MD5",
|
||||
"TLS",
|
||||
"PEAP",
|
||||
"TTLS",
|
||||
"SIM",
|
||||
"PSK",
|
||||
"FAST",
|
||||
"PWD",
|
||||
) },
|
||||
{ "eapol_flags", NM_SUPPL_OPT_TYPE_INT, 0, 3, NULL },
|
||||
{ "eappsk", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "engine", NM_SUPPL_OPT_TYPE_INT, 0, 1, NULL },
|
||||
{ "engine_id", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "fragment_size", NM_SUPPL_OPT_TYPE_INT, 1, 2000, NULL },
|
||||
{ "freq_list", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NULL },
|
||||
{ "frequency", NM_SUPPL_OPT_TYPE_INT, 2412, 5825, NULL },
|
||||
{ "group", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"CCMP",
|
||||
"TKIP",
|
||||
"WEP104",
|
||||
"WEP40",
|
||||
) },
|
||||
{ "proto", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"WPA",
|
||||
"RSN",
|
||||
) },
|
||||
{ "identity", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "ieee80211w", NM_SUPPL_OPT_TYPE_INT, 0, 2, NULL },
|
||||
{ "ignore_broadcast_ssid", NM_SUPPL_OPT_TYPE_INT, 0, 2, NULL },
|
||||
{ "key_id", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "key_mgmt", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"WPA-PSK",
|
||||
"WPA-PSK-SHA256",
|
||||
@@ -92,34 +87,20 @@ static const struct Opt opt_table[] = {
|
||||
"OWE",
|
||||
"NONE",
|
||||
) },
|
||||
{ "wep_key0", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "wep_key1", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "wep_key2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "wep_key3", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "wep_tx_keyidx", NM_SUPPL_OPT_TYPE_INT, 0, 3, NULL },
|
||||
{ "eapol_flags", NM_SUPPL_OPT_TYPE_INT, 0, 3, NULL },
|
||||
{ "eap", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"LEAP",
|
||||
"MD5",
|
||||
"TLS",
|
||||
"PEAP",
|
||||
"TTLS",
|
||||
"SIM",
|
||||
"PSK",
|
||||
"FAST",
|
||||
"PWD",
|
||||
{ "macsec_integ_only", NM_SUPPL_OPT_TYPE_INT, 0, 1, NULL },
|
||||
{ "macsec_policy", NM_SUPPL_OPT_TYPE_INT, 0, 1, NULL },
|
||||
{ "macsec_port", NM_SUPPL_OPT_TYPE_INT, 1, 65534, NULL },
|
||||
{ "mka_cak", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "mka_ckn", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "nai", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "pac_file", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "pairwise", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"CCMP",
|
||||
"TKIP",
|
||||
"NONE",
|
||||
) },
|
||||
{ "identity", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "password", NM_SUPPL_OPT_TYPE_UTF8, 0, 0, NULL },
|
||||
{ "ca_path", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "subject_match", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "altsubject_match", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "domain_suffix_match", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "domain_match", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "ca_cert", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "client_cert", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "private_key", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "private_key_passwd", NM_SUPPL_OPT_TYPE_BYTES, 0, 1024, NULL },
|
||||
{ "pcsc", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "phase1", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"peapver=0",
|
||||
"peapver=1",
|
||||
@@ -153,35 +134,26 @@ static const struct Opt opt_table[] = {
|
||||
"autheap=GTC",
|
||||
"autheap=TLS",
|
||||
) },
|
||||
{ "anonymous_identity", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "ca_path2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "subject_match2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "altsubject_match2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "domain_suffix_match2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "domain_match2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "ca_cert2", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "client_cert2", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "pin", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "private_key", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "private_key2", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "private_key2_passwd", NM_SUPPL_OPT_TYPE_BYTES, 0, 1024, NULL },
|
||||
{ "pin", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "pcsc", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "nai", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "eappsk", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "pac_file", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "engine", NM_SUPPL_OPT_TYPE_INT, 0, 1, NULL },
|
||||
{ "engine_id", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "key_id", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "fragment_size", NM_SUPPL_OPT_TYPE_INT, 1, 2000, NULL },
|
||||
{ "private_key_passwd", NM_SUPPL_OPT_TYPE_BYTES, 0, 1024, NULL },
|
||||
{ "proactive_key_caching", NM_SUPPL_OPT_TYPE_INT, 0, 1, NULL },
|
||||
{ "bgscan", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "freq_list", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NULL },
|
||||
{ "macsec_policy", NM_SUPPL_OPT_TYPE_INT, 0, 1, NULL },
|
||||
{ "macsec_integ_only", NM_SUPPL_OPT_TYPE_INT, 0, 1, NULL },
|
||||
{ "mka_cak", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "mka_ckn", NM_SUPPL_OPT_TYPE_BYTES, 0, 65536, NULL },
|
||||
{ "macsec_port", NM_SUPPL_OPT_TYPE_INT, 1, 65534, NULL },
|
||||
{ "ieee80211w", NM_SUPPL_OPT_TYPE_INT, 0, 2, NULL },
|
||||
{ "ignore_broadcast_ssid", NM_SUPPL_OPT_TYPE_INT, 0, 2, NULL },
|
||||
{ "proto", NM_SUPPL_OPT_TYPE_KEYWORD, 0, 0, NM_MAKE_STRV (
|
||||
"WPA",
|
||||
"RSN",
|
||||
) },
|
||||
{ "psk", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "scan_ssid", NM_SUPPL_OPT_TYPE_INT, 0, 1, NULL },
|
||||
{ "ssid", NM_SUPPL_OPT_TYPE_BYTES, 0, 32, NULL },
|
||||
{ "subject_match", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "subject_match2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "wep_key0", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "wep_key1", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "wep_key2", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "wep_key3", NM_SUPPL_OPT_TYPE_BYTES, 0, 0, NULL },
|
||||
{ "wep_tx_keyidx", NM_SUPPL_OPT_TYPE_INT, 0, 3, NULL },
|
||||
};
|
||||
|
||||
static gboolean
|
||||
@@ -191,8 +163,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;
|
||||
@@ -205,8 +177,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)
|
||||
@@ -222,8 +194,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
|
||||
@@ -242,8 +214,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)
|
||||
@@ -279,40 +251,73 @@ validate_type_keyword (const struct Opt * opt,
|
||||
}
|
||||
|
||||
NMSupplOptType
|
||||
nm_supplicant_settings_verify_setting (const char * key,
|
||||
const char * value,
|
||||
nm_supplicant_settings_verify_setting (const char *key,
|
||||
const char *value,
|
||||
const guint32 len)
|
||||
{
|
||||
NMSupplOptType type = NM_SUPPL_OPT_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;
|
||||
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 != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
g_return_val_if_fail (key, FALSE);
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
|
||||
if (strcmp (key, "mode") == 0) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,8 @@ typedef enum {
|
||||
NM_SUPPL_OPT_TYPE_BYTES,
|
||||
NM_SUPPL_OPT_TYPE_UTF8,
|
||||
NM_SUPPL_OPT_TYPE_KEYWORD,
|
||||
NM_SUPPL_OPT_TYPE_STRING
|
||||
NM_SUPPL_OPT_TYPE_STRING,
|
||||
_NM_SUPPL_OPT_TYPE_NUM,
|
||||
} NMSupplOptType;
|
||||
|
||||
NMSupplOptType nm_supplicant_settings_verify_setting (const char *key,
|
||||
|
Reference in New Issue
Block a user