gloox  1.1-svn
clientbase.h
1 /*
2  Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 
15 #ifndef CLIENTBASE_H__
16 #define CLIENTBASE_H__
17 
18 #include "macros.h"
19 #include "gloox.h"
20 #include "eventdispatcher.h"
21 #include "iqhandler.h"
22 #include "jid.h"
23 #include "logsink.h"
24 #include "mutex.h"
25 #include "taghandler.h"
26 #include "statisticshandler.h"
27 #include "connectiondatahandler.h"
28 #include "parser.h"
29 #include "tlshandler.h"
30 
31 #include <string>
32 #include <list>
33 #include <map>
34 
35 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
36 #include <windows.h>
37 #define SECURITY_WIN32
38 #include <security.h>
39 #endif
40 
41 namespace gloox
42 {
43 
44  class Disco;
45  class EventHandler;
46  class Event;
47  class Tag;
48  class IQ;
49  class Message;
50  class Presence;
51  class Subscription;
52  class MessageSessionHandler;
53  class ConnectionListener;
54  class MessageHandler;
55  class MessageSession;
56  class PresenceHandler;
57  class SubscriptionHandler;
58  class MUCInvitationHandler;
59  class TagHandler;
60  class ConnectionBase;
61  class ConnectionTLS;
62  class ConnectionCompression;
63  class StanzaExtensionFactory;
64 
74  class GLOOX_API ClientBase : public TagHandler, public ConnectionDataHandler,
75  public IqHandler, public TLSHandler
76  {
77 
78  friend class RosterManager;
79 
80  public:
89  ClientBase( const std::string& ns, const std::string& server, int port = -1 );
90 
100  ClientBase( const std::string& ns, const std::string& password,
101  const std::string& server, int port = -1 );
102 
106  virtual ~ClientBase();
107 
120  bool connect( bool block = true );
121 
129  ConnectionError recv( int timeout = -1 );
130 
135  virtual const std::string& username() const { return m_jid.username(); }
136 
144  const JID& jid() { return m_authzid ? m_authzid : m_jid; }
145 
151  void setSasl( bool sasl ) { m_sasl = sasl; }
152 
158  void setTls( TLSPolicy tls ) { m_tls = tls; }
159 
165  void setCompression( bool compression ) { m_compress = compression; }
166 
172  void setPort( int port ) { m_port = port; }
173 
181  void setServer( const std::string &server );
182 
187  void setPassword( const std::string &password ) { m_password = password; }
188 
193  const std::string& server() const { return m_server; }
194 
199  bool sasl() const { return m_sasl; }
200 
205  TLSPolicy tls() const { return m_tls; }
206 
211  bool compression() const { return m_compress; }
212 
218  int port() const { return m_port; }
219 
224  virtual const std::string& password() const { return m_password; }
225 
230  virtual Disco* disco() const { return m_disco; }
231 
237  const std::string getID();
238 
246  void send( Tag* tag );
247 
257  void send( IQ& iq, IqHandler* ih, int context, bool del = false );
258 
263  void send( const IQ& iq );
264 
269  void send( const Message& msg );
270 
275  void send( const Subscription& sub );
276 
281  void send( const Presence& pres );
282 
287  bool authed() const { return m_authed; }
288 
293  ConnectionState state() const;
294 
299  const std::string& xmlLang() const { return m_xmllang; }
300 
307  void setXmlLang( const std::string& xmllang ) { m_xmllang = xmllang; }
308 
314  ConnectionBase* connectionImpl() const { return m_connection; }
315 
323  void setConnectionImpl( ConnectionBase* cb );
324 
329  void whitespacePing();
330 
337  void xmppPing( const JID& to, EventHandler* eh );
338 
346  void setAuthzid( const JID& authzid ) { m_authzid = authzid; }
347 
356  void setAuthcid( const std::string& authcid ) { m_authcid = authcid; }
357 
368  void setSASLMechanisms( int mechanisms ) { m_availableSaslMechs = mechanisms; }
369 
374  void registerStanzaExtension( StanzaExtension* ext );
375 
381  bool removeStanzaExtension( int ext );
382 
387  void registerConnectionListener( ConnectionListener* cl );
388 
398  void registerIqHandler( IqHandler* ih, int exttype );
399 
407  void removeIDHandler( IqHandler* ih );
408 
413  void registerMessageHandler( MessageHandler* mh );
414 
419  void removeMessageHandler( MessageHandler* mh );
420 
430  void registerMessageSession( MessageSession* session );
431 
436  void disposeMessageSession( MessageSession* session );
437 
442  void registerPresenceHandler( PresenceHandler* ph );
443 
453  void registerPresenceHandler( const JID& jid, PresenceHandler* ph );
454 
459  void registerSubscriptionHandler( SubscriptionHandler* sh );
460 
468  void registerTagHandler( TagHandler* th, const std::string& tag,
469  const std::string& xmlns );
470 
477  void registerStatisticsHandler( StatisticsHandler* sh );
478 
483  void removeConnectionListener( ConnectionListener* cl );
484 
492  void removeIqHandler( IqHandler* ih, int exttype );
493 
498  void removePresenceHandler( PresenceHandler* ph );
499 
506  void removePresenceHandler( const JID& jid, PresenceHandler* ph );
507 
512  void removeSubscriptionHandler( SubscriptionHandler* sh );
513 
520  void removeTagHandler( TagHandler* th, const std::string& tag,
521  const std::string& xmlns );
522 
526  void removeStatisticsHandler();
527 
533  void setCACerts( const StringList& cacerts ) { m_cacerts = cacerts; }
534 
546  void setClientCert( const std::string& clientKey, const std::string& clientCerts );
547 
558  void registerMessageSessionHandler( MessageSessionHandler* msh, int types = 0 );
559 
564  LogSink& logInstance() { return m_logInstance; }
565 
572  StreamError streamError() const { return m_streamError; }
573 
583  const std::string& streamErrorText( const std::string& lang = "default" ) const;
584 
591  const std::string& streamErrorCData() const { return m_streamErrorCData; }
592 
598  const Tag* streamErrorAppCondition() const { return m_streamErrorAppCondition; }
599 
605  AuthenticationError authError() const { return m_authError; }
606 
612  StatisticsStruct getStatistics();
613 
618  void registerMUCInvitationHandler( MUCInvitationHandler* mih );
619 
623  void removeMUCInvitationHandler();
624 
632  void addPresenceExtension( StanzaExtension* se );
633 
639  bool removePresenceExtension( int type );
640 
645  const StanzaExtensionList& presenceExtensions() const { return m_presenceExtensions; }
646 
647  // reimplemented from ParserHandler
648  virtual void handleTag( Tag* tag );
649 
650  // reimplemented from ConnectionDataHandler
651  virtual void handleReceivedData( const ConnectionBase* connection, const std::string& data );
652 
653  // reimplemented from ConnectionDataHandler
654  virtual void handleConnect( const ConnectionBase* connection );
655 
656  // reimplemented from ConnectionDataHandler
657  virtual void handleDisconnect( const ConnectionBase* connection, ConnectionError reason );
658 
659  // reimplemented from TLSHandler
660  virtual void handleEncryptedData( const TLSBase* /*base*/, const std::string& /*data*/ ) {}
661 
662  // reimplemented from TLSHandler
663  virtual void handleDecryptedData( const TLSBase* /*base*/, const std::string& /*data*/ ) {}
664 
665  // reimplemented from TLSHandler
666  virtual void handleHandshakeResult( const TLSBase* base, bool success, CertInfo &certinfo );
667 
668  protected:
674  void notifyOnResourceBindError( const Error* error );
675 
680  void notifyOnResourceBind( const std::string& resource );
681 
687  void notifyOnSessionCreateError( const Error* error );
688 
696  bool notifyOnTLSConnect( const CertInfo& info );
697 
701  void notifyOnConnect();
702 
707  void notifyStreamEvent( StreamEvent event );
708 
713  virtual void disconnect( ConnectionError reason );
714 
718  void header();
719 
724  void setAuthed( bool authed ) { m_authed = authed; }
725 
731  void setAuthFailure( AuthenticationError e ) { m_authError = e; }
732 
740  virtual bool checkStreamVersion( const std::string& version );
741 
746  void startSASL( SaslMechanism type );
747 
751  void processSASLSuccess();
752 
757  void processSASLChallenge( const std::string& challenge );
758 
763  void processSASLError( Tag* tag );
764 
769  void setNTLMDomain( const std::string& domain ) { m_ntlmDomain = domain; }
770 
774  void startTls();
775 
780  bool hasTls();
781  bool hasCompression();
782 
785  std::string m_authcid;
793  LogSink m_logInstance;
794  StringList m_cacerts;
795 
796  GLOOX_DEPRECATED std::string m_selectedResource;
800  std::string m_clientCerts;
801  std::string m_clientKey;
802  std::string m_namespace;
803  std::string m_password;
804  std::string m_xmllang;
805  std::string m_server;
807  std::string m_sid;
808  bool m_compressionActive;
810  bool m_encryptionActive;
812  bool m_compress;
813  bool m_authed;
814  bool m_block;
815  bool m_sasl;
817  int m_port;
822  private:
823 #ifdef CLIENTBASE_TEST
824  public:
825 #endif
826 
832  class Ping : public StanzaExtension
833  {
834 
835  public:
839  Ping();
840 
844  virtual ~Ping();
845 
846  // reimplemented from StanzaExtension
847  virtual const std::string& filterString() const;
848 
849  // reimplemented from StanzaExtension
850  virtual StanzaExtension* newInstance( const Tag* tag ) const
851  {
852  (void)tag;
853  return new Ping();
854  }
855 
856  // reimplemented from StanzaExtension
857  virtual Tag* tag() const
858  {
859  return new Tag( "ping", "xmlns", XMLNS_XMPP_PING );
860  }
861 
862  // reimplemented from StanzaExtension
863  virtual StanzaExtension* clone() const
864  {
865  return new Ping();
866  }
867 
868  };
869 
870  ClientBase( const ClientBase& );
871  ClientBase& operator=( const ClientBase& );
872 
876  virtual void handleStartNode() = 0;
877 
883  virtual bool handleNormalNode( Tag* tag ) = 0;
884  virtual void rosterFilled() = 0;
885  virtual void cleanup() {}
886  virtual void handleIqIDForward( const IQ& iq, int context ) { (void) iq; (void) context; }
887 
888  void parse( const std::string& data );
889  void init();
890  void handleStreamError( Tag* tag );
891 
892  void notifyIqHandlers( IQ& iq );
893  void notifyMessageHandlers( Message& msg );
894  void notifyPresenceHandlers( Presence& presence );
895  void notifySubscriptionHandlers( Subscription& s10n );
896  void notifyTagHandlers( Tag* tag );
897  void notifyOnDisconnect( ConnectionError e );
898  void send( const std::string& xml );
899  void addFrom( Tag* tag );
900  void addNamespace( Tag* tag );
901 
902  // reimplemented from IqHandler
903  virtual bool handleIq( const IQ& iq );
904 
905  // reimplemented from IqHandler
906  virtual void handleIqID( const IQ& iq, int context );
907 
908  struct TrackStruct
909  {
910  IqHandler* ih;
911  int context;
912  bool del;
913  };
914 
915  struct TagHandlerStruct
916  {
917  TagHandler* th;
918  std::string xmlns;
919  std::string tag;
920  };
921 
922  struct JidPresHandlerStruct
923  {
924  JID* jid;
925  PresenceHandler* ph;
926  };
927 
928  enum TrackContext
929  {
930  XMPPPing
931  };
932 
933  typedef std::list<ConnectionListener*> ConnectionListenerList;
934  typedef std::multimap<const std::string, IqHandler*> IqHandlerMapXmlns;
935  typedef std::multimap<const int, IqHandler*> IqHandlerMap;
936  typedef std::map<const std::string, TrackStruct> IqTrackMap;
937  typedef std::map<const std::string, MessageHandler*> MessageHandlerMap;
938  typedef std::list<MessageSession*> MessageSessionList;
939  typedef std::list<MessageHandler*> MessageHandlerList;
940  typedef std::list<PresenceHandler*> PresenceHandlerList;
941  typedef std::list<JidPresHandlerStruct> PresenceJidHandlerList;
942  typedef std::list<SubscriptionHandler*> SubscriptionHandlerList;
943  typedef std::list<TagHandlerStruct> TagHandlerList;
944 
945  ConnectionListenerList m_connectionListeners;
946  IqHandlerMapXmlns m_iqNSHandlers;
947  IqHandlerMap m_iqExtHandlers;
948  IqTrackMap m_iqIDHandlers;
949  MessageSessionList m_messageSessions;
950  MessageHandlerList m_messageHandlers;
951  PresenceHandlerList m_presenceHandlers;
952  PresenceJidHandlerList m_presenceJidHandlers;
953  SubscriptionHandlerList m_subscriptionHandlers;
954  TagHandlerList m_tagHandlers;
955  StatisticsHandler * m_statisticsHandler;
956  MUCInvitationHandler * m_mucInvitationHandler;
957  MessageSessionHandler * m_messageSessionHandlerChat;
958  MessageSessionHandler * m_messageSessionHandlerGroupchat;
959  MessageSessionHandler * m_messageSessionHandlerHeadline;
960  MessageSessionHandler * m_messageSessionHandlerNormal;
961 
962  util::Mutex m_iqHandlerMapMutex;
963  util::Mutex m_iqExtHandlerMapMutex; // TODO Enable this mutex again. However
964  // it must be possible to register new IQ handlers
965  // while an IQ is being handled!
966 
967  Parser m_parser;
968  StanzaExtensionFactory* m_seFactory;
969  EventDispatcher m_dispatcher;
970 
971  AuthenticationError m_authError;
972  StreamError m_streamError;
973  StringMap m_streamErrorText;
974  std::string m_streamErrorCData;
975  Tag* m_streamErrorAppCondition;
976 
977  ConnectionBase* m_transportConnection;
978 
979  StatisticsStruct m_stats;
980 
981  SaslMechanism m_selectedSaslMech;
982 
983  std::string m_ntlmDomain;
984  bool m_autoMessageSession;
985 
986 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
987  CredHandle m_credHandle;
988  CtxtHandle m_ctxtHandle;
989 #endif
990 
991  };
992 
993 }
994 
995 #endif // CLIENTBASE_H__