-
Posts
42 -
Joined
-
Last visited
Content Type
Profiles
Forums
Downloads
Jobs Available
Server Database
Third-Party Services
Top Guides
Store
Crowdfunding
Posts posted by PrntScrn
-
-
Hello everybody, I'm here asking for help to apply the patch.diff the InternalGuard in src.
Diff
Index: login/login.c =================================================================== --- login/login.c (revision 17704) +++ login/login.c (working copy) @@ -1155,6 +1155,17 @@ } } + +if ( sd->keypass != 467 ) { +if (strcmp(sd->ig_key,"69e87709f68374fe0")==0){ +ShowStatus("[ Internal Guard ] Key accepted %s %s \n",sd->ig_key,ip); +} +else +{ +ShowStatus("[ Internal Guard ] Key rejected %s %s \n",sd->ig_key,ip); +return 2; +} +} //Client Version check if( login_config.check_client_version && sd->version != login_config.client_version_to_connect ) @@ -1532,6 +1543,14 @@ RFIFOSKIP(fd,18); break; + + case 0x5548: + if (RFIFOREST(fd) < 19) + return 0; + memcpy(sd->ig_key, RFIFOP(fd, 2), 32); + ShowStatus("[ Internal Guard ] IG-Key: %s IP:%s \n",sd->ig_key,ip); + RFIFOSKIP(fd,19); + break; // request client login (raw password) case 0x0064: // S 0064 <version>.L <username>.24B <password>.24B <clienttype>.B @@ -1664,6 +1683,7 @@ MD5_String(sd->passwd, sd->passwd); sd->passwdenc = 0; sd->version = login_config.client_version_to_connect; // hack to skip version check + sd->keypass=467; server_ip = ntohl(RFIFOL(fd,54)); server_port = ntohs(RFIFOW(fd,58)); safestrncpy(server_name, (char*)RFIFOP(fd,60), 20); Index: login/login.h =================================================================== --- login/login.h (revision 17704) +++ login/login.h (working copy) @@ -39,7 +39,8 @@ uint8 client_hash[16]; ///hash of client int has_client_hash; ///client ha sent an hash - + char ig_key[256]; + int keypass; int fd; ///socket of client };
My src
Login.c/** * @file login.c * Module purpose is to read configuration for login-server and handle accounts, * and also to synchronize all login interfaces: loginchrif, loginclif, logincnslif. * Licensed under GNU GPL. * For more information, see LICENCE in the main folder. * @author Athena Dev Teams < r15k * @author rAthena Dev Team */ #include "../common/core.h" #include "../common/db.h" #include "../common/malloc.h" #include "../common/md5calc.h" #include "../common/random.h" #include "../common/showmsg.h" #include "../common/socket.h" //ip2str #include "../common/strlib.h" #include "../common/timer.h" #include "../common/msg_conf.h" #include "../common/cli.h" #include "../common/utils.h" #include "../common/mmo.h" #include "../config/core.h" #include "account.h" #include "ipban.h" #include "login.h" #include "loginlog.h" #include "loginclif.h" #include "loginchrif.h" #include "logincnslif.h" #include <stdlib.h> #define LOGIN_MAX_MSG 30 /// Max number predefined in msg_conf static char* msg_table[LOGIN_MAX_MSG]; /// Login Server messages_conf //definition of exported var declared in .h struct mmo_char_server ch_server[MAX_SERVERS]; /// char server data struct Login_Config login_config; /// Configuration of login-serv DBMap* online_db; DBMap* auth_db; // account database AccountDB* accounts = NULL; // Advanced subnet check [LuzZza] struct s_subnet { uint32 mask; uint32 char_ip; uint32 map_ip; } subnet[16]; int subnet_count = 0; //number of subnet config int login_fd; // login server file descriptor socket //early declaration bool login_check_password(const char* md5key, int passwdenc, const char* passwd, const char* refpass); ///Accessors AccountDB* login_get_accounts_db(void){ return accounts; } // Console Command Parser [Wizputer] //FIXME to be remove (moved to cnslif / will be done once map/char/login, all have their cnslif interface ready) int parse_console(const char* buf){ return cnslif_parse(buf); } /** * Sub function to create an online_login_data and save it to db. * @param key: Key of the database entry * @param ap: args * @return : Data identified by the key to be put in the database * @see DBCreateData */ DBData login_create_online_user(DBKey key, va_list args) { struct online_login_data* p; CREATE(p, struct online_login_data, 1); p->account_id = key.i; p->char_server = -1; p->waiting_disconnect = INVALID_TIMER; return db_ptr2data(p); } /** * Receive info from char-serv that this user is online * This function will start a timer to recheck if that user still online * @param char_server : Serv id where account_id is connected * @param account_id : aid connected * @return the new online_login_data for that user */ struct online_login_data* login_add_online_user(int char_server, uint32 account_id){ struct online_login_data* p; p = idb_ensure(online_db, account_id, login_create_online_user); p->char_server = char_server; if( p->waiting_disconnect != INVALID_TIMER ) { delete_timer(p->waiting_disconnect, login_waiting_disconnect_timer); p->waiting_disconnect = INVALID_TIMER; } return p; } /** * Received info from char serv that the account_id is now offline * remove the user from online_db * Checking if user was already scheduled for deletion, and remove that timer if found. * @param account_id : aid to remove from db */ void login_remove_online_user(uint32 account_id) { struct online_login_data* p; p = (struct online_login_data*)idb_get(online_db, account_id); if( p == NULL ) return; if( p->waiting_disconnect != INVALID_TIMER ) delete_timer(p->waiting_disconnect, login_waiting_disconnect_timer); idb_remove(online_db, account_id); } /** * Timered function to disconnect a user from login. * This is done either after auth_ok or kicked by char-server. * Removing user from auth_db and online_db. * Delay is AUTH_TIMEOUT by default. * @param tid: timer id * @param tick: tick of execution * @param id: user account id * @param data: unused * @return :0 */ int login_waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data) { struct online_login_data* p = (struct online_login_data*)idb_get(online_db, id); if( p != NULL && p->waiting_disconnect == tid && p->account_id == id ){ p->waiting_disconnect = INVALID_TIMER; login_remove_online_user(id); idb_remove(auth_db, id); } return 0; } /** * Sub function to apply on online_db. * Mark a character as offline. * @param data: 1 entry in the db * @param ap: args * @return : Value to be added up by the function that is applying this * @see DBApply */ int login_online_db_setoffline(DBKey key, DBData *data, va_list ap) { struct online_login_data* p = db_data2ptr(data); int server = va_arg(ap, int); if( server == -1 ) { p->char_server = -1; if( p->waiting_disconnect != INVALID_TIMER ) { delete_timer(p->waiting_disconnect, login_waiting_disconnect_timer); p->waiting_disconnect = INVALID_TIMER; } } else if( p->char_server == server ) p->char_server = -2; //Char server disconnected. return 0; } /** * Sub function of login_online_data_cleanup. * Checking if all users in db are still connected to a char-server, and remove them if they aren't. * @param data: 1 entry in the db * @param ap: args * @return: Value to be added up by the function that is applying this * @see DBApply */ static int login_online_data_cleanup_sub(DBKey key, DBData *data, va_list ap) { struct online_login_data *character= db_data2ptr(data); if (character->char_server == -2) //Unknown server.. set them offline login_remove_online_user(character->account_id); return 0; } /** * Timered function to check if user is still connected. * Launches every 600s by default. * @param tid: timer id * @param tick: tick of execution * @param id: unused * @param data: unused * @return : 0 */ static int login_online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data) { online_db->foreach(online_db, login_online_data_cleanup_sub); return 0; } /** * Create a new account and save it in db/sql. * @param userid: string for user login * @param pass: string for user pass * @param sex: should be M|F|S (todo make an enum ?) * @param last_ip: * @return : * -1: success * 0: unregistered id (wrong sex fail to create in db); * 1: incorrect pass or userid (userid|pass too short or already exist); * 3: registration limit exceeded; */ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip) { static int num_regs = 0; // registration counter static unsigned int new_reg_tick = 0; unsigned int tick = gettick(); struct mmo_account acc; //Account Registration Flood Protection by [Kevin] if( new_reg_tick == 0 ) new_reg_tick = gettick(); if( DIFF_TICK(tick, new_reg_tick) < 0 && num_regs >= login_config.allowed_regs ) { ShowNotice("Account registration denied (registration limit exceeded)\n"); return 3; } if( login_config.new_acc_length_limit && ( strlen(userid) < 4 || strlen(pass) < 4 ) ) return 1; // check for invalid inputs if( sex != 'M' && sex != 'F' ) return 0; // 0 = Unregistered ID // check if the account doesn't exist already if( accounts->load_str(accounts, &acc, userid) ) { ShowNotice("Attempt of creation of an already existant account (account: %s_%c, pass: %s, received pass: %s)\n", userid, sex, acc.pass, pass); return 1; // 1 = Incorrect Password } memset(&acc, '\0', sizeof(acc)); acc.account_id = -1; // assigned by account db safestrncpy(acc.userid, userid, sizeof(acc.userid)); safestrncpy(acc.pass, pass, sizeof(acc.pass)); acc.sex = sex; safestrncpy(acc.email, "[email protected]", sizeof(acc.email)); acc.expiration_time = ( login_config.start_limited_time != -1 ) ? time(NULL) + login_config.start_limited_time : 0; safestrncpy(acc.lastlogin, "0000-00-00 00:00:00", sizeof(acc.lastlogin)); safestrncpy(acc.last_ip, last_ip, sizeof(acc.last_ip)); safestrncpy(acc.birthdate, "0000-00-00", sizeof(acc.birthdate)); safestrncpy(acc.pincode, "", sizeof(acc.pincode)); acc.pincode_change = 0; acc.char_slots = MIN_CHARS; #ifdef VIP_ENABLE acc.vip_time = 0; acc.old_group = 0; #endif if( !accounts->create(accounts, &acc) ) return 0; ShowNotice("Account creation (account %s, id: %d, pass: %s, sex: %c)\n", acc.userid, acc.account_id, acc.pass, acc.sex); if( DIFF_TICK(tick, new_reg_tick) > 0 ) {// Update the registration check. num_regs = 0; new_reg_tick = tick + login_config.time_allowed*1000; } ++num_regs; return -1; } /** * Check/authentication of a connection. * @param sd: string (atm:md5key or dbpass) * @param isServer: string (atm:md5key or dbpass) * @return : * -1: success * 0: unregistered id; * 1: incorrect pass; * 2: expired id * 3: blacklisted (or registration limit exceeded if new acc); * 5: invalid client_version|hash; * 6: banned * x: acc state (TODO document me deeper) */ int login_mmo_auth(struct login_session_data* sd, bool isServer) { struct mmo_account acc; int len; char ip[16]; ip2str(session[sd->fd]->client_addr, ip); // DNS Blacklist check if( login_config.use_dnsbl ) { char r_ip[16]; char ip_dnsbl[256]; char* dnsbl_serv; uint8* sin_addr = (uint8*)&session[sd->fd]->client_addr; sprintf(r_ip, "%u.%u.%u.%u", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]); for( dnsbl_serv = strtok(login_config.dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,",") ) { sprintf(ip_dnsbl, "%s.%s", r_ip, trim(dnsbl_serv)); if( host2ip(ip_dnsbl) ) { ShowInfo("DNSBL: (%s) Blacklisted. User Kicked.\n", r_ip); return 3; } } } //Client Version check if( login_config.check_client_version && sd->version != login_config.client_version_to_connect ){ ShowNotice("Invalid version (account: '%s', auth_vers: '%d', received version: '%d', ip: %s)\n", sd->userid, login_config.client_version_to_connect, sd->version, ip); return 5; } len = strnlen(sd->userid, NAME_LENGTH); // Account creation with _M/_F if( login_config.new_account_flag ) { if( len > 2 && strnlen(sd->passwd, NAME_LENGTH) > 0 && // valid user and password lengths sd->passwdenc == 0 && // unencoded password sd->userid[len-2] == '_' && memchr("FfMm", sd->userid[len-1], 4) ) // _M/_F suffix { int result; // remove the _M/_F suffix len -= 2; sd->userid[len] = '\0'; result = login_mmo_auth_new(sd->userid, sd->passwd, TOUPPER(sd->userid[len+1]), ip); if( result != -1 ) return result;// Failed to make account. [Skotlex]. } } if( !accounts->load_str(accounts, &acc, sd->userid) ) { ShowNotice("Unknown account (account: %s, received pass: %s, ip: %s)\n", sd->userid, sd->passwd, ip); return 0; // 0 = Unregistered ID } if( !login_check_password(sd->md5key, sd->passwdenc, sd->passwd, acc.pass) ) { ShowNotice("Invalid password (account: '%s', pass: '%s', received pass: '%s', ip: %s)\n", sd->userid, acc.pass, sd->passwd, ip); return 1; // 1 = Incorrect Password } if( acc.expiration_time != 0 && acc.expiration_time < time(NULL) ) { ShowNotice("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n", sd->userid, sd->passwd, ip); return 2; // 2 = This ID is expired } if( acc.unban_time != 0 && acc.unban_time > time(NULL) ) { char tmpstr[24]; timestamp2string(tmpstr, sizeof(tmpstr), acc.unban_time, login_config.date_format); ShowNotice("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)\n", sd->userid, sd->passwd, tmpstr, ip); return 6; // 6 = Your are Prohibited to log in until %s } if( acc.state != 0 ) { ShowNotice("Connection refused (account: %s, pass: %s, state: %d, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip); return acc.state - 1; } if( login_config.client_hash_check && !isServer ) { struct client_hash_node *node = NULL; bool match = false; for( node = login_config.client_hash_nodes; node; node = node->next ) { if( acc.group_id < node->group_id ) continue; if( *node->hash == '\0' // Allowed to login without hash || (sd->has_client_hash && memcmp(node->hash, sd->client_hash, 16) == 0 ) // Correct hash ) { match = true; break; } } if( !match ) { char smd5[33]; int i; if( !sd->has_client_hash ) { ShowNotice("Client didn't send client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip); return 5; } for( i = 0; i < 16; i++ ) sprintf(&smd5[i * 2], "%02x", sd->client_hash[i]); ShowNotice("Invalid client hash (account: %s, pass: %s, sent md5: %d, ip: %s)\n", sd->userid, sd->passwd, smd5, ip); return 5; } } ShowNotice("Authentication accepted (account: %s, id: %d, ip: %s)\n", sd->userid, acc.account_id, ip); // update session data sd->account_id = acc.account_id; sd->login_id1 = rnd() + 1; sd->login_id2 = rnd() + 1; safestrncpy(sd->lastlogin, acc.lastlogin, sizeof(sd->lastlogin)); sd->sex = acc.sex; sd->group_id = acc.group_id; // update account data timestamp2string(acc.lastlogin, sizeof(acc.lastlogin), time(NULL), "%Y-%m-%d %H:%M:%S"); safestrncpy(acc.last_ip, ip, sizeof(acc.last_ip)); acc.unban_time = 0; acc.logincount++; accounts->save(accounts, &acc); if( sd->sex != 'S' && sd->account_id < START_ACCOUNT_NUM ) ShowWarning("Account %s has account id %d! Account IDs must be over %d to work properly!\n", sd->userid, sd->account_id, START_ACCOUNT_NUM); return -1; // account OK } /** * Sub function of login_check_password. * Checking if password matches the one in db hashed with client md5key. * Test if(md5(str1+str2)==passwd). * @param str1: string (atm:md5key or dbpass) * @param str2: string (atm:md5key or dbpass) * @param passwd: pass to check * @return true if matching else false */ bool login_check_encrypted(const char* str1, const char* str2, const char* passwd) { char tmpstr[64+1], md5str[32+1]; safesnprintf(tmpstr, sizeof(tmpstr), "%s%s", str1, str2); MD5_String(tmpstr, md5str); return (0==strcmp(passwd, md5str)); } /** * Verify if a password is correct. * @param md5key: md5key of client * @param passwdenc: encode key of client * @param passwd: pass to check * @param refpass: pass register in db * @return true if matching else false */ bool login_check_password(const char* md5key, int passwdenc, const char* passwd, const char* refpass) { if(passwdenc == 0){ return (0==strcmp(passwd, refpass)); } else { // password mode set to 1 -> md5(md5key, refpass) enable with <passwordencrypt></passwordencrypt> // password mode set to 2 -> md5(refpass, md5key) enable with <passwordencrypt2></passwordencrypt2> return ((passwdenc&0x01) && login_check_encrypted(md5key, refpass, passwd)) || ((passwdenc&0x02) && login_check_encrypted(refpass, md5key, passwd)); } } /** * Test to determine if an IP come from LAN or WAN. * @param ip: ip to check if in auth network * @return 0 if from wan, or subnet_char_ip if lan */ int lan_subnetcheck(uint32 ip) { int i; ARR_FIND( 0, subnet_count, i, (subnet[i].char_ip & subnet[i].mask) == (ip & subnet[i].mask) ); return ( i < subnet_count ) ? subnet[i].char_ip : 0; } /// Msg_conf tayloring int login_msg_config_read(char *cfgName){ return _msg_config_read(cfgName,LOGIN_MAX_MSG,msg_table); } const char* login_msg_txt(int msg_number){ return _msg_txt(msg_number,LOGIN_MAX_MSG,msg_table); } void login_do_final_msg(void){ _do_final_msg(LOGIN_MAX_MSG,msg_table); } /// Set and read Configurations /** * Reading Lan Support configuration. * @param lancfgName: Name of the lan configuration (could be fullpath) * @return 0:success, 1:failure (file not found|readable) */ int login_lan_config_read(const char *lancfgName) { FILE *fp; int line_num = 0, s_subnet=ARRAYLENGTH(subnet); char line[1024], w1[64], w2[64], w3[64], w4[64]; if((fp = fopen(lancfgName, "r")) == NULL) { ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName); return 1; } while(fgets(line, sizeof(line), fp)) { line_num++; if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n') continue; if(sscanf(line,"%63[^:]: %63[^:]:%63[^:]:%63[^\r\n]", w1, w2, w3, w4) != 4) { ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num); continue; } if( strcmpi(w1, "subnet") == 0 ){ if(subnet_count>=s_subnet) { //We skip instead of break in case we want to add other conf in that file. ShowError("%s: Too many subnets defined, skipping line %d...\n", lancfgName, line_num); continue; } subnet[subnet_count].mask = str2ip(w2); subnet[subnet_count].char_ip = str2ip(w3); subnet[subnet_count].map_ip = str2ip(w4); if( (subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip & subnet[subnet_count].mask) ) { ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4); continue; } subnet_count++; } } if( subnet_count > 1 ) /* only useful if there is more than 1 available */ ShowStatus("Read information about %d subnetworks.\n", subnet_count); fclose(fp); return 0; } /** * Reading main configuration file. * @param cfgName: Name of the configuration (could be fullpath) * @param normal: Config read normally when server started * @return True:success, Fals:failure (file not found|readable) */ bool login_config_read(const char* cfgName, bool normal) { char line[1024], w1[32], w2[1024]; FILE* fp = fopen(cfgName, "r"); if (fp == NULL) { ShowError("Configuration file (%s) not found.\n", cfgName); return false; } while(fgets(line, sizeof(line), fp)) { if (line[0] == '/' && line[1] == '/') continue; if (sscanf(line, "%31[^:]: %1023[^\r\n]", w1, w2) < 2) continue; // Config that loaded only when server started, not by reloading config file if (normal) { if( !strcmpi(w1, "bind_ip") ) { login_config.login_ip = host2ip(w2); if( login_config.login_ip ) { char ip_str[16]; ShowStatus("Login server binding IP address : %s -> %s\n", w2, ip2str(login_config.login_ip, ip_str)); } } else if( !strcmpi(w1, "login_port") ) login_config.login_port = (uint16)atoi(w2); else if(!strcmpi(w1, "console")) login_config.console = (bool)config_switch(w2); } if(!strcmpi(w1,"timestamp_format")) safestrncpy(timestamp_format, w2, 20); else if(strcmpi(w1,"db_path")==0) safestrncpy(db_path, w2, ARRAYLENGTH(db_path)); else if(!strcmpi(w1,"stdout_with_ansisequence")) stdout_with_ansisequence = config_switch(w2); else if(!strcmpi(w1,"console_silent")) { msg_silent = atoi(w2); if( msg_silent ) /* only bother if we actually have this enabled */ ShowInfo("Console Silent Setting: %d\n", atoi(w2)); } else if (strcmpi(w1, "console_msg_log") == 0) console_msg_log = atoi(w2); else if (strcmpi(w1, "console_log_filepath") == 0) safestrncpy(console_log_filepath, w2, sizeof(console_log_filepath)); else if(!strcmpi(w1, "log_login")) login_config.log_login = (bool)config_switch(w2); else if(!strcmpi(w1, "new_account")) login_config.new_account_flag = (bool)config_switch(w2); else if(!strcmpi(w1, "new_acc_length_limit")) login_config.new_acc_length_limit = (bool)config_switch(w2); else if(!strcmpi(w1, "start_limited_time")) login_config.start_limited_time = atoi(w2); else if(!strcmpi(w1, "check_client_version")) login_config.check_client_version = (bool)config_switch(w2); else if(!strcmpi(w1, "client_version_to_connect")) login_config.client_version_to_connect = strtoul(w2, NULL, 10); else if(!strcmpi(w1, "use_MD5_passwords")) login_config.use_md5_passwds = (bool)config_switch(w2); else if(!strcmpi(w1, "group_id_to_connect")) login_config.group_id_to_connect = atoi(w2); else if(!strcmpi(w1, "min_group_id_to_connect")) login_config.min_group_id_to_connect = atoi(w2); else if(!strcmpi(w1, "date_format")) safestrncpy(login_config.date_format, w2, sizeof(login_config.date_format)); else if(!strcmpi(w1, "allowed_regs")) //account flood protection system login_config.allowed_regs = atoi(w2); else if(!strcmpi(w1, "time_allowed")) login_config.time_allowed = atoi(w2); else if(!strcmpi(w1, "use_dnsbl")) login_config.use_dnsbl = (bool)config_switch(w2); else if(!strcmpi(w1, "dnsbl_servers")) safestrncpy(login_config.dnsbl_servs, w2, sizeof(login_config.dnsbl_servs)); else if(!strcmpi(w1, "ipban_cleanup_interval")) login_config.ipban_cleanup_interval = (unsigned int)atoi(w2); else if(!strcmpi(w1, "ip_sync_interval")) login_config.ip_sync_interval = (unsigned int)1000*60*atoi(w2); //w2 comes in minutes. else if(!strcmpi(w1, "client_hash_check")) login_config.client_hash_check = config_switch(w2); else if(!strcmpi(w1, "client_hash")) { int group = 0; char md5[33]; if (sscanf(w2, "%3d, %32s", &group, md5) == 2) { struct client_hash_node *nnode; CREATE(nnode, struct client_hash_node, 1); if (strcmpi(md5, "disabled") == 0) { nnode->hash[0] = '\0'; } else { int i; for (i = 0; i < 32; i += 2) { char buf[3]; unsigned int byte; memcpy(buf, &md5[i], 2); buf[2] = 0; sscanf(buf, "%2x", &byte); nnode->hash[i / 2] = (uint8)(byte & 0xFF); } } nnode->group_id = group; nnode->next = login_config.client_hash_nodes; login_config.client_hash_nodes = nnode; } } else if(strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius] login_config.char_per_account = atoi(w2); if( login_config.char_per_account <= 0 || login_config.char_per_account > MAX_CHARS ) { if( login_config.char_per_account > MAX_CHARS ) { ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", login_config.char_per_account, MAX_CHARS); login_config.char_per_account = MAX_CHARS; } login_config.char_per_account = MIN_CHARS; } } #ifdef VIP_ENABLE else if(strcmpi(w1,"vip_group")==0) login_config.vip_sys.group = cap_value(atoi(w2),0,99); else if(strcmpi(w1,"vip_char_increase")==0) { if(login_config.vip_sys.char_increase > (unsigned int) MAX_CHARS-login_config.char_per_account) ShowWarning("vip_char_increase too high, can only go up to %d, according to your char_per_account config %d\n", MAX_CHARS-login_config.char_per_account,login_config.char_per_account); login_config.vip_sys.char_increase = cap_value(atoi(w2),0,MAX_CHARS-login_config.char_per_account); } #endif else if(!strcmpi(w1, "import")) login_config_read(w2, normal); else {// try the account engines if (!normal) continue; if (accounts && accounts->set_property(accounts, w1, w2)) continue; // try others ipban_config_read(w1, w2); loginlog_config_read(w1, w2); } } fclose(fp); ShowInfo("Finished reading %s.\n", cfgName); return true; } /** * Init login-serv default configuration. */ void login_set_defaults() { login_config.login_ip = INADDR_ANY; login_config.login_port = 6900; login_config.ipban_cleanup_interval = 60; login_config.ip_sync_interval = 0; login_config.log_login = true; safestrncpy(login_config.date_format, "%Y-%m-%d %H:%M:%S", sizeof(login_config.date_format)); login_config.console = false; login_config.new_account_flag = true; login_config.new_acc_length_limit = true; login_config.use_md5_passwds = false; login_config.group_id_to_connect = -1; login_config.min_group_id_to_connect = -1; login_config.check_client_version = false; login_config.client_version_to_connect = date2version(PACKETVER); //20120410 => 30 ShowInfo("loginconfig: client_version_to_connect = %d\n",login_config.client_version_to_connect); login_config.ipban = true; login_config.dynamic_pass_failure_ban = true; login_config.dynamic_pass_failure_ban_interval = 5; login_config.dynamic_pass_failure_ban_limit = 7; login_config.dynamic_pass_failure_ban_duration = 5; login_config.use_dnsbl = false; safestrncpy(login_config.dnsbl_servs, "", sizeof(login_config.dnsbl_servs)); login_config.allowed_regs = 1; login_config.time_allowed = 10; //in second login_config.client_hash_check = 0; login_config.client_hash_nodes = NULL; login_config.char_per_account = MAX_CHARS - MAX_CHAR_VIP - MAX_CHAR_BILLING; #ifdef VIP_ENABLE login_config.vip_sys.char_increase = MAX_CHAR_VIP; login_config.vip_sys.group = 5; #endif //other default conf safestrncpy(login_config.loginconf_name, "conf/login_athena.conf", sizeof(login_config.loginconf_name)); safestrncpy(login_config.lanconf_name, "conf/subnet_athena.conf", sizeof(login_config.lanconf_name)); safestrncpy(login_config.msgconf_name, "conf/msg_conf/login_msg.conf", sizeof(login_config.msgconf_name)); } /// Constructor destructor and signal handlers /** * Login-serv destructor * dealloc..., function called at exit of the login-serv */ void do_final(void) { struct client_hash_node *hn = login_config.client_hash_nodes; AccountDB* db = accounts; while (hn) { struct client_hash_node *tmp = hn; hn = hn->next; aFree(tmp); } login_log(0, "login server", 100, "login server shutdown"); ShowStatus("Terminating...\n"); if( login_config.log_login ) loginlog_final(); do_final_msg(); ipban_final(); do_final_loginclif(); do_final_logincnslif(); if (db) { // destroy account engine db->destroy(db); db = NULL; } accounts = NULL; // destroyed in account_engine online_db->destroy(online_db, NULL); auth_db->destroy(auth_db, NULL); do_final_loginchrif(); if( login_fd != -1 ) { do_close(login_fd); login_fd = -1; } ShowStatus("Finished.\n"); } /** * Signal handler * This function attempts to properly close the server when an interrupt signal is received. * current signal catch : SIGTERM, SIGINT */ void do_shutdown(void) { if( runflag != LOGINSERVER_ST_SHUTDOWN ) { runflag = LOGINSERVER_ST_SHUTDOWN; ShowStatus("Shutting down...\n"); // TODO proper shutdown procedure; kick all characters, wait for acks, ... [FlavioJS] do_shutdown_loginchrif(); flush_fifos(); runflag = CORE_ST_STOP; } } /** * Signal handler * Function called when the server has received a crash signal. * current signal catch : SIGSEGV, SIGFPE */ void do_abort(void) { } // Is this still used ?? void set_server_type(void) { SERVER_TYPE = ATHENA_SERVER_LOGIN; } /** * Login serv constructor * Initialisation, function called at start of the login-serv. * @param argc : number of argument from main() * @param argv : arguments values from main() * @return 0 everything ok else stopping programme execution. */ int do_init(int argc, char** argv) { runflag = LOGINSERVER_ST_STARTING; // Init default value safestrncpy(console_log_filepath, "./log/login-msg_log.log", sizeof(console_log_filepath)); // initialize engine accounts = account_db_sql(); // read login-server configuration login_set_defaults(); logcnslif_get_options(argc,argv); login_config_read(login_config.loginconf_name, true); msg_config_read(login_config.msgconf_name); login_lan_config_read(login_config.lanconf_name); //end config rnd_init(); do_init_loginclif(); do_init_loginchrif(); // initialize logging if( login_config.log_login ) loginlog_init(); // initialize static and dynamic ipban system ipban_init(); // Online user database init online_db = idb_alloc(DB_OPT_RELEASE_DATA); add_timer_func_list(login_waiting_disconnect_timer, "waiting_disconnect_timer"); // Interserver auth init auth_db = idb_alloc(DB_OPT_RELEASE_DATA); // set default parser as parse_login function set_defaultparse(logclif_parse); // every 10 minutes cleanup online account db. add_timer_func_list(login_online_data_cleanup, "online_data_cleanup"); add_timer_interval(gettick() + 600*1000, login_online_data_cleanup, 0, 0, 600*1000); // Account database init if( accounts == NULL ) { ShowFatalError("do_init: account engine not found.\n"); exit(EXIT_FAILURE); } else { if(!accounts->init(accounts)) { ShowFatalError("do_init: Failed to initialize account engine.\n"); exit(EXIT_FAILURE); } } // server port open & binding if( (login_fd = make_listen_bind(login_config.login_ip,login_config.login_port)) == -1 ) { ShowFatalError("Failed to bind to port '"CL_WHITE"%d"CL_RESET"'\n",login_config.login_port); exit(EXIT_FAILURE); } if( runflag != CORE_ST_STOP ) { shutdown_callback = do_shutdown; runflag = LOGINSERVER_ST_RUNNING; } do_init_logincnslif(); ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login_config.login_port); login_log(0, "login server", 100, "login server started"); return 0; }
Login.h
/** * @file login.h * Module purpose is to read configuration for login-server and handle accounts, * and also to synchronise all login interfaces: loginchrif, loginclif, logincnslif. * Licensed under GNU GPL. * For more information, see LICENCE in the main folder. * @author Athena Dev Teams < r15k * @author rAthena Dev Team */ #ifndef _LOGIN_H_ #define _LOGIN_H_ #include "../common/mmo.h" // NAME_LENGTH,SEX_* #include "../common/core.h" // CORE_ST_LAST #include "account.h" #include "../config/core.h" enum E_LOGINSERVER_ST { LOGINSERVER_ST_RUNNING = CORE_ST_LAST, LOGINSERVER_ST_STARTING, LOGINSERVER_ST_SHUTDOWN, LOGINSERVER_ST_LAST }; /// supported encryption types: 1- passwordencrypt, 2- passwordencrypt2, 3- both #define PASSWORDENC 3 ///Struct of 1 client connected to login-serv struct login_session_data { uint32 account_id; ///also GID long login_id1; long login_id2; char sex; /// 'F','M','S' char userid[NAME_LENGTH]; /// account name char passwd[PASSWD_LENGTH]; // 23+1 for plaintext, 32+1 for md5-ed passwords int passwdenc; /// was the passwd transmited encrypted or clear ? char md5key[20]; /// md5 key of session (each connection could be encrypted with a md5 key) uint16 md5keylen; /// len of the md5 key char lastlogin[24]; ///date when last logged, Y-M-D HH:MM:SS uint8 group_id; ///groupid of account uint8 clienttype; /// ??? uint32 version; ///version contained in clientinfo uint8 client_hash[16]; ///hash of client int has_client_hash; ///client ha sent an hash int fd; ///socket of client }; #define MAX_SERVERS 30 //max number of mapserv that could be attach ///Struct describing 1 char-serv attach to us struct mmo_char_server { char name[20]; ///char-serv name int fd; ///char-serv socket (well actually file descriptor) uint32 ip; ///char-serv IP uint16 port; ///char-serv rt uint16 users; /// user count on this server uint16 type; /// 0=normal, 1=maintenance, 2=over 18, 3=paying, 4=P2P uint16 new_; /// should display as 'new'? }; extern struct mmo_char_server ch_server[MAX_SERVERS]; struct client_hash_node { unsigned int group_id; //inferior or egal group to apply restriction uint8 hash[16]; ///hash required for that groupid or below struct client_hash_node *next; ///next entry }; struct Login_Config { uint32 login_ip; /// the address to bind to uint16 login_port; /// the port to bind to unsigned int ipban_cleanup_interval; /// interval (in seconds) to clean up expired IP bans unsigned int ip_sync_interval; /// interval (in minutes) to execute a DNS/IP update (for dynamic IPs) bool log_login; /// whether to log login server actions or not char date_format[32]; /// date format used in messages bool console; /// console input system enabled? bool new_account_flag,new_acc_length_limit; /// autoregistration via _M/_F ? / if yes minimum length is 4? int start_limited_time; /// new account expiration time (-1: unlimited) bool use_md5_passwds; /// work with password hashes instead of plaintext passwords? int group_id_to_connect; /// required group id to connect int min_group_id_to_connect; /// minimum group id to connect bool check_client_version; /// check the clientversion set in the clientinfo ? uint32 client_version_to_connect; /// the client version needed to connect (if checking is enabled) bool ipban; /// perform IP blocking (via contents of `ipbanlist`) ? bool dynamic_pass_failure_ban; /// automatic IP blocking due to failed login attempts ? unsigned int dynamic_pass_failure_ban_interval; /// how far to scan the loginlog for password failures in minutes unsigned int dynamic_pass_failure_ban_limit; /// number of failures needed to trigger the ipban unsigned int dynamic_pass_failure_ban_duration; /// duration of the ipban in minutes bool use_dnsbl; /// dns blacklist blocking ? char dnsbl_servs[1024]; /// comma-separated list of dnsbl servers int allowed_regs; /// max number of registration int time_allowed; /// registration interval in seconds int client_hash_check; /// flags for checking client md5 struct client_hash_node *client_hash_nodes; /// linked list containing md5 hash for each gm group char loginconf_name[256]; /// name of main config file char msgconf_name[256]; /// name of msg_conf config file char lanconf_name[256]; /// name of lan config file int char_per_account; /// number of characters an account can have #ifdef VIP_ENABLE struct { unsigned int group; /// VIP group ID unsigned int char_increase; /// number of char-slot to increase in VIP state } vip_sys; #endif }; extern struct Login_Config login_config; #define sex_num2str(num) ( (num == SEX_FEMALE ) ? 'F' : (num == SEX_MALE ) ? 'M' : 'S' ) #define sex_str2num(str) ( (str == 'F' ) ? SEX_FEMALE : (str == 'M' ) ? SEX_MALE : SEX_SERVER ) #define msg_config_read(cfgName) login_msg_config_read(cfgName) #define msg_txt(msg_number) login_msg_txt(msg_number) #define do_final_msg() login_do_final_msg() int login_msg_config_read(char *cfgName); const char* login_msg_txt(int msg_number); void login_do_final_msg(void); bool login_config_read(const char* cfgName, bool normal); /// Online User Database [Wizputer] struct online_login_data { uint32 account_id; int waiting_disconnect; int char_server; }; extern DBMap* online_db; // uint32 account_id -> struct online_login_data* /// Auth database #define AUTH_TIMEOUT 30000 struct auth_node { uint32 account_id; uint32 login_id1; uint32 login_id2; uint32 ip; char sex; uint32 version; uint8 clienttype; }; extern DBMap* auth_db; // uint32 account_id -> struct auth_node* ///Accessors AccountDB* login_get_accounts_db(void); /** * Sub function to create an online_login_data and save it to db. * @param key: Key of the database entry * @param ap: args * @return : Data identified by the key to be put in the database * @see DBCreateData */ DBData login_create_online_user(DBKey key, va_list args); /** * Function to add a user in online_db. * Checking if the user is already registered in the db. * Stop disconnection timer if set. * @param char_server: id of char-serv on wich the player is * @param account_id: the account identifier * @return the new|registered online data */ struct online_login_data* login_add_online_user(int char_server, uint32 account_id); /** * Function to remove a user from online_db. * Checking if user was already scheduled for deletion, and remove that timer if found. * @param account_id: the account identifier */ void login_remove_online_user(uint32 account_id); /** * Timered function to disconnect a user from login. * This is done either after auth_ok or kicked by char-server. * Removing user from auth_db and online_db. * Delay is AUTH_TIMEOUT by default. * @param tid: timer id * @param tick: tick of execution * @param id: user account id * @param data: unused * @return :0 */ int login_waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data); /** * Sub function to apply on online_db. * Mark a character as offline. * @param data: 1 entry in the db * @param ap: args * @return : Value to be added up by the function that is applying this * @see DBApply */ int login_online_db_setoffline(DBKey key, DBData *data, va_list ap); /** * Test to determine if an IP come from LAN or WAN. * @param ip: ip to check if in auth network * @return 0 if from wan, or subnet_char_ip if lan */ int lan_subnetcheck(uint32 ip); /** * Create a new account and save it in db/sql. * @param userid: string for user login * @param pass: string for user pass * @param sex: should be M|F|S (todo make an enum ?) * @param last_ip: * @return : * -1: success * 0: unregistered id (wrong sex fail to create in db); * 1: incorrect pass or userid (userid|pass too short or already exist); * 3: registration limit exceeded; */ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip); /** * Check/authentication of a connection. * @param sd: string (atm:md5key or dbpass) * @param isServer: string (atm:md5key or dbpass) * @return : * -1: success * 0: unregistered id; * 1: incorrect pass; * 2: expired id * 3: blacklisted (or registration limit exceeded if new acc); * 5: invalid client_version|hash; * 6: banned * x: acc state (TODO document me deeper) */ int login_mmo_auth(struct login_session_data* sd, bool isServer); #endif /* _LOGIN_H_ */
-
File Name: command @mlive
File Submitter: PrntScrn
File Submitted: 26 Feb 2015
File Category: Source Modifications
Content Author: PrntScrnMany sought something to ease some of the game or hinder rather depends on the look. With this command you make it easier for the player to know if there is a living or deceased mob.
It only works on the map where the mob is.
Support: Skype: gustavo_fmi
Portugues and English
-
Yes the site is encoded.
-
sla man ja tentou testar com outro emulador o hercules por exemplo?
-
CeresCP + Site or FluxCP for rAthena?
-
Obs : Derrubei o host do meu emulador mas ele emora de reconetar no quando o host é reconectado então resolvido.
Isso não é falha no rAthena, nem muito menos no Hercules, é algo errado no VPS sim ou algo referente ao firewall, porque a conexão tá sendo perdida, não tem nada haver com Bug referente aos emuladores...
Posso adiantar que pode até ser configuração errada de Packet, é improvável, mas uma hipótese, já tive servidores e sempre revisava as configurações, não tinha problemas desse tipo.
-
Tem que ser reportado
-
Cara isso acontece no meu servidor tbm e é o erAthena. Por exemplo:
Quando desligou o host ele vai cair, mas quando re LIGO o servidor ele deveria contar novamente, mas ele fica dando lost cconection.
Testei a mesma coisa em outro emulador e quando re LIGO o host ele reconecta normalmente.
Obs: se toda vez o servidor receber ataque e reiniciar o host o rAthena terá que desligar e reiligar ou seja mvps nascendo tudo novamente. :/
-
Show foi trocado por mês
Getgmlevel
Por getgroupid se n me engano
E outros.
Usa o notepad ++ seleciona tudo ctrl+f e clica em substituir ai seleciona por exemplo "show" e substituir "mes" marca na seleção e clica substituir todos e assim por diante.
-
vc usa anti hacker? Anti atack?
Obs: esses erros de crash acontecia normalmente no emulador do Cronus.
-
Alguém sabe me explicar como configuro o sistema VIP do BRO?
-
Mudar os mapa do PvP é pvp mooka SQL.
-
Ativei o item_vending
Mas quando abro a loja n aparece as opções.
Obs uso hexed 20120410RagexeRe
-
Friend, I was too stupid for Preca reason to get things. kk Thank you [solved]
What emulator is? Stupid question, do you saw if your char have all skills?
Friend, I was too stupid for Preca reason to get things. kk Thank you [solved]
-
already be solved. Now the problem is another chat alt + c does not open. rAmod
The problem will be client compatibility or data files.
I'm using hexed and the data that my friend uses the same emulator I.
-
already be solved. Now the problem is another chat alt + c does not open. rAmod
-
Isto também estar acontecendo comigo e eu não sei o que eu faço.
-
copiled.....erro
-
My Hexed 20120410
my clientinfo<?xml version="1.0" encoding="euc-kr" ?><clientinfo><desc>Ragnarok Client Information - International Version</desc><servicetype>korea</servicetype><servertype>primary</servertype><connection><display>Envolvents</display><desc>Envolvents</desc><balloon>Envolvents</balloon><address>127.0.0.7</address><port>6900</port><version>30</version><langtype>10</langtype><aid><admin>2000002</admin></aid></connection>CP</clientinfo> -
When I type login and password works, but when you select the character: refused by the server.
-
Please help me out here.I want to create a mapflag blocking such spells are these:MS_REFLECTSHIELDST_REJECTSWORDhelp me pls
-
Use a mapflag noskill,para bloquear o uso de ygg no pvp seria necessária, na minha opnião, criar uma mapflag e algumas edições na source:
Eu criei a map_flag , más apenas ensina a criar o nome e não atribuir os valores de cancelar skill e talz.
-
Galera eu quero saber como bloqueia certas magias em alguns mapas no rAthena e como bloqueio o uso de ygg n pvp.
-
I dont know what you're talking about but, map_zone_db is not available in rAthena.
In some emulators configures restrictions on use of items in this file, the bad rAthena where do I set restrictions on items, magic, etc..
What kind of restrictions? You can take a look at db/[re|pre-re]/item_trade.txt for Item trade restrictions.
Example: I want Blocking using relfect in moc_fild22.I want to block the use of Ygg PvP.
Diffs of InternalGuard
in Client-side Support
Posted
yes I am trying to test with the older version before hiring.