我正在尝试使用gpg从脚本中使用--clearsign文件(用于debian打包)。
我有一个导出的无密码private-key.gpg文件,希望:
gpg --clearsign -o output input我不想搅乱当前用户的~/.gnupg或/run/user/$(id -u)/gnupg,因为它们与我的脚本无关。而且,脚本可以在多个实例中同时运行,我不希望它们相互干扰。
我以为那会很容易。将$GNUPGHOME设置为temp并完成它。但是,我想不出如何让gpg在脚本中运行而不影响用户的标准配置。似乎gpg已经竭尽全力避免了gpg-agent和gpg-agent坚持使用全局/硬编码路径。
我能把所有东西都放在$GNUPGHOME下吗?或者,如何在不影响用户配置、使用gpg或脚本的其他实例的情况下安全地使用shell脚本中的gpg?
详细信息
阅读gpg博士,我看到:
--use-agent
--no-use-agent
This is dummy option. gpg always requires the agent.gpg-代理文档说:
--use-standard-socket
--no-use-standard-socket
--use-standard-socket-p
Since GnuPG 2.1 the standard socket is always used.
These options have no more effect. The command gpg-agent
--use-standard-socket-p will thus always return success.这个“标准套接字”大概在/run/user/$(id -u)/gnupg中--因此我似乎无法避免gpg干扰用户对gpg的“正常”使用。
版本: gpg 2.1.18上Debian 9/拉伸/稳定
发布于 2019-12-21 18:21:32
如果您不能阻止gpg创建文件,给gpg一个位置放置它们对于当前进程来说是独一无二的,这会有帮助吗?
# Create a temporary directory for gpg.
dir="$(mktemp -d)"
# Remove the directory and its contents when the script exits.
trap '[[ ! -d "${dir}" ]] || rm -r "${dir}"' EXIT
# Put your private-key.gpg in the temporary directory.
$(your command here)
# Tell gpg to use the temporary directory.
gpg --homedir "${dir}" --clearsign -o output input发布于 2022-09-12 21:42:03
在互联网上搜索了几个小时,寻找一些选项,以便能够在不同的gnupg家庭中运行多个gpg-agent实例之后,我尝试了限制对全局套接字位置的访问,它成功了。它返回到将套接字文件放置在gnupg主目录中。我用bwrap来做这件事。下面是起作用的完整命令:bwrap --dev-bind / / --tmpfs /run/user/$(id -u)/gnupg gpg-agent ...。因为您的问题通常是关于脚本的,所以您可能不能依赖于安装了bwrap,所以下一个最好的方法是使用一个shim来阻止gpg-agent为其套接字使用用户的xdg运行时目录。
在查看了strace的输出后,在bwrap下运行到gnupg主页的位置切换似乎是在发布stat on /run/user/${UID}/gnupg之后发生的。通过查看gpg-agent.c代码,这似乎可以完成以下检查:
/* Check that it is a directory, owned by the user, and only the
* user has permissions to use it. */
if (!S_ISDIR(sb.st_mode)
|| sb.st_uid != getuid ()
|| (sb.st_mode & (S_IRWXG|S_IRWXO)))
{
*r_info |= 4; /* Bad permissions or not a directory. */
if (!skip_checks)
goto leave;
}使用此方法,我们只需告诉gpg-agent存在/run/user/${UID}/gnupg,但它不是目录,因此它将在这些检查中的第一个失败。
下面是一个垫片的代码,它就是这样做的(可能会更好,但它能工作):
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <dlfcn.h>
#include <stdio.h>
#define STR_MAX 4096
#define MIN(a, b) (a < b ? a : b)
#define MAX(a, b) (a > b ? a : b)
// Set up checking stuff
#define MAX_UID_LEN 11
#define PREFIX_1 "/run/user"
#define PREFIX_2 "/var/run/user"
#define TEST_LEN_1 (sizeof(PREFIX_1) - 1 + 1 + MAX_UID_LEN + sizeof("/gnupg") - 1)
#define TEST_LEN_2 (sizeof(PREFIX_2) - 1 + 1 + MAX_UID_LEN + sizeof("/gnupg") - 1)
#define MAX_TEST_LEN MAX(TEST_LEN_1, TEST_LEN_2)
// Override stat function
int stat(const char *restrict pathname, struct stat *restrict statbuf) {
int (*original_stat)(const char *restrict, struct stat *restrict) = dlsym(RTLD_NEXT, "stat");
// Call original stat function
int retval = original_stat(pathname, statbuf);
if (retval == 0) {
// Check if a path we want to modify
size_t pathlen = strnlen(pathname, STR_MAX);
char path_check[MAX_TEST_LEN + 1];
snprintf(path_check, MAX_TEST_LEN + 1, "%s/%u/gnupg", PREFIX_1, getuid());
if (strncmp(pathname, path_check, MIN(MAX_TEST_LEN, pathlen)) == 0) {
// Report a regular file with perms: rwxrwxrwx
statbuf->st_mode = S_IFREG|0777;
}
snprintf(path_check, MAX_TEST_LEN + 1, "%s/%u/gnupg", PREFIX_2, getuid());
if (strncmp(pathname, path_check, MIN(MAX_TEST_LEN, pathlen)) == 0) {
// Report a regular file with perms: rwxrwxrwx
statbuf->st_mode = S_IFREG|0777;
}
}
return retval;
}您可以用:clang -Wall -O2 -fpic -shared -ldl -o gpg-shim.so gpg-shim.c编译它,然后将它添加到LD_PRELOAD中,然后它应该允许您运行多个gpg-agent,只要它们有不同的gnupg家园。
我知道这个答案真的晚了,但我希望它能帮助一些人,像我,寻找一种方法运行多个gpg-agent与不同的家庭。(对于我的具体情况,我希望运行多个gpg-agent实例,使密钥缓存不同的时间)。
https://stackoverflow.com/questions/52611053
复制相似问题