/* * Gone secure. */ static void ops_secure (void *opdata, ConnContext *context) { struct co_info *coi = context->app_data; char *trust = context->active_fingerprint->trust ?: ""; char ownfp[45], peerfp[45]; otr_notice (coi->ircctx, context->username, TXT_OPS_SEC); if (*trust != '\0') return; /* not authenticated. * Let's print out the fingerprints for comparison */ otrl_privkey_hash_to_human (peerfp, context->active_fingerprint->fingerprint); otr_notice (coi->ircctx, context->username, TXT_OPS_FPCOMP, otrl_privkey_fingerprint (otr_state, ownfp, context->accountname, PROTOCOLID), context->username, peerfp); }
/* Create a private key for the given accountname/protocol if * desired. */ void OtrConnection::create_privkey(const char *accountname, const char *protocol) { char fingerprint[45]; QLabel* l = new QLabel("\n Please wait, while generating key for " + QString(accountname) + " \n"); l->show(); QCoreApplication::processEvents(); QCoreApplication::processEvents(); otrl_privkey_generate(userstate, keysFile.toStdString().c_str(), accountname, protocol); QCoreApplication::processEvents(); l->hide(); QCoreApplication::processEvents(); if (otrl_privkey_fingerprint(userstate, fingerprint, accountname, protocol) == NULL) { qWarning() << "Failed to generate private key\n"; exit(1); } QMessageBox* d = new QMessageBox(QMessageBox::Information, "psi-otr", "The fingerprint for " + QString(accountname) + " is\n" + QString(fingerprint), QMessageBox::Ok, NULL, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); d->exec(); }
QHash<QString, QHash<QString, QString> > OtrInternal::getPrivateKeys() { QHash<QString, QHash<QString, QString> > privKeyList; ConnContext* context; for (context = m_userstate->context_root; context != NULL; context = context->next) { char fingerprintBuf[45]; char* success = otrl_privkey_fingerprint(m_userstate, fingerprintBuf, context->accountname, context->protocol); if (success) { QHash<QString, QString> hash; if(privKeyList.contains(QString(context->accountname))) hash = privKeyList.value(QString(context->accountname)); hash[QString(context->protocol)] = QString(fingerprintBuf); privKeyList.insert(QString(context->accountname),hash); } } return privKeyList; }
char* otr_get_my_fingerprint(void) { char fingerprint[45]; otrl_privkey_fingerprint(user_state, fingerprint, jid, "xmpp"); char *result = strdup(fingerprint); return result; }
void OtrInternal::create_privkey(const char *accountname, const char *protocol) { Q_ASSERT(m_userstate); if(!m_mutex.tryLock(10)) return; QMessageBox warnBox(QMessageBox::Warning,tr("qutim-otr"),tr("Key generation will be started.<br>Please, make sure that you <b>log out from all your jabber accounts</b>! QutIM may be crashed if they will be online while key is generating."),QMessageBox::Ok,NULL,Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); warnBox.setModal(false); warnBox.setWindowModality(Qt::NonModal); warnBox.setDefaultButton(QMessageBox::Ok); warnBox.show(); warnBox.setEscapeButton(QMessageBox::Cancel); while(!warnBox.isHidden()) QCoreApplication::processEvents(); QMessageBox infoMb(QMessageBox::Information, tr("qutim-otr"), tr("Generating keys for account %1\nThis may take a while.\nPlease, move mouse and use keyoard to decrease generation time.").arg(QString(accountname)), QMessageBox::Ok, NULL, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); infoMb.button(QMessageBox::Ok)->setEnabled(false); infoMb.button(QMessageBox::Ok)->setText(tr("please wait...")); infoMb.setWindowModality(Qt::NonModal); infoMb.setModal(false); infoMb.show(); { KeyGeneratorThread keyGenerator(m_userstate, m_keysFile, accountname, protocol); keyGenerator.start(); while (!keyGenerator.isFinished()) QCoreApplication::processEvents(); } m_mutex.unlock(); infoMb.button(QMessageBox::Ok)->setEnabled(true); infoMb.button(QMessageBox::Ok)->setText("Ok"); char fingerprint[45]; if (otrl_privkey_fingerprint(m_userstate, fingerprint, accountname, protocol) == NULL) { QMessageBox failMb(QMessageBox::Critical, tr("qutim-otr"), tr("Failed to generate key for account %1\nThe OTR Plugin will not work.").arg(QString(accountname)), QMessageBox::Ok, NULL, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); failMb.exec(); } else { infoMb.setText(tr("The fingerprint for account %1 is\n").arg(QString(accountname)) + QString(fingerprint)); } infoMb.exec(); }
//----------------------------------------------------------------------------- void OtrInternal::startSession(const QString& account, const QString& jid, TreeModelItem &item, int pol) { Q_UNUSED(jid); OtrlPolicy policy = (OtrlPolicy)pol; char fingerprint[45]; if (!otrl_privkey_fingerprint(m_userstate, fingerprint, account.toStdString().c_str(), item.m_protocol_name.toStdString().c_str())) { create_privkey(account.toStdString().c_str(), item.m_protocol_name.toStdString().c_str()); } if (!otrl_privkey_fingerprint(m_userstate, fingerprint, account.toStdString().c_str(), item.m_protocol_name.toStdString().c_str())) return; //TODO: make allowed otr versions configureable char* msg = otrl_proto_default_query_msg(account.toStdString().c_str(), policy); m_plugin->sendCustomMessage(item,QString(msg),true); }
/** * Returns a hash of private keys in the format accountJID -> fingerprint. */ QHash<QString, QString>* OtrConnection::getPrivateKeys() { QHash<QString, QString>* privKeyList = new QHash<QString, QString>(); ConnContext* context; for (context = userstate->context_root; context != NULL; context = context->next) { char fingerprint_buf[45]; char* fingerprint = otrl_privkey_fingerprint(userstate, fingerprint_buf, context->accountname, protocolString); if (fingerprint != NULL && strlen(fingerprint) > 1) { privKeyList->insert(QString(context->accountname), QString(fingerprint)); } } return privKeyList; }
QString OtrFingerprintService::extractAccountFingerprint(const Account &account) const { if (!UserStateService) return QString(); char fingerprint[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; char *result = otrl_privkey_fingerprint(UserStateService->userState(), fingerprint, qPrintable(account.id()), qPrintable(account.protocolName())); if (!result) return QString(); fingerprint[OTRL_PRIVKEY_FPRINT_HUMAN_LEN - 1] = 0; return QString::fromLatin1(fingerprint); }
/* * Gone secure. */ static void ops_secure(void *opdata, ConnContext *context) { int ret; char ownfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; char peerfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; SERVER_REC *irssi = opdata; struct otr_peer_context *opc; assert(context); /* This should *really* not happened */ assert(context->msgstate == OTRL_MSGSTATE_ENCRYPTED); IRSSI_NOTICE(irssi, context->username, "Gone %9secure%9"); otr_status_change(irssi, context->username, OTR_STATUS_GONE_SECURE); opc = context->app_data; opc->active_fingerprint = context->active_fingerprint; ret = otrl_context_is_fingerprint_trusted(context->active_fingerprint); if (ret) { /* Secure and trusted */ goto end; } /* Not authenticated. Let's print out the fingerprints for comparison. */ otrl_privkey_hash_to_human(peerfp, context->active_fingerprint->fingerprint); otrl_privkey_fingerprint(user_state_global->otr_state, ownfp, context->accountname, OTR_PROTOCOL_ID); IRSSI_NOTICE(irssi, context->username, "Your peer is not " "authenticated. To make sure you're talking to the right person you can " "either agree on a secret and use the authentication command " "%9/otr auth%9 or %9/otr authq [QUESTION] SECRET%9. You can also " "use the traditional way and compare fingerprints " "(e.g. telephone or GPG-signed mail) and subsequently enter " "%9/otr trust%9."); IRSSI_NOTICE(irssi, context->username, "Your fingerprint is: %y%s%n", ownfp); IRSSI_NOTICE(irssi, context->username, "%9%s's%9 fingerprint is: %r%s%n", context->username, peerfp); end: return; }
QHash<QString, QString> OtrInternal::getPrivateKeys() { QHash<QString, QString> privKeyList; OtrlPrivKey* privKey; for (privKey = m_userstate->privkey_root; privKey != NULL; privKey = privKey->next) { char fingerprintBuf[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; char* success = otrl_privkey_fingerprint(m_userstate, fingerprintBuf, privKey->accountname, OTR_PROTOCOL_STRING); if (success) { privKeyList.insert(QString::fromUtf8(privKey->accountname), QString(fingerprintBuf)); } } return privKeyList; }
static void account_menu_changed_cb(GtkWidget *item, PurpleAccount *account, void *data) { const char *accountname; const char *protocol; GtkWidget *fprint = ui_layout.fprint_label; char *s = NULL; char *fingerprint; if (account) { char fingerprint_buf[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; accountname = purple_account_get_username(account); protocol = purple_account_get_protocol_id(account); fingerprint = otrl_privkey_fingerprint(otrg_plugin_userstate, fingerprint_buf, accountname, protocol); if (fingerprint) { s = g_strdup_printf(_("Fingerprint: %.80s"), fingerprint); if (ui_layout.generate_button) gtk_widget_set_sensitive(ui_layout.generate_button, 0); } else { s = g_strdup(_("No key present")); if (ui_layout.generate_button) gtk_widget_set_sensitive(ui_layout.generate_button, 1); } } else { s = g_strdup(_("No account available")); if (ui_layout.generate_button) gtk_widget_set_sensitive(ui_layout.generate_button, 0); } if (fprint) { gtk_label_set_text(GTK_LABEL(fprint), s ? s : ""); gtk_widget_show(fprint); } if (s) { g_free(s); } }
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; }
void OtrInternal::create_privkey(const char* accountname, const char* protocol) { if (is_generating) { return; } QMessageBox qMB(QMessageBox::Question, QObject::tr("Psi OTR"), QObject::tr("Private keys for account \"%1\" need to be generated. " "This takes quite some time (from a few seconds to a " "couple of minutes), and while you can use Psi+ in the " "meantime, all the messages will be sent unencrypted " "until keys are generated. You will be notified when " "this process finishes.\n" "\n" "Do you want to generate keys now?") .arg(m_callback->humanAccount( QString::fromUtf8(accountname))), QMessageBox::Yes | QMessageBox::No); if (qMB.exec() != QMessageBox::Yes) { return; } is_generating = true; QByteArray keysfile = QFile::encodeName(m_keysFile); QEventLoop loop; QFutureWatcher<gcry_error_t> watcher; QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit())); QFuture<gcry_error_t> future = QtConcurrent::run(otrl_privkey_generate, m_userstate, keysfile.constData(), accountname, protocol); watcher.setFuture(future); loop.exec(); is_generating = false; char fingerprint[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; if (otrl_privkey_fingerprint(m_userstate, fingerprint, accountname, protocol)) { QMessageBox infoMb(QMessageBox::Information, QObject::tr("Psi OTR"), QObject::tr("Keys have been generated. " "Fingerprint for account \"%1\":\n" "%2\n" "\n" "Thanks for your patience.") .arg(m_callback->humanAccount( QString::fromUtf8(accountname))) .arg(QString(fingerprint))); infoMb.exec(); } else { QMessageBox failMb(QMessageBox::Critical, QObject::tr("Psi OTR"), QObject::tr("Failed to generate keys for account \"%1\"." "\nThe OTR Plugin will not work.") .arg(m_callback->humanAccount( QString::fromUtf8(accountname))), QMessageBox::Ok); failMb.exec(); } }