gpg-agent nói tác nhân tồn tại, nhưng gpg nói đại lý không tồn tại?


9

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 bashhộ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-agentnói rằng nó đã chạy ... nhưng gpgbả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, gpgkhô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_INFOthiết lập, sau đó trong một thiết bị đầu cuối đang chạy eval $(gpg-agent --daemon)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-agentphá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_INFOmôi trường vì điều đó có thể đề cập đến một tác nhân cũ (đã chết) đã được thay thế ... và gpgcũng không gpg-agentcung cấp tùy chọn dòng lệnh để ping tác nhân và trả về đúng nếu nó đồng ý.


Tôi cũng đã hỏi về danh sách gửi thư của người dùng gpg; Tôi sẽ liên kết đến bài viết một khi nó xuất hiện trong kho lưu trữ.
Craig Ringer

Unix.SE Cách định cấu hình gpg để chỉ nhập cụm mật khẩu một lần mỗi phiên đã giải quyết một số vấn đề của tôi - trên hệ thống một người dùng.
Joel Purra

Câu trả lời:


6
  1. Bạn có thể kiểm tra mã thoát của gpg-connect-agent /bye
  2. Bạn có thể kiểm tra xem ổ cắm được cung cấp trong $ GPG_AGENT_INFO có tồn tại không. Điều đó là đủ nhưng bạn cũng có thể kiểm tra với fuser hoặc lsof xem quy trình được đưa ra trong $ GPG_AGENT_INFO có phải là quy trình đã mở ổ cắm không. Và nếu bạn muốn thực sự mệt mỏi, bạn cũng có thể kiểm tra xem / Proc / $ PID / exe có phải là một liên kết đến / usr / bin / gpg-agent (hoặc bất cứ điều gì) không.

Thật không may, cả hai không giải quyết vấn đề. (1) xác định chính xác nếu gpg-agent đang chạy, nhưng nó không kiểm tra giống như cách gpgtự làm của nó, vì vậy nó có thể thành công khi gpg sau đó không kết nối được với tác nhân. Điều tương tự cũng đúng với (2) ở chỗ tác nhân có thể đang chạy, nhưng GPG_AGENT_INFO không được đặt trong phiên hiện tại và không có cách nào rõ ràng để yêu cầu gpg-agentlệnh cho tác GPG_AGENT_INFOnhân đã chạy.
Craig Ringer


3

Cho đến nay cách giải quyết tốt nhất tôi có là mớ hỗn độn đáng ghét sau:

if ! test -v GPG_AGENT_INFO; then
    if gpg-agent 2>/dev/null; then
        if test -e /tmp/.gpg-agent-$USER/env; then
            . /tmp/.gpg-agent-$USER/env
        elif test -e ~/.gpg-agent-info; then
            . ~/.gpg-agent-info
        else
            echo 'A gpg agent is running, but we cannot find its socket info because'
            echo 'the GPG_AGENT_INFO env var is not set and gpg agent info has not been'
            echo 'written to any expected location. Cannot continue. Please report this'
            echo 'issue for investigation.'
            exit 5
        fi
    else
        mkdir /tmp/.gpg-agent-$USER
        chmod 700 /tmp/.gpg-agent-$USER
        gpg-agent --daemon --write-env-file /tmp/.gpg-agent-$USER/env
        . /tmp/.gpg-agent-$USER/env
    fi
    # The env file doesn't include an export statement
    export GPG_AGENT_INFO
else
    if ! gpg-agent 2>/dev/null; then
        echo 'GPG_AGENT_INFO is set, but cannot connect to the agent.'
        echo 'Unsure how to proceed, so aborting execution. Please report this'
        echo 'issue for investigation.'
        exit 5
    fi
fi

Điều này sẽ kiểm tra GPG_AGENT_INFOtrong môi trường và nếu nó được đặt, hãy đảm bảo gpg-agent đang thực sự chạy. (Tôi vẫn chưa chắc cách thức này tương tác với các triển khai tác nhân gpg khác như tác nhân của Gnome). Nếu thông tin tác nhân được đặt nhưng tác nhân không chạy thì không biết cách đối phó và bỏ cuộc.

Nếu thông tin tác nhân không được đặt, nó sẽ kiểm tra xem tác nhân có đang chạy hay không. Nếu có, nó sẽ tìm thông tin env ở một vài địa điểm nổi tiếng và nếu không tìm thấy nó, hãy từ bỏ.

Nếu tác nhân không chạy và thông tin tác nhân không được đặt, nó sẽ khởi động một tác nhân, ghi tệp env vào một vị trí riêng tư và tiến hành.

Phải nói rằng tôi không hài lòng với vụ hack khủng khiếp, thù địch và không đáng tin cậy này là một cách đánh giá thấp.

Thật đáng ngạc nhiên rằng gpg, một công cụ bảo mật / tiền điện tử, sẽ bỏ qua các đối số và tiến hành. --use-agentsẽ là một lỗi nghiêm trọng nếu một tác nhân không chạy, ít nhất là tùy ý, nhiều như việc chỉ định -rvới một người nhận không hợp lệ sẽ là một lỗi thay vì bỏ qua. Thực tế là gpgtìm thấy tác nhân của nó một cách khác với gpg-agentlệnh đang hoang mang.


Như thường lệ nó có thể được thực hiện ngay cả Messier ... :-) Nếu GPG_AGENT_INFO không phải là (hoặc sai) thiết lập và bạn biết PID (ví dụ như bằng pgrep gpg-agent) sau đó ypu có thể làm điều này để tìm ra ổ cắm:lsof -n -p $PID | grep S.gpg-agent$ | awk '{print $NF}'
Hauke Laging

1
@HaukeLaging ... nếu nó thực sự gpg-agentkhông nói gnome-keyring-daemontại nơi làm việc. 'Vì nó chưa đủ kinh khủng: S. Tôi ngạc nhiên rằng tất cả như vậy là một mớ hỗn độn không nhất quán.
Craig Ringer

! test -v GPG_AGENT_INFO không hoạt động trên Mac OS X. [ -z ${GPG_AGENT_INFO+x} ]Thay vào đó, bạn sẽ cần sử dụng một cái gì đó giống như .
Dan Loewenherz

2

Trên hệ thống Ubuntu của tôi gpg-agentđược cấu hình để ghi tệp môi trường của nó vào ~/.gnupg/gpg-agent-info-$(hostname)(được thực hiện bởi /etc/X11/Xsession.d/90gpg-agent). Nếu hệ thống của bạn không làm điều này, bạn có thể sửa đổi cách tác nhân bắt đầu viết một tệp môi trường ở một vị trí nổi tiếng mà sau này có thể có nguồn gốc. Ví dụ:

$ gpg-agent --daemon --write-env-file="$HOME/.gnupg/gpg-agent-info"
$ source ~/.gnupg/gpg-agent-info

Vâng, vấn đề là tôi đang sử dụng các công cụ viết kịch bản; Tôi thực sự không thể dựa vào các chi tiết cụ thể của distro. gpg-agent sẽ không viết một tệp env nếu một tác nhân đang chạy và tôi không thể xác định nơi nào có thể có tệp env. Nếu gpg-agent --write-env-file sẽ truy vấn tác nhân hiện đang chạy và viết một tệp env, điều đó sẽ ổn, nhưng không được.
Craig Ringer

1
Lưu ý:gpg-agent[2333]: WARNING: "--write-env-file" is an obsolete option - it has no effect
Kent Fredric
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.