return _import_keylist(self, keys);
}
+static PyObject* Pakfire_fetch_key(PakfireObject* self, PyObject* args, PyObject* kwds) {
+ char* kwlist[] = { "userid", "fingerprint", NULL };
+ struct pakfire_key* key = NULL;
+ const char* userid = NULL;
+ const char* fingerprint = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$zz", kwlist, &userid, &fingerprint))
+ return NULL;
+
+ // Fetch the key
+ int r = pakfire_key_fetch(&key, self->pakfire, userid, fingerprint);
+ if (r) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+
+ // Return the result
+ if (key)
+ return new_key(&KeyType, key);
+
+ Py_RETURN_NONE;
+}
+
static PyObject* Pakfire_whatprovides(PakfireObject* self, PyObject* args) {
const char* provides = NULL;
struct pakfire_packagelist* list = NULL;
METH_VARARGS|METH_KEYWORDS,
NULL
},
+ {
+ "fetch_key",
+ (PyCFunction)Pakfire_fetch_key,
+ METH_VARARGS|METH_KEYWORDS,
+ NULL
+ },
{
"generate_key",
(PyCFunction)Pakfire_generate_key,
return 0;
}
+static int pakfire_key_extract_email(const char* uid, char** email) {
+ if (!uid)
+ return 1;
+
+ // Find a start
+ char* start = strrchr(uid, '<');
+ if (!start)
+ return 1;
+
+ // Find the end
+ char* end = strchr(start, '>');
+ if (!end)
+ return 1;
+
+ // Copy email address to new memory
+ int r = asprintf(email, "%.*s", (int)(end - start - 1), start + 1);
+ if (r < 0)
+ return 1;
+
+ return 0;
+}
+
+static int __pakfire_key_fetch(gpgme_key_t* key, Pakfire pakfire,
+ const char* what, gpgme_keylist_mode_t flags) {
+ // Fetch GPGME context
+ gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire);
+ if (!gpgctx)
+ return 1;
+
+ int r = 1;
+
+ // Fetch current keylist mode
+ gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(gpgctx);
+
+ // Set keylist mode
+ gpgme_error_t error = gpgme_set_keylist_mode(gpgctx, (mode|flags) & ~GPGME_KEYLIST_MODE_LOCAL);
+ if (error != GPG_ERR_NO_ERROR) {
+ ERROR(pakfire, "Could not set GPG keylist mode: %s\n",
+ gpgme_strerror(error));
+ goto ERROR;
+ }
+
+ // Fetch the key
+ error = gpgme_get_key(gpgctx, what, key, 0);
+ switch (gpg_err_code(error)) {
+ case GPG_ERR_NO_ERROR:
+ case GPG_ERR_EOF:
+ break;
+
+ default:
+ ERROR(pakfire, "Could not fetch key %s: %s\n", what, gpgme_strerror(error));
+ r = 1;
+ goto ERROR;
+ }
+
+ // Success
+ r = 0;
+
+ERROR:
+ if (r && *key)
+ gpgme_key_unref(*key);
+
+ // Reset keylist mode
+ gpgme_set_keylist_mode(gpgctx, mode);
+
+ return r;
+}
+
+static int pakfire_key_fetch_from_wkd(gpgme_key_t* key, Pakfire pakfire, const char* email) {
+ return __pakfire_key_fetch(key, pakfire, email, GPGME_KEYLIST_MODE_LOCATE);
+}
+
+static int pakfire_key_fetch_from_keyserver(gpgme_key_t* key, Pakfire pakfire, const char* fpr) {
+ return __pakfire_key_fetch(key, pakfire, fpr, GPGME_KEYLIST_MODE_EXTERN);
+}
+
+PAKFIRE_EXPORT int pakfire_key_fetch(struct pakfire_key** key, Pakfire pakfire,
+ const char* uid, const char* fingerprint) {
+ // At least one (uid or fingerprint) must be set
+ if (!uid && !fingerprint) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ gpgme_key_t gpgkey = NULL;
+ char* email = NULL;
+ int r;
+
+ // Extract email address from uid
+ if (uid) {
+ r = pakfire_key_extract_email(uid, &email);
+ if (r)
+ goto ERROR;
+ }
+
+ // Try importing the key using Web Key Directory
+ if (email) {
+ r = pakfire_key_fetch_from_wkd(&gpgkey, pakfire, email);
+ if (r)
+ goto ERROR;
+ }
+
+ // If nothing was found and we have a fingerprint, let's try a keyserver
+ if (!gpgkey && fingerprint) {
+ r = pakfire_key_fetch_from_keyserver(&gpgkey, pakfire, fingerprint);
+ if (r)
+ goto ERROR;
+ }
+
+ // Create a pakfire_key out of the gpg key object
+ if (gpgkey) {
+ r = pakfire_key_create(key, pakfire, gpgkey);
+ if (r)
+ goto ERROR;
+ }
+
+ERROR:
+ if (gpgkey)
+ gpgme_key_unref(gpgkey);
+ if (email)
+ free(email);
+
+ return r;
+}
+
static void pakfire_key_free(struct pakfire_key* key) {
gpgme_key_unref(key->gpgkey);
pakfire_unref(key->pakfire);
help=_("Include the secret key"))
export_key.set_defaults(func=self._export_key)
+ # fetch-key
+ fetch_key = subparsers.add_parser("fetch-key",
+ help=_("Download a key"))
+ fetch_key.add_argument("--userid",
+ help=_("The name/email address")
+ )
+ fetch_key.add_argument("--fingerprint",
+ help=_("The fingerprint of the key")
+ )
+ fetch_key.set_defaults(func=self._fetch_key)
+
# generate-key
generate_key = subparsers.add_parser("generate-key",
help=_("Generate a new key"))
else:
print(data)
+ def _fetch_key(self, p, args):
+ key = p.fetch_key(userid=args.userid, fingerprint=args.fingerprint)
+
+ # Print the key
+ if key:
+ print(key)
+
def _generate_key(self, p, args):
# Generate a new key
key = p.generate_key(