2
* protocol.h - XMPP-Core protocol state machine
3
* Copyright (C) 2004 Justin Karneges
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.
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.
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
25
#include"xmlprotocol.h"
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"
44
Version(int maj=0, int min=0);
54
bool tls_supported, sasl_supported, bind_supported;
56
QStringList sasl_mechs;
59
class BasicProtocol : public XmlProtocol
62
// xmpp 1.0 error conditions
87
RemoteConnectionFailed,
94
UnsupportedStanzaType,
104
// extend the XmlProtocol enums
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
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
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
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();
147
void sendStanza(const QDomElement &e);
148
void sendDirect(const QString &s);
149
void sendWhitespace();
150
QDomElement recvStanza();
154
void shutdownWithError(int cond, const QString &otherHost="");
156
// <stream> information
157
QString to, from, id, lang;
163
QDomElement errAppSpec;
166
QByteArray spare; // filled with unprocessed data on NStartTLS and NSASLLayer
168
bool isReady() const;
170
enum { TypeElement, TypeStanza, TypeDirect, TypePing };
173
static int stringToSASLCond(const QString &s);
174
static int stringToStreamCond(const QString &s);
175
static QString saslCondToString(int);
176
static QString streamCondToString(int);
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
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);
188
QDomElement docElement();
189
void handleDocOpen(const Parser::Event &pe);
191
bool handleCloseFinished();
192
bool doStep(const QDomElement &e);
193
void itemWritten(int id, int size);
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;
200
void setReady(bool b);
203
QStringList sasl_mechlist;
204
QByteArray sasl_step;
207
QDomElement stanzaToRecv;
215
static SASLCondEntry saslCondTable[];
217
struct StreamCondEntry
222
static StreamCondEntry streamCondTable[];
226
QDomElement stanzaToSend;
227
QString stringToSend;
230
QValueList<SendItem> sendList;
232
bool doShutdown, delayedError, closeError, ready;
233
int stanzasPending, stanzasWritten;
236
void extractStreamError(const QDomElement &e);
239
class CoreProtocol : public BasicProtocol
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
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);
260
void setLang(const QString &s);
261
void setAllowTLS(bool b);
262
void setAllowBind(bool b);
263
void setAllowPlain(bool b); // old-mode
265
void setPassword(const QString &s);
266
void setFrom(const QString &s);
267
void setDialbackKey(const QString &s);
275
StreamFeatures features;
277
//static QString xmlToString(const QDomElement &e, bool clip=false);
282
enum { ResultRequest, ResultGrant, VerifyRequest, VerifyGrant, Validated };
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
312
QValueList<DBItem> dbrequests, dbpending, dbvalidated;
314
bool server, dialback, dialback_verify;
318
bool tls_started, sasl_started;
323
bool doTLS, doAuth, doBinding;
326
QString dialback_id, dialback_key;
330
static int getOldErrorCode(const QDomElement &e);
331
bool loginComplete();
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);
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);