From 9267c2bf8add5b01ec22d6d16b521497eeae78d9 Mon Sep 17 00:00:00 2001 From: Jittapan Pluemsumran Date: Tue, 11 Jun 2024 03:03:49 +0700 Subject: [PATCH] Added sanity checks to pincode decryption (#8404) --- src/char/char.cpp | 17 +++++++++++++---- src/char/char.hpp | 2 +- src/char/char_clif.cpp | 38 +++++++++++++++++++++++++++----------- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/char/char.cpp b/src/char/char.cpp index 6b74b33f27..07c214ddc0 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -2158,16 +2158,23 @@ int char_pincode_compare( int fd, struct char_session_data* sd, char* pin ){ } } - -void char_pincode_decrypt( uint32 userSeed, char* pin ){ +bool char_pincode_decrypt( uint32 userSeed, char* pin ){ int i; char tab[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; char *buf; - + + if (safestrnlen(pin, 4) != PINCODE_LENGTH) + return false; + + for (i = 0; i < PINCODE_LENGTH; ++i) { + if (!ISDIGIT(pin[i])) + return false; + } + for( i = 1; i < 10; i++ ){ int pos; uint32 multiplier = 0x3498, baseSeed = 0x881234; - + userSeed = baseSeed + userSeed * multiplier; pos = userSeed % ( i + 1 ); if( i != pos ){ @@ -2184,6 +2191,8 @@ void char_pincode_decrypt( uint32 userSeed, char* pin ){ } strcpy( pin, buf ); aFree( buf ); + + return true; } #endif diff --git a/src/char/char.hpp b/src/char/char.hpp index f03dd9b158..0a17ac8cd8 100644 --- a/src/char/char.hpp +++ b/src/char/char.hpp @@ -318,7 +318,7 @@ int char_family(int pl1,int pl2,int pl3); int char_loadName(uint32 char_id, char* name); int char_check_char_name(char * name, char * esc_name); -void char_pincode_decrypt( uint32 userSeed, char* pin ); +bool char_pincode_decrypt( uint32 userSeed, char* pin ); int char_pincode_compare( int fd, struct char_session_data* sd, char* pin ); void char_auth_ok(int fd, struct char_session_data *sd); void char_set_charselect(uint32 account_id); diff --git a/src/char/char_clif.cpp b/src/char/char_clif.cpp index 86ae51657b..1ae2d56fa3 100644 --- a/src/char/char_clif.cpp +++ b/src/char/char_clif.cpp @@ -167,14 +167,20 @@ int chclif_parse_pincode_check( int fd, struct char_session_data* sd ){ char pin[PINCODE_LENGTH+1]; - if( charserv_config.pincode_config.pincode_enabled==0 || RFIFOL(fd,2) != sd->account_id ) + if( charserv_config.pincode_config.pincode_enabled==0 || RFIFOL(fd,2) != sd->account_id ) { + set_eof(fd); return 1; + } memset(pin,0,PINCODE_LENGTH+1); strncpy((char*)pin, RFIFOCP(fd, 6), PINCODE_LENGTH); RFIFOSKIP(fd,10); - char_pincode_decrypt(sd->pincode_seed, pin ); + if (!char_pincode_decrypt(sd->pincode_seed, pin )) { + set_eof(fd); + return 1; + } + if( char_pincode_compare( fd, sd, pin ) ){ chclif_pincode_sendstate( fd, sd, PINCODE_PASSED ); } @@ -257,28 +263,33 @@ bool pincode_allowed( char* pincode ){ int chclif_parse_pincode_change( int fd, struct char_session_data* sd ){ FIFOSD_CHECK(14); - if( charserv_config.pincode_config.pincode_enabled==0 || RFIFOL(fd,2) != sd->account_id ) + if( charserv_config.pincode_config.pincode_enabled==0 || RFIFOL(fd,2) != sd->account_id ) { + set_eof(fd); return 1; + } else { char oldpin[PINCODE_LENGTH+1]; char newpin[PINCODE_LENGTH+1]; - + memset(oldpin,0,PINCODE_LENGTH+1); memset(newpin,0,PINCODE_LENGTH+1); strncpy(oldpin, RFIFOCP(fd,6), PINCODE_LENGTH); strncpy(newpin, RFIFOCP(fd,10), PINCODE_LENGTH); RFIFOSKIP(fd,14); - - char_pincode_decrypt(sd->pincode_seed,oldpin); + + if (!char_pincode_decrypt(sd->pincode_seed,oldpin) || !char_pincode_decrypt(sd->pincode_seed,newpin)) { + set_eof(fd); + return 1; + } + if( !char_pincode_compare( fd, sd, oldpin ) ) return 1; - char_pincode_decrypt(sd->pincode_seed,newpin); if( pincode_allowed(newpin) ){ chlogif_pincode_notifyLoginPinUpdate( sd->account_id, newpin ); strncpy(sd->pincode, newpin, sizeof(newpin)); ShowInfo("Pincode changed for AID: %d\n", sd->account_id); - + chclif_pincode_sendstate( fd, sd, PINCODE_PASSED ); }else{ chclif_pincode_sendstate( fd, sd, PINCODE_ILLEGAL ); @@ -293,21 +304,26 @@ int chclif_parse_pincode_change( int fd, struct char_session_data* sd ){ int chclif_parse_pincode_setnew( int fd, struct char_session_data* sd ){ FIFOSD_CHECK(10); - if( charserv_config.pincode_config.pincode_enabled==0 || RFIFOL(fd,2) != sd->account_id ) + if( charserv_config.pincode_config.pincode_enabled==0 || RFIFOL(fd,2) != sd->account_id ) { + set_eof(fd); return 1; + } else { char newpin[PINCODE_LENGTH+1]; memset(newpin,0,PINCODE_LENGTH+1); strncpy( newpin, RFIFOCP(fd,6), PINCODE_LENGTH ); RFIFOSKIP(fd,10); - char_pincode_decrypt( sd->pincode_seed, newpin ); + if (!char_pincode_decrypt( sd->pincode_seed, newpin )) { + set_eof(fd); + return 1; + } if( pincode_allowed(newpin) ){ chlogif_pincode_notifyLoginPinUpdate( sd->account_id, newpin ); strncpy( sd->pincode, newpin, sizeof( newpin ) ); - chclif_pincode_sendstate( fd, sd, PINCODE_PASSED ); + chclif_pincode_sendstate( fd, sd, PINCODE_PASSED ); }else{ chclif_pincode_sendstate( fd, sd, PINCODE_ILLEGAL ); }