Changeset - c7f2b6298073
[Not reviewed]
include/Swiften/Server/Server.cpp
Show inline comments
 
@@ -134,12 +134,12 @@ void Server::handleSessionStarted(boost::shared_ptr<ServerFromClientSession> ses
 
}
 

	
 
void Server::handleSessionFinished(boost::shared_ptr<ServerFromClientSession> session) {
 
	if (!session->getRemoteJID().isValid()) {
 
		Swift::Presence::ref presence = Swift::Presence::create();
 
		presence->setFrom(session->getBareJID());
 
		presence->setType(Swift::Presence::Unavailable);
 
		dynamic_cast<ServerStanzaChannel *>(stanzaChannel_)->onPresenceReceived(presence);
 
	}
 
// 	if (!session->getRemoteJID().isValid()) {
 
// 		Swift::Presence::ref presence = Swift::Presence::create();
 
// 		presence->setFrom(session->getBareJID());
 
// 		presence->setType(Swift::Presence::Unavailable);
 
// 		dynamic_cast<ServerStanzaChannel *>(stanzaChannel_)->onPresenceReceived(presence);
 
// 	}
 
	serverFromClientSessions.erase(std::remove(serverFromClientSessions.begin(), serverFromClientSessions.end(), session), serverFromClientSessions.end());
 
	std::cout << "FINISH SESSION2 " << serverFromClientSessions.size() << "\n";
 
	session->onSessionStarted.disconnect(
include/Swiften/Server/ServerFromClientSession.cpp
Show inline comments
 
@@ -45,32 +45,21 @@ ServerFromClientSession::ServerFromClientSession(
 
}
 

	
 
ServerFromClientSession::~ServerFromClientSession() {
 
	std::cout << "DESTRUCTOR;\n";
 
	userRegistry_->onPasswordValid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
 
	userRegistry_->onPasswordInvalid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
 
	if (tlsLayer) {
 
		delete tlsLayer;
 
	}
 
}
 

	
 
void ServerFromClientSession::handlePasswordValid(const std::string &user) {
 
	if (user != JID(user_, getLocalJID().getDomain()).toString())
 
		return;
 
void ServerFromClientSession::handlePasswordValid() {
 
	if (!isInitialized()) {
 
		userRegistry_->onPasswordValid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
 
		userRegistry_->onPasswordInvalid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
 
		getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
 
		authenticated_ = true;
 
		getXMPPLayer()->resetParser();
 
	}
 
}
 

	
 
void ServerFromClientSession::handlePasswordInvalid(const std::string &user) {
 
	if (user != JID(user_, getLocalJID().getDomain()).toString() || authenticated_)
 
		return;
 
void ServerFromClientSession::handlePasswordInvalid() {
 
	if (!isInitialized()) {
 
		userRegistry_->onPasswordValid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
 
		userRegistry_->onPasswordInvalid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
 
		getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
 
		finishSession(AuthenticationFailedError);
 
	}
 
@@ -91,18 +80,7 @@ void ServerFromClientSession::handleElement(boost::shared_ptr<Element> element)
 
				else {
 
					PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : createSafeByteArray(""));
 
					user_ = plainMessage.getAuthenticationID();
 
					userRegistry_->onPasswordInvalid(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()).toBare().toString());
 
					userRegistry_->onPasswordValid.connect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
 
					userRegistry_->onPasswordInvalid.connect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
 
					if (userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), plainMessage.getPassword())) {
 
						// we're waiting for usermanager signal now
 
// 						authenticated_ = true;
 
// 						getXMPPLayer()->resetParser();
 
					}
 
					else {
 
						getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
 
						finishSession(AuthenticationFailedError);
 
					}
 
					userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), this, plainMessage.getPassword());
 
				}
 
			}
 
			else {
 
@@ -170,6 +148,10 @@ void ServerFromClientSession::setAllowSASLEXTERNAL() {
 
	allowSASLEXTERNAL = true;
 
}
 

	
 
void ServerFromClientSession::handleSessionFinished(const boost::optional<SessionError>&) {
 
	userRegistry_->stopLogin(JID(user_, getLocalJID().getDomain()), this);
 
}
 

	
 
void ServerFromClientSession::addTLSEncryption(TLSServerContextFactory* tlsContextFactory, const PKCS12Certificate& cert) {
 
	tlsLayer = new TLSServerLayer(tlsContextFactory);
 
	if (!tlsLayer->setServerCertificate(cert)) {
include/Swiften/Server/ServerFromClientSession.h
Show inline comments
 
@@ -53,11 +53,13 @@ namespace Swift {
 
				return Swift::JID(user_, getLocalJID().getDomain());
 
			}
 

	
 
			void handlePasswordValid();
 
			void handlePasswordInvalid();
 

	
 
		private:
 
			void handleElement(boost::shared_ptr<Element>);
 
			void handleStreamStart(const ProtocolHeader& header);
 
			void handlePasswordValid(const std::string &user);
 
			void handlePasswordInvalid(const std::string &user);
 
			void handleSessionFinished(const boost::optional<SessionError>&);
 

	
 
			void setInitialized();
 
			bool isInitialized() const { 
include/Swiften/Server/ServerStanzaChannel.cpp
Show inline comments
 
@@ -29,6 +29,7 @@ namespace {
 
}
 

	
 
void ServerStanzaChannel::addSession(boost::shared_ptr<ServerFromClientSession> session) {
 
	std::cout << "ADDING SESSION\n";
 
	sessions[session->getRemoteJID().toBare().toString()].push_back(session);
 
	session->onSessionFinished.connect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
 
	session->onElementReceived.connect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
 
@@ -53,20 +54,30 @@ void ServerStanzaChannel::sendPresence(boost::shared_ptr<Presence> presence) {
 
	send(presence);
 
}
 

	
 
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<Element> element) {
 
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<Element> element, bool last) {
 
	std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
 
	for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) {
 
		if (element) {
 
			(*i)->sendElement(element);
 
		}
 
		candidateSessions.push_back(*i);
 
	}
 

	
 
	for (std::vector<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) {
 
		
 
		removeSession(*i);
 
		if (element) {
 
			(*i)->sendElement(element);
 
		}
 

	
 
		if (last && (*i)->getRemoteJID().isValid()) {
 
			Swift::Presence::ref presence = Swift::Presence::create();
 
			presence->setFrom((*i)->getRemoteJID());
 
			presence->setType(Swift::Presence::Unavailable);
 
			onPresenceReceived(presence);
 
		}
 

	
 
		(*i)->finishSession();
 
		sessions[to.toBare().toString()].remove(*i);
 
		std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n";
 
		if (last) {
 
			break;
 
		}
 
	}
 
}
 

	
 
@@ -109,10 +120,12 @@ void ServerStanzaChannel::send(boost::shared_ptr<Stanza> stanza) {
 
void ServerStanzaChannel::handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession>& session) {
 
	removeSession(session);
 

	
 
	Swift::Presence::ref presence = Swift::Presence::create();
 
	presence->setFrom(session->getRemoteJID());
 
	presence->setType(Swift::Presence::Unavailable);
 
	onPresenceReceived(presence);
 
// 	if (!session->initiatedFinish()) {
 
		Swift::Presence::ref presence = Swift::Presence::create();
 
		presence->setFrom(session->getRemoteJID());
 
		presence->setType(Swift::Presence::Unavailable);
 
		onPresenceReceived(presence);
 
// 	}
 
}
 

	
 
void ServerStanzaChannel::handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession>& session) {
include/Swiften/Server/ServerStanzaChannel.h
Show inline comments
 
@@ -26,7 +26,7 @@ namespace Swift {
 
			void sendMessage(boost::shared_ptr<Message> message);
 
			void sendPresence(boost::shared_ptr<Presence> presence);
 

	
 
			void finishSession(const JID& to, boost::shared_ptr<Element> element);
 
			void finishSession(const JID& to, boost::shared_ptr<Element> element, bool last = false);
 

	
 
			bool getStreamManagementEnabled() const {
 
				return false;
include/Swiften/Server/SimpleUserRegistry.cpp
Show inline comments
 
@@ -11,9 +11,16 @@ namespace Swift {
 
SimpleUserRegistry::SimpleUserRegistry() {
 
}
 

	
 
bool SimpleUserRegistry::isValidUserPassword(const JID& user, const SafeByteArray& password) {
 
void SimpleUserRegistry::isValidUserPassword(const JID& user, ServerFromClientSession *session, const SafeByteArray& password) {
 
	std::map<JID,SafeByteArray>::const_iterator i = users.find(user);
 
	return i != users.end() ? i->second == password : false;
 

	
 
	
 
	if (i != users.end() && i->second == password) {
 
		session->handlePasswordValid();
 
	}
 
	else {
 
		session->handlePasswordInvalid();
 
	}
 
}
 

	
 
void SimpleUserRegistry::addUser(const JID& user, const std::string& password) {
include/Swiften/Server/SimpleUserRegistry.h
Show inline comments
 
@@ -19,7 +19,7 @@ namespace Swift {
 
		public:
 
			SimpleUserRegistry();
 

	
 
			virtual bool isValidUserPassword(const JID& user, const SafeByteArray& password);
 
			virtual void isValidUserPassword(const JID& user, ServerFromClientSession *session, const SafeByteArray& password);
 
			void addUser(const JID& user, const std::string& password);
 

	
 
		private:
include/Swiften/Server/UserRegistry.h
Show inline comments
 
@@ -9,6 +9,7 @@
 
#include <string>
 
#include <Swiften/Base/SafeByteArray.h>
 
#include <boost/signal.hpp>
 
#include "Swiften/Server/ServerFromClientSession.h"
 

	
 
namespace Swift {
 
	class JID;
 
@@ -17,12 +18,8 @@ namespace Swift {
 
		public:
 
			virtual ~UserRegistry();
 

	
 
			virtual bool isValidUserPassword(const JID& user, const SafeByteArray& password) = 0;
 

	
 
			virtual void stopLogin(const JID &/*user*/) {};
 

	
 
			boost::signal<void (const std::string &user)> onPasswordValid;
 
			boost::signal<void (const std::string &user)> onPasswordInvalid;
 
			virtual void isValidUserPassword(const JID& user, ServerFromClientSession *session, const SafeByteArray& password) = 0;
 

	
 
			virtual void stopLogin(const JID &/*user*/, ServerFromClientSession *) {};
 
	};
 
}
include/transport/transport.h
Show inline comments
 
@@ -180,7 +180,7 @@ namespace Transport {
 
			Swift::PresenceOracle *m_presenceOracle;
 
			Swift::StanzaChannel *m_stanzaChannel;
 
			Swift::IQRouter *m_iqRouter;
 
			Swift::UserRegistry *m_userRegistry;
 
			Transport::UserRegistry *m_userRegistry;
 
			StorageBackend *m_storageBackend;
 
 			DiscoInfoResponder *m_discoInfoResponder;
 
			DiscoItemsResponder *m_discoItemsResponder;
include/transport/usermanager.h
Show inline comments
 
@@ -82,6 +82,7 @@ class UserManager {
 
		}
 

	
 
		void connectUser(const Swift::JID &user);
 
		void disconnectUser(const Swift::JID &user);
 

	
 
	private:
 
		void handlePresence(Swift::Presence::ref presence);
 
@@ -89,7 +90,7 @@ class UserManager {
 
		void handleGeneralPresenceReceived(Swift::Presence::ref presence);
 
		void handleProbePresence(Swift::Presence::ref presence);
 
		void handleSubscription(Swift::Presence::ref presence);
 
		void handleRemoveTimeout(const std::string jid, bool reconnect);
 
		void handleRemoveTimeout(const std::string jid, User *user, bool reconnect);
 
// 		void handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid);
 
		void addUser(User *user);
 

	
include/transport/userregistry.h
Show inline comments
 
@@ -32,31 +32,84 @@ class UserRegistry : public Swift::UserRegistry {
 
	public:
 
		UserRegistry(Config *cfg) {config = cfg;}
 
		~UserRegistry() {}
 
		bool isValidUserPassword(const Swift::JID& user, const Swift::SafeByteArray& password) {
 
		void isValidUserPassword(const Swift::JID& user, Swift::ServerFromClientSession *session, const Swift::SafeByteArray& password) {
 
			if (!CONFIG_STRING(config, "service.admin_username").empty() && user.getNode() == CONFIG_STRING(config, "service.admin_username")) {
 
				if (Swift::safeByteArrayToString(password) == CONFIG_STRING(config, "service.admin_password")) {
 
					onPasswordValid(user);
 
					session->handlePasswordValid();
 
				}
 
				else {
 
					onPasswordInvalid(user);
 
					session->handlePasswordInvalid();
 
				}
 
				return true;
 
				return;
 
			}
 

	
 
			users[user.toBare().toString()] = Swift::safeByteArrayToString(password);
 
			std::string key = user.toBare().toString();
 

	
 
			// Users try to connect twice
 
			if (users.find(key) != users.end()) {
 
				// Kill the first session if the second password is same
 
				if (Swift::safeByteArrayToString(password) == users[key].password) {
 
					Swift::ServerFromClientSession *tmp = users[key].session;
 
					users[key].session = session;
 
					tmp->handlePasswordInvalid();
 
				}
 
				else {
 
					session->handlePasswordInvalid();
 
					std::cout << "invalid " << session << "\n";
 
					return;
 
				}
 
			}
 
			std::cout << "adding " << session << "\n";
 
			users[key].password = Swift::safeByteArrayToString(password);
 
			users[key].session = session;
 
			onConnectUser(user);
 

	
 
			return true;
 
			return;
 
		}
 

	
 
		void stopLogin(const Swift::JID& user, Swift::ServerFromClientSession *session) {
 
			std::cout << "stopping " << session << "\n";
 
			std::string key = user.toBare().toString();
 
			if (users.find(key) != users.end()) {
 
				if (users[key].session == session) {
 
					std::cout << "DISCONNECT USER\n";
 
					onDisconnectUser(user);
 
					users.erase(key);
 
				}
 
			}
 
		}
 

	
 
		void onPasswordValid(const Swift::JID &user) {
 
			std::string key = user.toBare().toString();
 
			if (users.find(key) != users.end()) {
 
				users[key].session->handlePasswordValid();
 
				users.erase(key);
 
			}
 
		}
 

	
 
		void onPasswordInvalid(const Swift::JID &user) {
 
			std::string key = user.toBare().toString();
 
			if (users.find(key) != users.end()) {
 
				users[key].session->handlePasswordInvalid();
 
				users.erase(key);
 
			}
 
		}
 

	
 
		const std::string &getUserPassword(const std::string &barejid) {
 
			return users[barejid];
 
			return users[barejid].password;
 
		}
 

	
 
		boost::signal<void (const Swift::JID &user)> onConnectUser;
 
		boost::signal<void (const Swift::JID &user)> onDisconnectUser;
 

	
 

	
 
	private:
 
		typedef struct {
 
			std::string password;
 
			Swift::ServerFromClientSession *session;
 
		} Sess;
 

	
 
		mutable std::map<std::string, std::string> users;
 
		mutable std::map<std::string, Sess> users;
 
		mutable Config *config;
 
};
 

	
src/user.cpp
Show inline comments
 
@@ -30,6 +30,9 @@
 
#include "Swiften/Elements/MUCPayload.h"
 
#include "log4cxx/logger.h"
 
#include <boost/foreach.hpp>
 
#include <execinfo.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 

	
 
using namespace log4cxx;
 
using namespace boost;
 
@@ -99,8 +102,28 @@ Swift::JID User::getJIDWithFeature(const std::string &feature) {
 
	return jid;
 
}
 

	
 
static void
 
print_trace (void)
 
{
 
void *array[80];
 
size_t size;
 
char **strings;
 
size_t i;
 

	
 
size = backtrace (array, 80);
 
strings = backtrace_symbols (array, size);
 

	
 
printf ("Obtained %zd stack frames.\n", size);
 

	
 
for (i = 0; i < size; i++)
 
	printf ("%s\n", strings[i]);
 

	
 
free (strings);
 
}
 

	
 
void User::handlePresence(Swift::Presence::ref presence) {
 
	std::cout << "PRESENCE " << presence->getFrom().toString() << "\n";
 
// 	print_trace();
 
	if (!m_connected) {
 
		// we are not connected to legacy network, so we should do it when disco#info arrive :)
 
		if (m_readyForConnect == false) {
src/usermanager.cpp
Show inline comments
 
@@ -55,6 +55,7 @@ UserManager::UserManager(Component *component, UserRegistry *userRegistry, Stora
 
	m_component->getStanzaChannel()->onPresenceReceived.connect(bind(&UserManager::handleGeneralPresenceReceived, this, _1));
 

	
 
	m_userRegistry->onConnectUser.connect(bind(&UserManager::connectUser, this, _1));
 
	m_userRegistry->onDisconnectUser.connect(bind(&UserManager::disconnectUser, this, _1));
 
// 	component->onDiscoInfoResponse.connect(bind(&UserManager::handleDiscoInfoResponse, this, _1, _2, _3));
 

	
 
	m_removeTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(1);
 
@@ -187,16 +188,20 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
 
			Swift::Presence::ref highest = m_component->getPresenceOracle()->getHighestPriorityPresence(presence->getFrom().toBare());
 
			// There's no presence for this user, so disconnect
 
			if (!highest || (highest && highest->getType() == Swift::Presence::Unavailable)) {
 
				m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user->getJID().toBare().toString(), false));
 
				m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user->getJID().toBare().toString(), user, false));
 
				m_removeTimer->start();
 
			}
 
		}
 
	}
 
}
 

	
 
void UserManager::handleRemoveTimeout(const std::string jid, bool reconnect) {
 
	m_removeTimer->onTick.disconnect(boost::bind(&UserManager::handleRemoveTimeout, this, jid, reconnect));
 
void UserManager::handleRemoveTimeout(const std::string jid, User *u, bool reconnect) {
 
	m_removeTimer->onTick.disconnect(boost::bind(&UserManager::handleRemoveTimeout, this, jid, u, reconnect));
 
	User *user = getUser(jid);
 
	if (user != u) {
 
		return;
 
	}
 

	
 
	if (user) {
 
		// Reconnect means that we're disconnecting this User instance from legacy network backend,
 
		// but we're going to connect it again in this call. Currently it's used only when
 
@@ -310,14 +315,28 @@ void UserManager::connectUser(const Swift::JID &user) {
 
	// Called by UserRegistry in server mode when user connects the server and wants
 
	// to connect legacy network
 
	if (m_users.find(user.toBare().toString()) != m_users.end()) {
 
		if (CONFIG_BOOL(m_component->getConfig(), "service.more_resources")) {
 
			m_userRegistry->onPasswordValid(user);
 
		}
 
		else {
 
			// Reconnect the user if more resources per one legacy network account are not allowed
 
			m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user.toBare().toString(), true));
 
			m_removeTimer->start();
 
		if (m_users[user.toBare().toString()]->isConnected()) {
 
			if (CONFIG_BOOL(m_component->getConfig(), "service.more_resources")) {
 
				m_userRegistry->onPasswordValid(user);
 
			}
 
			else {
 
				boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
				msg->setBody("You have signed on from another location.");
 
				msg->setTo(user);
 
				msg->setFrom(m_component->getJID());
 
				m_component->getStanzaChannel()->sendMessage(msg);
 
				m_userRegistry->onPasswordValid(user);
 
				m_component->onUserPresenceReceived.disconnect(bind(&UserManager::handlePresence, this, _1));
 
				dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->finishSession(user, boost::shared_ptr<Swift::Element>(new Swift::StreamError()), true);
 
				m_component->onUserPresenceReceived.connect(bind(&UserManager::handlePresence, this, _1));
 
			}
 
		}
 
// 		}
 
// 		else {
 
// 			// Reconnect the user if more resources per one legacy network account are not allowed
 
// 			m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user.toBare().toString(), true));
 
// 			m_removeTimer->start();
 
// 		}
 
	}
 
	else {
 
		// simulate initial available presence to start connecting this user.
 
@@ -325,9 +344,17 @@ void UserManager::connectUser(const Swift::JID &user) {
 
		response->setTo(m_component->getJID());
 
		response->setFrom(user);
 
		response->setType(Swift::Presence::Available);
 
		m_component->onUserPresenceReceived(response);
 
		dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->onPresenceReceived(response);
 
	}
 
}
 

	
 

	
 
void UserManager::disconnectUser(const Swift::JID &user) {
 
	Swift::Presence::ref response = Swift::Presence::create();
 
	response->setTo(m_component->getJID());
 
	response->setFrom(user);
 
	response->setType(Swift::Presence::Unavailable);
 
	dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->onPresenceReceived(response);
 
}
 

	
 
}
0 comments (0 inline, 0 general)