summaryrefslogtreecommitdiff
path: root/src/elogin/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/elogin/parse.c')
-rw-r--r--src/elogin/parse.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/src/elogin/parse.c b/src/elogin/parse.c
new file mode 100644
index 0000000..8f62e9f
--- /dev/null
+++ b/src/elogin/parse.c
@@ -0,0 +1,210 @@
+// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// Copyright (c) 2014 Evol developers
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common/HPMi.h"
+#include "common/malloc.h"
+#include "common/mmo.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "login/account.h"
+#include "login/login.h"
+
+#include "ecommon/ip.h"
+#include "elogin/config.h"
+#include "elogin/md5calc.h"
+#include "elogin/parse.h"
+#include "elogin/send.h"
+
+int clientVersion = 0;
+
+void login_parse_version(int fd)
+{
+ struct login_session_data* sd = (struct login_session_data*)session[fd]->session_data;
+ if (!sd)
+ return;
+
+ clientVersion = RFIFOL(fd, 2);
+
+ if (clientVersion < 2)
+ {
+ login->login_error(fd, 5);
+ return;
+ }
+
+ send_update_host(fd);
+ send_server_version(fd);
+}
+
+int elogin_parse_client_login_pre(int *fdPtr,
+ struct login_session_data* sd __attribute__ ((unused)),
+ const char *const ip __attribute__ ((unused)))
+{
+ int fd = *fdPtr;
+ uint16 command = RFIFOW(fd,0);
+ if (command != 0x64)
+ {
+ login->login_error(fd, 3);
+ hookStop();
+ return 1;
+ }
+ char username[NAME_LENGTH];
+ safestrncpy(username, (const char*)RFIFOP(fd, 6), NAME_LENGTH);
+ int len = strnlen(username, NAME_LENGTH);
+ if (clientVersion < 2)
+ {
+ login->login_error(fd, 5);
+ hookStop();
+ return 1;
+ }
+ else if (len >= 2 && username[len - 2] == '_' && memchr("FfMm", username[len - 1], 4))
+ {
+ login->login_error(fd, 3);
+ hookStop();
+ return 1;
+ }
+
+ return 0;
+}
+
+void elogin_parse_client_login2(int fd)
+{
+ char username[NAME_LENGTH];
+ char password[PASSWD_LEN];
+ char email[40];
+ uint8 clienttype;
+ int result;
+
+ safestrncpy(username, (const char*)RFIFOP(fd, 2), NAME_LENGTH);
+
+ int len = strnlen(username, NAME_LENGTH);
+ if (len < 2 || !(username[len - 2] == '_') || !memchr("FfMm", username[len - 1], 4))
+ {
+ login->login_error(fd, 3);
+ return;
+ }
+
+ safestrncpy(password, (const char*)RFIFOP(fd, 26), NAME_LENGTH);
+ safestrncpy(email, (const char*)RFIFOP(fd, 51), 40);
+ clienttype = RFIFOB(fd, 50);
+
+ struct login_session_data* sd = (struct login_session_data*)session[fd]->session_data;
+ if (!sd)
+ return;
+
+ char ip[16];
+ uint32 ipl = session[fd]->client_addr;
+ ip2str(ipl, ip);
+ sd->clienttype = clienttype;
+ sd->version = clientVersion;
+ sd->passwdenc = 0;
+ safestrncpy(sd->userid, username, NAME_LENGTH);
+ ShowStatus("Request for connection of %s (ip: %s).\n", sd->userid, ip);
+ safestrncpy(sd->passwd, password, PASSWD_LEN);
+
+ if (e_mail_check(email) == 0)
+ {
+ ShowNotice("Attempt to create an e-mail REFUSED - e-mail is invalid (ip: %s)\n", ip);
+ login->login_error(fd, 11);
+ return;
+ }
+
+ result = login->mmo_auth(sd, false);
+
+ if (result == -1)
+ {
+ int account_id = sd->account_id;
+ struct mmo_account acc;
+ if (!login->accounts->load_num(login->accounts, &acc, account_id))
+ {
+ ShowNotice("Attempt to create an e-mail on an account REFUSED - account: %d, ip: %s).\n", account_id, ip);
+ }
+ else
+ {
+ memcpy(acc.email, email, 40);
+ ShowNotice("Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", account_id, email, ip);
+ // Save
+ login->accounts->save(login->accounts, &acc);
+ }
+
+ login->auth_ok(sd);
+ }
+ else
+ {
+ login->auth_failed(sd, result);
+ }
+
+ return;
+}
+
+void elogin_parse_request_connection(int *fd, struct login_session_data* sd, const char *const ip)
+{
+ if (!inter_server_ip || !ip)
+ return;
+ if (!checkAllowedIp(inter_server_ip, ip))
+ {
+ hookStop();
+ login->char_server_connection_status(*fd, sd, 3);
+ ShowNotice("Connection of the char-server from ip %s REFUSED.\n", ip);
+ }
+}
+
+void elogin_parse_ping(int *fd, struct login_session_data* sd)
+{
+ RFIFOSKIP(*fd, 26);
+ if (!sd)
+ {
+ hookStop();
+ return;
+ }
+ struct online_login_data* data = (struct online_login_data*)idb_get(login->online_db, sd->account_id);
+ if (data == NULL)
+ {
+ hookStop();
+ return;
+ }
+ if (data->waiting_disconnect != INVALID_TIMER)
+ {
+ timer->delete(data->waiting_disconnect, login->waiting_disconnect_timer);
+ data->waiting_disconnect = timer->add(timer->gettick() + 30000, login->waiting_disconnect_timer, sd->account_id, 0);
+ }
+ hookStop();
+}
+
+void elogin_parse_change_paassword(int fd)
+{
+ char actual_pass[24], new_pass[24];
+ int status = 0;
+ struct mmo_account acc;
+ const int accountId = RFIFOL (fd, 2);
+
+ memcpy (actual_pass, RFIFOP (fd, 6), 24);
+ actual_pass[23] = '\0';
+ memcpy (new_pass, RFIFOP (fd, 30), 24);
+ new_pass[23] = '\0';
+
+ if (!login->accounts->load_num(login->accounts, &acc, accountId))
+ {
+ // account not found
+ send_char_password_change_ack(fd, accountId, 0);
+ return;
+ }
+
+ if (!strcmp(actual_pass, acc.pass) || pass_ok(actual_pass, acc.pass))
+ {
+ // changed ok
+ status = 1;
+ safestrncpy(acc.pass, new_pass, sizeof(acc.pass));
+ login->accounts->save(login->accounts, &acc);
+ }
+ else
+ {
+ // wrong password
+ status = 2;
+ }
+ send_char_password_change_ack(fd, accountId, status);
+}