gpg-rs / gpgme

GPGme bindings for Rust
GNU Lesser General Public License v2.1
83 stars 13 forks source link

find_trust_items doesn't return Error on invalid argument #28

Closed alexanderkjall closed 4 years ago

alexanderkjall commented 4 years ago

If I run the following code:

let mut ctx = gpgme::Context::from_protocol(gpgme::Protocol::OpenPgp)?;
ctx.find_trust_items("DF0C3D316B7312D5", 0)?;

Then it simple returns a empty TrustItems object.

Looking what gpgme does in strace produces the following calls:

[pid  6303] execve("/usr/bin/gpg", ["gpg", "--batch", "--no-sk-comments", "--status-fd", "9", "--no-tty", "--charset", "utf8", "--enable-progress-filter", "--exit-on-status-write-error", "--display", ":0.0", "--ttyname", "/dev/pts/1", "--ttytype", "xterm-256color", "--logger-fd", "13", "--with-colons", "--list-trust-path", "--", "DF0C3D316B7312D5"], 0x5580ba36ad10 /* 57 vars */) = 0
[pid  6303] arch_prctl(0x3001 /* ARCH_??? */, 0x7ffca1eb87e0) = -1 EINVAL (Invalid argument)
[pid  6303] arch_prctl(ARCH_SET_FS, 0x7fcb35d7e740) = 0
[pid  6303] exit_group(2)               = ?

And running that same command in my shell produces this result:

capitol@tool:~$ gpg --batch --no-sk-comments --no-tty --charset utf8 --enable-progress-filter --exit-on-status-write-error --display :0.0 --ttyname /dev/pts/1 --ttytype xterm-256color --with-colons --list-trust-path -- DF0C3D316B7312D5
gpg: invalid option "--list-trust-path"

I would have expected that gpgme would return an error object.

(why gpgme tries to run an option that doesn't seem to exist is a bug for that library maybe?)

johnschug commented 4 years ago

It does seem to be a problem with the upstream library. I ran a C version of your sample and it produced the same results.

// Based on t-trustlist.c from gpgme
// Copyright (C) 2000 Werner Koch (dd9jn)
// Copyright (C) 2001, 2003, 2004 g10 Code GmbH
// SPDX-License-Identifier: LGPL-2.1-or-later
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <gpgme.h>

#define fail_if_err(err) do {                                        \
    if (err) {                                                       \
      fprintf (stderr, "%s:%d: %s: %s\n",                            \
          __FILE__, __LINE__, gpgme_strsource (err),                 \
          gpgme_strerror (err));                                     \
      exit (1);                                                      \
    }                                                                \
  } while (0)

int main() {
  gpgme_ctx_t ctx;
  gpgme_trust_item_t item;
  gpgme_error_t err = GPG_ERR_NO_ERROR;

  assert(gpgme_check_version(GPGME_VERSION));

  err = gpgme_new(&ctx);
  fail_if_err(err);

  err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OPENPGP);
  fail_if_err(err);

  // Also tried with a key in my keyring
  err = gpgme_op_trustlist_start(ctx, "DF0C3D316B7312D5", 0);
  fail_if_err(err);

  while (!(err = gpgme_op_trustlist_next(ctx, &item))) {
    printf ("l=%d k=%s t=%d o=%s v=%s u=%s\n",
        item->level, item->keyid, item->type, item->owner_trust,
        item->validity, item->name);
    gpgme_trust_item_unref(item);
  }
  if (gpgme_err_code(err) != GPG_ERR_EOF) {
    fail_if_err(err);
  }

  err = gpgme_op_trustlist_end(ctx);
  fail_if_err(err);

  gpgme_release(ctx);

  return 0;
}

Compile with cc -lgpgme -pthread -o test test.c

After reading the gpg source, it seems that trust listing has been manually disabled. This appears to have been done in a commit all the way back in 2002.

alexanderkjall commented 4 years ago

I opened a bug upstream: https://dev.gnupg.org/T4834