From 3b55a62fdcb1f8222de3c2c8fbed530792c419a0 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 12 Oct 2012 14:53:57 +0000 Subject: GTalkExt, ICQ, IRC, Jabber: folders restructurization git-svn-id: http://svn.miranda-ng.org/main/trunk@1890 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/JabberG/jabber_byte.cpp | 778 -------------------------------------- 1 file changed, 778 deletions(-) delete mode 100644 protocols/JabberG/jabber_byte.cpp (limited to 'protocols/JabberG/jabber_byte.cpp') diff --git a/protocols/JabberG/jabber_byte.cpp b/protocols/JabberG/jabber_byte.cpp deleted file mode 100644 index 9e86b51388..0000000000 --- a/protocols/JabberG/jabber_byte.cpp +++ /dev/null @@ -1,778 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Copyright ( C ) 2002-04 Santithorn Bunchua -Copyright ( C ) 2005-12 George Hazan -Copyright ( C ) 2007 Maxim Mluhov - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or ( at your option ) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_iq.h" -#include "jabber_byte.h" -#include "jabber_caps.h" - -#define JABBER_NETWORK_BUFFER_SIZE 4096 - -///////////////// Bytestream sending ///////////////////////// - -JABBER_BYTE_TRANSFER::~JABBER_BYTE_TRANSFER() -{ - filetransfer* pft = ft; - if ( pft ) - pft->jbt = NULL; - - mir_free( srcJID ); - mir_free( dstJID ); - mir_free( streamhostJID ); - mir_free( iqId ); - mir_free( sid ); - - xi.destroyNode( iqNode ); - - // XEP-0065 proxy support - mir_free( szProxyHost ); - mir_free( szProxyPort ); - mir_free( szProxyJid ); - mir_free( szStreamhostUsed ); -} - -void CJabberProto::IqResultProxyDiscovery( HXML iqNode, CJabberIqInfo* pInfo ) -{ - JABBER_BYTE_TRANSFER *jbt = ( JABBER_BYTE_TRANSFER * )pInfo->GetUserData(); - - if ( pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT ) { - HXML queryNode = xmlGetChild( iqNode , "query" ); - if ( queryNode ) { - const TCHAR *queryXmlns = xmlGetAttrValue( queryNode, _T( "xmlns" )); - if (queryXmlns && !_tcscmp( queryXmlns, _T(JABBER_FEAT_BYTESTREAMS))) { - HXML streamHostNode = xmlGetChild( queryNode , "streamhost" ); - if ( streamHostNode ) { - const TCHAR *streamJid = xmlGetAttrValue( streamHostNode, _T( "jid" )); - const TCHAR *streamHost = xmlGetAttrValue( streamHostNode, _T( "host" )); - const TCHAR *streamPort = xmlGetAttrValue( streamHostNode, _T( "port" )); - if ( streamJid && streamHost && streamPort ) { - jbt->szProxyHost = mir_tstrdup( streamHost ); - jbt->szProxyJid = mir_tstrdup( streamJid ); - jbt->szProxyPort = mir_tstrdup( streamPort ); - jbt->bProxyDiscovered = TRUE; - } } } } } - else if ( pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR ) - jbt->state = JBT_ERROR; - - if ( jbt->hProxyEvent ) - SetEvent( jbt->hProxyEvent ); -} - -void JabberByteSendConnection( HANDLE hConn, DWORD /*dwRemoteIP*/, void* extra ) -{ - CJabberProto* ppro = ( CJabberProto* )extra; - TCHAR szPort[8]; - JABBER_BYTE_TRANSFER *jbt; - int recvResult, bytesParsed; - HANDLE hListen; - JABBER_LIST_ITEM *item; - char* buffer; - int datalen; - - NETLIBCONNINFO connInfo = { sizeof(connInfo) }; - CallService(MS_NETLIB_GETCONNECTIONINFO, (WPARAM)hConn, (LPARAM)&connInfo); - - mir_sntprintf( szPort, SIZEOF( szPort ), _T("%u"), connInfo.wPort ); - ppro->Log( "bytestream_send_connection incoming connection accepted: %s", connInfo.szIpPort ); - - if (( item = ppro->ListGetItemPtr( LIST_BYTE, szPort )) == NULL ) { - ppro->Log( "No bytestream session is currently active, connection closed." ); - Netlib_CloseHandle( hConn ); - return; - } - - jbt = item->jbt; - - if (( buffer = ( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE )) == NULL ) { - ppro->Log( "bytestream_send cannot allocate network buffer, connection closed." ); - jbt->state = JBT_ERROR; - Netlib_CloseHandle( hConn ); - if ( jbt->hEvent != NULL ) SetEvent( jbt->hEvent ); - return; - } - - hListen = jbt->hConn; - jbt->hConn = hConn; - jbt->state = JBT_INIT; - datalen = 0; - while ( jbt->state!=JBT_DONE && jbt->state!=JBT_ERROR ) { - recvResult = Netlib_Recv( hConn, buffer+datalen, JABBER_NETWORK_BUFFER_SIZE-datalen, 0 ); - if ( recvResult <= 0 ) - break; - - datalen += recvResult; - bytesParsed = ppro->ByteSendParse( hConn, jbt, buffer, datalen ); - if ( bytesParsed < datalen ) - memmove( buffer, buffer+bytesParsed, datalen-bytesParsed ); - datalen -= bytesParsed; - } - - if ( jbt->hConn ) - Netlib_CloseHandle( jbt->hConn ); - - ppro->Log( "bytestream_send_connection closing connection" ); - jbt->hConn = hListen; - mir_free( buffer ); - - if ( jbt->hEvent != NULL ) - SetEvent( jbt->hEvent ); -} - -void CJabberProto::ByteSendThread( JABBER_BYTE_TRANSFER *jbt ) -{ - char* localAddr = NULL; - 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 ) { - if ( m_options.BsDirectManual ) { - if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv )) - localAddr = dbv.pszVal; - } - - 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 ) CallService( 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 ) - localAddr = (char*)CallService( MS_NETLIB_ADDRESSTOSTRING, 1, nlb.dwExternalIP ); - - 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 ); - - NETLIBIPLIST* ihaddr = ( NETLIBIPLIST* )CallService( MS_NETLIB_GETMYIP, 1, 0 ); - for ( unsigned i = 0; i < ihaddr->cbNum; ++i ) - if ( strcmp( localAddr, ihaddr->szIp[i] )) - query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(ihaddr->szIp[i])) << XATTRI( _T("port"), nlb.wPort ); - - mir_free( ihaddr ); - mir_free( localAddr ); - } - - 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" ); -} - -void CJabberProto::ByteInitiateResult( HXML iqNode, CJabberIqInfo* pInfo ) -{ - JABBER_BYTE_TRANSFER *jbt = ( JABBER_BYTE_TRANSFER * )pInfo->GetUserData(); - - if ( pInfo->GetIqType() == JABBER_IQ_TYPE_RESULT ) { - HXML queryNode = xmlGetChild( iqNode , "query" ); - if ( queryNode ) { - const TCHAR* queryXmlns = xmlGetAttrValue( queryNode, _T("xmlns")); - if ( queryXmlns && !_tcscmp( queryXmlns, _T( JABBER_FEAT_BYTESTREAMS ))) { - HXML streamHostNode = xmlGetChild( queryNode , "streamhost-used" ); - if ( streamHostNode ) { - const TCHAR* streamJid = xmlGetAttrValue( streamHostNode, _T("jid")); - if ( streamJid ) - jbt->szStreamhostUsed = mir_tstrdup( streamJid ); - } } } } - - if ( jbt->hProxyEvent ) - SetEvent( jbt->hProxyEvent ); -} - -int CJabberProto::ByteSendParse( HANDLE hConn, JABBER_BYTE_TRANSFER *jbt, char* buffer, int datalen ) -{ - int nMethods; - BYTE data[10]; - int i; - char* str; - - switch ( jbt->state ) { - case JBT_INIT: - // received: - // 00-00 ver ( 0x05 ) - // 01-01 nmethods - // 02-xx list of methods ( nmethods bytes ) - // send: - // 00-00 ver ( 0x05 ) - // 01-01 select method ( 0=no auth required ) - if ( datalen>=2 && buffer[0]==5 && buffer[1]+2==datalen ) { - nMethods = buffer[1]; - for ( i=0; istate = JBT_CONNECT; - } - else { - data[1] = 0xff; - jbt->state = JBT_ERROR; - } - data[0] = 5; - Netlib_Send( hConn, ( char* )data, 2, 0 ); - } - else jbt->state = JBT_ERROR; - break; - - case JBT_CONNECT: - // received: - // 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 ) - // send: - // 00-00 ver ( 0x05 ) - // 01-01 reply ( 0=success,2=not allowed ) - // 02-02 reserved ( 0 ) - // 03-03 address type ( 1=IPv4 address ) - // 04-07 bnd.addr server bound address - // 08-09 bnd.port server bound port - if ( datalen == 47 && *(( DWORD* )buffer )==0x03000105 && buffer[4]==40 && *(( WORD* )( buffer+45 ))==0 ) { - 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 ); - if (( str = JabberSha1( szAuthString )) != NULL ) { - for ( i=0; i<40 && buffer[i+5]==str[i]; i++ ); - mir_free( str ); - - ZeroMemory( data, 10 ); - data[1] = ( i>=20 )?0:2; - data[0] = 5; - data[3] = 1; - Netlib_Send( hConn, ( char* )data, 10, 0 ); - - // wait stream activation - WaitForSingleObject( jbt->hSendEvent, INFINITE ); - - if ( jbt->state == JBT_ERROR ) - break; - - if ( i>=20 && (this->*jbt->pfnSend)( hConn, jbt->ft )==TRUE ) - jbt->state = JBT_DONE; - else - jbt->state = JBT_ERROR; - } - mir_free( szAuthString ); - } - else - jbt->state = JBT_ERROR; - break; - } - - return datalen; -} - -///////////////// Bytestream receiving ///////////////////////// - -void CJabberProto::IqResultStreamActivate( HXML iqNode ) -{ - int id = JabberGetPacketID( iqNode ); - - TCHAR listJid[JABBER_MAX_JID_LEN]; - mir_sntprintf(listJid, SIZEOF( listJid ), _T("ftproxy_%d"), id); - - JABBER_LIST_ITEM *item = ListGetItemPtr( LIST_FTIQID, listJid ); - if ( !item ) - return; - - if ( !lstrcmp( xmlGetAttrValue( iqNode, _T("type")), _T( "result" ))) - item->jbt->bStreamActivated = TRUE; - - if ( item->jbt->hProxyEvent ) - SetEvent( item->jbt->hProxyEvent ); -} - - -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 ) CallService( 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"))); -} - -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; -} - - -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 ) CallService( 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" ); -} - -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; -} -- cgit v1.2.3