On Tue, Dec 09, 2025 at 01:22:29 +0530, Arun Menon via Devel wrote:
> A new configuration file called secret.conf is introduced to
> let the user configure the path to the secrets encryption key.
> This key will be used to encrypt/decrypt the secrets in libvirt.
> 
> By default the path is set to the runtime directory
> /run/libvirt/secrets, and it is commented in the config file.
> After parsing the file, the virtsecretd driver checks if an
> encryption key is present in the path and is valid.
> 
> If no encryption key is present in the path, then
> the service will by default use the encryption key stored in the
> CREDENTIALS_DIRECTORY.
> 
> Add logic to parse the encryption key file and store the key.
> It also checks for the encrypt_data attribute in the config file.
> The encryption and decryption logic will be added in the subsequent patches.
> 
> Signed-off-by: Arun Menon <[email protected]>
> ---
>  include/libvirt/virterror.h            |   1 +
>  libvirt.spec.in                        |   3 +
>  po/POTFILES                            |   1 +
>  src/secret/libvirt_secrets.aug         |  40 ++++++
>  src/secret/meson.build                 |  19 +++
>  src/secret/secret.conf.in              |  14 ++
>  src/secret/secret_config.c             | 171 +++++++++++++++++++++++++
>  src/secret/secret_config.h             |  40 ++++++
>  src/secret/secret_driver.c             |   9 ++
>  src/secret/test_libvirt_secrets.aug.in |   6 +
>  src/util/virerror.c                    |   3 +
>  11 files changed, 307 insertions(+)
>  create mode 100644 src/secret/libvirt_secrets.aug
>  create mode 100644 src/secret/secret.conf.in
>  create mode 100644 src/secret/secret_config.c
>  create mode 100644 src/secret/secret_config.h
>  create mode 100644 src/secret/test_libvirt_secrets.aug.in

Build fails after this patch with:

' '-Dabs_top_srcdir="/home/pipo/libvirt"' -MD -MQ 
src/libvirt_driver_secret.so.p/secret_secret_driver.c.o -MF 
src/libvirt_driver_secret.so.p/secret_secret_driver.c.o.d -o 
src/libvirt_driver_secret.so.p/secret_secret_driver.c.o -c 
../../../libvirt/src/secret/secret_driver.c
../../../libvirt/src/secret/secret_driver.c:75:5: error: unknown type name 
‘virSecretDaemonConfig’
   75 |     virSecretDaemonConfig *config;
      |     ^~~~~~~~~~~~~~~~~~~~~
../../../libvirt/src/secret/secret_driver.c: In function 
‘secretStateInitialize’:
../../../libvirt/src/secret/secret_driver.c:525:28: error: implicit declaration 
of function ‘virSecretDaemonConfigNew’ [-Wimplicit-function-declaration]
  525 |     if (!(driver->config = 
virSecretDaemonConfigNew(driver->privileged)))
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~
../../../libvirt/src/secret/secret_driver.c:525:28: error: nested extern 
declaration of ‘virSecretDaemonConfigNew’ [-Werror=nested-externs]
../../../libvirt/src/secret/secret_driver.c:525:26: error: assignment to ‘int 
*’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
  525 |     if (!(driver->config = 
virSecretDaemonConfigNew(driver->privileged)))
      |                          ^
../../../libvirt/src/secret/secret_driver.c: In function ‘secretStateReload’:
../../../libvirt/src/secret/secret_driver.c:562:26: error: assignment to ‘int 
*’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
  562 |     if (!(driver->config = 
virSecretDaemonConfigNew(driver->privileged)))
      |                          ^

Since it succeeds after the last patch you likely misplaced some header
inclusion into the wrong patch.


[...]


> diff --git a/src/secret/secret_config.c b/src/secret/secret_config.c
> new file mode 100644
> index 0000000000..b63567944e
> --- /dev/null
> +++ b/src/secret/secret_config.c

[...]

> +
> +
> +static int virGetSecretsEncryptionKey(virSecretDaemonConfig *cfg,
> +                                      uint8_t **secretsEncryptionKey,
> +                                      size_t *secretsKeyLen)

inconsistent function header formatting

> +{
> +    VIR_AUTOCLOSE fd = -1;
> +    int encryption_key_length;
> +
> +    if ((encryption_key_length = 
> virFileReadAll(cfg->secretsEncryptionKeyPath, VIR_SECRETS_ENCRYPTION_KEY_LEN, 
> (char**)secretsEncryptionKey)) < 0) {

break the very long line on argument boundaries

> +        return -1;
> +    }
> +    if (encryption_key_length != VIR_SECRETS_ENCRYPTION_KEY_LEN) {
> +        virReportError(VIR_ERR_INVALID_ENCR_KEY_SECRET,
> +                       _("Encryption key length must be '%1$d' '%2$s'"),
> +                       VIR_SECRETS_ENCRYPTION_KEY_LEN, 
> cfg->secretsEncryptionKeyPath);
> +    }
> +
> +    *secretsKeyLen = (size_t)encryption_key_length;
> +    return 0;
> +}
> +
> +
> +virSecretDaemonConfig *
> +virSecretDaemonConfigNew(bool privileged)
> +{
> +    g_autoptr(virSecretDaemonConfig) cfg = NULL;
> +    g_autofree char *configdir = NULL;
> +    g_autofree char *configfile = NULL;
> +    const char *credentials_directory;
> +
> +    if (virSecretConfigInitialize() < 0)
> +        return NULL;
> +
> +    if (!(cfg = virObjectNew(virSecretDaemonConfigClass)))
> +        return NULL;
> +
> +    cfg->secretsEncryptionKeyPath = NULL;

all of 'cfg' ought to be initialized to NULL at this point so this isn't
needed.

> +
> +    if (virSecretDaemonConfigFilePath(privileged, &configfile) < 0)
> +        return NULL;
> +
> +    if (virSecretLoadDaemonConfig(cfg, configfile) < 0)
> +        return NULL;
> +
> +    credentials_directory = getenv("CREDENTIALS_DIRECTORY");
> +
> +    if (!cfg->secretsEncryptionKeyPath && credentials_directory) {
> +        cfg->secretsEncryptionKeyPath = 
> g_strdup_printf("%s/secrets-encryption-key",
> +                                                        
> credentials_directory);
> +        if (!virFileExists(cfg->secretsEncryptionKeyPath)) {
> +            g_clear_pointer(&cfg->secretsEncryptionKeyPath, g_free);
> +        }
> +    }
> +
> +    if (!cfg->encryptDataWasSet) {
> +        if (!cfg->secretsEncryptionKeyPath) {
> +            /* No path specified by user or environment, disable encryption 
> */
> +            cfg->encryptData = false;
> +        } else {
> +            cfg->encryptData = true;
> +        }
> +    } else {
> +        if (cfg->encryptData) {
> +            if (!cfg->secretsEncryptionKeyPath) {
> +                /* Built-in default path must be used */
> +                cfg->secretsEncryptionKeyPath = 
> g_strdup("/run/libvirt/secrets/encryption-key");

This ought to use some form of config-time variable to place it
correctly, otherwise it won't respect users' build-time options.

> +            }
> +        }
> +    }
> +    VIR_DEBUG("Secrets encryption key path: %s", 
> NULLSTR(cfg->secretsEncryptionKeyPath));
> +
> +    if (cfg->encryptData) {
> +        if (virGetSecretsEncryptionKey(cfg, &cfg->secretsEncryptionKey, 
> &cfg->secretsKeyLen) < 0) {
> +            return NULL;
> +        }
> +    }
> +    return g_steal_pointer(&cfg);
> +}

[...]

> diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
> index 04c3ca49f1..408a629ea0 100644
> --- a/src/secret/secret_driver.c
> +++ b/src/secret/secret_driver.c
> @@ -70,6 +70,9 @@ struct _virSecretDriverState {
>  
>      /* Immutable pointer, self-locking APIs */
>      virInhibitor *inhibitor;
> +
> +    /* Settings from secret.conf file */
> +    virSecretDaemonConfig *config;
>  };

Please use the annotation about how to access the data (as all other
values above have).

In this case I expect that the correct annotation is:

    /* Require lock to get reference on 'config',
     * then lockless thereafter */

same as the 'config' member of  struct _virQEMUDriver.

Reply via email to