diff --git a/include/Swiften/Elements/SpectrumErrorPayload.cpp b/include/Swiften/Elements/SpectrumErrorPayload.cpp new file mode 100644 index 00000000..9661f63e --- /dev/null +++ b/include/Swiften/Elements/SpectrumErrorPayload.cpp @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include + +namespace Swift { + +SpectrumErrorPayload::SpectrumErrorPayload(Error error) : error_(error) { } + +} diff --git a/include/Swiften/Elements/SpectrumErrorPayload.h b/include/Swiften/Elements/SpectrumErrorPayload.h new file mode 100644 index 00000000..b2b402ff --- /dev/null +++ b/include/Swiften/Elements/SpectrumErrorPayload.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include + +#include +#include + +namespace Swift { + class SpectrumErrorPayload : public Payload { + public: + enum Error { + CONNECTION_ERROR_NETWORK_ERROR = 0, + CONNECTION_ERROR_INVALID_USERNAME = 1, + CONNECTION_ERROR_AUTHENTICATION_FAILED = 2, + CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE = 3, + CONNECTION_ERROR_NO_SSL_SUPPORT = 4, + CONNECTION_ERROR_ENCRYPTION_ERROR = 5, + CONNECTION_ERROR_NAME_IN_USE = 6, + CONNECTION_ERROR_INVALID_SETTINGS = 7, + CONNECTION_ERROR_CERT_NOT_PROVIDED = 8, + CONNECTION_ERROR_CERT_UNTRUSTED = 9, + CONNECTION_ERROR_CERT_EXPIRED = 10, + CONNECTION_ERROR_CERT_NOT_ACTIVATED = 11, + CONNECTION_ERROR_CERT_HOSTNAME_MISMATCH = 12, + CONNECTION_ERROR_CERT_FINGERPRINT_MISMATCH = 13, + CONNECTION_ERROR_CERT_SELF_SIGNED = 14, + CONNECTION_ERROR_CERT_OTHER_ERROR = 15, + CONNECTION_ERROR_OTHER_ERROR = 16, + }; + + SpectrumErrorPayload(Error error = CONNECTION_ERROR_OTHER_ERROR); + + Error getError() const { + return error_; + } + + void setError(Error error) { + error_ = error; + } + + private: + Error error_; + }; +} diff --git a/include/Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.cpp b/include/Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.cpp new file mode 100644 index 00000000..552e1936 --- /dev/null +++ b/include/Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include + +#include + +#include +#include +#include +#include +#include + +namespace Swift { + +SpectrumErrorSerializer::SpectrumErrorSerializer() : GenericPayloadSerializer() { +} + +std::string SpectrumErrorSerializer::serializePayload(boost::shared_ptr error) const { + std::string data; + switch (error->getError()) { + case SpectrumErrorPayload::CONNECTION_ERROR_NETWORK_ERROR: data = "CONNECTION_ERROR_NETWORK_ERROR"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_INVALID_USERNAME: data = "CONNECTION_ERROR_INVALID_USERNAME"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_AUTHENTICATION_FAILED: data = "CONNECTION_ERROR_AUTHENTICATION_FAILED"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE: data = "CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_NO_SSL_SUPPORT: data = "CONNECTION_ERROR_NO_SSL_SUPPORT"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_ENCRYPTION_ERROR: data = "CONNECTION_ERROR_ENCRYPTION_ERROR"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_NAME_IN_USE: data = "CONNECTION_ERROR_NAME_IN_USE"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_INVALID_SETTINGS: data = "CONNECTION_ERROR_INVALID_SETTINGS"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_CERT_NOT_PROVIDED: data = "CONNECTION_ERROR_CERT_NOT_PROVIDED"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_CERT_UNTRUSTED: data = "CONNECTION_ERROR_CERT_UNTRUSTED"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_CERT_EXPIRED: data = "CONNECTION_ERROR_NETWORK_ERROR"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_CERT_NOT_ACTIVATED: data = "CONNECTION_ERROR_NETWORK_ERROR"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_CERT_HOSTNAME_MISMATCH: data = "CONNECTION_ERROR_NETWORK_ERROR"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_CERT_FINGERPRINT_MISMATCH: data = "CONNECTION_ERROR_NETWORK_ERROR"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_CERT_SELF_SIGNED: data = "CONNECTION_ERROR_NETWORK_ERROR"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_CERT_OTHER_ERROR: data = "CONNECTION_ERROR_NETWORK_ERROR"; break; + case SpectrumErrorPayload::CONNECTION_ERROR_OTHER_ERROR: data = "CONNECTION_ERROR_NETWORK_ERROR"; break; + } + + XMLElement el("spectrumerror", "http://spectrum.im/error", data); + + el.setAttribute("error", boost::lexical_cast(error->getError())); + + return el.serialize(); +} + +} diff --git a/include/Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h b/include/Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h new file mode 100644 index 00000000..112e79e2 --- /dev/null +++ b/include/Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include +#include + +namespace Swift { + class SpectrumErrorSerializer : public GenericPayloadSerializer { + public: + SpectrumErrorSerializer(); + + virtual std::string serializePayload(boost::shared_ptr) const; + }; +} diff --git a/include/transport/user.h b/include/transport/user.h index 952bb3b4..76fe48bc 100644 --- a/include/transport/user.h +++ b/include/transport/user.h @@ -27,6 +27,7 @@ #include "Swiften/Disco/EntityCapsProvider.h" #include "storagebackend.h" #include +#include "Swiften/Elements/SpectrumErrorPayload.h" namespace Transport { @@ -93,7 +94,7 @@ class User : public Swift::EntityCapsProvider { /// \return language const char *getLang() { return "en"; } - void handleDisconnected(const std::string &error); + void handleDisconnected(const std::string &error, Swift::SpectrumErrorPayload::Error e = Swift::SpectrumErrorPayload::CONNECTION_ERROR_OTHER_ERROR); bool isReadyToConnect() { return m_readyForConnect; diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index b284390c..a99c51de 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -39,6 +39,7 @@ #include "Swiften/Elements/AttentionPayload.h" #include "Swiften/Elements/XHTMLIMPayload.h" #include "Swiften/Elements/InvisiblePayload.h" +#include "Swiften/Elements/SpectrumErrorPayload.h" #include "transport/protocol.pb.h" #include "log4cxx/logger.h" @@ -387,7 +388,7 @@ void NetworkPluginServer::handleDisconnectedPayload(const std::string &data) { if (!user) { return; } - user->handleDisconnected(payload.message()); + user->handleDisconnected(payload.message(), (Swift::SpectrumErrorPayload::Error) payload.error()); } void NetworkPluginServer::handleVCardPayload(const std::string &data) { diff --git a/src/transport.cpp b/src/transport.cpp index 7d3677f1..90e28deb 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -36,6 +36,7 @@ #include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h" #include "Swiften/Parser/PayloadParsers/StatsParser.h" #include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h" +#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h" #include "transport/BlockParser.h" #include "transport/BlockSerializer.h" #include "Swiften/Parser/PayloadParsers/InvisibleParser.h" @@ -99,6 +100,7 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, m_server->addPayloadSerializer(new Transport::BlockSerializer()); m_server->addPayloadSerializer(new Swift::InvisibleSerializer()); m_server->addPayloadSerializer(new Swift::StatsSerializer()); + m_server->addPayloadSerializer(new Swift::SpectrumErrorSerializer()); m_server->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1)); m_server->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1)); @@ -124,6 +126,7 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, m_component->addPayloadSerializer(new Transport::BlockSerializer()); m_component->addPayloadSerializer(new Swift::InvisibleSerializer()); m_component->addPayloadSerializer(new Swift::StatsSerializer()); + m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer()); m_stanzaChannel = m_component->getStanzaChannel(); m_iqRouter = m_component->getIQRouter(); diff --git a/src/user.cpp b/src/user.cpp index 9b1d7fd6..7d9ec3ab 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -28,6 +28,7 @@ #include "Swiften/Server/ServerStanzaChannel.h" #include "Swiften/Elements/StreamError.h" #include "Swiften/Elements/MUCPayload.h" +#include "Swiften/Elements/SpectrumErrorPayload.h" #include "log4cxx/logger.h" #include #include @@ -315,7 +316,7 @@ void User::setIgnoreDisconnect(bool ignoreDisconnect) { LOG4CXX_INFO(logger, m_jid.toString() << ": Setting ignoreDisconnect=" << m_ignoreDisconnect); } -void User::handleDisconnected(const std::string &error) { +void User::handleDisconnected(const std::string &error, Swift::SpectrumErrorPayload::Error e) { if (m_ignoreDisconnect) { LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnecting from legacy network ignored (probably moving between backends)"); return; @@ -333,6 +334,7 @@ void User::handleDisconnected(const std::string &error) { msg->setBody(error); msg->setTo(m_jid.toBare()); msg->setFrom(m_component->getJID()); + msg->addPayload(boost::make_shared(e)); m_component->getStanzaChannel()->sendMessage(msg); // In server mode, server finishes the session and pass unavailable session to userManager if we're connected to legacy network,