diff options
Diffstat (limited to 'protocols/JabberG/jabber_byte.cpp')
-rw-r--r-- | protocols/JabberG/jabber_byte.cpp | 778 |
1 files changed, 0 insertions, 778 deletions
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; i<nMethods && buffer[2+i]!=0; i++ );
- if ( i < nMethods ) {
- data[1] = 0;
- jbt->state = 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;
-}
|