Tôi đang vật lộn với một số vấn đề trong khi tạo kịch bản gpg với bash
hộp Debian 6.0.6. Tôi có một tập lệnh thực hiện một loạt các hoạt động và muốn đảm bảo rằng một tác nhân gpg có sẵn trước khi nó cố gắng tiến hành.
Vì gpg-agent sẽ không thực hiện hành động nào và trả lại thành công nếu được khởi chạy khi đã chạy, việc đảm bảo đại lý có mặt đơn giản như sau:
eval $(gpg-agent --daemon)
gpg-agent
bắt đầu, hoặc sẽ báo cáo:
gpg-agent[21927]: a gpg-agent is already running - not starting a new one
và trả về 0 (thành công) nếu đã chạy.
Vấn đề phát sinh khi một tác nhân đã chạy trong một phiên khác. gpg-agent
nói rằng nó đã chạy ... nhưng gpg
bản thân nó tuyên bố rằng nó không khả dụng.
$ gpg-agent --version
gpg-agent (GnuPG) 2.0.19
libgcrypt 1.5.0
$ gpg --version
gpg (GnuPG) 1.4.13
$ eval $(gpg-agent --daemon)
gpg-agent[21927]: a gpg-agent is already running - not starting a new one
$ gpg -d demo-file.asc
gpg: gpg-agent is not available in this session
Điều này khiến tôi thất vọng và bối rối. Dường như gpg-agent
đang phát hiện tác nhân một cách khác để tự gpg nó. Tồi tệ hơn, gpg
không có cách nào để hỏi liệu đại lý có sẵn theo cách có thể viết được hay không, vì họ thích âm thầm bỏ qua người nhận bằng các khóa không sử dụng được và vẫn trả về thành công, vì vậy rất khó phát hiện vấn đề này trước khi bắt đầu đợt. Tôi không muốn phân tích cú pháp đầu ra của gpg vì lý do i18n trong số những người khác.
Bạn có thể tái tạo điều này bằng cách đảm bảo bạn không có tác nhân gpg đang chạy hoặc đã GPG_AGENT_INFO
thiết lập, sau đó trong một thiết bị đầu cuối đang chạy eval $(gpg-agent --daemon)
và trong một thiết bị đầu cuối khác chạy ở trên. Bạn sẽ lưu ý rằng đại lý gpg nói rằng nó đã chạy, nhưng gpg không kết nối được với đại lý.
Ý tưởng?
CẬP NHẬT : gpg-agent
phát hiện một tác nhân khác bằng cách tìm kiếm một tệp ổ cắm ở một vị trí nổi tiếng và viết thư cho nó để kiểm tra mức độ ổn định, theo điều này strace
:
socket(PF_FILE, SOCK_STREAM, 0) = 5
connect(5, {sa_family=AF_FILE, sun_path="/home/craig/.gnupg/S.gpg-agent"}, 32) = 0
fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)
select(6, [5], NULL, NULL, {0, 0}) = 1 (in [5], left {0, 0})
read(5, "OK Pleased to meet you, process "..., 1002) = 38
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f41a3e61000
write(2, "gpg-agent: gpg-agent running and"..., 43gpg-agent: gpg-agent running and available
) = 43
trong khi GnuPG dường như chỉ nhìn vào môi trường, bỏ qua vị trí ổ cắm nổi tiếng. Trong common/simple-pwquery.c
:
/* Try to open a connection to the agent, send all options and return
the file descriptor for the connection. Return -1 in case of
error. */
static int
agent_open (int *rfd)
{
int rc;
int fd;
char *infostr, *p;
struct sockaddr_un client_addr;
size_t len;
int prot;
char line[200];
int nread;
*rfd = -1;
infostr = getenv ( "GPG_AGENT_INFO" );
if ( !infostr || !*infostr )
infostr = default_gpg_agent_info;
if ( !infostr || !*infostr )
{
#ifdef SPWQ_USE_LOGGING
log_error (_("gpg-agent is not available in this session\n"));
#endif
return SPWQ_NO_AGENT;
}
/* blah blah blah truncated blah */
}
Tôi thực sự không muốn giết tác nhân chỉ để đảm bảo rằng tôi có thể bắt đầu lại nó, và không có nơi tiêu chuẩn nào mà tác nhân người dùng có thể viết một tệp môi trường. Tệ hơn nữa, tôi thậm chí không thể kiểm tra sự hiện diện của GPG_AGENT_INFO
môi trường vì điều đó có thể đề cập đến một tác nhân cũ (đã chết) đã được thay thế ... và gpg
cũng không gpg-agent
cung cấp tùy chọn dòng lệnh để ping tác nhân và trả về đúng nếu nó đồng ý.