mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 10:13:34 +08:00
creds: open up access to clients via Polkit
Use auth_admin_keep, so that users don't have to re-auth interactively again and again when encrypting/decrypting batches of credentials.
This commit is contained in:
parent
2a1ffd3e3a
commit
caef0bc3dc
@ -4,6 +4,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "build.h"
|
||||
#include "bus-polkit.h"
|
||||
#include "creds-util.h"
|
||||
#include "dirent-util.h"
|
||||
#include "escape.h"
|
||||
@ -983,6 +984,7 @@ static int vl_method_encrypt(Varlink *link, JsonVariant *parameters, VarlinkMeth
|
||||
{ "data", JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(MethodEncryptParameters, data), 0 },
|
||||
{ "timestamp", _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64, offsetof(MethodEncryptParameters, timestamp), 0 },
|
||||
{ "notAfter", _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64, offsetof(MethodEncryptParameters, not_after), 0 },
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
_cleanup_(method_encrypt_parameters_done) MethodEncryptParameters p = {
|
||||
@ -990,6 +992,7 @@ static int vl_method_encrypt(Varlink *link, JsonVariant *parameters, VarlinkMeth
|
||||
.not_after = UINT64_MAX,
|
||||
};
|
||||
_cleanup_(iovec_done) struct iovec output = {};
|
||||
Hashmap **polkit_registry = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -1010,6 +1013,16 @@ static int vl_method_encrypt(Varlink *link, JsonVariant *parameters, VarlinkMeth
|
||||
if (p.not_after != UINT64_MAX && p.not_after < p.timestamp)
|
||||
return varlink_error_invalid_parameter_name(link, "notAfter");
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
/* bus= */ NULL,
|
||||
"io.systemd.credentials.encrypt",
|
||||
/* details= */ NULL,
|
||||
/* good_user= */ UID_INVALID,
|
||||
polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = encrypt_credential_and_warn(
|
||||
arg_with_key,
|
||||
p.name,
|
||||
@ -1051,15 +1064,17 @@ static void method_decrypt_parameters_done(MethodDecryptParameters *p) {
|
||||
static int vl_method_decrypt(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
|
||||
|
||||
static const JsonDispatch dispatch_table[] = {
|
||||
{ "name", JSON_VARIANT_STRING, json_dispatch_const_string, offsetof(MethodDecryptParameters, name), 0 },
|
||||
{ "blob", JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(MethodDecryptParameters, blob), 0 },
|
||||
{ "timestamp", _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64, offsetof(MethodDecryptParameters, timestamp), 0 },
|
||||
{ "name", JSON_VARIANT_STRING, json_dispatch_const_string, offsetof(MethodDecryptParameters, name), 0 },
|
||||
{ "blob", JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(MethodDecryptParameters, blob), JSON_MANDATORY },
|
||||
{ "timestamp", _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64, offsetof(MethodDecryptParameters, timestamp), 0 },
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
_cleanup_(method_decrypt_parameters_done) MethodDecryptParameters p = {
|
||||
.timestamp = UINT64_MAX,
|
||||
};
|
||||
_cleanup_(iovec_done_erase) struct iovec output = {};
|
||||
Hashmap **polkit_registry = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -1073,11 +1088,19 @@ static int vl_method_decrypt(Varlink *link, JsonVariant *parameters, VarlinkMeth
|
||||
|
||||
if (p.name && !credential_name_valid(p.name))
|
||||
return varlink_error_invalid_parameter_name(link, "name");
|
||||
if (!p.blob.iov_base)
|
||||
return varlink_error_invalid_parameter_name(link, "blob");
|
||||
if (p.timestamp == UINT64_MAX)
|
||||
p.timestamp = now(CLOCK_REALTIME);
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
/* bus= */ NULL,
|
||||
"io.systemd.credentials.decrypt",
|
||||
/* details= */ NULL,
|
||||
/* good_user= */ UID_INVALID,
|
||||
polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = decrypt_credential_and_warn(
|
||||
p.name,
|
||||
p.timestamp,
|
||||
@ -1116,10 +1139,11 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
if (arg_varlink) {
|
||||
_cleanup_(varlink_server_unrefp) VarlinkServer *varlink_server = NULL;
|
||||
_cleanup_(hashmap_freep) Hashmap *polkit_registry = NULL;
|
||||
|
||||
/* Invocation as Varlink service */
|
||||
|
||||
r = varlink_server_new(&varlink_server, VARLINK_SERVER_ROOT_ONLY|VARLINK_SERVER_INHERIT_USERDATA);
|
||||
r = varlink_server_new(&varlink_server, VARLINK_SERVER_ACCOUNT_UID|VARLINK_SERVER_INHERIT_USERDATA);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
||||
|
||||
@ -1134,6 +1158,8 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind Varlink methods: %m");
|
||||
|
||||
varlink_server_set_userdata(varlink_server, &polkit_registry);
|
||||
|
||||
r = varlink_server_loop_auto(varlink_server);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to run Varlink event loop: %m");
|
||||
|
40
src/creds/io.systemd.credentials.policy
Normal file
40
src/creds/io.systemd.credentials.policy
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
|
||||
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"https://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
|
||||
|
||||
<!--
|
||||
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
This file is part of systemd.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
-->
|
||||
|
||||
<policyconfig>
|
||||
|
||||
<vendor>The systemd Project</vendor>
|
||||
<vendor_url>https://systemd.io</vendor_url>
|
||||
|
||||
<action id="io.systemd.credentials.encrypt">
|
||||
<description gettext-domain="systemd">Allow encryption and signing of system credentials.</description>
|
||||
<message gettext-domain="systemd">Authentication is required for an application to encrypt and sign a system credential.</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="io.systemd.credentials.decrypt">
|
||||
<description gettext-domain="systemd">Allow decryption of system credentials.</description>
|
||||
<message gettext-domain="systemd">Authentication is required for an application to decrypto a system credential.</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
</policyconfig>
|
@ -23,3 +23,6 @@ if install_sysconfdir
|
||||
install_emptydir(sysconfdir / 'credstore.encrypted',
|
||||
install_mode : 'rwx------')
|
||||
endif
|
||||
|
||||
install_data('io.systemd.credentials.policy',
|
||||
install_dir : polkitpolicydir)
|
||||
|
@ -16,7 +16,7 @@ Before=sockets.target
|
||||
[Socket]
|
||||
ListenStream=/run/systemd/io.systemd.Credentials
|
||||
FileDescriptorName=varlink
|
||||
SocketMode=0600
|
||||
SocketMode=0666
|
||||
Accept=yes
|
||||
|
||||
[Install]
|
||||
|
Loading…
Reference in New Issue
Block a user