Пример #1
0
void XPath::ProcessPath(LookupInfo &info, bool bCreate)
{
    if (!info.nodeName) return;

    TCHAR *nodeName = (TCHAR *)alloca(sizeof(TCHAR) * (info.nodeName.length+1));
    lstrcpyn(nodeName, info.nodeName.p, info.nodeName.length+1);

    if (info.attrName && info.attrValue) {
        TCHAR *attrName = (TCHAR *)alloca(sizeof(TCHAR)* (info.attrName.length + 1));
        lstrcpyn(attrName, info.attrName.p, info.attrName.length + 1);
        TCHAR *attrValue = (TCHAR *)alloca(sizeof(TCHAR)* (info.attrValue.length + 1));
        lstrcpyn(attrValue, info.attrValue.p, info.attrValue.length + 1);
        HXML hXml = xmlGetChildByTag(m_hXml, nodeName, attrName, attrValue);

        m_hXml = (hXml || !bCreate) ? hXml : (m_hXml << XCHILD(nodeName) << XATTR(attrName, attrValue));
    }
    else if (info.nodeIndex) {
        int idx = _ttoi(info.nodeIndex.p);
        m_hXml = lstrcmp(nodeName, _T("*")) ? xmlGetNthChild(m_hXml, nodeName, idx) : xmlGetChild(m_hXml, idx - 1);
    }
    else {
        HXML hXml = xmlGetChild(m_hXml, nodeName);
        m_hXml = (hXml || !bCreate) ? hXml : (m_hXml << XCHILD(nodeName));
    }

    info.Reset();
}
Пример #2
0
void scroll( short n )
{
	register row, col;

	if (!OPEN) return;

	col = 0;
	for ( row = 0; row < (HEIGHT-1); row++ )
		copy_row( WIDTH, (short *)&XCHAR(row+1,col), (short *)&CHAR(row,col), (short *)&XCHAR(row,col) );

//		for ( col = 0; col < WIDTH; col++ )
//		{
//			CHAR( row, col ) = XCHAR( row+1, col );
//			ATTR( row, col ) = XATTR( row+1, col );
//			XCHAR( row, col ) = XCHAR( row+1, col );
//			XATTR( row, col ) = XATTR( row+1, col );
//		}

	for ( col = 0; col < WIDTH; col++ )
	{
		CHAR( HEIGHT-1, col ) = ' ';
		ATTR( HEIGHT-1, col ) = XATTR( HEIGHT-1, col );
		XCHAR( HEIGHT-1, col ) = ' ';
	}

}
Пример #3
0
void CJabberProto::RetrieveMessageArchive(MCONTACT hContact, JABBER_LIST_ITEM *pItem)
{
	if (pItem->bHistoryRead)
		return;

	pItem->bHistoryRead = TRUE;

	XmlNodeIq iq( AddIQ(&CJabberProto::OnIqResultGetCollectionList, JABBER_IQ_TYPE_GET));
	HXML list = iq << XCHILDNS( _T("list"), JABBER_FEAT_ARCHIVE) << XATTR(_T("with"), pItem->jid);

	time_t tmLast = getDword(hContact, "LastCollection", 0);
	if (tmLast) {
		TCHAR buf[40];
		list << XATTR(_T("start"), time2str(tmLast, buf, SIZEOF(buf)));
	}
	m_ThreadInfo->send(iq);
}
Пример #4
0
void CJabberProto::IbbSendThread(JABBER_IBB_TRANSFER *jibb)
{
    debugLogA("Thread started: type=ibb_send");

    jibb->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    jibb->bStreamInitialized = FALSE;
    jibb->bStreamClosed = FALSE;
    jibb->state = JIBB_SENDING;

    m_ThreadInfo->send(
        XmlNodeIq( AddIQ(&CJabberProto::OnIbbInitiateResult, JABBER_IQ_TYPE_SET, jibb->dstJID, 0, -1, jibb))
        << XCHILDNS(_T("open"), JABBER_FEAT_IBB) << XATTR(_T("sid"), jibb->sid) << XATTRI(_T("block-size"), JABBER_IBB_BLOCK_SIZE)
        << XATTR(_T("stanza"), _T("message")));

    WaitForSingleObject(jibb->hEvent, INFINITE);
    CloseHandle(jibb->hEvent);
    jibb->hEvent = NULL;

    if (jibb->bStreamInitialized) {
        jibb->wPacketId = 0;

        BOOL bSent = (this->*jibb->pfnSend)(JABBER_IBB_BLOCK_SIZE, jibb->ft);

        if (!jibb->bStreamClosed) {
            jibb->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

            m_ThreadInfo->send(
                XmlNodeIq( AddIQ(&CJabberProto::OnIbbCloseResult, JABBER_IQ_TYPE_SET, jibb->dstJID, 0, -1, jibb))
                << XCHILDNS(_T("close"), JABBER_FEAT_IBB) << XATTR(_T("sid"), jibb->sid));

            WaitForSingleObject(jibb->hEvent, INFINITE);
            CloseHandle(jibb->hEvent);
            jibb->hEvent = NULL;

            if (jibb->bStreamClosed && bSent)
                jibb->state = JIBB_DONE;
        }
        else jibb->state = JIBB_ERROR;
    }

    (this->*jibb->pfnFinal)((jibb->state==JIBB_DONE)?TRUE:FALSE, jibb->ft);
    jibb->ft = NULL;
    JabberIbbFreeJibb(jibb);
}
Пример #5
0
HWND __cdecl CJabberProto::SearchAdvanced( HWND hwndDlg )
{
	if ( !m_bJabberOnline || !hwndDlg )
		return 0;	//error

	JabberSearchData * dat=(JabberSearchData *)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
	if ( !dat )
		return 0; //error

	// check if server connected (at least one field exists)
	if ( dat->nJSInfCount == 0 )
		return 0;

	// formating request
	BOOL fRequestNotEmpty=FALSE;

	// get server name
	TCHAR szServerName[100];
	GetDlgItemText( hwndDlg, IDC_SERVER, szServerName, SIZEOF( szServerName ));

	// formating query
	int iqId = SerialNext();
	XmlNodeIq iq( _T("set"), iqId, szServerName );
	HXML query = iq << XQUERY( _T("jabber:iq:search"));
	
	if ( m_tszSelectedLang )
		iq << XATTR( _T("xml:lang"), m_tszSelectedLang ); // i'm sure :)

	// next can be 2 cases:
	// Forms: XEP-0055 Example 7
	if ( dat->fSearchRequestIsXForm ) {
		fRequestNotEmpty=TRUE;
		HXML n = JabberFormGetData(GetDlgItem(hwndDlg, IDC_FRAME), dat->xNode);
		xmlAddChild( query, n );
		xi.destroyNode( n );
    }
	else { //and Simple fields: XEP-0055 Example 3
		for ( int i=0; i<dat->nJSInfCount; i++ ) {
			TCHAR szFieldValue[100];
			GetWindowText(dat->pJSInf[i].hwndValueItem, szFieldValue, SIZEOF(szFieldValue));
			if ( szFieldValue[0] != _T('\0')) {
				xmlAddChild( query, dat->pJSInf[i].szFieldName, szFieldValue );
				fRequestNotEmpty=TRUE;
	}	}	}

	if ( fRequestNotEmpty ) {
		// register search request result handler
		IqAdd( iqId, IQ_PROC_GETSEARCH, &CJabberProto::OnIqResultAdvancedSearch );
		// send request
		m_ThreadInfo->send( iq );
		return ( HWND )iqId;
	}
	return 0;
}
Пример #6
0
void CJabberProto::OnIqResultGetCollectionList(HXML iqNode, CJabberIqInfo*)
{
	const TCHAR *to = xmlGetAttrValue(iqNode, _T("to"));
	if (to == NULL || mir_tstrcmp( xmlGetAttrValue(iqNode, _T("type")), _T("result")))
		return;

	HXML list = xmlGetChild(iqNode, "list");
	if (!list || mir_tstrcmp( xmlGetAttrValue(list, _T("xmlns")), JABBER_FEAT_ARCHIVE))
		return;

	MCONTACT hContact = NULL;
	time_t tmLast = 0;

	for (int nodeIdx = 1; ; nodeIdx++) {
		HXML itemNode = xmlGetNthChild(list, _T("chat"), nodeIdx);
		if (!itemNode)
			break;

		const TCHAR* start = xmlGetAttrValue(itemNode, _T("start"));
		const TCHAR* with  = xmlGetAttrValue(itemNode, _T("with"));
		if (!start || !with)
			continue;

		if (hContact == NULL) {
			if ((hContact = HContactFromJID(with)) == NULL)
				continue;

			tmLast = getDword(hContact, "LastCollection", 0);
		}

		m_ThreadInfo->send(
			XmlNodeIq( AddIQ(&CJabberProto::OnIqResultGetCollection, JABBER_IQ_TYPE_GET))
				<< XCHILDNS( _T("retrieve"), JABBER_FEAT_ARCHIVE) << XATTR(_T("with"), with) << XATTR(_T("start"), start));

		time_t tmThis = str2time(start);
		if ( tmThis > tmLast) {
			tmLast = tmThis;
			setDword(hContact, "LastCollection", tmLast+1);
		}
	}
}
Пример #7
0
void CJabberProto::ProcessOutgoingNote(CNoteItem *pNote, bool ok)
{
	if (!ok || !pNote->IsNotEmpty())
	{
		delete pNote;
		return;
	}

	TCHAR buf[1024];
	mir_sntprintf(buf, SIZEOF(buf), _T("Incoming note: %s\n\n%s\nTags: %s"), 
		pNote->GetTitle(), pNote->GetText(), pNote->GetTagsStr());

	JabberCapsBits jcb = GetResourceCapabilites( pNote->GetFrom(), TRUE );

	if ( jcb & JABBER_RESOURCE_CAPS_ERROR )
		jcb = JABBER_RESOURCE_CAPS_NONE;

	int nMsgId = SerialNext();

	XmlNode m(_T("message"));
	m << XATTR(_T("type"), _T("chat")) << XATTR( _T("to"), pNote->GetFrom() ) << XATTRID( nMsgId );
	m << XCHILD(_T("body"), buf);
	HXML hXmlItem = m << XCHILDNS(_T("x"), _T(JABBER_FEAT_MIRANDA_NOTES)) << XCHILD(_T("note"));
	hXmlItem << XATTR(_T("tags"), pNote->GetTagsStr());
	hXmlItem << XCHILD(_T("title"), pNote->GetTitle());
	hXmlItem << XCHILD(_T("text"), pNote->GetText());

	// message receipts XEP priority
	if ( jcb & JABBER_CAPS_MESSAGE_RECEIPTS )
		m << XCHILDNS( _T("request"), _T(JABBER_FEAT_MESSAGE_RECEIPTS));
	else if ( jcb & JABBER_CAPS_MESSAGE_EVENTS ) {
		HXML x = m << XCHILDNS( _T("x"), _T(JABBER_FEAT_MESSAGE_EVENTS));
		x << XCHILD( _T("delivered")); x << XCHILD( _T("offline"));
	}
	else
		nMsgId = -1;

	m_ThreadInfo->send(m);
	delete pNote;
}
Пример #8
0
void __cdecl CJabberProto::OnAddContactForever( DBCONTACTWRITESETTING* cws, HANDLE hContact )
{
	if ( cws->value.type != DBVT_DELETED && !( cws->value.type==DBVT_BYTE && cws->value.bVal==0 ))
		return;

	DBVARIANT jid, dbv;
	if ( JGetStringT( hContact, "jid", &jid ))
		return;

	TCHAR *nick;
	Log( "Add " TCHAR_STR_PARAM " permanently to list", jid.pszVal );
	if ( !DBGetContactSettingTString( hContact, "CList", "MyHandle", &dbv )) {
		nick = mir_tstrdup( dbv.ptszVal );
		JFreeVariant( &dbv );
	}
	else if ( !JGetStringT( hContact, "Nick", &dbv )) {
		nick = mir_tstrdup( dbv.ptszVal );
		JFreeVariant( &dbv );
	}
	else nick = JabberNickFromJID( jid.ptszVal );
	if ( nick == NULL ) {
		JFreeVariant( &jid );
		return;
	}

	if ( !DBGetContactSettingTString( hContact, "CList", "Group", &dbv )) {
		AddContactToRoster( jid.ptszVal, nick, dbv.ptszVal );
		JFreeVariant( &dbv );
	}
	else AddContactToRoster( jid.ptszVal, nick, NULL );

	m_ThreadInfo->send( XmlNode( _T("presence")) << XATTR( _T("to"), jid.ptszVal ) << XATTR( _T("type"), _T("subscribe")));

	SendGetVcard( jid.ptszVal );

	mir_free( nick );
	DBDeleteContactSetting( hContact, "CList", "Hidden" );
	JFreeVariant( &jid );
}
Пример #9
0
BOOL CJabberProto::OnHandleDiscoItemsRequest(HXML iqNode, CJabberIqInfo *pInfo)
{
	if (!pInfo->GetChildNode())
		return TRUE;

	// ad-hoc commands check:
	const TCHAR *szNode = XmlGetAttrValue(pInfo->GetChildNode(), _T("node"));
	if (szNode && m_adhocManager.HandleItemsRequest(iqNode, pInfo, szNode))
		return TRUE;

	// another request, send empty result
	XmlNodeIq iq(_T("result"), pInfo);
	HXML resultQuery = iq << XQUERY(JABBER_FEAT_DISCO_ITEMS);
	if (szNode)
		XmlAddAttr(resultQuery, _T("node"), szNode);

	if (!szNode && m_options.EnableRemoteControl)
		resultQuery << XCHILD(_T("item")) << XATTR(_T("jid"), m_ThreadInfo->fullJID)
		<< XATTR(_T("node"), JABBER_FEAT_COMMANDS) << XATTR(_T("name"), _T("Ad-hoc commands"));

	m_ThreadInfo->send(iq);
	return TRUE;
}
Пример #10
0
// XEP-0224 support (Attention/Nudge)
INT_PTR __cdecl CJabberProto::JabberSendNudge(WPARAM wParam, LPARAM)
{
	if (!m_bJabberOnline)
		return 0;

	HANDLE hContact = (HANDLE)wParam;
	ptrT jid( getTStringA(hContact, "jid"));
	if (jid == NULL)
		return 0;

	TCHAR tszJid[JABBER_MAX_JID_LEN];
	TCHAR *szResource = ListGetBestClientResourceNamePtr(jid);
	if (szResource)
		mir_sntprintf(tszJid, SIZEOF(tszJid), _T("%s/%s"), jid, szResource);
	else
		mir_sntprintf(tszJid, SIZEOF(tszJid), _T("%s"), jid);

	JabberCapsBits jcb = GetResourceCapabilites(tszJid, FALSE);
	m_ThreadInfo->send(
		XmlNode(_T("message")) << XATTR(_T("type"), _T("headline")) << XATTR(_T("to"), tszJid)
			<< XCHILDNS(_T("attention"), JABBER_FEAT_ATTENTION));
	return 0;
}
Пример #11
0
void mrefresh(short n)
{
	short row, col;

	if (!OPEN) return;

	for (row=-1; row<HEIGHT+1; row++ )
		for (col=-1; col<WIDTH+1; col++ )  {
			CHAR(row,col) = XCHAR(row,col);
			ATTR(row,col) = XATTR(row,col);
		}

	msetcursor( ROW+CROW, COL+CCOL );

}
Пример #12
0
BOOL CJabberProto::OnSiRequest(HXML node, CJabberIqInfo *pInfo)
{
	const TCHAR *szProfile = XmlGetAttrValue(pInfo->GetChildNode(), _T("profile"));

	if (szProfile && !mir_tstrcmp(szProfile, JABBER_FEAT_SI_FT))
		FtHandleSiRequest(node);
	else {
		XmlNodeIq iq(_T("error"), pInfo);
		HXML error = iq << XCHILD(_T("error")) << XATTRI(_T("code"), 400) << XATTR(_T("type"), _T("cancel"));
		error << XCHILDNS(_T("bad-request"), _T("urn:ietf:params:xml:ns:xmpp-stanzas"));
		error << XCHILD(_T("bad-profile"));
		m_ThreadInfo->send(iq);
	}
	return TRUE;
}
Пример #13
0
BOOL CJabberProto::SendHttpAuthReply(CJabberHttpAuthParams *pParams, BOOL bAuthorized)
{
	if (!m_bJabberOnline || !pParams || !m_ThreadInfo)
		return FALSE;

	if (pParams->m_nType == CJabberHttpAuthParams::IQ) {
		XmlNodeIq iq(bAuthorized ? _T("result") : _T("error"), pParams->m_szIqId, pParams->m_szFrom);
		if (!bAuthorized) {
			iq << XCHILDNS(_T("confirm"), JABBER_FEAT_HTTP_AUTH) << XATTR(_T("id"), pParams->m_szId)
					<< XATTR(_T("method"), pParams->m_szMethod) << XATTR(_T("url"), pParams->m_szUrl);
			iq << XCHILD(_T("error")) << XATTRI(_T("code"), 401) << XATTR(_T("type"), _T("auth"))
					<< XCHILDNS(_T("not-authorized"), _T("urn:ietf:params:xml:xmpp-stanzas"));
		}
		m_ThreadInfo->send(iq);
	}
	else if (pParams->m_nType == CJabberHttpAuthParams::MSG) {
		XmlNode msg(_T("message"));
		msg << XATTR(_T("to"), pParams->m_szFrom);
		if (!bAuthorized)
			msg << XATTR(_T("type"), _T("error"));
		if (pParams->m_szThreadId)
			msg << XCHILD(_T("thread"), pParams->m_szThreadId);

		msg << XCHILDNS(_T("confirm"), JABBER_FEAT_HTTP_AUTH) << XATTR(_T("id"), pParams->m_szId)
					<< XATTR(_T("method"), pParams->m_szMethod) << XATTR(_T("url"), pParams->m_szUrl);

		if (!bAuthorized)
			msg << XCHILD(_T("error")) << XATTRI(_T("code"), 401) << XATTR(_T("type"), _T("auth"))
					<< XCHILDNS(_T("not-authorized"), _T("urn:ietf:params:xml:xmpp-stanzas"));

		m_ThreadInfo->send(msg);
	}
	else return FALSE;

	return TRUE;
}
Пример #14
0
void mclear( short n )
{
	short row, col;

	if (!OPEN) return;

	for (row=0; row<HEIGHT; row++ )
		for (col=0; col<WIDTH; col++ )  {
			CHAR(row,col) = 32;
			ATTR(row,col) = 7;
			XCHAR(row,col) = 32;
			XATTR(row,col) = 7;
		}
	CCOL = 0;
	CROW = 0;
}
Пример #15
0
BOOL CJabberProto::OnHandleDiscoInfoRequest(HXML iqNode, CJabberIqInfo *pInfo)
{
	if (!pInfo->GetChildNode())
		return TRUE;

	const TCHAR *szNode = XmlGetAttrValue(pInfo->GetChildNode(), _T("node"));
	// caps hack
	if (m_clientCapsManager.HandleInfoRequest(iqNode, pInfo, szNode))
		return TRUE;

	// ad-hoc hack:
	if (szNode && m_adhocManager.HandleInfoRequest(iqNode, pInfo, szNode))
		return TRUE;

	// another request, send empty result
	m_ThreadInfo->send(
		XmlNodeIq(_T("error"), pInfo)
		<< XCHILD(_T("error")) << XATTRI(_T("code"), 404) << XATTR(_T("type"), _T("cancel"))
		<< XCHILDNS(_T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")));
	return TRUE;
}
Пример #16
0
void CJabberProto::GroupchatJoinRoom(const TCHAR *server, const TCHAR *room, const TCHAR *nick, const TCHAR *password, bool autojoin)
{
	JabberGcRecentInfo info(this);

	bool found = false;
	for (int i = 0; i < 5; i++) {
		if (!info.loadRecent(i))
			continue;

		if (info.equals(room, server, nick, password)) {
			found = true;
			break;
		}
	}

	if (!found) {
		for (int i = 4; i--;) {
			if (info.loadRecent(i))
				info.saveRecent(i + 1);
		}

		info.fillData(room, server, nick, password);
		info.saveRecent(0);
	}

	TCHAR text[JABBER_MAX_JID_LEN + 1];
	mir_sntprintf(text, _T("%s@%s/%s"), room, server, nick);

	JABBER_LIST_ITEM *item = ListAdd(LIST_CHATROOM, text);
	item->bAutoJoin = autojoin;
	replaceStrT(item->nick, nick);
	replaceStrT(item->password, info.m_password);

	int status = (m_iStatus == ID_STATUS_INVISIBLE) ? ID_STATUS_ONLINE : m_iStatus;
	XmlNode x(_T("x")); x << XATTR(_T("xmlns"), JABBER_FEAT_MUC);
	if (info.m_password && info.m_password[0])
		x << XCHILD(_T("password"), info.m_password);

	SendPresenceTo(status, text, x);
}
Пример #17
0
BOOL CJabberProto::OnFtHandleIbbIq(HXML iqNode, CJabberIqInfo *pInfo)
{
    if (!mir_tstrcmp(pInfo->GetChildNodeName(), _T("open")))
        FtHandleIbbRequest(iqNode, TRUE);
    else if (!mir_tstrcmp(pInfo->GetChildNodeName(), _T("close")))
        FtHandleIbbRequest(iqNode, FALSE);
    else if (!mir_tstrcmp(pInfo->GetChildNodeName(), _T("data"))) {
        BOOL bOk = FALSE;
        const TCHAR *sid = XmlGetAttrValue(pInfo->GetChildNode(), _T("sid"));
        const TCHAR *seq = XmlGetAttrValue(pInfo->GetChildNode(), _T("seq"));
        if (sid && seq && XmlGetText(pInfo->GetChildNode()))
            bOk = OnIbbRecvdData(XmlGetText(pInfo->GetChildNode()), sid, seq);

        if (bOk)
            m_ThreadInfo->send( XmlNodeIq(_T("result"), pInfo));
        else
            m_ThreadInfo->send(
                XmlNodeIq(_T("error"), pInfo)
                << XCHILD(_T("error")) << XATTRI(_T("code"), 404) << XATTR(_T("type"), _T("cancel"))
                << XCHILDNS(_T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")));
    }
    return TRUE;
}
Пример #18
0
int CJabberProto::ByteSendProxyParse( HANDLE hConn, JABBER_BYTE_TRANSFER *jbt, char* buffer, int datalen )
{
	int num = datalen;

	switch ( jbt->state ) {
	case JBT_INIT:
		// received:
		// 00-00 ver ( 0x05 )
		// 01-01 selected method ( 0=no auth, 0xff=error )
		// send:
		// 00-00 ver ( 0x05 )
		// 01-01 cmd ( 1=connect )
		// 02-02 reserved ( 0 )
		// 03-03 address type ( 3 )
		// 04-44 dst.addr ( 41 bytes: 1-byte length, 40-byte SHA1 hash of [sid,srcJID,dstJID] )
		// 45-46 dst.port ( 0 )
		if ( datalen==2 && buffer[0]==5 && buffer[1]==0 ) {
			BYTE data[47];
			ZeroMemory( data, sizeof( data ));
			*(( DWORD* )data ) = 0x03000105;
			data[4] = 40;

			TCHAR text[256];

			TCHAR *szInitiatorJid = JabberPrepareJid(jbt->srcJID);
			TCHAR *szTargetJid = JabberPrepareJid(jbt->dstJID);
			mir_sntprintf( text, SIZEOF( text ), _T("%s%s%s"), jbt->sid, szInitiatorJid, szTargetJid );
			mir_free(szInitiatorJid);
			mir_free(szTargetJid);

			char* szAuthString = mir_utf8encodeT( text );
			Log( "Auth: '%s'", szAuthString );
			char* szHash = JabberSha1( szAuthString );
			strncpy(( char* )( data+5 ), szHash, 40 );
			mir_free( szHash );
			Netlib_Send( hConn, ( char* )data, 47, 0 );
			jbt->state = JBT_CONNECT;
			mir_free( szAuthString );
		}
		else jbt->state = JBT_SOCKSERR;
		break;

	case JBT_CONNECT:
		// received:
		// 00-00 ver ( 0x05 )
		// 01-01 reply ( 0=success,2=not allowed )
		// 02-02 reserved ( 0 )
		// 03-03 address type ( 1=IPv4 address,3=host address )
		// 04-mm bnd.addr server bound address ( 4-byte IP if IPv4, 1-byte length + n-byte host address string if host address )
		// nn-nn+1 bnd.port server bound port
		if ( datalen>=5 && buffer[0]==5 && buffer[1]==0 && ( buffer[3]==1 || buffer[3]==3 || buffer[3]==0 )) {
			if ( buffer[3]==1 && datalen>=10 )
				num = 10;
			else if ( buffer[3]==3 && datalen>=buffer[4]+7 )
				num = buffer[4] + 7;
			else if ( buffer[3]==0 && datalen>=6 )
				num = 6;
			else {
				jbt->state = JBT_SOCKSERR;
				break;
			}
			jbt->state = JBT_SENDING;

			jbt->hProxyEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
			jbt->bStreamActivated = FALSE;

			int iqId = SerialNext();

			TCHAR listJid[256];
			mir_sntprintf(listJid, SIZEOF( listJid ), _T("ftproxy_%d"), iqId);

			JABBER_LIST_ITEM *item = ListAdd( LIST_FTIQID, listJid );
			item->jbt = jbt;

			IqAdd( iqId, IQ_PROC_NONE, &CJabberProto::IqResultStreamActivate );
			m_ThreadInfo->send( 
				XmlNodeIq( _T("set"), iqId, jbt->streamhostJID ) << XQUERY( _T(JABBER_FEAT_BYTESTREAMS))
					<< XATTR( _T("sid"), jbt->sid ) << XCHILD( _T("activate"), jbt->dstJID ));

			WaitForSingleObject( jbt->hProxyEvent, INFINITE );

			CloseHandle( jbt->hProxyEvent );
			jbt->hProxyEvent = NULL;

			ListRemove( LIST_FTIQID, listJid );

			if ( jbt->bStreamActivated) 
				jbt->state = (this->*jbt->pfnSend)( hConn, jbt->ft ) ? JBT_DONE : JBT_ERROR;
			else
				jbt->state = JBT_ERROR;
		}
		else jbt->state = JBT_SOCKSERR;
		break;
	}

	return num;
}
Пример #19
0
JabberCapsBits CJabberProto::GetResourceCapabilites(const TCHAR *jid, BOOL appendBestResource)
{
	TCHAR fullJid[JABBER_MAX_JID_LEN];
	if (appendBestResource)
		GetClientJID(jid, fullJid, SIZEOF(fullJid));
	else
		_tcsncpy(fullJid, jid, SIZEOF(fullJid));

	pResourceStatus r(ResourceInfoFromJID(fullJid));
	if (r == NULL)
		return JABBER_RESOURCE_CAPS_ERROR;

	// XEP-0115 mode
	if (r->m_tszCapsNode && r->m_tszCapsVer) {
		JabberCapsBits jcbCaps = 0, jcbExtCaps = 0;
		BOOL bRequestSent = FALSE;
		JabberCapsBits jcbMainCaps = m_clientCapsManager.GetClientCaps(r->m_tszCapsNode, r->m_tszCapsVer);

		if (jcbMainCaps == JABBER_RESOURCE_CAPS_TIMEOUT && !r->m_dwDiscoInfoRequestTime)
			jcbMainCaps = JABBER_RESOURCE_CAPS_ERROR;

		if (jcbMainCaps == JABBER_RESOURCE_CAPS_UNINIT) {
			// send disco#info query

			CJabberIqInfo *pInfo = AddIQ(&CJabberProto::OnIqResultCapsDiscoInfo, JABBER_IQ_TYPE_GET, fullJid, JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_CHILD_TAG_NODE);
			pInfo->SetTimeout(JABBER_RESOURCE_CAPS_QUERY_TIMEOUT);
			m_clientCapsManager.SetClientCaps(r->m_tszCapsNode, r->m_tszCapsVer, JABBER_RESOURCE_CAPS_IN_PROGRESS, pInfo->GetIqId());
			r->m_dwDiscoInfoRequestTime = pInfo->GetRequestTime();

			TCHAR queryNode[512];
			mir_sntprintf(queryNode, SIZEOF(queryNode), _T("%s#%s"), r->m_tszCapsNode, r->m_tszCapsVer);
			m_ThreadInfo->send(XmlNodeIq(pInfo) << XQUERY(JABBER_FEAT_DISCO_INFO) << XATTR(_T("node"), queryNode));

			bRequestSent = TRUE;
		}
		else if (jcbMainCaps == JABBER_RESOURCE_CAPS_IN_PROGRESS)
			bRequestSent = TRUE;
		else if (jcbMainCaps != JABBER_RESOURCE_CAPS_TIMEOUT)
			jcbCaps |= jcbMainCaps;

		if (jcbMainCaps != JABBER_RESOURCE_CAPS_TIMEOUT && r->m_tszCapsExt) {
			TCHAR *caps = mir_tstrdup(r->m_tszCapsExt);

			TCHAR *token = _tcstok(caps, _T(" "));
			while (token) {
				switch (jcbExtCaps = m_clientCapsManager.GetClientCaps(r->m_tszCapsNode, token)) {
				case JABBER_RESOURCE_CAPS_ERROR:
					break;

				case JABBER_RESOURCE_CAPS_UNINIT:
					{
						// send disco#info query

						CJabberIqInfo *pInfo = AddIQ(&CJabberProto::OnIqResultCapsDiscoInfo, JABBER_IQ_TYPE_GET, fullJid, JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_CHILD_TAG_NODE);
						pInfo->SetTimeout(JABBER_RESOURCE_CAPS_QUERY_TIMEOUT);
						m_clientCapsManager.SetClientCaps(r->m_tszCapsNode, token, JABBER_RESOURCE_CAPS_IN_PROGRESS, pInfo->GetIqId());

						m_ThreadInfo->send(
							XmlNodeIq(pInfo) << XQUERY(JABBER_FEAT_DISCO_INFO) << XATTR(_T("node"), CMString(FORMAT, _T("%s#%s"), r->m_tszCapsNode, token)));

						bRequestSent = TRUE;
					}
					break;

				case JABBER_RESOURCE_CAPS_IN_PROGRESS:
					bRequestSent = TRUE;
					break;

				default:
					jcbCaps |= jcbExtCaps;
				}

				token = _tcstok(NULL, _T(" "));
			}

			mir_free(caps);
		}

		if (bRequestSent)
			return JABBER_RESOURCE_CAPS_IN_PROGRESS;

		return jcbCaps | r->m_jcbManualDiscoveredCaps;
	}

	// capability mode (version request + service discovery)

	// no version info:
	if (!r->m_tszSoftwareVersion && !r->m_tszSoftware) {
		// version request not sent:
		if (!r->m_dwVersionRequestTime) {
			// send version query

			CJabberIqInfo *pInfo = AddIQ(&CJabberProto::OnIqResultVersion, JABBER_IQ_TYPE_GET, fullJid, JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_HCONTACT | JABBER_IQ_PARSE_CHILD_TAG_NODE);
			pInfo->SetTimeout(JABBER_RESOURCE_CAPS_QUERY_TIMEOUT);
			r->m_dwVersionRequestTime = pInfo->GetRequestTime();

			XmlNodeIq iq(pInfo);
			iq << XQUERY(JABBER_FEAT_VERSION);
			m_ThreadInfo->send(iq);
			return JABBER_RESOURCE_CAPS_IN_PROGRESS;
		}
		// version not received:
		else if (r->m_dwVersionRequestTime != -1) {
			// no timeout?
			if (GetTickCount() - r->m_dwVersionRequestTime < JABBER_RESOURCE_CAPS_QUERY_TIMEOUT)
				return JABBER_RESOURCE_CAPS_IN_PROGRESS;

			// timeout
			r->m_dwVersionRequestTime = -1;
		}
		// no version information, try direct service discovery
		if (!r->m_dwDiscoInfoRequestTime) {
			// send disco#info query

			CJabberIqInfo *pInfo = AddIQ(&CJabberProto::OnIqResultCapsDiscoInfo, JABBER_IQ_TYPE_GET, fullJid, JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_CHILD_TAG_NODE);
			pInfo->SetTimeout(JABBER_RESOURCE_CAPS_QUERY_TIMEOUT);
			r->m_dwDiscoInfoRequestTime = pInfo->GetRequestTime();

			XmlNodeIq iq(pInfo);
			iq << XQUERY(JABBER_FEAT_DISCO_INFO);
			m_ThreadInfo->send(iq);

			return JABBER_RESOURCE_CAPS_IN_PROGRESS;
		}
		else if (r->m_dwDiscoInfoRequestTime == -1)
			return r->m_jcbCachedCaps | r->m_jcbManualDiscoveredCaps;
		else if (GetTickCount() - r->m_dwDiscoInfoRequestTime < JABBER_RESOURCE_CAPS_QUERY_TIMEOUT)
			return JABBER_RESOURCE_CAPS_IN_PROGRESS;
		else
			r->m_dwDiscoInfoRequestTime = -1;
		// version request timeout:
		return JABBER_RESOURCE_CAPS_NONE;
	}

	// version info available:
	if (r->m_tszSoftware && r->m_tszSoftwareVersion) {
		JabberCapsBits jcbMainCaps = m_clientCapsManager.GetClientCaps(r->m_tszSoftware, r->m_tszSoftwareVersion);
		if (jcbMainCaps == JABBER_RESOURCE_CAPS_ERROR) {
			// Bombus hack:
			if (!_tcscmp(r->m_tszSoftware, _T("Bombus")) || !_tcscmp(r->m_tszSoftware, _T("BombusMod"))) {
				jcbMainCaps = JABBER_CAPS_SI | JABBER_CAPS_SI_FT | JABBER_CAPS_IBB | JABBER_CAPS_MESSAGE_EVENTS | JABBER_CAPS_MESSAGE_EVENTS_NO_DELIVERY | JABBER_CAPS_DATA_FORMS | JABBER_CAPS_LAST_ACTIVITY | JABBER_CAPS_VERSION | JABBER_CAPS_COMMANDS | JABBER_CAPS_VCARD_TEMP;
				m_clientCapsManager.SetClientCaps(r->m_tszSoftware, r->m_tszSoftwareVersion, jcbMainCaps);
			}
			// Neos hack:
			else if (!_tcscmp(r->m_tszSoftware, _T("neos"))) {
				jcbMainCaps = JABBER_CAPS_OOB | JABBER_CAPS_MESSAGE_EVENTS | JABBER_CAPS_MESSAGE_EVENTS_NO_DELIVERY | JABBER_CAPS_LAST_ACTIVITY | JABBER_CAPS_VERSION;
				m_clientCapsManager.SetClientCaps(r->m_tszSoftware, r->m_tszSoftwareVersion, jcbMainCaps);
			}
			// sim hack:
			else if (!_tcscmp(r->m_tszSoftware, _T("sim"))) {
				jcbMainCaps = JABBER_CAPS_OOB | JABBER_CAPS_VERSION | JABBER_CAPS_MESSAGE_EVENTS | JABBER_CAPS_MESSAGE_EVENTS_NO_DELIVERY;
				m_clientCapsManager.SetClientCaps(r->m_tszSoftware, r->m_tszSoftwareVersion, jcbMainCaps);
			}
		}

		else if (jcbMainCaps == JABBER_RESOURCE_CAPS_UNINIT) {
			// send disco#info query

			CJabberIqInfo *pInfo = AddIQ(&CJabberProto::OnIqResultCapsDiscoInfo, JABBER_IQ_TYPE_GET, fullJid, JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_CHILD_TAG_NODE);
			pInfo->SetTimeout(JABBER_RESOURCE_CAPS_QUERY_TIMEOUT);
			m_clientCapsManager.SetClientCaps(r->m_tszSoftware, r->m_tszSoftwareVersion, JABBER_RESOURCE_CAPS_IN_PROGRESS, pInfo->GetIqId());
			r->m_dwDiscoInfoRequestTime = pInfo->GetRequestTime();

			XmlNodeIq iq(pInfo);
			iq << XQUERY(JABBER_FEAT_DISCO_INFO);
			m_ThreadInfo->send(iq);

			jcbMainCaps = JABBER_RESOURCE_CAPS_IN_PROGRESS;
		}
		return jcbMainCaps | r->m_jcbManualDiscoveredCaps;
	}

	return JABBER_RESOURCE_CAPS_NONE;
}
Пример #20
0
void CJabberProto::EnableArchive(bool bEnable)
{
	m_ThreadInfo->send( XmlNodeIq(_T("set"), SerialNext())
		<< XCHILDNS( _T("auto"), JABBER_FEAT_ARCHIVE) << XATTR(_T("save"), (bEnable) ? _T("true") : _T("false")));
}
Пример #21
0
int CJabberProto::ByteReceiveParse( HANDLE hConn, JABBER_BYTE_TRANSFER *jbt, char* buffer, int datalen )
{
	int bytesReceived, num = datalen;

	switch ( jbt->state ) {
	case JBT_INIT:
		// received:
		// 00-00 ver ( 0x05 )
		// 01-01 selected method ( 0=no auth, 0xff=error )
		// send:
		// 00-00 ver ( 0x05 )
		// 01-01 cmd ( 1=connect )
		// 02-02 reserved ( 0 )
		// 03-03 address type ( 3 )
		// 04-44 dst.addr ( 41 bytes: 1-byte length, 40-byte SHA1 hash of [sid,srcJID,dstJID] )
		// 45-46 dst.port ( 0 )
		if ( datalen==2 && buffer[0]==5 && buffer[1]==0 ) {
			BYTE data[47];
			ZeroMemory( data, sizeof( data ));
			*(( DWORD* )data ) = 0x03000105;
			data[4] = 40;

			TCHAR text[JABBER_MAX_JID_LEN*2];
			TCHAR *szInitiatorJid = JabberPrepareJid(jbt->srcJID);
			TCHAR *szTargetJid = JabberPrepareJid(jbt->dstJID);
			mir_sntprintf( text, SIZEOF( text ), _T("%s%s%s"), jbt->sid, szInitiatorJid, szTargetJid );
			mir_free(szInitiatorJid);
			mir_free(szTargetJid);
			char* szAuthString = mir_utf8encodeT( text );
			Log( "Auth: '%s'", szAuthString );
			char* szHash = JabberSha1( szAuthString );
			strncpy(( char* )( data+5 ), szHash, 40 );
			mir_free( szHash );
			Netlib_Send( hConn, ( char* )data, 47, 0 );
			jbt->state = JBT_CONNECT;
			mir_free( szAuthString );
		}
		else jbt->state = JBT_SOCKSERR;
		break;

	case JBT_CONNECT:
		// received:
		// 00-00 ver ( 0x05 )
		// 01-01 reply ( 0=success,2=not allowed )
		// 02-02 reserved ( 0 )
		// 03-03 address type ( 1=IPv4 address,3=host address )
		// 04-mm bnd.addr server bound address ( 4-byte IP if IPv4, 1-byte length + n-byte host address string if host address )
		// nn-nn+1 bnd.port server bound port
		if ( datalen>=5 && buffer[0]==5 && buffer[1]==0 && ( buffer[3]==1 || buffer[3]==3 || buffer[3]==0 )) {
			if ( buffer[3]==1 && datalen>=10 )
				num = 10;
			else if ( buffer[3]==3 && datalen>=buffer[4]+7 )
				num = buffer[4] + 7;
			else if ( buffer[3]==0 && datalen>=6 )
				num = 6;
			else {
				jbt->state = JBT_SOCKSERR;
				break;
			}
			jbt->state = JBT_RECVING;

			m_ThreadInfo->send(
				XmlNodeIq( _T("result"), jbt->iqId, jbt->srcJID ) << XQUERY( _T(JABBER_FEAT_BYTESTREAMS))
					<< XCHILD( _T("streamhost-used")) << XATTR( _T("jid"), jbt->streamhostJID ));
		}
		else jbt->state = JBT_SOCKSERR;
		break;

	case JBT_RECVING:
		bytesReceived = (this->*jbt->pfnRecv)( hConn, jbt->ft, buffer, datalen );
		if ( bytesReceived < 0 )
			jbt->state = JBT_ERROR;
		else if ( bytesReceived == 0 )
			jbt->state = JBT_DONE;
		break;
	}

	return num;
}
Пример #22
0
void CJabberProto::ByteSendViaProxy( JABBER_BYTE_TRANSFER *jbt )
{
	TCHAR *szHost, *szPort;
	WORD port;
	HANDLE hConn;
	char data[3];
	char* buffer;
	int datalen, bytesParsed, recvResult;
	BOOL validStreamhost;

	if ( jbt == NULL ) return;
	if (( buffer=( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE )) == NULL ) {
		m_ThreadInfo->send( XmlNodeIq( _T("error"), jbt->iqId, jbt->srcJID )
			<< XCHILD( _T("error")) << XATTRI( _T("code"), 406 ) << XATTR( _T("type"), _T("auth"))
			<< XCHILDNS( _T("not-acceptable"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")));
		return;
	}

	jbt->state = JBT_INIT;
	validStreamhost = FALSE;
	szPort = jbt->szProxyPort;
	szHost = jbt->szProxyHost;

	port = ( WORD )_ttoi( szPort );
	if ( jbt->streamhostJID ) mir_free( jbt->streamhostJID );
	jbt->streamhostJID = mir_tstrdup( jbt->szProxyJid );

	NETLIBOPENCONNECTION nloc = { 0 };
	nloc.cbSize = sizeof( nloc );
	nloc.szHost = mir_t2a(szHost);
	nloc.wPort = port;
	hConn = ( HANDLE ) JCallService( MS_NETLIB_OPENCONNECTION, ( WPARAM ) m_hNetlibUser, ( LPARAM )&nloc );
	mir_free((void*)nloc.szHost);

	if ( hConn != NULL ) {
		jbt->hConn = hConn;

		data[0] = 5;
		data[1] = 1;
		data[2] = 0;
		Netlib_Send( hConn, data, 3, 0 );

		jbt->state = JBT_INIT;
		datalen = 0;
		while ( jbt->state!=JBT_DONE && jbt->state!=JBT_ERROR && jbt->state!=JBT_SOCKSERR ) {
			recvResult = Netlib_Recv( hConn, buffer+datalen, JABBER_NETWORK_BUFFER_SIZE-datalen, 0 );
			if ( recvResult <= 0 )
				break;

			datalen += recvResult;
			bytesParsed = ByteSendProxyParse( hConn, jbt, buffer, datalen );
			if ( bytesParsed < datalen )
				memmove( buffer, buffer+bytesParsed, datalen-bytesParsed );
			datalen -= bytesParsed;
			if ( jbt->state == JBT_DONE ) validStreamhost = TRUE;
		}
		Netlib_CloseHandle( hConn );
	}
	mir_free( buffer );
	(this->*jbt->pfnFinal)(( jbt->state == JBT_DONE ) ? TRUE : FALSE, jbt->ft );
	jbt->ft = NULL;
	if ( !validStreamhost )
		m_ThreadInfo->send( XmlNodeIq( _T("error"), jbt->iqId, jbt->srcJID )
			<< XCHILD( _T("error")) << XATTRI( _T("code"), 404 ) << XATTR( _T("type"), _T("cancel"))
			<< XCHILDNS( _T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")));
}
Пример #23
0
void CJabberProto::ByteSendThread( JABBER_BYTE_TRANSFER *jbt )
{
	char* localAddr;
	char* localAddrInternal;
	struct in_addr in;
	DBVARIANT dbv;
	TCHAR szPort[8];
	HANDLE hEvent = NULL;
	TCHAR* proxyJid;
	CJabberIqInfo* pInfo = NULL;
	int nIqId = 0;

	Log( "Thread started: type=bytestream_send" );

	BOOL bDirect = m_options.BsDirect;

	if ( m_options.BsProxyManual ) {
		proxyJid = NULL;
		if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsProxyServer", &dbv )) {
			proxyJid = mir_a2t( dbv.pszVal );
			JFreeVariant( &dbv );
		}

		if ( proxyJid ) {
			jbt->bProxyDiscovered = FALSE;
			jbt->szProxyHost = NULL;
			jbt->szProxyPort = NULL;
			jbt->szProxyJid = NULL;
			jbt->hProxyEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

			pInfo = m_iqManager.AddHandler( &CJabberProto::IqResultProxyDiscovery, JABBER_IQ_TYPE_GET, proxyJid, 0, -1, jbt );
			nIqId = pInfo->GetIqId();
			XmlNodeIq iq( pInfo );
			iq << XQUERY( _T(JABBER_FEAT_BYTESTREAMS));
			m_ThreadInfo->send( iq );

			WaitForSingleObject( jbt->hProxyEvent, INFINITE );
			m_iqManager.ExpireIq ( nIqId );
			CloseHandle( jbt->hProxyEvent );
			jbt->hProxyEvent = NULL;

			mir_free( proxyJid );

			if ( jbt->state == JBT_ERROR && !bDirect ) {
				Log( "Bytestream proxy failure" );
				MsgPopup(  pInfo->GetHContact(), TranslateT("Bytestream Proxy not available"), pInfo->GetReceiver());
				jbt->ft->state = FT_DENIED;
				(this->*jbt->pfnFinal)( FALSE, jbt->ft );
				jbt->ft = NULL;
				delete jbt;
				return;
			}	
	}	}

	pInfo = m_iqManager.AddHandler( &CJabberProto::ByteInitiateResult, JABBER_IQ_TYPE_SET, jbt->dstJID, 0, -1, jbt );
	nIqId = pInfo->GetIqId();
	{
		XmlNodeIq iq( pInfo );
		HXML query = iq << XQUERY( _T(JABBER_FEAT_BYTESTREAMS)) << XATTR( _T("sid"), jbt->sid );

		if ( bDirect ) {
			localAddr = NULL;
			if ( m_options.BsDirectManual == TRUE ) {
				if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv )) {
					localAddr = NEWSTR_ALLOCA( dbv.pszVal );
					JFreeVariant( &dbv );
			}	}

			NETLIBBIND nlb = {0};
			nlb.cbSize = sizeof( NETLIBBIND );
			nlb.pfnNewConnectionV2 = JabberByteSendConnection;
			nlb.pExtra = this;
			nlb.wPort = 0;	// Use user-specified incoming port ranges, if available
			jbt->hConn = ( HANDLE ) JCallService( MS_NETLIB_BINDPORT, ( WPARAM ) m_hNetlibUser, ( LPARAM )&nlb );
			if ( jbt->hConn == NULL ) {
				Log( "Cannot allocate port for bytestream_send thread, thread ended." );
				delete jbt;
				return;
			}
			if ( localAddr == NULL ) {
				in.S_un.S_addr = htonl(nlb.dwExternalIP);
				localAddr = NEWSTR_ALLOCA( inet_ntoa( in ));
			}
			in.S_un.S_addr = htonl(nlb.dwInternalIP);
			localAddrInternal = NEWSTR_ALLOCA( inet_ntoa( in ));

			mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), nlb.wPort );
			JABBER_LIST_ITEM *item = ListAdd( LIST_BYTE, szPort );
			item->jbt = jbt;
			hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
			jbt->hEvent = hEvent;
			jbt->hSendEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
			query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(localAddr)) << XATTRI( _T("port"), nlb.wPort );
			if ( strcmp( localAddr, localAddrInternal ))
				query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(localAddrInternal)) << XATTRI( _T("port"), nlb.wPort );
		}

		if ( jbt->bProxyDiscovered )
			query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), jbt->szProxyJid ) << XATTR( _T("host"), jbt->szProxyHost ) << XATTR( _T("port"), jbt->szProxyPort );

		jbt->hProxyEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
		jbt->szStreamhostUsed = NULL;

		m_ThreadInfo->send( iq );
	}

	WaitForSingleObject( jbt->hProxyEvent, INFINITE );
	m_iqManager.ExpireIq( nIqId );
	CloseHandle( jbt->hProxyEvent );
	jbt->hProxyEvent = NULL;

	if ( !jbt->szStreamhostUsed ) {
		if ( bDirect ) {
			SetEvent( jbt->hSendEvent );
			CloseHandle( jbt->hSendEvent );
			CloseHandle( hEvent );
			jbt->hEvent = NULL;
			if ( jbt->hConn != NULL )
				Netlib_CloseHandle( jbt->hConn );
			jbt->hConn = NULL;
			ListRemove( LIST_BYTE, szPort );
		}
		(this->*jbt->pfnFinal)(( jbt->state==JBT_DONE )?TRUE:FALSE, jbt->ft );
		jbt->ft = NULL;
		// stupid fix: wait for listening thread exit
		Sleep( 100 );
		delete jbt;
		return;
	}

	if ( jbt->bProxyDiscovered && !_tcscmp( jbt->szProxyJid, jbt->szStreamhostUsed )) {
		// jabber proxy used
		if ( bDirect ) {
			SetEvent( jbt->hSendEvent );
			CloseHandle( jbt->hSendEvent );
			CloseHandle( hEvent );
			jbt->hEvent = NULL;
			if ( jbt->hConn != NULL )
				Netlib_CloseHandle( jbt->hConn );
			jbt->hConn = NULL;
			ListRemove( LIST_BYTE, szPort );
		}
		ByteSendViaProxy( jbt );
	}
	else {
		SetEvent( jbt->hSendEvent );
		WaitForSingleObject( hEvent, INFINITE );
		CloseHandle( hEvent );
		CloseHandle( jbt->hSendEvent );
		jbt->hEvent = NULL;
		(this->*jbt->pfnFinal)(( jbt->state == JBT_DONE ) ? TRUE : FALSE, jbt->ft );
		jbt->ft = NULL;
		if ( jbt->hConn != NULL )
			Netlib_CloseHandle( jbt->hConn );
		jbt->hConn = NULL;
		ListRemove( LIST_BYTE, szPort );
	}

	// stupid fix: wait for listening connection thread exit
	Sleep( 100 );
	delete jbt;
	Log( "Thread ended: type=bytestream_send" );
}
Пример #24
0
void __cdecl CJabberProto::IbbReceiveThread(JABBER_IBB_TRANSFER *jibb)
{
    debugLogA("Thread started: type=ibb_recv");

    filetransfer *ft = jibb->ft;

    jibb->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    jibb->bStreamClosed = FALSE;
    jibb->wPacketId = 0;
    jibb->dwTransferredSize = 0;
    jibb->state = JIBB_RECVING;

    WaitForSingleObject(jibb->hEvent, INFINITE);

    CloseHandle(jibb->hEvent);
    jibb->hEvent = NULL;

    if (jibb->state == JIBB_ERROR)
        m_ThreadInfo->send( XmlNodeIq(_T("set"), SerialNext(), jibb->dstJID) << XCHILDNS(_T("close"), JABBER_FEAT_IBB) << XATTR(_T("sid"), jibb->sid));

    if (jibb->bStreamClosed && jibb->dwTransferredSize == ft->dwExpectedRecvFileSize)
        jibb->state = JIBB_DONE;

    (this->*jibb->pfnFinal)((jibb->state==JIBB_DONE)?TRUE:FALSE, jibb->ft);
    jibb->ft = NULL;

    ListRemove(LIST_FTRECV, jibb->sid);

    JabberIbbFreeJibb(jibb);
}
Пример #25
0
BOOL CJabberProto::OnIqRequestAvatar(HXML, CJabberIqInfo *pInfo)
{
	if (!m_options.EnableAvatars)
		return TRUE;

	int pictureType = m_options.AvatarType;
	if (pictureType == PA_FORMAT_UNKNOWN)
		return TRUE;

	TCHAR *szMimeType;
	switch (pictureType) {
	case PA_FORMAT_JPEG:	 szMimeType = _T("image/jpeg");   break;
	case PA_FORMAT_GIF:	 szMimeType = _T("image/gif");    break;
	case PA_FORMAT_PNG:	 szMimeType = _T("image/png");    break;
	case PA_FORMAT_BMP:	 szMimeType = _T("image/bmp");    break;
	default:	return TRUE;
	}

	TCHAR szFileName[MAX_PATH];
	GetAvatarFileName(NULL, szFileName, _countof(szFileName));

	FILE* in = _tfopen(szFileName, _T("rb"));
	if (in == NULL)
		return TRUE;

	long bytes = _filelength(_fileno(in));
	ptrA buffer((char*)mir_alloc(bytes * 4 / 3 + bytes + 1000));
	if (buffer == NULL) {
		fclose(in);
		return TRUE;
	}

	fread(buffer, bytes, 1, in);
	fclose(in);

	ptrA str(mir_base64_encode((PBYTE)(char*)buffer, bytes));
	m_ThreadInfo->send(XmlNodeIq(_T("result"), pInfo) << XQUERY(JABBER_FEAT_AVATAR) << XCHILD(_T("query"), _A2T(str)) << XATTR(_T("mimetype"), szMimeType));
	return TRUE;
}
Пример #26
0
// XEP-0199: XMPP Ping support
BOOL CJabberProto::OnIqRequestPing(HXML, CJabberIqInfo *pInfo)
{
	m_ThreadInfo->send(XmlNodeIq(_T("result"), pInfo) << XATTR(_T("from"), m_ThreadInfo->fullJID));
	return TRUE;
}
Пример #27
0
void __cdecl CJabberProto::ByteReceiveThread( JABBER_BYTE_TRANSFER *jbt )
{
	HXML iqNode, queryNode = NULL, n;
	const TCHAR *sid = NULL, *from = NULL, *to = NULL, *szId = NULL, *szHost, *szPort, *str;
	int i;
	WORD port;
	HANDLE hConn;
	char data[3];
	char* buffer;
	int datalen, bytesParsed, recvResult;
	BOOL validStreamhost = FALSE;

	if ( jbt == NULL ) return;

	jbt->state = JBT_INIT;

	if ( iqNode = jbt->iqNode ) {
		from = xmlGetAttrValue( iqNode, _T("from"));
		to = xmlGetAttrValue( iqNode, _T("to"));
		szId = xmlGetAttrValue( iqNode, _T("id"));

		queryNode = xmlGetChild( iqNode , "query" );
		if ( queryNode )
			sid = xmlGetAttrValue( queryNode, _T("sid"));
	}

	if ( szId && from && to && sid && ( n = xmlGetChild( queryNode , "streamhost" ))!=NULL ) {
		jbt->iqId = mir_tstrdup( szId );
		jbt->srcJID = mir_tstrdup( from );
		jbt->dstJID = mir_tstrdup( to );
		jbt->sid = mir_tstrdup( sid );

		if (( buffer=( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE ))) {
			for ( i=1; ( n = xmlGetNthChild( queryNode, _T("streamhost"), i ))!=NULL; i++ ) {
				if (( szHost = xmlGetAttrValue( n, _T("host"))) != NULL &&
					( szPort = xmlGetAttrValue( n, _T("port"))) != NULL &&
					( str = xmlGetAttrValue( n, _T("jid"))) != NULL ) {

						port = ( WORD )_ttoi( szPort );
						if ( jbt->streamhostJID ) mir_free( jbt->streamhostJID );
						jbt->streamhostJID = mir_tstrdup( str );

						Log( "bytestream_recv connecting to " TCHAR_STR_PARAM ":%d", szHost, port );
						NETLIBOPENCONNECTION nloc = { 0 };
						nloc.cbSize = sizeof( nloc );
						nloc.szHost = mir_t2a(szHost);
						nloc.wPort = port;
						hConn = ( HANDLE ) JCallService( MS_NETLIB_OPENCONNECTION, ( WPARAM ) m_hNetlibUser, ( LPARAM )&nloc );
						mir_free((void*)nloc.szHost);

						if ( hConn == NULL ) {
							Log( "bytestream_recv_connection connection failed ( %d ), try next streamhost", WSAGetLastError());
							continue;
						}

						jbt->hConn = hConn;

						data[0] = 5;
						data[1] = 1;
						data[2] = 0;
						Netlib_Send( hConn, data, 3, 0 );

						jbt->state = JBT_INIT;
						datalen = 0;
						while ( jbt->state!=JBT_DONE && jbt->state!=JBT_ERROR && jbt->state!=JBT_SOCKSERR ) {
							recvResult = Netlib_Recv( hConn, buffer+datalen, JABBER_NETWORK_BUFFER_SIZE-datalen, 0 );
							if ( recvResult <= 0 ) break;
							datalen += recvResult;
							bytesParsed = ByteReceiveParse( hConn, jbt, buffer, datalen );
							if ( bytesParsed < datalen )
								memmove( buffer, buffer+bytesParsed, datalen-bytesParsed );
							datalen -= bytesParsed;
							if ( jbt->state == JBT_RECVING ) validStreamhost = TRUE;
						}
						Netlib_CloseHandle( hConn );
						Log( "bytestream_recv_connection closing connection" );
				}
				if ( jbt->state==JBT_ERROR || validStreamhost==TRUE )
					break;
				Log( "bytestream_recv_connection stream cannot be established, try next streamhost" );
			}
			mir_free( buffer );
		}
	}

	(this->*jbt->pfnFinal)(( jbt->state==JBT_DONE )?TRUE:FALSE, jbt->ft );
	jbt->ft = NULL;
	if ( !validStreamhost && szId && from ) {
		Log( "bytestream_recv_connection session not completed" );

		m_ThreadInfo->send( XmlNodeIq( _T("error"), szId, from )
			<< XCHILD( _T("error")) << XATTRI( _T("code"), 404 ) << XATTR( _T("type"), _T("cancel"))
			<< XCHILDNS( _T("item-not-found"), _T("urn:ietf:params:xml:ns:xmpp-stanzas")));
	}

	delete jbt;
	Log( "Thread ended: type=bytestream_recv" );
}
Пример #28
0
BOOL CJabberClientCapsManager::HandleInfoRequest(HXML, CJabberIqInfo *pInfo, const TCHAR *szNode)
{
	int i;
	JabberCapsBits jcb = 0;

	if (szNode) {
		for (i=0; g_JabberFeatCapPairsExt[i].szFeature; i++) {
			if (!g_JabberFeatCapPairsExt[i].Valid())
				continue;

			TCHAR szExtCap[ 512 ];
			mir_sntprintf(szExtCap, SIZEOF(szExtCap), _T("%s#%s"), JABBER_CAPS_MIRANDA_NODE, g_JabberFeatCapPairsExt[i].szFeature);
			if (!_tcscmp(szNode, szExtCap)) {
				jcb = g_JabberFeatCapPairsExt[i].jcbCap;
				break;
			}
		}

		// check features registered through IJabberNetInterface::RegisterFeature() and IJabberNetInterface::AddFeatures()
		for (i=0; i < ppro->m_lstJabberFeatCapPairsDynamic.getCount(); i++) {
			TCHAR szExtCap[ 512 ];
			mir_sntprintf(szExtCap, SIZEOF(szExtCap), _T("%s#%s"), JABBER_CAPS_MIRANDA_NODE, ppro->m_lstJabberFeatCapPairsDynamic[i]->szExt);
			if (!_tcscmp(szNode, szExtCap)) {
				jcb = ppro->m_lstJabberFeatCapPairsDynamic[i]->jcbCap;
				break;
			}
		}

		// unknown node, not XEP-0115 request
		if (!jcb)
			return FALSE;
	}
	else {
		jcb = JABBER_CAPS_MIRANDA_ALL;
		for (i=0; i < ppro->m_lstJabberFeatCapPairsDynamic.getCount(); i++)
			jcb |= ppro->m_lstJabberFeatCapPairsDynamic[i]->jcbCap;
	}

	if (!ppro->m_options.AllowVersionRequests)
		jcb &= ~JABBER_CAPS_VERSION;

	XmlNodeIq iq(_T("result"), pInfo);

	HXML query = iq << XQUERY(JABBER_FEAT_DISCO_INFO);
	if (szNode)
		query << XATTR(_T("node"), szNode);

	query << XCHILD(_T("identity")) << XATTR(_T("category"), _T("client"))
			<< XATTR(_T("type"), _T("pc")) << XATTR(_T("name"), _T("Miranda"));

	for (i=0; g_JabberFeatCapPairs[i].szFeature; i++)
		if (jcb & g_JabberFeatCapPairs[i].jcbCap)
			query << XCHILD(_T("feature")) << XATTR(_T("var"), g_JabberFeatCapPairs[i].szFeature);

	for (i=0; i < ppro->m_lstJabberFeatCapPairsDynamic.getCount(); i++)
		if (jcb & ppro->m_lstJabberFeatCapPairsDynamic[i]->jcbCap)
			query << XCHILD(_T("feature")) << XATTR(_T("var"), ppro->m_lstJabberFeatCapPairsDynamic[i]->szFeature);

	if (ppro->m_options.AllowVersionRequests && !szNode) {
		TCHAR szOsBuffer[256] = {0};
		TCHAR *os = szOsBuffer;

		if (ppro->m_options.ShowOSVersion) {
			if (!GetOSDisplayString(szOsBuffer, SIZEOF(szOsBuffer)))
				lstrcpyn(szOsBuffer, _T(""), SIZEOF(szOsBuffer));
			else {
				TCHAR *szOsWindows = _T("Microsoft Windows");
				size_t nOsWindowsLength = _tcslen(szOsWindows);
				if (!_tcsnicmp(szOsBuffer, szOsWindows, nOsWindowsLength))
					os += nOsWindowsLength + 1;
			}
		}

		HXML form = query << XCHILDNS(_T("x"), JABBER_FEAT_DATA_FORMS) << XATTR(_T("type"), _T("result"));
		form << XCHILD(_T("field")) << XATTR(_T("var"), _T("FORM_TYPE")) << XATTR(_T("type"), _T("hidden"))
			<< XCHILD(_T("value"), _T("urn:xmpp:dataforms:softwareinfo"));

		if (ppro->m_options.ShowOSVersion) {
			form << XCHILD(_T("field")) << XATTR(_T("var"), _T("os")) << XCHILD(_T("value"), _T("Microsoft Windows"));
			form << XCHILD(_T("field")) << XATTR(_T("var"), _T("os_version")) << XCHILD(_T("value"), os);
		}
		form << XCHILD(_T("field")) << XATTR(_T("var"), _T("software")) << XCHILD(_T("value"), _T("Miranda NG Jabber Protocol"));
		form << XCHILD(_T("field")) << XATTR(_T("var"), _T("software_version")) << XCHILD(_T("value"), _T(__VERSION_STRING_DOTS));
		form << XCHILD(_T("field")) << XATTR(_T("var"), _T("x-miranda-core-version")) << XCHILD(_T("value"), szCoreVersion);
	}

	ppro->m_ThreadInfo->send(iq);

	return TRUE;
}