diff --git a/.gitignore b/.gitignore index f398a12..b475913 100644 --- a/.gitignore +++ b/.gitignore @@ -107,11 +107,11 @@ dkms.conf build-aux/ libtool -src/.deps/ -src/.dirstamp +.deps +.dirstamp src/config.h src/config.h.in src/stamp-h1 -xmppc +xmppc doc/doxygen/ diff --git a/changelog b/changelog index 981159e..cac5719 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,22 @@ +2020-04-21 DebXWoody + + Release 0.0.4 + * Config file for accounts + * Changed output format of omemo list to URL format + * Bugfixes for OpenPGP / PGP Key lookup + +2020-04-19 DebXWoody + + Release 0.0.3-1 + * Moved xmppc to Anoxinon Repository + * 5b81fbb5862be7e1edeed32bbf5a72982cbac5d3 + +2020-04-18 DebXWoody + + Release 0.0.3 + * Implementation for XEP-0373: OpenPGP for XMPP. + * Module for XMPP Monitoring + 2020-04-10 DebXWoody Release 0.0.2 diff --git a/src/main.c b/src/main.c index dcae03e..b379e44 100644 --- a/src/main.c +++ b/src/main.c @@ -310,12 +310,14 @@ int main(int argc, char *argv[]) { xmppc_mode_t mode = UNKOWN; char *jid = NULL; char *pwd = NULL; + char *account = NULL; static struct option long_options[] = { /* These options set a flag. */ {"verbose", no_argument, &verbose_flag, 1}, {"help", no_argument, 0, 'h'}, {"config", required_argument, 0, 'c'}, + {"account", required_argument, 0, 'a'}, {"jid", required_argument, 0, 'j'}, {"pwd", required_argument, 0, 'p'}, {"mode", required_argument, 0, 'm'}, @@ -324,7 +326,7 @@ int main(int argc, char *argv[]) { while (c > -1) { int option_index = 0; - c = getopt_long(argc, argv, "hvj:p:m:", long_options, &option_index); + c = getopt_long(argc, argv, "hva:j:p:m:", long_options, &option_index); if (c > -1) { switch (c) { case 'h': @@ -339,6 +341,11 @@ int main(int argc, char *argv[]) { printf("option -f with value `%s'\n", optarg); break; + case 'a': + account = malloc(strlen(optarg) + 1); + strcpy(account, optarg); + break; + case 'j': jid = malloc(strlen(optarg) + 1); strcpy(jid, optarg); @@ -390,8 +397,11 @@ int main(int argc, char *argv[]) { } else { if(jid == NULL && pwd == NULL) { logInfo(&xmppc,"Loading default account\n"); - jid = g_key_file_get_value (config_file, "default", "jid" ,&error); - pwd = g_key_file_get_value (config_file, "default", "pwd" ,&error); + if( account == NULL ) { + account = "default"; + } + jid = g_key_file_get_value (config_file, account, "jid" ,&error); + pwd = g_key_file_get_value (config_file, account, "pwd" ,&error); } } @@ -434,12 +444,13 @@ static void _show_help() { #else printf("%s\n", PACKAGE_STRING); #endif - printf("Usage: xmppc --jid --pwd --mode \n"); + printf("Usage: xmppc --account --jid --pwd --mode \n"); printf("Options:\n"); - printf(" -h / --help Display this information.\n"); - printf(" -j / --jid Jabber ID\n"); - printf(" -p / --pwd Passwort\n"); - printf(" -m / --mode xmppc mode\n"); + printf(" -h / --help Display this information.\n"); + printf(" -j / --jid Jabber ID\n"); + printf(" -p / --pwd Passwort\n"); + printf(" -a / --account Passwort\n"); + printf(" -m / --mode xmppc mode\n"); printf("\n"); printf("Modes:\n"); printf(" -m --mode roster xmppc roster mode\n"); diff --git a/src/mode/monitor.c b/src/mode/monitor.c index f45541c..4f86e2f 100644 --- a/src/mode/monitor.c +++ b/src/mode/monitor.c @@ -44,7 +44,6 @@ #include "stdio.h" #include "string.h" - static int _monitor_log_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static int _monitor_show_microblog(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); @@ -98,11 +97,7 @@ int _monitor_log_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, vo } /* XEP-0277: Microblogging over XMPP */ - int _monitor_show_microblog(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata){ - - - xmpp_stanza_t *log = stanza; if(strcmp(xmpp_stanza_get_name(stanza), "message") == 0 ) { xmpp_stanza_t* event = xmpp_stanza_get_child_by_name(stanza, "event"); diff --git a/src/mode/openpgp.c b/src/mode/openpgp.c index ac7ede8..d4a51d0 100644 --- a/src/mode/openpgp.c +++ b/src/mode/openpgp.c @@ -81,6 +81,10 @@ void _openpgp_send_text(xmppc_t *xmppc, char* to, char* text) { size_t s; xmpp_stanza_to_text(signcrypt, &c,&s); char* signcrypt_e = _openpgp_gpg_signcrypt(xmppc,to, c); + if( signcrypt_e == NULL ) { + logError(xmppc, "Message not signcrypted.\n"); + return; + } // BASE64_OPENPGP_MESSAGE xmpp_stanza_t* base64_openpgp_message = xmpp_stanza_new(xmppc->ctx); xmpp_stanza_set_text(base64_openpgp_message,signcrypt_e); @@ -99,8 +103,6 @@ xmpp_stanza_t* _openpgp_signcrypt(xmppc_t *xmppc, char* to, char* text) { struct tm* tm = localtime(&now); char buf[255]; strftime(buf, sizeof(buf), "%FT%T%z", tm); - printf("%s\n",buf); - int randnr = rand() % 5; char rpad_data[randnr]; for(int i = 0; i < randnr-1; i++) { @@ -108,26 +110,32 @@ xmpp_stanza_t* _openpgp_signcrypt(xmppc_t *xmppc, char* to, char* text) { } rpad_data[randnr-1] = '\0'; - + // signcrypt xmpp_stanza_t *signcrypt = xmpp_stanza_new(xmppc->ctx); xmpp_stanza_set_name(signcrypt, "signcrypt"); xmpp_stanza_set_ns(signcrypt, "urn:xmpp:openpgp:0"); + // to xmpp_stanza_t *s_to = xmpp_stanza_new(xmppc->ctx); xmpp_stanza_set_name(s_to, "to"); xmpp_stanza_set_attribute(s_to, "jid", to); + // time xmpp_stanza_t *time = xmpp_stanza_new(xmppc->ctx); xmpp_stanza_set_name(time, "time"); xmpp_stanza_set_attribute(time, "stamp", buf); xmpp_stanza_set_name(time, "time"); + // rpad xmpp_stanza_t *rpad = xmpp_stanza_new(xmppc->ctx); xmpp_stanza_set_name(rpad, "rpad"); xmpp_stanza_t *rpad_text = xmpp_stanza_new(xmppc->ctx); xmpp_stanza_set_text(rpad_text, rpad_data); + // payload xmpp_stanza_t *payload= xmpp_stanza_new(xmppc->ctx); xmpp_stanza_set_name(payload, "payload"); + // body xmpp_stanza_t *body = xmpp_stanza_new(xmppc->ctx); xmpp_stanza_set_name(body, "body"); xmpp_stanza_set_ns(body, "jabber:client"); + // text xmpp_stanza_t *body_text = xmpp_stanza_new(xmppc->ctx); xmpp_stanza_set_text(body_text, text); xmpp_stanza_add_child(signcrypt,s_to); @@ -137,8 +145,8 @@ xmpp_stanza_t* _openpgp_signcrypt(xmppc_t *xmppc, char* to, char* text) { xmpp_stanza_add_child(signcrypt,payload); xmpp_stanza_add_child(payload, body); xmpp_stanza_add_child(body, body_text); - return signcrypt; + return signcrypt; } char* _openpgp_gpg_signcrypt(xmppc_t *xmppc, char* recipient, char* message) { @@ -176,14 +184,18 @@ char* _openpgp_gpg_signcrypt(xmppc_t *xmppc, char* recipient, char* message) { strcat(xmpp_jid_me, jid); strcat(xmpp_jid_recipient,recipient); + // lookup own key error = _openpgp_lookup_key(xmppc,xmpp_jid_me, &ctx, &recp[0]); if(error != 0) { - logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + logError(xmppc,"Key not found for %s. GpgME Error: %s\n", xmpp_jid_me, gpgme_strerror(error)); + return NULL; } + // lookup key of recipient error = _openpgp_lookup_key(xmppc,xmpp_jid_recipient, &ctx, &recp[1]); if(error != 0) { - logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + logError(xmppc,"Key not found for %s. GpgME Error: %s\n", xmpp_jid_recipient, gpgme_strerror(error)); + return NULL; } recp[2] = NULL; logInfo(xmppc, "%s <%s>\n", recp[0]->uids->name, recp[0]->uids->email); @@ -201,20 +213,24 @@ char* _openpgp_gpg_signcrypt(xmppc_t *xmppc, char* recipient, char* message) { error = gpgme_data_new (&plain); if(error != 0) { logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + return NULL; } error = gpgme_data_new_from_mem(&plain, message, strlen(message),0); if(error != 0) { logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + return NULL; } error = gpgme_data_new (&cipher); if(error != 0) { logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + return NULL; } error = gpgme_op_encrypt_sign ( ctx, recp, flags, plain, cipher); if(error != 0) { logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + return NULL; } size_t len; @@ -231,11 +247,9 @@ gpgme_error_t _openpgp_lookup_key(xmppc_t *xmppc,char* name, gpgme_ctx_t* ctx, g gpgme_error_t error = gpgme_op_keylist_start (*ctx, NULL, 0); while (!error) { error = gpgme_op_keylist_next (*ctx, key); - if(strcmp((*key)->uids->name, name) == 0) { + if(error == 0 && strcmp((*key)->uids->name, name) == 0) { logDebug(xmppc, "Key found: %s ...\n", (*key)->uids->name); - return error; - } - else { + } else { gpgme_key_release((*key)); } } diff --git a/src/mode/pgp.c b/src/mode/pgp.c index aa29bcf..105a550 100644 --- a/src/mode/pgp.c +++ b/src/mode/pgp.c @@ -49,7 +49,6 @@ #include #include - #define PGP_BEGIN "-----BEGIN PGP MESSAGE-----" #define PGP_END "-----END PGP MESSAGE-----" @@ -81,7 +80,8 @@ void _pgp_send_text(xmppc_t *xmppc, char* to, char* text) { xmpp_stanza_set_ns(x, "jabber:x:encrypted"); xmpp_stanza_t *b = xmpp_stanza_new(xmppc->ctx); char* encrypt_text = _pgp_encrypt_message(xmppc, to,text); - if(text == NULL) { + if(encrypt_text == NULL) { + logError(xmppc,"Encrypting of message failed.\n"); return; } xmpp_stanza_set_text(b,encrypt_text); @@ -107,15 +107,32 @@ char* _pgp_encrypt_message(xmppc_t *xmppc, char* recipient, char* message) { return NULL; } error = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OPENPGP); + if(error != 0) { + logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + } gpgme_set_armor(ctx,1); gpgme_set_textmode(ctx,1); gpgme_set_offline(ctx,1); gpgme_set_keylist_mode(ctx, GPGME_KEYLIST_MODE_LOCAL); gpgme_key_t recp[3]; + + // Key for sender const char *jid = xmpp_conn_get_jid(xmppc->conn); + logInfo(xmppc, "Looking up pgp key for %s\n", jid); error = gpgme_get_key(ctx, jid, &(recp[0]), 0); + if(error != 0) { + logError(xmppc,"Public key not found for %s. GpgME Error: %s\n", jid, gpgme_strerror(error)); + return NULL; + } + + // Key for recipient + logInfo(xmppc, "Looking up pgp key for %s\n", recipient); error = gpgme_get_key(ctx, recipient, &(recp[1]), 0); + if(error != 0) { + logError(xmppc,"Key not found for %s. GpgME Error: %s\n", recipient, gpgme_strerror(error)); + return NULL; + } recp[2] = NULL; logInfo(xmppc, "%s <%s>\n", recp[0]->uids->name, recp[0]->uids->email); @@ -126,11 +143,23 @@ char* _pgp_encrypt_message(xmppc_t *xmppc, char* recipient, char* message) { gpgme_data_t cipher; error = gpgme_data_new (&plain); + if(error != 0) { + logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + } error = gpgme_data_new_from_mem(&plain, message, strlen(message),0); + if(error != 0) { + logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + } error = gpgme_data_new (&cipher); + if(error != 0) { + logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + } error = gpgme_op_encrypt ( ctx, recp, flags, plain, cipher); + if(error != 0) { + logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error)); + } size_t len; char *cipher_str = gpgme_data_release_and_get_mem(cipher, &len); char* result = NULL;