Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add random session tokens #4661

Closed
wants to merge 8 commits into from
Closed

Add random session tokens #4661

wants to merge 8 commits into from

Conversation

ranisalt
Copy link
Member

Pull Request Prelude

Changes Proposed

Currently we use a fixed session token that is insecure if sniffed, since it contains plaintext username and password, and vulnerable to replay attacks, although extremely unlikely.

Changing this to a random session token, without any account information, is both safer and integrates better with external tools, while also (slightly) improving game login performance, since there's no verification needed - 16 random bytes is enough that it can't be guessed.

This is not ready yet, I can't test it since I'm not on my PC and there are two disconnection messages that need fixing.

src/protocolgame.cpp Outdated Show resolved Hide resolved
@Zbizu
Copy link
Contributor

Zbizu commented Apr 28, 2024

will this be compatible with both legacy character list and weblogin? (both can be tested with otc)

@ranisalt
Copy link
Member Author

will this be compatible with both legacy character list and weblogin? (both can be tested with otc)

I won't touch the current protocol login (it's time to let go) but yes it should be with no worries

@EvilHero90
Copy link
Contributor

what's the status on this one?

@ranisalt
Copy link
Member Author

ranisalt commented May 1, 2024

what's the status on this one?

Still missing the login protocol part

@EvilHero90
Copy link
Contributor

I can understand from a logging pov that you would want to save those session tokens into database.
Wouldn't it make more sense tho instead of fetching them from database on each authentication to rather have them stored in a std::unordered_list<ip, token> and just check from there if it's valid? and if it's expired just remove it out of the list.
They're not really meant to be persistent data since they expire at some point, that's why I'm making that suggestion.

If you save them for the purpose that if the server would suffer from a crash, that they could just login back again without re authenticating then the same could be achieved by fetching all the valid tokens from database into the list again at server startup.

We could get rid of database transactions from authentication then, which I kinda consider the purpose of a token system.

@ranisalt
Copy link
Member Author

ranisalt commented May 4, 2024

They are persisted to work with external authentication (i.e. separate login server). If we don't persist, then we forbid all login servers (while ours doesn't exist)

@EvilHero90
Copy link
Contributor

They are persisted to work with external authentication (i.e. separate login server). If we don't persist, then we forbid all login servers (while ours doesn't exist)

makes sense, completly forgot that a web service or any other software keeps track of them aswell
anything else you want to change or is it up for review?

@ranisalt
Copy link
Member Author

ranisalt commented May 4, 2024

It's ready but I can't really test since there are no working clients for Linux 🤷

@@ -53,7 +53,7 @@ void ProtocolLogin::getCharacterList(const std::string& accountName, const std::
}

// Generate and add session key
static std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned char> rbe;
static std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned short> rbe;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: the standard says "the effect is undefined unless the parameter is cv-unqualified and is one of unsigned short, unsigned int, unsigned long, or unsigned long long."

GCC and Clang accept unsigned char, but MSVC refuses to compile with an error message.

output->addString(accountName + "\n" + password + "\n" + token + "\n" + std::to_string(ticks));
output->addString({sessionKey.data(), sessionKey.size()});

if (Database& db = Database::getInstance(); !db.executeQuery(fmt::format(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be async query?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then there is no guarantee when it'll be saved, could possible lead to players not beeing able to login because the session key was not saved (only case I could think of and probably very unlikely)

@ranisalt ranisalt mentioned this pull request May 26, 2024
3 tasks
@EvilHero90 EvilHero90 removed this from the 1.6 milestone May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants