Changeset - 83f5f36c94a2
[Not reviewed]
0 5 0
HanzZ - 13 years ago 2012-08-07 17:41:13
hanzz.k@gmail.com
Check if JID is valid when calling setName and ignore buddies with invalid JID
5 files changed with 7 insertions and 3 deletions:
0 comments (0 inline, 0 general)
include/transport/buddy.h
Show inline comments
 
@@ -124,59 +124,59 @@ class Buddy {
 

	
 
		/// This method should be called whenever some information returned by virtual functions changes.
 

	
 
		/// This method sends presence to XMPP user.
 
		void handleBuddyChanged();
 

	
 
		/// Handles VCard from legacy network and forwards it to XMPP user.
 

	
 
		/// \param id ID used in IQ-result.
 
		/// \param vcard VCard which will be sent.
 
		void handleVCardReceived(const std::string &id, Swift::VCard::ref vcard);
 

	
 
		/// Returns legacy network username of this buddy. (for example UIN for ICQ, JID for Jabber, ...).
 

	
 
		/// \return legacy network username
 
		virtual std::string getName() = 0;
 

	
 
		/// Returns alias (nickname) of this buddy.
 

	
 
		/// \return alias (nickname)
 
		virtual std::string getAlias() = 0;
 

	
 
		/// Returns list of groups this buddy is in.
 

	
 
		/// \return groups
 
		virtual std::vector<std::string> getGroups() = 0;
 

	
 
		/// Returns current legacy network status and statuMessage of this buddy.
 

	
 
		/// \param status current status/show is stored here
 
		/// \param statusMessage current status message is stored here
 
		/// \return true if status was stored successfully
 
		virtual bool getStatus(Swift::StatusShow &status, std::string &statusMessage) = 0;
 

	
 
		/// Returns SHA-1 hash of buddy icon (avatar) or empty string if there is no avatar for this buddy.
 

	
 
		/// \return avatar hash or empty string.
 
		virtual std::string getIconHash() = 0;
 

	
 
		/// Returns legacy name of buddy from JID.
 

	
 
		/// \param jid Jabber ID.
 
		/// \return legacy name of buddy from JID.
 
		static std::string JIDToLegacyName(const Swift::JID &jid);
 
		static BuddyFlag buddFlagsFromJID(const Swift::JID &jid);
 

	
 
	protected:
 
		void generateJID();
 
		Swift::JID m_jid;
 

	
 
	private:
 
		long m_id;
 
// 		Swift::Presence::ref m_lastPresence;
 
		Swift::JID m_jid;
 
		BuddyFlag m_flags;
 
		RosterManager *m_rosterManager;
 
		Subscription m_subscription;
 
};
 

	
 
}
src/buddy.cpp
Show inline comments
 
@@ -6,101 +6,103 @@
 
 * This program is free software; you can redistribute it and/or modify
 
 * it under the terms of the GNU General Public License as published by
 
 * the Free Software Foundation; either version 2 of the License, or
 
 * (at your option) any later version.
 
 *
 
 * This program 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 General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 
 */
 

	
 
#include "transport/buddy.h"
 
#include "transport/rostermanager.h"
 
#include "transport/user.h"
 
#include "transport/transport.h"
 
#include "transport/BlockPayload.h"
 

	
 
namespace Transport {
 

	
 
Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager),
 
	m_subscription(Ask) {
 
// 	m_rosterManager->setBuddy(this);
 
}
 

	
 
Buddy::~Buddy() {
 
// 	m_rosterManager->unsetBuddy(this);
 
}
 

	
 
void Buddy::generateJID() {
 
	m_jid = Swift::JID();
 
	m_jid = Swift::JID(getSafeName(), m_rosterManager->getUser()->getComponent()->getJID().toString(), "bot");
 
}
 

	
 
void Buddy::setID(long id) {
 
	m_id = id;
 
}
 

	
 
long Buddy::getID() {
 
	return m_id;
 
}
 

	
 
void Buddy::setFlags(BuddyFlag flags) {
 
	m_flags = flags;
 

	
 
	if (!getSafeName().empty()) {
 
		try {
 
			generateJID();
 
		} catch (...) {
 
		}
 
	}
 
}
 

	
 
BuddyFlag Buddy::getFlags() {
 
	return m_flags;
 
}
 

	
 
const Swift::JID &Buddy::getJID() {
 
	if (!m_jid.isValid() || m_jid.getNode().empty()) {
 
		generateJID();
 
	}
 
	return m_jid;
 
}
 

	
 
void Buddy::setSubscription(Subscription subscription) {
 
	m_subscription = subscription;
 
}
 

	
 
Buddy::Subscription Buddy::getSubscription() {
 
	return m_subscription;
 
}
 

	
 
Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new) {
 
	std::string alias = getAlias();
 
	std::string name = getSafeName();
 

	
 
	Swift::StatusShow s;
 
	std::string statusMessage;
 
	if (!getStatus(s, statusMessage))
 
		return Swift::Presence::ref();
 

	
 
	if (m_jid.getNode().empty()) {
 
		generateJID();
 
	}
 

	
 
	Swift::Presence::ref presence = Swift::Presence::create();
 
 	presence->setFrom(m_jid);
 
	presence->setTo(m_rosterManager->getUser()->getJID().toBare());
 
	presence->setType(Swift::Presence::Available);
 

	
 
	if (!statusMessage.empty())
 
		presence->setStatus(statusMessage);
 

	
 
	if (s.getType() == Swift::StatusShow::None)
 
		presence->setType(Swift::Presence::Unavailable);
 
	presence->setShow(s.getType());
 

	
 
	if (presence->getType() != Swift::Presence::Unavailable) {
 
		// caps
 
		
src/localbuddy.cpp
Show inline comments
 
/**
 
 * XMPP - libpurple transport
 
 *
 
 * Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
 
 *
 
 * This program is free software; you can redistribute it and/or modify
 
 * it under the terms of the GNU General Public License as published by
 
 * the Free Software Foundation; either version 2 of the License, or
 
 * (at your option) any later version.
 
 *
 
 * This program 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 General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 
 */
 

	
 
#include "transport/localbuddy.h"
 
#include "transport/user.h"
 

	
 
namespace Transport {
 

	
 
LocalBuddy::LocalBuddy(RosterManager *rosterManager, long id) : Buddy(rosterManager, id) {
 
	m_status = Swift::StatusShow::None;
 
	m_firstSet = true;
 
}
 

	
 
LocalBuddy::~LocalBuddy() {
 
}
 

	
 
bool LocalBuddy::setName(const std::string &name) {
 
	if (name == m_name) {
 
		return true;
 
	}
 
	std::string oldName = name;
 
	m_name = name;
 
	try {
 
		generateJID();
 
		return true;
 
		return m_jid.isValid();
 
	} catch (...) {
 
		m_name = oldName;
 
		return false;
 
	}
 
}
 

	
 
void LocalBuddy::setAlias(const std::string &alias) {
 
//	if (m_firstSet) {
 
//		m_firstSet = false;
 
//		m_alias = alias;
 
//		return;
 
//	}
 
	bool changed = m_alias != alias;
 
	m_alias = alias;
 

	
 
	if (changed) {
 
		if (getRosterManager()->getUser()->getComponent()->inServerMode() || getRosterManager()->isRemoteRosterSupported()) {
 
			getRosterManager()->sendBuddyRosterPush(this);
 
		}
 
		getRosterManager()->storeBuddy(this);
 
	}
 
}
 

	
 
void LocalBuddy::setGroups(const std::vector<std::string> &groups) {
 
	bool changed = m_groups.size() != groups.size();
 
	if (!changed) {
 
		for (int i = 0; i != m_groups.size(); i++) {
 
			if (m_groups[i] != groups[i]) {
 
				changed = true;
 
				break;
 
			}
 
		}
 
	}
 

	
 
	m_groups = groups;
 
	if (changed) {
 
		if (getRosterManager()->getUser()->getComponent()->inServerMode() || getRosterManager()->isRemoteRosterSupported()) {
 
			getRosterManager()->sendBuddyRosterPush(this);
 
		}
 
		getRosterManager()->storeBuddy(this);
 
	}
 
}
 

	
 
}
src/networkpluginserver.cpp
Show inline comments
 
@@ -50,108 +50,108 @@
 
#include <Swiften/Elements/StreamInitiationFileInfo.h>
 

	
 
#ifdef _WIN32
 
#include "windows.h"
 
#include <stdint.h>
 
#else
 
#include "sys/wait.h"
 
#include "sys/signal.h"
 
#include "popt.h"
 
#endif
 

	
 
namespace Transport {
 

	
 
static unsigned long backend_id;
 
static unsigned long bytestream_id;
 

	
 
DEFINE_LOGGER(logger, "NetworkPluginServer");
 

	
 
class NetworkConversation : public Conversation {
 
	public:
 
		NetworkConversation(ConversationManager *conversationManager, const std::string &legacyName, bool muc = false) : Conversation(conversationManager, legacyName, muc) {
 
		}
 

	
 
		// Called when there's new message to legacy network from XMPP network
 
		void sendMessage(boost::shared_ptr<Swift::Message> &message) {
 
			onMessageToSend(this, message);
 
		}
 

	
 
		boost::signal<void (NetworkConversation *, boost::shared_ptr<Swift::Message> &)> onMessageToSend;
 
};
 

	
 
class NetworkFactory : public Factory {
 
	public:
 
		NetworkFactory(NetworkPluginServer *nps) {
 
			m_nps = nps;
 
		}
 

	
 
		// Creates new conversation (NetworkConversation in this case)
 
		Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) {
 
			NetworkConversation *nc = new NetworkConversation(conversationManager, legacyName);
 
			nc->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, m_nps, _1, _2));
 
			return nc;
 
		}
 

	
 
		// Creates new LocalBuddy
 
		Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) {
 
			LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id);
 
			buddy->setAlias(buddyInfo.alias);
 
			buddy->setFlags((BuddyFlag) (buddyInfo.flags));
 
			if (!buddy->setName(buddyInfo.legacyName)) {
 
				delete buddy;
 
				return NULL;
 
			}
 
			if (buddyInfo.subscription == "both") {
 
				buddy->setSubscription(Buddy::Both);
 
			}
 
			else {
 
				buddy->setSubscription(Buddy::Ask);
 
			}
 
			buddy->setGroups(buddyInfo.groups);
 
			buddy->setFlags((BuddyFlag) (buddyInfo.flags));
 
			if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end())
 
				buddy->setIconHash(buddyInfo.settings.find("icon_hash")->second.s);
 
			return buddy;
 
		}
 

	
 
	private:
 
		NetworkPluginServer *m_nps;
 
};
 

	
 
// Wraps google protobuf payload into WrapperMessage and serialize it to string
 
#define WRAP(MESSAGE, TYPE) 	pbnetwork::WrapperMessage wrap; \
 
	wrap.set_type(TYPE); \
 
	wrap.set_payload(MESSAGE); \
 
	wrap.SerializeToString(&MESSAGE);
 

	
 
// Executes new backend
 
static unsigned long exec_(std::string path, const char *host, const char *port, const char *config) {
 
	std::string original_path = path;
 
	// BACKEND_ID is replaced with unique ID. The ID is increasing for every backend.
 
	boost::replace_all(path, "BACKEND_ID", boost::lexical_cast<std::string>(backend_id++));
 

	
 
	// Add host and port.
 
	path += std::string(" --host ") + host + " --port " + port + " " + config;
 
	LOG4CXX_INFO(logger, "Starting new backend " << path);
 

	
 
#ifdef _WIN32
 
	STARTUPINFO         si;
 
	PROCESS_INFORMATION pi;
 

	
 
	ZeroMemory (&si, sizeof(si));
 
	si.cb=sizeof (si);
 

	
 
	if (! CreateProcess(
 
	NULL,
 
	(LPSTR)path.c_str(),         // command line
 
	0,                    // process attributes
 
	0,                    // thread attributes
 
	0,                    // inherit handles
 
	0,                    // creation flags
 
	0,                    // environment
 
	0,                    // cwd
 
	&si,
 
	&pi
 
	)
 
	)  {
 
		LOG4CXX_ERROR(logger, "Could not start process");
 
	}
 

	
src/rostermanager.cpp
Show inline comments
 
@@ -479,100 +479,102 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
 
					setBuddy(buddy);
 
					onBuddyAdded(buddy);
 
					response->setType(Swift::Presence::Subscribed);
 
					break;
 
				// buddy is already there, so nothing to do, just answer
 
				case Swift::Presence::Unsubscribe:
 
					response->setType(Swift::Presence::Unsubscribed);
 
// 					onBuddyRemoved(buddy);
 
					break;
 
				// just send response
 
				case Swift::Presence::Unsubscribed:
 
					response->setType(Swift::Presence::Unsubscribe);
 
					break;
 
				// just send response
 
				default:
 
					return;
 
			}
 
		}
 

	
 
		m_component->getStanzaChannel()->sendPresence(response);
 

	
 
		// We have to act as buddy and send its subscribe/unsubscribe just to be sure...
 
		switch (response->getType()) {
 
			case Swift::Presence::Unsubscribed:
 
				response->setType(Swift::Presence::Unsubscribe);
 
				m_component->getStanzaChannel()->sendPresence(response);
 
				break;
 
			case Swift::Presence::Subscribed:
 
				response->setType(Swift::Presence::Subscribe);
 
				m_component->getStanzaChannel()->sendPresence(response);
 
				break;
 
			default:
 
				break;
 
		}
 
	}
 
}
 

	
 
void RosterManager::setStorageBackend(StorageBackend *storageBackend) {
 
	if (m_rosterStorage || !storageBackend) {
 
		return;
 
	}
 
	RosterStorage *storage = new RosterStorage(m_user, storageBackend);
 

	
 
	std::list<BuddyInfo> roster;
 
	storageBackend->getBuddies(m_user->getUserInfo().id, roster);
 

	
 
	for (std::list<BuddyInfo>::const_iterator it = roster.begin(); it != roster.end(); it++) {
 
		Buddy *buddy = m_component->getFactory()->createBuddy(this, *it);
 
		if (buddy) {
 
			LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Adding cached buddy " << buddy->getName() << " fom database");
 
			m_buddies[buddy->getName()] = buddy;
 
			onBuddySet(buddy);
 
		}
 
	}
 

	
 
	m_rosterStorage = storage;
 
}
 

	
 
Swift::RosterPayload::ref RosterManager::generateRosterPayload() {
 
	Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
 

	
 
	for (std::map<std::string, Buddy *, std::less<std::string>, boost::pool_allocator< std::pair<std::string, Buddy *> > >::iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
 
		Buddy *buddy = (*it).second;
 
		if (!buddy) {
 
			continue;
 
		}
 
		Swift::RosterItemPayload item;
 
		item.setJID(buddy->getJID().toBare());
 
		item.setName(buddy->getAlias());
 
		item.setGroups(buddy->getGroups());
 
		item.setSubscription(Swift::RosterItemPayload::Both);
 
		payload->addItem(item);
 
	}
 
	return payload;
 
}
 

	
 
void RosterManager::sendCurrentPresences(const Swift::JID &to) {
 
	for (std::map<std::string, Buddy *, std::less<std::string>, boost::pool_allocator< std::pair<std::string, Buddy *> > >::iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
 
		Buddy *buddy = (*it).second;
 
		if (!buddy) {
 
			continue;
 
		}
 
		Swift::Presence::ref presence = buddy->generatePresenceStanza(255);
 
		if (presence) {
 
			presence->setTo(to);
 
			m_component->getStanzaChannel()->sendPresence(presence);
 
		}
 
	}
 
}
 

	
 
void RosterManager::sendCurrentPresence(const Swift::JID &from, const Swift::JID &to) {
 
	Buddy *buddy = getBuddy(Buddy::JIDToLegacyName(from));
 
	if (buddy) {
 
		Swift::Presence::ref presence = buddy->generatePresenceStanza(255);
 
		if (presence) {
 
			presence->setTo(to);
 
			m_component->getStanzaChannel()->sendPresence(presence);
 
		}
 
	}
 
	else {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo(to);
0 comments (0 inline, 0 general)