18 #include "clientbase.h" 19 #include "compressionbase.h" 20 #include "compressionzlib.h" 21 #include "connectionbase.h" 22 #include "connectionlistener.h" 23 #include "connectiontcpclient.h" 26 #include "eventhandler.h" 29 #include "iqhandler.h" 31 #include "loghandler.h" 34 #include "messagehandler.h" 35 #include "messagesessionhandler.h" 36 #include "mucinvitationhandler.h" 38 #include "mutexguard.h" 40 #include "presencehandler.h" 41 #include "rosterlistener.h" 42 #include "stanzaextensionfactory.h" 44 #include "subscription.h" 45 #include "subscriptionhandler.h" 47 #include "taghandler.h" 49 #include "tlsdefault.h" 64 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ ) 67 # ifndef SecureZeroMemory 68 # define SecureZeroMemory(p,s) RtlFillMemory((p),(s),0) 77 ClientBase::Ping::Ping()
82 ClientBase::Ping::~Ping()
86 const std::string& ClientBase::Ping::filterString()
const 88 static const std::string filter =
"/iq/ping[@xmlns='" +
XMLNS_XMPP_PING +
"']";
100 m_statisticsHandler( 0 ), m_mucInvitationHandler( 0 ),
101 m_messageSessionHandlerChat( 0 ), m_messageSessionHandlerGroupchat( 0 ),
102 m_messageSessionHandlerHeadline( 0 ), m_messageSessionHandlerNormal( 0 ),
105 m_selectedSaslMech(
SaslMechNone ), m_customConnection( false ),
119 m_statisticsHandler( 0 ), m_mucInvitationHandler( 0 ),
120 m_messageSessionHandlerChat( 0 ), m_messageSessionHandlerGroupchat( 0 ),
121 m_messageSessionHandlerHeadline( 0 ), m_messageSessionHandlerNormal( 0 ),
124 m_selectedSaslMech(
SaslMechNone ), m_customConnection( false ),
130 void ClientBase::init()
132 srand( static_cast<unsigned int>( time( 0 ) ) );
134 sha.
feed( util::long2string( time( 0 ) ) );
135 sha.
feed( util::int2string( rand() ) );
136 m_uniqueBaseId = sha.
hex();
151 memset( &m_stats, 0,
sizeof( m_stats ) );
157 m_iqHandlerMapMutex.
lock();
158 m_iqIDHandlers.clear();
159 m_iqHandlerMapMutex.
unlock();
161 m_iqExtHandlerMapMutex.
lock();
162 m_iqExtHandlers.clear();
163 m_iqExtHandlerMapMutex.
unlock();
178 PresenceJidHandlerList::const_iterator it1 = m_presenceJidHandlers.begin();
179 for( ; it1 != m_presenceJidHandlers.end(); ++it1 )
209 +
m_server + ( ( m_customConnection )?(
" using a custom connection" ):(
m_port > 0 ? (
":" + util::int2string(
m_port ) ) :
EmptyString ) ) +
"..." );
235 const std::string& version = tag->
findAttribute(
"version" );
239 " (it does not send a 'version' attribute). Please fix it or try another one.\n" );
245 handleStartNode( tag );
249 handleStreamError( tag );
254 if( !handleNormalNode( tag ) )
258 if( tag->
name() ==
"iq" )
264 notifyIqHandlers( iq );
269 else if( tag->
name() ==
"message" )
275 notifyMessageHandlers( msg );
280 else if( tag->
name() ==
"presence" )
283 if( type ==
"subscribe" || type ==
"unsubscribe" 284 || type ==
"subscribed" || type ==
"unsubscribed" )
290 notifySubscriptionHandlers( sub );
299 notifyPresenceHandlers( pres );
310 notifyTagHandlers( tag );
315 if( m_statisticsHandler )
401 notifyOnDisconnect( reason );
410 send(
"</stream:stream>" );
425 notifyOnDisconnect( reason );
427 #ifdef CLIENTBASE_TEST 432 void ClientBase::parse(
const std::string& data )
434 std::string copy = data;
436 if( ( i = m_parser.
feed( copy ) ) >= 0 )
438 std::string error =
"parse error (at pos ";
439 error += util::int2string( i );
442 Tag* e =
new Tag(
"stream:error" );
451 std::string head =
"<?xml version='1.0' ?>";
453 head +=
"xmlns:stream='http://etherx.jabber.org/streams' xml:lang='" +
m_xmllang +
"' ";
460 #if defined( HAVE_GNUTLS ) || defined( HAVE_OPENSSL ) || defined( HAVE_WINTLS ) 487 m_selectedSaslMech = type;
506 m_gs2Header =
"p=tls-unique,";
512 m_gs2Header +=
"a=" + t;
516 m_clientFirstMessageBare =
"n=";
518 m_clientFirstMessageBare += t;
520 m_clientFirstMessageBare += t;
522 m_clientFirstMessageBare +=
",r=" +
getRandom();
557 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ ) 572 "SASL GSSAPI is not supported on this platform. You should never see this." );
578 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ ) 580 SEC_WINNT_AUTH_IDENTITY_W identity, *ident = 0;
581 memset( &identity, 0,
sizeof( identity ) );
583 WCHAR *usernameW = 0, *domainW = 0, *passwordW = 0;
584 int cchUsernameW = 0, cchDomainW = 0, cchPasswordW = 0;
591 cchUsernameW = ::MultiByteToWideChar( CP_UTF8, 0,
m_jid.
username().c_str(), -1, 0, 0 );
592 if( cchUsernameW > 0 )
594 usernameW =
new WCHAR[cchUsernameW];
595 ::MultiByteToWideChar( CP_UTF8, 0,
m_jid.
username().c_str(), -1, usernameW, cchUsernameW );
597 usernameW[cchUsernameW-1] = L
'\0';
599 cchDomainW = ::MultiByteToWideChar( CP_UTF8, 0, m_ntlmDomain.c_str(), -1, 0, 0 );
602 domainW =
new WCHAR[cchDomainW];
603 ::MultiByteToWideChar( CP_UTF8, 0, m_ntlmDomain.c_str(), -1, domainW, cchDomainW );
605 domainW[cchDomainW-1] = L
'\0';
607 cchPasswordW = ::MultiByteToWideChar( CP_UTF8, 0,
m_password.c_str(), -1, 0, 0 );
608 if( cchPasswordW > 0 )
610 passwordW =
new WCHAR[cchPasswordW];
611 ::MultiByteToWideChar( CP_UTF8, 0,
m_password.c_str(), -1, passwordW, cchPasswordW );
613 passwordW[cchPasswordW-1] = L
'\0';
615 identity.User = (
unsigned short*)usernameW;
616 identity.UserLength = (
unsigned long)cchUsernameW-1;
617 identity.Domain = (
unsigned short*)domainW;
618 identity.DomainLength = (
unsigned long)cchDomainW-1;
619 identity.Password = (
unsigned short*)passwordW;
620 identity.PasswordLength = (
unsigned long)cchPasswordW-1;
621 identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
625 AcquireCredentialsHandleW( 0, L
"NTLM", SECPKG_CRED_OUTBOUND, 0, ident, 0, 0, &m_credHandle, 0 );
639 ::SecureZeroMemory( passwordW, cchPasswordW*
sizeof( WCHAR ) );
646 "SASL NTLM is not supported on this platform. You should never see this." );
657 std::string ClientBase::hmac(
const std::string& key,
const std::string& str )
660 std::string key_ = key;
661 if( key_.length() > 64 )
667 unsigned char ipad[65];
668 unsigned char opad[65];
669 memset( ipad,
'\0',
sizeof( ipad ) );
670 memset( opad,
'\0',
sizeof( opad ) );
671 memcpy( ipad, key_.c_str(), key_.length() );
672 memcpy( opad, key_.c_str(), key_.length() );
673 for(
int i = 0; i < 64; i++ )
678 sha.
feed( ipad, 64 );
682 sha.
feed( opad, 64 );
688 std::string ClientBase::hi(
const std::string& str,
const std::string& salt,
int iter )
691 memset( xored,
'\0',
sizeof( xored ) );
692 std::string tmp = salt;
693 tmp.append(
"\0\0\0\1", 4 );
694 for(
int i = 0; i < iter; ++i )
696 tmp = hmac( str, tmp );
697 for(
int j = 0; j < 20; ++j )
698 xored[j] ^= tmp.c_str()[j];
701 for(
int i=0; i < 20 ;++i )
702 n.push_back( static_cast<char>( xored[i] ) );
713 switch( m_selectedSaslMech )
718 std::string snonce, salt, tmp;
720 std::string::size_type posn = decoded.find(
"r=" );
721 std::string::size_type poss = decoded.find(
"s=" );
722 std::string::size_type posi = decoded.find(
"i=" );
723 if( posn == std::string::npos || poss == std::string::npos || posi == std::string::npos )
726 snonce = decoded.substr( posn + 2, poss - posn - 3 );
728 tmp = decoded.substr( posi + 2, decoded.length() - posi - 2 );
729 iter = atoi( tmp.c_str() );
734 std::string saltedPwd = hi( tmp, salt, iter );
735 std::string ck = hmac( saltedPwd,
"Client Key" );
738 std::string storedKey = sha.
binary();
744 tmp +=
",r=" + snonce;
746 std::string authMessage = m_clientFirstMessageBare +
"," + decoded +
"," + tmp;
747 std::string clientSignature = hmac( storedKey, authMessage );
748 unsigned char clientProof[20];
749 memcpy( clientProof, ck.c_str(), 20 );
750 for(
int i = 0; i < 20; ++i )
751 clientProof[i] ^= clientSignature.c_str()[i];
752 std::string serverKey = hmac( saltedPwd,
"Server Key" );
753 m_serverSignature = hmac( serverKey, authMessage );
756 tmp.append(
Base64::encode64( std::string( reinterpret_cast<const char*>( clientProof ), 20 ) ) );
764 if( !decoded.compare( 0, 7,
"rspauth" ) )
768 std::string::size_type end = 0;
769 std::string::size_type pos = decoded.find(
"realm=" );
770 if( pos != std::string::npos )
772 end = decoded.find(
'"', pos + 7 );
773 realm = decoded.substr( pos + 7, end - ( pos + 7 ) );
778 pos = decoded.find(
"nonce=" );
779 if( pos == std::string::npos )
782 end = decoded.find(
'"', pos + 7 );
783 while( decoded[end-1] ==
'\\' )
784 end = decoded.find(
'"', end + 1 );
785 std::string nonce = decoded.substr( pos + 7, end - ( pos + 7 ) );
796 const std::string& a1_h = md5.
binary();
804 const std::string& a1 = md5.
hex();
806 md5.
feed(
"AUTHENTICATE:xmpp/" );
809 const std::string& a2 = md5.
hex();
814 md5.
feed(
":00000001:" );
816 md5.
feed(
":auth:" );
820 std::string response =
"username=\"";
822 response +=
"\",realm=\"";
824 response +=
"\",nonce=\"";
826 response +=
"\",cnonce=\"";
828 response +=
"\",nc=00000001,qop=auth,digest-uri=\"xmpp/";
830 response +=
"\",response=";
831 response += md5.
hex();
832 response +=
",charset=utf-8";
842 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ ) 846 "Huh, received GSSAPI challenge?! This should have never happened!" );
851 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ ) 852 bool type1 = ( decoded.length() < 7 ) ?
true :
false;
854 SecBuffer bufferIn = { type1 ? 0 : (
unsigned long)decoded.length(),
856 (
void*)decoded.c_str() };
857 SecBufferDesc secIn = { 0, 1, &bufferIn };
861 SecBuffer bufferOut = {
sizeof( buffer ), SECBUFFER_TOKEN, buffer };
862 SecBufferDesc secOut = { 0, 1, &bufferOut };
865 unsigned long contextAttr;
867 SECURITY_STATUS status = InitializeSecurityContext( &m_credHandle, type1 ? 0 : &m_ctxtHandle,
868 0, ISC_REQ_MUTUAL_AUTH, 0, 0, &secIn, 0,
869 &m_ctxtHandle, &secOut, &contextAttr,
871 std::string response;
872 if( SUCCEEDED( status ) )
874 response = std::string( (
const char *)bufferOut.pvBuffer, bufferOut.cbBuffer );
879 "InitializeSecurityContext() failed, return value " 880 + util::int2string( status ) );
886 "Huh, received NTLM challenge?! This should have never happened!" );
903 else if( tag->
hasChild(
"incorrect-encoding" ) )
905 else if( tag->
hasChild(
"invalid-authzid" ) )
907 else if( tag->
hasChild(
"invalid-mechanism" ) )
909 else if( tag->
hasChild(
"malformed-request" ) )
911 else if( tag->
hasChild(
"mechanism-too-weak" ) )
913 else if( tag->
hasChild(
"not-authorized" ) )
915 else if( tag->
hasChild(
"temporary-auth-failure" ) )
918 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ ) 921 FreeCredentialsHandle( &m_credHandle );
922 DeleteSecurityContext( &m_ctxtHandle );
929 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ ) 932 FreeCredentialsHandle( &m_credHandle );
933 DeleteSecurityContext( &m_ctxtHandle );
939 if( decoded.length() < 3 ||
Base64::decode64( decoded.substr( 2 ) ) != m_serverSignature )
950 if( iq.
id().empty() )
955 track.context = context;
957 m_iqHandlerMapMutex.
lock();
958 m_iqIDHandlers[iq.
id()] = track;
959 m_iqHandlerMapMutex.
unlock();
971 send( tag,
true,
false );
980 send( tag,
true,
false );
989 send( tag,
true,
false );
1000 addNamespace( tag );
1001 send( tag,
true,
false );
1009 send( tag,
false,
true );
1021 if( m_statisticsHandler )
1026 m_queueMutex.
lock();
1027 m_smQueue.insert( std::make_pair( ++m_smSent, tag ) );
1055 SMQueueMap::iterator it = m_smQueue.begin();
1056 while( it != m_smQueue.end() )
1058 if( (*it).first <= handled )
1060 delete (*it).second;
1061 m_smQueue.erase( it++ );
1063 else if( resend && (*it).first > handled )
1065 send( (*it).second,
false,
false );
1079 SMQueueMap::iterator it = m_smQueue.begin();
1080 for( ; it != m_smQueue.end(); ++it )
1081 l.push_back( (*it).second->clone() );
1086 void ClientBase::addFrom(
Tag* tag )
1094 void ClientBase::addNamespace(
Tag* tag )
1096 if( !tag || !tag->
xmlns().empty() )
1138 const std::string&
id =
getID();
1142 send( iq,
this, XMPPPing );
1145 bool ClientBase::handleIq(
const IQ& iq )
1158 void ClientBase::handleIqID(
const IQ& iq,
int context )
1160 if( context == XMPPPing )
1165 handleIqIDForward( iq, context );
1170 #ifdef CLIENTBASE_TEST // to create predictable UIDs in test mode 1171 return "uid" + util::int2string( m_nextId.
increment() );
1174 sprintf( r,
"%s%08x", m_uniqueBaseId.c_str(), m_nextId.
increment() );
1175 std::string ret( r, 48 );
1182 if( version.empty() )
1189 size_t dot = version.find(
'.' );
1190 if( !version.empty() && dot && dot != std::string::npos )
1192 major = atoi( version.substr( 0, dot ).c_str() );
1196 return myMajor >= major;
1203 m_customConnection =
true;
1224 void ClientBase::handleStreamError(
Tag* tag )
1228 TagList::const_iterator it = c.begin();
1229 for( ; it != c.end(); ++it )
1231 const std::string& name = (*it)->name();
1232 if( name ==
"bad-format" )
1234 else if( name ==
"bad-namespace-prefix" )
1236 else if( name ==
"conflict" )
1238 else if( name ==
"connection-timeout" )
1240 else if( name ==
"host-gone" )
1242 else if( name ==
"host-unknown" )
1244 else if( name ==
"improper-addressing" )
1246 else if( name ==
"internal-server-error" )
1248 else if( name ==
"invalid-from" )
1250 else if( name ==
"invalid-id" )
1252 else if( name ==
"invalid-namespace" )
1254 else if( name ==
"invalid-xml" )
1256 else if( name ==
"not-authorized" )
1258 else if( name ==
"policy-violation" )
1260 else if( name ==
"remote-connection-failed" )
1262 else if( name ==
"resource-constraint" )
1264 else if( name ==
"restricted-xml" )
1266 else if( name ==
"see-other-host" )
1269 m_streamErrorCData = tag->
findChild(
"see-other-host" )->
cdata();
1271 else if( name ==
"system-shutdown" )
1273 else if( name ==
"undefined-condition" )
1275 else if( name ==
"unsupported-encoding" )
1277 else if( name ==
"unsupported-stanza-type" )
1279 else if( name ==
"unsupported-version" )
1281 else if( name ==
"xml-not-well-formed" )
1283 else if( name ==
"text" )
1285 const std::string& lang = (*it)->findAttribute(
"xml:lang" );
1287 m_streamErrorText[lang] = (*it)->cdata();
1289 m_streamErrorText[
"default"] = (*it)->cdata();
1292 m_streamErrorAppCondition = (*it);
1295 m_streamError = err;
1301 StringMap::const_iterator it = m_streamErrorText.find( lang );
1302 return ( it != m_streamErrorText.end() ) ? (*it).second :
EmptyString;
1308 m_messageSessionHandlerChat = msh;
1311 m_messageSessionHandlerNormal = msh;
1314 m_messageSessionHandlerGroupchat = msh;
1317 m_messageSessionHandlerHeadline = msh;
1323 m_presenceHandlers.push_back( ph );
1329 m_presenceHandlers.remove( ph );
1336 JidPresHandlerStruct jph;
1337 jph.jid =
new JID( jid.
bare() );
1339 m_presenceJidHandlers.push_back( jph );
1345 PresenceJidHandlerList::iterator t;
1346 PresenceJidHandlerList::iterator it = m_presenceJidHandlers.begin();
1347 while( it != m_presenceJidHandlers.end() )
1351 if( ( !ph || (*t).ph == ph ) && (*t).jid->bare() == jid.
bare() )
1354 m_presenceJidHandlers.erase( t );
1361 IqTrackMap::iterator t;
1362 m_iqHandlerMapMutex.
lock();
1363 IqTrackMap::iterator it = m_iqIDHandlers.begin();
1364 while( it != m_iqIDHandlers.end() )
1368 if( ih == (*t).second.ih )
1369 m_iqIDHandlers.erase( t );
1371 m_iqHandlerMapMutex.
unlock();
1380 typedef IqHandlerMap::const_iterator IQci;
1381 std::pair<IQci, IQci> g = m_iqExtHandlers.equal_range( exttype );
1382 for( IQci it = g.first; it != g.second; ++it )
1384 if( (*it).second == ih )
1388 m_iqExtHandlers.insert( std::make_pair( exttype, ih ) );
1397 typedef IqHandlerMap::iterator IQi;
1398 std::pair<IQi, IQi> g = m_iqExtHandlers.equal_range( exttype );
1401 while( it != g.second )
1404 if( (*it2).second == ih )
1405 m_iqExtHandlers.erase( it2 );
1412 m_messageSessions.push_back( session );
1420 MessageSessionList::iterator it = std::find( m_messageSessions.begin(),
1421 m_messageSessions.end(),
1423 if( it != m_messageSessions.end() )
1426 m_messageSessions.erase( it );
1433 m_messageHandlers.push_back( mh );
1439 m_messageHandlers.remove( mh );
1445 m_subscriptionHandlers.push_back( sh );
1451 m_subscriptionHandlers.remove( sh );
1456 if( th && !tag.empty() )
1458 TagHandlerStruct ths;
1462 m_tagHandlers.push_back( ths );
1470 for( TagHandlerList::iterator it = m_tagHandlers.begin(); it != m_tagHandlers.end(); )
1472 if( (*it).th == th && (*it).tag == tag && (*it).xmlns == xmlns )
1479 m_tagHandlers.erase( it++ );
1492 m_statisticsHandler = sh;
1497 m_statisticsHandler = 0;
1504 m_mucInvitationHandler = mih;
1511 m_mucInvitationHandler = 0;
1518 m_connectionListeners.push_back( cl );
1524 m_connectionListeners.remove( cl );
1540 ConnectionListenerList::const_iterator it = m_connectionListeners.begin();
1541 for( ; it != m_connectionListeners.end() && (*it)->onTLSConnect( info ); ++it )
1543 return m_stats.
encryption = ( it == m_connectionListeners.end() );
1566 void ClientBase::notifyPresenceHandlers(
Presence& pres )
1569 PresenceJidHandlerList::const_iterator t;
1570 PresenceJidHandlerList::const_iterator itj = m_presenceJidHandlers.begin();
1571 while( itj != m_presenceJidHandlers.end() )
1574 if( (*t).jid->bare() == pres.
from().
bare() && (*t).ph )
1576 (*t).ph->handlePresence( pres );
1584 PresenceHandlerList::const_iterator it = m_presenceHandlers.begin();
1585 for( ; it != m_presenceHandlers.end(); ++it )
1587 (*it)->handlePresence( pres );
1593 void ClientBase::notifySubscriptionHandlers(
Subscription& s10n )
1596 SubscriptionHandlerList::const_iterator it = m_subscriptionHandlers.begin();
1597 for( ; it != m_subscriptionHandlers.end(); ++it )
1599 (*it)->handleSubscription( s10n );
1605 void ClientBase::notifyIqHandlers(
IQ& iq )
1607 m_iqHandlerMapMutex.
lock();
1608 IqTrackMap::iterator it_id = m_iqIDHandlers.find( iq.
id() );
1609 bool haveIdHandler = ( it_id != m_iqIDHandlers.end() );
1610 m_iqHandlerMapMutex.
unlock();
1613 (*it_id).second.ih->handleIqID( iq, (*it_id).second.context );
1614 if( (*it_id).second.del )
1615 delete (*it_id).second.ih;
1616 m_iqHandlerMapMutex.
lock();
1617 m_iqIDHandlers.erase( it_id );
1618 m_iqHandlerMapMutex.
unlock();
1633 bool handled =
false;
1646 m_iqExtHandlerMapMutex.
lock();
1647 typedef IqHandlerMap::const_iterator IQci;
1649 StanzaExtensionList::const_iterator itse = sel.begin();
1650 for( ; !handled && itse != sel.end(); ++itse )
1652 std::pair<IQci, IQci> g = m_iqExtHandlers.equal_range( (*itse)->extensionType() );
1653 for( IQci it = g.first; !handled && it != g.second; ++it )
1655 if( (*it).second->handleIq( iq ) )
1659 m_iqExtHandlerMapMutex.
unlock();
1669 void ClientBase::notifyMessageHandlers(
Message& msg )
1671 if( m_mucInvitationHandler )
1678 mu->jid() ?
JID( *(mu->jid()) ) :
JID(),
1688 MessageSessionList::const_iterator it1 = m_messageSessions.begin();
1689 for( ; it1 != m_messageSessions.end(); ++it1 )
1691 if( (*it1)->target().full() == msg.
from().
full() &&
1693 || (*it1)->threadID() == msg.
thread()
1694 || (*it1)->honorThreadID() ) &&
1696 ( (*it1)->types() & msg.
subtype() || (*it1)->types() == 0 ) )
1698 (*it1)->handleMessage( msg );
1703 it1 = m_messageSessions.begin();
1704 for( ; it1 != m_messageSessions.end(); ++it1 )
1706 if( (*it1)->target().bare() == msg.
from().
bare() &&
1708 || (*it1)->threadID() == msg.
thread()
1709 || (*it1)->honorThreadID() ) &&
1711 ( (*it1)->types() & msg.
subtype() || (*it1)->types() == 0 ) )
1713 (*it1)->handleMessage( msg );
1723 msHandler = m_messageSessionHandlerChat;
1726 msHandler = m_messageSessionHandlerNormal;
1729 msHandler = m_messageSessionHandlerGroupchat;
1732 msHandler = m_messageSessionHandlerHeadline;
1747 MessageHandlerList::const_iterator it = m_messageHandlers.begin();
1748 for( ; it != m_messageHandlers.end(); ++it )
1750 (*it)->handleMessage( msg );
1757 void ClientBase::notifyTagHandlers(
Tag* tag )
1759 TagHandlerList::const_iterator it = m_tagHandlers.begin();
1760 for( ; it != m_tagHandlers.end(); ++it )
1763 (*it).th->handleTag( tag );
1781 if( (*it)->extensionType() == type )
1795 for(
int i = 0; i < 4; ++i )
1796 sprintf( cn + i*8,
"%08x", rand() );
1797 return std::string( cn, 4*8 );;
1815 TLSBase* ClientBase::getDefaultEncryption()
An abstract base class for a connection.
An abstraction of a MUC user query.
long int totalBytesReceived
virtual void handleMessageSession(MessageSession *session)=0
void processSASLChallenge(const std::string &challenge)
void addFeature(const std::string &feature)
void removeStatisticsHandler()
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
void registerEventHandler(EventHandler *eh, const std::string &context)
const std::string & streamErrorText(const std::string &lang="default") const
A simple implementation of a mutex guard.
virtual Tag * tag() const
void setServer(const std::string &server)
virtual void handleConnect(const ConnectionBase *connection)
std::list< const StanzaExtension * > StanzaExtensionList
MessageType subtype() const
long int messageStanzasSent
Tag * embeddedTag() const
virtual void onConnect()=0
void removeIDHandler(IqHandler *ih)
ConnectionBase * m_connection
virtual void handleStatistics(const StatisticsStruct stats)=0
const StanzaExtension * findExtension(int type) const
const std::string XMLNS_STREAM_TLS
void registerConnectionListener(ConnectionListener *cl)
void dbg(LogArea area, const std::string &message) const
An abstraction of a message session between any two entities.
void setClientCert(const std::string &clientKey, const std::string &clientCerts)
A virtual interface which can be reimplemented to receive incoming subscription stanzas.
virtual Tag * tag() const
virtual void handleMessage(Message &msg)
virtual const std::string channelBinding() const
const std::string XMLNS_STREAM_SASL
const std::string XMLNS_XMPP_PING
An base class for event handlers.
void registerMessageSessionHandler(MessageSessionHandler *msh, int types=0)
const std::string xmlns() const
void clearList(std::list< T * > &L)
void registerSubscriptionHandler(SubscriptionHandler *sh)
void removeConnectionListener(ConnectionListener *cl)
An abstraction of an IQ stanza.
This is an abstract base class for stream compression implementations.
const StanzaExtensionList & extensions() const
void removeIqHandler(IqHandler *ih, int exttype)
void registerIqHandler(IqHandler *ih, int exttype)
const std::string XMPP_STREAM_VERSION_MAJOR
void addExtension(const StanzaExtension *se)
ConnectionState state() const
Stanza * embeddedStanza() const
const std::string binary()
void removeTagHandler(TagHandler *th, const std::string &tag, const std::string &xmlns)
void registerMUCInvitationHandler(MUCInvitationHandler *mih)
void notifyOnResourceBind(const std::string &resource)
virtual bool encrypt(const std::string &data)=0
const std::string XMLNS_CLIENT
void registerMessageHandler(MessageHandler *mh)
void registerStanzaExtension(StanzaExtension *ext)
virtual void onSessionCreateError(const Error *error)
virtual void decompress(const std::string &data)=0
const std::string & bare() const
bool removePresenceExtension(int type)
virtual void onDisconnect(ConnectionError e)=0
std::list< Tag * > TagList
const TagList sendQueue()
virtual void onResourceBindError(const Error *error)
MUCUserOperation operation() const
const std::string & name() const
void notifyOnResourceBindError(const Error *error)
bool hasChild(const std::string &name, const std::string &attr=EmptyString, const std::string &value=EmptyString) const
const std::string & thread() const
void setServer(const std::string &server, int port=-1)
virtual bool init(const std::string &clientKey=EmptyString, const std::string &clientCerts=EmptyString, const StringList &cacerts=StringList())
StatisticsStruct getStatistics()
Tag * findChild(const std::string &name) const
A virtual interface which can be reimplemented to receive incoming message sessions.
const std::string & server() const
void addExtensions(Stanza &stanza, Tag *tag)
A stanza error abstraction implemented as a StanzaExtension.
virtual void disconnect()=0
virtual ConnectionError connect()=0
virtual Tag * tag() const
An abstraction of a presence stanza.
bool removeStanzaExtension(int ext)
bool setCData(const std::string &cdata)
void removeMUCInvitationHandler()
const std::string body(const std::string &lang="default") const
This is an implementation of a simple TCP connection.
int extensionType() const
virtual void handleReceivedData(const ConnectionBase *connection, const std::string &data)
const std::string XMPP_STREAM_VERSION_MINOR
void clearMap(std::map< Key, T * > &M)
void addChild(Tag *child)
const std::string decode64(const std::string &input)
virtual void onResourceBind(const std::string &resource)
bool hasEmbeddedStanza() const
virtual const std::string & password() const
An abstraction of a message stanza.
bool processSASLSuccess(const std::string &payload)
long int totalStanzasReceived
void feed(const unsigned char *data, int bytes)
virtual void handleDecryptedData(const TLSBase *base, const std::string &data)
void removeMessageHandler(MessageHandler *mh)
ConnectionState state() const
This is an abstraction of the various TLS backends.
const std::string & username() const
The namespace for the gloox library.
A virtual interface which can be reimplemented to receive incoming message stanzas.
const std::string encode64(const std::string &input)
virtual void handleCompressedData(const std::string &data)
This class abstracts a stanza extension, which is usually an XML child element in a specific namespac...
virtual ConnectionError recv(int timeout=-1)
StanzaExtensionList m_presenceExtensions
void notifyOnSessionCreateError(const Error *error)
const std::string & full() const
long int iqStanzasReceived
virtual bool send(const std::string &data)=0
A virtual interface which can be reimplemented to receive non-XMPP Core stanzas.
virtual void handleMUCInvitation(const JID &room, const JID &from, const std::string &reason, const std::string &body, const std::string &password, bool cont, const std::string &thread)=0
CompressionBase * m_compression
A virtual interface which can be reimplemented to receive presence stanzas.
const std::string & server() const
bool removeExtension(int ext)
void xmppPing(const JID &to, EventHandler *eh)
A Factory that creates StanzaExtensions from Tags.
virtual void disconnect(ConnectionError reason)
bool connect(bool block=true)
const std::string XMLNS_XMPP_STREAM
long int s10nStanzasReceived
void registerMessageSession(MessageSession *session)
virtual void handleDisconnect(const ConnectionBase *connection, ConnectionError reason)
virtual void handleTag(Tag *tag)
ClientBase(const std::string &ns, const std::string &server, int port=-1)
void disposeMessageSession(MessageSession *session)
void dispatch(const Event &event, const std::string &context, bool remove)
virtual bool checkStreamVersion(const std::string &version)
void feed(const unsigned char *data, unsigned length)
const std::string XMLNS_STREAM
const std::string GLOOX_VERSION
void removePresenceHandler(PresenceHandler *ph)
An implementation of SHA1.
void setVersion(const std::string &name, const std::string &version, const std::string &os=EmptyString)
virtual ConnectionError receive()=0
bool addAttribute(Attribute *attr)
virtual void onStreamEvent(StreamEvent event)
long int presenceStanzasReceived
virtual ConnectionError recv(int timeout=-1)=0
virtual void handleHandshakeResult(const TLSBase *base, bool success, CertInfo &certinfo)
void processSASLError(Tag *tag)
const std::string xml() const
std::string m_clientCerts
void registerPresenceHandler(PresenceHandler *ph)
A virtual interface which can be reimplemented to receive IQ stanzas.
virtual void getStatistics(long int &totalIn, long int &totalOut)=0
bool saslprep(const std::string &input, std::string &out)
void setCompressionImpl(CompressionBase *cb)
A handler that can be used to receive invitations to MUC rooms.
virtual void handleEncryptedData(const TLSBase *base, const std::string &data)
This class implements XEP-0030 (Service Discovery) and XEP-0092 (Software Version).
const std::string getID()
const std::string & findAttribute(const std::string &name) const
const TagList & children() const
const std::string cdata() const
virtual void handleDecompressedData(const std::string &data)
void setConnectionImpl(ConnectionBase *cb)
void notifyStreamEvent(StreamEvent event)
void setEncryptionImpl(TLSBase *tb)
An abstraction of a subscription stanza.
void removeSubscriptionHandler(SubscriptionHandler *sh)
void checkQueue(int handled, bool resend)
virtual void compress(const std::string &data)=0
long int presenceStanzasSent
const std::string & id() const
long int messageStanzasReceived
void removeFeature(const std::string &feature)
An abstract base class for TLS implementations.
void addPresenceExtension(StanzaExtension *se)
bool hasAttribute(const std::string &name, const std::string &value=EmptyString) const
void registerExtension(StanzaExtension *ext)
void startSASL(SaslMechanism type)
Derived classes can be registered as ConnectionListeners with the Client.
const std::string binary()
void registerStatisticsHandler(StatisticsHandler *sh)
void err(LogArea area, const std::string &message) const
const std::string EmptyString
virtual Tag * tag() const
This is an abstraction of an XML element.
bool notifyOnTLSConnect(const CertInfo &info)
A virtual interface which can be reimplemented to receive connection statistics.
virtual int decrypt(const std::string &data)=0
int feed(std::string &data)
const std::string XMLNS_MUC
long int totalStanzasSent
void registerTagHandler(TagHandler *th, const std::string &tag, const std::string &xmlns)