Index: src/common/mmo.h =================================================================== --- src/common/mmo.h (revision 17237) +++ src/common/mmo.h (working copy) @@ -122,6 +122,8 @@ //For Map Names, which the client considers to be 16 in length including the .gat extension #define MAP_NAME_LENGTH (11 + 1) #define MAP_NAME_LENGTH_EXT (MAP_NAME_LENGTH + 4) +//Pincode Length +#define PINCODE_LENGTH 4 #define MAX_FRIENDS 40 #define MAX_MEMOPOINTS 3 Index: src/login/login.c =================================================================== --- src/login/login.c (revision 17237) +++ src/login/login.c (working copy) @@ -552,8 +552,10 @@ uint8 char_slots = 0; int group_id = 0; char birthdate[10+1] = ""; - char pincode[4+1] = ""; + char pincode[PINCODE_LENGTH+1]; + memset(pincode,0,PINCODE_LENGTH+1); + int account_id = RFIFOL(fd,2); RFIFOSKIP(fd,6); Index: src/login/account.h =================================================================== --- src/login/account.h (revision 17237) +++ src/login/account.h (working copy) @@ -50,7 +50,7 @@ char lastlogin[24]; // date+time of last successful login char last_ip[16]; // save of last IP of connection char birthdate[10+1]; // assigned birth date (format: YYYY-MM-DD, default: 0000-00-00) - char pincode[4+1]; // pincode system + char pincode[PINCODE_LENGTH+1]; // pincode system time_t pincode_change; // (timestamp): last time of pincode change int account_reg2_num; struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server) Index: src/char/char.c =================================================================== --- src/char/char.c (revision 17237) +++ src/char/char.c (working copy) @@ -29,6 +29,7 @@ #include #include #include +#include #define CHAR_MAX_MSG 300 static char* msg_table[CHAR_MAX_MSG]; // Login Server messages_conf @@ -132,8 +133,8 @@ char new_name[NAME_LENGTH]; char birthdate[10+1]; // YYYY-MM-DD // Pincode system - char pincode[4+1]; - uint16 pincode_seed; + char pincode[PINCODE_LENGTH+1]; + uint64 pincode_seed; time_t pincode_change; uint16 pincode_try; // Addon system @@ -168,7 +169,7 @@ void pincode_sendstate( int fd, struct char_session_data* sd, uint16 state ); void pincode_notifyLoginPinUpdate( int account_id, char* pin ); void pincode_notifyLoginPinError( int account_id ); -void pincode_decrypt( unsigned long userSeed, char* pin ); +void pincode_decrypt( uint64 userSeed, char* pin ); int pincode_compare( int fd, struct char_session_data* sd, char* pin ); // Addon system @@ -4275,11 +4276,9 @@ if( RFIFOREST(fd) < 10 ) return 0; - if( RFIFOL(fd,2) != sd->account_id ) - break; + if( pincode_enabled && RFIFOL(fd,2) == sd->account_id ) + pincode_check( fd, sd ); - pincode_check( fd, sd ); - RFIFOSKIP(fd,10); break; @@ -4288,13 +4287,12 @@ if( RFIFOREST(fd) < 6 ) return 0; - if( RFIFOL(fd,2) != sd->account_id ) - break; - - if( strlen( sd->pincode ) <= 0 ){ - pincode_sendstate( fd, sd, PINCODE_NEW ); - }else{ - pincode_sendstate( fd, sd, PINCODE_ASK ); + if( pincode_enabled && RFIFOL(fd,2) == sd->account_id ){ + if( strlen( sd->pincode ) <= 0 ){ + pincode_sendstate( fd, sd, PINCODE_NEW ); + }else{ + pincode_sendstate( fd, sd, PINCODE_ASK ); + } } RFIFOSKIP(fd,6); @@ -4305,11 +4303,9 @@ if( RFIFOREST(fd) < 14 ) return 0; - if( RFIFOL(fd,2) != sd->account_id ) - break; + if( pincode_enabled && RFIFOL(fd,2) == sd->account_id ) + pincode_change( fd, sd ); - pincode_change( fd, sd ); - RFIFOSKIP(fd,14); break; @@ -4318,11 +4314,9 @@ if( RFIFOREST(fd) < 10 ) return 0; - if( RFIFOL(fd,2) != sd->account_id ) - break; + if( pincode_enabled && RFIFOL(fd,2) == sd->account_id ) + pincode_setnew( fd, sd ); - pincode_setnew( fd, sd ); - RFIFOSKIP(fd,10); break; @@ -4520,9 +4514,12 @@ //Pincode system //------------------------------------------------ void pincode_check( int fd, struct char_session_data* sd ){ - char pin[5] = "\0\0\0\0"; - strncpy((char*)pin, (char*)RFIFOP(fd, 6), 4+1); + char pin[PINCODE_LENGTH+1]; + memset(pin,0,PINCODE_LENGTH+1); + + strncpy((char*)pin, (char*)RFIFOP(fd, 6), PINCODE_LENGTH); + pincode_decrypt(sd->pincode_seed, pin ); if( pincode_compare( fd, sd, pin ) ){ @@ -4531,7 +4528,7 @@ } int pincode_compare( int fd, struct char_session_data* sd, char* pin ){ - if( strcmp( sd->pincode, pin ) == 0 ){ + if( strncmp( sd->pincode, pin, PINCODE_LENGTH ) == 0 ){ sd->pincode_try = 0; return 1; }else{ @@ -4546,27 +4543,33 @@ } void pincode_change( int fd, struct char_session_data* sd ){ - char oldpin[5] = "\0\0\0\0"; - char newpin[5] = "\0\0\0\0"; + char oldpin[PINCODE_LENGTH+1]; + char newpin[PINCODE_LENGTH+1]; - strncpy(oldpin, (char*)RFIFOP(fd,6), 4+1); + memset(oldpin,0,PINCODE_LENGTH+1); + memset(newpin,0,PINCODE_LENGTH+1); + + strncpy(oldpin, (char*)RFIFOP(fd,6), PINCODE_LENGTH); pincode_decrypt(sd->pincode_seed,oldpin); if( !pincode_compare( fd, sd, oldpin ) ) return; - strncpy(newpin, (char*)RFIFOP(fd,10), 4+1); + strncpy(newpin, (char*)RFIFOP(fd,10), PINCODE_LENGTH); pincode_decrypt(sd->pincode_seed,newpin); pincode_notifyLoginPinUpdate( sd->account_id, newpin ); + strncpy(sd->pincode, newpin, sizeof(newpin)); pincode_sendstate( fd, sd, PINCODE_PASSED ); } void pincode_setnew( int fd, struct char_session_data* sd ){ - char newpin[5] = "\0\0\0\0"; + char newpin[PINCODE_LENGTH+1]; - strncpy( newpin, (char*)RFIFOP(fd,6), 4+1 ); + memset(newpin,0,PINCODE_LENGTH+1); + + strncpy( newpin, (char*)RFIFOP(fd,6), PINCODE_LENGTH ); pincode_decrypt( sd->pincode_seed, newpin ); pincode_notifyLoginPinUpdate( sd->account_id, newpin ); @@ -4597,7 +4600,7 @@ WFIFOHEAD(login_fd,11); WFIFOW(login_fd,0) = 0x2738; WFIFOL(login_fd,2) = account_id; - strncpy( (char*)WFIFOP(login_fd,6), pin, 5 ); + strncpy( (char*)WFIFOP(login_fd,6), pin, PINCODE_LENGTH+1 ); WFIFOSET(login_fd,11); } @@ -4608,26 +4611,33 @@ WFIFOSET(login_fd,6); } -void pincode_decrypt( unsigned long userSeed, char* pin ){ +void pincode_decrypt( uint64 userSeed, char* pin ){ int i, pos; char tab[10] = {0,1,2,3,4,5,6,7,8,9}; - unsigned long multiplier = 0x3498, baseSeed = 0x881234; + uint64 multiplier = 0x3498, baseSeed = 0x881234; + ShowInfo("pinraw = %s \n",pin); for( i = 1; i < 10; i++ ){ userSeed = baseSeed + userSeed * multiplier; pos = userSeed % (i + 1); if( i != pos ){ - tab[i] ^= tab[pos]; + tab[i] ^= tab[pos]; //x = x xor y; i != j tab[pos] ^= tab[i]; tab[i] ^= tab[pos]; } } - for( i = 0; i < 4; i++ ){ - pin[i] = tab[pin[i]- '0']; + ShowInfo("pinin = %s \n",pin); +// for( i = 0; i < PINCODE_LENGTH; i++ ) +// pin[i] = tab[atoi(pin+i)]; +// ShowInfo("pininout=%s \n",pin); + + for( i = 0; i < PINCODE_LENGTH; i++ ){ + char tmp = tab[atoi(pin+i-1)]; + ShowInfo("tmp = %d \n",tmp); + sprintf( pin+i, "%d", tmp); } - - sprintf(pin, "%d%d%d%d", pin[0], pin[1], pin[2], pin[3]); + ShowInfo("pinout=%s \n",pin); } //------------------------------------------------ @@ -5018,6 +5028,13 @@ guild_exp_rate = atoi(w2); } else if (strcmpi(w1, "pincode_enabled") == 0) { pincode_enabled = config_switch(w2); + + #if PACKETVER < 20110309 + if( pincode_enabled ) { + ShowWarning("pincode_enabled requires PACKETVER 20110309 or higher. Disabling...\n"); + pincode_enabled = false; + } + #endif } else if (strcmpi(w1, "pincode_changetime") == 0) { pincode_changetime = atoi(w2)*60*60*24; } else if (strcmpi(w1, "pincode_maxtry") == 0) {