/**
 * 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;	
}
void OtrProxyChannel::Adaptee::sendMessage(const Tp::MessagePartList &message, uint flags,
        const Tp::Service::ChannelProxyInterfaceOTRAdaptor::SendMessageContextPtr &context)
{
    qCDebug(KTP_PROXY);

    if(!connected()) {
        context->setFinishedWithError(KTP_PROXY_ERROR_NOT_CONNECTED, QString::fromLatin1("Proxy is not connected"));
        return;
    }

    OTR::Message otrMessage(message);
    const OTR::CryptResult cres = otrSes.encrypt(otrMessage);
    if(cres == OTR::CryptResult::ERROR) {
        qCDebug(KTP_PROXY) << "Sending error";
        context->setFinishedWithError(KTP_PROXY_ERROR_ENCRYPTION_ERROR,
                QLatin1String("Message could not be encrypted with OTR"));
        return;
    }

    // we are starting an AKE - do not show it to the user
    // policy is probably set to ALWAYS in this case
    if(otrl_proto_message_type(otrMessage.text().toLocal8Bit()) == OTRL_MSGTYPE_QUERY) {
        sendOTRmessage(otrMessage);
    } else {
        PendingSendMessageResult *pending = new PendingSendMessageResult(
                chan->send(otrMessage.parts(), (Tp::MessageSendingFlags) flags),
                chan,
                context,
                message,
                flags);

        connect(pending,
                SIGNAL(finished(Tp::PendingOperation*)),
                SLOT(onPendingSendFinished(Tp::PendingOperation*)));
    }
}
示例#3
0
static void test_otrl_proto_message_type(void)
{
	OtrlMessageType ret;

	const char *test1 = "This is plaintext";
	ret = otrl_proto_message_type(test1);
	ok(ret == OTRL_MSGTYPE_NOTOTR, "Proto message type is not OTR");

	const char *test2 = OTRL_MESSAGE_TAG_BASE "This is plaintext";
	ret = otrl_proto_message_type(test2);
	ok(ret == OTRL_MSGTYPE_TAGGEDPLAINTEXT, "Proto message type is tagged plaintext");

	const char *test3 = "?OTR:AAIC";
	ret = otrl_proto_message_type(test3);
	ok(ret == OTRL_MSGTYPE_DH_COMMIT, "Proto message type v2 is dh commit");

	const char *test4 = "?OTR:AAMC";
	ret = otrl_proto_message_type(test4);
	ok(ret == OTRL_MSGTYPE_DH_COMMIT, "Proto message type v3 is dh commit");

	const char *test5 = "?OTR:AAIK";
	ret = otrl_proto_message_type(test5);
	ok(ret == OTRL_MSGTYPE_DH_KEY, "Proto message type v2 is DH key");

	const char *test6 = "?OTR:AAMK";
	ret = otrl_proto_message_type(test6);
	ok(ret == OTRL_MSGTYPE_DH_KEY, "Proto message type v3 is DH key");

	const char *test7 = "?OTR:AAIR";
	ret = otrl_proto_message_type(test7);
	ok(ret == OTRL_MSGTYPE_REVEALSIG, "Proto message type v2 is revealsig");

	const char *test8 = "?OTR:AAMR";
	ret = otrl_proto_message_type(test8);
	ok(ret == OTRL_MSGTYPE_REVEALSIG, "Proto message type v3 is revealsig");

	const char *test9 = "?OTR:AAIS";
	ret = otrl_proto_message_type(test9);
	ok(ret == OTRL_MSGTYPE_SIGNATURE, "Proto message type v2 is a signature");

	const char *test10 = "?OTR:AAMS";
	ret = otrl_proto_message_type(test10);
	ok(ret == OTRL_MSGTYPE_SIGNATURE, "Proto message type v3 is a signature");

	const char *test11 = "?OTR:AAID";
	ret = otrl_proto_message_type(test11);
	ok(ret == OTRL_MSGTYPE_DATA, "Proto message type v2 is a data msg");

	const char *test12 = "?OTR:AAMD";
	ret = otrl_proto_message_type(test12);
	ok(ret == OTRL_MSGTYPE_DATA, "Proto message type v3 is a data msg");

	const char *test13 = "?OTR?";
	ret = otrl_proto_message_type(test13);
	ok(ret == OTRL_MSGTYPE_QUERY, "Proto message type is a query");

	const char *test14 = "?OTR?v";
	ret = otrl_proto_message_type(test14);
	ok(ret == OTRL_MSGTYPE_QUERY, "Proto message type is a query");

	const char *test15 = "?OTR Error:";
	ret = otrl_proto_message_type(test15);
	ok(ret == OTRL_MSGTYPE_ERROR, "Proto message type is an error");

	const char *test16 = "?OTR: Please verify me";
	ret = otrl_proto_message_type(test16);
	ok(ret == OTRL_MSGTYPE_UNKNOWN, "Proto message type is unknown");

	const char *test17 = "?OTR:AAMA";
	ret = otrl_proto_message_type(test17);
	ok(ret == OTRL_MSGTYPE_UNKNOWN, "Proto message type is unknown");
}
示例#4
0
文件: otr_modify.c 项目: Ri0n/libotr
int main(int argc, char **argv)
{
    unsigned char *mackey;
    size_t mackeylen;
    unsigned char macval[20];
    char *otrmsg = NULL;
    DataMsg datamsg;
    size_t textlen;
    unsigned int offset;
    const unsigned char *old_text, *new_text;
    char *newdatamsg;
    size_t i;

    if (argc != 5) {
	usage(argv[0]);
    }

    argv_to_buf(&mackey, &mackeylen, argv[1]);
    if (!mackey) {
	usage(argv[0]);
    }

    if (mackeylen != 20) {
	fprintf(stderr, "The MAC key must be 40 hex chars long.\n");
	usage(argv[0]);
    }

    textlen = strlen(argv[2]);
    if (textlen != strlen(argv[3])) {
	fprintf(stderr, "The old_text and new_text must be of the same "
		"length.\n");
	usage(argv[0]);
    }
    old_text = (const unsigned char *)argv[2];
    new_text = (const unsigned char *)argv[3];

    if (sscanf(argv[4], "%u", &offset) != 1) {
	fprintf(stderr, "Unparseable offset given.\n");
	usage(argv[0]);
    }

    otrmsg = readotr(stdin);
    if (otrmsg == NULL) {
	fprintf(stderr, "No OTR Data Message found on stdin.\n");
	exit(1);
    }

    if (otrl_proto_message_type(otrmsg) != OTRL_MSGTYPE_DATA) {
	fprintf(stderr, "OTR Non-Data Message found on stdin.\n");
	exit(1);
    }

    datamsg = parse_datamsg(otrmsg);
    free(otrmsg);
    if (datamsg == NULL) {
	fprintf(stderr, "Invalid OTR Data Message found on stdin.\n");
	exit(1);
    }

    /* Check the MAC */
    sha1hmac(macval, mackey, datamsg->macstart,
	    datamsg->macend - datamsg->macstart);
    if (memcmp(macval, datamsg->mac, 20)) {
	fprintf(stderr, "MAC does not verify: wrong MAC key?\n");
	exit(1);
    }

    /* Modify the ciphertext */
    for(i=0; i<textlen && offset+i < datamsg->encmsglen; ++i) {
	datamsg->encmsg[offset+i] ^= (old_text[i] ^ new_text[i]);
    }

    /* Recalculate the MAC */
    newdatamsg = remac_datamsg(datamsg, mackey);
    printf("%s\n", newdatamsg);
    free(newdatamsg);

    free_datamsg(datamsg);
    free(mackey);
    fflush(stdout);
    return 0;
}
示例#5
0
int totrEncryptMessage(int windowID, char* subwindow, char* event, void* data, void* userData) 
{
	edit_event_t* msg = reinterpret_cast<edit_event_t*>(data);
	TotrAppData* eopts = reinterpret_cast<TotrAppData*>(userData);
	char* message = NULL;
	char* newmessage = NULL;
	char* account_name = NULL;
	int res = -1;
	int connection_id = -1;
	ConnContext* conn = userstate->context_root;
	//CAtlRegExp<> reStart, reEnd;
	//CAtlREMatchContext<> mcStart, mcEnd;
	BOOL resStart = FALSE;
	BOOL resEnd = FALSE;

	if(!msg || !reinterpret_cast<char*>(msg->data)
		|| stricmp(event, "edit_sendText") != 0 || !strlen(reinterpret_cast<char*>(msg->data))
		|| (reinterpret_cast<char*>(msg->data)[0]) == '/')
		return 0;
	/* Bail out of parsing any messages starting with /
		* Too bad we can't tell if this is a real command
		* or not without doing some interpretive lists.
		* Even then, such lists would not include other
		* plugins that impliment their own / commands.
		*
		* May need to exclude everything and include
		* /me. Unsure of that.
		*/

	while(conn)
	{
		if(conn->app_data != NULL)
		{
			TotrAppData *appdata = reinterpret_cast<TotrAppData*>(conn->app_data);

			if(appdata->window_id == msg->window_id)
			{
				connection_id = appdata->connection_id;
				break;
			}
		}
		conn = conn->next;
	}

	if(connection_id == -1)
		return 0;

	account_name = accountNameLookup(conn->protocol, connection_id);

	if(!account_name)
		return 0;

	/* Cleanse our text string of the <cursor/> tag Trillian puts in */
	message = _strdup(reinterpret_cast<char*>(msg->data));
	stripCursorTag(message,reinterpret_cast<char*>(msg->data));

#if 0
	char *search = strstr((char *) msg->data, "<cursor/>");

	if (search) {
		char *c = NULL, *s = NULL;
		size_t bufsize=strlen((char *)msg->data)-strlen("<cursor/>")+1;
		c = message = (char *)malloc(bufsize);
		ZeroMemory(c,bufsize);
		ZeroMemory(message,bufsize);
		strncpy(message, (char *)msg->data, search-((char *) msg->data));
		c = c + (search - (char *) msg->data);
		s = search + strlen("<cursor/>");
		strncpy(c, s, strlen(search)-strlen("<cursor/>")+1);
	}
	else
		message = _strdup(reinterpret_cast<char*>(msg->data));

#endif

	res = otrl_message_sending(userstate, &totr_ops, msg,
		account_name, conn->protocol, conn->username, message, 
		NULL, &newmessage, totrNewContext, eopts);

	if(res && !newmessage)
		newmessage = "";
		
	if(newmessage)
	{
		if(totr_config.GetSaveHistory()) 
			if(!totr_config.appendHistory(message,conn->protocol,account_name,conn->username))
				MessageBox(NULL,"Could not save history","ERROR",MB_OK); // Added by Thisita 10/22/11

		message_t msg2;
		message_options_t mopts;
		edit_event_t eet;
		int psres = -1;

		trillianInitialize(msg2);
		trillianInitialize(eet);
		
		memset(&mopts, -1, sizeof(mopts));
		mopts.struct_size = sizeof(mopts);
		mopts.disable_message = mopts.logging_name = mopts.echo_name = NULL;
		mopts.nicklist = NULL;

		reinterpret_cast<TotrAppData*>(conn->app_data)->last_msg = 
			_strdup(reinterpret_cast<char*>(msg->data));
		reinterpret_cast<TotrAppData*>(conn->app_data)->last_msg_len = 
			strlen(reinterpret_cast<char*>(msg->data)) + 1;
	

		eet.window_id = msg->window_id;
		eet.event = "edit_setText";

		if(strlen(newmessage) != 0)
		{
			msg2.connection_id = connection_id;
			msg2.window_id = msg->window_id;
			msg2.name = conn->username;
			msg2.medium = conn->protocol;
			msg2.text = "";
			//msg2.text = _strdup(newmessage);
			msg2.text_len = static_cast<int>(strlen(newmessage) + 1); // Change proposed by Thisita 10/20/11
			msg2.type = "outgoing_privateMessage";
			msg2.extra_information = &mopts;
			msg2.extra_information_size = mopts.struct_size;
			eet.data = newmessage;

			OutputDebugString("sent ");
			OutputDebugString(newmessage);

			if(otrl_proto_message_type(newmessage) != OTRL_MSGTYPE_TAGGEDPLAINTEXT)
			{
				messageWindowEchostate(&msg2, 1);
				psres = plugin_send(MYGUID, "editEventSend", &eet);
				msg2.type="outgoing_privateMessage";
				msg2.text = message; //<HTML><BODY BGCOLOR=\"#ffffff\">greets</BODY></HTML>";
				plugin_send(MYGUID, "messageReceive", &msg2);
			}
		}
	}

	otrl_message_free(newmessage);
	free(account_name);
	account_name = NULL;

	return 0;
}
示例#6
0
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();
}