gloox 1.0
clientbase.h
00001 /*
00002   Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 
00014 
00015 #ifndef CLIENTBASE_H__
00016 #define CLIENTBASE_H__
00017 
00018 #include "macros.h"
00019 #include "gloox.h"
00020 #include "eventdispatcher.h"
00021 #include "iqhandler.h"
00022 #include "jid.h"
00023 #include "logsink.h"
00024 #include "mutex.h"
00025 #include "taghandler.h"
00026 #include "statisticshandler.h"
00027 #include "tlshandler.h"
00028 #include "compressiondatahandler.h"
00029 #include "connectiondatahandler.h"
00030 #include "parser.h"
00031 
00032 #include <string>
00033 #include <list>
00034 #include <map>
00035 
00036 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
00037 #include <windows.h>
00038 #define SECURITY_WIN32
00039 #include <security.h>
00040 #endif
00041 
00042 namespace gloox
00043 {
00044 
00045   class Disco;
00046   class EventHandler;
00047   class Event;
00048   class Tag;
00049   class IQ;
00050   class Message;
00051   class Presence;
00052   class Subscription;
00053   class MessageSessionHandler;
00054   class ConnectionListener;
00055   class MessageHandler;
00056   class MessageSession;
00057   class PresenceHandler;
00058   class SubscriptionHandler;
00059   class MUCInvitationHandler;
00060   class TagHandler;
00061   class TLSBase;
00062   class ConnectionBase;
00063   class CompressionBase;
00064   class StanzaExtensionFactory;
00065 
00075   class GLOOX_API ClientBase : public TagHandler, public ConnectionDataHandler,
00076                                public CompressionDataHandler, public TLSHandler,
00077                                public IqHandler
00078   {
00079 
00080     friend class RosterManager;
00081 
00082     public:
00091       ClientBase( const std::string& ns, const std::string& server, int port = -1 );
00092 
00102       ClientBase( const std::string& ns, const std::string& password,
00103                   const std::string& server, int port = -1 );
00104 
00108       virtual ~ClientBase();
00109 
00122       bool connect( bool block = true );
00123 
00131       ConnectionError recv( int timeout = -1 );
00132 
00137       virtual const std::string& username() const { return m_jid.username(); }
00138 
00146       const JID& jid() { return m_authzid ? m_authzid : m_jid; }
00147 
00153       void setSasl( bool sasl ) { m_sasl = sasl; }
00154 
00160       void setTls( TLSPolicy tls ) { m_tls = tls; }
00161 
00167       void setCompression( bool compression ) { m_compress = compression; }
00168 
00174       void setPort( int port ) { m_port = port; }
00175 
00183       void setServer( const std::string &server );
00184 
00189       void setPassword( const std::string &password ) { m_password = password; }
00190 
00195       const std::string& server() const { return m_server; }
00196 
00201       bool sasl() const { return m_sasl; }
00202 
00207       TLSPolicy tls() const { return m_tls; }
00208 
00213       bool compression() const { return m_compress; }
00214 
00220       int port() const { return m_port; }
00221 
00226       virtual const std::string& password() const { return m_password; }
00227 
00232       virtual Disco* disco() const { return m_disco; }
00233 
00239       const std::string getID();
00240 
00248       void send( Tag* tag );
00249 
00259       void send( IQ& iq, IqHandler* ih, int context, bool del = false );
00260 
00265       void send( const IQ& iq );
00266 
00271       void send( const Message& msg );
00272 
00277       void send( const Subscription& sub );
00278 
00283       void send( Presence& pres );
00284 
00289       bool authed() const { return m_authed; }
00290 
00295       ConnectionState state() const;
00296 
00301       const std::string& xmlLang() const { return m_xmllang; }
00302 
00309       void setXmlLang( const std::string& xmllang ) { m_xmllang = xmllang; }
00310 
00316       ConnectionBase* connectionImpl() const { return m_connection; }
00317 
00325       void setConnectionImpl( ConnectionBase* cb );
00326 
00332       TLSBase* encryptionImpl() const { return m_encryption; }
00333 
00341       void setEncryptionImpl( TLSBase* tb );
00342 
00348       CompressionBase* compressionImpl() const { return m_compression; }
00349 
00357       void setCompressionImpl( CompressionBase* cb );
00358 
00363       void whitespacePing();
00364 
00371       void xmppPing( const JID& to, EventHandler* eh );
00372 
00380       void setAuthzid( const JID& authzid ) { m_authzid = authzid; }
00381 
00390       void setAuthcid( const std::string& authcid ) { m_authcid = authcid; }
00391 
00402       void setSASLMechanisms( int mechanisms ) { m_availableSaslMechs = mechanisms; }
00403 
00408       void registerStanzaExtension( StanzaExtension* ext );
00409 
00415       bool removeStanzaExtension( int ext );
00416 
00421       void registerConnectionListener( ConnectionListener* cl );
00422 
00432       void registerIqHandler( IqHandler* ih, int exttype );
00433 
00441       void removeIDHandler( IqHandler* ih );
00442 
00447       void registerMessageHandler( MessageHandler* mh );
00448 
00453       void removeMessageHandler( MessageHandler* mh );
00454 
00464       void registerMessageSession( MessageSession* session );
00465 
00470       void disposeMessageSession( MessageSession* session );
00471 
00476       void registerPresenceHandler( PresenceHandler* ph );
00477 
00487       void registerPresenceHandler( const JID& jid, PresenceHandler* ph );
00488 
00493       void registerSubscriptionHandler( SubscriptionHandler* sh );
00494 
00502       void registerTagHandler( TagHandler* th, const std::string& tag,
00503                                                const std::string& xmlns );
00504 
00511       void registerStatisticsHandler( StatisticsHandler* sh );
00512 
00517       void removeConnectionListener( ConnectionListener* cl );
00518 
00526       void removeIqHandler( IqHandler* ih, int exttype );
00527 
00532       void removePresenceHandler( PresenceHandler* ph );
00533 
00540       void removePresenceHandler( const JID& jid, PresenceHandler* ph );
00541 
00546       void removeSubscriptionHandler( SubscriptionHandler* sh );
00547 
00554       void removeTagHandler( TagHandler* th, const std::string& tag,
00555                                              const std::string& xmlns );
00556 
00560       void removeStatisticsHandler();
00561 
00567       void setCACerts( const StringList& cacerts ) { m_cacerts = cacerts; }
00568 
00580       void setClientCert( const std::string& clientKey, const std::string& clientCerts );
00581 
00592       void registerMessageSessionHandler( MessageSessionHandler* msh, int types = 0 );
00593 
00598       LogSink& logInstance() { return m_logInstance; }
00599 
00606       StreamError streamError() const { return m_streamError; }
00607 
00617       const std::string& streamErrorText( const std::string& lang = "default" ) const;
00618 
00625       const std::string& streamErrorCData() const { return m_streamErrorCData; }
00626 
00632       const Tag* streamErrorAppCondition() const { return m_streamErrorAppCondition; }
00633 
00639       AuthenticationError authError() const { return m_authError; }
00640 
00646       StatisticsStruct getStatistics();
00647 
00652       void registerMUCInvitationHandler( MUCInvitationHandler* mih );
00653 
00657       void removeMUCInvitationHandler();
00658 
00666       void addPresenceExtension( StanzaExtension* se );
00667 
00673       bool removePresenceExtension( int type );
00674 
00679       const StanzaExtensionList& presenceExtensions() const { return m_presenceExtensions; }
00680 
00681       // reimplemented from ParserHandler
00682       virtual void handleTag( Tag* tag );
00683 
00684       // reimplemented from CompressionDataHandler
00685       virtual void handleCompressedData( const std::string& data );
00686 
00687       // reimplemented from CompressionDataHandler
00688       virtual void handleDecompressedData( const std::string& data );
00689 
00690       // reimplemented from ConnectionDataHandler
00691       virtual void handleReceivedData( const ConnectionBase* connection, const std::string& data );
00692 
00693       // reimplemented from ConnectionDataHandler
00694       virtual void handleConnect( const ConnectionBase* connection );
00695 
00696       // reimplemented from ConnectionDataHandler
00697       virtual void handleDisconnect( const ConnectionBase* connection, ConnectionError reason );
00698 
00699       // reimplemented from TLSHandler
00700       virtual void handleEncryptedData( const TLSBase* base, const std::string& data );
00701 
00702       // reimplemented from TLSHandler
00703       virtual void handleDecryptedData( const TLSBase* base, const std::string& data );
00704 
00705       // reimplemented from TLSHandler
00706       virtual void handleHandshakeResult( const TLSBase* base, bool success, CertInfo &certinfo );
00707 
00708     protected:
00714       void notifyOnResourceBindError( const Error* error );
00715 
00720       void notifyOnResourceBind( const std::string& resource );
00721 
00727       void notifyOnSessionCreateError( const Error* error );
00728 
00736       bool notifyOnTLSConnect( const CertInfo& info );
00737 
00741       void notifyOnConnect();
00742 
00747       void notifyStreamEvent( StreamEvent event );
00748 
00753       virtual void disconnect( ConnectionError reason );
00754 
00758       void header();
00759 
00764       void setAuthed( bool authed ) { m_authed = authed; }
00765 
00771       void setAuthFailure( AuthenticationError e ) { m_authError = e; }
00772 
00780       virtual bool checkStreamVersion( const std::string& version );
00781 
00786       void startSASL( SaslMechanism type );
00787 
00791       void processSASLSuccess();
00792 
00797       void processSASLChallenge( const std::string& challenge );
00798 
00803       void processSASLError( Tag* tag );
00804 
00809       void setNTLMDomain( const std::string& domain ) { m_ntlmDomain = domain; }
00810 
00814       void startTls();
00815 
00820       bool hasTls();
00821 
00822       JID m_jid;                         
00823       JID m_authzid;                     
00824       std::string m_authcid;             
00825       ConnectionBase* m_connection;      
00826       TLSBase* m_encryption;             
00827       CompressionBase* m_compression;    
00828       Disco* m_disco;                    
00831       StanzaExtensionList m_presenceExtensions;
00832 
00833       std::string m_selectedResource;    
00835       std::string m_clientCerts;         
00836       std::string m_clientKey;           
00837       std::string m_namespace;           
00838       std::string m_password;            
00839       std::string m_xmllang;             
00840       std::string m_server;              
00842       std::string m_sid;                 
00843       bool m_compressionActive;          
00845       bool m_encryptionActive;           
00847       bool m_compress;                   
00849       bool m_authed;                     
00850       bool m_block;                      
00851       bool m_sasl;                       
00852       TLSPolicy m_tls;                   
00853       int m_port;                        
00856       int m_availableSaslMechs;          
00858     private:
00859 #ifdef CLIENTBASE_TEST
00860     public:
00861 #endif
00862 
00868       class Ping : public StanzaExtension
00869       {
00870 
00871         public:
00875           Ping();
00876 
00880           virtual ~Ping();
00881 
00882           // reimplemented from StanzaExtension
00883           virtual const std::string& filterString() const;
00884 
00885           // reimplemented from StanzaExtension
00886           virtual StanzaExtension* newInstance( const Tag* tag ) const
00887           {
00888             (void)tag;
00889             return new Ping();
00890           }
00891 
00892           // reimplemented from StanzaExtension
00893           virtual Tag* tag() const
00894           {
00895             return new Tag( "ping", "xmlns", XMLNS_XMPP_PING );
00896           }
00897 
00898           // reimplemented from StanzaExtension
00899           virtual StanzaExtension* clone() const
00900           {
00901             return new Ping();
00902           }
00903 
00904       };
00905 
00906       ClientBase( const ClientBase& );
00907       ClientBase& operator=( const ClientBase& );
00908 
00912       virtual void handleStartNode() = 0;
00913 
00919       virtual bool handleNormalNode( Tag* tag ) = 0;
00920       virtual void rosterFilled() = 0;
00921       virtual void cleanup() {}
00922       virtual void handleIqIDForward( const IQ& iq, int context ) { (void) iq; (void) context; }
00923 
00924       void parse( const std::string& data );
00925       void init();
00926       void handleStreamError( Tag* tag );
00927       TLSBase* getDefaultEncryption();
00928       CompressionBase* getDefaultCompression();
00929 
00930       void notifyIqHandlers( IQ& iq );
00931       void notifyMessageHandlers( Message& msg );
00932       void notifyPresenceHandlers( Presence& presence );
00933       void notifySubscriptionHandlers( Subscription& s10n );
00934       void notifyTagHandlers( Tag* tag );
00935       void notifyOnDisconnect( ConnectionError e );
00936       void send( const std::string& xml );
00937       void addFrom( Tag* tag );
00938       void addNamespace( Tag* tag );
00939 
00940       // reimplemented from IqHandler
00941       virtual bool handleIq( const IQ& iq );
00942 
00943       // reimplemented from IqHandler
00944       virtual void handleIqID( const IQ& iq, int context );
00945 
00946       struct TrackStruct
00947       {
00948         IqHandler* ih;
00949         int context;
00950         bool del;
00951       };
00952 
00953       struct TagHandlerStruct
00954       {
00955         TagHandler* th;
00956         std::string xmlns;
00957         std::string tag;
00958       };
00959 
00960       struct JidPresHandlerStruct
00961       {
00962         JID* jid;
00963         PresenceHandler* ph;
00964       };
00965 
00966       enum TrackContext
00967       {
00968         XMPPPing
00969       };
00970 
00971       typedef std::list<ConnectionListener*>               ConnectionListenerList;
00972       typedef std::multimap<const std::string, IqHandler*> IqHandlerMapXmlns;
00973       typedef std::multimap<const int, IqHandler*>         IqHandlerMap;
00974       typedef std::map<const std::string, TrackStruct>     IqTrackMap;
00975       typedef std::map<const std::string, MessageHandler*> MessageHandlerMap;
00976       typedef std::list<MessageSession*>                   MessageSessionList;
00977       typedef std::list<MessageHandler*>                   MessageHandlerList;
00978       typedef std::list<PresenceHandler*>                  PresenceHandlerList;
00979       typedef std::list<JidPresHandlerStruct>              PresenceJidHandlerList;
00980       typedef std::list<SubscriptionHandler*>              SubscriptionHandlerList;
00981       typedef std::list<TagHandlerStruct>                  TagHandlerList;
00982 
00983       ConnectionListenerList   m_connectionListeners;
00984       IqHandlerMapXmlns        m_iqNSHandlers;
00985       IqHandlerMap             m_iqExtHandlers;
00986       IqTrackMap               m_iqIDHandlers;
00987       MessageSessionList       m_messageSessions;
00988       MessageHandlerList       m_messageHandlers;
00989       PresenceHandlerList      m_presenceHandlers;
00990       PresenceJidHandlerList   m_presenceJidHandlers;
00991       SubscriptionHandlerList  m_subscriptionHandlers;
00992       TagHandlerList           m_tagHandlers;
00993       StringList               m_cacerts;
00994       StatisticsHandler      * m_statisticsHandler;
00995       MUCInvitationHandler   * m_mucInvitationHandler;
00996       MessageSessionHandler  * m_messageSessionHandlerChat;
00997       MessageSessionHandler  * m_messageSessionHandlerGroupchat;
00998       MessageSessionHandler  * m_messageSessionHandlerHeadline;
00999       MessageSessionHandler  * m_messageSessionHandlerNormal;
01000 
01001       util::Mutex m_iqHandlerMapMutex;
01002 
01003       Parser m_parser;
01004       LogSink m_logInstance;
01005       StanzaExtensionFactory* m_seFactory;
01006       EventDispatcher m_dispatcher;
01007 
01008       AuthenticationError m_authError;
01009       StreamError m_streamError;
01010       StringMap m_streamErrorText;
01011       std::string m_streamErrorCData;
01012       Tag* m_streamErrorAppCondition;
01013 
01014       StatisticsStruct m_stats;
01015 
01016       SaslMechanism m_selectedSaslMech;
01017 
01018       std::string m_ntlmDomain;
01019       bool m_autoMessageSession;
01020 
01021 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
01022       CredHandle m_credHandle;
01023       CtxtHandle m_ctxtHandle;
01024 #endif
01025 
01026   };
01027 
01028 }
01029 
01030 #endif // CLIENTBASE_H__