Commit 1f2a2ab6 authored by Lisa's avatar Lisa
Browse files

2nd revision of akabei-key.

parent 4001892d
/*[13:31] <boom1992> shainer: okay about gpgme support: manutortosa and me basically agreed that we should handle our
* keys in a different keyring... thus: a) akabei-key should work on a specified keyring and b) akabeiclient shall read
* from that ring :)
[13:31] <boom1992> shainer: b) is easy, I will do that, can you do a)
[13:32] <boom1992> then manutortosa can adjust the chakra-signatures package, to use akabei-key in the scriptlet,
and thus keeping our keys up to date all the time? :)
[13:32] <boom1992> shainer: also, we need to trust the keys when being imported :)
[13:33] <shainer> boom1992: ok so akabei-key must add/remove/see keys from a specified keyring, say "akabei"
[13:33] <shainer> and trusting keys when imported :)
[13:33] <boom1992> yes :) keyrings are identified by a .pub file, as far as I understood it
[13:33] <boom1992> so the keyring would be in /etc/akabei.d/gpg/akabei.pub or sth like that :)
[13:33] <boom1992> we can decide on that :)
/* This file is part of the Chakra project
* Akabei-key is a tool for managing keys in the Akabei keyring
Copyright (C) 2013 Lisa Vitolo <shainer@chakra-project.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include <QCoreApplication>
#include <QStringList>
#include <QDebug>
......@@ -19,50 +17,100 @@ and thus keeping our keys up to date all the time? :)
#include <sys/stat.h>
#include <errno.h>
#include <gpgme.h>
#include <iostream>
#define IS_HELP(x) ((x) == "help" || (x) == "--help" || (x) == "-h")
#define AKABEI_KEYRING_DIR "etc/akabei.d/keyring/"
#define AKABEI_KEYRING_PUB "pubring.gpg"
#define AKABEI_KEYRING_SEC "secring.gpg"
#define AKABEI_KEYRING_TRUST "trustdb.gpg"
//#define AKABEI_KEYRING_CONF "/etc/akabei.d/keyring/gpg.conf"
/*
* import from keyserver
* help
* version
* error handling
* comments
/**
* TODO
* - comments
* - import from keyserver
* - trusting when importing
* - good error handling
* - remove useless cmake modules from directory
* - fix paths
*/
using namespace std;
void printHelp()
{
qDebug() << "print help";
QTextStream out(stdout);
out << ":: akabei-key v2.0 (Akabei)." << endl;
out << "usage: akabei-key [op] [args]" << endl;
out << endl;
out << "help, -h, --help" << endl;
out << " " << QObject::tr("prints this message") << endl;
out << "version" << endl;
out << " " << QObject::tr("prints version information") << endl;
out << "list" << endl;
out << " " << QObject::tr("list all keys in the keyring") << endl;
out << "print <ID>" << endl;
out << " " << QObject::tr("prints information about the key identified by ID") << endl;
out << "import <file>" << endl;
out << " " << QObject::tr("imports and trusts a new key from file") << endl;
out << "get <ID>" << endl;
out << " " << QObject::tr("imports the key ID from the keyserver specified in gnupg.conf") << endl;
out << "remove <ID>" << endl;
out << " " << QObject::tr("remove the key identified by ID") << endl;
}
void printVersion()
{
qDebug() << "print version";
QTextStream out(stdout);
out << QObject::tr(":: akabei-key v2.0 is part of the Akabei suite.") << endl;
}
void initRing()
void initRing(QDir& keyring)
{
const QString AkabeiKeyringPub( "pubring.gpg" );
const QString AkabeiKeyringSec( "secring.gpg" );
const QString AkabeiKeyringTrust( "trustdb.gpg" );
const QString AkabeiKeyringConf( "gpg.conf" );
QTextStream err(stderr);
QTextStream out(stdout);
QDir keyring(AKABEI_KEYRING_DIR); /* TODO: root */
keyring.mkpath(".");
if (!keyring.mkpath(".")) {
err << "ERROR: keyring " << keyring.path() << " could not be created. Check your permissions." << endl;
return;
}
QFile pub( keyring.absoluteFilePath(AKABEI_KEYRING_PUB) );
pub.open(QIODevice::ReadWrite);
QFile pub( keyring.absoluteFilePath(AkabeiKeyringPub) );
if (!pub.open(QIODevice::ReadWrite)) {
err << "ERROR: public key file " << pub.fileName() << "could not be created." << endl;
return;
}
pub.close();
QFile sec( keyring.absoluteFilePath(AKABEI_KEYRING_SEC) );
sec.open(QIODevice::ReadWrite);
QFile sec( keyring.absoluteFilePath(AkabeiKeyringSec) );
if (!sec.open(QIODevice::ReadWrite)) {
err << "ERROR: secret key file " << sec.fileName() << "could not be created." << endl;
return;
}
sec.close();
QFile trust( keyring.absoluteFilePath(AKABEI_KEYRING_TRUST) );
trust.open(QIODevice::ReadWrite);
QFile trust( keyring.absoluteFilePath(AkabeiKeyringTrust) );
if (!trust.open(QIODevice::ReadWrite)) {
err << "ERROR: trust file " << trust.fileName() << "could not be created." << endl;
return;
}
trust.close();
QFile conf( keyring.absoluteFilePath(AkabeiKeyringConf) );
if (!conf.open(QIODevice::ReadWrite)) {
err << "ERROR: configuration file " << conf.fileName() << "could not be created." << endl;
return;
}
conf.write("\n");
conf.write("###+++--- GPGConf ---+++###\n");
conf.write("utf8-strings\n");
conf.write("keyserver hkp://keys.gnupg.net");
conf.close();
}
void listKeys(gpgme_ctx_t ctx)
......@@ -72,6 +120,8 @@ void listKeys(gpgme_ctx_t ctx)
if (!err) {
err = gpgme_op_keylist_start(ctx, "", 0);
QTextStream out(stdout);
while (!err) {
err = gpgme_op_keylist_next(ctx, &key);
......@@ -79,13 +129,13 @@ void listKeys(gpgme_ctx_t ctx)
break;
}
printf("%s: %s %s\n", key->subkeys->keyid, key->uids->name, key->uids->email);
out << "- " << key->subkeys->keyid << " " << key->uids->name << " " << key->uids->email << endl;
gpgme_key_release(key);
}
}
if (gpgme_err_code(err) != GPG_ERR_EOF) {
qDebug() << "Cannot list keys" << gpgme_strerror(err);
if (gpgme_err_code(err) != GPG_ERR_EOF) {
cerr << ":: Error while listing keys" << gpgme_strerror(err) << endl;
}
}
......@@ -149,10 +199,52 @@ void removeKey(gpgme_ctx_t ctx, const QString& id)
gpgme_key_release(key);
}
void getFromServer(gpgme_ctx_t ctx, QString id)
{
gpgme_error_t err;
gpgme_key_t key;
if (!id.startsWith("0x")) {
id.prepend("0x");
}
gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(ctx);
mode &= ~GPGME_KEYLIST_MODE_LOCAL;
mode |= GPGME_KEYLIST_MODE_EXTERN;
err = gpgme_set_keylist_mode(ctx, mode);
if (err) {
qDebug() << "Cannot set new mode";
return;
}
err = gpgme_get_key(ctx, id.toUtf8().data(), &key, 0);
if (err) {
qDebug() << "Cannot get key" << id << gpgme_strerror(err);
return;
}
gpgme_key_t* keys = (gpgme_key_t *)malloc( 2 * sizeof(gpgme_key_t) );
keys[0] = key;
keys[1] = NULL;
err = gpgme_op_import_keys(ctx, keys);
free(keys);
if (err) {
qDebug() << gpgme_strerror(err);
return;
}
qDebug() << "Imported" << key->uids->name << key->uids->email << key->subkeys->keyid;
}
int main(int argc, char **argv)
{
const QString AkabeiKeyringDir( "etc/akabei.d/keyring/" );
QCoreApplication app(argc, argv);
QDir keyring(AKABEI_KEYRING_DIR);
QDir keyring(AkabeiKeyringDir);
if (!keyring.exists()) {
QTextStream out(stdout);
......@@ -161,58 +253,72 @@ int main(int argc, char **argv)
out << ":: It looks like you don't have an Akabei keyring yet." << endl;
out << ":: This application will initialize the ring before continuing normally." << endl;
out << ":: Starting initialization..." << endl;
initRing();
initRing(keyring);
}
QStringList args = QCoreApplication::arguments();
if (args.size() <= 1) {
printHelp();
} else {
QString op = args.at(1);
gpgme_ctx_t ctx;
exit(0);
}
QString op = args.at(1);
if ( IS_HELP(op) ) {
printHelp();
exit(0);
}
if (op == "version") {
printVersion();
exit(0);
}
gpgme_ctx_t ctx;
gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, AkabeiKeyringDir.toUtf8().data());
gpgme_check_version(NULL);
gpgme_error_t err = gpgme_new(&ctx);
if (err) {
qDebug() << "init error";
exit(-1);
}
if (op == "list") {
listKeys(ctx);
} else if (op == "import") {
if (args.size() < 3) {
qDebug() << "missing arg";
exit(-1);
}
gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, AKABEI_KEYRING_DIR);
gpgme_check_version(NULL);
gpgme_error_t err = gpgme_new(&ctx);
importKey(ctx, args.at(2));
} else if (op == "print") {
if (args.size() < 3) {
qDebug() << "missing arg";
exit(-1);
}
if (err) {
qDebug() << "init error";
printKeyById(ctx, args.at(2));
} else if (op == "remove") {
if (args.size() < 3) {
qDebug() << "missing arg";
exit(-1);
}
if ( IS_HELP(op) ) {
printHelp();
} else if (op == "version") {
printVersion();
} else if (op == "list") {
listKeys(ctx);
} else if (op == "import") {
if (args.size() < 3) {
qDebug() << "missing arg";
exit(-1);
}
importKey(ctx, args.at(2));
} else if (op == "print") {
if (args.size() < 3) {
qDebug() << "missing arg";
exit(-1);
}
printKeyById(ctx, args.at(2));
} else if (op == "remove") {
if (args.size() < 3) {
qDebug() << "missing arg";
exit(-1);
}
removeKey(ctx, args.at(2));
removeKey(ctx, args.at(2));
} else if (op == "get") {
if (args.size() < 3) {
qDebug() << "missing arg";
exit(-1);
}
gpgme_release(ctx);
getFromServer(ctx, args.at(2));
}
gpgme_release(ctx);
return 0;
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment