keyfile: add NMKeyfileHandlerData typedef for arguments of keyfile callbacks

As the keyfile handler callback will become public API, it needs to be
usable via bindings. A plain void pointer is not usable. Instead, add
a new type that can be used via introspection.
This commit is contained in:
Thomas Haller 2020-05-23 17:45:50 +02:00
parent 18c1fe6ed8
commit 0bfdb26973
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
4 changed files with 88 additions and 64 deletions

View file

@ -36,6 +36,8 @@ typedef enum {
NM_KEYFILE_HANDLER_TYPE_WRITE_CERT = 2,
} NMKeyfileHandlerType;
typedef struct _NMKeyfileHandlerData NMKeyfileHandlerData;
/**
* NMKeyfileReadHandler:
*
@ -43,13 +45,13 @@ typedef enum {
* @error.
*
* Returns: should return TRUE, if the reading was handled. Otherwise,
* a default action will be performed that depends on the @type.
* For %NM_KEYFILE_HANDLER_TYPE_WARN type, the default action is doing nothing.
* a default action will be performed that depends on the @handler_type.
* For %NM_KEYFILE_HANDLER_TYPE_WARN handler_type, the default action is doing nothing.
*/
typedef gboolean (*NMKeyfileReadHandler) (GKeyFile *keyfile,
NMConnection *connection,
NMKeyfileHandlerType type,
void *type_data,
NMKeyfileHandlerType handler_type,
NMKeyfileHandlerData *handler_data,
void *user_data,
GError **error);
@ -60,26 +62,6 @@ typedef enum {
NM_KEYFILE_WARN_SEVERITY_WARN = 3000,
} NMKeyfileWarnSeverity;
/**
* NMKeyfileReadTypeDataWarn:
*
* this struct is passed as @type_data for the @NMKeyfileReadHandler of
* type %NM_KEYFILE_HANDLER_TYPE_WARN.
*/
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;
const char *message;
} NMKeyfileReadTypeDataWarn;
NMConnection *nm_keyfile_read (GKeyFile *keyfile,
const char *base_dir,
NMKeyfileReadHandler handler,
@ -100,11 +82,11 @@ gboolean nm_keyfile_read_ensure_uuid (NMConnection *connection,
* This is a hook to tweak the serialization.
*
* Handler for certain properties or events that are not entirely contained
* within the keyfile or that might be serialized differently. The @type and
* @type_data arguments tell which kind of argument we have at hand.
* within the keyfile or that might be serialized differently. The @handler_type and
* @handler_data arguments tell which kind of argument we have at hand.
*
* Currently only the type %NM_KEYFILE_HANDLER_TYPE_WRITE_CERT is supported, which provides
* @type_data as %NMKeyfileWriteTypeDataCert. However, this handler should be generic enough
* Currently only the handler_type %NM_KEYFILE_HANDLER_TYPE_WRITE_CERT is supported, which provides
* @handler_data as %NMKeyfileHandlerDataWriteCert. However, this handler should be generic enough
* to support other types as well.
*
* This don't have to be only "properties". For example, nm_keyfile_read() uses
@ -119,22 +101,11 @@ gboolean nm_keyfile_read_ensure_uuid (NMConnection *connection,
*/
typedef gboolean (*NMKeyfileWriteHandler) (NMConnection *connection,
GKeyFile *keyfile,
NMKeyfileHandlerType type,
void *type_data,
NMKeyfileHandlerType handler_type,
NMKeyfileHandlerData *handler_data,
void *user_data,
GError **error);
/**
* NMKeyfileWriteTypeDataCert:
*
* this struct is passed as @type_data for the @NMKeyfileWriteHandler of
* type %NM_KEYFILE_HANDLER_TYPE_WRITE_CERT.
*/
typedef struct {
const NMSetting8021xSchemeVtable *vtable;
NMSetting8021x *setting;
} NMKeyfileWriteTypeDataCert;
GKeyFile *nm_keyfile_write (NMConnection *connection,
NMKeyfileWriteHandler handler,
void *user_data,
@ -142,6 +113,47 @@ GKeyFile *nm_keyfile_write (NMConnection *connection,
/*****************************************************************************/
/**
* NMKeyfileHandlerDataWarn:
*
* this struct is passed as @handler_data for the @NMKeyfileReadHandler of
* handler_type %NM_KEYFILE_HANDLER_TYPE_WARN.
*/
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;
const char *message;
} NMKeyfileHandlerDataWarn;
/**
* NMKeyfileHandlerDataWriteCert:
*
* this struct is passed as @handler_data for the @NMKeyfileWriteHandler of
* handler_type %NM_KEYFILE_HANDLER_TYPE_WRITE_CERT.
*/
typedef struct {
const NMSetting8021xSchemeVtable *vtable;
NMSetting8021x *setting;
} NMKeyfileHandlerDataWriteCert;
struct _NMKeyfileHandlerData {
NMKeyfileHandlerType type;
union {
NMKeyfileHandlerDataWarn warn;
NMKeyfileHandlerDataWriteCert write_cert;
};
};
/*****************************************************************************/
char *nm_keyfile_plugin_kf_get_string (GKeyFile *kf, const char *group, const char *key, GError **error);
void nm_keyfile_plugin_kf_set_string (GKeyFile *kf, const char *group, const char *key, const char *value);

View file

@ -55,7 +55,10 @@ _handle_warn (KeyfileReaderInfo *info,
NMKeyfileWarnSeverity severity,
char *message)
{
NMKeyfileReadTypeDataWarn type_data = {
NMKeyfileHandlerData type_data;
type_data.type = NM_KEYFILE_HANDLER_TYPE_WARN;
type_data.warn = (NMKeyfileHandlerDataWarn) {
.group = info->group,
.setting = info->setting,
.property_name = property_name,
@ -2340,19 +2343,20 @@ password_raw_writer (KeyfileWriterInfo *info,
static void
cert_writer_default (NMConnection *connection,
GKeyFile *file,
NMKeyfileWriteTypeDataCert *cert_data)
NMSetting8021x *setting,
const NMSetting8021xSchemeVtable *vtable)
{
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;
scheme = cert_data->vtable->scheme_func (cert_data->setting);
scheme = vtable->scheme_func (setting);
if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
gs_free char *path_free = NULL;
gs_free char *base_dir = NULL;
gs_free char *tmp = NULL;
const char *path;
path = cert_data->vtable->path_func (cert_data->setting);
path = vtable->path_func (setting);
g_assert (path);
/* If the path is relative, make it an absolute path.
@ -2379,7 +2383,7 @@ cert_writer_default (NMConnection *connection,
/* Path contains at least a '/', hence it cannot be recognized as the old
* binary format consisting of a list of integers. */
nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, path);
nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, path);
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
GBytes *blob;
const guint8 *blob_data;
@ -2387,17 +2391,17 @@ cert_writer_default (NMConnection *connection,
gs_free char *blob_base64 = NULL;
gs_free char *val = NULL;
blob = cert_data->vtable->blob_func (cert_data->setting);
blob = vtable->blob_func (setting);
g_assert (blob);
blob_data = g_bytes_get_data (blob, &blob_len);
blob_base64 = g_base64_encode (blob_data, blob_len);
val = g_strconcat (NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB, blob_base64, NULL);
nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, val);
nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, val);
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key,
cert_data->vtable->uri_func (cert_data->setting));
nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key,
vtable->uri_func (setting));
} else {
/* scheme_func() returns UNKNOWN in all other cases. The only valid case
* where a scheme is allowed to be UNKNOWN, is unsetting the value. In this
@ -2415,21 +2419,24 @@ cert_writer (KeyfileWriterInfo *info,
const char *key,
const GValue *value)
{
const NMSetting8021xSchemeVtable *objtype = NULL;
const NMSetting8021xSchemeVtable *vtable = NULL;
NMKeyfileHandlerData type_data;
guint i;
NMKeyfileWriteTypeDataCert type_data = { 0 };
for (i = 0; nm_setting_8021x_scheme_vtable[i].setting_key; i++) {
if (nm_streq0 (nm_setting_8021x_scheme_vtable[i].setting_key, key)) {
objtype = &nm_setting_8021x_scheme_vtable[i];
vtable = &nm_setting_8021x_scheme_vtable[i];
break;
}
}
if (!objtype)
if (!vtable)
g_return_if_reached ();
type_data.setting = NM_SETTING_802_1X (setting);
type_data.vtable = objtype;
type_data.type = NM_KEYFILE_HANDLER_TYPE_WRITE_CERT;
type_data.write_cert = (NMKeyfileHandlerDataWriteCert) {
.setting = NM_SETTING_802_1X (setting),
.vtable = vtable,
};
if (info->handler) {
if (info->handler (info->connection,
@ -2443,7 +2450,10 @@ cert_writer (KeyfileWriterInfo *info,
return;
}
cert_writer_default (info->connection, info->keyfile, &type_data);
cert_writer_default (info->connection,
info->keyfile,
NM_SETTING_802_1X (setting),
vtable);
}
/*****************************************************************************/

View file

@ -49,14 +49,14 @@ static gboolean
_handler_read (GKeyFile *keyfile,
NMConnection *connection,
NMKeyfileHandlerType type,
void *type_data,
NMKeyfileHandlerData *type_data,
void *user_data,
GError **error)
{
const HandlerReadData *handler_data = user_data;
if (type == NM_KEYFILE_HANDLER_TYPE_WARN) {
NMKeyfileReadTypeDataWarn *warn_data = type_data;
const NMKeyfileHandlerDataWarn *warn_data = &type_data->warn;
NMLogLevel level;
char *message_free = NULL;
@ -81,6 +81,7 @@ _handler_read (GKeyFile *keyfile,
g_free (message_free);
return TRUE;
}
return FALSE;
}

View file

@ -28,7 +28,7 @@ typedef struct {
static void
cert_writer (NMConnection *connection,
GKeyFile *file,
NMKeyfileWriteTypeDataCert *cert_data,
NMKeyfileHandlerDataWriteCert *cert_data,
WriteInfo *info,
GError **error)
{
@ -147,14 +147,15 @@ static gboolean
_handler_write (NMConnection *connection,
GKeyFile *keyfile,
NMKeyfileHandlerType type,
void *type_data,
NMKeyfileHandlerData *type_data,
void *user_data,
GError **error)
{
if (type == NM_KEYFILE_HANDLER_TYPE_WRITE_CERT) {
cert_writer (connection, keyfile,
(NMKeyfileWriteTypeDataCert *) type_data,
(WriteInfo *) user_data, error);
&type_data->write_cert,
user_data,
error);
return TRUE;
}
return FALSE;