示例#1
0
void LoginHandler::guestLogin(const QString &username)
{
	if(_server->identityManager() && _server->identityManager()->isAuthorizedOnly()) {
		send("ERROR NOGUEST");
		_client->disconnectError("login error");
		return;
	}

	_client->setUsername(username);
	_state = WAIT_FOR_LOGIN;
	send("IDENTIFIED GUEST -");
	announceServerInfo();
}
示例#2
0
void LoginHandler::guestLogin(const QString &username)
{
	if(m_server->identityManager() && m_server->identityManager()->isAuthorizedOnly()) {
		sendError("noGuest", "Guest logins not allowed");
		return;
	}

	m_client->setUsername(username);
	m_state = WAIT_FOR_LOGIN;
	
	protocol::ServerReply identReply;
	identReply.type = protocol::ServerReply::RESULT;
	identReply.message = "Guest login OK!";
	identReply.reply["state"] = "identOk";
	identReply.reply["flags"] = QJsonArray();
	identReply.reply["ident"] = m_client->username();
	identReply.reply["guest"] = true;
	send(identReply);

	announceServerInfo();
}
示例#3
0
void LoginHandler::handleIdentMessage(const QString &message)
{
	const QRegularExpression re("\\IDENT \"([^\"]+)\"\\s*(?:;(.+))?\\z");
	auto m = re.match(message);
	if(!m.hasMatch()) {
		send("ERROR SYNTAX");
		_client->disconnectError("login error");
		return;
	}

	QString username = m.captured(1);
	QString password;
	if(m.lastCapturedIndex() == 2)
		password = m.captured(2);

	if(!validateUsername(username)) {
		send("ERROR BADNAME");
		_client->disconnectError("login error");
		return;
	}

	if(_server->identityManager()) {
		_state = WAIT_FOR_IDENTITYMANAGER_REPLY;
		IdentityResult *result = _server->identityManager()->checkLogin(username, password);
		connect(result, &IdentityResult::resultAvailable, [this, username, password](IdentityResult *result) {
			QString error;
			Q_ASSERT(result->status() != IdentityResult::INPROGRESS);
			switch(result->status()) {
			case IdentityResult::INPROGRESS: /* can't happen */ break;
			case IdentityResult::NOTFOUND:
				if(!_server->identityManager()->isAuthorizedOnly()) {
					guestLogin(username);
					break;
				}
				// fall through to badpass if guest logins are disabled
			case IdentityResult::BADPASS:
				if(password.isEmpty()) {
					// No password: tell client that guest login is not possible (for this username)
					_state = WAIT_FOR_IDENT;
					send("NEEDPASS");
					return;
				}
				error = "BADPASS";
				break;
			case IdentityResult::BANNED: error = "BANNED"; break;
			case IdentityResult::OK: {
				// Yay, username and password were valid!
				QString okstr = "IDENTIFIED USER ";
				if(result->flags().isEmpty())
					okstr += "-";
				else
					okstr += result->flags().join(",");

				if(validateUsername(result->canonicalName())) {
					_client->setUsername(result->canonicalName());

				} else {
					logger::warning() << "Identity manager gave us an invalid username:"******"MOD"));
				_hostPrivilege = result->flags().contains("HOST");
				_state = WAIT_FOR_LOGIN;
				send(okstr);
				announceServerInfo();
				} break;
			}

			if(!error.isEmpty()) {
				send("ERROR " + error);
				_client->disconnectError("login error");
			}
		});

	} else {
		if(!password.isNull()) {
			// if we have no identity manager, we can't accept passwords
			send("ERROR NOIDENT");
			_client->disconnectError("login error");
			return;
		}
		guestLogin(username);
	}
}
示例#4
0
void LoginHandler::handleIdentMessage(const protocol::ServerCommand &cmd)
{
	QString username, password;
	if(cmd.args.size()!=1 && cmd.args.size()!=2) {
		sendError("syntax", "Expected username and (optional) password");
		return;
	}

	username = cmd.args[0].toString();
	if(cmd.args.size()>1)
		password = cmd.args[1].toString();

	if(!validateUsername(username)) {
		sendError("badUsername", "Invalid username");
		return;
	}

	if(m_server->identityManager()) {
		m_state = WAIT_FOR_IDENTITYMANAGER_REPLY;
		IdentityResult *result = m_server->identityManager()->checkLogin(username, password);
		connect(result, &IdentityResult::resultAvailable, [this, username, password](IdentityResult *result) {
			QString errorcode, errorstr;
			Q_ASSERT(result->status() != IdentityResult::INPROGRESS);
			switch(result->status()) {
			case IdentityResult::INPROGRESS: /* can't happen */ break;
			case IdentityResult::NOTFOUND:
				if(!m_server->identityManager()->isAuthorizedOnly()) {
					guestLogin(username);
					break;
				}
				// fall through to badpass if guest logins are disabled
			case IdentityResult::BADPASS:
				if(password.isEmpty()) {
					// No password: tell client that guest login is not possible (for this username)
					m_state = WAIT_FOR_IDENT;

					protocol::ServerReply identReply;
					identReply.type = protocol::ServerReply::RESULT;
					identReply.message = "Password needed";
					identReply.reply["state"] = "needPassword";
					send(identReply);

					return;
				}
				errorcode = "badPassword";
				errorstr = "Incorrect password";
				break;

			case IdentityResult::BANNED:
				errorcode = "banned";
				errorstr = "This username is banned";
				break;

			case IdentityResult::OK: {
				// Yay, username and password were valid!
				if(validateUsername(result->canonicalName())) {
					m_client->setUsername(result->canonicalName());

				} else {
					logger::warning() << "Identity manager gave us an invalid username:"******"Authenticated login OK!";
				identReply.reply["state"] = "identOk";
				identReply.reply["flags"] = QJsonArray::fromStringList(result->flags());
				identReply.reply["ident"] = m_client->username();
				identReply.reply["guest"] = false;

				m_client->setAuthenticated(true);
				m_client->setModerator(result->flags().contains("MOD"));
				m_hostPrivilege = result->flags().contains("HOST");
				m_state = WAIT_FOR_LOGIN;

				send(identReply);
				announceServerInfo();
				} break;
			}

			if(!errorcode.isEmpty()) {
				sendError(errorcode, errorstr);
			}
		});

	} else {
		if(!password.isNull()) {
			// if we have no identity manager, we can't accept passwords
			sendError("noIdent", "This is a guest-only server");
			return;
		}
		guestLogin(username);
	}
}