initial commit
This commit is contained in:
commit
9d20827c46
2469 changed files with 470994 additions and 0 deletions
361
iris-legacy/iris/xmpp-core/protocol.h
Normal file
361
iris-legacy/iris/xmpp-core/protocol.h
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
* protocol.h - XMPP-Core protocol state machine
|
||||
* Copyright (C) 2004 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PROTOCOL_H
|
||||
#define PROTOCOL_H
|
||||
|
||||
#include <qpair.h>
|
||||
//Added by qt3to4:
|
||||
#include <QList>
|
||||
#include "xmlprotocol.h"
|
||||
#include "xmpp.h"
|
||||
|
||||
#define NS_ETHERX "http://etherx.jabber.org/streams"
|
||||
#define NS_CLIENT "jabber:client"
|
||||
#define NS_SERVER "jabber:server"
|
||||
#define NS_DIALBACK "jabber:server:dialback"
|
||||
#define NS_STREAMS "urn:ietf:params:xml:ns:xmpp-streams"
|
||||
#define NS_TLS "urn:ietf:params:xml:ns:xmpp-tls"
|
||||
#define NS_SASL "urn:ietf:params:xml:ns:xmpp-sasl"
|
||||
#define NS_SESSION "urn:ietf:params:xml:ns:xmpp-session"
|
||||
#define NS_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas"
|
||||
#define NS_BIND "urn:ietf:params:xml:ns:xmpp-bind"
|
||||
#define NS_COMPRESS_FEATURE "http://jabber.org/features/compress"
|
||||
#define NS_COMPRESS_PROTOCOL "http://jabber.org/protocol/compress"
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Version
|
||||
{
|
||||
public:
|
||||
Version(int maj=0, int min=0);
|
||||
|
||||
int major, minor;
|
||||
};
|
||||
|
||||
class StreamFeatures
|
||||
{
|
||||
public:
|
||||
StreamFeatures();
|
||||
|
||||
bool tls_supported, sasl_supported, bind_supported, compress_supported;
|
||||
bool tls_required;
|
||||
QStringList sasl_mechs;
|
||||
QStringList compression_mechs;
|
||||
};
|
||||
|
||||
class BasicProtocol : public XmlProtocol
|
||||
{
|
||||
public:
|
||||
// xmpp 1.0 error conditions
|
||||
enum SASLCond {
|
||||
Aborted,
|
||||
IncorrectEncoding,
|
||||
InvalidAuthzid,
|
||||
InvalidMech,
|
||||
MechTooWeak,
|
||||
NotAuthorized,
|
||||
TemporaryAuthFailure
|
||||
};
|
||||
enum StreamCond {
|
||||
BadFormat,
|
||||
BadNamespacePrefix,
|
||||
Conflict,
|
||||
ConnectionTimeout,
|
||||
HostGone,
|
||||
HostUnknown,
|
||||
ImproperAddressing,
|
||||
InternalServerError,
|
||||
InvalidFrom,
|
||||
InvalidId,
|
||||
InvalidNamespace,
|
||||
InvalidXml,
|
||||
StreamNotAuthorized,
|
||||
PolicyViolation,
|
||||
RemoteConnectionFailed,
|
||||
ResourceConstraint,
|
||||
RestrictedXml,
|
||||
SeeOtherHost,
|
||||
SystemShutdown,
|
||||
UndefinedCondition,
|
||||
UnsupportedEncoding,
|
||||
UnsupportedStanzaType,
|
||||
UnsupportedVersion,
|
||||
XmlNotWellFormed
|
||||
};
|
||||
enum BindCond {
|
||||
BindBadRequest,
|
||||
BindNotAllowed,
|
||||
BindConflict
|
||||
};
|
||||
|
||||
// extend the XmlProtocol enums
|
||||
enum Need {
|
||||
NSASLMechs = XmlProtocol::NCustom, // need SASL mechlist
|
||||
NStartTLS, // need to switch on TLS layer
|
||||
NCompress, // need to switch on compression layer
|
||||
NSASLFirst, // need SASL first step
|
||||
NSASLNext, // need SASL next step
|
||||
NSASLLayer, // need to switch on SASL layer
|
||||
NCustom = XmlProtocol::NCustom+10
|
||||
};
|
||||
enum Event {
|
||||
EFeatures = XmlProtocol::ECustom, // breakpoint after features packet is received
|
||||
ESASLSuccess, // breakpoint after successful sasl auth
|
||||
EStanzaReady, // a stanza was received
|
||||
EStanzaSent, // a stanza was sent
|
||||
EReady, // stream is ready for stanza use
|
||||
ECustom = XmlProtocol::ECustom+10
|
||||
};
|
||||
enum Error {
|
||||
ErrProtocol = XmlProtocol::ErrCustom, // there was an error in the xmpp-core protocol exchange
|
||||
ErrStream, // <stream:error>, see errCond, errText, and errAppSpec for details
|
||||
ErrStartTLS, // server refused starttls
|
||||
ErrCompress, // server refused compression
|
||||
ErrAuth, // authorization error. errCond holds sasl condition (or numeric code for old-protocol)
|
||||
ErrBind, // server refused resource bind
|
||||
ErrCustom = XmlProtocol::ErrCustom+10
|
||||
};
|
||||
|
||||
BasicProtocol();
|
||||
~BasicProtocol();
|
||||
|
||||
void reset();
|
||||
|
||||
// for outgoing xml
|
||||
QDomDocument doc;
|
||||
|
||||
// sasl-related
|
||||
QString saslMech() const;
|
||||
QByteArray saslStep() const;
|
||||
void setSASLMechList(const QStringList &list);
|
||||
void setSASLFirst(const QString &mech, const QByteArray &step);
|
||||
void setSASLNext(const QByteArray &step);
|
||||
void setSASLAuthed();
|
||||
|
||||
// send / recv
|
||||
void sendStanza(const QDomElement &e);
|
||||
void sendDirect(const QString &s);
|
||||
void sendWhitespace();
|
||||
QDomElement recvStanza();
|
||||
|
||||
// shutdown
|
||||
void shutdown();
|
||||
void shutdownWithError(int cond, const QString &otherHost="");
|
||||
|
||||
// <stream> information
|
||||
QString to, from, id, lang;
|
||||
Version version;
|
||||
|
||||
// error output
|
||||
int errCond;
|
||||
QString errText;
|
||||
QDomElement errAppSpec;
|
||||
QString otherHost;
|
||||
|
||||
QByteArray spare; // filled with unprocessed data on NStartTLS and NSASLLayer
|
||||
|
||||
bool isReady() const;
|
||||
|
||||
enum { TypeElement, TypeStanza, TypeDirect, TypePing };
|
||||
|
||||
protected:
|
||||
static int stringToSASLCond(const QString &s);
|
||||
static int stringToStreamCond(const QString &s);
|
||||
static QString saslCondToString(int);
|
||||
static QString streamCondToString(int);
|
||||
|
||||
void send(const QDomElement &e, bool clip=false);
|
||||
void sendStreamError(int cond, const QString &text="", const QDomElement &appSpec=QDomElement());
|
||||
void sendStreamError(const QString &text); // old-style
|
||||
|
||||
bool errorAndClose(int cond, const QString &text="", const QDomElement &appSpec=QDomElement());
|
||||
bool error(int code);
|
||||
void delayErrorAndClose(int cond, const QString &text="", const QDomElement &appSpec=QDomElement());
|
||||
void delayError(int code);
|
||||
|
||||
// reimplemented
|
||||
QDomElement docElement();
|
||||
void handleDocOpen(const Parser::Event &pe);
|
||||
bool handleError();
|
||||
bool handleCloseFinished();
|
||||
bool doStep(const QDomElement &e);
|
||||
void itemWritten(int id, int size);
|
||||
|
||||
virtual QString defaultNamespace();
|
||||
virtual QStringList extraNamespaces(); // stringlist: prefix,uri,prefix,uri, [...]
|
||||
virtual void handleStreamOpen(const Parser::Event &pe);
|
||||
virtual bool doStep2(const QDomElement &e)=0;
|
||||
|
||||
void setReady(bool b);
|
||||
|
||||
QString sasl_mech;
|
||||
QStringList sasl_mechlist;
|
||||
QByteArray sasl_step;
|
||||
bool sasl_authed;
|
||||
|
||||
QDomElement stanzaToRecv;
|
||||
|
||||
private:
|
||||
struct SASLCondEntry
|
||||
{
|
||||
const char *str;
|
||||
int cond;
|
||||
};
|
||||
static SASLCondEntry saslCondTable[];
|
||||
|
||||
struct StreamCondEntry
|
||||
{
|
||||
const char *str;
|
||||
int cond;
|
||||
};
|
||||
static StreamCondEntry streamCondTable[];
|
||||
|
||||
struct SendItem
|
||||
{
|
||||
QDomElement stanzaToSend;
|
||||
QString stringToSend;
|
||||
bool doWhitespace;
|
||||
};
|
||||
QList<SendItem> sendList;
|
||||
|
||||
bool doShutdown, delayedError, closeError, ready;
|
||||
int stanzasPending, stanzasWritten;
|
||||
|
||||
void init();
|
||||
void extractStreamError(const QDomElement &e);
|
||||
};
|
||||
|
||||
class CoreProtocol : public BasicProtocol
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
NPassword = NCustom, // need password for old-mode
|
||||
EDBVerify = ECustom, // breakpoint after db:verify request
|
||||
ErrPlain = ErrCustom // server only supports plain, but allowPlain is false locally
|
||||
};
|
||||
|
||||
CoreProtocol();
|
||||
~CoreProtocol();
|
||||
|
||||
void reset();
|
||||
|
||||
void startClientOut(const Jid &jid, bool oldOnly, bool tlsActive, bool doAuth, bool doCompression);
|
||||
void startServerOut(const QString &to);
|
||||
void startDialbackOut(const QString &to, const QString &from);
|
||||
void startDialbackVerifyOut(const QString &to, const QString &from, const QString &id, const QString &key);
|
||||
void startClientIn(const QString &id);
|
||||
void startServerIn(const QString &id);
|
||||
|
||||
void setLang(const QString &s);
|
||||
void setAllowTLS(bool b);
|
||||
void setAllowBind(bool b);
|
||||
void setAllowPlain(bool b); // old-mode
|
||||
const Jid& jid() const;
|
||||
|
||||
void setPassword(const QString &s);
|
||||
void setFrom(const QString &s);
|
||||
void setDialbackKey(const QString &s);
|
||||
|
||||
// input
|
||||
QString user, host;
|
||||
|
||||
// status
|
||||
bool old;
|
||||
|
||||
StreamFeatures features;
|
||||
|
||||
//static QString xmlToString(const QDomElement &e, bool clip=false);
|
||||
|
||||
class DBItem
|
||||
{
|
||||
public:
|
||||
enum { ResultRequest, ResultGrant, VerifyRequest, VerifyGrant, Validated };
|
||||
int type;
|
||||
Jid to, from;
|
||||
QString key, id;
|
||||
bool ok;
|
||||
};
|
||||
|
||||
private:
|
||||
enum Step {
|
||||
Start,
|
||||
Done,
|
||||
SendFeatures,
|
||||
GetRequest,
|
||||
HandleTLS,
|
||||
GetSASLResponse,
|
||||
IncHandleSASLSuccess,
|
||||
GetFeatures, // read features packet
|
||||
HandleFeatures, // act on features, by initiating tls, sasl, or bind
|
||||
GetTLSProceed, // read <proceed/> tls response
|
||||
GetCompressProceed, // read <compressed/> compression response
|
||||
GetSASLFirst, // perform sasl first step using provided data
|
||||
GetSASLChallenge, // read server sasl challenge
|
||||
GetSASLNext, // perform sasl next step using provided data
|
||||
HandleSASLSuccess, // handle what must be done after reporting sasl success
|
||||
GetBindResponse, // read bind response
|
||||
HandleAuthGet, // send old-protocol auth-get
|
||||
GetAuthGetResponse, // read auth-get response
|
||||
HandleAuthSet, // send old-protocol auth-set
|
||||
GetAuthSetResponse // read auth-set response
|
||||
};
|
||||
|
||||
QList<DBItem> dbrequests, dbpending, dbvalidated;
|
||||
|
||||
bool server, dialback, dialback_verify;
|
||||
int step;
|
||||
|
||||
bool digest;
|
||||
bool tls_started, sasl_started, compress_started;
|
||||
|
||||
Jid jid_;
|
||||
bool oldOnly;
|
||||
bool allowPlain;
|
||||
bool doTLS, doAuth, doBinding, doCompress;
|
||||
QString password;
|
||||
|
||||
QString dialback_id, dialback_key;
|
||||
QString self_from;
|
||||
|
||||
void init();
|
||||
static int getOldErrorCode(const QDomElement &e);
|
||||
bool loginComplete();
|
||||
|
||||
bool isValidStanza(const QDomElement &e) const;
|
||||
bool grabPendingItem(const Jid &to, const Jid &from, int type, DBItem *item);
|
||||
bool normalStep(const QDomElement &e);
|
||||
bool dialbackStep(const QDomElement &e);
|
||||
|
||||
// reimplemented
|
||||
bool stepAdvancesParser() const;
|
||||
bool stepRequiresElement() const;
|
||||
void stringSend(const QString &s);
|
||||
void stringRecv(const QString &s);
|
||||
QString defaultNamespace();
|
||||
QStringList extraNamespaces();
|
||||
void handleStreamOpen(const Parser::Event &pe);
|
||||
bool doStep2(const QDomElement &e);
|
||||
void elementSend(const QDomElement &e);
|
||||
void elementRecv(const QDomElement &e);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in a new issue