diff --git a/server/access.c b/server/access.c index 6ca9f4af..79255cfb 100644 --- a/server/access.c +++ b/server/access.c @@ -227,10 +227,12 @@ add_source_mask(fko_srv_options_t *opts, acc_stanza_t *acc, const char *ip) { char *ndx; char ip_str[MAX_IPV4_STR_LEN] = {0}; + char ip_mask_str[MAX_IPV4_STR_LEN] = {0}; uint32_t mask; - int is_err; + int is_err, mask_len = 0, need_shift = 1; struct in_addr in; + struct in_addr mask_in; acc_int_list_t *last_sle, *new_sle, *tmp_sle; @@ -242,7 +244,7 @@ add_source_mask(fko_srv_options_t *opts, acc_stanza_t *acc, const char *ip) clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE); } - /* Convert the IP data into the appropriate mask + /* Convert the IP data into the appropriate IP + (optional) mask */ if(strcasecmp(ip, "ANY") == 0) { @@ -264,13 +266,57 @@ add_source_mask(fko_srv_options_t *opts, acc_stanza_t *acc, const char *ip) return 0; } - mask = strtol_wrapper(ndx+1, 1, 32, NO_EXIT_UPON_ERR, &is_err); - if(is_err != FKO_SUCCESS) + mask_len = strlen(ip) - (ndx-ip+1); + + if(mask_len > 2) { - log_msg(LOG_ERR, "[*] Invalid IP mask str '%s'.", ndx+1); - free(new_sle); - new_sle = NULL; - return 0; + if(mask_len >= MIN_IPV4_STR_LEN && mask_len < MAX_IPV4_STR_LEN) + { + /* IP formatted mask + */ + strlcpy(ip_mask_str, (ip + (ndx-ip) + 1), mask_len+1); + if(inet_aton(ip_mask_str, &mask_in) == 0) + { + log_msg(LOG_ERR, + "[*] Fatal error parsing IP mask to int for: %s", ip_mask_str + ); + free(new_sle); + new_sle = NULL; + return 0; + } + mask = ntohl(mask_in.s_addr); + need_shift = 0; + } + else + { + log_msg(LOG_ERR, "[*] Invalid IP mask str '%s'.", ndx+1); + free(new_sle); + new_sle = NULL; + return 0; + } + } + else + { + if(mask_len > 0) + { + /* CIDR mask + */ + mask = strtol_wrapper(ndx+1, 1, 32, NO_EXIT_UPON_ERR, &is_err); + if(is_err != FKO_SUCCESS) + { + log_msg(LOG_ERR, "[*] Invalid IP mask str '%s'.", ndx+1); + free(new_sle); + new_sle = NULL; + return 0; + } + } + else + { + log_msg(LOG_ERR, "[*] Missing mask value."); + free(new_sle); + new_sle = NULL; + return 0; + } } strlcpy(ip_str, ip, (ndx-ip)+1); @@ -302,7 +348,10 @@ add_source_mask(fko_srv_options_t *opts, acc_stanza_t *acc, const char *ip) /* Store our mask converted from CIDR to a 32-bit value. */ - new_sle->mask = (0xFFFFFFFF << (32 - mask)); + if(need_shift) + new_sle->mask = (0xFFFFFFFF << (32 - mask)); + else + new_sle->mask = mask; /* Store our masked address for comparisons with future incoming * packets. @@ -768,7 +817,7 @@ expand_acc_ent_lists(fko_srv_options_t *opts) */ while(acc) { - /* Expand the source string to 32-bit integer masks foreach entry. + /* Expand the source string to 32-bit integer IP + masks for each entry. */ if(expand_acc_source(opts, acc) == 0) { diff --git a/test/conf/client-gpg-no-pw/trustdb.gpg b/test/conf/client-gpg-no-pw/trustdb.gpg index 58ec2d6d..4c30150c 100644 Binary files a/test/conf/client-gpg-no-pw/trustdb.gpg and b/test/conf/client-gpg-no-pw/trustdb.gpg differ diff --git a/test/tests/basic_operations.pl b/test/tests/basic_operations.pl index fd843257..7e3f52e8 100644 --- a/test/tests/basic_operations.pl +++ b/test/tests/basic_operations.pl @@ -2066,6 +2066,71 @@ ], 'positive_output_matches' => [qr/Error\sparsing.*IP/], }, + { + 'category' => 'basic operations', + 'subcategory' => 'server', + 'detail' => 'access SOURCE format (3)', + 'function' => \&server_conf_files, + 'fwknopd_cmdline' => $server_rewrite_conf_files, + 'exec_err' => $YES, + 'server_access_file' => [ + 'SOURCE 123.123.123.123/255.255.255.258', + 'KEY testtest' + ], + 'server_conf_file' => [ + '### comment line' + ], + 'positive_output_matches' => [qr/error\sparsing.*IP/], + }, + { + 'category' => 'basic operations', + 'subcategory' => 'server', + 'detail' => 'access SOURCE format (4)', + 'function' => \&server_conf_files, + 'fwknopd_cmdline' => $server_rewrite_conf_files, + 'exec_err' => $YES, + 'server_access_file' => [ + 'SOURCE 123.123.123.123/33', + 'KEY testtest' + ], + 'server_conf_file' => [ + '### comment line' + ], + 'positive_output_matches' => [qr/Invalid\sIP\smask/], + }, + { + 'category' => 'basic operations', + 'subcategory' => 'server', + 'detail' => 'access SOURCE format (5)', + 'function' => \&server_conf_files, + 'fwknopd_cmdline' => $server_rewrite_conf_files, + 'exec_err' => $YES, + 'server_access_file' => [ + 'SOURCE 1.1.1.1/1234.1.1.1', + 'KEY testtest' + ], + 'server_conf_file' => [ + '### comment line' + ], + 'positive_output_matches' => [qr/error\sparsing.*IP/], + }, + { + 'category' => 'basic operations', + 'subcategory' => 'server', + 'detail' => 'access SOURCE format (6)', + 'function' => \&server_conf_files, + 'fwknopd_cmdline' => $server_rewrite_conf_files, + 'exec_err' => $YES, + 'server_access_file' => [ + 'SOURCE 1.1.1.1/255.255.255.0, 2.2.2.2/33, 123.123.123.123/24', + 'KEY testtest' + ], + 'server_conf_file' => [ + '### comment line' + ], + 'positive_output_matches' => [qr/Invalid\sIP\smask/], + }, + { 'category' => 'basic operations', 'subcategory' => 'server',