Преглед на файлове

Added missing session auth checks to charserver.
Packets from non-authed clients will now be discarded.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@12034 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage преди 17 години
родител
ревизия
b3696e2e03
променени са 3 файла, в които са добавени 31 реда и са изтрити 14 реда
  1. 2 0
      Changelog-Trunk.txt
  2. 15 7
      src/char/char.c
  3. 14 7
      src/char_sql/char.c

+ 2 - 0
Changelog-Trunk.txt

@@ -4,6 +4,8 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2008/01/08
+	* Added missing session auth checks to charserver. [ultramage]
+	  Packets from non-authed clients will now be discarded.
 	* Fixed Wand of Hermod not starting the SC_HERMOD status change (which
 	  blocks spells)
 	* Fixed additional def/mdef from vit/int bonuses being lost when a status

+ 15 - 7
src/char/char.c

@@ -104,8 +104,9 @@ struct s_subnet {
 int subnet_count = 0;
 
 struct char_session_data {
+	bool auth; // whether the session is authed or not
 	int account_id, login_id1, login_id2, sex;
-	int found_char[MAX_CHARS];
+	int found_char[MAX_CHARS]; // ids of chars on this account
 	char email[40]; // e-mail (default: a@a.com) by [Yor]
 	time_t connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
 };
@@ -1735,8 +1736,6 @@ int mmo_char_send006b(int fd, struct char_session_data* sd)
 {
 	int i, j, found_num;
 
-	set_char_online(-1, 99, sd->account_id);
-
 	found_num = 0;
 	for(i = 0; i < char_num; i++) {
 		if (char_dat[i].status.account_id == sd->account_id) {
@@ -1912,7 +1911,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
 		return;
 	}
 
-	if (online_check && (character = idb_get(online_char_db, sd->account_id)))
+	if( online_check && (character = idb_get(online_char_db, sd->account_id)) != NULL )
 	{	// check if character is not online already. [Skotlex]
 		if (character->server > -1)
 		{	//Character already online. KICK KICK KICK
@@ -1933,13 +1932,22 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
 		}
 		character->fd = fd;
 	}
+
 	if (login_fd > 0) {
 		// request to login-server to obtain e-mail/time limit
+		//FIXME: isn't this part of the auth_ok packet? [ultramage]
 		WFIFOHEAD(login_fd,6);
 		WFIFOW(login_fd,0) = 0x2716;
 		WFIFOL(login_fd,2) = sd->account_id;
 		WFIFOSET(login_fd,6);
 	}
+
+	// mark session as 'authed'
+	sd->auth = true;
+
+	// set char online on charserver
+	set_char_online(-1, 99, sd->account_id);
+
 	// send characters to player
 	mmo_char_send006b(fd, sd);
 }
@@ -3242,7 +3250,7 @@ int parse_char(int fd)
 	while( RFIFOREST(fd) >= 2 )
 	{
 		//For use in packets that depend on an sd being present [Skotlex]
-		#define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL) { RFIFOSKIP(fd,rest); return 0; } }
+		#define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,rest); return 0; } }
 
 		cmd = RFIFOW(fd,0);
 		switch( cmd )
@@ -3276,6 +3284,7 @@ int parse_char(int fd)
 			sd->login_id1 = RFIFOL(fd,6);
 			sd->login_id2 = RFIFOL(fd,10);
 			sd->sex = RFIFOB(fd,16);
+			sd->auth = false; // not authed yet
 
 			// send back account_id
 			WFIFOHEAD(fd,4);
@@ -3606,8 +3615,7 @@ int parse_char(int fd)
 		// char rename request
 		// R 028d <account ID>.l <char ID>.l <new name>.24B
 		case 0x28d:
-			if (RFIFOREST(fd) < 34)
-				return 0;
+			FIFOSD_CHECK(34);
 			//not implemented
 			RFIFOSKIP(fd,34);
 		break;

+ 14 - 7
src/char_sql/char.c

@@ -133,8 +133,9 @@ struct s_subnet {
 int subnet_count = 0;
 
 struct char_session_data {
+	bool auth; // whether the session is authed or not
 	int account_id, login_id1, login_id2, sex;
-	int found_char[MAX_CHARS];
+	int found_char[MAX_CHARS]; // ids of chars on this account
 	char email[40]; // e-mail (default: a@a.com) by [Yor]
 	time_t connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
 };
@@ -1488,8 +1489,6 @@ int mmo_char_send006b(int fd, struct char_session_data* sd)
 {
 	int j;
 
-	set_char_online(-1, 99, sd->account_id);
-
 	if (save_log)
 		ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
 
@@ -1581,7 +1580,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
 		return;
 	}
 
-	if (online_check && (character = idb_get(online_char_db, sd->account_id)))
+	if( online_check && (character = idb_get(online_char_db, sd->account_id)) != NULL )
 	{	// check if character is not online already. [Skotlex]
 		if (character->server > -1)
 		{	//Character already online. KICK KICK KICK
@@ -1602,6 +1601,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
 		}
 		character->fd = fd;
 	}
+
 	if (login_fd > 0) {
 		// request to login-server to obtain e-mail/time limit
 		WFIFOHEAD(login_fd,6);
@@ -1609,6 +1609,13 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
 		WFIFOL(login_fd,2) = sd->account_id;
 		WFIFOSET(login_fd,6);
 	}
+
+	// mark session as 'authed'
+	sd->auth = true;
+
+	// set char online on charserver
+	set_char_online(-1, 99, sd->account_id);
+
 	// send characters to player
 	mmo_char_send006b(fd, sd);
 }
@@ -2817,7 +2824,7 @@ int parse_char(int fd)
 	while( RFIFOREST(fd) >= 2 )
 	{
 		//For use in packets that depend on an sd being present [Skotlex]
-		#define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL) { RFIFOSKIP(fd,rest); return 0; } }
+		#define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,rest); return 0; } }
 
 		cmd = RFIFOW(fd,0);
 		switch( cmd )
@@ -2844,6 +2851,7 @@ int parse_char(int fd)
 			sd->login_id1 = RFIFOL(fd,6);
 			sd->login_id2 = RFIFOL(fd,10);
 			sd->sex = RFIFOB(fd,16);
+			sd->auth = false; // not authed yet
 
 			// send back account_id
 			WFIFOHEAD(fd,4);
@@ -3155,8 +3163,7 @@ int parse_char(int fd)
 		// char rename request
 		// R 028d <account ID>.l <char ID>.l <new name>.24B 
 		case 0x28d:
-			if (RFIFOREST(fd) < 34)
-				return 0;
+			FIFOSD_CHECK(34);
 			//not implemented
 			RFIFOSKIP(fd,34);
 		break;