Ejemplo n.º 1
0
static void
_otr_on_connect(ProfAccount *account)
{
    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_");

    GString *basedir = g_string_new(data_home);
    g_string_append(basedir, "/profanity/otr/");
    g_string_append(basedir, account_dir);
    g_string_append(basedir, "/");
    free(account_dir);

    if (!mkdir_recursive(basedir->str)) {
        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);
        g_string_free(basedir, TRUE);
        return;
    }

    user_state = otrl_userstate_create();

    gcry_error_t err = 0;

    GString *keysfilename = g_string_new(basedir->str);
    g_string_append(keysfilename, "keys.txt");
    if (!g_file_test(keysfilename->str, G_FILE_TEST_IS_REGULAR)) {
        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);
            log_error("Failed to load private key");
            return;
        } else {
            log_info("Loaded private key");
            data_loaded = TRUE;
        }
    }

    GString *fpsfilename = g_string_new(basedir->str);
    g_string_append(fpsfilename, "fingerprints.txt");
    if (!g_file_test(fpsfilename->str, G_FILE_TEST_IS_REGULAR)) {
        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);
            g_string_free(fpsfilename, TRUE);
            log_error("Failed to load fingerprints");
            return;
        } else {
            log_info("Loaded fingerprints");
            data_loaded = TRUE;
        }
    }

    if (data_loaded) {
        cons_show("Loaded OTR private key for %s", jid);
    }

    g_string_free(basedir, TRUE);
    g_string_free(keysfilename, TRUE);
    g_string_free(fpsfilename, TRUE);
    return;
}
Ejemplo n.º 2
0
static 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, "/");
    free(account_dir);

    if (!mkdir_recursive(basedir->str)) {
        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);
        g_string_free(basedir, TRUE);
        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_update_screen();
    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);
        log_error("Failed to load private key");
        data_loaded = FALSE;
        return;
    }

    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);
        log_error("Failed to load fingerprints");
        data_loaded = FALSE;
        return;
    }

    data_loaded = TRUE;

    g_string_free(basedir, TRUE);
    g_string_free(keysfilename, TRUE);
    g_string_free(fpsfilename, TRUE);
    return;
}
Ejemplo n.º 3
0
void
p_gpg_on_connect(const char *const barejid)
{
    gchar *data_home = xdg_get_data_home();
    GString *pubsfile = g_string_new(data_home);
    free(data_home);

    gchar *account_dir = str_replace(barejid, "@", "_at_");
    g_string_append(pubsfile, "/profanity/pgp/");
    g_string_append(pubsfile, account_dir);
    free(account_dir);

    // mkdir if doesn't exist for account
    errno = 0;
    int res = g_mkdir_with_parents(pubsfile->str, S_IRWXU);
    if (res == -1) {
        char *errmsg = strerror(errno);
        if (errmsg) {
            log_error("Error creating directory: %s, %s", pubsfile->str, errmsg);
        } else {
            log_error("Error creating directory: %s", pubsfile->str);
        }
    }

    // create or read publickeys
    g_string_append(pubsfile, "/pubkeys");
    pubsloc = pubsfile->str;
    g_string_free(pubsfile, FALSE);

    if (g_file_test(pubsloc, G_FILE_TEST_EXISTS)) {
        g_chmod(pubsloc, S_IRUSR | S_IWUSR);
    }

    pubkeyfile = g_key_file_new();
    g_key_file_load_from_file(pubkeyfile, pubsloc, G_KEY_FILE_KEEP_COMMENTS, NULL);

    // load each keyid
    gsize len = 0;
    gchar **jids = g_key_file_get_groups(pubkeyfile, &len);

    gpgme_ctx_t ctx;
    gpgme_error_t error = gpgme_new(&ctx);

    if (error) {
        log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error));
        g_strfreev(jids);
        return;
    }

    int i = 0;
    for (i = 0; i < len; i++) {
        GError *gerr = NULL;
        gchar *jid = jids[i];
        gchar *keyid = g_key_file_get_string(pubkeyfile, jid, "keyid", &gerr);
        if (gerr) {
            log_error("Error loading PGP key id for %s", jid);
            g_error_free(gerr);
            g_free(keyid);
        } else {
            gpgme_key_t key = NULL;
            error = gpgme_get_key(ctx, keyid, &key, 0);
            if (error || key == NULL) {
                log_warning("GPG: Failed to get key for %s: %s %s", jid, gpgme_strsource(error), gpgme_strerror(error));
                continue;
            }

            ProfPGPPubKeyId *pubkeyid = malloc(sizeof(ProfPGPPubKeyId));
            pubkeyid->id = strdup(keyid);
            pubkeyid->received = FALSE;
            g_hash_table_replace(pubkeys, strdup(jid), pubkeyid);
            g_free(keyid);
            gpgme_key_unref(key);
        }
    }

    gpgme_release(ctx);
    g_strfreev(jids);

    _save_pubkeys();
}