}
PyObject* new_key(PakfireObject* pakfire, PakfireKey key) {
- return Key_new_core(&KeyType, pakfire, key);
+ return Key_new_core(&KeyType, pakfire, pakfire_key_ref(key));
}
static PyObject* Key_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
static void Key_dealloc(KeyObject* self) {
if (self->key)
- pakfire_key_free(self->key);
+ pakfire_key_unref(self->key);
if (self->pakfire)
Py_DECREF(self->pakfire);
return PyUnicode_FromString(arch);
}
-static PyObject* Pakfire_get_keys(PakfireObject* self) {
+static PyObject* _import_keylist(PakfireObject* pakfire, PakfireKey* keys) {
PyObject* list = PyList_New(0);
- PakfireKey* keys = pakfire_key_list(self->pakfire);
while (keys && *keys) {
PakfireKey key = *keys++;
- PyObject* object = new_key(self, key);
+ PyObject* object = new_key(pakfire, key);
PyList_Append(list, object);
+
+ // Drop reference to the Python object
Py_DECREF(object);
- pakfire_key_free(key);
+ // Drop reference to the key object
+ pakfire_key_unref(key);
}
return list;
}
+static PyObject* Pakfire_get_keys(PakfireObject* self) {
+ PakfireKey* keys = pakfire_key_list(self->pakfire);
+
+ return _import_keylist(self, keys);
+}
+
static PyObject* Pakfire_get_key(PakfireObject* self, PyObject* args) {
const char* pattern = NULL;
return new_key(self, key);
}
+static PyObject* Pakfire_import_key(PakfireObject* self, PyObject* args) {
+ const char* data = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &data))
+ return NULL;
+
+ PakfireKey* keys = pakfire_key_import(self->pakfire, data);
+ if (!keys)
+ return NULL; // TODO Raise error from errno
+
+ return _import_keylist(self, keys);
+}
+
static struct PyMethodDef Pakfire_methods[] = {
{
"generate_key",
METH_VARARGS,
NULL
},
+ {
+ "import_key",
+ (PyCFunction)Pakfire_import_key,
+ METH_VARARGS,
+ NULL
+ },
{ NULL },
};
PAKFIRE_E_SOLV_NOT_SOLV, // SOLV file in not in SOLV format
PAKFIRE_E_SOLV_UNSUPPORTED, // SOLV file is in an unsupported format
PAKFIRE_E_SOLV_CORRUPTED, // SOLV file is corrupted
+ PAKFIRE_E_INVALID_INPUT,
};
extern __thread int pakfire_errno;
PakfireKey* pakfire_key_list(Pakfire pakfire);
PakfireKey pakfire_key_create(Pakfire pakfire, gpgme_key_t gpgkey);
-void pakfire_key_free(PakfireKey key);
+PakfireKey pakfire_key_ref(PakfireKey key);
+void pakfire_key_unref(PakfireKey key);
PakfireKey pakfire_key_get(Pakfire pakfire, const char* fingerprint);
const char* pakfire_key_get_fingerprint(PakfireKey key);
PakfireKey pakfire_key_generate(Pakfire pakfire, const char* userid);
char* pakfire_key_export(PakfireKey key, pakfire_key_export_mode_t mode);
+PakfireKey* pakfire_key_import(Pakfire pakfire, const char* data);
#ifdef PAKFIRE_PRIVATE
#include <assert.h>
#include <gpgme.h>
+#include <string.h>
+#include <pakfire/errno.h>
#include <pakfire/key.h>
#include <pakfire/pakfire.h>
#include <pakfire/util.h>
PakfireKey key = pakfire_calloc(1, sizeof(*key));
if (key) {
+ key->nrefs = 1;
key->pakfire = pakfire_ref(pakfire);
key->gpgkey = gpgkey;
return key;
}
-void pakfire_key_free(PakfireKey key) {
+static void pakfire_key_free(PakfireKey key) {
pakfire_unref(key->pakfire);
gpgme_key_unref(key->gpgkey);
pakfire_free(key);
}
+PakfireKey pakfire_key_ref(PakfireKey key) {
+ ++key->nrefs;
+
+ return key;
+}
+
+void pakfire_key_unref(PakfireKey key) {
+ if (--key->nrefs > 0)
+ return;
+
+ pakfire_key_free(key);
+}
+
PakfireKey pakfire_key_get(Pakfire pakfire, const char* fingerprint) {
gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire);
assert(gpgctx);
return NULL;
}
+
+PakfireKey* pakfire_key_import(Pakfire pakfire, const char* data) {
+ gpgme_error_t error;
+ gpgme_data_t keydata;
+
+ gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire);
+ assert(gpgctx);
+
+ // 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;
+
+ // Try importing the key(s)
+ error = gpgme_op_import(gpgctx, keydata);
+
+ gpgme_import_result_t result;
+ switch (error) {
+ // Everything went fine
+ case GPG_ERR_NO_ERROR:
+ result = gpgme_op_import_result(gpgctx);
+
+ PakfireKey* head = pakfire_calloc(result->imported + 1, sizeof(*head));
+ PakfireKey* list = head;
+
+ // Retrieve all imported keys
+ gpgme_import_status_t status = result->imports;
+ while (status) {
+ PakfireKey key = pakfire_key_get(pakfire, status->fpr);
+ if (key) {
+ // Append key to list
+ *list++ = key;
+ }
+
+ status = status->next;
+ }
+
+ // Terminate list
+ *list = NULL;
+
+ gpgme_data_release(keydata);
+ gpgme_release(gpgctx);
+
+ return head;
+
+ // Input was invalid
+ case GPG_ERR_INV_VALUE:
+ pakfire_errno = PAKFIRE_E_INVALID_INPUT;
+ break;
+
+ // Fall through for any other errors
+ default:
+ break;
+ }
+
+FAIL:
+ gpgme_data_release(keydata);
+ gpgme_release(gpgctx);
+
+ return NULL;
+}
# key
pakfire_key_create;
pakfire_key_export;
- pakfire_key_free;
pakfire_key_generate;
pakfire_key_get;
pakfire_key_get_fingerprint;
+ pakfire_key_import;
pakfire_key_list;
+ pakfire_key_ref;
+ pakfire_key_unref;
# package
pakfire_package_add_conflicts;
# Add common arguments
self._add_common_arguments(parser)
+ # export
+ export = subparsers.add_parser("export", help=_("Export a key to a file"))
+ export.add_argument("fingerprint", nargs=1,
+ help=_("The fingerprint of the key to export"))
+ export.add_argument("--filename", nargs="*", help=_("Write the key to this file"))
+ export.add_argument("--secret", action="store_true",
+ help=_("Export the secret key"))
+ export.set_defaults(func=self.handle_export)
+
+ # import
+ _import = subparsers.add_parser("import", help=_("Import a key from file"))
+ _import.add_argument("filename", nargs="+", help=_("Filename of that key to import"))
+ _import.set_defaults(func=self.handle_import)
+
# generate
generate = subparsers.add_parser("generate", help=_("Import a key from file"))
generate.add_argument("--realname", nargs=1,
list = subparsers.add_parser("list", help=_("List all imported keys"))
list.set_defaults(func=self.handle_list)
- # export
- export = subparsers.add_parser("export", help=_("Export a key to a file"))
- export.add_argument("fingerprint", nargs=1,
- help=_("The fingerprint of the key to export"))
- export.add_argument("--filename", nargs="*", help=_("Write the key to this file"))
- export.add_argument("--secret", action="store_true",
- help=_("Export the secret key"))
- export.set_defaults(func=self.handle_export)
-
return parser.parse_args()
- def parse_command_generate(self):
- # Parse "generate" command.
- sub_gen = self.sub_commands.add_parser("generate",
- help=_("Import a key from file."))
- sub_gen.add_argument("--realname", nargs=1,
- help=_("The real name of the owner of this key."))
- sub_gen.add_argument("--email", nargs=1,
- help=_("The email address of the owner of this key."))
- sub_gen.set_defaults(func=self.handle_generate)
-
- def parse_command_import(self):
- # Parse "import" command.
- sub_import = self.sub_commands.add_parser("import",
- help=_("Import a key from file."))
- sub_import.add_argument("filename", nargs=1,
- help=_("Filename of that key to import."))
- sub_import.add_argument("action", action="store_const", const="import")
-
def parse_command_delete(self):
# Parse "delete" command.
sub_del = self.sub_commands.add_parser("delete",
else:
print(data)
- def handle_import(self):
- filename = self.args.filename[0]
+ def handle_import(self, ns):
+ p = self.pakfire(ns)
- # Simply import the file.
- p = self.create_pakfire()
- p.keyring.import_key(filename)
+ for filename in ns.filename:
+ with open(filename) as f:
+ data = f.read()
+
+ key = p.import_key(data)
+ print(key)
def handle_delete(self):
keyid = self.args.keyid[0]