void UserRegistry::isValidUserPassword(const Swift::JID& user, Swift::ServerFromClientSession *session, const Swift::SafeByteArray& password) { std::vector<std::string> const &x = CONFIG_VECTOR(config,"service.admin_jid"); if (std::find(x.begin(), x.end(), user.toBare().toString()) != x.end()) { if (Swift::safeByteArrayToString(password) == CONFIG_STRING(config, "service.admin_password")) { session->handlePasswordValid(); } else { session->handlePasswordInvalid(); } return; } std::string key = user.toBare().toString(); // Users try to connect twice if (users.find(key) != users.end()) { // Kill the first session LOG4CXX_INFO(logger, key << ": Removing previous session and making this one active"); Swift::ServerFromClientSession *tmp = users[key].session; users[key].session = session; tmp->handlePasswordInvalid(); } LOG4CXX_INFO(logger, key << ": Connecting this user to find if password is valid"); users[key].password = Swift::safeByteArrayToString(password); users[key].session = session; onConnectUser(user); return; }
bool RosterResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::RosterPayload> payload) { // Get means we're in server mode and user wants to fetch his roster. // For now we send empty reponse, but TODO: Get buddies from database and send proper stored roster. User *user = m_userManager->getUser(from.toBare().toString()); if (!user) { sendResponse(from, id, boost::shared_ptr<RosterPayload>(new RosterPayload())); LOG4CXX_WARN(logger, from.toBare().toString() << ": User is not logged in"); return true; } sendResponse(from, id, user->getRosterManager()->generateRosterPayload()); user->getRosterManager()->sendCurrentPresences(from); return true; }
void User::handleDiscoInfo(const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info) { LOG4CXX_INFO(logger, jid.toString() << ": got disco#info"); #ifdef SUPPORT_LEGACY_CAPS Swift::DiscoInfo::ref discoInfo = m_entityCapsManager->getCaps(jid); // This is old legacy cap which is not stored in entityCapsManager, // we have to store it in our user class. if (!discoInfo) { LOG4CXX_INFO(logger, jid.toString() << ": LEGACY"); m_legacyCaps[jid] = info; } #endif onConnectingTimeout(); }
void UserRegistry::onPasswordInvalid(const Swift::JID &user, const std::string &error) { std::string key = user.toBare().toString(); if (users.find(key) != users.end()) { LOG4CXX_INFO(logger, key << ": Password is invalid or there was an error when connecting the legacy network"); users[key].session->handlePasswordInvalid(error); users.erase(key); } }
void UserRegistry::onPasswordValid(const Swift::JID &user) { std::string key = user.toBare().toString(); if (users.find(key) != users.end()) { LOG4CXX_INFO(logger, key << ": Password is valid"); users[key].session->handlePasswordValid(); users.erase(key); } }
std::string Buddy::JIDToLegacyName(const Swift::JID &jid) { std::string name; if (jid.getUnescapedNode() == jid.getNode()) { name = jid.getNode(); if (name.find_last_of("%") != std::string::npos) { name.replace(name.find_last_of("%"), 1, "@"); // OK } } else { name = jid.getUnescapedNode(); // Psi sucks... // if (name.find_last_of("\\40") != std::string::npos) { // name.replace(name.find_last_of("\\40"), 1, "@"); // OK // } } return name; }
bool DiscoInfoResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> info) { // disco#info for transport if (to.getNode().empty()) { // Adhoc command if (m_commands.find(info->getNode()) != m_commands.end()) { boost::shared_ptr<DiscoInfo> res(new DiscoInfo()); res->addFeature("http://jabber.org/protocol/commands"); res->addFeature("jabber:x:data"); res->addIdentity(DiscoInfo::Identity(m_commands[info->getNode()], "automation", "command-node")); res->setNode(info->getNode()); sendResponse(from, to, id, res); } else if (info->getNode() == "http://jabber.org/protocol/commands") { boost::shared_ptr<DiscoInfo> res(new DiscoInfo()); res->addIdentity(DiscoInfo::Identity("Commands", "automation", "command-list")); res->setNode(info->getNode()); sendResponse(from, to, id, res); } else { if (!info->getNode().empty()) { sendError(from, id, ErrorPayload::ItemNotFound, ErrorPayload::Cancel); return true; } boost::shared_ptr<DiscoInfo> res(new DiscoInfo(m_transportInfo)); res->setNode(info->getNode()); sendResponse(from, id, res); } } // disco#info for room else if (m_rooms.find(to.toBare().toString()) != m_rooms.end()) { boost::shared_ptr<DiscoInfo> res(new DiscoInfo()); res->addIdentity(DiscoInfo::Identity(m_rooms[to.toBare().toString()], "conference", "text")); res->addFeature("http://jabber.org/protocol/muc"); res->setNode(info->getNode()); sendResponse(from, to, id, res); } // disco#info for buddy else { boost::shared_ptr<DiscoInfo> res(new DiscoInfo(*m_buddyInfo)); res->setNode(info->getNode()); sendResponse(from, to, id, res); } return true; }
SlackUser::SlackUser(const Swift::JID &jid, UserInfo &userInfo, Component *component, UserManager *userManager) : User(jid, userInfo, component, userManager) { m_jid = jid.toBare(); m_component = component; m_userManager = userManager; m_userInfo = userInfo; m_session = static_cast<SlackUserManager *>(userManager)->moveTempSession(m_jid.toString()); m_session->setUser(this); }
bool DiscoItemsResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoItems> info) { LOG4CXX_INFO(logger, "get request received with node " << info->getNode()); if (info->getNode() == "http://jabber.org/protocol/commands") { sendResponse(from, id, m_commands); } else if (to.getNode().empty()) { sendResponse(from, id, m_rooms); } else { sendResponse(from, id, boost::shared_ptr<DiscoItems>(new DiscoItems())); } return true; }
bool DiscoItemsResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Swift::DiscoItems> info) { LOG4CXX_INFO(logger, "get request received with node " << info->getNode()); if (info->getNode() == "http://jabber.org/protocol/commands") { sendResponse(from, id, m_commands); } else if (to.getNode().empty() && info->getNode().empty()) { XMPPUser *user = static_cast<XMPPUser *>(m_userManager->getUser(from.toBare().toString())); if (!user) { sendResponse(from, id, m_rooms); return true; } SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<DiscoItems> rooms = SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<DiscoItems>(new DiscoItems()); BOOST_FOREACH(const DiscoItems::Item &item, m_rooms->getItems()) { rooms->addItem(item); } BOOST_FOREACH(const DiscoItems::Item &item, user->getRoomList()->getItems()) { rooms->addItem(item); } sendResponse(from, id, rooms); }
void UserRegistry::stopLogin(const Swift::JID& user, Swift::ServerFromClientSession *session) { std::string key = user.toBare().toString(); if (users.find(key) != users.end()) { if (users[key].session == session) { LOG4CXX_INFO(logger, key << ": Stopping login process (user probably disconnected while logging in)"); users.erase(key); } else { LOG4CXX_WARN(logger, key << ": Stopping login process (user probably disconnected while logging in), but this is not active session"); } } // ::removeLater can be called only by libtransport, not by Swift and libtransport // takes care about user disconnecting itself, so don't call our signal. if (!m_inRemoveLater) onDisconnectUser(user); }
bool RosterResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::RosterPayload> payload) { sendResponse(from, id, boost::shared_ptr<RosterPayload>(new RosterPayload())); User *user = m_userManager->getUser(from.toBare().toString()); if (!user) { LOG4CXX_WARN(logger, from.toBare().toString() << ": User is not logged in"); return true; } if (payload->getItems().size() == 0) { LOG4CXX_WARN(logger, from.toBare().toString() << ": Roster push with no item"); return true; } Swift::RosterItemPayload item = payload->getItems()[0]; if (item.getJID().getNode().empty()) { return true; } Buddy *buddy = user->getRosterManager()->getBuddy(Buddy::JIDToLegacyName(item.getJID())); if (buddy) { if (item.getSubscription() == Swift::RosterItemPayload::Remove) { LOG4CXX_INFO(logger, from.toBare().toString() << ": Removing buddy " << buddy->getName()); onBuddyRemoved(buddy); // send roster push here Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, user->getJID().toBare(), user->getComponent()->getIQRouter()); request->send(); } else { LOG4CXX_INFO(logger, from.toBare().toString() << ": Updating buddy " << buddy->getName()); onBuddyUpdated(buddy, item); } } else if (item.getSubscription() != Swift::RosterItemPayload::Remove) { // Roster push for this new buddy is sent by RosterManager BuddyInfo buddyInfo; buddyInfo.id = -1; buddyInfo.alias = item.getName(); buddyInfo.legacyName = Buddy::JIDToLegacyName(item.getJID()); buddyInfo.subscription = "both"; buddyInfo.flags = Buddy::buddyFlagsFromJID(item.getJID()); LOG4CXX_INFO(logger, from.toBare().toString() << ": Adding buddy " << buddyInfo.legacyName); buddy = user->getComponent()->getFactory()->createBuddy(user->getRosterManager(), buddyInfo); user->getRosterManager()->setBuddy(buddy); onBuddyAdded(buddy, item); } return true; }
template<class Archive> void save(Archive& ar, const Swift::JID& jid, const unsigned int /*version*/) { std::string jidStr = jid.toString(); ar << jidStr; }
bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload) { if (CONFIG_STRING(m_config, "service.protocol") == "irc") { Swift::GetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify); return true; } std::string barejid = from.toBare().toString(); // AbstractUser *user = m_component->userManager()->getUserByJID(barejid); if (!CONFIG_BOOL(m_config,"registration.enable_public_registration")) { std::list<std::string> const &x = CONFIG_LIST(m_config,"service.allowed_servers"); if (std::find(x.begin(), x.end(), from.getDomain()) == x.end()) { // Log("UserRegistration", "This user has no permissions to register an account"); Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify); return true; } } UserInfo res; bool registered = m_storageBackend->getUser(barejid, res); std::string encoding; std::string language; Form::ref form = payload->getForm(); if (form) { const std::vector<FormField::ref> fields = form->getFields(); for (std::vector<FormField::ref>::const_iterator it = fields.begin(); it != fields.end(); it++) { TextSingleFormField::ref textSingle = boost::dynamic_pointer_cast<TextSingleFormField>(*it); if (textSingle) { if (textSingle->getName() == "username") { payload->setUsername(textSingle->getValue()); } else if (textSingle->getName() == "encoding") { encoding = textSingle->getValue(); } continue; } TextPrivateFormField::ref textPrivate = boost::dynamic_pointer_cast<TextPrivateFormField>(*it); if (textPrivate) { if (textPrivate->getName() == "password") { payload->setPassword(textPrivate->getValue()); } continue; } ListSingleFormField::ref listSingle = boost::dynamic_pointer_cast<ListSingleFormField>(*it); if (listSingle) { if (listSingle->getName() == "language") { language = listSingle->getValue(); } continue; } BooleanFormField::ref boolean = boost::dynamic_pointer_cast<BooleanFormField>(*it); if (boolean) { if (boolean->getName() == "unregister") { if (boolean->getValue()) { payload->setRemove(true); } } continue; } } } if (payload->isRemove()) { unregisterUser(barejid); Swift::SetResponder<Swift::InBandRegistrationPayload>::sendResponse(from, id, InBandRegistrationPayload::ref()); return true; } if (!payload->getUsername() || !payload->getPassword()) { Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify); return true; } // Register or change password if (payload->getUsername()->empty() || (payload->getPassword()->empty() && CONFIG_STRING(m_config, "service.protocol") != "twitter" && CONFIG_STRING(m_config, "service.protocol") != "bonjour") // || localization.getLanguages().find(language) == localization.getLanguages().end() ) { Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify); return true; } if (CONFIG_STRING(m_config, "service.protocol") == "xmpp") { // User tries to register himself. if ((Swift::JID(*payload->getUsername()).toBare() == from.toBare())) { Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify); return true; } // User tries to register someone who's already registered. UserInfo user_row; bool registered = m_storageBackend->getUser(Swift::JID(*payload->getUsername()).toBare().toString(), user_row); if (registered) { Swift::SetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify); return true; } } std::string username = *payload->getUsername(); // m_component->protocol()->prepareUsername(username); std::string newUsername(username); if (!CONFIG_STRING(m_config, "registration.username_mask").empty()) { newUsername = CONFIG_STRING(m_config, "registration.username_mask"); // replace(newUsername, "$username", username.c_str()); } // if (!m_component->protocol()->isValidUsername(newUsername)) { // Log("UserRegistration", "This is not valid username: "******"registration.reg_allowed_usernames").empty() && // !g_regex_match_simple(CONFIG_STRING(m_config, "registration.reg_allowed_usernames"), newUsername.c_str(),(GRegexCompileFlags) (G_REGEX_CASELESS | G_REGEX_EXTENDED), (GRegexMatchFlags) 0)) { // Log("UserRegistration", "This is not valid username: "******"UserRegistration", "changing user password: "******", " << username); res.jid = barejid; res.password = *payload->getPassword(); res.language = language; res.encoding = encoding; m_storageBackend->setUser(res); onUserUpdated(res); } Swift::SetResponder<Swift::InBandRegistrationPayload>::sendResponse(from, id, InBandRegistrationPayload::ref()); return true; }
bool UserRegistration::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload) { if (CONFIG_STRING(m_config, "service.protocol") == "irc") { Swift::GetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify); return true; } std::string barejid = from.toBare().toString(); // User *user = m_userManager->getUserByJID(barejid); if (!CONFIG_BOOL(m_config,"registration.enable_public_registration")) { std::list<std::string> const &x = CONFIG_LIST(m_config,"service.allowed_servers"); if (std::find(x.begin(), x.end(), from.getDomain()) == x.end()) { // Log("UserRegistration", "This user has no permissions to register an account"); Swift::GetResponder<Swift::InBandRegistrationPayload>::sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify); return true; } } // const char *_language = user ? user->getLang() : CONFIG_STRING(m_config, "registration.language").c_str(); boost::shared_ptr<InBandRegistrationPayload> reg(new InBandRegistrationPayload()); UserInfo res; bool registered = m_storageBackend->getUser(barejid, res); std::string instructions = CONFIG_STRING(m_config, "registration.instructions"); reg->setInstructions(instructions); reg->setRegistered(registered); reg->setUsername(res.uin); if (CONFIG_STRING(m_config, "service.protocol") != "twitter" && CONFIG_STRING(m_config, "service.protocol") != "bonjour") reg->setPassword(res.password); std::string usernameField = CONFIG_STRING(m_config, "registration.username_field"); Form::ref form(new Form(Form::FormType)); form->setTitle(tr(_language, _("Registration"))); form->setInstructions(tr(_language, instructions)); HiddenFormField::ref type = HiddenFormField::create(); type->setName("FORM_TYPE"); type->setValue("jabber:iq:register"); form->addField(type); TextSingleFormField::ref username = TextSingleFormField::create(); username->setName("username"); username->setLabel(tr(_language, usernameField)); username->setValue(res.uin); username->setRequired(true); form->addField(username); if (CONFIG_STRING(m_config, "service.protocol") != "twitter" && CONFIG_STRING(m_config, "service.protocol") != "bonjour") { TextPrivateFormField::ref password = TextPrivateFormField::create(); password->setName("password"); password->setLabel(tr(_language, _("Password"))); password->setRequired(true); form->addField(password); } ListSingleFormField::ref language = ListSingleFormField::create(); language->setName("language"); language->setLabel(tr(_language, _("Language"))); if (registered) language->setValue(res.language); else language->setValue(CONFIG_STRING(m_config, "registration.language")); // std::map <std::string, std::string> languages = localization.getLanguages(); // for (std::map <std::string, std::string>::iterator it = languages.begin(); it != languages.end(); it++) { // language->addOption(FormField::Option((*it).second, (*it).first)); // } form->addField(language); TextSingleFormField::ref encoding = TextSingleFormField::create(); encoding->setName("encoding"); encoding->setLabel(tr(_language, _("Encoding"))); if (registered) encoding->setValue(res.encoding); else encoding->setValue(CONFIG_STRING(m_config, "registration.encoding")); form->addField(encoding); if (registered) { BooleanFormField::ref boolean = BooleanFormField::create(); boolean->setName("unregister"); boolean->setLabel(tr(_language, _("Remove your registration"))); boolean->setValue(0); form->addField(boolean); } reg->setForm(form); Swift::GetResponder<Swift::InBandRegistrationPayload>::sendResponse(from, id, reg); return true; }
BuddyFlag Buddy::buddFlagsFromJID(const Swift::JID &jid) { if (jid.getUnescapedNode() == jid.getNode()) { return BUDDY_NO_FLAG; } return BUDDY_JID_ESCAPING; }