unsigned int CALLBACK verify_context_thread(void *param) { Thread_Push( 0 ); if (param) { ConnContext *context = (ConnContext *)param; TCHAR msg[1024]; switch ( DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SMP_INPUT), 0, DlgProcVerifyContext, (LPARAM)param) ) { case IDOK: case IDYES: lib_cs_lock(); otrl_context_set_trust(context->active_fingerprint, "verified"); otrl_privkey_write_fingerprints(otr_user_state, g_fingerprint_store_filename); lib_cs_unlock(); mir_sntprintf(msg, 1024, TranslateT(LANG_FINGERPRINT_VERIFIED), contact_get_nameT((HANDLE)context->app_data)); msg[1023] = '\0'; ShowMessage((HANDLE)context->app_data, msg); SetEncryptionStatus(context->app_data, otr_context_get_trust(context)); break; case IDNO: lib_cs_lock(); otrl_context_set_trust(context->active_fingerprint, NULL); otrl_privkey_write_fingerprints(otr_user_state, g_fingerprint_store_filename); lib_cs_unlock(); mir_sntprintf(msg, 1024, TranslateT(LANG_FINGERPRINT_NOT_VERIFIED), contact_get_nameT((HANDLE)context->app_data)); msg[1023] = '\0'; ShowMessage((HANDLE)context->app_data, msg); SetEncryptionStatus(context->app_data, otr_context_get_trust(context)); break; } } Thread_Pop(); return 0; }
/** * set fingerprint verified/not verified */ void OtrConnection::verifyFingerprint(unsigned char* fp, bool verified) { ConnContext* context; Fingerprint* fingerprint; for (context = userstate->context_root; context != NULL; context = context->next) { fingerprint = otrl_context_find_fingerprint(context, fp, 0, NULL); if (verified) { otrl_context_set_trust(fingerprint, "verified"); } else { otrl_context_set_trust(fingerprint, ""); } } write_fingerprints(); }
/* Set verification of fingerprint */ void VerifyFingerprint(ConnContext *context, bool verify) { lib_cs_lock(); otrl_context_set_trust(context->active_fingerprint, (verify)?"verified":NULL); otrl_privkey_write_fingerprints(otr_user_state, g_fingerprint_store_filename); lib_cs_unlock(); VerifyFingerprintMessage(context, verify); }
void OtrInternal::verifyFingerprint(const psiotr::Fingerprint& fingerprint, bool verified) { ConnContext* context = otrl_context_find(m_userstate, fingerprint.username.toUtf8().constData(), fingerprint.account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); if (context) { ::Fingerprint* fp = otrl_context_find_fingerprint(context, fingerprint.fingerprint, 0, NULL); if (fp) { otrl_context_set_trust(fp, verified? "verified" : ""); write_fingerprints(); if (context->active_fingerprint == fp) { m_callback->stateChange(QString::fromUtf8(context->accountname), QString::fromUtf8(context->username), psiotr::OTR_STATECHANGE_TRUST); } } } }
void input_manual_otr_verify(char *arg) { char *msg, *temp, *sn; if (conn->conn == NULL) return; printf("\n"); sn = arg; struct BuddyList *buddy = find_buddy(sn); if (buddy) { if (buddy->otr_context) { char human_hash[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; otrl_privkey_hash_to_human(human_hash, buddy->otr_context->active_fingerprint-> fingerprint); b_echostr_s(); otrl_context_set_trust( buddy->otr_context->active_fingerprint, "verified"); printf("[OTR] Manually trusting fingerprint %s from %s\n", human_hash, sn); } } b_echostr_s(); printf("[OTR] No OTR context found for %s\n", sn); }
/* * Trust our peer. */ void otr_trust(SERVER_REC *irssi, const char *nick, char *str_fp, struct otr_user_state *ustate) { char peerfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; struct otr_peer_context *opc; ConnContext *ctx; Fingerprint *fp_trust; assert(ustate); if (!irssi && !str_fp) { IRSSI_NOTICE(NULL, nick, "Need a fingerprint!"); goto error; } /* No human string fingerprint given. */ if (!str_fp) { ctx = otr_find_context(irssi, nick, FALSE); if (!ctx) { goto error; } opc = ctx->app_data; /* Always NEED a peer context or else code error. */ assert(opc); fp_trust = ctx->active_fingerprint; } else { fp_trust = otr_find_hash_fingerprint_from_human(str_fp, ustate); } if (fp_trust) { int ret; ret = otrl_context_is_fingerprint_trusted(fp_trust); if (ret) { IRSSI_NOTICE(irssi, nick, "Already trusted!"); goto end; } /* Trust level is manual at this point. */ otrl_context_set_trust(fp_trust, "manual"); key_write_fingerprints(ustate); otr_status_change(irssi, nick, OTR_STATUS_TRUST_MANUAL); otrl_privkey_hash_to_human(peerfp, fp_trust->fingerprint); IRSSI_NOTICE(irssi, nick, "Fingerprint %g%s%n trusted!", peerfp); } else { IRSSI_NOTICE(irssi, nick, "Fingerprint %y%s%n NOT found", (str_fp != NULL) ? str_fp : ""); } end: error: return; }
void OtrFingerprintService::setContactFingerprintTrust(const Contact &contact, OtrFingerprintService::Trust trust) const { if (!ContextConverter) return; ConnContext *context = ContextConverter->contactToContextConverter(contact); if (!context->active_fingerprint) return; otrl_context_set_trust(context->active_fingerprint, TrustVerified == trust ? "verified" : ""); writeFingerprints(); }
/* * Distrust a fingerprint. * * If str_fp is not NULL, it must be on the OTR human format like this: * "487FFADA 5073FEDD C5AB5C14 5BB6C1FF 6D40D48A". If str_fp is NULL, get the * context of the target nickname, check for the OTR peer context active * fingerprint and distrust it. */ void otr_distrust(SERVER_REC *irssi, const char *nick, char *str_fp, struct otr_user_state *ustate) { int ret; char fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; Fingerprint *fp_distrust; ConnContext *ctx; struct otr_peer_context *opc; if (!irssi && !str_fp) { IRSSI_NOTICE(NULL, nick, "Need a fingerprint!"); goto error; } /* No human string fingerprint given. */ if (!str_fp) { ctx = otr_find_context(irssi, nick, FALSE); if (!ctx) { goto error; } opc = ctx->app_data; /* Always NEED a peer context or else code error. */ assert(opc); fp_distrust = opc->active_fingerprint; } else { fp_distrust = otr_find_hash_fingerprint_from_human(str_fp, ustate); } if (fp_distrust) { ret = otrl_context_is_fingerprint_trusted(fp_distrust); if (!ret) { /* Fingerprint already not trusted. Do nothing. */ IRSSI_NOTICE(irssi, nick, "Already not trusting it!"); goto end; } otrl_privkey_hash_to_human(fp, fp_distrust->fingerprint); otrl_context_set_trust(fp_distrust, ""); /* Update fingerprints file. */ key_write_fingerprints(ustate); IRSSI_NOTICE(irssi, nick, "Fingerprint %y%s%n distrusted.", fp); } else { IRSSI_NOTICE(irssi, nick, "Fingerprint %y%s%n NOT found", (str_fp != NULL) ? str_fp : ""); } end: error: return; }
void OtrInternal::verifyFingerprint(const qutimotr::Fingerprint& fingerprint, bool verified) { ConnContext* context; ::Fingerprint* fp; for (context = m_userstate->context_root; context != NULL; context = context->next) { fp = otrl_context_find_fingerprint(context, fingerprint.fingerprint, 0, NULL); if (verified) { otrl_context_set_trust(fp, "verified"); } else { otrl_context_set_trust(fp, ""); } } write_fingerprints(); }
static INT_PTR CALLBACK DlgProcMirOTROptsFinger(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { HWND lv = GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) new FPModifyMap()); SendDlgItemMessage(hwndDlg, IDC_LV_FINGER_LIST, 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_CONTACT); lvc.cx = 100; // width of column in pixels ListView_InsertColumn(lv, 0, &lvc); lvc.iSubItem = 1; lvc.pszText = TranslateT(LANG_PROTO); lvc.cx = 90; // width of column in pixels ListView_InsertColumn(lv, 1, &lvc); lvc.iSubItem = 2; lvc.pszText = TranslateT(LANG_ACTIVE); lvc.cx = 50; // width of column in pixels ListView_InsertColumn(lv, 2, &lvc); lvc.iSubItem = 3; lvc.pszText = TranslateT(LANG_VERIFIED); lvc.cx = 50; // width of column in pixels ListView_InsertColumn(lv, 3, &lvc); lvc.iSubItem = 4; lvc.pszText = TranslateT(LANG_FINGERPRINT); lvc.cx = 300; // width of column in pixels ListView_InsertColumn(lv, 4, &lvc); } SendMessage(hwndDlg, WMU_REFRESHLIST, 0, 0); return TRUE; case WMU_REFRESHLIST: // enumerate contacts, fill in list ListView_DeleteAllItems(lv); { LVITEM lvI = { 0 }; // Some code to create the list-view control. // Initialize LVITEM members that are common to all // items. lvI.mask = LVIF_TEXT | LVIF_PARAM;// | LVIF_NORECOMPUTE;// | LVIF_IMAGE; TCHAR *user, hash[45] = { 0 }; for (ConnContext *context = otr_user_state->context_root; context; context = context->next) { if (context->app_data) { user = (TCHAR*)contact_get_nameT((UINT_PTR)context->app_data); if (user) { PROTOACCOUNT *pa = Proto_GetAccount(context->protocol); for (Fingerprint *fp = context->fingerprint_root.next; fp; fp = fp->next) { otrl_privkey_hash_to_humanT(hash, fp->fingerprint); lvI.iSubItem = 0; lvI.lParam = (LPARAM)fp; lvI.pszText = user; int d = ListView_InsertItem(lv, &lvI); ListView_SetItemText(lv, d, 1, pa->tszAccountName); ListView_SetItemText(lv, d, 2, (context->active_fingerprint == fp) ? TranslateT(LANG_YES) : TranslateT(LANG_NO)); ListView_SetItemText(lv, d, 3, (fp->trust && fp->trust[0] != '\0') ? TranslateT(LANG_YES) : TranslateT(LANG_NO)); ListView_SetItemText(lv, d, 4, hash); } } } } } return TRUE; case WM_COMMAND: switch (HIWORD(wParam)) { int sel; case BN_CLICKED: switch (LOWORD(wParam)) { case IDC_BTN_FINGER_DONTTRUST: sel = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST)); if (sel != -1) { LVITEM lvi = { 0 }; lvi.mask = LVIF_PARAM; lvi.iItem = sel; ListView_GetItem(GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST), &lvi); Fingerprint *fp = (Fingerprint*)lvi.lParam; FPModifyMap* fpm = (FPModifyMap*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); (*fpm)[fp] = FPM_NOTRUST; ListView_SetItemText(GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST), sel, 3, TranslateT(LANG_NO)); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } break; case IDC_BTN_FINGER_TRUST: sel = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST)); if (sel != -1) { LVITEM lvi = { 0 }; lvi.mask = LVIF_PARAM; lvi.iItem = sel; ListView_GetItem(GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST), &lvi); Fingerprint *fp = (Fingerprint*)lvi.lParam; FPModifyMap* fpm = (FPModifyMap*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); (*fpm)[fp] = FPM_VERIFY; ListView_SetItemText(GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST), sel, 3, TranslateT(LANG_YES)); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } break; case IDC_BTN_FINGER_FORGET: sel = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST)); if (sel != -1) { LVITEM lvi = { 0 }; lvi.mask = LVIF_PARAM; lvi.iItem = sel; ListView_GetItem(GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST), &lvi); Fingerprint *fp = (Fingerprint*)lvi.lParam; if (fp->context->active_fingerprint == fp) { MCONTACT hContact = (UINT_PTR)fp->context->app_data; TCHAR buff[1024], hash[45]; otrl_privkey_hash_to_humanT(hash, fp->fingerprint); PROTOACCOUNT *pa = Proto_GetAccount(GetContactProto(hContact)); mir_sntprintf(buff, TranslateT(LANG_FINGERPRINT_STILL_IN_USE), hash, contact_get_nameT(hContact), pa->tszAccountName); ShowError(buff); } else { FPModifyMap* fpm = (FPModifyMap*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); (*fpm)[fp] = FPM_DELETE; ListView_DeleteItem(GetDlgItem(hwndDlg, IDC_LV_FINGER_LIST), sel); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } } break; } } break; case WM_NOTIFY: if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY) { // handle apply FPModifyMap *fpm = (FPModifyMap*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); // Iterate over the map and print out all key/value pairs. // Using a const_iterator since we are not going to change the values. for (FPModifyMap::const_iterator it = fpm->begin(); it != fpm->end(); ++it) { if (!it->first) continue; switch (it->second) { case FPM_DELETE: if (it->first->context->active_fingerprint == it->first) { MCONTACT hContact = (UINT_PTR)it->first->context->app_data; TCHAR buff[1024], hash[45]; otrl_privkey_hash_to_humanT(hash, it->first->fingerprint); PROTOACCOUNT *pa = Proto_GetAccount(GetContactProto(hContact)); mir_sntprintf(buff, TranslateT(LANG_FINGERPRINT_NOT_DELETED), hash, contact_get_nameT(hContact), pa->tszAccountName); ShowError(buff); } else otrl_context_forget_fingerprint(it->first, 1); break; case FPM_VERIFY: otrl_context_set_trust(it->first, "verified"); if (it->first == it->first->context->active_fingerprint) VerifyFingerprint(it->first->context, true); break; case FPM_NOTRUST: otrl_context_set_trust(it->first, NULL); if (it->first == it->first->context->active_fingerprint) VerifyFingerprint(it->first->context, false); break; } } if (!fpm->empty()) otr_gui_write_fingerprints(0); fpm->clear(); SendMessage(hwndDlg, WMU_REFRESHLIST, 0, 0); return TRUE; } break; case WM_DESTROY: FPModifyMap *fpm = (FPModifyMap*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); fpm->clear(); delete fpm; break; } return FALSE; }
/* * Initiate or respond to SMP authentication. */ void otr_auth(SERVER_REC *irssi, const char *nick, const char *question, const char *secret) { int ret; size_t secret_len = 0; ConnContext *ctx; struct otr_peer_context *opc; assert(irssi); assert(nick); ctx = otr_find_context(irssi, nick, 0); if (!ctx) { IRSSI_NOTICE(irssi, nick, "Context for %9%s%9 not found.", nick); goto end; } opc = ctx->app_data; /* Again, code flow error. */ assert(opc); if (ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED) { IRSSI_INFO(irssi, nick, "You need to establish an OTR session before you " "can authenticate."); goto end; } /* Aborting an ongoing auth */ if (ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) { otr_auth_abort(irssi, nick); } /* reset trust level */ if (ctx->active_fingerprint) { ret = otrl_context_is_fingerprint_trusted(ctx->active_fingerprint); if (!ret) { otrl_context_set_trust(ctx->active_fingerprint, ""); key_write_fingerprints(user_state_global); } } /* Libotr allows empty secret. */ if (secret) { secret_len = strlen(secret); } if (opc->ask_secret) { otrl_message_respond_smp(user_state_global->otr_state, &otr_ops, irssi, ctx, (unsigned char *) secret, secret_len); otr_status_change(irssi, nick, OTR_STATUS_SMP_RESPONDED); IRSSI_NOTICE(irssi, nick, "%yResponding to authentication...%n"); } else { if (question) { otrl_message_initiate_smp_q(user_state_global->otr_state, &otr_ops, irssi, ctx, question, (unsigned char *) secret, secret_len); } else { otrl_message_initiate_smp(user_state_global->otr_state, &otr_ops, irssi, ctx, (unsigned char *) secret, secret_len); } otr_status_change(irssi, nick, OTR_STATUS_SMP_STARTED); IRSSI_NOTICE(irssi, nick, "%yInitiated authentication...%n"); } opc->ask_secret = 0; end: return; }
/* Read the fingerprint store from a FILE* into the given * OtrlUserState. Use add_app_data to add application data to each * ConnContext so created. The FILE* must be open for reading. */ gcry_error_t otrl_privkey_read_fingerprints_FILEp(OtrlUserState us, FILE *storef, void (*add_app_data)(void *data, ConnContext *context), void *data) { ConnContext *context; char storeline[1000]; unsigned char fingerprint[20]; size_t maxsize = sizeof(storeline); if (!storef) return gcry_error(GPG_ERR_NO_ERROR); while(fgets(storeline, maxsize, storef)) { char *username; char *accountname; char *protocol; char *hex; char *trust; char *tab; char *eol; Fingerprint *fng; int i, j; /* Parse the line, which should be of the form: * username\taccountname\tprotocol\t40_hex_nybbles\n */ username = storeline; tab = strchr(username, '\t'); if (!tab) continue; *tab = '\0'; accountname = tab + 1; tab = strchr(accountname, '\t'); if (!tab) continue; *tab = '\0'; protocol = tab + 1; tab = strchr(protocol, '\t'); if (!tab) continue; *tab = '\0'; hex = tab + 1; tab = strchr(hex, '\t'); if (!tab) { eol = strchr(hex, '\r'); if (!eol) eol = strchr(hex, '\n'); if (!eol) continue; *eol = '\0'; trust = NULL; } else { *tab = '\0'; trust = tab + 1; eol = strchr(trust, '\r'); if (!eol) eol = strchr(trust, '\n'); if (!eol) continue; *eol = '\0'; } if (strlen(hex) != 40) continue; for(j=0, i=0; i<40; i+=2) { fingerprint[j++] = (ctoh(hex[i]) << 4) + (ctoh(hex[i+1])); } /* Get the context for this user, adding if not yet present */ context = otrl_context_find(us, username, accountname, protocol, 1, NULL, add_app_data, data); /* Add the fingerprint if not already there */ fng = otrl_context_find_fingerprint(context, fingerprint, 1, NULL); otrl_context_set_trust(fng, trust); } return gcry_error(GPG_ERR_NO_ERROR); }