@@ -208,64 +208,97 @@ ResponseCode CHTTPD::RequestLogin(HttpRequest* ipoHttpRequest, HttpResponse* ipo
208
208
209
209
CAccount* CHTTPD::CheckAuthentication (HttpRequest* ipoHttpRequest)
210
210
{
211
- string authorization = ipoHttpRequest->oRequestHeaders [" authorization" ];
212
- if (authorization.length () > 6 )
211
+ const std::string strAuthorization = ipoHttpRequest->oRequestHeaders [" authorization" ];
212
+
213
+ if (strAuthorization.length () < 7 || strAuthorization.substr (0 , 6 ) != " Basic " )
214
+ {
215
+ return m_pGuestAccount;
216
+ }
217
+
218
+ const std::string strAddress = ipoHttpRequest->GetAddress ();
219
+ const char * szAddress = strAddress.c_str ();
220
+ const bool bIsFlooding = m_BruteForceProtect.IsFlooding (szAddress);
221
+
222
+ // Basic auth
223
+ SString strAuthName, strAuthPassword;
224
+
225
+ // If we're not flooding, or authorization header value isn't crazy long, let's parse it to get the username for console logs
226
+ if (!bIsFlooding || strAuthorization.length () < 768 )
213
227
{
214
- if (authorization.substr (0 , 6 ) == " Basic " )
228
+ SString strAuthDecoded = SharedUtil::Base64decode (strAuthorization.substr (6 ));
229
+ strAuthDecoded.Split (" :" , &strAuthName, &strAuthPassword);
230
+ }
231
+
232
+ if (bIsFlooding)
233
+ {
234
+ if (strAuthName.length () > 0 )
215
235
{
216
- // Basic auth
217
- SString strAuthDecoded = SharedUtil::Base64decode (authorization.substr (6 ));
236
+ CLogger::AuthPrintf (" HTTP: Ignoring login attempt for user '%s' from %s\n " , strAuthName.substr (0 , CAccountManager::MAX_USERNAME_LENGTH).c_str (),
237
+ szAddress);
238
+ }
239
+ else
240
+ {
241
+ CLogger::AuthPrintf (" HTTP: Ignoring login attempt from %s\n " , szAddress);
242
+ }
218
243
219
- SString authName, authPassword ;
220
- strAuthDecoded. Split ( " : " , &authName, &authPassword);
244
+ return m_pGuestAccount ;
245
+ }
221
246
222
- if (m_BruteForceProtect.IsFlooding (ipoHttpRequest->GetAddress ().c_str ()))
223
- {
224
- CLogger::AuthPrintf (" HTTP: Ignoring login attempt for user '%s' from %s\n " , authName.c_str (), ipoHttpRequest->GetAddress ().c_str ());
225
- return m_pGuestAccount;
226
- }
247
+ if (strAuthName.length () < CAccountManager::MIN_USERNAME_LENGTH || strAuthName.length () > CAccountManager::MAX_USERNAME_LENGTH ||
248
+ strAuthPassword.length () < MIN_PASSWORD_LENGTH)
249
+ {
250
+ m_BruteForceProtect.AddConnect (szAddress);
227
251
228
- CAccount* account = g_pGame->GetAccountManager ()->Get (authName.c_str ());
229
- if (account)
252
+ CLogger::AuthPrintf (" HTTP: Failed login attempt from %s (bad login)\n " , szAddress);
253
+
254
+ return m_pGuestAccount;
255
+ }
256
+
257
+ if (CAccount* pAccount = g_pGame->GetAccountManager ()->Get (strAuthName.c_str ()); pAccount)
258
+ {
259
+ bool bSkipIpCheck;
260
+
261
+ // Check that the password is right
262
+ if (pAccount->IsPassword (strAuthPassword, &bSkipIpCheck))
263
+ {
264
+ // Check that it isn't the Console account
265
+ if (pAccount->GetName () != CONSOLE_ACCOUNT_NAME)
230
266
{
231
- // Check that the password is right
232
- bool bSkipIpCheck;
233
- if (account->IsPassword (authPassword.c_str (), &bSkipIpCheck))
267
+ // Do IP check if required
268
+ if (!bSkipIpCheck && !g_pGame->GetAccountManager ()->IsHttpLoginAllowed (pAccount, strAddress))
234
269
{
235
- // Check that it isn't the Console account
236
- std::string strAccountName = account->GetName ();
237
- if (strAccountName.compare (CONSOLE_ACCOUNT_NAME) != 0 )
270
+ if (m_WarnMessageTimer.Get () > 8000 || m_strWarnMessageForIp != strAddress)
238
271
{
239
- // Do IP check if required
240
- if (!bSkipIpCheck && !g_pGame->GetAccountManager ()->IsHttpLoginAllowed (account, ipoHttpRequest->GetAddress ()))
241
- {
242
- if (m_WarnMessageTimer.Get () > 8000 || m_strWarnMessageForIp != ipoHttpRequest->GetAddress ())
243
- {
244
- m_strWarnMessageForIp = ipoHttpRequest->GetAddress ();
245
- m_WarnMessageTimer.Reset ();
246
- }
247
- CLogger::AuthPrintf (" HTTP: Failed login for user '%s' because %s not associated with authorized serial\n " , authName.c_str (),
248
- ipoHttpRequest->GetAddress ().c_str ());
249
- return m_pGuestAccount;
250
- }
251
-
252
- // Handle initial login logging
253
- std::lock_guard<std::mutex> guard (m_mutexLoggedInMap);
254
- if (m_LoggedInMap.find (authName) == m_LoggedInMap.end ())
255
- CLogger::AuthPrintf (" HTTP: '%s' entered correct password from %s\n " , authName.c_str (), ipoHttpRequest->GetAddress ().c_str ());
256
- m_LoggedInMap[authName] = GetTickCount64_ ();
257
- account->OnLoginHttpSuccess (ipoHttpRequest->GetAddress ());
258
- return account;
272
+ m_strWarnMessageForIp = strAddress;
273
+ m_WarnMessageTimer.Reset ();
259
274
}
275
+
276
+ CLogger::AuthPrintf (" HTTP: Failed login for user '%s' because %s not associated with authorized serial\n " , strAuthName.c_str (), szAddress);
277
+
278
+ return m_pGuestAccount;
260
279
}
261
- }
262
- if (authName.length () > 0 )
263
- {
264
- m_BruteForceProtect.AddConnect (ipoHttpRequest->GetAddress ().c_str ());
265
- CLogger::AuthPrintf (" HTTP: Failed login attempt for user '%s' from %s\n " , authName.c_str (), ipoHttpRequest->GetAddress ().c_str ());
280
+
281
+ // Handle initial login logging
282
+ std::lock_guard guard (m_mutexLoggedInMap);
283
+
284
+ if (m_LoggedInMap.find (strAuthName) == m_LoggedInMap.end ())
285
+ {
286
+ CLogger::AuthPrintf (" HTTP: '%s' entered correct password from %s\n " , strAuthName.c_str (), szAddress);
287
+ }
288
+
289
+ m_LoggedInMap[strAuthName] = GetTickCount64_ ();
290
+
291
+ pAccount->OnLoginHttpSuccess (strAddress);
292
+
293
+ return pAccount;
266
294
}
267
295
}
268
296
}
297
+
298
+ m_BruteForceProtect.AddConnect (szAddress);
299
+
300
+ CLogger::AuthPrintf (" HTTP: Failed login attempt for user '%s' from %s\n " , strAuthName.c_str (), szAddress);
301
+
269
302
return m_pGuestAccount;
270
303
}
271
304
0 commit comments