Permalink
Browse files

Fixed a very old login/char authentication exploit (r12034)

git-svn-id: http://eathena.googlecode.com/svn/branches/stable@12039 9c4de8d1-4af9-ca9b-867f-b47ac08f6c80
  • Loading branch information...
ultramage
ultramage committed Jan 9, 2008
1 parent 3be2d4d commit d1fdddf36d913b7c85dcb9ed186a092a43fcec46
Showing with 29 additions and 18 deletions.
  1. +1 −0 Changelog-Stable.txt
  2. +14 −9 src/char/char.c
  3. +14 −9 src/char_sql/char.c
@@ -5,6 +5,7 @@ GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS
WELL AS TRUNK. EVERYTHING ELSE GOES INTO TRUNK

2008/01/09
* Fixed a very old login/char authentication exploit (r12034)
* Fixed a memleak when using string variables (r11997)
* The memory manager can now destroy deleted data (r11994 and followups)
2008/01/07
@@ -104,9 +104,9 @@ struct s_subnet {
int subnet_count = 0;

struct char_session_data {
int fd;
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)
};
@@ -1736,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) {
@@ -1913,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
@@ -1934,13 +1932,21 @@ 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);
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 +3248,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 )
@@ -3270,13 +3276,13 @@ int parse_char(int fd)

CREATE(session[fd]->session_data, struct char_session_data, 1);
sd = (struct char_session_data*)session[fd]->session_data;
sd->fd = fd;
strncpy(sd->email, "no mail", 40); // put here a mail without '@' to refuse deletion if we don't receive the e-mail
sd->connect_until_time = 0; // unknown or unlimited (not displaying on map-server)
sd->account_id = RFIFOL(fd,2);
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);
@@ -3607,8 +3613,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;
@@ -132,9 +132,9 @@ struct s_subnet {
int subnet_count = 0;

struct char_session_data {
int fd;
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)
};
@@ -1487,8 +1487,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);

@@ -1580,7 +1578,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
@@ -1601,13 +1599,21 @@ 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);
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);
}
@@ -2819,7 +2825,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 )
@@ -2841,12 +2847,12 @@ int parse_char(int fd)

CREATE(session[fd]->session_data, struct char_session_data, 1);
sd = (struct char_session_data*)session[fd]->session_data;
sd->fd = fd;
sd->connect_until_time = 0; // unknown or unlimited (not displaying on map-server)
sd->account_id = RFIFOL(fd,2);
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);
@@ -3158,8 +3164,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;

0 comments on commit d1fdddf

Please sign in to comment.