about summary refs log tree commit diff
path: root/src/settings/plugins/keyfile/nms-keyfile-writer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/plugins/keyfile/nms-keyfile-writer.c')
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-writer.c481
1 files changed, 0 insertions, 481 deletions
diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.c b/src/settings/plugins/keyfile/nms-keyfile-writer.c
deleted file mode 100644
index 4b13cef4..00000000
--- a/src/settings/plugins/keyfile/nms-keyfile-writer.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 - 2015 Red Hat, Inc.
- */
-
-#include "nm-default.h"
-
-#include "nms-keyfile-writer.h"
-
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "nm-keyfile/nm-keyfile-internal.h"
-
-#include "nms-keyfile-utils.h"
-#include "nms-keyfile-reader.h"
-
-#include "nm-glib-aux/nm-io-utils.h"
-
-/*****************************************************************************/
-
-typedef struct {
-    const char *keyfile_dir;
-} WriteInfo;
-
-static void
-cert_writer(NMConnection *                    connection,
-            GKeyFile *                        file,
-            NMSetting8021x *                  setting,
-            const NMSetting8021xSchemeVtable *vtable,
-            WriteInfo *                       info,
-            GError **                         error)
-{
-    const char *           setting_name = nm_setting_get_name(NM_SETTING(setting));
-    NMSetting8021xCKScheme scheme;
-    NMSetting8021xCKFormat format;
-    const char *           path = NULL, *ext = "pem";
-
-    scheme = vtable->scheme_func(setting);
-    if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
-        char *      tmp           = NULL;
-        const char *accepted_path = NULL;
-
-        path = vtable->path_func(setting);
-        g_assert(path);
-
-        if (g_str_has_prefix(path, info->keyfile_dir)) {
-            const char *p = path + strlen(info->keyfile_dir);
-
-            /* If the path is rooted in the keyfile directory, just use a
-             * relative path instead of an absolute one.
-             */
-            if (*p == '/') {
-                while (*p == '/')
-                    p++;
-                if (p[0]) {
-                    /* If @p looks like an integer list, the following detection will fail too and
-                     * we will file:// qualify the path below. We thus avoid writing a path string
-                     * that would be interpreted as legacy binary format by reader. */
-                    tmp = nm_keyfile_detect_unqualified_path_scheme(info->keyfile_dir,
-                                                                    p,
-                                                                    -1,
-                                                                    FALSE,
-                                                                    NULL);
-                    if (tmp) {
-                        nm_clear_g_free(&tmp);
-                        accepted_path = p;
-                    }
-                }
-            }
-        }
-        if (!accepted_path) {
-            /* What we are about to write, must also be understood by the reader.
-             * Otherwise, add a file:// prefix */
-            tmp =
-                nm_keyfile_detect_unqualified_path_scheme(info->keyfile_dir, path, -1, FALSE, NULL);
-            if (tmp) {
-                nm_clear_g_free(&tmp);
-                accepted_path = path;
-            }
-        }
-
-        if (!accepted_path)
-            accepted_path = tmp = g_strconcat(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL);
-        nm_keyfile_plugin_kf_set_string(file, setting_name, vtable->setting_key, accepted_path);
-        g_free(tmp);
-    } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
-        nm_keyfile_plugin_kf_set_string(file,
-                                        setting_name,
-                                        vtable->setting_key,
-                                        vtable->uri_func(setting));
-    } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
-        GBytes *      blob;
-        const guint8 *blob_data;
-        gsize         blob_len;
-        gboolean      success;
-        GError *      local = NULL;
-        char *        new_path;
-
-        blob = vtable->blob_func(setting);
-        g_assert(blob);
-        blob_data = g_bytes_get_data(blob, &blob_len);
-
-        if (vtable->format_func) {
-            /* Get the extension for a private key */
-            format = vtable->format_func(setting);
-            if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
-                ext = "p12";
-        } else {
-            /* DER or PEM format certificate? */
-            if (blob_len > 2 && blob_data[0] == 0x30 && blob_data[1] == 0x82)
-                ext = "der";
-        }
-
-        /* Write the raw data out to the standard file so that we can use paths
-         * 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),
-                                   vtable->file_suffix,
-                                   ext);
-
-        /* 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
-         * proceed. That means, while writing we must only collect the blogs in-memory, and write
-         * them all in the end together (or not at all). */
-        success = nm_utils_file_set_contents(new_path,
-                                             (const char *) blob_data,
-                                             blob_len,
-                                             0600,
-                                             NULL,
-                                             &local);
-        if (success) {
-            /* Write the path value to the keyfile.
-             * 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,
-                                            vtable->setting_key,
-                                            strrchr(new_path, '/') + 1);
-        } else {
-            nm_log_warn(LOGD_SETTINGS,
-                        "keyfile: %s.%s: failed to write certificate to file %s: %s",
-                        setting_name,
-                        vtable->setting_key,
-                        new_path,
-                        local->message);
-            g_error_free(local);
-        }
-        g_free(new_path);
-    } 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
-         * case, we don't expect the writer to be called, because the default value
-         * will not be serialized.
-         * The only other reason for the scheme to be UNKNOWN is an invalid cert.
-         * But our connection verifies, so that cannot happen either. */
-        g_return_if_reached();
-    }
-}
-
-static gboolean
-_handler_write(NMConnection *        connection,
-               GKeyFile *            keyfile,
-               NMKeyfileHandlerType  type,
-               NMKeyfileHandlerData *type_data,
-               void *                user_data)
-{
-    if (type == NM_KEYFILE_HANDLER_TYPE_WRITE_CERT) {
-        cert_writer(connection,
-                    keyfile,
-                    NM_SETTING_802_1X(type_data->cur_setting),
-                    type_data->write_cert.vtable,
-                    user_data,
-                    type_data->p_error);
-        return TRUE;
-    }
-    return FALSE;
-}
-
-static gboolean
-_internal_write_connection(NMConnection *                  connection,
-                           gboolean                        is_nm_generated,
-                           gboolean                        is_volatile,
-                           gboolean                        is_external,
-                           const char *                    shadowed_storage,
-                           gboolean                        shadowed_owned,
-                           const char *                    keyfile_dir,
-                           const char *                    profile_dir,
-                           gboolean                        with_extension,
-                           uid_t                           owner_uid,
-                           pid_t                           owner_grp,
-                           const char *                    existing_path,
-                           gboolean                        existing_path_read_only,
-                           gboolean                        force_rename,
-                           NMSKeyfileWriterAllowFilenameCb allow_filename_cb,
-                           gpointer                        allow_filename_user_data,
-                           char **                         out_path,
-                           NMConnection **                 out_reread,
-                           gboolean *                      out_reread_same,
-                           GError **                       error)
-{
-    nm_auto_unref_keyfile GKeyFile *kf_file        = NULL;
-    gs_free char *                  kf_content_buf = NULL;
-    gsize                           kf_content_len;
-    gs_free char *                  path = NULL;
-    const char *                    id;
-    WriteInfo                       info = {0};
-    gs_free_error GError *local_err      = NULL;
-    int                   errsv;
-    gboolean              rename;
-    int                   i_path;
-    gs_unref_object NMConnection *reread      = NULL;
-    gboolean                      reread_same = FALSE;
-
-    g_return_val_if_fail(!out_path || !*out_path, FALSE);
-    g_return_val_if_fail(keyfile_dir && keyfile_dir[0] == '/', FALSE);
-
-    nm_assert(_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS);
-
-    nm_assert(!shadowed_owned || shadowed_storage);
-
-    rename = force_rename || existing_path_read_only
-             || (existing_path && !nm_utils_file_is_in_path(existing_path, keyfile_dir));
-
-    id = nm_connection_get_id(connection);
-    nm_assert(id && *id);
-
-    info.keyfile_dir = keyfile_dir;
-
-    kf_file =
-        nm_keyfile_write(connection, NM_KEYFILE_HANDLER_FLAGS_NONE, _handler_write, &info, error);
-    if (!kf_file)
-        return FALSE;
-
-    if (is_nm_generated) {
-        g_key_file_set_boolean(kf_file,
-                               NM_KEYFILE_GROUP_NMMETA,
-                               NM_KEYFILE_KEY_NMMETA_NM_GENERATED,
-                               TRUE);
-    }
-
-    if (is_volatile) {
-        g_key_file_set_boolean(kf_file,
-                               NM_KEYFILE_GROUP_NMMETA,
-                               NM_KEYFILE_KEY_NMMETA_VOLATILE,
-                               TRUE);
-    }
-
-    if (is_external) {
-        g_key_file_set_boolean(kf_file,
-                               NM_KEYFILE_GROUP_NMMETA,
-                               NM_KEYFILE_KEY_NMMETA_EXTERNAL,
-                               TRUE);
-    }
-
-    if (shadowed_storage) {
-        g_key_file_set_string(kf_file,
-                              NM_KEYFILE_GROUP_NMMETA,
-                              NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE,
-                              shadowed_storage);
-    }
-
-    if (shadowed_owned) {
-        g_key_file_set_boolean(kf_file,
-                               NM_KEYFILE_GROUP_NMMETA,
-                               NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED,
-                               TRUE);
-    }
-
-    kf_content_buf = g_key_file_to_data(kf_file, &kf_content_len, error);
-    if (!kf_content_buf)
-        return FALSE;
-
-    if (!g_file_test(keyfile_dir, G_FILE_TEST_IS_DIR))
-        (void) g_mkdir_with_parents(keyfile_dir, 0755);
-
-    for (i_path = -2; i_path < 10000; i_path++) {
-        gs_free char *path_candidate = NULL;
-        gboolean      is_existing_path;
-
-        if (i_path == -2) {
-            if (!existing_path || rename)
-                continue;
-            path_candidate = g_strdup(existing_path);
-        } else if (i_path == -1) {
-            gs_free char *filename_escaped = NULL;
-
-            filename_escaped = nm_keyfile_utils_create_filename(id, with_extension);
-            path_candidate   = g_build_filename(keyfile_dir, filename_escaped, NULL);
-        } else {
-            gs_free char *filename_escaped = NULL;
-            gs_free char *filename         = NULL;
-
-            if (i_path == 0)
-                filename = g_strdup_printf("%s-%s", id, nm_connection_get_uuid(connection));
-            else
-                filename =
-                    g_strdup_printf("%s-%s-%d", id, nm_connection_get_uuid(connection), i_path);
-
-            filename_escaped = nm_keyfile_utils_create_filename(filename, with_extension);
-
-            path_candidate = g_strdup_printf("%s/%s", keyfile_dir, filename_escaped);
-        }
-
-        is_existing_path = existing_path && nm_streq(existing_path, path_candidate);
-
-        if (is_existing_path && rename)
-            continue;
-
-        if (allow_filename_cb && !allow_filename_cb(path_candidate, allow_filename_user_data))
-            continue;
-
-        if (!is_existing_path) {
-            if (g_file_test(path_candidate, G_FILE_TEST_EXISTS))
-                continue;
-        }
-
-        path = g_steal_pointer(&path_candidate);
-        break;
-    }
-
-    if (!path) {
-        /* this really should not happen, we tried hard to find an unused name... bail out. */
-        g_set_error(error,
-                    NM_SETTINGS_ERROR,
-                    NM_SETTINGS_ERROR_FAILED,
-                    "could not find suitable keyfile file name (%s already used)",
-                    path);
-        return FALSE;
-    }
-
-    if (out_reread || out_reread_same) {
-        gs_free_error GError *reread_error = NULL;
-
-        reread =
-            nms_keyfile_reader_from_keyfile(kf_file, path, NULL, profile_dir, FALSE, &reread_error);
-
-        if (!reread || !nm_connection_normalize(reread, NULL, NULL, &reread_error)) {
-            nm_log_err(
-                LOGD_SETTINGS,
-                "BUG: the profile cannot be stored in keyfile format without becoming unusable: %s",
-                reread_error->message);
-            g_set_error(error,
-                        NM_SETTINGS_ERROR,
-                        NM_SETTINGS_ERROR_FAILED,
-                        "keyfile writer produces an invalid connection: %s",
-                        reread_error->message);
-            nm_assert_not_reached();
-            return FALSE;
-        }
-
-        if (out_reread_same) {
-            reread_same =
-                !!nm_connection_compare(reread, connection, NM_SETTING_COMPARE_FLAG_EXACT);
-
-            nm_assert(reread_same
-                      == nm_connection_compare(connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
-            nm_assert(reread_same == ({
-                          gs_unref_hashtable GHashTable *_settings = NULL;
-
-                          (nm_connection_diff(reread,
-                                              connection,
-                                              NM_SETTING_COMPARE_FLAG_EXACT,
-                                              &_settings)
-                           && !_settings);
-                      }));
-        }
-    }
-
-    nm_utils_file_set_contents(path, kf_content_buf, kf_content_len, 0600, NULL, &local_err);
-    if (local_err) {
-        g_set_error(error,
-                    NM_SETTINGS_ERROR,
-                    NM_SETTINGS_ERROR_FAILED,
-                    "error writing to file '%s': %s",
-                    path,
-                    local_err->message);
-        return FALSE;
-    }
-
-    if (chown(path, owner_uid, owner_grp) < 0) {
-        errsv = errno;
-        g_set_error(error,
-                    NM_SETTINGS_ERROR,
-                    NM_SETTINGS_ERROR_FAILED,
-                    "error chowning '%s': %s (%d)",
-                    path,
-                    nm_strerror_native(errsv),
-                    errsv);
-        unlink(path);
-        return FALSE;
-    }
-
-    /* In case of updating the connection and changing the file path,
-     * we need to remove the old one, not to end up with two connections.
-     */
-    if (existing_path && !existing_path_read_only && !nm_streq(path, existing_path))
-        unlink(existing_path);
-
-    NM_SET_OUT(out_reread, g_steal_pointer(&reread));
-    NM_SET_OUT(out_reread_same, reread_same);
-    NM_SET_OUT(out_path, g_steal_pointer(&path));
-
-    return TRUE;
-}
-
-gboolean
-nms_keyfile_writer_connection(NMConnection *                  connection,
-                              gboolean                        is_nm_generated,
-                              gboolean                        is_volatile,
-                              gboolean                        is_external,
-                              const char *                    shadowed_storage,
-                              gboolean                        shadowed_owned,
-                              const char *                    keyfile_dir,
-                              const char *                    profile_dir,
-                              const char *                    existing_path,
-                              gboolean                        existing_path_read_only,
-                              gboolean                        force_rename,
-                              NMSKeyfileWriterAllowFilenameCb allow_filename_cb,
-                              gpointer                        allow_filename_user_data,
-                              char **                         out_path,
-                              NMConnection **                 out_reread,
-                              gboolean *                      out_reread_same,
-                              GError **                       error)
-{
-    return _internal_write_connection(connection,
-                                      is_nm_generated,
-                                      is_volatile,
-                                      is_external,
-                                      shadowed_storage,
-                                      shadowed_owned,
-                                      keyfile_dir,
-                                      profile_dir,
-                                      TRUE,
-                                      0,
-                                      0,
-                                      existing_path,
-                                      existing_path_read_only,
-                                      force_rename,
-                                      allow_filename_cb,
-                                      allow_filename_user_data,
-                                      out_path,
-                                      out_reread,
-                                      out_reread_same,
-                                      error);
-}
-
-gboolean
-nms_keyfile_writer_test_connection(NMConnection * connection,
-                                   const char *   keyfile_dir,
-                                   uid_t          owner_uid,
-                                   pid_t          owner_grp,
-                                   char **        out_path,
-                                   NMConnection **out_reread,
-                                   gboolean *     out_reread_same,
-                                   GError **      error)
-{
-    return _internal_write_connection(connection,
-                                      FALSE,
-                                      FALSE,
-                                      FALSE,
-                                      NULL,
-                                      FALSE,
-                                      keyfile_dir,
-                                      keyfile_dir,
-                                      FALSE,
-                                      owner_uid,
-                                      owner_grp,
-                                      NULL,
-                                      FALSE,
-                                      FALSE,
-                                      NULL,
-                                      NULL,
-                                      out_path,
-                                      out_reread,
-                                      out_reread_same,
-                                      error);
-}