summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/jabber/jabberclient.h
blob: 7cd33e02c6c7762e2d1d74922cfd1a6ebd767670 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

/***************************************************************************
                jabberclient.h - Generic Jabber Client Class
                             -------------------
    begin                : Sat May 25 2005
    copyright            : (C) 2005 by Till Gerken <till@tantalo.net>
                           (C) 2006 by Michaƫl Larouche <michael.larouche@kdemail.net>

			   Kopete (C) 2001-2006 Kopete developers
			   <kopete-devel@kde.org>.
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef JABBERCLIENT_H
#define JABBERCLIENT_H

#include <qobject.h>

// include these because of namespace reasons
#include <im.h>
#include <xmpp.h>
#include <s5b.h>

using namespace XMPP;

class JabberConnector;

/**
 * This class provides an interface to the Iris subsystem. The goal is to
 * abstract the Iris layer and manage it via a single, simple to use class.
 * By default, @ref JabberClient will attempt to establish a connection
 * using XMPP 1.0. This means that apart from the JID and password, no
 * further details are necessary to connect. The server and port will be
 * determined using a SRV lookup. If TLS is possible (meaning, the TLS
 * plugin is available and the server supports TLS) it will automatically
 * be used. Otherwise, a non-encrypted connection will be established.
 * If XMPP 1.0 is not possible, the connection will fall back to the old
 * protocol. By default, this connection is not encrypted. You can, however,
 * use @ref setUseSSL to immediately attempt an SSL connection. This is
 * most useful if you want to establish an SSL connection to a non-standard
 * port, in which case you will also have to use @ref setOverrideHost. In case
 * XMPP 1.0 does not work, an automatic attempt to connect to the standard port
 * 5223 with SSL can be made with @ref setProbeSSL. If the attempt is not
 * sucessful, the connection will fall back to an unencrypted attempt
 * at port 5222.
 * @brief Provides a Jabber client
 * @author Till Gerken
 */
class JabberClient : public QObject
{

Q_OBJECT

public:
	/**
	 * Error codes indicating problems during operation.
	 */
	enum ErrorCode
	{
		Ok,					/** No error. */
		InvalidPassword,	/** Password used to connect to the server was incorrect. */
		AlreadyConnected,	/** A new connection was attempted while the previous one hasn't been closed. */
		NoTLS,				/** Use of TLS has been forced (see @ref forceTLS) but TLS is not available, either server- or client-side. */
		InvalidPasswordForMUC = 401,	/** A password is require to enter on this Multi-User Chat */
		NicknameConflict = 409,		/** There is already someone with that nick connected to the Multi-User Chat */
		BannedFromThisMUC = 403,	/** You can't join this Multi-User Chat because you were bannished */
		MaxUsersReachedForThisMuc = 503	/** You can't join this Multi-User Chat because it is full */
	};

	JabberClient();
	~JabberClient();

	/**
	 * Connect to a Jabber server.
	 * @param jid JID to connect to.
	 * @param password Password to authenticate with.
	 * @param auth True if authentication should be done, false if not.
	 */
	ErrorCode connect ( const XMPP::Jid &jid, const QString &password, bool auth = true );

	/**
	 * Disconnect from Jabber server.
	 */
	void disconnect ();
	
	/**
	 * Disconnect from Jabber server with reason
	 * @param reason The reason for disconnecting
	 */
	void disconnect (XMPP::Status &reason);

	/**
	 * Returns if this instance is connected to a server.
	 */
	bool isConnected () const;

	/**
	 * Returns the JID associated with this instance.
	 */
	XMPP::Jid jid () const;

	/**
	 * Set flag to ignore TLS warnings. If TLS
	 * warnings are not ignored, the class will emit
	 * @ref tlsWarning and wait for the user to
	 * call @ref continueAfterTLSWarning or
	 * @ref disconnect. Default is false.
	 */
	void setIgnoreTLSWarnings ( bool flag );
	/**
	 * Return if TLS warnings are being ignored.
	 */
	bool ignoreTLSWarnings ();

	/**
	 * Continue after a @ref tlsWarning signal.
	 */
	void continueAfterTLSWarning ();

	/**
	 * Set the port on which the S5B server should listen.
	 * This is only taken into account if @ref setFileTransfersEnabled
	 * is set to true.
	 * @return True if port could be bound, false if not.
	 */
	bool setS5BServerPort ( int port );
	/**
	 * Returns the port the S5B server listens on.
	 */
	int s5bServerPort () const;

	/**
	 * Force the use of TLS. If TLS connections are forced,
	 * unencrypted connections will not be established.
	 * Default is false.
	 */
	void setForceTLS ( bool flag );
	/**
	 * Returns if TLS connections are forced.
	 */
	bool forceTLS () const;
	
	/**
	 * Force direct SSL connection, also for the
	 * handshake. This is only useful if you know
	 * the server supports it or you want to use
	 * a non-standard port, in which case @ref setOverrideHost
	 * will be useful. Default is false.
	 */
	void setUseSSL ( bool flag );
	/**
	 * Returns if an SSL connection attempt should be made.
	 */
	bool useSSL () const;

	/**
	 * Use only the old protocol (pre-XMPP 1.0). This should only
	 * be used with servers not supporting XMPP 1.0 or with servers
	 * that have a broken login procedure. Default is false. If
	 * a connection attempt is not possible, Iris will automatically
	 * fall back to the old protocol.
	 */
	void setUseXMPP09 ( bool flag );
	/**
	 * Returns if the old protocol should be used.
	 */
	bool useXMPP09 () const;

	/**
	 * Probe port 5223 if an SSL connection is possible. If
	 * a connection is not possible, an unencrypted connection
	 * will be attempted at port 5222. This is only meaningful
	 * if @ref useXMPP09 is true. Default is false.
	 */
	void setProbeSSL ( bool flag );
	/**
	 * Returns if SSL support will be probed.
	 */
	bool probeSSL () const;

	/**
	 * Override the name and port of the server to connect to.
	 * This only has an effect if the old protocol (@ref useXMPP09)
	 * has been enabled. Default is false.
	 */
	void setOverrideHost ( bool flag, const QString &server = "", int port = 5222 );
	/**
	 * Returns if the server name and port are overridden.
	 */
	bool overrideHost () const;

	/**
	 * Allow the transmission of a plain text password. If digested
	 * passwords are supported by the server, they will still be preferred.
	 * Defaults to true.
	 */
	void setAllowPlainTextPassword ( bool flag );
	/**
	 * Returns if plain text passwords are allowed.
	 */
	bool allowPlainTextPassword () const;

	/**
	 * Enable file transfers. Default is false.
	 * @param flag Whether to enable file transfers.
	 * @param localAddress Local address to receive file transfers at. Will be determined automatically if not specified.
	 */
	void setFileTransfersEnabled ( bool flag, const QString &localAddress = QString::null );

	/**
	 * Returns the address of the local interface.
	 */
	QString localAddress () const;

	/**
	 * Returns if file transfers are enabled.
	 */
	bool fileTransfersEnabled () const;

	/**
	 * Set client name.
	 */
	void setClientName ( const QString &clientName );
	/**
	 * Return client name.
	 */
	QString clientName () const;

	/**
	 * Set client version.
	 */
	void setClientVersion ( const QString &clientVersion );
	/**
	 * Return client version.
	 */
	QString clientVersion () const;

	/**
	 * Set operating system name.
	 */
	void setOSName ( const QString &osName );
	/**
	 * Return operating system name.
	 */
	QString osName () const;

	/**
	 * Set the caps(JEP-0115: Entity capabilities) node name.
	 * @param node Node name.
	 */
	void setCapsNode( const QString &capsNode );
	/**
	 * Return the caps node name for this client.
	 * @return the caps node name.
	 */
	QString capsNode() const;
	
	/**
	 * Set the caps(JEP-0115: Entity capabilities) node version.
	 * @param capsVersion the node version.
	 */
	void setCapsVersion( const QString &capsVersion );
	/**
	 * Return the caps version for this client.
	 * @return the caps version.
	 */
	QString capsVersion() const;

	/**
	 * Return the caps extension list for this client.
	 * @return A string containing all extensions separated by space.
	 */
	QString capsExt() const;

	/**
	 * Set the disco Identity information for this client.
	 * Create a Disco identity like this:
	 * @code
	 * DiscoItem::Identity identity;
	 * identity.category = "client";
	 * identity.type = "pc";
	 * identity.name = "Kopete";
	 * @endcode
	 *
	 * @param identity DiscoItem::Identity for the client.
	 */
	void setDiscoIdentity(DiscoItem::Identity identity);
	/**
	 * Get the disco Identity information for this client.
	 * @return the DiscoItem::Identity for this client.
	 */
	DiscoItem::Identity discoIdentity() const;

	/**
	 * Set timezone information. Default is UTC.
	 */
	void setTimeZone ( const QString &timeZoneName, int timeZoneOffset );
	/**
	 * Return timezone name.
	 */
	QString timeZoneName () const;
	/**
	 * Return timezone offset.
	 */
	int timeZoneOffset () const;

	/**
	 * This method can be used to implement a penalty
	 * system when a lot of queries need to be sent to the
	 * server. Using the time returned by this method,
	 * the caller can determine a delay until the next
	 * operation in the queue can be carried out.
	 * @brief Return current penalty time in seconds.
	 */
	int getPenaltyTime ();

	/**
	 * Return the XMPP client instance.
	 */
	XMPP::Client *client () const;

	/**
	 * Return client stream instance.
	 */
	XMPP::ClientStream *clientStream () const;

	/**
	 * Return client connector instance.
	 */
	JabberConnector *clientConnector () const;

	/**
	 * Get the root task for this connection.
	 * You need this instance for every task
	 * you want to start.
	 */
	XMPP::Task *rootTask () const;

	/**
	 * Returns the file transfer manager
	 * instance that deals with current file
	 * transfers.
	 */
	XMPP::FileTransferManager *fileTransferManager () const;

	/**
	 * Join a group chat.
	 * @param host Node to join the room at.
	 * @param room Name of room to join.
	 * @param nick Nick name you want to join with.
	 */
	void joinGroupChat ( const QString &host, const QString &room, const QString &nick );

	/**
	 * Join a group chat that require a password.
	 * @param host Node to join the room at.
	 * @param room Name of room to join.
	 * @param nick Nick name you want to join with.
	 * @param password The password to join the room.
	 */
	void joinGroupChat ( const QString &host, const QString &room, const QString &nick, const QString &password );

	/**
	 * Leave a group chat.
	 * @param host Node to leave room at.
	 * @param room Name of room to leave.
	 */
	void leaveGroupChat ( const QString &host, const QString &room );
	
	/**
	 * change the status of a group chat
	 */
	void setGroupChatStatus(const QString &host, const QString &room, const XMPP::Status &);
	/**
	 * change the nick in a group chat
	 */
	void changeGroupChatNick(const QString &host, const QString &room, const QString &nick, const XMPP::Status &status =XMPP::Status());

	/**
	 * Send a message.
	 */
	void sendMessage ( const XMPP::Message &message );

	/**
	 * Send raw packet to the server.
	 */
	void send ( const QString &packet );

	/**
	 * Request the roster from the Jabber server.
	 */
	void requestRoster ();

signals:
	/**
	 * Connected successfully.
	 */
	void connected ();

	/**
	 * Client stream authenticated. This
	 * signal is emitted when the socket
	 * connection has been successfully
	 * established, before sending the login
	 * packet.
	 */
	void csAuthenticated ();

	/**
	 * Client stream error.
	 */
	void csError ( int error );

	/**
	 * Client stream was disconnected.
	 */
	void csDisconnected ();

	/**
	 * TLS problem encountered.
	 */
	void tlsWarning ( int validityResult );

	/**
	 * A new file transfer needs to be handled.
	 * The file transfer can be dealt with by
	 * querying the file transfer manager from
	 * @ref client.
	 */
	void incomingFileTransfer ();

	/**
	 * Fatal error has been encountered,
	 * further operations are not possible.
	 */
	void error ( JabberClient::ErrorCode code );

	/**
	 * Roster has been transmitted and processed.
	 */
	void rosterRequestFinished ( bool success );

	/**
	 * A new contact appeared on the roster.
	 */
	void newContact ( const XMPP::RosterItem &item );

	/**
	 * A contact has been removed from the roster.
	 */
	void contactDeleted ( const XMPP::RosterItem &item );

	/**
	 * A roster item has changed.
	 */
	void contactUpdated ( const XMPP::RosterItem &item );

	/**
	 * New resource is available for a contact.
	 */
	void resourceAvailable ( const XMPP::Jid &jid, const XMPP::Resource &resource );

	/**
	 * An existing resource has been removed.
	 */
	void resourceUnavailable ( const XMPP::Jid &jid, const XMPP::Resource &resource );

	/**
	 * A new message has been received.
	 */
	void messageReceived ( const XMPP::Message &message );

	/**
	 * Group chat has been joined.
	 */
	void groupChatJoined ( const XMPP::Jid &jid );

	/**
	 * Group chat has been left.
	 */
	void groupChatLeft ( const XMPP::Jid &jid );

	/**
	 * A presence to a group chat has been signalled.
	 */
	void groupChatPresence ( const XMPP::Jid &jid, const XMPP::Status &status );

	/**
	 * An error was encountered joining or processing a group chat.
	 */
	void groupChatError ( const XMPP::Jid &jid, int error, const QString &reason );

	/**
	 * New subscription request.
	 */
	void subscription ( const XMPP::Jid &jid, const QString &type );
	
	/**
	 * Dispatches a debug message. Debug messages
	 * include incoming and outgoing XML packets
	 * as well as internal status messages.
	 */
	void debugMessage ( const QString &message );

private:
	class Private;
	Private *d;

	/**
	 * Delete all member classes and reset the class to a predefined state.
	 */
	void cleanUp ();

	/** 
	 * Return current instance of the S5B server.
	 */
	XMPP::S5BServer *s5bServer ();
	/** 
	 * Add an address that the S5B server should handle.
	 */
	void addS5BServerAddress ( const QString &address );
	/** 
	 * Remove an address that the S5B server currently handles.
	 */
	void removeS5BServerAddress ( const QString &address );

private slots:
	/* S5B server object has been destroyed. */
	void slotS5BServerGone ();

	/* update the penalty timer */
	void slotUpdatePenaltyTime ();

	/* Login if the connection was OK. */
	void slotCSNeedAuthParams (bool user, bool pass, bool realm);

	/* Called from Psi: tells us when we're logged in OK. */
	void slotCSAuthenticated ();

	/* Called from Psi: tells us when we've been disconnected from the server. */
	void slotCSDisconnected ();

	/* Called from Psi: alerts us to a protocol warning. */
	void slotCSWarning (int);

	/* Called from Psi: alerts us to a protocol error. */
	void slotCSError (int);

	/* Called from Psi: report certificate status */
	void slotTLSHandshaken ();

	/* Called from Psi: roster request finished */
	void slotRosterRequestFinished ( bool success, int statusCode, const QString &statusString );

	/* Called from Psi: incoming file transfer */
	void slotIncomingFileTransfer ();

	/* A new item appeared in our roster */
	void slotNewContact (const RosterItem &);

	/* An item has been deleted from our roster. */
	void slotContactDeleted (const RosterItem &);

	/* Update a contact's details. */
	void slotContactUpdated (const RosterItem &);

	/* Someone on our contact list had (another) resource come online. */
	void slotResourceAvailable (const Jid &, const Resource &);

	/* Someone on our contact list had a resource go offline. */
	void slotResourceUnavailable (const Jid &, const Resource &);

	/* Incoming message. */
	void slotReceivedMessage (const Message &);
	
	/* Called from Psi: debug messages from the backend. */
	void slotPsiDebug (const QString & msg);
	void slotIncomingXML (const QString &msg);
	void slotOutgoingXML (const QString &msg);

	/* Slots for handling group chats. */
	void slotGroupChatJoined (const Jid & jid);
	void slotGroupChatLeft (const Jid & jid);
	void slotGroupChatPresence (const Jid & jid, const Status & status);
	void slotGroupChatError (const Jid & jid, int error, const QString & reason);

	/* Incoming subscription request. */
	void slotSubscription (const Jid & jid, const QString & type);

};

#endif