Windows: Remember session cookie, bypasses MFA when logged in from same device

This commit is contained in:
UnknownShadow200 2020-12-30 20:04:56 +11:00
parent 8f888c0589
commit 3c3664b9cf
9 changed files with 56 additions and 10 deletions

View File

@ -924,7 +924,7 @@ static void MainScreen_TickGetToken(struct MainScreen* s) {
return; return;
} }
if (String_CaselessEquals(&GetTokenTask.username, &s->iptUsername.text)) { if (!GetTokenTask.error && String_CaselessEquals(&GetTokenTask.username, &s->iptUsername.text)) {
/* Already logged in, go straight to fetching servers */ /* Already logged in, go straight to fetching servers */
MainScreen_LoginPhase2(s, &GetTokenTask.username); MainScreen_LoginPhase2(s, &GetTokenTask.username);
} else { } else {

View File

@ -9,6 +9,8 @@
#include "Options.h" #include "Options.h"
#include "PackedCol.h" #include "PackedCol.h"
#include "Errors.h" #include "Errors.h"
#include "Game.h"
#include "Utils.h"
/*########################################################################################################################* /*########################################################################################################################*
*----------------------------------------------------------JSON-----------------------------------------------------------* *----------------------------------------------------------JSON-----------------------------------------------------------*
@ -239,6 +241,8 @@ static void GetTokenTask_OnValue(struct JsonContext* ctx, const cc_string* str)
String_Copy(&GetTokenTask.token, str); String_Copy(&GetTokenTask.token, str);
} else if (String_CaselessEqualsConst(&ctx->curKey, "username")) { } else if (String_CaselessEqualsConst(&ctx->curKey, "username")) {
String_Copy(&GetTokenTask.username, str); String_Copy(&GetTokenTask.username, str);
} else if (String_CaselessEqualsConst(&ctx->curKey, "errors")) {
if (str->length) GetTokenTask.error = true;
} }
} }
@ -255,6 +259,7 @@ void GetTokenTask_Run(void) {
LWebTask_Reset(&GetTokenTask.Base); LWebTask_Reset(&GetTokenTask.Base);
String_InitArray(GetTokenTask.token, tokenBuffer); String_InitArray(GetTokenTask.token, tokenBuffer);
String_InitArray(GetTokenTask.username, userBuffer); String_InitArray(GetTokenTask.username, userBuffer);
GetTokenTask.error = false;
GetTokenTask.Base.Handle = GetTokenTask_Handle; GetTokenTask.Base.Handle = GetTokenTask_Handle;
GetTokenTask.Base.reqID = Http_AsyncGetDataEx(&url, false, NULL, NULL, &ccCookies); GetTokenTask.Base.reqID = Http_AsyncGetDataEx(&url, false, NULL, NULL, &ccCookies);
@ -416,6 +421,7 @@ static void FetchServersTask_Handle(cc_uint8* data, cc_uint32 len) {
int count; int count;
Mem_Free(FetchServersTask.servers); Mem_Free(FetchServersTask.servers);
Mem_Free(FetchServersTask.orders); Mem_Free(FetchServersTask.orders);
Session_Save();
FetchServersTask.numServers = 0; FetchServersTask.numServers = 0;
FetchServersTask.servers = NULL; FetchServersTask.servers = NULL;
@ -533,7 +539,7 @@ void FetchUpdateTask_Run(cc_bool release, cc_bool d3d9) {
/*########################################################################################################################* /*########################################################################################################################*
*-----------------------------------------------------FetchFlagsTask-----------------------------------------------------* *-----------------------------------------------------FetchFlagsTask------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
struct FetchFlagsData FetchFlagsTask; struct FetchFlagsData FetchFlagsTask;
static int flagsCount, flagsCapacity; static int flagsCount, flagsCapacity;
@ -639,4 +645,32 @@ void Flags_Free(void) {
flagsCount = 0; flagsCount = 0;
FetchFlagsTask.count = 0; FetchFlagsTask.count = 0;
} }
/*########################################################################################################################*
*------------------------------------------------------Session cache------------------------------------------------------*
*#########################################################################################################################*/
static cc_string sessionKey = String_FromConst("session");
static cc_bool loadedSession;
void Session_Load(void) {
cc_string session; char buffer[3072];
if (loadedSession) return;
loadedSession = true;
/* Increase from max 512 to 2048 per entry */
StringsBuffer_SetLengthBits(&ccCookies, 11);
String_InitArray(session, buffer);
Options_GetSecure(LOPT_SESSION, &session, &Game_Username);
if (!session.length) return;
EntryList_Set(&ccCookies, &sessionKey, &session, '=');
}
void Session_Save(void) {
#ifdef CC_BUILD_WIN
cc_string session = EntryList_UNSAFE_Get(&ccCookies, &sessionKey, '=');
if (!session.length) return;
Options_SetSecure(LOPT_SESSION, &session, &Game_Username);
#endif
}
#endif #endif

View File

@ -59,6 +59,7 @@ extern struct GetTokenTaskData {
struct LWebTask Base; struct LWebTask Base;
cc_string token; /* Random CSRF token for logging in. */ cc_string token; /* Random CSRF token for logging in. */
cc_string username; /* Username if session is already logged in. */ cc_string username; /* Username if session is already logged in. */
cc_bool error; /* Whether a signin error occurred */
} GetTokenTask; } GetTokenTask;
void GetTokenTask_Run(void); void GetTokenTask_Run(void);
@ -118,4 +119,7 @@ void FetchFlagsTask_Add(const struct ServerInfo* server);
struct Bitmap* Flags_Get(const struct ServerInfo* server); struct Bitmap* Flags_Get(const struct ServerInfo* server);
/* Frees all flag bitmaps. */ /* Frees all flag bitmaps. */
void Flags_Free(void); void Flags_Free(void);
void Session_Load(void);
void Session_Save(void);
#endif #endif

View File

@ -299,6 +299,8 @@ void Launcher_Run(void) {
Drawer2D_BlackTextShadows = true; Drawer2D_BlackTextShadows = true;
InitFramebuffer(); InitFramebuffer();
Options_UNSAFE_Get("launcher-cc-username", &Game_Username);
Session_Load();
Launcher_LoadSkin(); Launcher_LoadSkin();
Launcher_Init(); Launcher_Init();
Launcher_TryLoadTexturePack(); Launcher_TryLoadTexturePack();

View File

@ -33,6 +33,8 @@ static cc_bool Options_LoadFilter(const cc_string* entry) {
} }
void Options_Load(void) { void Options_Load(void) {
/* Increase from max 512 to 2048 per entry */
StringsBuffer_SetLengthBits(&Options, 11);
EntryList_Load(&Options, "options-default.txt", '=', NULL); EntryList_Load(&Options, "options-default.txt", '=', NULL);
EntryList_Load(&Options, "options.txt", '=', NULL); EntryList_Load(&Options, "options.txt", '=', NULL);
} }

View File

@ -72,6 +72,8 @@
#define OPT_TOUCH_SCALE "gui-touchscale" #define OPT_TOUCH_SCALE "gui-touchscale"
#define OPT_HTTP_ONLY "http-no-https" #define OPT_HTTP_ONLY "http-no-https"
#define LOPT_SESSION "launcher-session"
struct StringsBuffer; struct StringsBuffer;
extern struct StringsBuffer Options; extern struct StringsBuffer Options;
/* Frees any memory allocated in storing options. */ /* Frees any memory allocated in storing options. */

View File

@ -756,7 +756,6 @@ cc_bool Convert_ParseBool(const cc_string* str, cc_bool* value) {
*------------------------------------------------------StringsBuffer------------------------------------------------------* *------------------------------------------------------StringsBuffer------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
#define STRINGSBUFFER_BUFFER_EXPAND_SIZE 8192 #define STRINGSBUFFER_BUFFER_EXPAND_SIZE 8192
#define STRINGSBUFFER_DEFAULT_LEN_SHIFT 9
#define StringsBuffer_GetOffset(raw) ((raw) >> buffer->_lenShift) #define StringsBuffer_GetOffset(raw) ((raw) >> buffer->_lenShift)
#define StringsBuffer_GetLength(raw) ((raw) & buffer->_lenMask) #define StringsBuffer_GetLength(raw) ((raw) & buffer->_lenMask)
@ -771,7 +770,7 @@ CC_NOINLINE static void StringsBuffer_Init(struct StringsBuffer* buffer) {
buffer->_flagsCapacity = STRINGSBUFFER_FLAGS_DEF_ELEMS; buffer->_flagsCapacity = STRINGSBUFFER_FLAGS_DEF_ELEMS;
if (buffer->_lenShift) return; if (buffer->_lenShift) return;
StringsBuffer_SetLengthBits(buffer, STRINGSBUFFER_DEFAULT_LEN_SHIFT); StringsBuffer_SetLengthBits(buffer, STRINGSBUFFER_DEF_LEN_SHIFT);
} }
void StringsBuffer_SetLengthBits(struct StringsBuffer* buffer, int bits) { void StringsBuffer_SetLengthBits(struct StringsBuffer* buffer, int bits) {

View File

@ -207,7 +207,8 @@ CC_API cc_bool Convert_ParseBool(const cc_string* str, cc_bool* value);
#define STRINGSBUFFER_BUFFER_DEF_SIZE 4096 #define STRINGSBUFFER_BUFFER_DEF_SIZE 4096
#define STRINGSBUFFER_FLAGS_DEF_ELEMS 256 #define STRINGSBUFFER_FLAGS_DEF_ELEMS 256
#define STRINGSBUFFER_LEN_MASK 0x1FFUL #define STRINGSBUFFER_DEF_LEN_SHIFT 9
#define STRINGSBUFFER_DEF_LEN_MASK 0x1FFUL
struct StringsBuffer { struct StringsBuffer {
char* textBuffer; /* Raw characters of all entries */ char* textBuffer; /* Raw characters of all entries */
@ -223,6 +224,8 @@ struct StringsBuffer {
int _lenMask; int _lenMask;
}; };
/* Sets the number of bits in an entry's flags that are used to store its length. */
/* (e.g. if bits is 9, then the maximum length of an entry is 2^9-1 = 511) */
void StringsBuffer_SetLengthBits(struct StringsBuffer* buffer, int bits); void StringsBuffer_SetLengthBits(struct StringsBuffer* buffer, int bits);
/* Resets counts to 0, and frees any allocated memory. */ /* Resets counts to 0, and frees any allocated memory. */
CC_NOINLINE void StringsBuffer_Clear(struct StringsBuffer* buffer); CC_NOINLINE void StringsBuffer_Clear(struct StringsBuffer* buffer);

View File

@ -225,16 +225,16 @@ int Convert_FromBase64(const char* src, int len, cc_uint8* dst) {
*#########################################################################################################################*/ *#########################################################################################################################*/
void EntryList_Load(struct StringsBuffer* list, const char* file, char separator, EntryList_Filter filter) { void EntryList_Load(struct StringsBuffer* list, const char* file, char separator, EntryList_Filter filter) {
cc_string entry; char entryBuffer[768]; cc_string entry; char entryBuffer[768];
cc_string path; char pathBuffer[FILENAME_SIZE]; cc_string path;
cc_string key, value; cc_string key, value;
int lineLen; int lineLen, maxLen;
cc_uint8 buffer[2048]; cc_uint8 buffer[2048];
struct Stream stream, buffered; struct Stream stream, buffered;
cc_result res; cc_result res;
String_InitArray(path, pathBuffer); path = String_FromReadonly(file);
String_AppendConst(&path, file); maxLen = list->_lenMask ? list->_lenMask : STRINGSBUFFER_DEF_LEN_MASK;
res = Stream_OpenFile(&stream, &path); res = Stream_OpenFile(&stream, &path);
if (res == ReturnCode_FileNotFound) return; if (res == ReturnCode_FileNotFound) return;
@ -258,7 +258,7 @@ void EntryList_Load(struct StringsBuffer* list, const char* file, char separator
/* Sometimes file becomes corrupted and replaced with NULL */ /* Sometimes file becomes corrupted and replaced with NULL */
/* If don't prevent this here, client aborts in StringsBuffer_Add */ /* If don't prevent this here, client aborts in StringsBuffer_Add */
if (entry.length > STRINGSBUFFER_LEN_MASK) { if (entry.length > maxLen) {
lineLen = entry.length; lineLen = entry.length;
entry.length = 0; entry.length = 0;
String_Format2(&entry, "Skipping very long (%i characters) line in %c, file may be corrupted", &lineLen, file); String_Format2(&entry, "Skipping very long (%i characters) line in %c, file may be corrupted", &lineLen, file);