/* * xmpp.h - XMPP "core" library API * Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef XMPP_H #define XMPP_H #include #include #include #include #include #include #include namespace TQCA { class TLS; } #ifndef CS_XMPP class ByteStream; #endif namespace XMPP { // CS_IMPORT_BEGIN cutestuff/bytestream.h #ifdef CS_XMPP class ByteStream; #endif // CS_IMPORT_END class Debug { public: virtual ~Debug(); virtual void msg(const TQString &)=0; virtual void outgoingTag(const TQString &)=0; virtual void incomingTag(const TQString &)=0; virtual void outgoingXml(const TQDomElement &)=0; virtual void incomingXml(const TQDomElement &)=0; }; void setDebug(Debug *); class Connector : public TQObject { Q_OBJECT public: Connector(TQObject *parent=0); virtual ~Connector(); virtual void connectToServer(const TQString &server)=0; virtual ByteStream *stream() const=0; virtual void done()=0; bool useSSL() const; bool havePeerAddress() const; TQHostAddress peerAddress() const; TQ_UINT16 peerPort() const; signals: void connected(); void error(); protected: void setUseSSL(bool b); void setPeerAddressNone(); void setPeerAddress(const TQHostAddress &addr, TQ_UINT16 port); private: bool ssl; bool haveaddr; TQHostAddress addr; TQ_UINT16 port; }; class AdvancedConnector : public Connector { Q_OBJECT public: enum Error { ErrConnectionRefused, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth, ErrStream }; AdvancedConnector(TQObject *parent=0); virtual ~AdvancedConnector(); class Proxy { public: enum { None, HttpConnect, HttpPoll, Socks }; Proxy(); ~Proxy(); int type() const; TQString host() const; TQ_UINT16 port() const; TQString url() const; TQString user() const; TQString pass() const; int pollInterval() const; void setHttpConnect(const TQString &host, TQ_UINT16 port); void setHttpPoll(const TQString &host, TQ_UINT16 port, const TQString &url); void setSocks(const TQString &host, TQ_UINT16 port); void setUserPass(const TQString &user, const TQString &pass); void setPollInterval(int secs); private: int t; TQString v_host, v_url; TQ_UINT16 v_port; TQString v_user, v_pass; int v_poll; }; void setProxy(const Proxy &proxy); void setOptHostPort(const TQString &host, TQ_UINT16 port); void setOptProbe(bool); void setOptSSL(bool); void changePollInterval(int secs); void connectToServer(const TQString &server); ByteStream *stream() const; void done(); int errorCode() const; signals: void srvLookup(const TQString &server); void srvResult(bool success); void httpSyncStarted(); void httpSyncFinished(); private slots: void dns_done(); void srv_done(); void bs_connected(); void bs_error(int); void http_syncStarted(); void http_syncFinished(); private: class Private; Private *d; void cleanup(); void do_resolve(); void do_connect(); void tryNextSrv(); }; class TLSHandler : public TQObject { Q_OBJECT public: TLSHandler(TQObject *parent=0); virtual ~TLSHandler(); virtual void reset()=0; virtual void startClient(const TQString &host)=0; virtual void write(const TQByteArray &a)=0; virtual void writeIncoming(const TQByteArray &a)=0; signals: void success(); void fail(); void closed(); void readyRead(const TQByteArray &a); void readyReadOutgoing(const TQByteArray &a, int plainBytes); }; class TQCATLSHandler : public TLSHandler { Q_OBJECT public: TQCATLSHandler(TQCA::TLS *parent); ~TQCATLSHandler(); TQCA::TLS *tls() const; int tlsError() const; void reset(); void startClient(const TQString &host); void write(const TQByteArray &a); void writeIncoming(const TQByteArray &a); signals: void tlsHandshaken(); public slots: void continueAfterHandshake(); private slots: void tls_handshaken(); void tls_readyRead(); void tls_readyReadOutgoing(int); void tls_closed(); void tls_error(int); private: class Private; Private *d; }; class Jid { public: Jid(); ~Jid(); Jid(const TQString &s); Jid(const char *s); Jid & operator=(const TQString &s); Jid & operator=(const char *s); void set(const TQString &s); void set(const TQString &domain, const TQString &node, const TQString &resource=""); void setDomain(const TQString &s); void setNode(const TQString &s); void setResource(const TQString &s); const TQString & domain() const { return d; } const TQString & node() const { return n; } const TQString & resource() const { return r; } const TQString & bare() const { return b; } const TQString & full() const { return f; } Jid withNode(const TQString &s) const; Jid withResource(const TQString &s) const; bool isValid() const; bool isEmpty() const; bool compare(const Jid &a, bool compareRes=true) const; static bool validDomain(const TQString &s, TQString *norm=0); static bool validNode(const TQString &s, TQString *norm=0); static bool validResource(const TQString &s, TQString *norm=0); // TODO: kill these later const TQString & host() const { return d; } const TQString & user() const { return n; } const TQString & userHost() const { return b; } private: void reset(); void update(); TQString f, b, d, n, r; bool valid; }; class Stream; class Stanza { public: enum Kind { Message, Presence, IQ }; enum ErrorType { Cancel, Continue, Modify, Auth, Wait }; enum ErrorCond { BadRequest, Conflict, FeatureNotImplemented, Forbidden, InternalServerError, ItemNotFound, JidMalformed, NotAllowed, PaymentRequired, RecipientUnavailable, RegistrationRequired, ServerNotFound, ServerTimeout, ResourceConstraint, ServiceUnavailable, SubscriptionRequired, UndefinedCondition, UnexpectedRequest }; Stanza(); Stanza(const Stanza &from); Stanza & operator=(const Stanza &from); virtual ~Stanza(); class Error { public: Error(int type=Cancel, int condition=UndefinedCondition, const TQString &text="", const TQDomElement &appSpec=TQDomElement()); int type; int condition; TQString text; TQDomElement appSpec; }; bool isNull() const; TQDomElement element() const; TQString toString() const; TQDomDocument & doc() const; TQString baseNS() const; TQString xhtmlImNS() const; TQString xhtmlNS() const; TQDomElement createElement(const TQString &ns, const TQString &tagName); TQDomElement createTextElement(const TQString &ns, const TQString &tagName, const TQString &text); TQDomElement createXHTMLElement(const TQString &xHTML); void appendChild(const TQDomElement &e); Kind kind() const; void setKind(Kind k); Jid to() const; Jid from() const; TQString id() const; TQString type() const; TQString lang() const; void setTo(const Jid &j); void setFrom(const Jid &j); void setId(const TQString &id); void setType(const TQString &type); void setLang(const TQString &lang); Error error() const; void setError(const Error &err); void clearError(); private: friend class Stream; Stanza(Stream *s, Kind k, const Jid &to, const TQString &type, const TQString &id); Stanza(Stream *s, const TQDomElement &e); class Private; Private *d; }; class Stream : public TQObject { Q_OBJECT public: enum Error { ErrParse, ErrProtocol, ErrStream, ErrCustom = 10 }; enum StreamCond { GenericStreamError, Conflict, ConnectionTimeout, InternalServerError, InvalidFrom, InvalidXml, PolicyViolation, ResourceConstraint, SystemShutdown }; Stream(TQObject *parent=0); virtual ~Stream(); virtual TQDomDocument & doc() const=0; virtual TQString baseNS() const=0; virtual TQString xhtmlImNS() const=0; virtual TQString xhtmlNS() const=0; virtual bool old() const=0; virtual void close()=0; virtual bool stanzaAvailable() const=0; virtual Stanza read()=0; virtual void write(const Stanza &s)=0; virtual int errorCondition() const=0; virtual TQString errorText() const=0; virtual TQDomElement errorAppSpec() const=0; Stanza createStanza(Stanza::Kind k, const Jid &to="", const TQString &type="", const TQString &id=""); Stanza createStanza(const TQDomElement &e); static TQString xmlToString(const TQDomElement &e, bool clip=false); signals: void connectionClosed(); void delayedCloseFinished(); void readyRead(); void stanzaWritten(); void error(int); }; class ClientStream : public Stream { Q_OBJECT public: enum Error { ErrConnection = ErrCustom, // Connection error, ask Connector-subclass what's up ErrNeg, // Negotiation error, see condition ErrTLS, // TLS error, see condition ErrAuth, // Auth error, see condition ErrSecurityLayer, // broken SASL security layer ErrBind // Resource binding error }; enum Warning { WarnOldVersion, // server uses older XMPP/Jabber "0.9" protocol WarnNoTLS // there is no chance for TLS at this point }; enum NegCond { HostGone, // host no longer hosted HostUnknown, // unknown host RemoteConnectionFailed, // unable to connect to a required remote resource SeeOtherHost, // a 'redirect', see errorText() for other host UnsupportedVersion // unsupported XMPP version }; enum TLSCond { TLSStart, // server rejected STARTTLS TLSFail // TLS failed, ask TLSHandler-subclass what's up }; enum SecurityLayer { LayerTLS, LayerSASL }; enum AuthCond { GenericAuthError, // all-purpose "can't login" error NoMech, // No appropriate auth mech available BadProto, // Bad SASL auth protocol BadServ, // Server failed mutual auth EncryptionRequired, // can't use mech without TLS InvalidAuthzid, // bad input JID InvalidMech, // bad mechanism InvalidRealm, // bad realm MechTooWeak, // can't use mech with this authzid NotAuthorized, // bad user, bad password, bad creditials TemporaryAuthFailure // please try again later! }; enum BindCond { BindNotAllowed, // not allowed to bind a resource BindConflict // resource in-use }; ClientStream(Connector *conn, TLSHandler *tlsHandler=0, TQObject *parent=0); ClientStream(const TQString &host, const TQString &defRealm, ByteStream *bs, TQCA::TLS *tls=0, TQObject *parent=0); // server ~ClientStream(); Jid jid() const; void connectToServer(const Jid &jid, bool auth=true); void accept(); // server bool isActive() const; bool isAuthenticated() const; // login params void setUsername(const TQString &s); void setPassword(const TQString &s); void setRealm(const TQString &s); void continueAfterParams(); // SASL information TQString saslMechanism() const; int saslSSF() const; // binding void setResourceBinding(bool); // security options (old protocol only uses the first !) void setAllowPlain(bool); void setRequireMutualAuth(bool); void setSSFRange(int low, int high); void setOldOnly(bool); void setSASLMechanism(const TQString &s); void setLocalAddr(const TQHostAddress &addr, TQ_UINT16 port); // reimplemented TQDomDocument & doc() const; TQString baseNS() const; TQString xhtmlImNS() const; TQString xhtmlNS() const; bool old() const; void close(); bool stanzaAvailable() const; Stanza read(); void write(const Stanza &s); int errorCondition() const; TQString errorText() const; TQDomElement errorAppSpec() const; // extra void writeDirect(const TQString &s); void setNoopTime(int mills); signals: void connected(); void securityLayerActivated(int); void needAuthParams(bool user, bool pass, bool realm); void authenticated(); void warning(int); void incomingXml(const TQString &s); void outgoingXml(const TQString &s); public slots: void continueAfterWarning(); private slots: void cr_connected(); void cr_error(); void bs_connectionClosed(); void bs_delayedCloseFinished(); void bs_error(int); // server only void ss_readyRead(); void ss_bytesWritten(int); void ss_tlsHandshaken(); void ss_tlsClosed(); void ss_error(int); void sasl_clientFirstStep(const TQString &mech, const TQByteArray *clientInit); void sasl_nextStep(const TQByteArray &stepData); void sasl_needParams(bool user, bool authzid, bool pass, bool realm); void sasl_authCheck(const TQString &user, const TQString &authzid); void sasl_authenticated(); void sasl_error(int); void doNoop(); void doReadyRead(); private: class Private; Private *d; void reset(bool all=false); void processNext(); int convertedSASLCond() const; bool handleNeed(); void handleError(); void srvProcessNext(); }; } #endif