From 5c13538e6b71cc0d1f5fe49017a99dceecfd007a Mon Sep 17 00:00:00 2001 From: James Booth Date: Sat, 11 Jan 2014 15:48:22 +0000 Subject: Load OTR private key on connect, gen command checks if already generated --- src/command/commands.c | 2 +- src/otr.c | 120 +++++++++++++++++++++++++++++++++++++++---------- src/otr.h | 4 +- src/server_events.c | 1 + 4 files changed, 102 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/command/commands.c b/src/command/commands.c index cb38d934..649c084e 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2294,7 +2294,7 @@ cmd_otr(gchar **args, struct cmd_help_t help) if (strcmp(args[0], "gen") == 0) { ProfAccount *account = accounts_get_account(jabber_get_account_name()); - otr_account_load(account); + otr_keygen(account); return TRUE; } else if (strcmp(args[0], "fp") == 0) { char *fingerprint = otr_get_fingerprint(); diff --git a/src/otr.c b/src/otr.c index cb72b777..b5be978d 100644 --- a/src/otr.c +++ b/src/otr.c @@ -26,11 +26,13 @@ #include #include "otr.h" +#include "log.h" #include "ui/ui.h" static OtrlUserState user_state; static OtrlMessageAppOps ops; static char *jid; +static gboolean data_loaded; // ops callbacks static OtrlPolicy @@ -141,7 +143,7 @@ cb_log_message(void *opdata, const char *message) void otr_init(void) { - cons_debug("otr_init()"); + log_info("Initialising OTR"); OTRL_INIT; ops.policy = cb_policy; @@ -159,14 +161,15 @@ otr_init(void) ops.gone_insecure = cb_gone_insecure; ops.still_secure = cb_still_secure; ops.log_message = cb_log_message; + + data_loaded = FALSE; } void -otr_account_load(ProfAccount *account) +otr_on_connect(ProfAccount *account) { - cons_debug("otr_account_load()"); - jid = strdup(account->jid); + log_info("Loading OTR key for %s", jid); gchar *data_home = xdg_get_data_home(); gchar *account_dir = str_replace(jid, "@", "_at_"); @@ -178,7 +181,8 @@ otr_account_load(ProfAccount *account) if (!mkdir_recursive(basedir->str)) { g_string_free(basedir, TRUE); - cons_show_error("Could not create otr directory for account %s.", jid); + log_error("Could not create %s for account %s.", basedir->str, jid); + cons_show_error("Could not create %s for account %s.", basedir->str, jid); return; } @@ -189,54 +193,124 @@ otr_account_load(ProfAccount *account) GString *keysfilename = g_string_new(basedir->str); g_string_append(keysfilename, "keys.txt"); if (!g_file_test(keysfilename->str, G_FILE_TEST_IS_REGULAR)) { - cons_debug("Private key not found, generating one"); - err = otrl_privkey_generate(user_state, keysfilename->str, account->jid, "xmpp"); + log_info("No private key file found %s", keysfilename->str); + data_loaded = FALSE; + } else { + log_info("Loading OTR private key %s", keysfilename->str); + err = otrl_privkey_read(user_state, keysfilename->str); if (!err == GPG_ERR_NO_ERROR) { g_string_free(basedir, TRUE); g_string_free(keysfilename, TRUE); - cons_debug("Failed to generate private key"); + log_error("Failed to load private key"); return; + } else { + log_info("Loaded private key"); + data_loaded = TRUE; } - cons_debug("Generated private key"); } GString *fpsfilename = g_string_new(basedir->str); g_string_append(fpsfilename, "fingerprints.txt"); if (!g_file_test(fpsfilename->str, G_FILE_TEST_IS_REGULAR)) { - cons_debug("Fingerprints not found, creating file"); - err = otrl_privkey_write_fingerprints(user_state, fpsfilename->str); + log_info("No fingerprints file found %s", fpsfilename->str); + data_loaded = FALSE; + } else { + log_info("Loading fingerprints %s", fpsfilename->str); + err = otrl_privkey_read_fingerprints(user_state, fpsfilename->str, NULL, NULL); if (!err == GPG_ERR_NO_ERROR) { g_string_free(basedir, TRUE); g_string_free(keysfilename, TRUE); - cons_debug("Failed to create fingerprints file"); + log_error("Failed to load fingerprints"); return; + } else { + log_info("Loaded fingerprints"); + data_loaded = TRUE; } - cons_debug("Created fingerprints file"); } - cons_debug("Loading private key"); + g_string_free(basedir, TRUE); + g_string_free(keysfilename, TRUE); + g_string_free(fpsfilename, TRUE); + return; +} + +void +otr_keygen(ProfAccount *account) +{ + if (data_loaded) { + cons_show("OTR key already generated."); + return; + } + + jid = strdup(account->jid); + log_info("Generating OTR key for %s", jid); + + jid = strdup(account->jid); + + gchar *data_home = xdg_get_data_home(); + gchar *account_dir = str_replace(jid, "@", "_at_"); + + GString *basedir = g_string_new(data_home); + g_string_append(basedir, "/profanity/otr/"); + g_string_append(basedir, account_dir); + g_string_append(basedir, "/"); + + if (!mkdir_recursive(basedir->str)) { + g_string_free(basedir, TRUE); + log_error("Could not create %s for account %s.", basedir->str, jid); + cons_show_error("Could not create %s for account %s.", basedir->str, jid); + return; + } + + gcry_error_t err = 0; + + GString *keysfilename = g_string_new(basedir->str); + g_string_append(keysfilename, "keys.txt"); + log_debug("Generating private key file %s for %s", keysfilename->str, jid); + cons_show("Generating private key, this may take some time."); + cons_show("Moving the mouse randomly around the screen may speed up the process!"); + ui_current_page_off(); + ui_refresh(); + err = otrl_privkey_generate(user_state, keysfilename->str, account->jid, "xmpp"); + if (!err == GPG_ERR_NO_ERROR) { + g_string_free(basedir, TRUE); + g_string_free(keysfilename, TRUE); + log_error("Failed to generate private key"); + cons_show_error("Failed to generate private key"); + return; + } + log_info("Private key generated"); + cons_show(""); + cons_show("Private key generation complete."); + + GString *fpsfilename = g_string_new(basedir->str); + g_string_append(fpsfilename, "fingerprints.txt"); + log_debug("Generating fingerprints file %s for %s", fpsfilename->str, jid); + err = otrl_privkey_write_fingerprints(user_state, fpsfilename->str); + if (!err == GPG_ERR_NO_ERROR) { + g_string_free(basedir, TRUE); + g_string_free(keysfilename, TRUE); + log_error("Failed to create fingerprints file"); + cons_show_error("Failed to create fingerprints file"); + return; + } + log_info("Fingerprints file created"); + err = otrl_privkey_read(user_state, keysfilename->str); if (!err == GPG_ERR_NO_ERROR) { g_string_free(basedir, TRUE); g_string_free(keysfilename, TRUE); - cons_debug("Failed to load private key"); + log_error("Failed to load private key"); return; } - cons_debug("Loaded private key"); - cons_debug("Loading fingerprints"); err = otrl_privkey_read_fingerprints(user_state, fpsfilename->str, NULL, NULL); if (!err == GPG_ERR_NO_ERROR) { g_string_free(basedir, TRUE); g_string_free(keysfilename, TRUE); - cons_debug("Failed to load fingerprints"); + log_error("Failed to load fingerprints"); return; } - cons_debug("Loaded fingerprints"); - - char fingerprint[45]; - otrl_privkey_fingerprint(user_state, fingerprint, jid, "xmpp"); - cons_debug("Your fingerprint: %s", fingerprint); g_string_free(basedir, TRUE); g_string_free(keysfilename, TRUE); diff --git a/src/otr.h b/src/otr.h index c96290c2..924a18f6 100644 --- a/src/otr.h +++ b/src/otr.h @@ -26,7 +26,9 @@ #include "config/accounts.h" void otr_init(void); -void otr_account_load(ProfAccount *account); +void otr_on_connect(ProfAccount *account); +void otr_keygen(ProfAccount *account); + char * otr_get_fingerprint(void); char * otr_encrypt_message(const char * const to, const char * const message); diff --git a/src/server_events.c b/src/server_events.c index 48dae2ea..e83fbf27 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -49,6 +49,7 @@ void handle_login_account_success(char *account_name) { ProfAccount *account = accounts_get_account(account_name); + otr_on_connect(account); resource_presence_t resource_presence = accounts_get_login_presence(account->name); contact_presence_t contact_presence = contact_presence_from_resource_presence(resource_presence); cons_show_login_success(account); -- cgit 1.4.1-2-gfad0