gloox  1.0.10
clientbase.h
1 /*
2  Copyright (c) 2005-2013 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 "tlshandler.h"
28 #include "compressiondatahandler.h"
29 #include "connectiondatahandler.h"
30 #include "parser.h"
31 #include "atomicrefcount.h"
32 
33 #include <string>
34 #include <list>
35 #include <map>
36 
37 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
38 #include <windows.h>
39 #define SECURITY_WIN32
40 #include <security.h>
41 #endif
42 
43 namespace gloox
44 {
45 
46  class Disco;
47  class EventHandler;
48  class Event;
49  class Tag;
50  class IQ;
51  class Message;
52  class Presence;
53  class Subscription;
54  class MessageSessionHandler;
55  class ConnectionListener;
56  class MessageHandler;
57  class MessageSession;
58  class PresenceHandler;
59  class SubscriptionHandler;
60  class MUCInvitationHandler;
61  class TagHandler;
62  class TLSBase;
63  class ConnectionBase;
64  class CompressionBase;
65  class StanzaExtensionFactory;
66 
76  class GLOOX_API ClientBase : public TagHandler, public ConnectionDataHandler,
77  public CompressionDataHandler, public TLSHandler,
78  public IqHandler
79  {
80 
81  friend class RosterManager;
82 
83  public:
92  ClientBase( const std::string& ns, const std::string& server, int port = -1 );
93 
103  ClientBase( const std::string& ns, const std::string& password,
104  const std::string& server, int port = -1 );
105 
109  virtual ~ClientBase();
110 
123  bool connect( bool block = true );
124 
132  virtual ConnectionError recv( int timeout = -1 );
133 
138  virtual const std::string& username() const { return m_jid.username(); }
139 
147  const JID& jid() { return m_authzid ? m_authzid : m_jid; }
148 
154  void setSasl( bool sasl ) { m_sasl = sasl; }
155 
161  void setTls( TLSPolicy tls ) { m_tls = tls; }
162 
168  void setCompression( bool compression ) { m_compress = compression; }
169 
175  void setPort( int port ) { m_port = port; }
176 
184  void setServer( const std::string &server );
185 
190  void setPassword( const std::string &password ) { m_password = password; }
191 
196  const std::string& server() const { return m_server; }
197 
202  bool sasl() const { return m_sasl; }
203 
208  TLSPolicy tls() const { return m_tls; }
209 
214  bool compression() const { return m_compress; }
215 
221  int port() const { return m_port; }
222 
227  virtual const std::string& password() const { return m_password; }
228 
233  virtual Disco* disco() const { return m_disco; }
234 
240  const std::string getID();
241 
249  void send( Tag* tag );
250 
260  void send( IQ& iq, IqHandler* ih, int context, bool del = false );
261 
266  void send( const IQ& iq );
267 
272  void send( const Message& msg );
273 
278  void send( const Subscription& sub );
279 
284  void send( const Presence& pres );
285 
290  bool authed() const { return m_authed; }
291 
296  ConnectionState state() const;
297 
302  const std::string& xmlLang() const { return m_xmllang; }
303 
310  void setXmlLang( const std::string& xmllang ) { m_xmllang = xmllang; }
311 
317  ConnectionBase* connectionImpl() const { return m_connection; }
318 
326  void setConnectionImpl( ConnectionBase* cb );
327 
333  TLSBase* encryptionImpl() const { return m_encryption; }
334 
342  void setEncryptionImpl( TLSBase* tb );
343 
349  CompressionBase* compressionImpl() const { return m_compression; }
350 
358  void setCompressionImpl( CompressionBase* cb );
359 
364  void whitespacePing();
365 
372  void xmppPing( const JID& to, EventHandler* eh );
373 
381  void setAuthzid( const JID& authzid ) { m_authzid = authzid; }
382 
391  void setAuthcid( const std::string& authcid ) { m_authcid = authcid; }
392 
403  void setSASLMechanisms( int mechanisms ) { m_availableSaslMechs = mechanisms; }
404 
409  void registerStanzaExtension( StanzaExtension* ext );
410 
416  bool removeStanzaExtension( int ext );
417 
422  void registerConnectionListener( ConnectionListener* cl );
423 
433  void registerIqHandler( IqHandler* ih, int exttype );
434 
442  void removeIDHandler( IqHandler* ih );
443 
448  void registerMessageHandler( MessageHandler* mh );
449 
454  void removeMessageHandler( MessageHandler* mh );
455 
465  void registerMessageSession( MessageSession* session );
466 
471  void disposeMessageSession( MessageSession* session );
472 
477  void registerPresenceHandler( PresenceHandler* ph );
478 
488  void registerPresenceHandler( const JID& jid, PresenceHandler* ph );
489 
494  void registerSubscriptionHandler( SubscriptionHandler* sh );
495 
503  void registerTagHandler( TagHandler* th, const std::string& tag,
504  const std::string& xmlns );
505 
512  void registerStatisticsHandler( StatisticsHandler* sh );
513 
518  void removeConnectionListener( ConnectionListener* cl );
519 
527  void removeIqHandler( IqHandler* ih, int exttype );
528 
533  void removePresenceHandler( PresenceHandler* ph );
534 
541  void removePresenceHandler( const JID& jid, PresenceHandler* ph );
542 
547  void removeSubscriptionHandler( SubscriptionHandler* sh );
548 
555  void removeTagHandler( TagHandler* th, const std::string& tag,
556  const std::string& xmlns );
557 
561  void removeStatisticsHandler();
562 
568  void setCACerts( const StringList& cacerts ) { m_cacerts = cacerts; }
569 
581  void setClientCert( const std::string& clientKey, const std::string& clientCerts );
582 
593  void registerMessageSessionHandler( MessageSessionHandler* msh, int types = 0 );
594 
599  LogSink& logInstance() { return m_logInstance; }
600 
607  StreamError streamError() const { return m_streamError; }
608 
618  const std::string& streamErrorText( const std::string& lang = "default" ) const;
619 
626  const std::string& streamErrorCData() const { return m_streamErrorCData; }
627 
633  const Tag* streamErrorAppCondition() const { return m_streamErrorAppCondition; }
634 
640  AuthenticationError authError() const { return m_authError; }
641 
647  StatisticsStruct getStatistics();
648 
653  void registerMUCInvitationHandler( MUCInvitationHandler* mih );
654 
658  void removeMUCInvitationHandler();
659 
667  void addPresenceExtension( StanzaExtension* se );
668 
674  bool removePresenceExtension( int type );
675 
680  const StanzaExtensionList& presenceExtensions() const { return m_presenceExtensions; }
681 
689  const TagList sendQueue();
690 
691  // reimplemented from ParserHandler
692  virtual void handleTag( Tag* tag );
693 
694  // reimplemented from CompressionDataHandler
695  virtual void handleCompressedData( const std::string& data );
696 
697  // reimplemented from CompressionDataHandler
698  virtual void handleDecompressedData( const std::string& data );
699 
700  // reimplemented from ConnectionDataHandler
701  virtual void handleReceivedData( const ConnectionBase* connection, const std::string& data );
702 
703  // reimplemented from ConnectionDataHandler
704  virtual void handleConnect( const ConnectionBase* connection );
705 
706  // reimplemented from ConnectionDataHandler
707  virtual void handleDisconnect( const ConnectionBase* connection, ConnectionError reason );
708 
709  // reimplemented from TLSHandler
710  virtual void handleEncryptedData( const TLSBase* base, const std::string& data );
711 
712  // reimplemented from TLSHandler
713  virtual void handleDecryptedData( const TLSBase* base, const std::string& data );
714 
715  // reimplemented from TLSHandler
716  virtual void handleHandshakeResult( const TLSBase* base, bool success, CertInfo &certinfo );
717 
718  protected:
719 #ifdef CLIENTBASE_TEST
720  public:
721 #endif
722 
727  void notifyOnResourceBindError( const Error* error );
728 
733  void notifyOnResourceBind( const std::string& resource );
734 
740  void notifyOnSessionCreateError( const Error* error );
741 
749  bool notifyOnTLSConnect( const CertInfo& info );
750 
754  void notifyOnConnect();
755 
760  void notifyStreamEvent( StreamEvent event );
761 
766  virtual void disconnect( ConnectionError reason );
767 
771  void header();
772 
777  void setAuthed( bool authed ) { m_authed = authed; }
778 
784  void setAuthFailure( AuthenticationError e ) { m_authError = e; }
785 
793  virtual bool checkStreamVersion( const std::string& version );
794 
799  void startSASL( SaslMechanism type );
800 
808  bool processSASLSuccess( const std::string& payload );
809 
814  void processSASLChallenge( const std::string& challenge );
815 
820  void processSASLError( Tag* tag );
821 
826  void setNTLMDomain( const std::string& domain ) { m_ntlmDomain = domain; }
827 
831  void startTls();
832 
837  bool hasTls();
838 
844  void send( const std::string& xml );
845 
854  void checkQueue( int handled, bool resend );
855 
860  int stanzasSent() const { return m_smSent; }
861 
866  std::string getRandom();
867 
870  std::string m_authcid;
878 
879  GLOOX_DEPRECATED std::string m_selectedResource;
883  std::string m_clientCerts;
884  std::string m_clientKey;
885  std::string m_namespace;
886  std::string m_password;
887  std::string m_xmllang;
888  std::string m_server;
890  std::string m_sid;
891  bool m_compressionActive;
893  bool m_encryptionActive;
895  bool m_compress;
897  bool m_authed;
898  bool m_block;
899  bool m_sasl;
901  int m_port;
910  {
916  CtxSMResumed
917  };
918 
920  int m_smHandled;
923  private:
924 #ifdef CLIENTBASE_TEST
925  public:
926 #endif
927 
933  class Ping : public StanzaExtension
934  {
935 
936  public:
940  Ping();
941 
945  virtual ~Ping();
946 
947  // reimplemented from StanzaExtension
948  virtual const std::string& filterString() const;
949 
950  // reimplemented from StanzaExtension
951  virtual StanzaExtension* newInstance( const Tag* tag ) const
952  {
953  (void)tag;
954  return new Ping();
955  }
956 
957  // reimplemented from StanzaExtension
958  virtual Tag* tag() const
959  {
960  return new Tag( "ping", "xmlns", XMLNS_XMPP_PING );
961  }
962 
963  // reimplemented from StanzaExtension
964  virtual StanzaExtension* clone() const
965  {
966  return new Ping();
967  }
968 
969  };
970 
971  ClientBase( const ClientBase& );
972  ClientBase& operator=( const ClientBase& );
973 
979  virtual void handleStartNode( const Tag* start ) = 0;
980 
987  virtual bool handleNormalNode( Tag* tag ) = 0;
988  virtual void rosterFilled() = 0;
989  virtual void cleanup() {}
990  virtual void handleIqIDForward( const IQ& iq, int context ) { (void) iq; (void) context; }
991  void send( Tag* tag, bool queue, bool del );
992  std::string hmac( const std::string& str, const std::string& key );
993  std::string hi( const std::string& str, const std::string& key, int iter );
994 
995  void parse( const std::string& data );
996  void init();
997  void handleStreamError( Tag* tag );
998  TLSBase* getDefaultEncryption();
999  CompressionBase* getDefaultCompression();
1000 
1001  void notifyIqHandlers( IQ& iq );
1002  void notifyMessageHandlers( Message& msg );
1003  void notifyPresenceHandlers( Presence& presence );
1004  void notifySubscriptionHandlers( Subscription& s10n );
1005  void notifyTagHandlers( Tag* tag );
1006  void notifyOnDisconnect( ConnectionError e );
1007  void addFrom( Tag* tag );
1008  void addNamespace( Tag* tag );
1009 
1010  // reimplemented from IqHandler
1011  virtual bool handleIq( const IQ& iq );
1012 
1013  // reimplemented from IqHandler
1014  virtual void handleIqID( const IQ& iq, int context );
1015 
1016  struct TrackStruct
1017  {
1018  IqHandler* ih;
1019  int context;
1020  bool del;
1021  };
1022 
1023  struct TagHandlerStruct
1024  {
1025  TagHandler* th;
1026  std::string xmlns;
1027  std::string tag;
1028  };
1029 
1030  struct JidPresHandlerStruct
1031  {
1032  JID* jid;
1033  PresenceHandler* ph;
1034  };
1035 
1036  enum TrackContext
1037  {
1038  XMPPPing
1039  };
1040 
1041  typedef std::list<ConnectionListener*> ConnectionListenerList;
1042  typedef std::multimap<const std::string, IqHandler*> IqHandlerMapXmlns;
1043  typedef std::multimap<const int, IqHandler*> IqHandlerMap;
1044  typedef std::map<const std::string, TrackStruct> IqTrackMap;
1045  typedef std::map<const std::string, MessageHandler*> MessageHandlerMap;
1046  typedef std::map<int, Tag*> SMQueueMap;
1047  typedef std::list<MessageSession*> MessageSessionList;
1048  typedef std::list<MessageHandler*> MessageHandlerList;
1049  typedef std::list<PresenceHandler*> PresenceHandlerList;
1050  typedef std::list<JidPresHandlerStruct> PresenceJidHandlerList;
1051  typedef std::list<SubscriptionHandler*> SubscriptionHandlerList;
1052  typedef std::list<TagHandlerStruct> TagHandlerList;
1053 
1054  ConnectionListenerList m_connectionListeners;
1055  IqHandlerMapXmlns m_iqNSHandlers;
1056  IqHandlerMap m_iqExtHandlers;
1057  IqTrackMap m_iqIDHandlers;
1058  SMQueueMap m_smQueue;
1059  MessageSessionList m_messageSessions;
1060  MessageHandlerList m_messageHandlers;
1061  PresenceHandlerList m_presenceHandlers;
1062  PresenceJidHandlerList m_presenceJidHandlers;
1063  SubscriptionHandlerList m_subscriptionHandlers;
1064  TagHandlerList m_tagHandlers;
1065  StringList m_cacerts;
1066  StatisticsHandler * m_statisticsHandler;
1067  MUCInvitationHandler * m_mucInvitationHandler;
1068  MessageSessionHandler * m_messageSessionHandlerChat;
1069  MessageSessionHandler * m_messageSessionHandlerGroupchat;
1070  MessageSessionHandler * m_messageSessionHandlerHeadline;
1071  MessageSessionHandler * m_messageSessionHandlerNormal;
1072 
1073  util::Mutex m_iqHandlerMapMutex;
1074  util::Mutex m_iqExtHandlerMapMutex;
1075  util::Mutex m_queueMutex;
1076 
1077  Parser m_parser;
1078  LogSink m_logInstance;
1079  StanzaExtensionFactory* m_seFactory;
1080  EventDispatcher m_dispatcher;
1081 
1082  AuthenticationError m_authError;
1083  StreamError m_streamError;
1084  StringMap m_streamErrorText;
1085  std::string m_streamErrorCData;
1086  Tag* m_streamErrorAppCondition;
1087 
1088  StatisticsStruct m_stats;
1089 
1090  SaslMechanism m_selectedSaslMech;
1091 
1092  std::string m_clientFirstMessageBare;
1093  std::string m_serverSignature;
1094  std::string m_gs2Header;
1095  std::string m_ntlmDomain;
1096  bool m_customConnection;
1097 
1098  int m_uniqueBaseId;
1099  util::AtomicRefCount m_nextId;
1100 
1101  int m_smSent;
1102 
1103 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
1104  CredHandle m_credHandle;
1105  CtxtHandle m_ctxtHandle;
1106 #endif
1107 
1108  };
1109 
1110 }
1111 
1112 #endif // CLIENTBASE_H__