summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2014-02-08 04:05:03 +0100
committerHaru <haru@dotalux.com>2014-02-08 04:05:03 +0100
commite4a1ca28de80e221198854b745be71d256e1f7b1 (patch)
tree56ca439cbdbf31314f397fc85c4ddef7c2179d3e
parent2c72e01b827f4e17644bafc52154f6d76ef4a5b9 (diff)
downloadhercules-e4a1ca28de80e221198854b745be71d256e1f7b1.tar.gz
hercules-e4a1ca28de80e221198854b745be71d256e1f7b1.tar.bz2
hercules-e4a1ca28de80e221198854b745be71d256e1f7b1.tar.xz
hercules-e4a1ca28de80e221198854b745be71d256e1f7b1.zip
Improved client_hash_check
- Added option to disable hash check by GM group_id (specify 'disabled' as hash for a certain group_id to let them log in with any client, even if client_hash_check is enabled - Updated and reworded related documentation for the feature, following user feedback about certain parts being incomplete or confusing.
-rw-r--r--conf/login-server.conf15
-rw-r--r--doc/md5_hashcheck.txt46
-rw-r--r--src/login/login.c40
3 files changed, 67 insertions, 34 deletions
diff --git a/conf/login-server.conf b/conf/login-server.conf
index 5a5a3e049..06e0eb18b 100644
--- a/conf/login-server.conf
+++ b/conf/login-server.conf
@@ -136,14 +136,21 @@ dnsbl_servers: bl.blocklist.de, socks.dnsbl.sorbs.net
// Client MD5 hash check
// If turned on, the login server will check if the client's hash matches
// the value below, and will not connect tampered clients.
-// Note: see doc\md5_hashcheck.txt for more details.
+// Note: see doc/md5_hashcheck.txt for more details.
client_hash_check: off
// Client MD5 hashes
-// A player can login with a client hash at or below the account group_id.
+// The client with the specified hash can be used to log in by players with
+// a group_id equal to or greater than the given value.
+// If you specify 'disabled' as hash, players with a group_id greater than or
+// equal to the given value will be able to log in regardless of hash (and even
+// if their client does not send a hash at all.)
// Format: group_id, hash
-client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
-client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae
+// Note: see doc/md5_hashcheck.txt for more details.
+//client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
+//client_hash: 10, cb1ea78023d337c38e8ba5124e2338ae
+//client_hash: 99, disabled
+
import: conf/inter-server.conf
import: conf/import/login_conf.txt
diff --git a/doc/md5_hashcheck.txt b/doc/md5_hashcheck.txt
index 779785638..d9064b1ab 100644
--- a/doc/md5_hashcheck.txt
+++ b/doc/md5_hashcheck.txt
@@ -3,7 +3,7 @@
//===== By: ==================================================
//= Hercules Dev Team
//===== Current Version: =====================================
-//= 20120921
+//= 20140208
//===== Description: =========================================
//= This file outlines the login server's MD5 hash check.
//============================================================
@@ -13,26 +13,46 @@ This will ensure that a user has not tampered with the client and that
the client is the one specific to your server.
The client can only send the correct MD5 hash to the server on certain
-server types, so a client diff is required to ensure the hash is sent.
-A link containing the required WeeDiffGen plugin can be found at:
-http://rathena.org/board/topic/70841-r16771-client-md5-hash-check/
+server types, so a client diff may be required to ensure the hash is
+sent.
+Please refer to your client diff tool manual for the appropriate patch
+(i.e. in NEMO it's called "Force Send Client Hash Packet", in other
+tools or diffs it may have similar names.)
-The settings for the hash check are located in conf\login.conf:
+The serverside settings for the hash check are located in
+conf/login.conf:
// Client MD5 hash check
// If turned on, the login server will check if the client's hash matches
// the value below, and will not connect tampered clients.
-// Note: see doc\md5_hashcheck.txt for more details.
+// Note: see doc/md5_hashcheck.txt for more details.
client_hash_check: off
// Client MD5 hashes
-// A player can login with a client hash at or below the account group_id.
+// The client with the specified hash can be used to log in by players with
+// a group_id equal to or greater than the given value.
+// If you specify 'disabled' as hash, players with a group_id greater than or
+// equal to the given value will be able to log in regardless of hash (and even
+// if their client does not send a hash at all.)
// Format: group_id, hash
+// Note: see doc/md5_hashcheck.txt for more details.
client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
-client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae
+client_hash: 10, cb1ea78023d337c38e8ba5124e2338ae
+client_hash: 99, disabled
-To enable MD5 hash checks, set 'client_hash_check' to 'on'.
-The 'client_hash' group_id can be any of the groups in conf\groups.conf,
-and is particularly useful if you wanted to allow GMs a different client
-than normal players; for example, a GM client could be hexed differently
-with dual-clienting enabled and chat flood disabled.
+To enable MD5 hash checks, set 'client_hash_check' to 'on' and add one
+'client_hash' entry for each client you want to use.
+The group_id can be any of the groups in conf/groups.conf, and it is
+useful in case if you want to allow GMs to use a different client
+than normal players; for example, a GM client could be hexed
+differently, perhaps with dual-clienting enabled and chat flood
+disabled.
+You will need to replace the example MD5 hashes with the actual hash of
+your client.
+You can use any MD5 hash tools to generate it, e.g.:
+- md5sum (command line) on linux
+- WinMD5 on Windows
+- md5 (command line) on Mac OS X
+- If you hexed your client with NEMO (version 2.0 and above), you
+ can find the MD5 hash of the generated client automatically saved to
+ client_filename.exe.secure.txt
diff --git a/src/login/login.c b/src/login/login.c
index e9d0eac9d..249d008ec 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -977,27 +977,29 @@ int mmo_auth(struct login_session_data* sd, bool isServer) {
}
if( login_config.client_hash_check && !isServer ) {
- struct client_hash_node *node = login_config.client_hash_nodes;
+ struct client_hash_node *node = NULL;
bool match = false;
- if( !sd->has_client_hash ) {
- ShowNotice("Client doesn't sent client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
- return 5;
- }
-
- while( node ) {
- if( node->group_id <= acc.group_id && memcmp(node->hash, sd->client_hash, 16) == 0 ) {
+ for( node = login_config.client_hash_nodes; node; node = node->next ) {
+ if( acc.group_id < node->group_id )
+ continue;
+ if( *node->hash == '\0' // Allowed to login without hash
+ || (sd->has_client_hash && memcmp(node->hash, sd->client_hash, 16) == 0 ) // Correct hash
+ ) {
match = true;
break;
}
-
- node = node->next;
}
if( !match ) {
char smd5[33];
int i;
+ if( !sd->has_client_hash ) {
+ ShowNotice("Client didn't send client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
+ return 5;
+ }
+
for( i = 0; i < 16; i++ )
sprintf(&smd5[i * 2], "%02x", sd->client_hash[i]);
@@ -1607,15 +1609,19 @@ int login_config_read(const char* cfgName)
int i;
CREATE(nnode, struct client_hash_node, 1);
- for (i = 0; i < 32; i += 2) {
- char buf[3];
- unsigned int byte;
+ if (strcmpi(md5, "disabled") == 0) {
+ nnode->hash[0] = '\0';
+ } else {
+ for (i = 0; i < 32; i += 2) {
+ char buf[3];
+ unsigned int byte;
- memcpy(buf, &md5[i], 2);
- buf[2] = 0;
+ memcpy(buf, &md5[i], 2);
+ buf[2] = 0;
- sscanf(buf, "%x", &byte);
- nnode->hash[i / 2] = (uint8)(byte & 0xFF);
+ sscanf(buf, "%x", &byte);
+ nnode->hash[i / 2] = (uint8)(byte & 0xFF);
+ }
}
nnode->group_id = group;