ソースを参照

Merge pull request #748 from rathena/feature/pincode_extension

Feature/pincode extension
Lemongrass3110 9 年 前
コミット
085cd98bfd

+ 8 - 0
conf/char_athena.conf

@@ -196,6 +196,14 @@ pincode_maxtry: 3
 // Default: yes
 pincode_force: yes
 
+// Are repeated numbers allowed?
+// Default: no
+pincode_allow_repeated: no
+
+// Are sequential numbers allowed?
+// Default: no
+pincode_allow_sequential: no
+
 //===================================
 // Addon system
 //===================================

+ 16 - 6
src/char/char.c

@@ -2055,6 +2055,7 @@ int parse_console(const char* buf){
 	return cnslif_parse(buf);
 }
 
+#if PACKETVER_SUPPORTS_PINCODE
 //------------------------------------------------
 //Pincode system
 //------------------------------------------------
@@ -2100,6 +2101,7 @@ void char_pincode_decrypt( uint32 userSeed, char* pin ){
 	strcpy( pin, buf );
 	aFree( buf );
 }
+#endif
 
 //------------------------------------------------
 //Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't
@@ -2584,10 +2586,14 @@ void char_set_default_sql(){
 
 //set default config
 void char_set_defaults(){
+#if PACKETVER_SUPPORTS_PINCODE
 	charserv_config.pincode_config.pincode_enabled = true;
 	charserv_config.pincode_config.pincode_changetime = 0;
 	charserv_config.pincode_config.pincode_maxtry = 3;
 	charserv_config.pincode_config.pincode_force = true;
+	charserv_config.pincode_config.pincode_allow_repeated = false;
+	charserv_config.pincode_config.pincode_allow_sequential = false;
+#endif
 
 	charserv_config.charmove_config.char_move_enabled = true;
 	charserv_config.charmove_config.char_movetoused = true;
@@ -2813,19 +2819,23 @@ bool char_config_read(const char* cfgName, bool normal){
 		} else if (strcmpi(w1, "guild_exp_rate") == 0) {
 			charserv_config.guild_exp_rate = atoi(w2);
 		} else if (strcmpi(w1, "pincode_enabled") == 0) {
+#if PACKETVER_SUPPORTS_PINCODE
 			charserv_config.pincode_config.pincode_enabled = config_switch(w2);
-#if PACKETVER < 20110309
-			if( charserv_config.pincode_config.pincode_enabled ) {
-				ShowWarning("pincode_enabled requires PACKETVER 20110309 or higher. Disabling...\n");
-				charserv_config.pincode_config.pincode_enabled = false;
-			}
-#endif
 		} else if (strcmpi(w1, "pincode_changetime") == 0) {
 			charserv_config.pincode_config.pincode_changetime = atoi(w2)*60*60*24;
 		} else if (strcmpi(w1, "pincode_maxtry") == 0) {
 			charserv_config.pincode_config.pincode_maxtry = atoi(w2);
 		} else if (strcmpi(w1, "pincode_force") == 0) {
 			charserv_config.pincode_config.pincode_force = config_switch(w2);
+		}  else if (strcmpi(w1, "pincode_allow_repeated") == 0) {
+			charserv_config.pincode_config.pincode_allow_repeated = config_switch(w2);
+		}  else if (strcmpi(w1, "pincode_allow_sequential") == 0) {
+			charserv_config.pincode_config.pincode_allow_sequential = config_switch(w2);
+#else
+			if( config_switch(w2) ) {
+				ShowWarning("pincode_enabled requires PACKETVER 20110309 or higher.\n");
+			}
+#endif
 		} else if (strcmpi(w1, "char_move_enabled") == 0) {
 			charserv_config.charmove_config.char_move_enabled = config_switch(w2);
 		} else if (strcmpi(w1, "char_movetoused") == 0) {

+ 11 - 0
src/char/char.h

@@ -71,6 +71,7 @@ struct Schema_Config {
 };
 extern struct Schema_Config schema_config;
 
+#if PACKETVER_SUPPORTS_PINCODE
 /// Pincode system
 enum pincode_state {
 	PINCODE_OK		= 0,
@@ -78,6 +79,10 @@ enum pincode_state {
 	PINCODE_NOTSET	= 2,
 	PINCODE_EXPIRED	= 3,
 	PINCODE_NEW		= 4,
+	PINCODE_ILLEGAL = 5,
+#if 0
+	PINCODE_KSSN	= 6, // Not supported since we do not store KSSN
+#endif
 	PINCODE_PASSED	= 7,
 	PINCODE_WRONG	= 8,
 	PINCODE_MAXSTATE
@@ -87,7 +92,11 @@ struct Pincode_Config {
 	int pincode_changetime;
 	int pincode_maxtry;
 	bool pincode_force;
+	bool pincode_allow_repeated;
+	bool pincode_allow_sequential;
 };
+#endif
+
 struct CharMove_Config {
 	bool char_move_enabled;
 	bool char_movetoused;
@@ -124,7 +133,9 @@ struct CharServ_Config {
 
 	struct CharMove_Config charmove_config;
 	struct Char_Config char_config;
+#if PACKETVER_SUPPORTS_PINCODE
 	struct Pincode_Config pincode_config;
+#endif
 
 	int save_log; // show loading/saving messages
 	int log_char;	// loggin char or not [devil]

+ 93 - 9
src/char/char_clif.c

@@ -19,6 +19,9 @@
 
 #include <stdlib.h>
 
+#if PACKETVER_SUPPORTS_PINCODE
+bool pincode_allowed( char* pincode );
+#endif
 
 //------------------------------------------------
 //Add On system
@@ -97,6 +100,7 @@ int chclif_parse_moveCharSlot( int fd, struct char_session_data* sd){
 	return 1;
 }
 
+#if PACKETVER_SUPPORTS_PINCODE
 /* pincode_sendstate transmist the pincode state to client
  * S 08b9 <seed>.L <aid>.L <state>.W (HC_SECOND_PASSWD_LOGIN)
  * state :
@@ -158,6 +162,76 @@ int chclif_parse_pincode_check( int fd, struct char_session_data* sd ){
 	return 1;
 }
 
+/*
+ * Helper function to check if a new pincode contains illegal characters or combinations
+ */
+bool pincode_allowed( char* pincode ){
+	int i;
+	char c, n, compare[PINCODE_LENGTH+1];
+
+	memset( compare, 0, PINCODE_LENGTH+1);
+
+	// Sanity check for bots to prevent errors
+	for( i = 0; i < PINCODE_LENGTH; i++ ){
+		c = pincode[i];
+
+		if( c < '0' || c > '9' ){
+			return false;
+		}
+	}
+
+	// Is it forbidden to use only the same character?
+	if( !charserv_config.pincode_config.pincode_allow_repeated ){
+		c = pincode[0];
+
+		// Check if the first character equals the rest of the input
+		for( i = 0; i < PINCODE_LENGTH; i++ ){
+			compare[i] = c;
+		}
+
+		if( strncmp( pincode, compare, PINCODE_LENGTH + 1 ) == 0 ){
+			return false;
+		}
+	}
+
+	// Is it forbidden to use a sequential combination of numbers?
+	if( !charserv_config.pincode_config.pincode_allow_sequential ){
+		c = pincode[0];
+
+		// Check if it is an ascending sequence
+		for( i = 0; i < PINCODE_LENGTH; i++ ){
+			n = c + i;
+
+			if( n > '9' ){
+				compare[i] = '0' + ( n - '9' ) - 1;
+			}else{
+				compare[i] = n;
+			}
+		}
+
+		if( strncmp( pincode, compare, PINCODE_LENGTH + 1 ) == 0 ){
+			return false;
+		}
+
+		// Check if it is an descending sequence
+		for( i = 0; i < PINCODE_LENGTH; i++ ){
+			n = c - i;
+
+			if( n < '0' ){
+				compare[i] = '9' - ( '0' - n ) + 1;
+			}else{
+				compare[i] = n;
+			}
+		}
+
+		if( strncmp( pincode, compare, PINCODE_LENGTH + 1 ) == 0 ){
+			return false;
+		}
+	}
+
+	return true;
+}
+
 /*
  * Client request to change pincode
  */
@@ -180,12 +254,16 @@ int chclif_parse_pincode_change( int fd, struct char_session_data* sd ){
 		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);
 		
-		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 );
+			chclif_pincode_sendstate( fd, sd, PINCODE_PASSED );
+		}else{
+			chclif_pincode_sendstate( fd, sd, PINCODE_ILLEGAL );
+		}
 	}
 	return 1;
 }
@@ -207,14 +285,18 @@ int chclif_parse_pincode_setnew( int fd, struct char_session_data* sd ){
 
 		char_pincode_decrypt( sd->pincode_seed, newpin );
 
-		chlogif_pincode_notifyLoginPinUpdate( sd->account_id, newpin );
-		strncpy( sd->pincode, newpin, strlen( newpin ) );
+		if( pincode_allowed(newpin) ){
+			chlogif_pincode_notifyLoginPinUpdate( sd->account_id, newpin );
+			strncpy( sd->pincode, newpin, strlen( newpin ) );
 
-		chclif_pincode_sendstate( fd, sd, PINCODE_PASSED );
+			chclif_pincode_sendstate( fd, sd, PINCODE_PASSED );	
+		}else{
+			chclif_pincode_sendstate( fd, sd, PINCODE_ILLEGAL );
+		}
 	}
 	return 1;
 }
-
+#endif
 
 //----------------------------------------
 // Tell client how many pages, kRO sends 17 (Yommy)
@@ -1150,11 +1232,13 @@ int chclif_parse(int fd) {
 			case 0x82b: next=chclif_parse_char_delete2_cancel(fd, sd); break;
 			// login as map-server
 			case 0x2af8: chclif_parse_maplogin(fd); return 0; // avoid processing of followup packets here
+#if PACKETVER_SUPPORTS_PINCODE
 			//pincode
 			case 0x8b8: next=chclif_parse_pincode_check( fd, sd ); break; // checks the entered pin
 			case 0x8c5: next=chclif_parse_reqpincode_window(fd,sd); break; // request for PIN window
 			case 0x8be: next=chclif_parse_pincode_change( fd, sd ); break; // pincode change request
 			case 0x8ba: next=chclif_parse_pincode_setnew( fd, sd ); break; // activate PIN system and set first PIN
+#endif
 			// character movement request
 			case 0x8d4: next=chclif_parse_moveCharSlot(fd,sd); break;
 			case 0x9a1: next=chclif_parse_req_charlist(fd,sd); break;

+ 2 - 0
src/char/char_clif.h

@@ -16,11 +16,13 @@ extern "C" {
 
 void chclif_moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short index, short reason );
 int chclif_parse_moveCharSlot( int fd, struct char_session_data* sd);
+#if PACKETVER_SUPPORTS_PINCODE
 void chclif_pincode_sendstate( int fd, struct char_session_data* sd, enum pincode_state state );
 int chclif_parse_reqpincode_window(int fd, struct char_session_data* sd);
 int chclif_parse_pincode_check( int fd, struct char_session_data* sd );
 int chclif_parse_pincode_change( int fd, struct char_session_data* sd );
 int chclif_parse_pincode_setnew( int fd, struct char_session_data* sd );
+#endif
 
 void chclif_reject(int fd, uint8 errCode);
 void chclif_refuse_delchar(int fd, uint8 errCode);

+ 4 - 0
src/char/char_logif.c

@@ -20,6 +20,7 @@
 void chlogif_on_ready(void);
 void chlogif_on_disconnect(void);
 
+#if PACKETVER_SUPPORTS_PINCODE
 void chlogif_pincode_notifyLoginPinError( uint32 account_id ){
 	if ( chlogif_isconnected() ){
 		WFIFOHEAD(login_fd,6);
@@ -76,6 +77,7 @@ void chlogif_pincode_start(int fd, struct char_session_data* sd){
 		chclif_pincode_sendstate( fd, sd, PINCODE_OK );
 	}
 }
+#endif
 
 /**
  * Load this character's account id into the 'online accounts' packet
@@ -365,8 +367,10 @@ int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){
 		} else {
 			// send characters to player
 			chclif_mmo_char_send(u_fd, sd);
+#if PACKETVER_SUPPORTS_PINCODE
 			if(sd->version >= date2version(20110309))
 				chlogif_pincode_start(u_fd,sd);
+#endif
 		}
 	}
 	RFIFOSKIP(fd,75);

+ 2 - 0
src/char/char_logif.h

@@ -14,9 +14,11 @@
 extern "C" {
 #endif
 
+#if PACKETVER_SUPPORTS_PINCODE
 void chlogif_pincode_notifyLoginPinError( uint32 account_id );
 void chlogif_pincode_notifyLoginPinUpdate( uint32 account_id, char* pin );
 void chlogif_pincode_start(int fd, struct char_session_data* sd);
+#endif
 int chlogif_send_acc_tologin(int tid, unsigned int tick, int id, intptr_t data);
 int chlogif_broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data);
 void chlogif_send_usercount(int users);

+ 3 - 0
src/common/mmo.h

@@ -25,6 +25,9 @@
 	//#define PACKETVER 20120410
 #endif
 
+// Check if the specified packetversion supports the pincode system
+#define PACKETVER_SUPPORTS_PINCODE PACKETVER>=20110309
+
 ///Remove/Comment this line to disable sc_data saving. [Skotlex]
 #define ENABLE_SC_SAVING
 /** Remove/Comment this line to disable server-side hot-key saving support [Skotlex]

+ 4 - 0
src/login/loginchrif.c

@@ -594,6 +594,7 @@ int logchrif_parse_setalloffline(int fd, int id){
 	return 1;
 }
 
+#if PACKETVER_SUPPORTS_PINCODE
 /**
  * Request to change PIN Code for an account.
  * @param fd: fd to parse from (char-serv)
@@ -642,6 +643,7 @@ int logchrif_parse_pincode_authfail(int fd){
 	}
 	return 1;
 }
+#endif
 
 /**
  * Received a vip data reqest from char
@@ -809,8 +811,10 @@ int logchrif_parse(int fd){
 			case 0x272e: next = logchrif_parse_req_global_accreg(fd); break;
 			case 0x2736: next = logchrif_parse_updcharip(fd,cid); break;
 			case 0x2737: next = logchrif_parse_setalloffline(fd,cid); break;
+#if PACKETVER_SUPPORTS_PINCODE
 			case 0x2738: next = logchrif_parse_updpincode(fd); break;
 			case 0x2739: next = logchrif_parse_pincode_authfail(fd); break;
+#endif
 			case 0x2742: next = logchrif_parse_reqvipdata(fd); break; //Vip sys
 			default:
 				ShowError("logchrif_parse: Unknown packet 0x%x from a char-server! Disconnecting!\n", command);