/** * Decrypt a received message. */ const char* OtrConnection::decryptMessage(const char* from, const char* to, const char* cryptedMessage) { int ignore_message = 0; char *newMessage = NULL; ignore_message = otrl_message_receiving( userstate, &ui_ops, this, to, "prpl-jabber", from, cryptedMessage, &newMessage, NULL, NULL, NULL); if (ignore_message == 1) { // internal protocol message. show user what kind of message was received. QString msg; OtrlMessageType type = otrl_proto_message_type(cryptedMessage); if (type == OTRL_MSGTYPE_NOTOTR) msg = "no OTR Message"; else if (type == OTRL_MSGTYPE_TAGGEDPLAINTEXT) msg= "OTR TaggedPlaintexMessage"; else if (type == OTRL_MSGTYPE_QUERY) msg= "OTR QueryMessage"; else if (type == OTRL_MSGTYPE_DH_COMMIT) msg= "OTR DH-Commit Message"; else if (type == OTRL_MSGTYPE_DH_KEY) msg= "OTR DH-Key Message"; else if (type == OTRL_MSGTYPE_REVEALSIG) msg= "OTR Reveal Signature Message"; else if (type == OTRL_MSGTYPE_SIGNATURE) msg= "OTR Signature Message"; else if (type == OTRL_MSGTYPE_V1_KEYEXCH) msg= "OTR Version 1 Key Exchange Message"; else if (type == OTRL_MSGTYPE_DATA) msg ="OTR Data Message"; else if (type == OTRL_MSGTYPE_ERROR) msg ="OTR Error Message"; else if (type == OTRL_MSGTYPE_UNKNOWN) msg= "OTR Unknown Message"; else msg= "Unknown Message Type"; msg.insert(0, "Received "); QString state = "[" + getMessageStateString(to, from) + "]"; msg.append(" " + state); OtrlMessageState* stateId; stateId = getMessageState(to, from); if (stateId != NULL && *stateId == OTRL_MSGSTATE_ENCRYPTED) { msg.append("\nsessionId: " + getSessionId(to, from)); } char* retMsg = (char*) malloc( msg.length() + 1 ); strcpy(retMsg, msg.toStdString().c_str()); return retMsg; } else if (ignore_message == 0) { if (newMessage != NULL) { // replace message return newMessage; } else { // no otr message char* retMsg = (char*) malloc(strlen(cryptedMessage)+1); strcpy(retMsg, cryptedMessage); return retMsg; } } return NULL; }
char* pass_otr_in_msg(char* account, char* protocol, char* msg) { char *new_message = NULL; OtrlTLV *tlvs = NULL; uint32_t ignore = 0; pthread_mutex_lock(&log_mutex); fprintf(logfd, "Passing incoming msg to OTR from account %s protocol %s payload %s\n", account, protocol, msg); fflush(logfd); pthread_mutex_unlock(&log_mutex); #if defined OTR40 ignore = otrl_message_receiving(us, &ops, NULL, our_account, protocol, account, msg, &new_message, &tlvs, NULL, NULL, NULL); #endif #if defined OTR30 || defined OTR31 || defined OTR32 ignore = otrl_message_receiving(us, &ops, NULL, our_account, protocol, account, msg, &new_message, &tlvs, NULL, NULL); #endif if (new_message) { char *ourm = malloc(strlen(new_message) + 1); if (ourm) { strcpy(ourm, new_message); } otrl_message_free(new_message); new_message = ourm; pthread_mutex_lock(&log_mutex); fprintf(logfd, "New message from OTR message_receiving %s\n", new_message); fflush(logfd); pthread_mutex_unlock(&log_mutex); } if (ignore) { free(new_message); new_message = NULL; } return new_message; }
void receiving(const char *from, const char *to, const char *msg) { int ignore; char *newmsg; OtrlTLV *tlvs; ignore = otrl_message_receiving(us, &ops, NULL, to, PROTO, from, msg, &newmsg, &tlvs, NULL, NULL); if (!ignore) { printf("%s> %s\n\n", from, newmsg ? newmsg : msg); } otrl_message_free(newmsg); otrl_tlv_free(tlvs); }
int otrlib_decrypt_message(OtrlUserState user_state, OtrlMessageAppOps *ops, char *jid, const char *const from, const char *const message, char **decrypted, OtrlTLV **tlvs) { return otrl_message_receiving( user_state, ops, NULL, jid, "xmpp", from, message, decrypted, tlvs, NULL, NULL); }
/* PROTO */ void getmessage(void *c, const char *who, const int automessage, const char *message) { const char *msgin = message; char *msg = NULL, *tempmsg = NULL; char *sname; struct Waiting *wtemp, *wptr = NULL; int offset, foundWaiting = 0; int otr_message = 0; if (conn->otr) { struct BuddyList *buddy = NULL; buddy = find_buddy(who); if (buddy) { if (buddy->otr != -1) { char *newmsg; int ret = otrl_message_receiving(userstate, &ui_ops, NULL, conn->username, otr_proto, buddy->sn, msgin, &newmsg, NULL, &buddy->otr_context, NULL, NULL); if (ret) { #ifdef DEBUG b_echostr_s(); printf("[OTR] debug: internal msg %s\n", msgin); #endif return; } else { if (newmsg) { msgin = strdup(newmsg); otrl_message_free(newmsg); if (buddy->otr_context->msgstate == OTRL_MSGSTATE_ENCRYPTED) otr_message = 1; } } } } } tempmsg = strip_html(msgin); if (tempmsg == NULL) return; if (strlen(tempmsg) == 0) { free(tempmsg); return; } if (conn->netspeak_filter) { msg = undo_netspeak(tempmsg); free(tempmsg); } else { msg = tempmsg; } if (msg == NULL) return; if (strlen(msg) == 0) { free(msg); return; } if (conn->istyping == 0) { if (conn->lastsn != NULL) free(conn->lastsn); conn->lastsn = simplify_sn(who); } sname = simplify_sn(who); if (waiting == NULL) { waiting = malloc(sizeof(struct Waiting)); wptr = waiting; } else { for (wtemp = waiting; wtemp != NULL; wtemp = wtemp->next) if (imcomm_compare_nicks(c, wtemp->sn, who)) { foundWaiting = 1; wptr = wtemp; break; } if (!foundWaiting) { for (wtemp = waiting; wtemp->next != NULL; wtemp = wtemp->next); wtemp->next = malloc(sizeof(struct Waiting)); wptr = wtemp->next; } } if (!foundWaiting) { wptr->sn = strdup(who); wptr->next = NULL; if (conn->isaway && !automessage) { if ((conn->respond_idle_only && conn->isidle) || (!conn->respond_idle_only)) { imcomm_im_send_message(c, who, conn->awaymsg, 1); eraseline(); b_echostr_s(); if (conn->timestamps) { addts(); putchar(' '); } printf("Sent auto-response to %s.\n", who); show_prompt(); } } } #ifdef MESSAGE_QUEUE if (conn->isaway) wptr->mqueue = addToMQueue(wptr->mqueue, msg, who); #endif /* MESSAGE_QUEUE */ eraseline(); if (conn->bell_on_incoming) putchar('\a'); if (conn->timestamps) { addts(); putchar(' '); offset = 11; } else { offset = 0; } offset += strlen(who) + 2; if (automessage) { set_color(COLOR_AUTORESPONSE); printf("*AUTO RESPONSE* "); set_color(0); offset += 16; } set_color(COLOR_INCOMING_IM); if (!otr_message) printf("%s", who); else { offset += 5; printf("(otr)%s", who); } set_color(0); printf(": "); wordwrap_print(msg, offset); if (automessage) log_event(EVENT_IM_AUTORESPONSE, sname, msg); else log_event(EVENT_IM, sname, msg); free(msg); free(sname); show_prompt(); }
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; }
/* * Hand the given message to OTR. * * Returns 0 if its an OTR protocol message or else negative value. */ int otr_receive(SERVER_REC *irssi, const char *msg, const char *from, char **new_msg) { int ret = -1; char *accname = NULL, *full_msg = NULL; const char *recv_msg = NULL; OtrlTLV *tlvs; ConnContext *ctx; struct otr_peer_context *opc; assert(irssi); accname = create_account_name(irssi); if (!accname) { goto error; } IRSSI_DEBUG("Receiving message..."); ctx = otr_find_context(irssi, from, 1); if (!ctx) { goto error; } /* Add peer context to OTR context if none exists */ if (!ctx->app_data) { add_peer_context_cb(irssi, ctx); } opc = ctx->app_data; assert(opc); ret = enqueue_otr_fragment(msg, opc, &full_msg); switch (ret) { case OTR_MSG_ORIGINAL: recv_msg = msg; break; case OTR_MSG_WAIT_MORE: ret = 1; goto error; case OTR_MSG_USE_QUEUE: recv_msg = full_msg; break; case OTR_MSG_ERROR: ret = -1; goto error; } ret = otrl_message_receiving(user_state_global->otr_state, &otr_ops, irssi, accname, OTR_PROTOCOL_ID, from, recv_msg, new_msg, &tlvs, &ctx, add_peer_context_cb, irssi); if (ret) { IRSSI_DEBUG("Ignoring message of length %d from %s to %s.\n" "%s", strlen(msg), from, accname, msg); } else { if (*new_msg) { IRSSI_DEBUG("Converted received message."); } } /* Check for disconnected message */ OtrlTLV *tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED); if (tlv) { otr_status_change(irssi, from, OTR_STATUS_PEER_FINISHED); IRSSI_NOTICE(irssi, from, "%9%s%9 has finished the OTR " "conversation. If you want to continue talking enter " "%9/otr finish%9 for plaintext or %9/otr init%9 to restart.", from); } otrl_tlv_free(tlvs); IRSSI_DEBUG("Message received."); error: if (full_msg) { free(full_msg); } free(accname); return ret; }
QString OtrInternal::decryptMessage(const QString& from, const QString& to, const QString& cryptedMessage, TreeModelItem &item) { QString protocol = item.m_protocol_name; int ignoreMessage = 0; char *newMessage = NULL; OtrlTLV *tlvs = NULL; OtrlTLV *tlv = NULL; ConnContext *context = 0; NextExpectedSMP nextMsg; ignoreMessage = otrl_message_receiving(m_userstate, &m_uiOps, this, to.toStdString().c_str(), protocol.toStdString().c_str(), from.toStdString().c_str(), cryptedMessage.toUtf8().data(), &newMessage, &tlvs, NULL, NULL); context = otrl_context_find( m_userstate, from.toStdString().c_str(), to.toStdString().c_str(), protocol.toStdString().c_str(), 0, NULL, NULL, NULL); // qDebug() << "[OTR] context fragment: " << QString(context->lastmessage); tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED); if( tlv ){ sendCustomNessage(item,tr("%1 has ended the OTR session. You should do the same.").arg(item.m_item_name)); gone_insecure(context); } while (context) { OtrlSMState *state = context->smstate; if(!state) break; nextMsg = state->nextExpected; tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q); if (tlv) { // qDebug() << "[OTR] SMP detected. Found SMP1Q"; //a-la pidgin if (nextMsg != OTRL_SMP_EXPECT1) abortSMP(context,item); else { char *question = (char *)tlv->data; char *eoq = (char*)memchr(question, '\0', tlv->len); if (eoq) { QString ans = QInputDialog::getText(NULL,tr("Auth"),tr("Please, answer the question to be authorised by %1.<br>Question: <b>%2</b>").arg(from).arg(QString(question))); if(!ans.isEmpty()) respondSMP(context,item,ans,false); else abortSMP(context,item); } } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1); if (tlv) { // qDebug() << "[OTR] SMP detected. Found SMP1"; if (nextMsg != OTRL_SMP_EXPECT1 ){ abortSMP( context, item ); } else { QString s = QInputDialog::getText ( NULL, tr("Authorysing"), tr("Please, enter passphrase to authorise %1").arg(context->username), QLineEdit::Normal); if(!s.isEmpty()) respondSMP(context,item,s,false); else abortSMP(context,item); } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2); if (tlv) { // qDebug() << "[OTR] SMP detected. Found SMP2"; if (nextMsg != OTRL_SMP_EXPECT2){ abortSMP( context, item ); } else { context->smstate->nextExpected = OTRL_SMP_EXPECT4; } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3); if (tlv) { // qDebug() << "[OTR] SMP detected. Found SMP3"; if (nextMsg != OTRL_SMP_EXPECT3){ abortSMP( context, item ); } else { if (context->active_fingerprint->trust && context->active_fingerprint->trust[0]) { sendCustomNessage(item, tr("Your buddy has successfully authenticated you. The conversation is now secure!")); gone_secure(context); } else { // sendCustomNessage(item, tr("Authentication failed. The conversation is now insecure!")); sendCustomNessage(item,tr("Your buddy has successfully authenticated you. You may want to authenticate your buddy as well by asking your own question.")); gone_secure(context); } context->smstate->nextExpected = OTRL_SMP_EXPECT1; } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4); if (tlv) { // qDebug() << "[OTR] SMP detected. Found SMP4"; if (nextMsg != OTRL_SMP_EXPECT4) { abortSMP( context, item ); } else { if (context->active_fingerprint->trust && context->active_fingerprint->trust[0]) { sendCustomNessage(item, tr("Authentication successful. The conversation is now secure!")); gone_secure(context); } else { sendCustomNessage(item, tr("Authentication failed. The conversation is now insecure!")); gone_secure(context); } context->smstate->nextExpected = OTRL_SMP_EXPECT1; } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT); if (tlv) { // qDebug() << "[OTR] SMP detected. Found SMP_ABORT"; sendCustomNessage(item,tr("Authentication error!").toLocal8Bit() ); context->smstate->nextExpected = OTRL_SMP_EXPECT1; } otrl_tlv_free(tlvs); break; } if (ignoreMessage == 1) // internal protocol message { OtrlMessageType type = otrl_proto_message_type( cryptedMessage.toStdString().c_str()); QString retMessage("<Internal OTR message>\n"+tr("received %1 \nOTR state now is [%2]").arg(otrlMessageTypeToString(type)).arg(getMessageStateString(to, from, item))) ; if (getMessageState(to, from, item) == qutimotr::OTR_MESSAGESTATE_ENCRYPTED) { retMessage.append(tr("\nsessionId: ") + getSessionId(to, from, item)); } // TODO: если бы эти сообщения можна было заблокировать... // но recivelevel1/2 не дает такой возможности... почему то // хотя в вики написано обратное // sendCustomNessage(item,retMessage); return retMessage; } else if (ignoreMessage == 0) { if (newMessage != NULL) // message has been decrypted. replace it { QString retMessage = QString::fromUtf8(newMessage); otrl_message_free(newMessage); return retMessage; } else // received message was not an otr message { return cryptedMessage; } } assert(false); return QString(); }
int main(){ OTRL_INIT; OtrlUserState userstate; char *newmessage = NULL; char *nlmsg=NULL; OtrlMessageAppOps ui_ops; int sockfd, clientfd, recvbytes, recv_ret; socklen_t sin_size; char buf[1024], pwdbuf[1024]; char *dbuf; struct sockaddr_in remote_addr, my_addr; fd_set fds; int one = 1; /* initialize ui callbacks */ memset(&ui_ops, 0, sizeof(OtrlMessageAppOps)); ui_ops.inject_message= inject_msg; ui_ops.gone_secure=gone_secure; printf("\033[31mStarting driver...\033[0m\n"); /* initialize socket connection */ sockfd = socket(AF_INET, SOCK_STREAM, 0); my_addr.sin_family=AF_INET; my_addr.sin_port= htons(3333); my_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(my_addr.sin_zero),8); /* Allow rebinding to address */ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } if (listen(sockfd, 1) == -1) { perror("listen"); exit(1); } sin_size = sizeof(struct sockaddr_in); if ((clientfd = accept(sockfd, (struct sockaddr *)&remote_addr, \ &sin_size)) == -1) { perror("accept"); } printf("\033[31mConnected to Bob\033[0m\n"); /* create userstate, and read the private key */ userstate = otrl_userstate_create(); getcwd(pwdbuf, 1024); strcat(pwdbuf, "/private_key"); otrl_privkey_read(userstate, pwdbuf); /* Clients send messages asynchronously*/ while(1){ FD_ZERO(&fds); FD_SET(0, &fds); FD_SET(clientfd, &fds); select(clientfd+1, &fds, NULL, NULL, NULL); if(FD_ISSET(0, &fds)){ /* send message */ fgets(buf, 1023, stdin); buf[strlen(buf)-1]= '\0'; printf("\033[31mTo OTR:%d:\033[0m%s\n\033[0m",strlen(buf), buf); dbuf = strdup(buf); otrl_message_sending(userstate, &ui_ops, NULL, "*****@*****.**", "msn", "*****@*****.**", &dbuf, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP, NULL, NULL, NULL, NULL); free(dbuf); nlmsg = (char*)malloc(strlen(newmessage)+2); memcpy(nlmsg, newmessage, strlen(newmessage)); nlmsg[strlen(newmessage)]='\n'; nlmsg[strlen(newmessage)+1]='\0'; send(clientfd, nlmsg, strlen(nlmsg), 0); printf("\033[31mTo network:%d:\033[35m%s\033[0m\n\033[0m", strlen(newmessage), newmessage); }else{ /*receive message */ recvbytes=recv(clientfd, buf, MAXDATASIZE, 0); if(recvbytes==0) break; recvbytes--; buf[recvbytes] = '\0'; if(buf[recvbytes-1]=='\r'){ recvbytes--; buf[recvbytes]='\0'; } printf("\033[31mFrom network:%d:\033[35m %s\033[0m\n",recvbytes, buf); recv_ret=otrl_message_receiving(userstate, &ui_ops, &clientfd, "*****@*****.**", "msn", "*****@*****.**", buf, &newmessage, NULL, NULL, NULL, NULL, NULL); if(recv_ret==0) printf("\033[31mFrom OTR:%d:\033[0m %s\n", newmessage ? strlen(newmessage) : 0, newmessage); } } return 0; }