Skip to content

Commit 6b76656

Browse files
committed
Added option to block server admins who login with an unrecognized serial
1 parent b2227c3 commit 6b76656

15 files changed

+587
-26
lines changed

Server/mods/deathmatch/acl.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
<right name="command.whois" access="false"/>
8787
<right name="command.whowas" access="false"/>
8888
<right name="command.aclrequest" access="false" />
89+
<right name="command.authserial" access="false" />
8990
<right name="function.executeCommandHandler" access="false"/>
9091
<right name="function.setPlayerMuted" access="false"/>
9192
<right name="function.addAccount" access="false"/>
@@ -196,6 +197,7 @@
196197
<right name="command.srun" access="true"/>
197198
<right name="command.run" access="true"/>
198199
<right name="command.aclrequest" access="true" />
200+
<right name="command.authserial" access="true" />
199201
<right name="function.addBan" access="true"/>
200202
<right name="function.setUnbanTime" access="true"/>
201203
<right name="function.setBanAdmin" access="true"/>

Server/mods/deathmatch/logic/CAccount.cpp

Lines changed: 181 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,189 @@ void CAccount::RemoveData ( const std::string& strKey )
164164
}
165165

166166

167-
//////////////////////////////////////////////////////////////////////
167+
//
168+
// Authorized aerial stuff
169+
//
170+
// Account serial usage is only recorded for accounts that require serial authorization,
171+
// and is only loaded when required.
172+
void CAccount::EnsureLoadedSerialUsage( void )
173+
{
174+
if ( !m_bLoadedSerialUsage )
175+
{
176+
m_bLoadedSerialUsage = true;
177+
m_pManager->LoadAccountSerialUsage( this );
178+
}
179+
}
180+
181+
182+
bool CAccount::HasLoadedSerialUsage( void )
183+
{
184+
return m_bLoadedSerialUsage;
185+
}
186+
187+
188+
std::vector<CAccount::SSerialUsage>& CAccount::GetSerialUsageList( void )
189+
{
190+
EnsureLoadedSerialUsage();
191+
return m_SerialUsageList;
192+
}
193+
194+
195+
CAccount::SSerialUsage* CAccount::GetSerialUsage( const SString& strSerial )
196+
{
197+
EnsureLoadedSerialUsage();
198+
for ( auto& info : m_SerialUsageList )
199+
{
200+
if ( info.strSerial == strSerial )
201+
return &info;
202+
}
203+
return nullptr;
204+
}
205+
206+
//
207+
// Check if the supplied serial had been authorized for this account
208+
//
209+
bool CAccount::IsSerialAuthorized( const SString& strSerial )
210+
{
211+
SSerialUsage* pInfo = GetSerialUsage( strSerial );
212+
if ( pInfo )
213+
{
214+
return pInfo->IsAuthorized();
215+
}
216+
return false;
217+
}
218+
219+
//
220+
// Check if the supplied IP was last used by an authorized serial
221+
//
222+
bool CAccount::IsIpAuthorized( const SString& strIp )
223+
{
224+
EnsureLoadedSerialUsage();
225+
for ( auto& info : m_SerialUsageList )
226+
{
227+
if ( info.strLastLoginIp == strIp && info.IsAuthorized() )
228+
return true;
229+
}
230+
return false;
231+
}
232+
233+
//
234+
// Mark pending serial as authorized for this account
235+
//
236+
bool CAccount::AuthorizeSerial( const SString& strSerial, const SString& strWho )
237+
{
238+
SSerialUsage* pInfo = GetSerialUsage( strSerial );
239+
if ( pInfo )
240+
{
241+
if ( !pInfo->IsAuthorized() )
242+
{
243+
pInfo->tAuthDate = time( nullptr );
244+
pInfo->strAuthWho = strWho;
245+
m_pManager->MarkAsChanged( this );
246+
return true;
247+
}
248+
}
249+
return false;
250+
}
251+
252+
//
253+
// Unconditionally remove usage info for a serial
254+
//
255+
bool CAccount::RemoveSerial( const SString& strSerial )
256+
{
257+
EnsureLoadedSerialUsage();
258+
for ( auto iter = m_SerialUsageList.begin() ; iter != m_SerialUsageList.end() ; ++iter )
259+
{
260+
SSerialUsage& info = *iter;
261+
if ( info.strSerial == strSerial )
262+
{
263+
iter = m_SerialUsageList.erase( iter );
264+
m_pManager->MarkAsChanged( this );
265+
return true;
266+
}
267+
}
268+
return false;
269+
}
270+
271+
//
272+
// Cleanup unauthorized serials
273+
//
274+
void CAccount::RemoveUnauthorizedSerials( void )
275+
{
276+
EnsureLoadedSerialUsage();
277+
for ( auto iter = m_SerialUsageList.begin() ; iter != m_SerialUsageList.end() ; )
278+
{
279+
SSerialUsage& info = *iter;
280+
if ( !info.IsAuthorized() )
281+
iter = m_SerialUsageList.erase( iter );
282+
else
283+
++iter;
284+
}
285+
m_pManager->MarkAsChanged( this );
286+
}
287+
288+
//
289+
// If serial not already present, add for possible authorization
290+
//
291+
bool CAccount::AddSerialForAuthorization( const SString& strSerial, const SString& strIp )
292+
{
293+
SSerialUsage* pInfo = GetSerialUsage( strSerial );
294+
if ( !pInfo )
295+
{
296+
// Only one new serial at a time, so remove all other unauthorized serials for this account
297+
RemoveUnauthorizedSerials();
298+
299+
SSerialUsage info;
300+
info.strSerial = strSerial;
301+
info.strAddedIp = strIp;
302+
info.tAddedDate = time( nullptr );
303+
info.tAuthDate = 0;
304+
info.tLastLoginDate = 0;
305+
info.tLastLoginHttpDate = 0;
306+
307+
// First one doesn't require authorization
308+
if ( m_SerialUsageList.size() == 0 )
309+
{
310+
info.tAuthDate = time( nullptr );
311+
}
312+
m_SerialUsageList.push_back( info );
313+
m_pManager->MarkAsChanged( this );
314+
return true;
315+
}
316+
return false;
317+
}
318+
319+
//
168320
// Called when the player has successful logged in
169-
//////////////////////////////////////////////////////////////////////
170-
void CAccount::OnLoginSuccess ( const SString& strSerial, const SString& strIp )
321+
//
322+
void CAccount::OnLoginSuccess( const SString& strSerial, const SString& strIp )
171323
{
324+
SSerialUsage* pInfo = GetSerialUsage( strSerial );
325+
if ( pInfo )
326+
{
327+
pInfo->strLastLoginIp = strIp;
328+
pInfo->tLastLoginDate = time( nullptr );
329+
330+
// On successful login, delete all other unauthorized serials for this account
331+
RemoveUnauthorizedSerials();
332+
}
172333
m_strIP = strIp;
173334
m_strSerial = strSerial;
174-
m_pManager->MarkAsChanged ( this );
335+
m_pManager->MarkAsChanged( this );
336+
}
337+
338+
//
339+
// Called when the player has successful logged in via the http interface
340+
//
341+
void CAccount::OnLoginHttpSuccess( const SString& strIp )
342+
{
343+
EnsureLoadedSerialUsage();
344+
for ( auto& info : m_SerialUsageList )
345+
{
346+
if ( info.strLastLoginIp == strIp && info.IsAuthorized() )
347+
{
348+
info.tLastLoginHttpDate = time( nullptr );
349+
m_pManager->MarkAsChanged( this );
350+
}
351+
}
175352
}

Server/mods/deathmatch/logic/CAccount.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,27 @@ class CAccountData;
5353
class CAccount
5454
{
5555
public:
56+
struct SSerialUsage
57+
{
58+
SString strSerial;
59+
SString strAddedIp;
60+
time_t tAddedDate;
61+
SString strAuthWho;
62+
time_t tAuthDate;
63+
SString strLastLoginIp;
64+
time_t tLastLoginDate;
65+
time_t tLastLoginHttpDate;
66+
bool IsAuthorized ( void ) const { return tAuthDate != 0; }
67+
};
68+
5669
ZERO_ON_NEW
5770
CAccount ( class CAccountManager* pManager, EAccountType accountType, const std::string& strName, const std::string& strPassword = "", int iUserID = 0, const std::string& strIP = "", const std::string& strSerial = "" );
5871
~CAccount ( void );
5972

6073
bool IsRegistered ( void ) { return m_AccountType != EAccountType::Guest; }
6174
bool IsConsoleAccount ( void ) { return m_AccountType == EAccountType::Console; }
6275
void OnLoginSuccess ( const SString& strSerial, const SString& strIp );
76+
void OnLoginHttpSuccess ( const SString& strIp );
6377

6478
const SString& GetName ( void ) { return m_strName; }
6579
void SetName ( const std::string& strName );
@@ -72,6 +86,17 @@ class CAccount
7286
inline const std::string& GetSerial ( void ) { return m_strSerial; }
7387
inline int GetID ( void ) { return m_iUserID; }
7488

89+
bool HasLoadedSerialUsage ( void );
90+
void EnsureLoadedSerialUsage ( void );
91+
std::vector< SSerialUsage >& GetSerialUsageList ( void );
92+
SSerialUsage* GetSerialUsage ( const SString& strSerial );
93+
bool IsIpAuthorized ( const SString& strIp );
94+
bool IsSerialAuthorized ( const SString& strSerial );
95+
bool AddSerialForAuthorization ( const SString& strSerial, const SString& strIp );
96+
bool AuthorizeSerial ( const SString& strSerial, const SString& strWho );
97+
bool RemoveSerial ( const SString& strSerial );
98+
void RemoveUnauthorizedSerials ( void );
99+
75100
CClient* GetClient ( void ) { return m_pClient; }
76101
void SetClient ( CClient* pClient );
77102

@@ -97,6 +122,8 @@ class CAccount
97122
std::string m_strIP;
98123
std::string m_strSerial;
99124
int m_iUserID;
125+
bool m_bLoadedSerialUsage;
126+
std::vector< SSerialUsage > m_SerialUsageList;
100127

101128
bool m_bChanged;
102129

0 commit comments

Comments
 (0)