File indexing completed on 2024-12-08 03:47:59
0001 0002 /*************************************************************************** 0003 jabberclient.h - Generic Jabber Client Class 0004 ------------------- 0005 begin : Sat May 25 2005 0006 copyright : (C) 2005 by Till Gerken <till@tantalo.net> 0007 (C) 2006 by Michaƫl Larouche <larouche@kde.org> 0008 0009 Copyright 2006 by Tommi Rantala <tommi.rantala@cs.helsinki.fi> 0010 0011 Kopete (C) 2001-2006 Kopete developers 0012 <kopete-devel@kde.org>. 0013 ***************************************************************************/ 0014 0015 /*************************************************************************** 0016 * * 0017 * This program is free software; you can redistribute it and/or modify * 0018 * it under the terms of the GNU General Public License as published by * 0019 * the Free Software Foundation; either either version 2 0020 of the License, or (at your option) any later version.of the License, or * 0021 * (at your option) any later version. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #ifndef JABBERCLIENT_H 0026 #define JABBERCLIENT_H 0027 0028 0029 #include <QObject> 0030 0031 // include these because of namespace reasons 0032 #include <im.h> 0033 #include <xmpp.h> 0034 #include <xmpp_discoitem.h> 0035 #include <s5b.h> 0036 0037 #include <QtCrypto> 0038 0039 class JabberConnector; 0040 namespace XMPP { class PrivacyManager; } 0041 0042 using namespace XMPP; 0043 /** 0044 * This class provides an interface to the Iris subsystem. The goal is to 0045 * abstract the Iris layer and manage it via a single, simple to use class. 0046 * By default, @ref JabberClient will attempt to establish a connection 0047 * using XMPP 1.0. This means that apart from the JID and password, no 0048 * further details are necessary to connect. The server and port will be 0049 * determined using a SRV lookup. If TLS is possible (meaning, the TLS 0050 * plugin is available and the server supports TLS) it will automatically 0051 * be used. Otherwise, a non-encrypted connection will be established. 0052 * If XMPP 1.0 is not possible, the connection will fall back to the old 0053 * protocol. By default, this connection is not encrypted. You can, however, 0054 * use @ref setUseSSL to immediately attempt an SSL connection. This is 0055 * most useful if you want to establish an SSL connection to a non-standard 0056 * port, in which case you will also have to use @ref setOverrideHost. In case 0057 * XMPP 1.0 does not work, an automatic attempt to connect to the standard port 0058 * 5223 with SSL can be made with @ref setProbeSSL. If the attempt is not 0059 * sucessful, the connection will fall back to an unencrypted attempt 0060 * at port 5222. 0061 * @brief Provides a Jabber client 0062 * @author Till Gerken 0063 */ 0064 class JabberClient : public QObject 0065 { 0066 0067 Q_OBJECT 0068 0069 public: 0070 /** 0071 * Error codes indicating problems during operation. 0072 */ 0073 enum ErrorCode 0074 { 0075 Ok, /** No error. */ 0076 InvalidPassword, /** Password used to connect to the server was incorrect. */ 0077 AlreadyConnected, /** A new connection was attempted while the previous one hasn't been closed. */ 0078 NoTLS, /** Use of TLS has been forced (see @ref forceTLS) but TLS is not available, either server- or client-side. */ 0079 InvalidPasswordForMUC = 401, /** A password is require to enter on this Multi-User Chat */ 0080 NicknameConflict = 409, /** There is already someone with that nick connected to the Multi-User Chat */ 0081 BannedFromThisMUC = 403, /** You can't join this Multi-User Chat because you were bannished */ 0082 MaxUsersReachedForThisMuc = 503 /** You can't join this Multi-User Chat because it is full */ 0083 }; 0084 0085 JabberClient(); 0086 ~JabberClient() override; 0087 0088 /** 0089 * Connect to a Jabber server. 0090 * @param jid JID to connect to. 0091 * @param password Password to authenticate with. 0092 * @param auth True if authentication should be done, false if not. 0093 */ 0094 ErrorCode connect ( const Jid &jid, const QString &password, bool auth = true ); 0095 0096 /** 0097 * Disconnect from Jabber server. 0098 */ 0099 void disconnect (); 0100 0101 /** 0102 * Disconnect from Jabber server with reason 0103 * @param reason The reason for disconnecting 0104 */ 0105 void disconnect (Status &reason); 0106 0107 /** 0108 * Returns if this instance is connected to a server. 0109 */ 0110 bool isConnected () const; 0111 0112 /** 0113 * Returns the JID associated with this instance. 0114 */ 0115 Jid jid () const; 0116 0117 /** 0118 * Set flag to ignore TLS warnings. If TLS 0119 * warnings are not ignored, the class will emit 0120 * @ref tlsWarning and wait for the user to 0121 * call @ref continueAfterTLSWarning or 0122 * @ref disconnect. Default is false. 0123 */ 0124 void setIgnoreTLSWarnings ( bool flag ); 0125 /** 0126 * Return if TLS warnings are being ignored. 0127 */ 0128 bool ignoreTLSWarnings (); 0129 0130 /** 0131 * Continue after a @ref tlsWarning signal. 0132 */ 0133 void continueAfterTLSWarning (); 0134 0135 /** 0136 * Set the port on which the S5B server should listen. 0137 * This is only taken into account if @ref setFileTransfersEnabled 0138 * is set to true. 0139 * @return True if port could be bound, false if not. 0140 */ 0141 bool setS5BServerPort ( int port ); 0142 /** 0143 * Returns the port the S5B server listens on. 0144 */ 0145 int s5bServerPort () const; 0146 0147 /** 0148 * Force the use of TLS. If TLS connections are forced, 0149 * unencrypted connections will not be established. 0150 * Default is false. 0151 */ 0152 void setForceTLS ( bool flag ); 0153 /** 0154 * Returns if TLS connections are forced. 0155 */ 0156 bool forceTLS () const; 0157 0158 /** 0159 * Force direct SSL connection, also for the 0160 * handshake. This is only useful if you know 0161 * the server supports it or you want to use 0162 * a non-standard port, in which case @ref setOverrideHost 0163 * will be useful. Default is false. 0164 */ 0165 void setUseSSL ( bool flag ); 0166 /** 0167 * Returns if an SSL connection attempt should be made. 0168 */ 0169 bool useSSL () const; 0170 0171 /** 0172 * Use only the old protocol (pre-XMPP 1.0). This should only 0173 * be used with servers not supporting XMPP 1.0 or with servers 0174 * that have a broken login procedure. Default is false. If 0175 * a connection attempt is not possible, Iris will automatically 0176 * fall back to the old protocol. 0177 */ 0178 void setUseXMPP09 ( bool flag ); 0179 /** 0180 * Returns if the old protocol should be used. 0181 */ 0182 bool useXMPP09 () const; 0183 0184 /** 0185 * Probe port 5223 if an SSL connection is possible. If 0186 * a connection is not possible, an unencrypted connection 0187 * will be attempted at port 5222. This is only meaningful 0188 * if @ref useXMPP09 is true. Default is false. 0189 */ 0190 void setProbeSSL ( bool flag ); 0191 /** 0192 * Returns if SSL support will be probed. 0193 */ 0194 bool probeSSL () const; 0195 0196 /** 0197 * Override the name and port of the server to connect to. 0198 * This only has an effect if the old protocol (@ref useXMPP09) 0199 * has been enabled. Default is false. 0200 */ 0201 void setOverrideHost ( bool flag, const QString &server = "", int port = 5222 ); 0202 /** 0203 * Returns if the server name and port are overridden. 0204 */ 0205 bool overrideHost () const; 0206 0207 /** 0208 * Allow the transmission of a plain text password. If digested 0209 * passwords are supported by the server, they will still be preferred. 0210 * Defaults to true. 0211 */ 0212 void setAllowPlainTextPassword ( bool flag ); 0213 /** 0214 * Returns if plain text passwords are allowed. 0215 */ 0216 bool allowPlainTextPassword () const; 0217 0218 /** 0219 * Enable file transfers. Default is false. 0220 * @param flag Whether to enable file transfers. 0221 * @param localAddress Local address to receive file transfers at. Will be determined automatically if not specified. 0222 */ 0223 void setFileTransfersEnabled ( bool flag, const QString &localAddress = QString() ); 0224 0225 /** 0226 * Returns the address of the local interface. 0227 */ 0228 QString localAddress () const; 0229 0230 /** 0231 * Returns if file transfers are enabled. 0232 */ 0233 bool fileTransfersEnabled () const; 0234 0235 /** 0236 * Set client name. 0237 */ 0238 void setClientName ( const QString &clientName ); 0239 /** 0240 * Return client name. 0241 */ 0242 QString clientName () const; 0243 0244 /** 0245 * Set client version. 0246 */ 0247 void setClientVersion ( const QString &clientVersion ); 0248 /** 0249 * Return client version. 0250 */ 0251 QString clientVersion () const; 0252 0253 /** 0254 * Set operating system name. 0255 */ 0256 void setOSName ( const QString &osName ); 0257 /** 0258 * Return operating system name. 0259 */ 0260 QString osName () const; 0261 0262 /** 0263 * Set the caps(JEP-0115: Entity capabilities) node name. 0264 * @param node Node name. 0265 */ 0266 void setCapsNode( const QString &capsNode ); 0267 /** 0268 * Return the caps node name for this client. 0269 * @return the caps node name. 0270 */ 0271 QString capsNode() const; 0272 0273 /** 0274 * Set the caps(JEP-0115: Entity capabilities) node version. 0275 * @param capsVersion the node version. 0276 */ 0277 void setCapsVersion( const QString &capsVersion ); 0278 /** 0279 * Return the caps version for this client. 0280 * @return the caps version. 0281 */ 0282 QString capsVersion() const; 0283 0284 /** 0285 * Return the caps extension list for this client. 0286 * @return A string containing all extensions separated by space. 0287 */ 0288 QString capsExt() const; 0289 0290 /** 0291 * Set the disco Identity information for this client. 0292 * Create a Disco identity like this: 0293 * @code 0294 * DiscoItem::Identity identity; 0295 * identity.category = "client"; 0296 * identity.type = "pc"; 0297 * identity.name = "Kopete"; 0298 * @endcode 0299 * 0300 * @param identity DiscoItem::Identity for the client. 0301 */ 0302 void setDiscoIdentity(DiscoItem::Identity identity); 0303 /** 0304 * Get the disco Identity information for this client. 0305 * @return the DiscoItem::Identity for this client. 0306 */ 0307 DiscoItem::Identity discoIdentity() const; 0308 0309 /** 0310 * Set timezone information. Default is UTC. 0311 */ 0312 void setTimeZone ( const QString &timeZoneName, int timeZoneOffset ); 0313 /** 0314 * Return timezone name. 0315 */ 0316 QString timeZoneName () const; 0317 /** 0318 * Return timezone offset. 0319 */ 0320 int timeZoneOffset () const; 0321 0322 /** 0323 * This method can be used to implement a penalty 0324 * system when a lot of queries need to be sent to the 0325 * server. Using the time returned by this method, 0326 * the caller can determine a delay until the next 0327 * operation in the queue can be carried out. 0328 * @brief Return current penalty time in seconds. 0329 */ 0330 int getPenaltyTime (); 0331 0332 /** 0333 * Return the XMPP client instance. 0334 */ 0335 Client *client () const; 0336 0337 /** 0338 * Return client stream instance. 0339 */ 0340 ClientStream *clientStream () const; 0341 0342 /** 0343 * Return client connector instance. 0344 */ 0345 JabberConnector *clientConnector () const; 0346 0347 /** 0348 * Get the root task for this connection. 0349 * You need this instance for every task 0350 * you want to start. 0351 */ 0352 Task *rootTask () const; 0353 0354 /** 0355 * Returns the file transfer manager 0356 * instance that deals with current file 0357 * transfers. 0358 */ 0359 FileTransferManager *fileTransferManager () const; 0360 0361 /** 0362 * Returns the privacy lists manager 0363 */ 0364 PrivacyManager *privacyManager () const; 0365 0366 /** 0367 * Join a groupchat. 0368 * @param host Node to join the room at. 0369 * @param room Name of room to join. 0370 * @param nick Nick name you want to join with. 0371 */ 0372 void joinGroupChat ( const QString &host, const QString &room, const QString &nick ); 0373 0374 /** 0375 * Join a groupchat that require a password. 0376 * @param host Node to join the room at. 0377 * @param room Name of room to join. 0378 * @param nick Nick name you want to join with. 0379 * @param password The password to join the room. 0380 */ 0381 void joinGroupChat ( const QString &host, const QString &room, const QString &nick, const QString &password ); 0382 0383 /** 0384 * Leave a groupchat. 0385 * @param host Node to leave room at. 0386 * @param room Name of room to leave. 0387 */ 0388 void leaveGroupChat ( const QString &host, const QString &room ); 0389 0390 /** 0391 * change the status of a groupchat 0392 */ 0393 void setGroupChatStatus(const QString &host, const QString &room, const Status &); 0394 /** 0395 * change the nick in a groupchat 0396 */ 0397 void changeGroupChatNick(const QString &host, const QString &room, const QString &nick, const Status &status =Status()); 0398 0399 /** 0400 * Send a message. 0401 */ 0402 void sendMessage ( const Message &message ); 0403 0404 /** 0405 * Send raw packet to the server. 0406 */ 0407 void send ( const QString &packet ); 0408 0409 /** 0410 * Request the roster from the Jabber server. 0411 */ 0412 void requestRoster (); 0413 0414 signals: 0415 /** 0416 * Connected successfully. 0417 */ 0418 void connected (); 0419 0420 /** 0421 * Client stream authenticated. This 0422 * signal is emitted when the socket 0423 * connection has been successfully 0424 * established, before sending the login 0425 * packet. 0426 */ 0427 void csAuthenticated (); 0428 0429 /** 0430 * Client stream error. 0431 */ 0432 void csError ( int error ); 0433 0434 /** 0435 * Client stream was disconnected. 0436 */ 0437 void csDisconnected (); 0438 0439 /** 0440 * TLS problem encountered. 0441 */ 0442 void tlsWarning ( QCA::TLS::IdentityResult, QCA::Validity ); 0443 0444 /** 0445 * A new file transfer needs to be handled. 0446 * The file transfer can be dealt with by 0447 * querying the file transfer manager from 0448 * @ref client. 0449 */ 0450 void incomingFileTransfer (); 0451 0452 /** 0453 * Fatal error has been encountered, 0454 * further operations are not possible. 0455 */ 0456 void error ( JabberClient::ErrorCode code ); 0457 0458 /** 0459 * Roster has been transmitted and processed. 0460 */ 0461 void rosterRequestFinished ( bool success ); 0462 0463 /** 0464 * A new contact appeared on the roster. 0465 */ 0466 void newContact ( const RosterItem &item ); 0467 0468 /** 0469 * A contact has been removed from the roster. 0470 */ 0471 void contactDeleted ( const RosterItem &item ); 0472 0473 /** 0474 * A roster item has changed. 0475 */ 0476 void contactUpdated ( const RosterItem &item ); 0477 0478 /** 0479 * New resource is available for a contact. 0480 */ 0481 void resourceAvailable ( const Jid &jid, const Resource &resource ); 0482 0483 /** 0484 * An existing resource has been removed. 0485 */ 0486 void resourceUnavailable ( const Jid &jid, const Resource &resource ); 0487 0488 /** 0489 * A new message has been received. 0490 */ 0491 void messageReceived ( const XMPP::Message &message ); 0492 0493 /** 0494 * Group chat has been joined. 0495 */ 0496 void groupChatJoined ( const XMPP::Jid &jid ); 0497 0498 /** 0499 * Group chat has been left. 0500 */ 0501 void groupChatLeft ( const XMPP::Jid &jid ); 0502 0503 /** 0504 * A presence to a groupchat has been signalled. 0505 */ 0506 void groupChatPresence ( const XMPP::Jid &jid, const XMPP::Status &status ); 0507 0508 /** 0509 * An error was encountered joining or processing a groupchat. 0510 */ 0511 void groupChatError ( const XMPP::Jid &jid, int error, const QString &reason ); 0512 0513 /** 0514 * New subscription request. 0515 */ 0516 void subscription ( const Jid &jid, const QString &type ); 0517 0518 /** 0519 * Dispatches a debug message. Debug messages 0520 * include incoming and outgoing XML packets 0521 * as well as internal status messages. 0522 */ 0523 void debugMessage ( const QString &message ); 0524 void incomingXML (const QString &msg); 0525 void outgoingXML (const QString &msg); 0526 0527 private: 0528 class Private; 0529 Private *d; 0530 0531 /** 0532 * Delete all member classes and reset the class to a predefined state. 0533 */ 0534 void cleanUp (); 0535 0536 /** 0537 * Return current instance of the S5B server. 0538 */ 0539 S5BServer *s5bServer (); 0540 /** 0541 * Add an address that the S5B server should handle. 0542 */ 0543 void addS5BServerAddress ( const QString &address ); 0544 /** 0545 * Remove an address that the S5B server currently handles. 0546 */ 0547 void removeS5BServerAddress ( const QString &address ); 0548 0549 private slots: 0550 /* S5B server object has been destroyed. */ 0551 void slotS5BServerGone (); 0552 0553 /* update the penalty timer */ 0554 void slotUpdatePenaltyTime (); 0555 0556 /* Login if the connection was OK. */ 0557 void slotCSNeedAuthParams (bool user, bool pass, bool realm); 0558 0559 /* Called from Psi: tells us when we're logged in OK. */ 0560 void slotCSAuthenticated (); 0561 0562 /* Called from Psi: tells us when we've been disconnected from the server. */ 0563 void slotCSDisconnected (); 0564 0565 /* Called from Psi: alerts us to a protocol warning. */ 0566 void slotCSWarning (int); 0567 0568 /* Called from Psi: alerts us to a protocol error. */ 0569 void slotCSError (int); 0570 0571 /* Called from Psi: report certificate status */ 0572 void slotTLSHandshaken (); 0573 0574 /* Called from Psi: roster request finished */ 0575 void slotRosterRequestFinished ( bool success, int statusCode, const QString &statusString ); 0576 0577 /* Called from Psi: incoming file transfer */ 0578 void slotIncomingFileTransfer (); 0579 0580 /* A new item appeared in our roster */ 0581 void slotNewContact (const RosterItem &); 0582 0583 /* An item has been deleted from our roster. */ 0584 void slotContactDeleted (const RosterItem &); 0585 0586 /* Update a contact's details. */ 0587 void slotContactUpdated (const RosterItem &); 0588 0589 /* Someone on our contact list had (another) resource come online. */ 0590 void slotResourceAvailable (const Jid &, const Resource &); 0591 0592 /* Someone on our contact list had a resource go offline. */ 0593 void slotResourceUnavailable (const Jid &, const Resource &); 0594 0595 /* Incoming message. */ 0596 void slotReceivedMessage (const Message &); 0597 0598 /* Called from Psi: debug messages from the backend. */ 0599 void slotPsiDebug (const QString & msg); 0600 void slotIncomingXML (const QString &msg); 0601 void slotOutgoingXML (const QString &msg); 0602 0603 /* Slots for handling groupchats. */ 0604 void slotGroupChatJoined (const Jid & jid); 0605 void slotGroupChatLeft (const Jid & jid); 0606 void slotGroupChatPresence (const Jid & jid, const Status & status); 0607 void slotGroupChatError (const Jid & jid, int error, const QString & reason); 0608 0609 /* Incoming subscription request. */ 0610 void slotSubscription (const Jid& jid, const QString& type); 0611 0612 }; 0613 0614 #endif