示例#1
0
文件: module.c 项目: DrWhax/irssi-otr
/*
 * Pipes all incoming private messages through OTR
 */
void sig_message_private(SERVER_REC *server, const char *msg,
		const char *nick, const char *address)
{
	int ret;
	char *new_msg = NULL;

	key_gen_check();

	ret = otr_receive(server, msg, nick, &new_msg);
	if (ret) {
		signal_stop();
		goto end;
	}

	if (!new_msg) {
		/* This message was not OTR */
		signal_continue(4, server, msg, nick, address);
	} else {
		/* OTR received message */
		signal_continue(4, server, new_msg, nick, address);
	}

end:
	otrl_message_free(new_msg);
	return;
}
示例#2
0
文件: module.c 项目: ahf/irssi-otr
/*
 * Pipes all outgoing private messages through OTR
 */
static void sig_server_sendmsg(SERVER_REC *server, const char *target,
		const char *msg, void *target_type_p)
{
	int ret;
	char *otrmsg = NULL;

	key_gen_check();

	if (GPOINTER_TO_INT(target_type_p) != SEND_TARGET_NICK) {
		goto end;
	}

	/* Critical section. On error, message MUST NOT be sent */
	ret = otr_send(server, msg, target, &otrmsg);
	if (ret) {
		signal_stop();
		goto end;
	}

	if (!otrmsg) {
		/* Send original message */
		signal_continue(4, server, target, msg, target_type_p);
	} else {
		/* Send encrypted message */
		signal_continue(4, server, target, otrmsg, target_type_p);
	}

end:
	otrl_message_free(otrmsg);
	return;
}
示例#3
0
QString OtrInternal::encryptMessage(const QString& from, const QString& to,
                                      const QString& message, TreeModelItem &item)
{
    QString protocol = item.m_protocol_name;
    char* encMessage = NULL;
    gcry_error_t err;

    err = otrl_message_sending(m_userstate, &m_uiOps, this,
                               from.toStdString().c_str(), protocol.toStdString().c_str(),
                               to.toStdString().c_str(),
                               message.toUtf8().data(),
                               NULL, &encMessage, NULL, NULL);
    if (err != 0)
    {
        QMessageBox mb(QMessageBox::Critical, tr("qutim-otr"),
                       tr("Encrypting message from %1 to %2 failed.").arg(QString(from)).arg(QString(to)) + "\n" +
                       tr("The message was not sent."),
                       QMessageBox::Ok, NULL,
                       Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
        mb.exec();
        return QString();
    }

    if (encMessage != NULL)
    {
        QString retMessage(QString::fromUtf8(encMessage));
        otrl_message_free(encMessage);

        return retMessage;
    }
    return message;
}
示例#4
0
文件: module.c 项目: ahf/irssi-otr
/*
 * Handle /me IRC command.
 */
static void cmd_me(const char *data, IRC_SERVER_REC *server,
		WI_ITEM_REC *item)
{
	int ret;
	const char *target;
	char *msg, *otrmsg = NULL;
	QUERY_REC *query;

	query = QUERY(item);

	key_gen_check();

	if (!query || !query->server) {
		goto end;
	}

	CMD_IRC_SERVER(server);
	if (!IS_IRC_QUERY(query)) {
		goto end;
	}

	if (!server || !server->connected) {
		cmd_return_error(CMDERR_NOT_CONNECTED);
	}

	target = window_item_get_target(item);

	ret = asprintf(&msg, OTR_IRC_MARKER_ME "%s", data);
	if (ret < 0) {
		goto end;
	}

	/* Critical section. On error, message MUST NOT be sent */
	ret = otr_send(query->server, msg, target, &otrmsg);
	free(msg);

	if (!otrmsg) {
		goto end;
	}

	signal_stop();

	if (otrmsg) {
		/* Send encrypted message */
		irssi_send_message(SERVER(server), target, otrmsg);
		otrl_message_free(otrmsg);
	}

	signal_emit("message irc own_action", 3, server, data, item->visible_name);

end:
	return;
}
示例#5
0
文件: tests.c 项目: Ri0n/libotr
static void sending(const char *from, const char *to, const char *msg)
{
    gcry_error_t err;
    OtrlTLV *tlvs = NULL;
    char *newmsg;

    err = otrl_message_sending(us, &ops, NULL, from, PROTO, to, msg,
	    tlvs, &newmsg, NULL, NULL, NULL);

    if (!err) {
	inject(from, to, newmsg ? newmsg : msg);
    }

    otrl_message_free(newmsg);
    otrl_tlv_free(tlvs);
}
示例#6
0
文件: tests.c 项目: Ri0n/libotr
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);
}
示例#7
0
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;
}
示例#8
0
char* pass_otr_out_msg(uint32_t id, char* account, char* protocol, char* message) {
    char *new_message = NULL;    
    gcry_error_t err;

    pthread_mutex_lock(&log_mutex);
    fprintf(logfd, "Passing to OTR message_sending %s to account %s protocol %s\n", message, account, protocol);
    fflush(logfd);
    pthread_mutex_unlock(&log_mutex);

#ifdef OTR40
#ifdef FRAG40
    err = otrl_message_sending(us, &ops, NULL,
	    our_account, protocol, account, OTRL_INSTAG_BEST, message, NULL, &new_message,
	    OTRL_FRAGMENT_SEND_ALL_BUT_LAST, NULL, NULL, NULL);
#else
    err = otrl_message_sending(us, &ops, NULL,
	    our_account, protocol, account, OTRL_INSTAG_BEST, message, NULL, &new_message,
	    OTRL_FRAGMENT_SEND_SKIP, NULL, NULL, NULL);
#endif
#endif

#if defined OTR30 || defined OTR31 || defined OTR32
    err = otrl_message_sending(us, &ops, NULL,
	    our_account, protocol, account, message, NULL, &new_message,
	    NULL, NULL);
#endif

    if (new_message) {
      char *ourm = strdup(new_message);

      write_query_response(id, new_message); /* send modified message back */ 
      
      otrl_message_free(new_message);
      new_message = ourm;
    }

  if (err) {
    	/* Do not send out plain text */
    	char *ourm = strdup("");
    	new_message = ourm;
  }

  return new_message;
}
QString OtrInternal::encryptMessage(const QString& account, const QString& contact,
                                    const QString& message)
{
    char* encMessage = NULL;
    gcry_error_t err;

    err = otrl_message_sending(m_userstate, &m_uiOps, this,
                               account.toUtf8().constData(), OTR_PROTOCOL_STRING,
                               contact.toUtf8().constData(),
#if (OTRL_VERSION_MAJOR >= 4)
                               OTRL_INSTAG_BEST,
#endif
                               message.toUtf8().constData(),
                               NULL, &encMessage,
#if (OTRL_VERSION_MAJOR >= 4)
                               OTRL_FRAGMENT_SEND_SKIP,
                               NULL,
#endif
                               NULL, NULL);
    if (err)
    {
        QString err_message = QObject::tr("Encrypting message to %1 "
                                          "failed.\nThe message was not sent.")
                                          .arg(contact);
        if (!m_callback->displayOtrMessage(account, contact, err_message))
        {
            m_callback->notifyUser(account, contact, err_message, psiotr::OTR_NOTIFY_ERROR);
        }
        return QString();
    }

    if (encMessage)
    {
        QString retMessage(QString::fromUtf8(encMessage));
        otrl_message_free(encMessage);

        return retMessage;
    }
    return message;
}
示例#10
0
文件: module.c 项目: ahf/irssi-otr
/*
 * Pipes all incoming private messages through OTR
 */
void sig_message_private(SERVER_REC *server, const char *msg,
		const char *nick, const char *address)
{
	int ret;
	char *new_msg = NULL;

	key_gen_check();

	ret = otr_receive(server, msg, nick, &new_msg);
	if (ret) {
		signal_stop();
		goto end;
	}

	if (!new_msg) {
		/* This message was not OTR */
		signal_continue(4, server, msg, nick, address);
	} else {
		/*
		 * Check for /me IRC marker and if so, handle it so the user does not
		 * receive a message beginning with /me but rather let irssi handle it
		 * as a IRC action.
		 */
		if (!strncmp(new_msg, OTR_IRC_MARKER_ME, OTR_IRC_MARKER_ME_LEN)) {
			signal_stop();
			signal_emit("message irc action", 5, server,
					new_msg + OTR_IRC_MARKER_ME_LEN, nick, address, nick);
		} else {
			/* OTR received message */
			signal_continue(4, server, new_msg, nick, address);
		}
	}

end:
	otrl_message_free(new_msg);
	return;
}
示例#11
0
文件: aim.c 项目: esseye/bsflite-otr
/* 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();
}
示例#12
0
void
otr_free_message(char *message)
{
    otrl_message_free(message);
}
示例#13
0
static void
_otr_free_message(char *message)
{
    otrl_message_free(message);
}
示例#14
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;
}
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;
}
示例#16
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();
}