![]() |
Crossfire Server, Trunk
1.75.0
|
#include <set>
#include "global.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "object.h"
#include "sproto.h"
#include "output_file.h"
Go to the source code of this file.
Data Structures | |
struct | account_struct |
Structure that holds account data. More... | |
Macros | |
#define | ACCOUNT_FILE "accounts" |
Name of the accounts file. More... | |
#define | NUM_ACCOUNT_FIELDS 6 |
Number of fields in the accounts file. More... | |
Functions | |
static account_struct * | account_alloc () |
Allocate a new account_struct item. More... | |
int | account_change_password (const char *account_name, const char *current_password, const char *new_password) |
Change an account password. More... | |
int | account_check_string (const char *str) |
Checks a string to make sure it does not have any invalid characters. More... | |
const char * | account_exists (const char *account_name) |
Checks the existing accounts, and see if this account exists. More... | |
const char * | account_get_account_for_char (const char *charname) |
This looks at all the accounts and sees if charname is associated with any of them. More... | |
linked_char * | account_get_additional_chars (const char *account_name, const Account_Chars *chars, int *count) |
Get a list of character names linked to the specified account which are not listed in chars. More... | |
char ** | account_get_players_for_account (const char *account_name) |
Returns an array of strings for the characters on this account - the array is null terminated. More... | |
int | account_is_logged_in (const char *name) |
This checkes if an account is logged in. More... | |
int | account_link (const char *account_name, const char *player_name) |
Adds a player name to an account. More... | |
int | account_login (const char *account_name, const char *account_password) |
Check if the given account exists, and whether the password is correct. More... | |
void | account_logout (const char *account_name) |
Remove 'account_name' from the list of logged in accounts. More... | |
int | account_new (const char *account_name, const char *account_password) |
Adds an account. More... | |
int | account_remove_player (const char *account_name, const char *player_name) |
Removes a player name from an account. More... | |
static void | account_write_entry (FILE *fp, account_struct *ac) |
This writes a single account entry to the given filepointer. More... | |
void | accounts_clear (void) |
This is used purely by the test harness - by clearing the accounts, it can then verify that the data is added is loaded back into memory properly. More... | |
void | accounts_load (void) |
This loads all the account entries into memory. More... | |
void | accounts_save (void) |
Save all the account information. More... | |
static int | char_in_list (const char *name, const std::vector< Account_Char * > chars) |
Check if a character name is in a list or not. More... | |
static void | ensure_available_characters (account_struct *account, int count) |
Ensure an account can handle at least the specified count of character names. More... | |
Variables | |
static std::vector< account_struct * > | accounts |
list of all accounts. More... | |
static int | accounts_loaded = 0 |
Whether the account information was loaded or not. More... | |
static std::set< std::string > | accounts_logged_in = std::set<std::string>() |
Set of accounts names that are currently logged in. More... | |
This file contains account management logic - creation, deletion, log in verification, as well as associating player files with the account.
The code in this file mostly assumes that the number of account operations will be low - for example, we load up all acounts in a linked list, and save them all out. If we have 10,000 accounts, this would be very slow. But for a few hundred accounts, should be plenty fast on most any hardware.
Likewise, the account structure is not exposed outside this file - this means that account access/updates is done through the account name. This adds some extra overhead in that code has to search the linked list, but for a relatively low number of entries, and relatively infrequent updates, this should not be much of an issue.
Since the accounts file is updated in several places in this file, it is documented here. The file is a list of accounts, one line per account, with fields separted by colons, eg:
Account name:Password:Account last used:Characters (semicolon separated):expansion mwede:mypassword:1260686494:Mark;MarkW;: l@so nic.n et
none of the the fields listed could contain colons, and player names can not contain semicolon, as that is used to separate those. In addition, everything is limited to printable characters. The accounts file is designed to be human readable, even if it is not expected that a human will read it. Passwords are hashed using crypt(3) in traditional mode, unless you're on FreeBSD or Windows in which case passwords are stored in plaintext due to legacy reasons. expansion (last field) is there for possible expansion. There may be desire to store bits of information there. An example might be dm=1. But it is there for expansion.
Definition in file account.cpp.
#define ACCOUNT_FILE "accounts" |
Name of the accounts file.
I can not ever see a reason why this name would not work, but may as well still make it easy to change it.
Definition at line 108 of file account.cpp.
#define NUM_ACCOUNT_FIELDS 6 |
Number of fields in the accounts file.
These are colon separated
Definition at line 67 of file account.cpp.
|
static |
Allocate a new account_struct item.
Will fatal() if memory error.
Definition at line 135 of file account.cpp.
References account_struct::created, ensure_available_characters(), fatal(), account_struct::last_login, llevError, LOG(), OUT_OF_MEMORY, and time.
Referenced by account_new(), and accounts_load().
int account_change_password | ( | const char * | account_name, |
const char * | current_password, | ||
const char * | new_password | ||
) |
Change an account password.
It does error checking, but the caller might want to do checking before getting here.
account_name | account name we are changing |
current_password | current password for the account or NULL. This is the unencrypted password (password as entered by user). If NULL, the current password is not checked, suitable for resetting lost passwords. |
new_password | new password to set, unencrypted. |
0 | password changed successfully. |
1 | account name, old or new password has invalid character. |
2 | account does not exist. |
3 | current password is invalid. |
Definition at line 627 of file account.cpp.
References account_check_string(), accounts, check_password(), newhash(), strcasecmp(), and strdup_local.
Referenced by account_password(), and command_accountpasswd().
int account_check_string | ( | const char * | str | ) |
Checks a string to make sure it does not have any invalid characters.
We are fairly permissive on character here. String must start with alphanumeric String must not contain :;/'[ String can not end if a space This string will get used for file/directory names, but so long as as characters are not included that are not illegal, one can still manipulate the file/directory by putting it in quotes. If one starts to block all characters that may get interperted by shells, a large number of characters now get blocked (|*]()!, etc), and deciding which should be allowed and not just becomes a judgement call, so easier to just allow all and have the user put it in quotes.
str | string to check |
Definition at line 360 of file account.cpp.
References MAX_NAME.
Referenced by account_change_password(), account_new(), account_new_cmd(), account_password(), and create_player_cmd().
const char* account_exists | ( | const char * | account_name | ) |
Checks the existing accounts, and see if this account exists.
This can also be used to get the official name for the account (eg, as user first entered, so Mark instead of mARk)
account_name | account name we are looking for. |
Definition at line 296 of file account.cpp.
References accounts, and strcasecmp().
Referenced by account_login_cmd(), account_new(), and account_new_cmd().
const char* account_get_account_for_char | ( | const char * | charname | ) |
This looks at all the accounts and sees if charname is associated with any of them.
charname | character name to check for. |
Definition at line 579 of file account.cpp.
References accounts.
Referenced by account_add_player_cmd(), and save_player().
linked_char* account_get_additional_chars | ( | const char * | account_name, |
const Account_Chars * | chars, | ||
int * | count | ||
) |
Get a list of character names linked to the specified account which are not listed in chars.
account_name | account name. | |
chars | known character names. | |
[out] | count | will be incremented by the number of items returned. Not initialized before use. |
Definition at line 550 of file account.cpp.
References accounts, char_in_list(), Account_Chars::chars, linked_char::name, linked_char::next, and strcasecmp().
Referenced by send_account_players().
char** account_get_players_for_account | ( | const char * | account_name | ) |
Returns an array of strings for the characters on this account - the array is null terminated.
In fact, it just returns the ac->character_names.
account_name | name of the account to get the players for. |
Definition at line 519 of file account.cpp.
References accounts, and strcasecmp().
Referenced by account_play_cmd().
int account_is_logged_in | ( | const char * | name | ) |
This checkes if an account is logged in.
It is mainly used because some operations should not be done on logged in accounts (keeping everything synchronized is harder.)
name | name to look for. |
Definition at line 604 of file account.cpp.
References accounts_logged_in, and name.
Referenced by account_add_player_cmd().
int account_link | ( | const char * | account_name, |
const char * | player_name | ||
) |
Adds a player name to an account.
Player corresponds to the names used in the pl object, not the person sitting at the computer. This function presumes that the caller has done the work to verify that the player does in fact exist, and does any related work to update the player. What this function does is simply update the account structure.
account_name | name of the account we are adding this player to. |
player_name | name of this player. |
0 | player name added successfully. |
1 | could not find account of that name. |
Definition at line 444 of file account.cpp.
References accounts, ensure_available_characters(), strcasecmp(), and strdup_local.
Referenced by account_add_player_cmd(), and save_player().
int account_login | ( | const char * | account_name, |
const char * | account_password | ||
) |
Check if the given account exists, and whether the password is correct.
Note - if we do get a match, we update the last_login value - it is presumed that if someone knows the right accountname/password, that the account is effectively getting logged in.
account_name | account name we are looking for. |
account_password | password for the account. This is the unencrypted password (password as entered by user) |
Definition at line 318 of file account.cpp.
References account_password(), accounts, accounts_logged_in, check_password(), strcasecmp(), and time.
Referenced by account_login_cmd().
void account_logout | ( | const char * | account_name | ) |
Remove 'account_name' from the list of logged in accounts.
Definition at line 337 of file account.cpp.
References accounts_logged_in.
Referenced by free_newsocket().
int account_new | ( | const char * | account_name, |
const char * | account_password | ||
) |
Adds an account.
It does error checking, but the caller might want to do checking before getting here.
account_name | account name we are adding |
account_password | password for the account. This is the unencrypted password (password as entered by user) |
0 | account added successfully. |
1 | name or password has invalid character. |
2 | account already exists. |
Definition at line 399 of file account.cpp.
References account_alloc(), account_check_string(), account_exists(), account_password(), accounts, accounts_loaded, account_struct::name, newhash(), account_struct::password, and strdup_local.
Referenced by account_new_cmd().
int account_remove_player | ( | const char * | account_name, |
const char * | player_name | ||
) |
Removes a player name from an account.
Player corresponds to the names used in the pl object, not the person sitting at the computer. This function presumes that the caller has done the work to verify that the player does in fact exist, and does any related work to update the player. What this function does is simply update the account structure.
account_name | name of the account we are removing this player from. |
player_name | name of this player. |
0 | player name removed successfully. |
1 | could not find account of that name. |
2 | player of this name not on account. |
Definition at line 474 of file account.cpp.
References accounts, and strcasecmp().
Referenced by account_add_player_cmd(), key_confirm_quit(), and kill_player_permadeath().
|
static |
This writes a single account entry to the given filepointer.
it is used both when saving all accounts, or if we just need to append a new account to the end of the file.
fp | file pointer to write to. |
ac | account structure to write out. |
Definition at line 234 of file account.cpp.
References account_struct::character_names, account_struct::created, account_struct::last_login, account_struct::name, account_struct::num_characters, and account_struct::password.
Referenced by accounts_save().
void accounts_clear | ( | void | ) |
This is used purely by the test harness - by clearing the accounts, it can then verify that the data is added is loaded back into memory properly.
As such, we don't worry about memory cleanup, etc.
Definition at line 152 of file account.cpp.
References accounts, and accounts_loaded.
void accounts_load | ( | void | ) |
This loads all the account entries into memory.
It is presumed to only be called once during the program startup.
Definition at line 161 of file account.cpp.
References account_alloc(), ACCOUNT_FILE, accounts, accounts_loaded, buf, bufferreader_destroy(), bufferreader_init_from_file(), bufferreader_next_line(), account_struct::character_names, account_struct::created, ensure_available_characters(), fields, account_struct::last_login, llevError, llevInfo, Settings::localdir, LOG(), MAX_BUF, account_struct::name, NUM_ACCOUNT_FIELDS, account_struct::num_characters, account_struct::password, settings, split_string(), and strdup_local.
Referenced by init().
void accounts_save | ( | void | ) |
Save all the account information.
Since the data is stored in a flat file, if an update is needed for an account, the only way to save updates is to save all the data - there isn't an easy way to just add another player name for an account.
Definition at line 255 of file account.cpp.
References ACCOUNT_FILE, account_write_entry(), accounts, accounts_loaded, Settings::localdir, MAX_BUF, of_close(), of_open(), settings, and time.
Referenced by account_new_cmd(), cleanup(), and do_specials().
|
static |
Check if a character name is in a list or not.
name | character name to check. |
chars | list of names to check. |
Definition at line 533 of file account.cpp.
References name.
Referenced by account_get_additional_chars().
|
static |
Ensure an account can handle at least the specified count of character names.
account | account to check. |
count | number of names to handle. |
Definition at line 115 of file account.cpp.
References account_struct::allocated_characters, account_struct::character_names, fatal(), llevError, LOG(), and OUT_OF_MEMORY.
Referenced by account_alloc(), account_link(), and accounts_load().
|
static |
list of all accounts.
Definition at line 94 of file account.cpp.
Referenced by account_change_password(), account_exists(), account_get_account_for_char(), account_get_additional_chars(), account_get_players_for_account(), account_link(), account_login(), account_new(), account_remove_player(), accounts_clear(), accounts_load(), and accounts_save().
|
static |
Whether the account information was loaded or not.
Because accounts_save() is called in cleanup(), we don't want programs using this library to erase the server's account information, since it is NOT loaded by default.
Definition at line 102 of file account.cpp.
Referenced by account_new(), accounts_clear(), accounts_load(), and accounts_save().
Set of accounts names that are currently logged in.
Definition at line 55 of file account.cpp.
Referenced by account_is_logged_in(), account_login(), and account_logout().