Ver Fonte

Added sanity checks to pincode decryption (#8404)

Jittapan Pluemsumran há 11 meses atrás
pai
commit
9267c2bf8a
3 ficheiros alterados com 41 adições e 16 exclusões
  1. 13 4
      src/char/char.cpp
  2. 1 1
      src/char/char.hpp
  3. 27 11
      src/char/char_clif.cpp

+ 13 - 4
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
 

+ 1 - 1
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);

+ 27 - 11
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 );
 		}