Esempio n. 1
0
// last activity (XEP-0012) support
BOOL CJabberProto::OnIqRequestLastActivity(HXML, CJabberIqInfo *pInfo)
{
	m_ThreadInfo->send(
		XmlNodeIq(_T("result"), pInfo) << XQUERY(JABBER_FEAT_LAST_ACTIVITY)
		<< XATTRI(_T("seconds"), m_tmJabberIdleStartTime ? time(0) - m_tmJabberIdleStartTime : 0));
	return TRUE;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
0
void CJabberProto::IbbSendThread( JABBER_IBB_TRANSFER *jibb )
{
	Log( "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( m_iqManager.AddHandler( &CJabberProto::OnIbbInitiateResult, JABBER_IQ_TYPE_SET, jibb->dstJID, 0, -1, jibb ))
			<< XCHILDNS( _T("open"), _T(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( m_iqManager.AddHandler( &CJabberProto::OnIbbCloseResult, JABBER_IQ_TYPE_SET, jibb->dstJID, 0, -1, jibb ))
					<< XCHILDNS( _T("close"), _T(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 );
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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" );
}
Esempio n. 8
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")));
}
Esempio n. 9
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" );
}