source: psi/trunk/iris/include/xmpp.h@ 170

Last change on this file since 170 was 2, checked in by dmik, 19 years ago

Imported original Psi 0.10 sources from Affinix

File size: 13.2 KB
Line 
1/*
2 * xmpp.h - XMPP "core" library API
3 * Copyright (C) 2003 Justin Karneges
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#ifndef XMPP_H
22#define XMPP_H
23
24#include<qobject.h>
25#include<qstring.h>
26#include<qhostaddress.h>
27#include<qstring.h>
28#include<qcstring.h>
29#include<qxml.h>
30#include<qdom.h>
31
32namespace QCA
33{
34 class TLS;
35};
36
37#ifndef CS_XMPP
38class ByteStream;
39#endif
40
41namespace XMPP
42{
43 // CS_IMPORT_BEGIN cutestuff/bytestream.h
44#ifdef CS_XMPP
45 class ByteStream;
46#endif
47 // CS_IMPORT_END
48
49 class Debug
50 {
51 public:
52 virtual ~Debug();
53
54 virtual void msg(const QString &)=0;
55 virtual void outgoingTag(const QString &)=0;
56 virtual void incomingTag(const QString &)=0;
57 virtual void outgoingXml(const QDomElement &)=0;
58 virtual void incomingXml(const QDomElement &)=0;
59 };
60
61 void setDebug(Debug *);
62
63 class Connector : public QObject
64 {
65 Q_OBJECT
66 public:
67 Connector(QObject *parent=0);
68 virtual ~Connector();
69
70 virtual void connectToServer(const QString &server)=0;
71 virtual ByteStream *stream() const=0;
72 virtual void done()=0;
73
74 bool useSSL() const;
75 bool havePeerAddress() const;
76 QHostAddress peerAddress() const;
77 Q_UINT16 peerPort() const;
78
79 signals:
80 void connected();
81 void error();
82
83 protected:
84 void setUseSSL(bool b);
85 void setPeerAddressNone();
86 void setPeerAddress(const QHostAddress &addr, Q_UINT16 port);
87
88 private:
89 bool ssl;
90 bool haveaddr;
91 QHostAddress addr;
92 Q_UINT16 port;
93 };
94
95 class AdvancedConnector : public Connector
96 {
97 Q_OBJECT
98 public:
99 enum Error { ErrConnectionRefused, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth, ErrStream };
100 AdvancedConnector(QObject *parent=0);
101 virtual ~AdvancedConnector();
102
103 class Proxy
104 {
105 public:
106 enum { None, HttpConnect, HttpPoll, Socks };
107 Proxy();
108 ~Proxy();
109
110 int type() const;
111 QString host() const;
112 Q_UINT16 port() const;
113 QString url() const;
114 QString user() const;
115 QString pass() const;
116 int pollInterval() const;
117
118 void setHttpConnect(const QString &host, Q_UINT16 port);
119 void setHttpPoll(const QString &host, Q_UINT16 port, const QString &url);
120 void setSocks(const QString &host, Q_UINT16 port);
121 void setUserPass(const QString &user, const QString &pass);
122 void setPollInterval(int secs);
123
124 private:
125 int t;
126 QString v_host, v_url;
127 Q_UINT16 v_port;
128 QString v_user, v_pass;
129 int v_poll;
130 };
131
132 void setProxy(const Proxy &proxy);
133 void setOptHostPort(const QString &host, Q_UINT16 port);
134 void setOptProbe(bool);
135 void setOptSSL(bool);
136
137 void changePollInterval(int secs);
138
139 void connectToServer(const QString &server);
140 ByteStream *stream() const;
141 void done();
142
143 int errorCode() const;
144
145 signals:
146 void srvLookup(const QString &server);
147 void srvResult(bool success);
148 void httpSyncStarted();
149 void httpSyncFinished();
150
151 private slots:
152 void dns_done();
153 void srv_done();
154 void bs_connected();
155 void bs_error(int);
156 void http_syncStarted();
157 void http_syncFinished();
158
159 private:
160 class Private;
161 Private *d;
162
163 void cleanup();
164 void do_resolve();
165 void do_connect();
166 void tryNextSrv();
167 };
168
169 class TLSHandler : public QObject
170 {
171 Q_OBJECT
172 public:
173 TLSHandler(QObject *parent=0);
174 virtual ~TLSHandler();
175
176 virtual void reset()=0;
177 virtual void startClient(const QString &host)=0;
178 virtual void write(const QByteArray &a)=0;
179 virtual void writeIncoming(const QByteArray &a)=0;
180
181 signals:
182 void success();
183 void fail();
184 void closed();
185 void readyRead(const QByteArray &a);
186 void readyReadOutgoing(const QByteArray &a, int plainBytes);
187 };
188
189 class QCATLSHandler : public TLSHandler
190 {
191 Q_OBJECT
192 public:
193 QCATLSHandler(QCA::TLS *parent);
194 ~QCATLSHandler();
195
196 QCA::TLS *tls() const;
197 int tlsError() const;
198
199 void reset();
200 void startClient(const QString &host);
201 void write(const QByteArray &a);
202 void writeIncoming(const QByteArray &a);
203
204 signals:
205 void tlsHandshaken();
206
207 public slots:
208 void continueAfterHandshake();
209
210 private slots:
211 void tls_handshaken();
212 void tls_readyRead();
213 void tls_readyReadOutgoing(int);
214 void tls_closed();
215 void tls_error(int);
216
217 private:
218 class Private;
219 Private *d;
220 };
221
222 class Jid
223 {
224 public:
225 Jid();
226 ~Jid();
227
228 Jid(const QString &s);
229 Jid(const char *s);
230 Jid & operator=(const QString &s);
231 Jid & operator=(const char *s);
232
233 void set(const QString &s);
234 void set(const QString &domain, const QString &node, const QString &resource="");
235
236 void setDomain(const QString &s);
237 void setNode(const QString &s);
238 void setResource(const QString &s);
239
240 const QString & domain() const { return d; }
241 const QString & node() const { return n; }
242 const QString & resource() const { return r; }
243 const QString & bare() const { return b; }
244 const QString & full() const { return f; }
245
246 Jid withNode(const QString &s) const;
247 Jid withResource(const QString &s) const;
248
249 bool isValid() const;
250 bool isEmpty() const;
251 bool compare(const Jid &a, bool compareRes=true) const;
252
253 static bool validDomain(const QString &s, QString *norm=0);
254 static bool validNode(const QString &s, QString *norm=0);
255 static bool validResource(const QString &s, QString *norm=0);
256
257 // TODO: kill these later
258 const QString & host() const { return d; }
259 const QString & user() const { return n; }
260 const QString & userHost() const { return b; }
261
262 private:
263 void reset();
264 void update();
265
266 QString f, b, d, n, r;
267 bool valid;
268 };
269
270 class Stream;
271 class Stanza
272 {
273 public:
274 enum Kind { Message, Presence, IQ };
275 enum ErrorType { Cancel, Continue, Modify, Auth, Wait };
276 enum ErrorCond
277 {
278 BadRequest,
279 Conflict,
280 FeatureNotImplemented,
281 Forbidden,
282 InternalServerError,
283 ItemNotFound,
284 JidMalformed,
285 NotAllowed,
286 PaymentRequired,
287 RecipientUnavailable,
288 RegistrationRequired,
289 ServerNotFound,
290 ServerTimeout,
291 ResourceConstraint,
292 ServiceUnavailable,
293 SubscriptionRequired,
294 UndefinedCondition,
295 UnexpectedRequest
296 };
297
298 Stanza();
299 Stanza(const Stanza &from);
300 Stanza & operator=(const Stanza &from);
301 virtual ~Stanza();
302
303 class Error
304 {
305 public:
306 Error(int type=Cancel, int condition=UndefinedCondition, const QString &text="", const QDomElement &appSpec=QDomElement());
307
308 int type;
309 int condition;
310 QString text;
311 QDomElement appSpec;
312 };
313
314 bool isNull() const;
315
316 QDomElement element() const;
317 QString toString() const;
318
319 QDomDocument & doc() const;
320 QString baseNS() const;
321 QDomElement createElement(const QString &ns, const QString &tagName);
322 QDomElement createTextElement(const QString &ns, const QString &tagName, const QString &text);
323 void appendChild(const QDomElement &e);
324
325 Kind kind() const;
326 void setKind(Kind k);
327
328 Jid to() const;
329 Jid from() const;
330 QString id() const;
331 QString type() const;
332 QString lang() const;
333
334 void setTo(const Jid &j);
335 void setFrom(const Jid &j);
336 void setId(const QString &id);
337 void setType(const QString &type);
338 void setLang(const QString &lang);
339
340 Error error() const;
341 void setError(const Error &err);
342 void clearError();
343
344 private:
345 friend class Stream;
346 Stanza(Stream *s, Kind k, const Jid &to, const QString &type, const QString &id);
347 Stanza(Stream *s, const QDomElement &e);
348
349 class Private;
350 Private *d;
351 };
352
353 class Stream : public QObject
354 {
355 Q_OBJECT
356 public:
357 enum Error { ErrParse, ErrProtocol, ErrStream, ErrCustom = 10 };
358 enum StreamCond {
359 GenericStreamError,
360 Conflict,
361 ConnectionTimeout,
362 InternalServerError,
363 InvalidFrom,
364 InvalidXml,
365 PolicyViolation,
366 ResourceConstraint,
367 SystemShutdown
368 };
369
370 Stream(QObject *parent=0);
371 virtual ~Stream();
372
373 virtual QDomDocument & doc() const=0;
374 virtual QString baseNS() const=0;
375 virtual bool old() const=0;
376
377 virtual void close()=0;
378 virtual bool stanzaAvailable() const=0;
379 virtual Stanza read()=0;
380 virtual void write(const Stanza &s)=0;
381
382 virtual int errorCondition() const=0;
383 virtual QString errorText() const=0;
384 virtual QDomElement errorAppSpec() const=0;
385
386 Stanza createStanza(Stanza::Kind k, const Jid &to="", const QString &type="", const QString &id="");
387 Stanza createStanza(const QDomElement &e);
388
389 static QString xmlToString(const QDomElement &e, bool clip=false);
390
391 signals:
392 void connectionClosed();
393 void delayedCloseFinished();
394 void readyRead();
395 void stanzaWritten();
396 void error(int);
397 };
398
399 class ClientStream : public Stream
400 {
401 Q_OBJECT
402 public:
403 enum Error {
404 ErrConnection = ErrCustom, // Connection error, ask Connector-subclass what's up
405 ErrNeg, // Negotiation error, see condition
406 ErrTLS, // TLS error, see condition
407 ErrAuth, // Auth error, see condition
408 ErrSecurityLayer, // broken SASL security layer
409 ErrBind // Resource binding error
410 };
411 enum Warning {
412 WarnOldVersion, // server uses older XMPP/Jabber "0.9" protocol
413 WarnNoTLS // there is no chance for TLS at this point
414 };
415 enum NegCond {
416 HostGone, // host no longer hosted
417 HostUnknown, // unknown host
418 RemoteConnectionFailed, // unable to connect to a required remote resource
419 SeeOtherHost, // a 'redirect', see errorText() for other host
420 UnsupportedVersion // unsupported XMPP version
421 };
422 enum TLSCond {
423 TLSStart, // server rejected STARTTLS
424 TLSFail // TLS failed, ask TLSHandler-subclass what's up
425 };
426 enum SecurityLayer {
427 LayerTLS,
428 LayerSASL
429 };
430 enum AuthCond {
431 GenericAuthError, // all-purpose "can't login" error
432 NoMech, // No appropriate auth mech available
433 BadProto, // Bad SASL auth protocol
434 BadServ, // Server failed mutual auth
435 EncryptionRequired, // can't use mech without TLS
436 InvalidAuthzid, // bad input JID
437 InvalidMech, // bad mechanism
438 InvalidRealm, // bad realm
439 MechTooWeak, // can't use mech with this authzid
440 NotAuthorized, // bad user, bad password, bad creditials
441 TemporaryAuthFailure // please try again later!
442 };
443 enum BindCond {
444 BindNotAllowed, // not allowed to bind a resource
445 BindConflict // resource in-use
446 };
447
448 ClientStream(Connector *conn, TLSHandler *tlsHandler=0, QObject *parent=0);
449 ClientStream(const QString &host, const QString &defRealm, ByteStream *bs, QCA::TLS *tls=0, QObject *parent=0); // server
450 ~ClientStream();
451
452 Jid jid() const;
453 void connectToServer(const Jid &jid, bool auth=true);
454 void accept(); // server
455 bool isActive() const;
456 bool isAuthenticated() const;
457
458 // login params
459 void setUsername(const QString &s);
460 void setPassword(const QString &s);
461 void setRealm(const QString &s);
462 void continueAfterParams();
463
464 // SASL information
465 QString saslMechanism() const;
466 int saslSSF() const;
467
468 // binding
469 void setResourceBinding(bool);
470
471 // security options (old protocol only uses the first !)
472 void setAllowPlain(bool);
473 void setRequireMutualAuth(bool);
474 void setSSFRange(int low, int high);
475 void setOldOnly(bool);
476 void setSASLMechanism(const QString &s);
477 void setLocalAddr(const QHostAddress &addr, Q_UINT16 port);
478
479 // reimplemented
480 QDomDocument & doc() const;
481 QString baseNS() const;
482 bool old() const;
483
484 void close();
485 bool stanzaAvailable() const;
486 Stanza read();
487 void write(const Stanza &s);
488
489 int errorCondition() const;
490 QString errorText() const;
491 QDomElement errorAppSpec() const;
492
493 // extra
494 void writeDirect(const QString &s);
495 void setNoopTime(int mills);
496
497 signals:
498 void connected();
499 void securityLayerActivated(int);
500 void needAuthParams(bool user, bool pass, bool realm);
501 void authenticated();
502 void warning(int);
503 void incomingXml(const QString &s);
504 void outgoingXml(const QString &s);
505
506 public slots:
507 void continueAfterWarning();
508
509 private slots:
510 void cr_connected();
511 void cr_error();
512
513 void bs_connectionClosed();
514 void bs_delayedCloseFinished();
515 void bs_error(int); // server only
516
517 void ss_readyRead();
518 void ss_bytesWritten(int);
519 void ss_tlsHandshaken();
520 void ss_tlsClosed();
521 void ss_error(int);
522
523 void sasl_clientFirstStep(const QString &mech, const QByteArray *clientInit);
524 void sasl_nextStep(const QByteArray &stepData);
525 void sasl_needParams(bool user, bool authzid, bool pass, bool realm);
526 void sasl_authCheck(const QString &user, const QString &authzid);
527 void sasl_authenticated();
528 void sasl_error(int);
529
530 void doNoop();
531 void doReadyRead();
532
533 private:
534 class Private;
535 Private *d;
536
537 void reset(bool all=false);
538 void processNext();
539 int convertedSASLCond() const;
540 bool handleNeed();
541 void handleError();
542 void srvProcessNext();
543 };
544};
545
546#endif
Note: See TracBrowser for help on using the repository browser.