/**
 * Delete the private key for a account.
 */
void OtrConnection::deletePrivateKey(QString account) {
	OtrlPrivKey* key = otrl_privkey_find(userstate, account.toStdString().c_str(),
		protocolString);
	if (key != NULL) {
		otrl_privkey_forget(key);
	}
	//TODO: write changed otr.keys
}
void OtrInternal::deleteKey(const QString& account)
{
    OtrlPrivKey* privKey = otrl_privkey_find(m_userstate,
                                             account.toUtf8().constData(),
                                             OTR_PROTOCOL_STRING);

    otrl_privkey_forget(privKey);

    otrl_privkey_write(m_userstate, QFile::encodeName(m_keysFile).constData());
}
Exemplo n.º 3
0
gcry_error_t jsapi_privkey_delete(OtrlUserState us, const char *filename,
	const char *accountname, const char *protocol)
{
    gcry_error_t err = GPG_ERR_NO_ERROR;

    /* remove key from userstate */
    OtrlPrivKey* existing_key = otrl_privkey_find(us,accountname,protocol);
    if( existing_key ){
        otrl_privkey_forget(existing_key);
        err = jsapi_userstate_write_to_file(us, filename);//write out the changes
    }
    return err;

}
Exemplo n.º 4
0
/* Calculate a raw hash of our DSA public key.  Return it in the passed
 * fingerprint buffer.  Return NULL on error, or a pointer to the given
 * buffer on success. */
unsigned char *otrl_privkey_fingerprint_raw(OtrlUserState us,
	unsigned char hash[20], const char *accountname, const char *protocol)
{
    OtrlPrivKey *p = otrl_privkey_find(us, accountname, protocol);

    if (p) {
	/* Calculate the hash */
	gcry_md_hash_buffer(GCRY_MD_SHA1, hash, p->pubkey_data,
		p->pubkey_datalen);
    } else {
	return NULL;
    }

    return hash;
}
void OtrInternal::startSession(const QString& account, const QString& contact)
{
    m_callback->stateChange(account, contact, psiotr::OTR_STATECHANGE_GOINGSECURE);

    if (!otrl_privkey_find(m_userstate, account.toUtf8().constData(),
                           OTR_PROTOCOL_STRING))
    {
        create_privkey(account.toUtf8().constData(), OTR_PROTOCOL_STRING);
    }

    //TODO: make allowed otr versions configureable
    char* msg = otrl_proto_default_query_msg(m_callback->humanAccountPublic(account).toUtf8().constData(),
                                             OTRL_POLICY_DEFAULT);

    m_callback->sendMessage(account, contact, QString::fromUtf8(msg));

    free(msg);
}
Exemplo n.º 6
0
/* Calculate a human-readable hash of our DSA public key.  Return it in
 * the passed fingerprint buffer.  Return NULL on error, or a pointer to
 * the given buffer on success. */
char *otrl_privkey_fingerprint(OtrlUserState us, char fingerprint[45],
	const char *accountname, const char *protocol)
{
    unsigned char hash[20];
    OtrlPrivKey *p = otrl_privkey_find(us, accountname, protocol);

    if (p) {
	/* Calculate the hash */
	gcry_md_hash_buffer(GCRY_MD_SHA1, hash, p->pubkey_data,
		p->pubkey_datalen);

	/* Now convert it to a human-readable format */
	otrl_privkey_hash_to_human(fingerprint, hash);
    } else {
	return NULL;
    }

    return fingerprint;
}
Exemplo n.º 7
0
static INT_PTR CALLBACK DlgProcMirOTROptsProto(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HWND lv = GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS);
	int sel;

	switch (msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		{
			HWND cmb = GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY);
			SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_DEFAULT));
			SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_ALWAYS));
			SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_OPP));
			SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_MANUAL));
			SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_POLICY_NEVER));
			SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_SETCURSEL, (LPARAM)-1, 0);
			EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY), FALSE);
			EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_NEWKEY), FALSE);
			EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_FORGET), FALSE);
		}

		SendMessage(lv, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);// | LVS_EX_CHECKBOXES);
		{
			// add list columns
			LVCOLUMN lvc;
			// Initialize the LVCOLUMN structure.
			// The mask specifies that the format, width, text, and
			// subitem members of the structure are valid.
			lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
			lvc.fmt = LVCFMT_LEFT;

			lvc.iSubItem = 0;
			lvc.pszText = TranslateT(LANG_PROTO);
			lvc.cx = 85;     // width of column in pixels
			ListView_InsertColumn(lv, 0, &lvc);

			lvc.iSubItem = 1;
			lvc.pszText = TranslateT(LANG_POLICY);
			lvc.cx = 80;     // width of column in pixels
			ListView_InsertColumn(lv, 1, &lvc);

			lvc.iSubItem = 2;
			lvc.pszText = TranslateT(LANG_FINGERPRINT);
			lvc.cx = 275;     // width of column in pixels
			ListView_InsertColumn(lv, 2, &lvc);
		}
		PostMessage(hwndDlg, WMU_REFRESHPROTOLIST, 0, 0);
		return TRUE;

	case WMU_REFRESHPROTOLIST:
		ListView_DeleteAllItems(lv);
		{
			LV_ITEM item = { 0 };

			int num_protocols;
			PROTOACCOUNT **pppDesc;
			Proto_EnumAccounts(&num_protocols, &pppDesc);
			for (int i = 0; i < num_protocols; i++) {
				if (!mir_strcmp(pppDesc[i]->szModuleName, META_PROTO))
					continue;
				if ((CallProtoService(pppDesc[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IM) == 0)
					continue;

				item.mask = LVIF_TEXT | LVIF_PARAM;
				item.pszText = pppDesc[i]->tszAccountName;
				item.lParam = (LPARAM)pppDesc[i]->szModuleName;
				int ilvItem = ListView_InsertItem(lv, &item);

				ListView_SetItemText(lv, ilvItem, 1, (TCHAR*)policy_to_string(db_get_dw(0, MODULENAME"_ProtoPol", pppDesc[i]->szModuleName, CONTACT_DEFAULT_POLICY)));

				char fprint[45];
				if (otrl_privkey_fingerprint(otr_user_state, fprint, pppDesc[i]->szModuleName, pppDesc[i]->szModuleName)) {
					TCHAR *temp = mir_a2t(fprint);
					ListView_SetItemText(lv, ilvItem, 2, temp);
					mir_free(temp);
				}
			}
		}
		return TRUE;

	case WM_COMMAND:
		switch (HIWORD(wParam)) {
		case BN_CLICKED:
			switch (LOWORD(wParam)) {
			case IDC_BTN_PROTO_NEWKEY:
				sel = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS));
				if (sel != -1) {
					PROTOREGENKEYOPTIONS *opts = new PROTOREGENKEYOPTIONS();
					opts->refresh = hwndDlg;
					ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS), sel, 0, opts->proto, _countof(opts->proto));
					CloseHandle((HANDLE)_beginthreadex(0, 0, regen_key_thread, opts, 0, 0));
				}
				break;
			
			case IDC_BTN_PROTO_FORGET:
				sel = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS));
				if (sel != -1) {
					TCHAR buff_proto[128];
					ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS), sel, 0, buff_proto, _countof(buff_proto));
					TCHAR buff[512];
					mir_sntprintf(buff, TranslateT(LANG_OTR_ASK_REMOVEKEY), buff_proto);
					if (IDYES == MessageBox(hwndDlg, buff, TranslateT(LANG_OTR_INFO), MB_ICONQUESTION | MB_YESNO)) {
						char *proto = GetProtoName(lv, sel);
						if (proto == NULL)
							break;

						OtrlPrivKey *key = otrl_privkey_find(otr_user_state, proto, proto);
						if (key) {
							otrl_privkey_forget(key);
							otrl_privkey_write(otr_user_state, _T2A(g_private_key_filename));
							ListView_SetItemText(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS), sel, 2, _T(""));
						}
					}
				}
			}
			break;

		case CBN_SELCHANGE:
			switch (LOWORD(wParam)) {
			case IDC_CMB_PROTO_POLICY:
				int proto = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS));
				if (proto == -1) break;
				int sel = SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_GETCURSEL, 0, 0);
				if (sel == CB_ERR) break;
				int len = SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_GETLBTEXTLEN, sel, 0);
				if (len < 0) break;
				TCHAR *text = new TCHAR[len + 1];
				SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_GETLBTEXT, sel, (LPARAM)text);
				ListView_SetItemText(GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS), proto, 1, text);
				delete[] text;
				SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
			}
			break;
		}
		break;

	case WM_NOTIFY:
		if (((LPNMHDR)lParam)->code == LVN_ITEMCHANGED && ((LPNMHDR)lParam)->hwndFrom == lv) {
			LPNMLISTVIEW notif = (LPNMLISTVIEW)lParam;
			if ((notif->uNewState & LVIS_SELECTED) == 0)
				break;

			if (notif->iItem == -1) {
				SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_SETCURSEL, (LPARAM)-1, 0);
				EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY), FALSE);
				EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_NEWKEY), FALSE);
				EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_FORGET), FALSE);
			}
			else {
				EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY), TRUE);
				EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_NEWKEY), TRUE);
				EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_FORGET), TRUE);
				TCHAR buff[50];
				ListView_GetItemText(((LPNMHDR)lParam)->hwndFrom, notif->iItem, 1, buff, _countof(buff));
				SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_SELECTSTRING, (LPARAM)-1, (WPARAM)buff);
			}
		}
		else if (((LPNMHDR)lParam)->code == PSN_APPLY) {
			int cnt = ListView_GetItemCount(lv);
			TCHAR policy[64];
			for (int i = 0; i < cnt; ++i) {
				char *proto = GetProtoName(lv, i);
				if (proto == NULL)
					continue;

				ListView_GetItemText(lv, i, 1, policy, _countof(policy));
				db_set_dw(0, MODULENAME"_ProtoPol", proto, policy_from_string(policy));
			}
			// handle apply
			return TRUE;
		}
		break;
	}
	return FALSE;
}
Exemplo n.º 8
0
void
otr_on_connect(ProfAccount *account)
{
    if (jid) {
        free(jid);
    }
    jid = strdup(account->jid);
    log_info("Loading OTR key for %s", jid);

    gchar *data_home = xdg_get_data_home();
    GString *basedir = g_string_new(data_home);
    free(data_home);

    gchar *account_dir = str_replace(jid, "@", "_at_");
    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 OTR 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) {
            log_warning("Failed to read OTR private key file: %s", keysfilename->str);
            cons_show_error("Failed to read OTR private key file: %s", keysfilename->str);
            g_string_free(basedir, TRUE);
            g_string_free(keysfilename, TRUE);
            return;
        }

        OtrlPrivKey* privkey = otrl_privkey_find(user_state, jid, "xmpp");
        if (!privkey) {
            log_warning("No OTR private key found for account \"%s\", protocol \"xmpp\" in file: %s", jid, keysfilename->str);
            cons_show_error("No OTR private key found for account \"%s\", protocol \"xmpp\" in file: %s", jid, keysfilename->str);
            g_string_free(basedir, TRUE);
            g_string_free(keysfilename, TRUE);
            return;
        }
        log_info("Loaded OTR 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 OTR fingerprints file found %s", fpsfilename->str);
        data_loaded = FALSE;
    } else {
        log_info("Loading OTR fingerprints %s", fpsfilename->str);
        err = otrl_privkey_read_fingerprints(user_state, fpsfilename->str, NULL, NULL);
        if (!err == GPG_ERR_NO_ERROR) {
            log_error("Failed to load OTR fingerprints file: %s", fpsfilename->str);
            g_string_free(basedir, TRUE);
            g_string_free(keysfilename, TRUE);
            g_string_free(fpsfilename, TRUE);
            return;
        } else {
            log_info("Loaded OTR 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;
}
Exemplo n.º 9
0
void OtrInternal::deleteKey(QString account, QString protocol)
{
    otrl_privkey_forget(otrl_privkey_find(m_userstate,account.toLocal8Bit().data(),protocol.toLocal8Bit().data()));
}
Exemplo n.º 10
0
gcry_error_t jsapi_userstate_import_privkey(OtrlUserState us, char *accountname, char * protocol,
                    gcry_mpi_t p, gcry_mpi_t q, gcry_mpi_t g, gcry_mpi_t y, gcry_mpi_t x){

    size_t *erroff;
    const char *token;
    size_t tokenlen;
    gcry_error_t err;
    gcry_sexp_t allkeys;
    size_t i;

    //puts("jsapi_userstate_import_privkey: building sexp");

    err = gcry_sexp_build(&allkeys,erroff,"(privkeys (account (name %s) (protocol %s) (private-key (dsa \
        (p %M) (q %M) (g %M) (y %M) (x %M) ))))",accountname,protocol,p,q,g,y,x);

    if(err) return err;

    /* forget existing account/key */
    OtrlPrivKey* existing_key = otrl_privkey_find(us,accountname,protocol);
    if( existing_key) otrl_privkey_forget(existing_key);

    //puts("getting allkeys from sexp");

    token = gcry_sexp_nth_data(allkeys, 0, &tokenlen);
    if (tokenlen != 8 || strncmp(token, "privkeys", 8)) {
	    gcry_sexp_release(allkeys);
	    return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
    }

    /* Get each account */
    for(i=1; i<gcry_sexp_length(allkeys); ++i) {

	    gcry_sexp_t names, protos, privs;
	    char *name, *proto;
	    gcry_sexp_t accounts;
	    OtrlPrivKey *p;

	    //printf("reading account #:%d\n",i);
	    /* Get the ith "account" S-exp */
	    accounts = gcry_sexp_nth(allkeys, i);

	    /* It's really an "account" S-exp? */
	    token = gcry_sexp_nth_data(accounts, 0, &tokenlen);
	    if (tokenlen != 7 || strncmp(token, "account", 7)) {
	        gcry_sexp_release(accounts);
	        gcry_sexp_release(allkeys);
	        return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	    }

	    /* Extract the name, protocol, and privkey S-exps */
	    names = gcry_sexp_find_token(accounts, "name", 0);
	    protos = gcry_sexp_find_token(accounts, "protocol", 0);
	    privs = gcry_sexp_find_token(accounts, "private-key", 0);
	    gcry_sexp_release(accounts);
	    if (!names || !protos || !privs) {
	        gcry_sexp_release(names);
	        gcry_sexp_release(protos);
	        gcry_sexp_release(privs);
	        gcry_sexp_release(allkeys);
	        return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	    }
	    /* Extract the actual name and protocol */
	    token = gcry_sexp_nth_data(names, 1, &tokenlen);
	    if (!token) {
	        gcry_sexp_release(names);
	        gcry_sexp_release(protos);
	        gcry_sexp_release(privs);
	        gcry_sexp_release(allkeys);
	        return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	    }
	    name = malloc(tokenlen + 1);
	    if (!name) {
	        gcry_sexp_release(names);
	        gcry_sexp_release(protos);
	        gcry_sexp_release(privs);
	        gcry_sexp_release(allkeys);
	        return gcry_error(GPG_ERR_ENOMEM);
	    }
	    memmove(name, token, tokenlen);
	    name[tokenlen] = '\0';
	    gcry_sexp_release(names);

	    token = gcry_sexp_nth_data(protos, 1, &tokenlen);
	    if (!token) {
	        free(name);
	        gcry_sexp_release(protos);
	        gcry_sexp_release(privs);
	        gcry_sexp_release(allkeys);
	        return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	    }
	    proto = malloc(tokenlen + 1);
	    if (!proto) {
	        free(name);
	        gcry_sexp_release(protos);
	        gcry_sexp_release(privs);
	        gcry_sexp_release(allkeys);
	        return gcry_error(GPG_ERR_ENOMEM);
	    }
	    memmove(proto, token, tokenlen);
	    proto[tokenlen] = '\0';
	    gcry_sexp_release(protos);

	    /* Make a new OtrlPrivKey entry */
	    p = malloc(sizeof(*p));
	    if (!p) {
	        free(name);
	        free(proto);
	        gcry_sexp_release(privs);
	        gcry_sexp_release(allkeys);
	        return gcry_error(GPG_ERR_ENOMEM);
	    }

	    /* Fill it in and link it up */
	    p->accountname = name;
	    p->protocol = proto;
	    p->pubkey_type = OTRL_PUBKEY_TYPE_DSA;
	    p->privkey = privs;
	    p->next = us->privkey_root;
	    if (p->next) {
	        p->next->tous = &(p->next);
	    }
	    p->tous = &(us->privkey_root);
	    us->privkey_root = p;
	    err = jsapi_make_pubkey(&(p->pubkey_data), &(p->pubkey_datalen), p->privkey);
	    if (err) {
	        gcry_sexp_release(allkeys);
	        otrl_privkey_forget(p);
	        return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	    }
    }
    gcry_sexp_release(allkeys);

    /* application should write out userstate to disk */
    return gcry_error(GPG_ERR_NO_ERROR);
}