Crossfire Server, Trunk
|
#include <set>
#include <string>
#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 |
Macros | |
#define | ACCOUNT_FILE "accounts" |
#define | NUM_ACCOUNT_FIELDS 6 |
Functions | |
static account_struct * | account_alloc () |
int | account_change_password (const char *account_name, const char *current_password, const char *new_password) |
int | account_check_string (const char *str) |
const char * | account_exists (const char *account_name) |
const char * | account_get_account_for_char (const char *charname) |
linked_char * | account_get_additional_chars (const char *account_name, const Account_Chars *chars, int *count) |
char ** | account_get_players_for_account (const char *account_name) |
int | account_is_logged_in (const char *name) |
int | account_link (const char *account_name, const char *player_name) |
int | account_login (const char *account_name, const char *account_password) |
void | account_logout (const char *account_name) |
int | account_new (const char *account_name, const char *account_password) |
int | account_remove_player (const char *account_name, const char *player_name) |
static void | account_write_entry (FILE *fp, account_struct *ac) |
void | accounts_clear (void) |
void | accounts_load (void) |
void | accounts_save (void) |
static int | char_in_list (const char *name, const std::vector< Account_Char * > chars) |
static void | ensure_available_characters (account_struct *account, int count) |
Variables | |
static std::vector< account_struct * > | accounts |
static int | accounts_loaded = 0 |
static std::set< std::string > | accounts_logged_in = std::set<std::string>() |
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 109 of file account.cpp.
#define NUM_ACCOUNT_FIELDS 6 |
Number of fields in the accounts file. These are colon separated
Definition at line 68 of file account.cpp.
|
static |
Allocate a new account_struct item. Will fatal() if memory error.
Definition at line 136 of file account.cpp.
References curse_on_apply::ac, ensure_available_characters(), fatal(), llevError, LOG(), and OUT_OF_MEMORY.
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 628 of file account.cpp.
References curse_on_apply::ac, 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 361 of file account.cpp.
References MAX_NAME, and make_face_from_files::str.
Referenced by account_change_password(), account_new(), account_new_cmd(), account_password(), create_player_cmd(), and START_TEST().
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 297 of file account.cpp.
References curse_on_apply::ac, accounts, and strcasecmp().
Referenced by account_login_cmd(), account_new(), account_new_cmd(), and START_TEST().
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 580 of file account.cpp.
References curse_on_apply::ac, accounts, and guildjoin::charname.
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 551 of file account.cpp.
References curse_on_apply::ac, 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 520 of file account.cpp.
References curse_on_apply::ac, accounts, and strcasecmp().
Referenced by account_play_cmd(), and START_TEST().
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 605 of file account.cpp.
References accounts_logged_in, and give::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 445 of file account.cpp.
References curse_on_apply::ac, accounts, ensure_available_characters(), strcasecmp(), and strdup_local.
Referenced by account_add_player_cmd(), save_player(), and START_TEST().
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 319 of file account.cpp.
References curse_on_apply::ac, account_password(), accounts, accounts_logged_in, check_password(), and strcasecmp().
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 338 of file account.cpp.
References accounts_logged_in.
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 400 of file account.cpp.
References curse_on_apply::ac, account_alloc(), account_check_string(), account_exists(), account_password(), accounts, accounts_loaded, newhash(), and strdup_local.
Referenced by account_new_cmd(), and START_TEST().
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 475 of file account.cpp.
References curse_on_apply::ac, accounts, push::match, and strcasecmp().
Referenced by account_add_player_cmd(), key_confirm_quit(), kill_player_permadeath(), and START_TEST().
|
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 235 of file account.cpp.
References curse_on_apply::ac.
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 153 of file account.cpp.
References accounts, and accounts_loaded.
Referenced by START_TEST().
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 162 of file account.cpp.
References curse_on_apply::ac, account_alloc(), ACCOUNT_FILE, accounts, accounts_loaded, buf, bufferreader_destroy(), bufferreader_init_from_file(), bufferreader_next_line(), ensure_available_characters(), llevError, llevInfo, Settings::localdir, LOG(), MAX_BUF, NUM_ACCOUNT_FIELDS, settings, split_string(), strdup_local, and Ice::tmp.
Referenced by init(), and START_TEST().
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 256 of file account.cpp.
References curse_on_apply::ac, ACCOUNT_FILE, account_write_entry(), accounts, accounts_loaded, Settings::localdir, MAX_BUF, of_close(), of_open(), and settings.
Referenced by account_new_cmd(), cleanup(), do_specials(), and START_TEST().
|
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 534 of file account.cpp.
References give::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 116 of file account.cpp.
References account_struct::allocated_characters, account_struct::character_names, disinfect::count, fatal(), llevError, LOG(), and OUT_OF_MEMORY.
Referenced by account_alloc(), account_link(), and accounts_load().
|
static |
list of all accounts.
Definition at line 95 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 103 of file account.cpp.
Referenced by account_new(), accounts_clear(), accounts_load(), and accounts_save().
|
static |
Set of accounts names that are currently logged in.
Definition at line 54 of file account.cpp.
Referenced by account_is_logged_in(), account_login(), and account_logout().