Skip to content

Commit

Permalink
subnet.conf overhaul
Browse files Browse the repository at this point in the history
The subnet.conf system has been rewritten to offer greater flexibility,
and to fix some issues that appeared with 838321a.

It is now possible to enter, separately, LAN subnets:

- `lan_subnets`: This is essentially the same feature present in the old
  subnet.conf. Each entry in this list defines a (LAN, private) subnet
  the server is in. Clients connecting from the same subnet, will be
  redirected to the LAN IP rather than the default public IP. The format
  has been simplified, and it only requires one IP and one subnet mask (as
  opposed to a character and a map server IP).
- `allowed`: Allowed IPs are IP ranges a server (char to login or map to
  char) can connect from. Any attempt to connect as a server from an IP
  not included here, will fail. For convenience, a wildcard range
  (matching all possible IP addresses) has been provided
  (`0.0.0.0:0.0.0.0`), but it is very advisable to edit it to a more
  restrictive set.
- `trusted`: Trusted IPs are IP ranges excluded from the IPban checks.
  This may be useful, for example, to exclude the server's own IP from
  ipbans, in case of false positives. Any IP ranges added to this list are
  also implicitly included in the allowed IP ranges.
  • Loading branch information
MishimaHaruna committed Aug 11, 2015
1 parent a8e54e5 commit e13f1f7
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 184 deletions.
37 changes: 37 additions & 0 deletions conf/network.conf
@@ -0,0 +1,37 @@
// Network configuration file

/*
* List here any LAN subnets this server is in.
* Example:
* - char- (or map-) server's IP in LAN is 192.168.0.10
* - Public IP is 198.51.100.37
* If the list contains "192.168.0.10:255.255.255.0", any clients connecting
* from the same 192.168.0.0/24 network will be presented with the LAN IP
* (192.168.0.10) in the server list, rather than the public IP (198.51.100.37).
*/
lan_subnets: (
"127.0.0.1:255.0.0.0",
// "192.168.1.1:255.255.255.0",
)

/*
* List here any IP ranges a char- or map-server can connect from.
* A wildcard of "0.0.0.0:0.0.0.0" means that server connections are allowed
* from ANY IP. (not recommended).
*/
allowed: (
"0.0.0.0:0.0.0.0",
// "127.0.0.1:255.0.0.0",
)

/*
* List here any IP ranges a char- or map-server can connect from. These ranges
* will also be excluded from the automatic ipban in casee of password failure.
* Any entry present in this list is also automatically included in the
* allowed IP list.
* Note: This may be a security threat. Only edit this list if you know what
* you are doing.
*/
trusted: (
"127.0.0.1:255.0.0.0",
)
7 changes: 0 additions & 7 deletions conf/subnet.conf

This file was deleted.

113 changes: 26 additions & 87 deletions src/char/char.c
Expand Up @@ -121,14 +121,6 @@ int log_inter = 1; // logging inter or not [devil]

int char_aegis_delete = 0; // Verify if char is in guild/party or char and reacts as Aegis does (doesn't allow deletion), see chr->delete2_req for more information

// Advanced subnet check [LuzZza]
struct s_subnet {
uint32 mask;
uint32 char_ip;
uint32 map_ip;
} subnet[16];
int subnet_count = 0;

int max_connect_user = -1;
int gm_allow_group = -1;
int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
Expand Down Expand Up @@ -4171,20 +4163,22 @@ static int char_mapif_init(int fd)
return inter->mapif_init(fd);
}

//--------------------------------------------
// Test to know if an IP come from LAN or WAN.
//--------------------------------------------
int char_lan_subnetcheck(uint32 ip)
/**
* Checks whether the given IP comes from LAN or WAN.
*
* @param ip IP address to check.
* @retval 0 if it is a WAN IP.
* @return the appropriate LAN server address to send, if it is a LAN IP.
*/
uint32 char_lan_subnet_check(uint32 ip)
{
int i;
ARR_FIND( 0, subnet_count, i, (subnet[i].char_ip & subnet[i].mask) == (ip & subnet[i].mask) );
if( i < subnet_count ) {
ShowInfo("Subnet check [%u.%u.%u.%u]: Matches "CL_CYAN"%u.%u.%u.%u/%u.%u.%u.%u"CL_RESET"\n", CONVIP(ip), CONVIP(subnet[i].char_ip & subnet[i].mask), CONVIP(subnet[i].mask));
return subnet[i].map_ip;
} else {
ShowInfo("Subnet check [%u.%u.%u.%u]: "CL_CYAN"WAN"CL_RESET"\n", CONVIP(ip));
return 0;
struct s_subnet lan = {0};
if (sockt->lan_subnet_check(ip, &lan)) {
ShowInfo("Subnet check [%u.%u.%u.%u]: Matches "CL_CYAN"%u.%u.%u.%u/%u.%u.%u.%u"CL_RESET"\n", CONVIP(ip), CONVIP(lan.ip & lan.mask), CONVIP(lan.mask));
return lan.ip;
}
ShowInfo("Subnet check [%u.%u.%u.%u]: "CL_CYAN"WAN"CL_RESET"\n", CONVIP(ip));
return 0;
}


Expand Down Expand Up @@ -4662,7 +4656,7 @@ void char_parse_char_select(int fd, struct char_session_data* sd, uint32 ipl)
return;
}

subnet_map_ip = chr->lan_subnetcheck(ipl); // Advanced subnet check [LuzZza]
subnet_map_ip = chr->lan_subnet_check(ipl);
//Send player to map
chr->send_map_info(fd, i, subnet_map_ip, cd);

Expand Down Expand Up @@ -4971,7 +4965,7 @@ void char_parse_char_login_map_server(int fd, uint32 ipl)
i == ARRAYLENGTH(chr->server) ||
strcmp(l_user, chr->userid) != 0 ||
strcmp(l_pass, chr->passwd) != 0 ||
!chr->lan_subnetcheck(ipl))
!sockt->allowed_ip_check(ipl))
{
chr->login_map_server_ack(fd, 3); // Failure
} else {
Expand Down Expand Up @@ -5449,60 +5443,6 @@ static int char_online_data_cleanup(int tid, int64 tick, int id, intptr_t data)
return 0;
}

//----------------------------------
// Reading LAN Support configuration
// Rewrote: Advanced subnet check [LuzZza]
//----------------------------------
int char_lan_config_read(const char *lancfgName)
{
FILE *fp;
int line_num = 0;
char line[1024], w1[64], w2[64], w3[64], w4[64];

if((fp = fopen(lancfgName, "r")) == NULL) {
ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName);
return 1;
}

while(fgets(line, sizeof(line), fp)) {
line_num++;
if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n')
continue;

if (sscanf(line,"%63[^:]: %63[^:]:%63[^:]:%63[^\r\n]", w1, w2, w3, w4) != 4) {

ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num);
continue;
}

remove_control_chars(w1);
remove_control_chars(w2);
remove_control_chars(w3);
remove_control_chars(w4);

if( strcmpi(w1, "subnet") == 0 )
{
subnet[subnet_count].mask = str2ip(w2);
subnet[subnet_count].char_ip = str2ip(w3);
subnet[subnet_count].map_ip = str2ip(w4);

if( (subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip & subnet[subnet_count].mask) )
{
ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
continue;
}

subnet_count++;
}
}

if( subnet_count > 1 ) /* only useful if there is more than 1 */
ShowStatus("Read information about %d subnetworks.\n", subnet_count);

fclose(fp);
return 0;
}

void char_sql_config_read(const char* cfgName)
{
char line[1024], w1[1024], w2[1024];
Expand Down Expand Up @@ -5826,7 +5766,7 @@ int do_final(void) {
aFree(chr->server[i].map);

aFree(chr->CHAR_CONF_NAME);
aFree(chr->LAN_CONF_NAME);
aFree(chr->NET_CONF_NAME);
aFree(chr->SQL_CONF_NAME);
aFree(chr->INTER_CONF_NAME);

Expand Down Expand Up @@ -5911,15 +5851,15 @@ static CMDLINEARG(interconfig)
return true;
}
/**
* --lan-config handler
* --net-config handler
*
* Overrides the default subnet configuration file.
* Overrides the default network configuration file.
* @see cmdline->exec
*/
static CMDLINEARG(lanconfig)
static CMDLINEARG(netconfig)
{
aFree(chr->LAN_CONF_NAME);
chr->LAN_CONF_NAME = aStrdup(params);
aFree(chr->NET_CONF_NAME);
chr->NET_CONF_NAME = aStrdup(params);
return true;
}
/**
Expand All @@ -5929,7 +5869,7 @@ void cmdline_args_init_local(void)
{
CMDLINEARG_DEF2(char-config, charconfig, "Alternative char-server configuration.", CMDLINE_OPT_PARAM);
CMDLINEARG_DEF2(inter-config, interconfig, "Alternative inter-server configuration.", CMDLINE_OPT_PARAM);
CMDLINEARG_DEF2(lan-config, lanconfig, "Alternative subnet configuration.", CMDLINE_OPT_PARAM);
CMDLINEARG_DEF2(net-config, netconfig, "Alternative network configuration.", CMDLINE_OPT_PARAM);
}

int do_init(int argc, char **argv) {
Expand All @@ -5939,7 +5879,7 @@ int do_init(int argc, char **argv) {
char_load_defaults();

chr->CHAR_CONF_NAME = aStrdup("conf/char-server.conf");
chr->LAN_CONF_NAME = aStrdup("conf/subnet.conf");
chr->NET_CONF_NAME = aStrdup("conf/network.conf");
chr->SQL_CONF_NAME = aStrdup("conf/inter-server.conf");
chr->INTER_CONF_NAME = aStrdup("conf/inter-server.conf");

Expand All @@ -5958,7 +5898,7 @@ int do_init(int argc, char **argv) {

cmdline->exec(argc, argv, CMDLINE_OPT_NORMAL);
chr->config_read(chr->CHAR_CONF_NAME);
chr->lan_config_read(chr->LAN_CONF_NAME);
sockt->net_config_read(chr->NET_CONF_NAME);
chr->sql_config_read(chr->SQL_CONF_NAME);

if (strcmp(chr->userid, "s1")==0 && strcmp(chr->passwd, "p1")==0) {
Expand Down Expand Up @@ -6194,7 +6134,7 @@ void char_defaults(void)
chr->parse_frommap = char_parse_frommap;
chr->search_mapserver = char_search_mapserver;
chr->mapif_init = char_mapif_init;
chr->lan_subnetcheck = char_lan_subnetcheck;
chr->lan_subnet_check = char_lan_subnet_check;
chr->delete2_ack = char_delete2_ack;
chr->delete2_accept_actual_ack = char_delete2_accept_actual_ack;
chr->delete2_accept_ack = char_delete2_accept_ack;
Expand Down Expand Up @@ -6243,7 +6183,6 @@ void char_defaults(void)
chr->check_connect_login_server = char_check_connect_login_server;
chr->online_data_cleanup_sub = char_online_data_cleanup_sub;
chr->online_data_cleanup = char_online_data_cleanup;
chr->lan_config_read = char_lan_config_read;
chr->sql_config_read = char_sql_config_read;
chr->config_dispatch = char_config_dispatch;
chr->config_read = char_config_read;
Expand Down
5 changes: 2 additions & 3 deletions src/char/char.h
Expand Up @@ -145,7 +145,7 @@ struct char_interface {
int new_display;

char *CHAR_CONF_NAME;
char *LAN_CONF_NAME;
char *NET_CONF_NAME; ///< Network config filename
char *SQL_CONF_NAME;
char *INTER_CONF_NAME;

Expand Down Expand Up @@ -256,7 +256,7 @@ struct char_interface {
int (*parse_frommap) (int fd);
int (*search_mapserver) (unsigned short map, uint32 ip, uint16 port);
int (*mapif_init) (int fd);
int (*lan_subnetcheck) (uint32 ip);
uint32 (*lan_subnet_check) (uint32 ip);
void (*delete2_ack) (int fd, int char_id, uint32 result, time_t delete_date);
void (*delete2_accept_actual_ack) (int fd, int char_id, uint32 result);
void (*delete2_accept_ack) (int fd, int char_id, uint32 result);
Expand Down Expand Up @@ -305,7 +305,6 @@ struct char_interface {
int (*check_connect_login_server) (int tid, int64 tick, int id, intptr_t data);
int (*online_data_cleanup_sub) (DBKey key, DBData *data, va_list ap);
int (*online_data_cleanup) (int tid, int64 tick, int id, intptr_t data);
int (*lan_config_read) (const char *lancfgName);
void (*sql_config_read) (const char* cfgName);
void (*config_dispatch) (char *w1, char *w2);
int (*config_read) (const char* cfgName);
Expand Down

0 comments on commit e13f1f7

Please sign in to comment.