}
static PyObject* Pakfire_import_key(PakfireObject* self, PyObject* args) {
- const char* data = NULL;
+ PyObject* object = NULL;
- if (!PyArg_ParseTuple(args, "s", &data))
+ if (!PyArg_ParseTuple(args, "O", &object))
return NULL;
- struct pakfire_key** keys = pakfire_key_import(self->pakfire, data);
- if (!keys)
- return NULL; // TODO Raise error from errno
+ // Get a file descriptor from object
+ int fd = PyObject_AsFileDescriptor(object);
+ if (fd < 0)
+ return NULL;
+
+ // Convert to FILE*
+ FILE* f = fdopen(fd, "r");
+ if (!f) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+
+ struct pakfire_key** keys = NULL;
+ // Import keys from f
+ int r = pakfire_key_import(self->pakfire, f, &keys);
+ if (r) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+
+#warning THIS LEAKS MEMORY
return _import_keylist(self, keys);
}
return NULL;
}
-PAKFIRE_EXPORT struct pakfire_key** pakfire_key_import(Pakfire pakfire, const char* data) {
- gpgme_error_t error;
- gpgme_data_t keydata;
+PAKFIRE_EXPORT int pakfire_key_import(Pakfire pakfire, FILE* f,
+ struct pakfire_key*** keys) {
+ gpgme_data_t data;
+ int r = 1;
+
+ if (!f) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ // Reset keys
+ if (keys)
+ *keys = NULL;
+ // Fetch GPGME context
gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire);
+ if (!gpgctx)
+ return 1;
- // Form a data object out of the input without copying data
- error = gpgme_data_new_from_mem(&keydata, data, strlen(data), 0);
- if (error != GPG_ERR_NO_ERROR)
- goto FAIL;
+ // Import key data
+ gpgme_error_t e = gpgme_data_new_from_stream(&data, f);
+ if (gpg_error(e) != GPG_ERR_NO_ERROR)
+ goto ERROR;
+
+ gpgme_import_result_t result = NULL;
// Try importing the key(s)
- error = gpgme_op_import(gpgctx, keydata);
+ e = gpgme_op_import(gpgctx, data);
- gpgme_import_result_t result;
- switch (error) {
+ switch (gpg_error(e)) {
// Everything went fine
case GPG_ERR_NO_ERROR:
result = gpgme_op_import_result(gpgctx);
- DEBUG(pakfire, "Keys considered = %d\n", result->considered);
- DEBUG(pakfire, "Keys imported = %d\n", result->imported);
- DEBUG(pakfire, "Keys not imported = %d\n", result->not_imported);
-
// Did we import any keys?
gpgme_import_status_t status = result->imports;
- if (!status)
- return NULL;
+ if (!status) {
+ errno = ENOENT;
+ goto ERROR;
+ }
- struct pakfire_key** head = calloc(result->imported + 1, sizeof(*head));
- struct pakfire_key** list = head;
+ DEBUG(pakfire, "Keys considered = %d\n", result->considered);
+ DEBUG(pakfire, "Keys imported = %d\n", result->imported);
+ DEBUG(pakfire, "Keys not imported = %d\n", result->not_imported);
- // Retrieve all imported keys
- struct pakfire_key* key;
- while (status) {
- int r = pakfire_find_key(&key, pakfire, status->fpr);
- if (r)
- goto FAIL;
+ if (keys) {
+ // Allocate array
+ *keys = calloc(result->imported + 1, sizeof(**keys));
+ if (!*keys)
+ goto ERROR;
- const char* fingerprint = pakfire_key_get_fingerprint(key);
- INFO(pakfire, "Imported key %s\n", fingerprint);
+ // Retrieve all imported keys
- // Append key to list
- *list++ = key;
+ struct pakfire_key* key;
+ for (int i = 0; i < result->imported && status; i++, status = status->next) {
+ r = pakfire_find_key(&key, pakfire, status->fpr);
+ if (r)
+ goto ERROR;
- status = status->next;
+ // Append to array
+ (*keys)[i] = key;
+ }
}
-
- // Terminate list
- *list = NULL;
-
- gpgme_data_release(keydata);
-
- return head;
+ break;
// Input was invalid
case GPG_ERR_INV_VALUE:
// Fall through for any other errors
default:
- ERROR(pakfire, "Failed with gpgme error: %s\n", gpgme_strerror(error));
+ ERROR(pakfire, "Failed with gpgme error: %s\n", gpgme_strerror(e));
break;
}
-FAIL:
- gpgme_data_release(keydata);
+ // Success
+ r = 0;
- return NULL;
+ERROR:
+ gpgme_data_release(data);
+
+ // Free keys on error
+ if (r && keys && *keys) {
+ for (struct pakfire_key** key = *keys; *key; key++)
+ pakfire_key_unref(*key);
+ free(*keys);
+
+ *keys = NULL;
+ }
+
+ return r;
}
PAKFIRE_EXPORT char* pakfire_key_dump(struct pakfire_key* key) {
help=_("Algorithm to use for this key"))
key_generate.set_defaults(func=self._key_generate)
+ # import
+ key_import = key_subparsers.add_parser("import",
+ help=_("Import a key from file"))
+ key_import.add_argument("file", nargs="+", type=argparse.FileType("r"),
+ help=_("File of that key to import"))
+ key_import.set_defaults(func=self._key_import)
+
# key list
key_list = key_subparsers.add_parser("list",
help=_("List all imported keys"))
# Print the generated key
print(key)
+ def _key_import(self, p, args):
+ for file in args.file:
+ keys = p.import_key(file)
+
+ for key in keys:
+ print(key)
+
def _key_list(self, p, args):
for key in p.keys:
print(key)