~ubuntu-branches/ubuntu/edgy/psi/edgy

« back to all changes in this revision

Viewing changes to iris/xmpp-core/protocol.h

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2004-06-15 00:10:41 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040615001041-enywb6pcpe4sjsw6
Tags: 0.9.2-1
* New upstream release
* Set KDEDIR for ./configure so kde specific files get installed
* Don't install libpsiwidgets.so. It got installed in /usr/share
  where it doesn't belong. May be included (at a better location)
  later.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * protocol.h - XMPP-Core protocol state machine
 
3
 * Copyright (C) 2004  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 PROTOCOL_H
 
22
#define PROTOCOL_H
 
23
 
 
24
#include<qpair.h>
 
25
#include"xmlprotocol.h"
 
26
#include"xmpp.h"
 
27
 
 
28
#define NS_ETHERX   "http://etherx.jabber.org/streams"
 
29
#define NS_CLIENT   "jabber:client"
 
30
#define NS_SERVER   "jabber:server"
 
31
#define NS_DIALBACK "jabber:server:dialback"
 
32
#define NS_STREAMS  "urn:ietf:params:xml:ns:xmpp-streams"
 
33
#define NS_TLS      "urn:ietf:params:xml:ns:xmpp-tls"
 
34
#define NS_SASL     "urn:ietf:params:xml:ns:xmpp-sasl"
 
35
#define NS_SESSION  "urn:ietf:params:xml:ns:xmpp-session"
 
36
#define NS_STANZAS  "urn:ietf:params:xml:ns:xmpp-stanzas"
 
37
#define NS_BIND     "urn:ietf:params:xml:ns:xmpp-bind"
 
38
 
 
39
namespace XMPP
 
40
{
 
41
        class Version
 
42
        {
 
43
        public:
 
44
                Version(int maj=0, int min=0);
 
45
 
 
46
                int major, minor;
 
47
        };
 
48
 
 
49
        class StreamFeatures
 
50
        {
 
51
        public:
 
52
                StreamFeatures();
 
53
 
 
54
                bool tls_supported, sasl_supported, bind_supported;
 
55
                bool tls_required;
 
56
                QStringList sasl_mechs;
 
57
        };
 
58
 
 
59
        class BasicProtocol : public XmlProtocol
 
60
        {
 
61
        public:
 
62
                // xmpp 1.0 error conditions
 
63
                enum SASLCond {
 
64
                        Aborted,
 
65
                        IncorrectEncoding,
 
66
                        InvalidAuthzid,
 
67
                        InvalidMech,
 
68
                        MechTooWeak,
 
69
                        NotAuthorized,
 
70
                        TemporaryAuthFailure
 
71
                };
 
72
                enum StreamCond {
 
73
                        BadFormat,
 
74
                        BadNamespacePrefix,
 
75
                        Conflict,
 
76
                        ConnectionTimeout,
 
77
                        HostGone,
 
78
                        HostUnknown,
 
79
                        ImproperAddressing,
 
80
                        InternalServerError,
 
81
                        InvalidFrom,
 
82
                        InvalidId,
 
83
                        InvalidNamespace,
 
84
                        InvalidXml,
 
85
                        StreamNotAuthorized,
 
86
                        PolicyViolation,
 
87
                        RemoteConnectionFailed,
 
88
                        ResourceConstraint,
 
89
                        RestrictedXml,
 
90
                        SeeOtherHost,
 
91
                        SystemShutdown,
 
92
                        UndefinedCondition,
 
93
                        UnsupportedEncoding,
 
94
                        UnsupportedStanzaType,
 
95
                        UnsupportedVersion,
 
96
                        XmlNotWellFormed
 
97
                };
 
98
                enum BindCond {
 
99
                        BindBadRequest,
 
100
                        BindNotAllowed,
 
101
                        BindConflict
 
102
                };
 
103
 
 
104
                // extend the XmlProtocol enums
 
105
                enum Need {
 
106
                        NSASLMechs = XmlProtocol::NCustom, // need SASL mechlist
 
107
                        NStartTLS,  // need to switch on TLS layer
 
108
                        NSASLFirst, // need SASL first step
 
109
                        NSASLNext,  // need SASL next step
 
110
                        NSASLLayer, // need to switch on SASL layer
 
111
                        NCustom = XmlProtocol::NCustom+10
 
112
                };
 
113
                enum Event {
 
114
                        EFeatures = XmlProtocol::ECustom, // breakpoint after features packet is received
 
115
                        ESASLSuccess, // breakpoint after successful sasl auth
 
116
                        EStanzaReady, // a stanza was received
 
117
                        EStanzaSent,  // a stanza was sent
 
118
                        EReady,       // stream is ready for stanza use
 
119
                        ECustom = XmlProtocol::ECustom+10
 
120
                };
 
121
                enum Error {
 
122
                        ErrProtocol = XmlProtocol::ErrCustom, // there was an error in the xmpp-core protocol exchange
 
123
                        ErrStream,   // <stream:error>, see errCond, errText, and errAppSpec for details
 
124
                        ErrStartTLS, // server refused starttls
 
125
                        ErrAuth,     // authorization error.  errCond holds sasl condition (or numeric code for old-protocol)
 
126
                        ErrBind,     // server refused resource bind
 
127
                        ErrCustom = XmlProtocol::ErrCustom+10
 
128
                };
 
129
 
 
130
                BasicProtocol();
 
131
                ~BasicProtocol();
 
132
 
 
133
                void reset();
 
134
 
 
135
                // for outgoing xml
 
136
                QDomDocument doc;
 
137
 
 
138
                // sasl-related
 
139
                QString saslMech() const;
 
140
                QByteArray saslStep() const;
 
141
                void setSASLMechList(const QStringList &list);
 
142
                void setSASLFirst(const QString &mech, const QByteArray &step);
 
143
                void setSASLNext(const QByteArray &step);
 
144
                void setSASLAuthed();
 
145
 
 
146
                // send / recv
 
147
                void sendStanza(const QDomElement &e);
 
148
                void sendDirect(const QString &s);
 
149
                void sendWhitespace();
 
150
                QDomElement recvStanza();
 
151
 
 
152
                // shutdown
 
153
                void shutdown();
 
154
                void shutdownWithError(int cond, const QString &otherHost="");
 
155
 
 
156
                // <stream> information
 
157
                QString to, from, id, lang;
 
158
                Version version;
 
159
 
 
160
                // error output
 
161
                int errCond;
 
162
                QString errText;
 
163
                QDomElement errAppSpec;
 
164
                QString otherHost;
 
165
 
 
166
                QByteArray spare; // filled with unprocessed data on NStartTLS and NSASLLayer
 
167
 
 
168
                bool isReady() const;
 
169
 
 
170
                enum { TypeElement, TypeStanza, TypeDirect, TypePing };
 
171
 
 
172
        protected:
 
173
                static int stringToSASLCond(const QString &s);
 
174
                static int stringToStreamCond(const QString &s);
 
175
                static QString saslCondToString(int);
 
176
                static QString streamCondToString(int);
 
177
 
 
178
                void send(const QDomElement &e, bool clip=false);
 
179
                void sendStreamError(int cond, const QString &text="", const QDomElement &appSpec=QDomElement());
 
180
                void sendStreamError(const QString &text); // old-style
 
181
 
 
182
                bool errorAndClose(int cond, const QString &text="", const QDomElement &appSpec=QDomElement());
 
183
                bool error(int code);
 
184
                void delayErrorAndClose(int cond, const QString &text="", const QDomElement &appSpec=QDomElement());
 
185
                void delayError(int code);
 
186
 
 
187
                // reimplemented
 
188
                QDomElement docElement();
 
189
                void handleDocOpen(const Parser::Event &pe);
 
190
                bool handleError();
 
191
                bool handleCloseFinished();
 
192
                bool doStep(const QDomElement &e);
 
193
                void itemWritten(int id, int size);
 
194
 
 
195
                virtual QString defaultNamespace();
 
196
                virtual QStringList extraNamespaces(); // stringlist: prefix,uri,prefix,uri, [...]
 
197
                virtual void handleStreamOpen(const Parser::Event &pe);
 
198
                virtual bool doStep2(const QDomElement &e)=0;
 
199
 
 
200
                void setReady(bool b);
 
201
 
 
202
                QString sasl_mech;
 
203
                QStringList sasl_mechlist;
 
204
                QByteArray sasl_step;
 
205
                bool sasl_authed;
 
206
 
 
207
                QDomElement stanzaToRecv;
 
208
 
 
209
        private:
 
210
                struct SASLCondEntry
 
211
                {
 
212
                        const char *str;
 
213
                        int cond;
 
214
                };
 
215
                static SASLCondEntry saslCondTable[];
 
216
 
 
217
                struct StreamCondEntry
 
218
                {
 
219
                        const char *str;
 
220
                        int cond;
 
221
                };
 
222
                static StreamCondEntry streamCondTable[];
 
223
 
 
224
                struct SendItem
 
225
                {
 
226
                        QDomElement stanzaToSend;
 
227
                        QString stringToSend;
 
228
                        bool doWhitespace;
 
229
                };
 
230
                QValueList<SendItem> sendList;
 
231
 
 
232
                bool doShutdown, delayedError, closeError, ready;
 
233
                int stanzasPending, stanzasWritten;
 
234
 
 
235
                void init();
 
236
                void extractStreamError(const QDomElement &e);
 
237
        };
 
238
 
 
239
        class CoreProtocol : public BasicProtocol
 
240
        {
 
241
        public:
 
242
                enum {
 
243
                        NPassword = NCustom,  // need password for old-mode
 
244
                        EDBVerify = ECustom,  // breakpoint after db:verify request
 
245
                        ErrPlain = ErrCustom  // server only supports plain, but allowPlain is false locally
 
246
                };
 
247
 
 
248
                CoreProtocol();
 
249
                ~CoreProtocol();
 
250
 
 
251
                void reset();
 
252
 
 
253
                void startClientOut(const Jid &jid, bool oldOnly, bool tlsActive, bool doAuth);
 
254
                void startServerOut(const QString &to);
 
255
                void startDialbackOut(const QString &to, const QString &from);
 
256
                void startDialbackVerifyOut(const QString &to, const QString &from, const QString &id, const QString &key);
 
257
                void startClientIn(const QString &id);
 
258
                void startServerIn(const QString &id);
 
259
 
 
260
                void setLang(const QString &s);
 
261
                void setAllowTLS(bool b);
 
262
                void setAllowBind(bool b);
 
263
                void setAllowPlain(bool b); // old-mode
 
264
 
 
265
                void setPassword(const QString &s);
 
266
                void setFrom(const QString &s);
 
267
                void setDialbackKey(const QString &s);
 
268
 
 
269
                // input
 
270
                QString user, host;
 
271
 
 
272
                // status
 
273
                bool old;
 
274
 
 
275
                StreamFeatures features;
 
276
 
 
277
                //static QString xmlToString(const QDomElement &e, bool clip=false);
 
278
 
 
279
                class DBItem
 
280
                {
 
281
                public:
 
282
                        enum { ResultRequest, ResultGrant, VerifyRequest, VerifyGrant, Validated };
 
283
                        int type;
 
284
                        Jid to, from;
 
285
                        QString key, id;
 
286
                        bool ok;
 
287
                };
 
288
 
 
289
        private:
 
290
                enum Step {
 
291
                        Start,
 
292
                        Done,
 
293
                        SendFeatures,
 
294
                        GetRequest,
 
295
                        HandleTLS,
 
296
                        GetSASLResponse,
 
297
                        IncHandleSASLSuccess,
 
298
                        GetFeatures,        // read features packet
 
299
                        HandleFeatures,     // act on features, by initiating tls, sasl, or bind
 
300
                        GetTLSProceed,      // read <proceed/> tls response
 
301
                        GetSASLFirst,       // perform sasl first step using provided data
 
302
                        GetSASLChallenge,   // read server sasl challenge
 
303
                        GetSASLNext,        // perform sasl next step using provided data
 
304
                        HandleSASLSuccess,  // handle what must be done after reporting sasl success
 
305
                        GetBindResponse,    // read bind response
 
306
                        HandleAuthGet,      // send old-protocol auth-get
 
307
                        GetAuthGetResponse, // read auth-get response
 
308
                        HandleAuthSet,      // send old-protocol auth-set
 
309
                        GetAuthSetResponse  // read auth-set response
 
310
                };
 
311
 
 
312
                QValueList<DBItem> dbrequests, dbpending, dbvalidated;
 
313
 
 
314
                bool server, dialback, dialback_verify;
 
315
                int step;
 
316
 
 
317
                bool digest;
 
318
                bool tls_started, sasl_started;
 
319
 
 
320
                Jid jid;
 
321
                bool oldOnly;
 
322
                bool allowPlain;
 
323
                bool doTLS, doAuth, doBinding;
 
324
                QString password;
 
325
 
 
326
                QString dialback_id, dialback_key;
 
327
                QString self_from;
 
328
 
 
329
                void init();
 
330
                static int getOldErrorCode(const QDomElement &e);
 
331
                bool loginComplete();
 
332
 
 
333
                bool isValidStanza(const QDomElement &e) const;
 
334
                bool grabPendingItem(const Jid &to, const Jid &from, int type, DBItem *item);
 
335
                bool normalStep(const QDomElement &e);
 
336
                bool dialbackStep(const QDomElement &e);
 
337
 
 
338
                // reimplemented
 
339
                bool stepAdvancesParser() const;
 
340
                bool stepRequiresElement() const;
 
341
                void stringSend(const QString &s);
 
342
                void stringRecv(const QString &s);
 
343
                QString defaultNamespace();
 
344
                QStringList extraNamespaces();
 
345
                void handleStreamOpen(const Parser::Event &pe);
 
346
                bool doStep2(const QDomElement &e);
 
347
                void elementSend(const QDomElement &e);
 
348
                void elementRecv(const QDomElement &e);
 
349
        };
 
350
}
 
351
 
 
352
#endif