void test_crash1(void) { ConnContext *alicecontext, *bobcontext; printf("\n\n*** Testing old double gcry_cipher_release case ***\n\n"); otrl_context_forget_all(us); ALICEPOLICY = OTRL_POLICY_DEFAULT; sending(ALICE, BOB, "?OTR?"); dispatch(); alicecontext = otrl_context_find(us, BOB, ALICE, PROTO, 0, 0, NULL, NULL, NULL); bobcontext = otrl_context_find(us, ALICE, BOB, PROTO, 0, 0, NULL, NULL, NULL); sending(ALICE, BOB, "Hi!"); dispatch(); sending(BOB, ALICE, "There!"); dispatch(); sending(ALICE, BOB, "You!"); dispatch(); otrl_context_force_plaintext(bobcontext); sending(BOB, ALICE, "?OTR?"); dispatch(); sending(ALICE, BOB, "now."); dispatch(); printf("%d %p %p\n", alicecontext->our_keyid, alicecontext->their_y, alicecontext->their_old_y); printf("%p %p %p %p\n", alicecontext->sesskeys[0][0].sendenc, alicecontext->sesskeys[0][1].sendenc, alicecontext->sesskeys[1][0].sendenc, alicecontext->sesskeys[1][1].sendenc); sending(BOB, ALICE, "then."); dispatch(); }
void test_refresh(int vers) { ConnContext *alicecontext, *bobcontext; printf("\n\n*** Testing refresh ***\n\n"); otrl_context_forget_all(us); if (vers == 1) ALICEPOLICY = OTRL_POLICY_ALLOW_V1; else if (vers == 2) ALICEPOLICY = OTRL_POLICY_ALLOW_V2; else ALICEPOLICY = OTRL_POLICY_DEFAULT; sending(ALICE, BOB, "?OTR?"); dispatch(); alicecontext = otrl_context_find(us, BOB, ALICE, PROTO, 0, 0, NULL, NULL, NULL); bobcontext = otrl_context_find(us, ALICE, BOB, PROTO, 0, 0, NULL, NULL, NULL); printf("%p %p\n", alicecontext, bobcontext); sending(ALICE, BOB, "Hi!"); dispatch(); sending(BOB, ALICE, "There!"); dispatch(); sending(ALICE, BOB, "You!"); dispatch(); sending(ALICE, BOB, "Guys!"); dispatch(); sending(BOB, ALICE, "?OTR?"); dispatch(); sending(ALICE, BOB, "Refreshed!"); dispatch(); sending(BOB, ALICE, "Also refreshed!"); dispatch(); }
psiotr::OtrMessageState OtrInternal::getMessageState(const QString& account, const QString& contact) { ConnContext* context = otrl_context_find(m_userstate, contact.toUtf8().constData(), account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); if (context) { if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT) { return psiotr::OTR_MESSAGESTATE_PLAINTEXT; } else if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED) { return psiotr::OTR_MESSAGESTATE_ENCRYPTED; } else if (context->msgstate == OTRL_MSGSTATE_FINISHED) { return psiotr::OTR_MESSAGESTATE_FINISHED; } } return psiotr::OTR_MESSAGESTATE_UNKNOWN; }
void OtrInternal::deleteFingerprint(const psiotr::Fingerprint& fingerprint) { 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) { if (context->active_fingerprint == fp) { otrl_context_force_finished(context); } otrl_context_forget_fingerprint(fp, true); write_fingerprints(); } } }
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); } } } }
qutimotr::OtrMessageState OtrInternal::getMessageState(const QString& thisJid, const QString& remoteJid, TreeModelItem &item) { ConnContext* context = otrl_context_find(m_userstate, remoteJid.toStdString().c_str(), thisJid.toStdString().c_str(), item.m_protocol_name.toStdString().c_str(), false, NULL, NULL, NULL); if (context != NULL) { if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT) { return qutimotr::OTR_MESSAGESTATE_PLAINTEXT; } else if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED) { return qutimotr::OTR_MESSAGESTATE_ENCRYPTED; } else if (context->msgstate == OTRL_MSGSTATE_FINISHED) { return qutimotr::OTR_MESSAGESTATE_FINISHED; } } return qutimotr::OTR_MESSAGESTATE_UNKNOWN; }
TrustLevel getTrustLevel(const SessionContext &ctx, OtrlUserState userState, otrl_instag_t instance) { ConnContext *context = otrl_context_find( userState, ctx.recipientName.toLocal8Bit(), ctx.accountName.toLocal8Bit(), ctx.protocol.toLocal8Bit(), instance, 0, NULL, NULL, NULL); if(context == nullptr) { qCWarning(KTP_PROXY) << "Could not get trust level"; return TrustLevel::NOT_PRIVATE; } switch(context->msgstate) { case OTRL_MSGSTATE_PLAINTEXT: return TrustLevel::NOT_PRIVATE; case OTRL_MSGSTATE_ENCRYPTED: { if(otrl_context_is_fingerprint_trusted(context->active_fingerprint)) { return TrustLevel::VERIFIED; } else { return TrustLevel::UNVERIFIED; } } case OTRL_MSGSTATE_FINISHED: return TrustLevel::FINISHED; } return TrustLevel::NOT_PRIVATE; }
void OtrInternal::requestAuth(TreeModelItem &item, bool agree, QString answer, QString question) { qutimotr::Fingerprint fingerprint; bool found = false; foreach(fingerprint, getFingerprints()) { if (fingerprint.username == item.m_item_name && fingerprint.account == item.m_account_name ) { found = true; break; } } if(!found) return; ConnContext *context = otrl_context_find(m_userstate,item.m_item_name.toAscii().data(),item.m_account_name.toAscii().data(),item.m_protocol_name.toAscii().data(),0,NULL,NULL,NULL); if(!context) return; if(!question.isNull()) { otrl_message_initiate_smp_q( m_userstate,&m_uiOps,this,context,question.toAscii(),(unsigned char *)answer.toAscii().data(),answer.toAscii().count()); } else if(!answer.isNull()) { otrl_message_initiate_smp(m_userstate,&m_uiOps,this,context,(unsigned char *)answer.toAscii().data(),answer.toAscii().count()); } else // if(agree) { verifyFingerprint(fingerprint, agree); } }
QString OtrInternal::getSessionId(const QString& thisJid, const QString& remoteJid, TreeModelItem &item) { ConnContext* context; context = otrl_context_find(m_userstate, remoteJid.toStdString().c_str(), thisJid.toStdString().c_str(), item.m_protocol_name.toStdString().c_str(), false, NULL, NULL, NULL); if (context != NULL) { QString firstHalf; QString secondHalf; for (unsigned int i = 0; i < context->sessionid_len / 2; i++) { firstHalf.append(QString::number(context->sessionid[i], 16)); } for (unsigned int i = context->sessionid_len / 2; i < context->sessionid_len; i++) { secondHalf.append(QString::number(context->sessionid[i], 16)); } if (context->sessionid_half == OTRL_SESSIONID_FIRST_HALF_BOLD) { return QString("<b>" + firstHalf + "</b>" + secondHalf); } else { return QString(firstHalf + "<b>" + secondHalf + "</b>"); } } return QString(); }
QString OtrInternal::getMessageStateString(const QString& thisJid, const QString& remoteJid, TreeModelItem &item) { qutimotr::OtrMessageState state = getMessageState(thisJid, remoteJid, item); if (state == qutimotr::OTR_MESSAGESTATE_PLAINTEXT) { return tr("not private"); } else if (state == qutimotr::OTR_MESSAGESTATE_ENCRYPTED) { ConnContext* context = otrl_context_find(m_userstate, remoteJid.toStdString().c_str(), thisJid.toStdString().c_str(), item.m_protocol_name.toStdString().c_str(), false, NULL, NULL, NULL); if(context->active_fingerprint->trust&&context->active_fingerprint->trust[0]) return tr("private"); return tr("unverifed"); } else if (state == qutimotr::OTR_MESSAGESTATE_FINISHED) { return tr("finished"); } return tr("unknown"); }
void OtrInternal::startSMP(const QString& account, const QString& contact, const QString& question, const QString& secret) { ConnContext* context = otrl_context_find(m_userstate, contact.toUtf8().constData(), account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); if (context) { QByteArray secretArray = secret.toUtf8(); const char* secretPointer = secretArray.constData(); size_t secretLength = qstrlen(secretPointer); if (question.isEmpty()) { otrl_message_initiate_smp(m_userstate, &m_uiOps, this, context, reinterpret_cast<const unsigned char*>(const_cast<char*>(secretPointer)), secretLength); } else { otrl_message_initiate_smp_q(m_userstate, &m_uiOps, this, context, question.toUtf8().constData(), reinterpret_cast<const unsigned char*>(const_cast<char*>(secretPointer)), secretLength); } } }
/* Look up a connection context by hContact from the given * OtrlUserState. If add_if_missing is true, allocate and return a new * context if one does not currently exist. In that event, call * add_app_data(data, context) so that app_data and app_data_free can be * filled in by the application, and set *addedp to 1. */ ConnContext * otrl_context_find_miranda(OtrlUserState us, MCONTACT hContact) { const char *proto = GetContactProto(hContact); char *username = contact_get_id(hContact); ConnContext* ret = otrl_context_find(us, username, proto, proto, OTRL_INSTAG_BEST, 0, nullptr, nullptr, nullptr); mir_free(username); return ret; }
/** * Return the OtrlMessageState for a context. * i.e. plaintext, encrypted, finished */ OtrlMessageState* OtrConnection::getMessageState(const char* thisJid, const char* remoteJid) { ConnContext* context; context = otrl_context_find(userstate, remoteJid, thisJid, protocolString, false, NULL, NULL, NULL); if (context != NULL) { return &(context->msgstate); } return NULL; }
ConnContext * otrg_context_get_origin(OtrgContextClone *clone) { g_return_val_if_fail(clone != NULL, NULL); return otrl_context_find(otrg_plugin_userstate, clone->username, clone->accountname, clone->protocol, clone->their_instance, FALSE, NULL, NULL, NULL); }
void otrlib_end_session(OtrlUserState user_state, const char *const recipient, char *jid, OtrlMessageAppOps *ops) { ConnContext *context = otrl_context_find(user_state, recipient, jid, "xmpp", 0, NULL, NULL, NULL); if (context) { otrl_message_disconnect(user_state, ops, NULL, jid, "xmpp", recipient); } }
void OtrInternal::respondSMP(ConnContext *context, TreeModelItem &item, const QString &secret, bool initiate) { if( initiate ){ context = otrl_context_find( m_userstate, item.m_item_name.toAscii(), item.m_account_name.toAscii(), item.m_protocol_name.toAscii(), 0, NULL, NULL, NULL); otrl_message_initiate_smp( m_userstate, &m_uiOps, this, context, (unsigned char*)secret.toAscii().data(), secret.toAscii().count() ); } else { otrl_message_respond_smp( m_userstate, &m_uiOps, this, context, (unsigned char*)secret.toAscii().data(), secret.toAscii().count()); } sendCustomNessage(item,tr("Authenticating contact...")); }
void test_unreadable(void) { ConnContext *bobcontext; printf("\n\n*** Testing Bob receiving unreadable messages from " "Alice ***\n\n"); bobcontext = otrl_context_find(us, ALICE, BOB, PROTO, 0, 0, NULL, NULL, NULL); otrl_context_force_plaintext(bobcontext); sending(ALICE, BOB, "unreadable text"); dispatch(); }
bool OtrInternal::isVerified(const QString& account, const QString& contact) { ConnContext* context; context = otrl_context_find(m_userstate, contact.toUtf8().constData(), account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); return isVerified(context); }
void OtrInternal::abortSMP(const QString& account, const QString& contact) { ConnContext* context = otrl_context_find(m_userstate, contact.toUtf8().constData(), account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); if (context) { abortSMP(context); } }
void OtrInternal::expireSession(const QString& account, const QString& contact) { ConnContext* context = otrl_context_find(m_userstate, contact.toUtf8().constData(), account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); if (context && (context->msgstate == OTRL_MSGSTATE_ENCRYPTED)) { otrl_context_force_finished(context); m_callback->stateChange(account, contact, psiotr::OTR_STATECHANGE_GONEINSECURE); } }
QString OtrInternal::getSessionId(const QString& account, const QString& contact) { ConnContext* context; context = otrl_context_find(m_userstate, contact.toUtf8().constData(), account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); if (context && (context->sessionid_len > 0)) { QString firstHalf; QString secondHalf; for (unsigned int i = 0; i < context->sessionid_len / 2; i++) { if (context->sessionid[i] <= 0xf) { firstHalf.append("0"); } firstHalf.append(QString::number(context->sessionid[i], 16)); } for (unsigned int i = context->sessionid_len / 2; i < context->sessionid_len; i++) { if (context->sessionid[i] <= 0xf) { secondHalf.append("0"); } secondHalf.append(QString::number(context->sessionid[i], 16)); } if (context->sessionid_half == OTRL_SESSIONID_FIRST_HALF_BOLD) { return QString("<b>" + firstHalf + "</b> " + secondHalf); } else { return QString(firstHalf + " <b>" + secondHalf + "</b>"); } } return QString(); }
bool OtrInternal::smpSucceeded(const QString& account, const QString& contact) { ConnContext* context; context = otrl_context_find(m_userstate, contact.toUtf8().constData(), account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); if (context) { return context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED; } return false; }
psiotr::Fingerprint OtrInternal::getActiveFingerprint(const QString& account, const QString& contact) { ConnContext* context; context = otrl_context_find(m_userstate, contact.toUtf8().constData(), account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); if (context && context->active_fingerprint) { return psiotr::Fingerprint(context->active_fingerprint->fingerprint, QString::fromUtf8(context->accountname), QString::fromUtf8(context->username), QString::fromUtf8(context->active_fingerprint->trust)); } return psiotr::Fingerprint(); }
void OtrInternal::endSession(const QString& account, const QString& contact) { ConnContext* context = otrl_context_find(m_userstate, contact.toUtf8().constData(), account.toUtf8().constData(), OTR_PROTOCOL_STRING, #if (OTRL_VERSION_MAJOR >= 4) OTRL_INSTAG_BEST, #endif false, NULL, NULL, NULL); if (context && (context->msgstate != OTRL_MSGSTATE_PLAINTEXT)) { m_callback->stateChange(account, contact, psiotr::OTR_STATECHANGE_CLOSE); } otrl_message_disconnect(m_userstate, &m_uiOps, this, account.toUtf8().constData(), OTR_PROTOCOL_STRING, contact.toUtf8().constData() #if (OTRL_VERSION_MAJOR >= 4) ,OTRL_INSTAG_BEST #endif ); }
/* * Find context from nickname and irssi server record. */ ConnContext *otr_find_context(SERVER_REC *irssi, const char *nick, int create) { char *accname = NULL; ConnContext *ctx = NULL; assert(irssi); assert(nick); accname = create_account_name(irssi); if (!accname) { goto error; } ctx = otrl_context_find(user_state_global->otr_state, nick, accname, OTR_PROTOCOL_ID, OTRL_INSTAG_BEST, create, NULL, add_peer_context_cb, irssi); free(accname); error: return ctx; }
/** * Find the secure session id (ssid) for a context. */ QString OtrConnection::getSessionId(const char* thisJid, const char* remoteJid) { ConnContext* context; context = otrl_context_find(userstate, remoteJid, thisJid, protocolString, false, NULL, NULL, NULL); if (context != NULL) { QString firstHalf; QString secondHalf; for (unsigned int i =0; i<context->sessionid_len/2; i++) { firstHalf.append(QString::number(context->sessionid[i], 16)); } for (unsigned int i =context->sessionid_len/2; i<context->sessionid_len; i++) { secondHalf.append(QString::number(context->sessionid[i], 16)); } if (context->sessionid_half == OTRL_SESSIONID_FIRST_HALF_BOLD) { return QString("<b>" + firstHalf + "</b>" + secondHalf); } else { return QString(firstHalf + " <b> " + secondHalf + "</b>"); } } return QString(); }
psiotr::OtrMessageType OtrInternal::decryptMessage(const QString& account, const QString& contact, const QString& cryptedMessage, QString& decrypted) { QByteArray accArray = account.toUtf8(); QByteArray userArray = contact.toUtf8(); const char* accountName = accArray.constData(); const char* userName = userArray.constData(); int ignoreMessage = 0; char* newMessage = NULL; OtrlTLV* tlvs = NULL; OtrlTLV* tlv = NULL; ignoreMessage = otrl_message_receiving(m_userstate, &m_uiOps, this, accountName, OTR_PROTOCOL_STRING, userName, cryptedMessage.toUtf8().constData(), &newMessage, &tlvs, NULL, #if (OTRL_VERSION_MAJOR >= 4) NULL, #endif NULL); tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED); if (tlv) { m_callback->stateChange(accountName, userName, psiotr::OTR_STATECHANGE_REMOTECLOSE); } #if (OTRL_VERSION_MAJOR >= 4) // Magic hack to force it work similar to libotr < 4.0.0. // If user received unencrypted message he (she) should be notified. // See OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED as well. if (ignoreMessage && !newMessage && !cryptedMessage.startsWith("?OTR")) { ignoreMessage = 0; } #else // Check for SMP data (required only with libotr < 4.0.0) ConnContext* context = otrl_context_find(m_userstate, userName, accountName, OTR_PROTOCOL_STRING, false, NULL, NULL, NULL); if (context) { NextExpectedSMP nextMsg = context->smstate->nextExpected; if (context->smstate->sm_prog_state == OTRL_SMP_PROG_CHEATED) { abortSMP(context); // Reset state context->smstate->nextExpected = OTRL_SMP_EXPECT1; context->smstate->sm_prog_state = OTRL_SMP_PROG_OK; // Report result to user m_callback->updateSMP(accountName, userName, -2); } else { tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q); if (tlv) { if (nextMsg != OTRL_SMP_EXPECT1) { abortSMP(context); } else { char* question = (char *)tlv->data; char* eoq = static_cast<char*>(memchr(question, '\0', tlv->len)); if (eoq) { m_callback->receivedSMP(accountName, userName, QString::fromUtf8(question)); } } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1); if (tlv) { if (nextMsg != OTRL_SMP_EXPECT1) { abortSMP(context); } else { m_callback->receivedSMP(accountName, userName, QString()); } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2); if (tlv) { if (nextMsg != OTRL_SMP_EXPECT2) { abortSMP(context); } else { // If we received TLV2, we will send TLV3 and expect TLV4 context->smstate->nextExpected = OTRL_SMP_EXPECT4; // Report result to user m_callback->updateSMP(accountName, userName, 66); } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3); if (tlv) { if (nextMsg != OTRL_SMP_EXPECT3) { abortSMP(context); } else { // SMP finished, reset context->smstate->nextExpected = OTRL_SMP_EXPECT1; // Report result to user m_callback->updateSMP(accountName, userName, 100); } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4); if (tlv) { if (nextMsg != OTRL_SMP_EXPECT4) { abortSMP(context); } else { // SMP finished, reset context->smstate->nextExpected = OTRL_SMP_EXPECT1; // Report result to user m_callback->updateSMP(accountName, userName, 100); } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT); if (tlv) { // SMP aborted, reset context->smstate->nextExpected = OTRL_SMP_EXPECT1; // Report result to user m_callback->updateSMP(accountName, userName, -1); } } } #endif otrl_tlv_free(tlvs); if (ignoreMessage == 1) { // Internal protocol message return psiotr::OTR_MESSAGETYPE_IGNORE; } else if ((ignoreMessage == 0) && newMessage) { // Message has been decrypted, replace it decrypted = QString::fromUtf8(newMessage); otrl_message_free(newMessage); return psiotr::OTR_MESSAGETYPE_OTR; } return psiotr::OTR_MESSAGETYPE_NONE; }
/* PROTO */ void buddy_online(void *c, const char *who) { struct BuddyList *trav, *newbuddy; char *sname; trav = buddylist; sname = simplify_sn(who); if (buddylist == NULL) { buddylist = malloc(sizeof(struct BuddyList)); newbuddy = buddylist; newbuddy->prev = NULL; newbuddy->next = NULL; } else { for (trav = buddylist; trav != NULL; trav = trav->next) { if (strcmp(sname, trav->sn) < 0) break; } newbuddy = malloc(sizeof(struct BuddyList)); if (trav == NULL) { /* if it's the last entry */ for (trav = buddylist; trav->next != NULL; trav = trav->next); trav->next = newbuddy; newbuddy->prev = trav; newbuddy->next = NULL; } else { if (trav == buddylist) { buddylist->prev = newbuddy; newbuddy->prev = NULL; newbuddy->next = buddylist; buddylist = newbuddy; } else { trav->prev->next = newbuddy; newbuddy->prev = trav->prev; newbuddy->next = trav; trav->prev = newbuddy; } } } newbuddy->sn = strdup(sname); newbuddy->formattedsn = strdup(who); newbuddy->away = 0; newbuddy->idle = 0; newbuddy->otr = 0; newbuddy->otr_context = otrl_context_find(userstate, newbuddy->sn, conn->username, otr_proto, OTRL_INSTAG_BEST, 1, 0, NULL, NULL); conn->buddiesonline++; if (conn->squelchconnect) { free(sname); return; } eraseline(); b_echostr(); if (conn->timestamps) { putchar(' '); addts(); } set_color(COLOR_BUDDY_SIGNON); printf(" %s ", who); set_color(0); printf("is now online.\n"); log_event(EVENT_SIGNON, sname, NULL); free(sname); show_prompt(); }
ConnContext* otrlib_context_find(OtrlUserState user_state, const char *const recipient, char *jid) { return otrl_context_find(user_state, recipient, jid, "xmpp", 0, NULL, NULL, NULL); }
/* Send the given IM to the given recipient from the given * accountname/protocol. */ void inject_message_cb(void* opdata, const char* accountname, const char* protocol, const char* recipient, const char* message) { message_t outmsg; message_options_t outmsgopts; message_t* msg = reinterpret_cast<message_t*>(opdata); char* account_name = NULL; ConnContext* conn = NULL; TotrAppData* appdata = NULL; int err; /* Forcibly attempting to create an OTR connection to a mobile device will * do so, with mixed results. This is partly instigated through our UI, as * there is no direct otrl_...() call that fires off a new conversation. * * If OTR won't do this for us, we should validate against our own * is_logged_in_cb callback function that the user is online before sending. */ trillianInitialize(outmsg); memset(&outmsgopts, -1, sizeof(outmsgopts)); outmsgopts.struct_size = sizeof(outmsgopts); outmsgopts.disable_message = outmsgopts.logging_name = outmsgopts.echo_name = NULL; outmsgopts.nicklist = NULL; /* Build our message to inject */ if(msg) { outmsg.connection_id = msg->connection_id; outmsg.type = "outgoing"; outmsg.medium = msg->medium; outmsg.name = msg->name; } else { outmsg.type = "outgoing"; outmsg.medium = _strdup(protocol); outmsg.name = _strdup(recipient); outmsg.display_name = _strdup(account_name); /* Turn echoing off */ messageWindowEchostate(&outmsg, 1); outmsg.text = _strdup(message); outmsg.text_len = static_cast<int>(strlen(message) + 1); OutputDebugString("sent "); OutputDebugString(message); /* Fire in the hole! */ err = plugin_send(MYGUID, "messageSend", &outmsg); /* Turn echoing back on. We're all done now */ messageWindowEchostate(&outmsg, 0); delete [] outmsg.text; delete [] outmsg.name; delete [] outmsg.medium; delete [] outmsg.display_name; return; } /* Check to see if we have a window already. We need this * for echo control. */ if(msg->window_id == -1) { /* Open a window. */ err = plugin_send(MYGUID, "messageSend", &outmsg); OutputDebugString("sent "); OutputDebugString(message); /* Now, find it */ account_name = accountNameLookup(msg->medium, msg->connection_id); conn = otrl_context_find(userstate, msg->name, account_name, msg->medium, 0, NULL, NULL, NULL); /* And fill in our window_ids */ if(conn) { appdata = reinterpret_cast<TotrAppData*>(conn->app_data); if(appdata) outmsg.window_id = msg->window_id = appdata->window_id; } /* Don't forget to clean up our account name */ free(account_name); account_name; } /* Turn echoing off */ messageWindowEchostate(msg, 1); //outmsg.text = new char [strlen(message)]; outmsg.text = _strdup(message); // Fix suggested by http://forums.ceruleanstudios.com/showpost.php?p=831067&postcount=88 outmsg.text_len = static_cast<int>(strlen(message) + 1); //sprintf_s(outmsg.text,outmsg.text_len, "%s", message); //_snprintf(outmsg.text, outmsg.text_len, "%s", message); OutputDebugString("sent "); OutputDebugString(message); /* Fire in the hole! */ err = plugin_send(MYGUID, "messageSend", &outmsg); /* Turn echoing back on. We're all done now */ messageWindowEchostate(msg, 0); delete [] outmsg.text; }