keyfile: add handler context for all parser callbacks

From inside a callback 4 properties are potentially interesting
to all callbacks: the currenty group, key, setting and property-name.

Refactor the code to track these properties in NMKeyfileHandlerData
and distinguish between the property name and the keyfile key.
This commit is contained in:
Thomas Haller 2020-05-25 18:24:00 +02:00
parent 5c67b72bb7
commit 7d47a8fdbf
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
4 changed files with 204 additions and 73 deletions

View file

@ -118,15 +118,6 @@ GKeyFile *nm_keyfile_write (NMConnection *connection,
* handler_type %NM_KEYFILE_HANDLER_TYPE_WARN. * handler_type %NM_KEYFILE_HANDLER_TYPE_WARN.
*/ */
typedef struct { typedef struct {
/* might be %NULL, if the warning is not about a group. */
const char *group;
/* might be %NULL, if the warning is not about a setting. */
NMSetting *setting;
/* might be %NULL, if the warning is not about a property. */
const char *property_name;
NMKeyfileWarnSeverity severity; NMKeyfileWarnSeverity severity;
const char *message; const char *message;
} NMKeyfileHandlerDataWarn; } NMKeyfileHandlerDataWarn;
@ -139,12 +130,19 @@ typedef struct {
*/ */
typedef struct { typedef struct {
const NMSetting8021xSchemeVtable *vtable; const NMSetting8021xSchemeVtable *vtable;
NMSetting8021x *setting;
} NMKeyfileHandlerDataWriteCert; } NMKeyfileHandlerDataWriteCert;
struct _NMKeyfileHandlerData { struct _NMKeyfileHandlerData {
NMKeyfileHandlerType type; NMKeyfileHandlerType type;
GError **p_error; GError **p_error;
const char *kf_group_name;
const char *kf_key;
NMSetting *cur_setting;
const char *cur_property;
union { union {
NMKeyfileHandlerDataWarn warn; NMKeyfileHandlerDataWarn warn;
NMKeyfileHandlerDataWriteCert write_cert; NMKeyfileHandlerDataWriteCert write_cert;

View file

@ -52,6 +52,10 @@ typedef struct {
static void static void
_key_file_handler_data_init (NMKeyfileHandlerData *handler_data, _key_file_handler_data_init (NMKeyfileHandlerData *handler_data,
NMKeyfileHandlerType handler_type, NMKeyfileHandlerType handler_type,
const char *kf_group_name,
const char *kf_key,
NMSetting *cur_setting,
const char *cur_property,
GError **p_error) GError **p_error)
{ {
nm_assert (handler_data); nm_assert (handler_data);
@ -59,23 +63,61 @@ _key_file_handler_data_init (NMKeyfileHandlerData *handler_data,
handler_data->type = handler_type; handler_data->type = handler_type;
handler_data->p_error = p_error; handler_data->p_error = p_error;
handler_data->kf_group_name = kf_group_name;
handler_data->kf_key = kf_key;
handler_data->cur_setting = cur_setting;
handler_data->cur_property = cur_property;
}
static void
_key_file_handler_data_init_read (NMKeyfileHandlerData *handler_data,
NMKeyfileHandlerType handler_type,
KeyfileReaderInfo *info,
const char *kf_key,
const char *cur_property)
{
_key_file_handler_data_init (handler_data,
handler_type,
info->group,
kf_key,
info->setting,
cur_property,
&info->error);
}
static void
_key_file_handler_data_init_write (NMKeyfileHandlerData *handler_data,
NMKeyfileHandlerType handler_type,
KeyfileWriterInfo *info,
const char *kf_group,
const char *kf_key,
NMSetting *cur_setting,
const char *cur_property)
{
_key_file_handler_data_init (handler_data,
handler_type,
kf_group,
kf_key,
cur_setting,
cur_property,
&info->error);
} }
static void static void
_handle_warn (KeyfileReaderInfo *info, _handle_warn (KeyfileReaderInfo *info,
const char *property_name, const char *kf_key,
const char *cur_property,
NMKeyfileWarnSeverity severity, NMKeyfileWarnSeverity severity,
char *message) char *message)
{ {
NMKeyfileHandlerData handler_data; NMKeyfileHandlerData handler_data;
_key_file_handler_data_init (&handler_data, _key_file_handler_data_init_read (&handler_data,
NM_KEYFILE_HANDLER_TYPE_WARN, NM_KEYFILE_HANDLER_TYPE_WARN,
&info->error); info,
kf_key,
cur_property);
handler_data.warn = (NMKeyfileHandlerDataWarn) { handler_data.warn = (NMKeyfileHandlerDataWarn) {
.group = info->group,
.setting = info->setting,
.property_name = property_name,
.severity = severity, .severity = severity,
.message = message, .message = message,
}; };
@ -87,14 +129,18 @@ _handle_warn (KeyfileReaderInfo *info,
info->user_data); info->user_data);
g_free (message); g_free (message);
} }
#define handle_warn(arg_info, arg_property_name, arg_severity, ...) \
#define handle_warn(arg_info, arg_kf_key, arg_property_name, arg_severity, ...) \
({ \ ({ \
KeyfileReaderInfo *_info = (arg_info); \ KeyfileReaderInfo *_info = (arg_info); \
\ \
nm_assert (!_info->error); \ nm_assert (!_info->error); \
\ \
if (_info->read_handler) { \ if (_info->read_handler) { \
_handle_warn (_info, (arg_property_name), (arg_severity), \ _handle_warn (_info, \
(arg_kf_key), \
(arg_property_name), \
(arg_severity), \
g_strdup_printf (__VA_ARGS__)); \ g_strdup_printf (__VA_ARGS__)); \
} \ } \
_info->error == NULL; \ _info->error == NULL; \
@ -196,15 +242,22 @@ read_array_of_uint (GKeyFile *file,
} }
static gboolean static gboolean
get_one_int (KeyfileReaderInfo *info, const char *property_name, const char *str, guint32 max_val, guint32 *out) get_one_int (KeyfileReaderInfo *info,
const char *kf_key,
const char *property_name,
const char *str,
guint32 max_val,
guint32 *out)
{ {
gint64 tmp; gint64 tmp;
nm_assert ((!info) == (!property_name)); nm_assert ((!info) == (!property_name));
nm_assert ((!info) == (!kf_key));
if (!str || !str[0]) { if (!str || !str[0]) {
if (property_name) { if (info) {
handle_warn (info, handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring missing number")); _("ignoring missing number"));
@ -214,8 +267,9 @@ get_one_int (KeyfileReaderInfo *info, const char *property_name, const char *str
tmp = _nm_utils_ascii_str_to_int64 (str, 10, 0, max_val, -1); tmp = _nm_utils_ascii_str_to_int64 (str, 10, 0, max_val, -1);
if (tmp == -1) { if (tmp == -1) {
if (property_name) { if (info) {
handle_warn (info, handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid number '%s'"), _("ignoring invalid number '%s'"),
@ -229,7 +283,12 @@ get_one_int (KeyfileReaderInfo *info, const char *property_name, const char *str
} }
static gpointer static gpointer
build_address (KeyfileReaderInfo *info, int family, const char *address_str, guint32 plen, const char *property_name) build_address (KeyfileReaderInfo *info,
const char *kf_key,
const char *property_name,
int family,
const char *address_str,
guint32 plen)
{ {
NMIPAddress *addr; NMIPAddress *addr;
GError *error = NULL; GError *error = NULL;
@ -239,6 +298,7 @@ build_address (KeyfileReaderInfo *info, int family, const char *address_str, gui
addr = nm_ip_address_new (family, address_str, plen, &error); addr = nm_ip_address_new (family, address_str, plen, &error);
if (!addr) { if (!addr) {
handle_warn (info, handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid %s address: %s"), _("ignoring invalid %s address: %s"),
@ -252,6 +312,7 @@ build_address (KeyfileReaderInfo *info, int family, const char *address_str, gui
static gpointer static gpointer
build_route (KeyfileReaderInfo *info, build_route (KeyfileReaderInfo *info,
const char *kf_key,
const char *property_name, const char *property_name,
int family, int family,
const char *dest_str, const char *dest_str,
@ -279,11 +340,12 @@ build_route (KeyfileReaderInfo *info,
**/ **/
if ( family == AF_INET6 if ( family == AF_INET6
&& !metric_str && !metric_str
&& get_one_int (NULL, NULL, gateway_str, G_MAXUINT32, &u32)) { && get_one_int (NULL, NULL, NULL, gateway_str, G_MAXUINT32, &u32)) {
metric = u32; metric = u32;
gateway_str = NULL; gateway_str = NULL;
} else { } else {
handle_warn (info, handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid gateway '%s' for %s route"), _("ignoring invalid gateway '%s' for %s route"),
@ -297,7 +359,12 @@ build_route (KeyfileReaderInfo *info,
/* parse metric, default to -1 */ /* parse metric, default to -1 */
if (metric_str) { if (metric_str) {
if (!get_one_int (info, property_name, metric_str, G_MAXUINT32, &u32)) if (!get_one_int (info,
kf_key,
property_name,
metric_str,
G_MAXUINT32,
&u32))
return NULL; return NULL;
metric = u32; metric = u32;
} }
@ -310,6 +377,7 @@ build_route (KeyfileReaderInfo *info,
&error); &error);
if (!route) { if (!route) {
handle_warn (info, handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid %s route: %s"), _("ignoring invalid %s route: %s"),
@ -455,7 +523,7 @@ static gpointer
read_one_ip_address_or_route (KeyfileReaderInfo *info, read_one_ip_address_or_route (KeyfileReaderInfo *info,
const char *property_name, const char *property_name,
const char *setting_name, const char *setting_name,
const char *key_name, const char *kf_key,
gboolean ipv6, gboolean ipv6,
gboolean route, gboolean route,
char **out_gateway, char **out_gateway,
@ -472,9 +540,9 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
gs_free char *value = NULL; gs_free char *value = NULL;
gs_free char *value_orig = NULL; gs_free char *value_orig = NULL;
#define VALUE_ORIG() (value_orig ?: (value_orig = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key_name, NULL))) #define VALUE_ORIG() (value_orig ?: (value_orig = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, kf_key, NULL)))
value = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key_name, NULL); value = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, kf_key, NULL);
if (!value) if (!value)
return NULL; return NULL;
@ -484,11 +552,12 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
address_str = read_field (&current, &err_str, IP_ADDRESS_CHARS, DELIMITERS); address_str = read_field (&current, &err_str, IP_ADDRESS_CHARS, DELIMITERS);
if (err_str) { if (err_str) {
handle_warn (info, handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("unexpected character '%c' for address %s: '%s' (position %td)"), _("unexpected character '%c' for address %s: '%s' (position %td)"),
*err_str, *err_str,
key_name, kf_key,
VALUE_ORIG (), VALUE_ORIG (),
err_str - current); err_str - current);
return NULL; return NULL;
@ -499,11 +568,12 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
gateway_str = read_field (&current, &err_str, IP_ADDRESS_CHARS, DELIMITERS); gateway_str = read_field (&current, &err_str, IP_ADDRESS_CHARS, DELIMITERS);
if (err_str) { if (err_str) {
handle_warn (info, handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("unexpected character '%c' for %s: '%s' (position %td)"), _("unexpected character '%c' for %s: '%s' (position %td)"),
*err_str, *err_str,
key_name, kf_key,
VALUE_ORIG (), VALUE_ORIG (),
err_str - current); err_str - current);
return NULL; return NULL;
@ -513,11 +583,12 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
metric_str = read_field (&current, &err_str, DIGITS, DELIMITERS); metric_str = read_field (&current, &err_str, DIGITS, DELIMITERS);
if (err_str) { if (err_str) {
handle_warn (info, handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("unexpected character '%c' in prefix length for %s: '%s' (position %td)"), _("unexpected character '%c' in prefix length for %s: '%s' (position %td)"),
*err_str, *err_str,
key_name, kf_key,
VALUE_ORIG (), VALUE_ORIG (),
err_str - current); err_str - current);
return NULL; return NULL;
@ -529,19 +600,21 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
if (*current) { if (*current) {
/* another field follows */ /* another field follows */
handle_warn (info, handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("garbage at the end of value %s: '%s'"), _("garbage at the end of value %s: '%s'"),
key_name, kf_key,
VALUE_ORIG ()); VALUE_ORIG ());
return NULL; return NULL;
} else { } else {
/* semicolon at the end of input */ /* semicolon at the end of input */
if (!handle_warn (info, if (!handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_INFO, NM_KEYFILE_WARN_SEVERITY_INFO,
_("deprecated semicolon at the end of value %s: '%s'"), _("deprecated semicolon at the end of value %s: '%s'"),
key_name, kf_key,
VALUE_ORIG ())) VALUE_ORIG ()))
return NULL; return NULL;
} }
@ -551,14 +624,20 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
/* parse plen, fallback to defaults */ /* parse plen, fallback to defaults */
if (plen_str) { if (plen_str) {
if (!get_one_int (info, property_name, plen_str, ipv6 ? 128 : 32, &plen)) { if (!get_one_int (info,
kf_key,
property_name,
plen_str,
ipv6 ? 128 : 32,
&plen)) {
plen = DEFAULT_PREFIX (route, ipv6); plen = DEFAULT_PREFIX (route, ipv6);
if ( info->error if ( info->error
|| !handle_warn (info, || !handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid prefix length for %s '%s', defaulting to %d"), _("invalid prefix length for %s '%s', defaulting to %d"),
key_name, kf_key,
VALUE_ORIG (), VALUE_ORIG (),
plen)) plen))
return NULL; return NULL;
@ -566,10 +645,11 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
} else { } else {
plen = DEFAULT_PREFIX (route, ipv6); plen = DEFAULT_PREFIX (route, ipv6);
if (!handle_warn (info, if (!handle_warn (info,
kf_key,
property_name, property_name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("missing prefix length for %s '%s', defaulting to %d"), _("missing prefix length for %s '%s', defaulting to %d"),
key_name, kf_key,
VALUE_ORIG (), VALUE_ORIG (),
plen)) plen))
return NULL; return NULL;
@ -578,6 +658,7 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
/* build the appropriate data structure for NetworkManager settings */ /* build the appropriate data structure for NetworkManager settings */
if (route) { if (route) {
result = build_route (info, result = build_route (info,
kf_key,
property_name, property_name,
ipv6 ? AF_INET6 : AF_INET, ipv6 ? AF_INET6 : AF_INET,
address_str, address_str,
@ -586,10 +667,11 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
metric_str); metric_str);
} else { } else {
result = build_address (info, result = build_address (info,
kf_key,
property_name,
ipv6 ? AF_INET6 : AF_INET, ipv6 ? AF_INET6 : AF_INET,
address_str, address_str,
plen, plen);
property_name);
if (!result) if (!result)
return NULL; return NULL;
if (gateway_str) if (gateway_str)
@ -905,6 +987,7 @@ ip_routing_rule_parser_full (KeyfileReaderInfo *info,
&local); &local);
if (!rule) { if (!rule) {
if (!handle_warn (info, if (!handle_warn (info,
build_list[i_build_list].s_key,
property_info->name, property_info->name,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid value for \"%s\": %s"), _("invalid value for \"%s\": %s"),
@ -944,6 +1027,7 @@ ip_dns_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
if (inet_pton (addr_family, list[i], &addr) <= 0) { if (inet_pton (addr_family, list[i], &addr) <= 0) {
if (!handle_warn (info, if (!handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid DNS server IPv%c address '%s'"), _("ignoring invalid DNS server IPv%c address '%s'"),
@ -978,6 +1062,7 @@ ip6_addr_gen_mode_parser (KeyfileReaderInfo *info, NMSetting *setting, const cha
if (!nm_utils_enum_from_str (nm_setting_ip6_config_addr_gen_mode_get_type (), s, if (!nm_utils_enum_from_str (nm_setting_ip6_config_addr_gen_mode_get_type (), s,
(int *) &addr_gen_mode, NULL)) { (int *) &addr_gen_mode, NULL)) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid option '%s', use one of [%s]"), _("invalid option '%s', use one of [%s]"),
@ -1033,6 +1118,7 @@ mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key
} }
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid MAC address")); _("ignoring invalid MAC address"));
@ -1291,6 +1377,7 @@ ssid_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
bytes = get_bytes (info, setting_name, key, FALSE, TRUE); bytes = get_bytes (info, setting_name, key, FALSE, TRUE);
if (!bytes) { if (!bytes) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid SSID")); _("ignoring invalid SSID"));
@ -1307,7 +1394,10 @@ password_raw_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *ke
bytes = get_bytes (info, setting_name, key, FALSE, TRUE); bytes = get_bytes (info, setting_name, key, FALSE, TRUE);
if (!bytes) { if (!bytes) {
handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, handle_warn (info,
key,
key,
NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid raw password")); _("ignoring invalid raw password"));
return; return;
} }
@ -1450,6 +1540,7 @@ cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
if (bin_len == 0) { if (bin_len == 0) {
if (!info->error) { if (!info->error) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid key/cert value")); _("invalid key/cert value"));
@ -1463,6 +1554,7 @@ cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
if (nm_setting_802_1x_check_cert_scheme (bin, bin_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_PATH) { if (nm_setting_802_1x_check_cert_scheme (bin, bin_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_PATH) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid key/cert value path \"%s\""), _("invalid key/cert value path \"%s\""),
@ -1486,6 +1578,7 @@ cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
* collect the file names to be checked and check them later). */ * collect the file names to be checked and check them later). */
if (!g_file_test (path2, G_FILE_TEST_EXISTS)) { if (!g_file_test (path2, G_FILE_TEST_EXISTS)) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE, NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE,
_("certificate or key file '%s' does not exist"), _("certificate or key file '%s' does not exist"),
@ -1497,6 +1590,7 @@ cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
if (HAS_SCHEME_PREFIX (bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_PKCS11)) { if (HAS_SCHEME_PREFIX (bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_PKCS11)) {
if (nm_setting_802_1x_check_cert_scheme (bin, bin_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_PKCS11) { if (nm_setting_802_1x_check_cert_scheme (bin, bin_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid PKCS#11 URI \"%s\""), _("invalid PKCS#11 URI \"%s\""),
@ -1544,6 +1638,7 @@ cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
if (bin_decoded_len == 0) { if (bin_decoded_len == 0) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid key/cert value data:;base64, is not base64")); _("invalid key/cert value data:;base64, is not base64"));
@ -1555,6 +1650,7 @@ cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
* In fact this is a limitation of NMSetting8021x which does not support setting blobs that start * In fact this is a limitation of NMSetting8021x which does not support setting blobs that start
* with file://. Just warn and return TRUE to signal that we ~handled~ the setting. */ * with file://. Just warn and return TRUE to signal that we ~handled~ the setting. */
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid key/cert value data:;base64,file://")); _("invalid key/cert value data:;base64,file://"));
@ -1578,6 +1674,7 @@ cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
/* Warn if the certificate didn't exist */ /* Warn if the certificate didn't exist */
if (!path_exists) { if (!path_exists) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE, NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE,
_("certificate or key file '%s' does not exist"), _("certificate or key file '%s' does not exist"),
@ -1592,6 +1689,7 @@ cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
* In fact, NMSetting8021x does not support setting such binary data, so just warn and * In fact, NMSetting8021x does not support setting such binary data, so just warn and
* continue. */ * continue. */
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid key/cert value is not a valid blob")); _("invalid key/cert value is not a valid blob"));
@ -1696,6 +1794,7 @@ parity_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
} }
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid parity value '%s'"), _("invalid parity value '%s'"),
@ -1713,6 +1812,7 @@ out_err:
return; return;
} }
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid setting: %s"), _("invalid setting: %s"),
@ -1733,6 +1833,7 @@ team_config_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key
if ( conf if ( conf
&& !nm_setting_verify (setting, NULL, &error)) { && !nm_setting_verify (setting, NULL, &error)) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid team configuration: %s"), _("ignoring invalid team configuration: %s"),
@ -1766,6 +1867,7 @@ bridge_vlan_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key
vlan = nm_bridge_vlan_from_str (*iter, &local); vlan = nm_bridge_vlan_from_str (*iter, &local);
if (!vlan) { if (!vlan) {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
"invalid bridge VLAN: %s", "invalid bridge VLAN: %s",
@ -1817,6 +1919,7 @@ qdisc_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
if (!qdisc) { if (!qdisc) {
handle_warn (info, handle_warn (info,
keys[i], keys[i],
key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid qdisc: %s"), _("invalid qdisc: %s"),
err->message); err->message);
@ -1865,6 +1968,7 @@ tfilter_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
if (!tfilter) { if (!tfilter) {
handle_warn (info, handle_warn (info,
keys[i], keys[i],
key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid tfilter: %s"), _("invalid tfilter: %s"),
err->message); err->message);
@ -2439,9 +2543,9 @@ static void
cert_writer_default (NMConnection *connection, cert_writer_default (NMConnection *connection,
GKeyFile *file, GKeyFile *file,
NMSetting8021x *setting, NMSetting8021x *setting,
const char *setting_name,
const NMSetting8021xSchemeVtable *vtable) const NMSetting8021xSchemeVtable *vtable)
{ {
const char *setting_name = nm_setting_get_name (NM_SETTING (setting));
NMSetting8021xCKScheme scheme; NMSetting8021xCKScheme scheme;
scheme = vtable->scheme_func (setting); scheme = vtable->scheme_func (setting);
@ -2515,7 +2619,7 @@ cert_writer (KeyfileWriterInfo *info,
const GValue *value) const GValue *value)
{ {
const NMSetting8021xSchemeVtable *vtable = NULL; const NMSetting8021xSchemeVtable *vtable = NULL;
NMKeyfileHandlerData handler_data; const char *setting_name;
guint i; guint i;
for (i = 0; nm_setting_8021x_scheme_vtable[i].setting_key; i++) { for (i = 0; nm_setting_8021x_scheme_vtable[i].setting_key; i++) {
@ -2527,12 +2631,19 @@ cert_writer (KeyfileWriterInfo *info,
if (!vtable) if (!vtable)
g_return_if_reached (); g_return_if_reached ();
setting_name = nm_setting_get_name (NM_SETTING (setting));
if (info->write_handler) { if (info->write_handler) {
_key_file_handler_data_init (&handler_data, NMKeyfileHandlerData handler_data;
NM_KEYFILE_HANDLER_TYPE_WRITE_CERT,
&info->error); _key_file_handler_data_init_write (&handler_data,
NM_KEYFILE_HANDLER_TYPE_WRITE_CERT,
info,
setting_name,
vtable->setting_key,
setting,
key);
handler_data.write_cert = (NMKeyfileHandlerDataWriteCert) { handler_data.write_cert = (NMKeyfileHandlerDataWriteCert) {
.setting = NM_SETTING_802_1X (setting),
.vtable = vtable, .vtable = vtable,
}; };
@ -2549,6 +2660,7 @@ cert_writer (KeyfileWriterInfo *info,
cert_writer_default (info->connection, cert_writer_default (info->connection,
info->keyfile, info->keyfile,
NM_SETTING_802_1X (setting), NM_SETTING_802_1X (setting),
setting_name,
vtable); vtable);
} }
@ -3108,6 +3220,7 @@ read_one_setting_value (KeyfileReaderInfo *info,
/* Key doesn't exist or an error occurred, thus nothing to do. */ /* Key doesn't exist or an error occurred, thus nothing to do. */
if (err) { if (err) {
if (!handle_warn (info, if (!handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("error loading setting value: %s"), _("error loading setting value: %s"),
@ -3211,6 +3324,7 @@ read_one_setting_value (KeyfileReaderInfo *info,
if (val > 255u) { if (val > 255u) {
if ( !already_warned if ( !already_warned
&& !handle_warn (info, && !handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid byte element '%u' (not between 0 and 255 inclusive)"), _("ignoring invalid byte element '%u' (not between 0 and 255 inclusive)"),
@ -3263,6 +3377,7 @@ read_one_setting_value (KeyfileReaderInfo *info,
/* ignore such errors. The key is not present. */ /* ignore such errors. The key is not present. */
} else { } else {
handle_warn (info, handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid setting: %s"), _("invalid setting: %s"),
@ -3287,6 +3402,7 @@ _read_setting (KeyfileReaderInfo *info)
type = nm_setting_lookup_type (alias); type = nm_setting_lookup_type (alias);
if (!type) { if (!type) {
handle_warn (info, handle_warn (info,
NULL,
NULL, NULL,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid setting name '%s'"), _("invalid setting name '%s'"),
@ -3336,6 +3452,7 @@ _read_setting (KeyfileReaderInfo *info)
if (!variant_type) { if (!variant_type) {
if (!handle_warn (info, if (!handle_warn (info,
key, key,
NULL,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid key '%s.%s'"), _("invalid key '%s.%s'"),
info->group, info->group,
@ -3353,6 +3470,7 @@ _read_setting (KeyfileReaderInfo *info)
&local); &local);
if (local) { if (local) {
if (!handle_warn (info, if (!handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("key '%s.%s' is not boolean"), _("key '%s.%s' is not boolean"),
@ -3372,6 +3490,7 @@ _read_setting (KeyfileReaderInfo *info)
if (local) { if (local) {
if (!handle_warn (info, if (!handle_warn (info,
key,
key, key,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("key '%s.%s' is not a uint32"), _("key '%s.%s' is not a uint32"),
@ -3433,6 +3552,7 @@ _read_setting_wireguard_peer (KeyfileReaderInfo *info)
* is uniquely identified. */ * is uniquely identified. */
handle_warn (info, handle_warn (info,
NULL, NULL,
NM_SETTING_WIREGUARD_PEERS,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid peer public key in section '%s'"), _("invalid peer public key in section '%s'"),
info->group); info->group);
@ -3447,6 +3567,7 @@ _read_setting_wireguard_peer (KeyfileReaderInfo *info)
if (!nm_wireguard_peer_set_preshared_key (peer, str, FALSE)) { if (!nm_wireguard_peer_set_preshared_key (peer, str, FALSE)) {
if (!handle_warn (info, if (!handle_warn (info,
key, key,
NM_SETTING_WIREGUARD_PEERS,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("key '%s.%s' is not a valid 256 bit key in base64 encoding"), _("key '%s.%s' is not a valid 256 bit key in base64 encoding"),
info->group, info->group,
@ -3463,6 +3584,7 @@ _read_setting_wireguard_peer (KeyfileReaderInfo *info)
|| !_nm_setting_secret_flags_valid (i64)) { || !_nm_setting_secret_flags_valid (i64)) {
if (!handle_warn (info, if (!handle_warn (info,
key, key,
NM_SETTING_WIREGUARD_PEERS,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("key '%s.%s' is not a valid secret flag"), _("key '%s.%s' is not a valid secret flag"),
info->group, info->group,
@ -3478,6 +3600,7 @@ _read_setting_wireguard_peer (KeyfileReaderInfo *info)
if (i64 == -1) { if (i64 == -1) {
if (!handle_warn (info, if (!handle_warn (info,
key, key,
NM_SETTING_WIREGUARD_PEERS,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("key '%s.%s' is not a integer in range 0 to 2^32"), _("key '%s.%s' is not a integer in range 0 to 2^32"),
info->group, info->group,
@ -3493,6 +3616,7 @@ _read_setting_wireguard_peer (KeyfileReaderInfo *info)
if (!nm_wireguard_peer_set_endpoint (peer, str, FALSE)) { if (!nm_wireguard_peer_set_endpoint (peer, str, FALSE)) {
if (!handle_warn (info, if (!handle_warn (info,
key, key,
NM_SETTING_WIREGUARD_PEERS,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("key '%s.%s' is not a valid endpoint"), _("key '%s.%s' is not a valid endpoint"),
info->group, info->group,
@ -3518,6 +3642,7 @@ _read_setting_wireguard_peer (KeyfileReaderInfo *info)
if (has_error) { if (has_error) {
if (!handle_warn (info, if (!handle_warn (info,
key, key,
NM_SETTING_WIREGUARD_PEERS,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("key '%s.%s' has invalid allowed-ips"), _("key '%s.%s' has invalid allowed-ips"),
info->group, info->group,
@ -3531,7 +3656,8 @@ _read_setting_wireguard_peer (KeyfileReaderInfo *info)
if (!nm_wireguard_peer_is_valid (peer, TRUE, TRUE, &error)) { if (!nm_wireguard_peer_is_valid (peer, TRUE, TRUE, &error)) {
handle_warn (info, handle_warn (info,
key, NULL,
NM_SETTING_WIREGUARD_PEERS,
NM_KEYFILE_WARN_SEVERITY_WARN, NM_KEYFILE_WARN_SEVERITY_WARN,
_("peer '%s' is invalid: %s"), _("peer '%s' is invalid: %s"),
info->group, info->group,

View file

@ -43,23 +43,23 @@ _fmt_warn (const char *group, NMSetting *setting, const char *property_name, con
typedef struct { typedef struct {
bool verbose; bool verbose;
} HandlerReadData; } ReadInfo;
static gboolean static gboolean
_handler_read (GKeyFile *keyfile, _handler_read (GKeyFile *keyfile,
NMConnection *connection, NMConnection *connection,
NMKeyfileHandlerType type, NMKeyfileHandlerType handler_type,
NMKeyfileHandlerData *type_data, NMKeyfileHandlerData *handler_data,
void *user_data) void *user_data)
{ {
const HandlerReadData *handler_data = user_data; const ReadInfo *read_info = user_data;
if (type == NM_KEYFILE_HANDLER_TYPE_WARN) { if (handler_type == NM_KEYFILE_HANDLER_TYPE_WARN) {
const NMKeyfileHandlerDataWarn *warn_data = &type_data->warn; const NMKeyfileHandlerDataWarn *warn_data = &handler_data->warn;
NMLogLevel level; NMLogLevel level;
char *message_free = NULL; char *message_free = NULL;
if (!handler_data->verbose) if (!read_info->verbose)
return TRUE; return TRUE;
if (warn_data->severity > NM_KEYFILE_WARN_SEVERITY_WARN) if (warn_data->severity > NM_KEYFILE_WARN_SEVERITY_WARN)
@ -71,11 +71,15 @@ _handler_read (GKeyFile *keyfile,
else else
level = LOGL_INFO; level = LOGL_INFO;
nm_log (level, LOGD_SETTINGS, NULL, nm_log (level,
LOGD_SETTINGS,
NULL,
nm_connection_get_uuid (connection), nm_connection_get_uuid (connection),
"keyfile: %s", "keyfile: %s",
_fmt_warn (warn_data->group, warn_data->setting, _fmt_warn (handler_data->kf_group_name,
warn_data->property_name, warn_data->message, handler_data->cur_setting,
handler_data->cur_property,
warn_data->message,
&message_free)); &message_free));
g_free (message_free); g_free (message_free);
return TRUE; return TRUE;
@ -93,7 +97,7 @@ nms_keyfile_reader_from_keyfile (GKeyFile *key_file,
GError **error) GError **error)
{ {
NMConnection *connection; NMConnection *connection;
HandlerReadData data = { ReadInfo read_info = {
.verbose = verbose, .verbose = verbose,
}; };
gs_free char *base_dir_free = NULL; gs_free char *base_dir_free = NULL;
@ -122,7 +126,7 @@ nms_keyfile_reader_from_keyfile (GKeyFile *key_file,
filename = &s[1]; filename = &s[1];
} }
connection = nm_keyfile_read (key_file, base_dir, _handler_read, &data, error); connection = nm_keyfile_read (key_file, base_dir, _handler_read, &read_info, error);
if (!connection) if (!connection)
return NULL; return NULL;

View file

@ -28,21 +28,22 @@ typedef struct {
static void static void
cert_writer (NMConnection *connection, cert_writer (NMConnection *connection,
GKeyFile *file, GKeyFile *file,
NMKeyfileHandlerDataWriteCert *cert_data, NMSetting8021x *setting,
const NMSetting8021xSchemeVtable *vtable,
WriteInfo *info, WriteInfo *info,
GError **error) GError **error)
{ {
const char *setting_name = nm_setting_get_name (NM_SETTING (cert_data->setting)); const char *setting_name = nm_setting_get_name (NM_SETTING (setting));
NMSetting8021xCKScheme scheme; NMSetting8021xCKScheme scheme;
NMSetting8021xCKFormat format; NMSetting8021xCKFormat format;
const char *path = NULL, *ext = "pem"; const char *path = NULL, *ext = "pem";
scheme = cert_data->vtable->scheme_func (cert_data->setting); scheme = vtable->scheme_func (setting);
if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
char *tmp = NULL; char *tmp = NULL;
const char *accepted_path = NULL; const char *accepted_path = NULL;
path = cert_data->vtable->path_func (cert_data->setting); path = vtable->path_func (setting);
g_assert (path); g_assert (path);
if (g_str_has_prefix (path, info->keyfile_dir)) { if (g_str_has_prefix (path, info->keyfile_dir)) {
@ -78,11 +79,11 @@ cert_writer (NMConnection *connection,
if (!accepted_path) if (!accepted_path)
accepted_path = tmp = g_strconcat (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL); accepted_path = tmp = g_strconcat (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL);
nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, accepted_path); nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, accepted_path);
g_free (tmp); g_free (tmp);
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key,
cert_data->vtable->uri_func (cert_data->setting)); vtable->uri_func (setting));
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
GBytes *blob; GBytes *blob;
const guint8 *blob_data; const guint8 *blob_data;
@ -91,13 +92,13 @@ cert_writer (NMConnection *connection,
GError *local = NULL; GError *local = NULL;
char *new_path; char *new_path;
blob = cert_data->vtable->blob_func (cert_data->setting); blob = vtable->blob_func (setting);
g_assert (blob); g_assert (blob);
blob_data = g_bytes_get_data (blob, &blob_len); blob_data = g_bytes_get_data (blob, &blob_len);
if (cert_data->vtable->format_func) { if (vtable->format_func) {
/* Get the extension for a private key */ /* Get the extension for a private key */
format = cert_data->vtable->format_func (cert_data->setting); format = vtable->format_func (setting);
if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
ext = "p12"; ext = "p12";
} else { } else {
@ -110,7 +111,7 @@ cert_writer (NMConnection *connection,
* from now on instead of pushing around the certificate data. * from now on instead of pushing around the certificate data.
*/ */
new_path = g_strdup_printf ("%s/%s-%s.%s", info->keyfile_dir, nm_connection_get_uuid (connection), new_path = g_strdup_printf ("%s/%s-%s.%s", info->keyfile_dir, nm_connection_get_uuid (connection),
cert_data->vtable->file_suffix, ext); vtable->file_suffix, ext);
/* FIXME(keyfile-parse-in-memory): writer must not access/write to the file system before /* FIXME(keyfile-parse-in-memory): writer must not access/write to the file system before
* being sure that the entire profile can be written and all circumstances are good to * being sure that the entire profile can be written and all circumstances are good to
@ -125,10 +126,10 @@ cert_writer (NMConnection *connection,
if (success) { if (success) {
/* Write the path value to the keyfile. /* Write the path value to the keyfile.
* We know, that basename(new_path) starts with a UUID, hence no conflict with "data:;base64," */ * We know, that basename(new_path) starts with a UUID, hence no conflict with "data:;base64," */
nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, strrchr (new_path, '/') + 1); nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, strrchr (new_path, '/') + 1);
} else { } else {
nm_log_warn (LOGD_SETTINGS, "keyfile: %s.%s: failed to write certificate to file %s: %s", nm_log_warn (LOGD_SETTINGS, "keyfile: %s.%s: failed to write certificate to file %s: %s",
setting_name, cert_data->vtable->setting_key, new_path, local->message); setting_name, vtable->setting_key, new_path, local->message);
g_error_free (local); g_error_free (local);
} }
g_free (new_path); g_free (new_path);
@ -151,8 +152,10 @@ _handler_write (NMConnection *connection,
void *user_data) void *user_data)
{ {
if (type == NM_KEYFILE_HANDLER_TYPE_WRITE_CERT) { if (type == NM_KEYFILE_HANDLER_TYPE_WRITE_CERT) {
cert_writer (connection, keyfile, cert_writer (connection,
&type_data->write_cert, keyfile,
NM_SETTING_802_1X (type_data->cur_setting),
type_data->write_cert.vtable,
user_data, user_data,
type_data->p_error); type_data->p_error);
return TRUE; return TRUE;