[core, sql, auth] Trust Tokens - Remember this computer for X days 2FA#9418
Conversation
|
✨ Hello and thanks for the PR! ✨ 🤖: This is a friendly automated reminder that the maintainers won't look at your PR until you've properly completed all of the checkboxes in the pre-filled template. |
ca81448 to
679c41b
Compare
970bbba to
fea46b5
Compare
| LOGIN_ERROR_TRUST_TOKEN_INVALID = 0x13, | ||
| }; | ||
|
|
||
| constexpr std::array<uint8, 3> SupportedXiloaderVersion = { 2, 0, 0 }; |
There was a problem hiding this comment.
I imagine this will need to be bumped in tandem with the xiloader PR, but I wanted to get direction from everyone on whether it should be a major, minor, or patch bump
There was a problem hiding this comment.
Technically, if the server end updates we don't need to force support the new xiloader version. But the client may be mismatched, but that's a server distribution problem. I'll have to think about this a bit
There was a problem hiding this comment.
I tested old xiloader and it's forwards compatible with this build of xi_map, so no need to change this
fea46b5 to
b382f9f
Compare
Xaver-DaRed
left a comment
There was a problem hiding this comment.
Approving out of "I am not opposed to this functionality"
However, WinterSolstice And Zach should review this properly
|
I have pulled this down and tested it. xiloader 2.0.1 is forwards compatible with this |
I affirm:
What does this pull request do?
Summary
When a user has TOTP enabled, they currently have to enter a one-time code on every login. This adds trust tokens so a client can send
"trust_this_computer": truealong with a valid OTP login, receive back atrust_tokenin the response, and use that token on future logins to skip the OTP prompt for 30 days (server configurable).What changed
sql/accounts_trust_tokens.sql- New table storing hashed trust tokens per account with an expiration timestamp. Foreign key onaccidwithON DELETE CASCADE.src/login/otp_helpers.h- New helper functions:generateTrustToken()- 32 random bytes via OpenSSLRAND_bytes, returned as hexhashTrustToken()- SHA-256 hash before storing (raw token never hits the DB)saveTrustToken()- cleans expired tokens for the account, inserts new one with 30-day expiryvalidateTrustToken()- cleans expired tokens, checks if hashed token exists for the accountremoveAllTrustTokens()- wipes all tokens for an account (called on password change and TOTP removal)doesAccountNeedOTP(uint32 accid, ...)overload that takes an account ID directly instead of looking it up by username againsrc/login/auth_session.cpp- Login flow changes:validatePassword()now returnsstd::optional<std::pair<uint32, uint32>>(account ID + status) instead ofbool, eliminating a redundant second DB query that fetched the same infotrust_tokenandtrust_this_computerfrom the JSON payloadtrust_this_computer == trueand a verified OTP, a new trust token is generated and returned in the response JSONremoveAllTrustTokens()to invalidate all trusted devicessendLoginResultno longer takes an unusedlenparametersrc/login/auth_session.h- Signature change forvalidatePassword.Security notes
Dependencies
LandSandBoat/xiloader#46
Steps to test these changes
Prerequisites: A running LSB server with the
accounts_trust_tokenstable created, and an account with TOTP enabled.trust_this_computer. Login succeeds and notrust_tokenis in the response."trust_this_computer": true. Login succeeds and response JSON contains atrust_token(64 hex chars). A row exists inaccounts_trust_tokenswithexpires~30 days out.trust_tokenfrom above, no OTP code. Login succeeds.trust_tokenfails.accounts_trust_tokensshould be empty for that account.otpVerifiedis settruewhen the account requires OTP regardless of whether the user authenticated via trust token or direct TOTP code. Confirm satchel size query still runs.Screenshots of xiloader
New [ ] Trust this computer option
Successful login with trust, shows message specifying how long it is trusted for (server specific, falls back to 30 days)
Example of a trusted computer (Dynamically updates when username changes)
Bogus token auto revoke
Revoke Trust option