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); }
/* * 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); }
/** * Returns a list of all known fingerprints. * */ QList< Fprint > OtrConnection::getFingerprints() { QList< Fprint > fpList; ConnContext* context; Fingerprint* fingerprint; char hash[45]; for (context = userstate->context_root; context != NULL; context = context->next) { fingerprint = context->fingerprint_root.next; while(fingerprint) { Fprint fpData; // my account fpData.setAccount(context->accountname); // buddy username fpData.setUsername(context->username); // fingerprint fpData.setFingerprint(fingerprint->fingerprint); otrl_privkey_hash_to_human(hash, fingerprint->fingerprint); fpData.setFingerprintHuman(hash); // trust level fpData.setTrust(fingerprint->trust); // message state fpData.setMessageState(getMessageStateString( context->accountname, context->username)); fpList.append(fpData); fingerprint = fingerprint->next; } } return fpList; }
/* * Search for a OTR Fingerprint object from the given human readable string and * return a pointer to the object if found else NULL. */ Fingerprint *otr_find_hash_fingerprint_from_human(const char *human_fp, struct otr_user_state *ustate) { char str_fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; Fingerprint *fp = NULL, *fp_iter = NULL; ConnContext *context; /* Loop on all context of the user state */ for (context = ustate->otr_state->context_root; context != NULL; context = context->next) { /* Loop on all fingerprint of the context */ for (fp_iter = context->fingerprint_root.next; fp_iter; fp_iter = fp_iter->next) { otrl_privkey_hash_to_human(str_fp, fp_iter->fingerprint); /* Compare human fingerprint given in argument to the current. */ if (strncmp(str_fp, human_fp, sizeof(str_fp)) == 0) { fp = otrl_context_find_fingerprint(context, fp_iter->fingerprint, 0, NULL); goto end; } } } end: return fp; }
void input_show_otr(char *arg) { if (conn->conn == NULL) return; printf("\n"); if (strlen(arg) <= 0) { check_key_gen_state(); return; } else { b_echostr_s(); struct BuddyList *buddy = find_buddy(arg); if (buddy) { printf("[OTR] status for %s\n", arg); printf(" local otr: "); switch (buddy->otr) { case -1: printf("disabled\n"); break; case 0: printf("inactive\n"); break; case 1: printf("active\n"); break; default: printf("error\n"); break; } if (buddy->otr_context) { if (buddy->otr_context->active_fingerprint) { char human_hash[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; otrl_privkey_hash_to_human(human_hash, buddy->otr_context->active_fingerprint->fingerprint); int ret = otrl_context_is_fingerprint_trusted(buddy->otr_context->active_fingerprint); printf(" fingerprint: %s (%s)\n", human_hash, ret ? "trusted" : "untrusted"); } printf(" context state: "); switch (buddy->otr_context->msgstate) { case OTRL_MSGSTATE_ENCRYPTED: printf("encrypted\n"); break; case OTRL_MSGSTATE_PLAINTEXT: printf("plaintext\n"); break; case OTRL_MSGSTATE_FINISHED: printf("finished\n"); break; default: printf("error\n"); break; } } } else { printf("[OTR] buddy not found %s\n", arg); } return; } }
/* * 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; }
/* * Forget 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 forget this one if possible. */ void otr_forget(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_forget; ConnContext *ctx = NULL; 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_forget = opc->active_fingerprint; } else { fp_forget = otr_find_hash_fingerprint_from_human(str_fp, ustate); } if (fp_forget) { /* Don't do anything if context is in encrypted state. */ ret = check_fp_encrypted_msgstate(fp_forget); if (ret) { IRSSI_NOTICE(irssi, nick, "Fingerprint " "context is still encrypted. Finish the OTR " "session before forgetting a fingerprint " "(%9/otr finish%9)."); goto end; } otrl_privkey_hash_to_human(fp, fp_forget->fingerprint); /* Forget fp and context if it's the only one remaining. */ otrl_context_forget_fingerprint(fp_forget, 1); /* Update fingerprints file. */ key_write_fingerprints(ustate); IRSSI_NOTICE(irssi, nick, "Fingerprint %y%s%n forgotten.", fp); } else { IRSSI_NOTICE(irssi, nick, "Fingerprint %y%s%n NOT found", (str_fp != NULL) ? str_fp : ""); } end: error: return; }
/* * 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; }
/* A new fingerprint for the given user has been received. */ void OtrConnection::new_fingerprint(OtrlUserState us, const char *accountname, const char *protocol, const char *username, unsigned char fingerprint[20]) { Q_UNUSED(us); Q_UNUSED(protocol); char fpHuman[45]; otrl_privkey_hash_to_human(fpHuman, fingerprint); QMessageBox* d = new QMessageBox(QMessageBox::Information, "psi-otr", QString(accountname) + " has received new fingerprint from " + QString(username) + ":\n" + QString(fpHuman), QMessageBox::Ok, NULL, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); d->exec(); }
char* otr_get_their_fingerprint(const char *const recipient) { ConnContext *context = otrlib_context_find(user_state, recipient, jid); if (context) { Fingerprint *fingerprint = context->active_fingerprint; char readable[45]; otrl_privkey_hash_to_human(readable, fingerprint->fingerprint); return strdup(readable); } else { return NULL; } }
static void otrwui_new_fingerprint( void *opdata, OtrlUserState us, const char *accountname, const char *protocol, const char *username, unsigned char fingerprint[20]) { /* A new fingerprint for the given user has been received. */ std::string trace= "otrwui_new_fingerprint: "; trace += username; trace += "@"; trace += protocol; trace += " has a new fingerprint ("; char fingerprint_copy[45]; otrl_privkey_hash_to_human(fingerprint_copy, fingerprint); trace += fingerprint_copy; trace += ")"; otrwui_tbd(trace.c_str()); // $TODO$ write me }
QString OtrFingerprintService::extractContactFingerprint(const Contact &contact) const { if (!ContextConverter) return QString(); ConnContext *context = ContextConverter->contactToContextConverter(contact); if (!context->active_fingerprint) return QString(); char fingerprint[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; otrl_privkey_hash_to_human(fingerprint, context->active_fingerprint->fingerprint); fingerprint[OTRL_PRIVKEY_FPRINT_HUMAN_LEN - 1] = 0; return QString::fromLatin1(fingerprint); }
QList<qutimotr::Fingerprint> OtrInternal::getFingerprints() { QList<qutimotr::Fingerprint> fpList; ConnContext* context; ::Fingerprint* fingerprint; for (context = m_userstate->context_root; context != NULL; context = context->next) { fingerprint = context->fingerprint_root.next; while(fingerprint) { qutimotr::Fingerprint fp; fp.account = QString(context->accountname); fp.username = QString(context->username); fp.fingerprint = fingerprint->fingerprint; char fpHash[45]; otrl_privkey_hash_to_human(fpHash, fingerprint->fingerprint); fp.fingerprintHuman = QString(fpHash); fp.trust = QString(fingerprint->trust); if (fingerprint == context->active_fingerprint) { TreeModelItem item; item.m_account_name = context->accountname; item.m_item_type = 0; item.m_protocol_name = context->protocol; fp.messageState = QString( getMessageStateString(context->accountname, context->username, item)); } else { fp.messageState.clear(); } fpList.append(fp); fingerprint = fingerprint->next; } } return fpList; }
/* * 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; }
void HandleNewFingerprint (void *opData, OtrlUserState, const char *accountname, const char*, const char *username, unsigned char fingerprint [20]) { char fpHash [OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; otrl_privkey_hash_to_human (fpHash, fingerprint); QString hrHash (fpHash); // human readable fingerprint const auto plugin = static_cast<OtrHandler*> (opData); const auto& msg = OtrHandler::tr ("You have received a new fingerprint from %1: %2") .arg (plugin->GetVisibleEntryName (QString::fromUtf8 (accountname), QString::fromUtf8 (username))) .arg (hrHash); plugin->InjectMsg (QString::fromUtf8 (accountname), QString::fromUtf8 (username), msg, false, IMessage::Direction::In, IMessage::Type::ServiceMessage); }
/* 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; }
void OtrInternal::new_fingerprint(OtrlUserState us, const char *accountname, const char *protocol, const char *username, unsigned char fingerprint[20]) { Q_UNUSED(us); Q_UNUSED(protocol); char fpHuman[45]; otrl_privkey_hash_to_human(fpHuman, fingerprint); TreeModelItem item; item.m_account_name = QString(accountname); item.m_protocol_name = QString(protocol); item.m_item_name = QString(username); item.m_item_type = 0; sendCustomNessage(item,tr("Account %1 has received new fingerprint from %2 :\n %3").arg(QString(accountname)).arg(QString(username)).arg(QString(fpHuman))); // QMessageBox mb(QMessageBox::Information, tr("qutim-otr"), // tr("Account ") + QString(accountname) + tr(" has received new fingerprint from ") // + QString(username) + ":\n" + QString(fpHuman), // QMessageBox::Ok, NULL, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); // mb.exec(); }
QString OtrInternal::humanFingerprint(const unsigned char* fingerprint) { char fpHash[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; otrl_privkey_hash_to_human(fpHash, fingerprint); return QString(fpHash); }
/* Update the keylist, if it's visible */ static void otrg_gtk_ui_update_keylist(void) { gchar *titles[5]; char hash[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; ConnContext * context; Fingerprint * fingerprint; int selected_row = -1; GtkWidget *keylist = ui_layout.keylist; if (keylist == NULL) return; gtk_clist_freeze(GTK_CLIST(keylist)); gtk_clist_clear(GTK_CLIST(keylist)); for (context = otrg_plugin_userstate->context_root; context != NULL; context = context->next) { int i; PurplePlugin *p; const char *proto_name; if (context->m_context != context) continue; fingerprint = context->fingerprint_root.next; /* If there's no fingerprint, don't add it to the known * fingerprints list */ while(fingerprint) { ConnContext *context_iter; TrustLevel best_level = TRUST_NOT_PRIVATE; int used = 0; titles[0] = context->username; titles[1] = _("Unused"); for (context_iter = context->m_context; context_iter && context_iter->m_context == context->m_context; context_iter = context_iter->next) { TrustLevel this_level = TRUST_NOT_PRIVATE; if (context_iter->active_fingerprint == fingerprint) { this_level = otrg_plugin_context_to_trust(context_iter); used = 1; if (this_level == TRUST_PRIVATE) { best_level = TRUST_PRIVATE; } else if (this_level == TRUST_UNVERIFIED && best_level != TRUST_PRIVATE) { best_level = TRUST_UNVERIFIED; } else if (this_level == TRUST_FINISHED && best_level == TRUST_NOT_PRIVATE) { best_level = TRUST_FINISHED; } } } if (used) { titles[1] = (gchar *) _(trust_states[best_level]); } titles[2] = otrg_fingerprint_is_trusted(fingerprint) ? _("Yes") : _("No"); otrl_privkey_hash_to_human(hash, fingerprint->fingerprint); titles[3] = hash; p = purple_find_prpl(context->protocol); proto_name = (p && p->info->name) ? p->info->name : _("Unknown"); titles[4] = g_strdup_printf("%s (%s)", context->accountname, proto_name); i = gtk_clist_append(GTK_CLIST(keylist), titles); g_free(titles[4]); gtk_clist_set_row_data(GTK_CLIST(keylist), i, fingerprint); if (ui_layout.selected_fprint == fingerprint) { selected_row = i; } fingerprint = fingerprint->next; } } if (selected_row >= 0) { gtk_clist_select_row(GTK_CLIST(keylist), selected_row, 0); } else { clist_all_unselected(); } gtk_clist_sort(GTK_CLIST(keylist)); gtk_clist_thaw(GTK_CLIST(keylist)); }
/* * List otr contexts to the main Irssi windows. */ void otr_contexts(struct otr_user_state *ustate) { char human_fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN], *trust; ConnContext *ctx, *c_iter; Fingerprint *fp; assert(ustate); if (!ustate->otr_state->context_root) { IRSSI_INFO(NULL, NULL, "No active OTR contexts found"); goto end; } IRSSI_MSG("[ %KUser%n - %KAccount%n - %KStatus%n - %KFingerprint%n - " "%KTrust%n ]"); /* Iterate over all contextes of the user state. */ for (ctx = ustate->otr_state->context_root; ctx != NULL; ctx = ctx->next) { OtrlMessageState best_mstate = OTRL_MSGSTATE_PLAINTEXT; /* Skip master context. */ if (ctx != ctx->m_context) { continue; } for (fp = ctx->fingerprint_root.next; fp != NULL; fp = fp->next) { int used = 0; char *username, *accountname; username = ctx->username; accountname = ctx->accountname; for (c_iter = ctx->m_context; c_iter && c_iter->m_context == ctx->m_context; c_iter = c_iter->next) { /* Print account name, username and msgstate. */ if (c_iter->active_fingerprint == fp) { used = 1; if (c_iter->msgstate == OTRL_MSGSTATE_ENCRYPTED) { best_mstate = OTRL_MSGSTATE_ENCRYPTED; } else if (c_iter->msgstate == OTRL_MSGSTATE_FINISHED && best_mstate == OTRL_MSGSTATE_PLAINTEXT) { best_mstate = OTRL_MSGSTATE_FINISHED; } } } if (used) { switch (best_mstate) { case OTRL_MSGSTATE_ENCRYPTED: IRSSI_MSG("%b>%n %9%s%9 - %B%s%n - %GEncrypted%n -", accountname, username); break; case OTRL_MSGSTATE_PLAINTEXT: IRSSI_MSG("%b>%n %9%s%9 - %B%s%n - Plaintext -", accountname, username); break; case OTRL_MSGSTATE_FINISHED: IRSSI_MSG("%b>%n %9%s%9 - %B%s%n - %yFinished%n -", accountname, username); break; default: IRSSI_MSG("%b>%n %9%s%9 - %B%s%n - Unknown -", accountname, username); break; }; } else { IRSSI_MSG("%b>%n %9%s%9 - %B%s%n - Unused -", accountname, username); } /* Hash fingerprint to human. */ otrl_privkey_hash_to_human(human_fp, fp->fingerprint); trust = fp->trust; if (trust && trust[0] != '\0') { if (strncmp(trust, "smp", 3) == 0) { IRSSI_MSG(" %g%s%n - SMP", human_fp); } else { IRSSI_MSG(" %g%s%n - Manual", human_fp); } } else { IRSSI_MSG(" %r%s%n - Unverified", human_fp); } } } end: return; }
void jsapi_conncontext_get_active_fingerprint(ConnContext* ctx, char* human){ human[0]='\0'; if(ctx->active_fingerprint==NULL) return; otrl_privkey_hash_to_human(human, ctx->active_fingerprint->fingerprint); }
void jsapi_fingerprint_get_fingerprint(Fingerprint *fingerprint, char* human){ human[0]='\0'; otrl_privkey_hash_to_human(human, fingerprint->fingerprint); }