Added FORCE_NAT mode to the access.conf file
This commit adds a new configuration variable "FORCE_NAT" to the access.conf
file:
For any valid SPA packet, force the requested connection to be NAT'd
through to the specified (usually internal) IP and port value. This is
useful if there are multiple internal systems running a service such as
SSHD, and you want to give transparent access to only one internal system
for each stanza in the access.conf file. This way, multiple external
users can each directly access only one internal system per SPA key.
This commit also implements a few minor code cleanups.
This commit is contained in:
+12
-12
@@ -240,7 +240,7 @@ parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
|
||||
else if(CONF_VAR_IS(var, "SPA_SERVER_PORT"))
|
||||
{
|
||||
tmpint = atoi(val);
|
||||
if(tmpint < 0 || tmpint > 65535)
|
||||
if(tmpint < 0 || tmpint > MAX_PORT)
|
||||
return(-1);
|
||||
else
|
||||
options->spa_dst_port = tmpint;
|
||||
@@ -249,7 +249,7 @@ parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
|
||||
else if(CONF_VAR_IS(var, "SPA_SOURCE_PORT"))
|
||||
{
|
||||
tmpint = atoi(val);
|
||||
if(tmpint < 0 || tmpint > 65535)
|
||||
if(tmpint < 0 || tmpint > MAX_PORT)
|
||||
return(-1);
|
||||
else
|
||||
options->spa_src_port = tmpint;
|
||||
@@ -277,7 +277,7 @@ parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
|
||||
else if(strcasecmp(val, "resolve") == 0)
|
||||
options->resolve_ip_http = 1;
|
||||
else /* Assume IP address */
|
||||
strlcpy(options->allow_ip_str, val, MAX_IP_STR_LEN);
|
||||
strlcpy(options->allow_ip_str, val, MAX_IPV4_STR_LEN);
|
||||
}
|
||||
/* Time Offset */
|
||||
else if(CONF_VAR_IS(var, "TIME_OFFSET"))
|
||||
@@ -319,7 +319,7 @@ parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
|
||||
/* Spoof Source IP */
|
||||
else if(CONF_VAR_IS(var, "SPOOF_SOURCE_IP"))
|
||||
{
|
||||
strlcpy(options->spoof_ip_src_str, val, MAX_IP_STR_LEN);
|
||||
strlcpy(options->spoof_ip_src_str, val, MAX_IPV4_STR_LEN);
|
||||
}
|
||||
/* ACCESS request */
|
||||
else if(CONF_VAR_IS(var, "ACCESS"))
|
||||
@@ -382,7 +382,7 @@ parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
|
||||
else if(CONF_VAR_IS(var, "NAT_PORT"))
|
||||
{
|
||||
tmpint = atoi(val);
|
||||
if(tmpint < 0 || tmpint > 65535)
|
||||
if(tmpint < 0 || tmpint > MAX_PORT)
|
||||
return(-1);
|
||||
else
|
||||
options->nat_port = tmpint;
|
||||
@@ -673,13 +673,13 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
/* Reset the options index so we can run through them again.
|
||||
*/
|
||||
optind = 0;
|
||||
|
||||
|
||||
while ((cmd_arg = getopt_long(argc, argv,
|
||||
GETOPTS_OPTION_STRING, cmd_opts, &index)) != -1) {
|
||||
|
||||
switch(cmd_arg) {
|
||||
case 'a':
|
||||
strlcpy(options->allow_ip_str, optarg, MAX_IP_STR_LEN);
|
||||
strlcpy(options->allow_ip_str, optarg, MAX_IPV4_STR_LEN);
|
||||
break;
|
||||
case 'A':
|
||||
strlcpy(options->access_str, optarg, MAX_LINE_LEN);
|
||||
@@ -740,7 +740,7 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
break;
|
||||
case 'p':
|
||||
options->spa_dst_port = atoi(optarg);
|
||||
if (options->spa_dst_port < 0 || options->spa_dst_port > 65535)
|
||||
if (options->spa_dst_port < 0 || options->spa_dst_port > MAX_PORT)
|
||||
{
|
||||
fprintf(stderr, "Unrecognized port: %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -754,7 +754,7 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 'Q':
|
||||
strlcpy(options->spoof_ip_src_str, optarg, MAX_IP_STR_LEN);
|
||||
strlcpy(options->spoof_ip_src_str, optarg, MAX_IPV4_STR_LEN);
|
||||
break;
|
||||
case 'r':
|
||||
options->rand_port = 1;
|
||||
@@ -777,11 +777,11 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
options->show_last_command = 1;
|
||||
break;
|
||||
case 's':
|
||||
strlcpy(options->allow_ip_str, "0.0.0.0", MAX_IP_STR_LEN);
|
||||
strlcpy(options->allow_ip_str, "0.0.0.0", MAX_IPV4_STR_LEN);
|
||||
break;
|
||||
case 'S':
|
||||
options->spa_src_port = atoi(optarg);
|
||||
if (options->spa_src_port < 0 || options->spa_src_port > 65535)
|
||||
if (options->spa_src_port < 0 || options->spa_src_port > MAX_PORT)
|
||||
{
|
||||
fprintf(stderr, "Unrecognized port: %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -827,7 +827,7 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
break;
|
||||
case NAT_PORT:
|
||||
options->nat_port = atoi(optarg);
|
||||
if (options->nat_port < 0 || options->nat_port > 65535)
|
||||
if (options->nat_port < 0 || options->nat_port > MAX_PORT)
|
||||
{
|
||||
fprintf(stderr, "Unrecognized port: %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
@@ -85,8 +85,8 @@ typedef struct fko_cli_options
|
||||
int run_last_command;
|
||||
int no_save_args;
|
||||
char spa_server_str[MAX_SERVER_STR_LEN]; /* may be a hostname */
|
||||
char allow_ip_str[MAX_IP_STR_LEN];
|
||||
char spoof_ip_src_str[MAX_IP_STR_LEN];
|
||||
char allow_ip_str[MAX_IPV4_STR_LEN];
|
||||
char spoof_ip_src_str[MAX_IPV4_STR_LEN];
|
||||
char spoof_user[MAX_USERNAME_LEN];
|
||||
int rand_port;
|
||||
char gpg_recipient_key[MAX_GPG_KEY_ID];
|
||||
|
||||
@@ -78,7 +78,7 @@ parse_url(char *res_url, struct url* url)
|
||||
if(e_ndx != NULL)
|
||||
{
|
||||
port = atoi(e_ndx+1);
|
||||
if(port < 1 || port > 65535)
|
||||
if(port < 1 || port > MAX_PORT)
|
||||
{
|
||||
fprintf(stderr, "resolve-url port value is invalid.\n");
|
||||
return(-1);
|
||||
@@ -251,7 +251,7 @@ resolve_ip_http(fko_cli_options_t *options)
|
||||
* Note: We are expecting the content to be just an IP address
|
||||
* (possibly followed by whitespace or other not-digit value).
|
||||
*/
|
||||
for(i=0; i<MAX_IP_STR_LEN; i++) {
|
||||
for(i=0; i<MAX_IPV4_STR_LEN; i++) {
|
||||
if(! isdigit(*(ndx+i)) && *(ndx+i) != '.')
|
||||
break;
|
||||
}
|
||||
@@ -269,7 +269,7 @@ resolve_ip_http(fko_cli_options_t *options)
|
||||
&& o3 >= 0 && o3 <= 255
|
||||
&& o4 >= 0 && o4 <= 255)
|
||||
{
|
||||
strlcpy(options->allow_ip_str, ndx, MAX_IP_STR_LEN);
|
||||
strlcpy(options->allow_ip_str, ndx, MAX_IPV4_STR_LEN);
|
||||
|
||||
if(options->verbose)
|
||||
printf("Resolved external IP (via http://%s%s) as: %s\n",
|
||||
|
||||
+2
-2
@@ -104,8 +104,8 @@ enum {
|
||||
#define MAX_PORT 65535
|
||||
#define MAX_PORT_STR_LEN 6
|
||||
#define MAX_PROTO_STR_LEN 6
|
||||
#define MAX_IP_STR_LEN 16
|
||||
#define MIN_IP_STR_LEN 9
|
||||
#define MAX_IPV4_STR_LEN 16
|
||||
#define MIN_IPV4_STR_LEN 9
|
||||
#define MAX_SERVER_STR_LEN 50
|
||||
|
||||
#define MAX_LINE_LEN 1024
|
||||
|
||||
@@ -162,7 +162,7 @@ SPA OPTIONS
|
||||
Specify IP address that should be permitted through the destination
|
||||
*fwknopd* server firewall (this IP is encrypted within the SPA packet
|
||||
itself). This is useful to prevent a MTIM attack where a SPA packet
|
||||
can be intercepted enroute and sent from a different IP than the
|
||||
can be intercepted en-route and sent from a different IP than the
|
||||
original. Hence, if the *fwknopd* server trusts the source address
|
||||
on the SPA packet IP header then the attacker gains access.
|
||||
The *-a* option puts the source address within the encrypted SPA
|
||||
@@ -359,7 +359,7 @@ commented out. It is up to the user to edit this file to meet their needs.
|
||||
|
||||
The '.fwknoprc' file contains a default configuration area or stanza which
|
||||
holds global configuration directives that override the program defaults.
|
||||
You can edit this file and create additonal 'named stanzas' that can be
|
||||
You can edit this file and create additional 'named stanzas' that can be
|
||||
specified with the *-n* or *--named-config* option. Parameters defined in
|
||||
the named stanzas will override any matching 'default' stanza directives.
|
||||
Note that command-line options will still override any corresponding
|
||||
|
||||
@@ -29,7 +29,7 @@ vulnerabilities (both 0-day and unpatched code) much more difficult.
|
||||
The main configuration for *fwknopd* is maintained within two files:
|
||||
'fwknopd.conf' and 'access.conf'. The default location for these files
|
||||
is determined at package configuration (typically '@sysconfdir@/fwknop')The
|
||||
configuration variables within these files are desribed below.
|
||||
configuration variables within these files are described below.
|
||||
|
||||
|
||||
COMMAND-LINE OPTIONS
|
||||
@@ -183,7 +183,7 @@ See the 'fwknopd.conf' file for the full list and corresponding details.
|
||||
*ACCESS_EXPIRE_EPOCH* '<seconds>'::
|
||||
Defines an expiration date for the access stanza as the epoch time, and is
|
||||
useful if a more accurate expiration time needs to be given than the day
|
||||
resolution offered by the ACCESS_EXPIRE variable agove. All SPA packets
|
||||
resolution offered by the ACCESS_EXPIRE variable above. All SPA packets
|
||||
that match an expired stanza will be ignored. This parameter is optional.
|
||||
|
||||
*ENABLE_DIGEST_PERSISTENCE* '<Y/N>'::
|
||||
@@ -221,7 +221,7 @@ See the 'fwknopd.conf' file for the full list and corresponding details.
|
||||
when ``ENABLE_IPT_SNAT'' is set to ``Y'' and by default SNAT rules are
|
||||
built with the MASQUERADE target (since then the internal IP does not
|
||||
have to be defined here in the 'fwknopd.conf' file), but if you want
|
||||
*fwknopd* to use the SNAT target, you mus also define an IP address with
|
||||
*fwknopd* to use the SNAT target, you must also define an IP address with
|
||||
the ``SNAT_TRANSLATE_IP'' variable.
|
||||
|
||||
*ENABLE_IPT_OUTPUT* '<Y/N>'::
|
||||
@@ -306,7 +306,7 @@ is granted to *fwknop* clients that have generated the appropriate
|
||||
encrypted message.
|
||||
|
||||
The 'access.conf' variables described below provide the access directives
|
||||
for the SPA packets with a source (or embeded request) IP that matches an
|
||||
for the SPA packets with a source (or embedded request) IP that matches an
|
||||
address or network range defined by the ``SOURCE'' variable. All variables
|
||||
following ``SOURCE'' apply to the source 'stanza'. Each ``SOURCE''
|
||||
directive starts a new stanza.
|
||||
@@ -368,6 +368,14 @@ directive starts a new stanza.
|
||||
to be used to automatically resolve the external address (if the
|
||||
client behind a NAT) or the client must know the external IP.
|
||||
|
||||
*FORCE_NAT*: '<IP> <PORT>'::
|
||||
For any valid SPA packet, force the requested connection to be NAT'd
|
||||
through to the specified (usually internal) IP and port value. This is
|
||||
useful if there are multiple internal systems running a service such as
|
||||
SSHD, and you want to give transparent access to only one internal system
|
||||
for each stanza in the access.conf file. This way, multiple external
|
||||
users can each directly access only one internal system per SPA key.
|
||||
|
||||
*GPG_HOME_DIR*: '<path>'::
|
||||
Define the path to the GnuPG directory to be used by the *fwknopd*
|
||||
server. If this keyword is not specified within 'access.conf' then
|
||||
@@ -442,7 +450,7 @@ are received.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
fwknop(8), iptables(8), libfko docmentation.
|
||||
fwknop(8), iptables(8), libfko documentation.
|
||||
|
||||
|
||||
AUTHOR
|
||||
|
||||
+47
-4
@@ -80,11 +80,12 @@ add_acc_expire_time(fko_srv_options_t *opts, time_t *access_expire_time, const c
|
||||
|
||||
memset(&tm, 0, sizeof(struct tm));
|
||||
|
||||
if (sscanf(val, "%d/%d/%d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3)
|
||||
if (sscanf(val, "%2d/%2d/%4d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3)
|
||||
{
|
||||
|
||||
log_msg(LOG_ERR,
|
||||
"Fatal invalid epoch seconds value for access stanza expiration time"
|
||||
"Fatal: invalid date value '%s' (need MM/DD/YYYY) for access stanza expiration time",
|
||||
val
|
||||
);
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
@@ -120,7 +121,8 @@ add_acc_expire_time_epoch(fko_srv_options_t *opts, time_t *access_expire_time, c
|
||||
if (errno == ERANGE || (errno != 0 && expire_time == 0))
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"Fatal invalid epoch seconds value for access stanza expiration time"
|
||||
"Fatal: invalid epoch seconds value '%s' for access stanza expiration time",
|
||||
val
|
||||
);
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
@@ -130,6 +132,34 @@ add_acc_expire_time_epoch(fko_srv_options_t *opts, time_t *access_expire_time, c
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
add_acc_force_nat(fko_srv_options_t *opts, acc_stanza_t *curr_acc, const char *val)
|
||||
{
|
||||
char ip_str[MAX_IPV4_STR_LEN] = {0};
|
||||
|
||||
if (sscanf(val, "%15s %5u", ip_str, &curr_acc->force_nat_port) != 2)
|
||||
{
|
||||
|
||||
log_msg(LOG_ERR,
|
||||
"Fatal: invalid FORCE_NAT arg '%s', need <IP> <PORT>",
|
||||
val
|
||||
);
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (curr_acc->force_nat_port > MAX_PORT)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"Fatal: invalid FORCE_NAT port '%d'", curr_acc->force_nat_port);
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
curr_acc->force_nat = 1;
|
||||
add_acc_string(&(curr_acc->force_nat_ip), ip_str);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Take an IP or Subnet/Mask and convert it to mask for later
|
||||
* comparisons of incoming source IPs against this mask.
|
||||
*/
|
||||
@@ -137,7 +167,7 @@ static void
|
||||
add_source_mask(acc_stanza_t *acc, const char *ip)
|
||||
{
|
||||
char *ndx;
|
||||
char ip_str[16] = {0};
|
||||
char ip_str[MAX_IPV4_STR_LEN] = {0};
|
||||
uint32_t mask;
|
||||
|
||||
struct in_addr in;
|
||||
@@ -523,6 +553,9 @@ free_acc_stanza_data(acc_stanza_t *acc)
|
||||
free_acc_port_list(acc->rport_list);
|
||||
}
|
||||
|
||||
if(acc->force_nat_ip != NULL)
|
||||
free(acc->force_nat_ip);
|
||||
|
||||
if(acc->key != NULL)
|
||||
free(acc->key);
|
||||
|
||||
@@ -915,6 +948,16 @@ parse_access_file(fko_srv_options_t *opts)
|
||||
{
|
||||
add_acc_expire_time_epoch(opts, &(curr_acc->access_expire_time), val);
|
||||
}
|
||||
else if(CONF_VAR_IS(var, "FORCE_NAT"))
|
||||
{
|
||||
if(strncasecmp(opts->config[CONF_ENABLE_IPT_FORWARDING], "Y", 1) !=0 )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[*] FORCE_NAT requires ENABLE_IPT_FORWARDING to be enabled in fwknopd.conf\n");
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
add_acc_force_nat(opts, curr_acc, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ void fw_initialize(const fko_srv_options_t *opts);
|
||||
int fw_cleanup(const fko_srv_options_t *opts);
|
||||
void check_firewall_rules(const fko_srv_options_t *opts);
|
||||
int fw_dump_rules(const fko_srv_options_t *opts);
|
||||
int process_spa_request(const fko_srv_options_t *opts, spa_data_t *spdat);
|
||||
int process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_data_t *spdat);
|
||||
|
||||
#endif /* FW_UTIL_H */
|
||||
|
||||
|
||||
@@ -109,11 +109,11 @@ fw_cleanup(void)
|
||||
/* Rule Processing - Create an access request...
|
||||
*/
|
||||
int
|
||||
process_spa_request(const fko_srv_options_t *opts, spa_data_t *spadat)
|
||||
process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_data_t *spadat)
|
||||
{
|
||||
/* TODO: Implement me */
|
||||
|
||||
char nat_ip[16] = {0};
|
||||
char nat_ip[MAX_IPV4_STR_LEN] = {0};
|
||||
char *ndx;
|
||||
|
||||
unsigned int nat_port = 0;;
|
||||
|
||||
@@ -415,7 +415,7 @@ fw_cleanup(const fko_srv_options_t *opts)
|
||||
/* Rule Processing - Create an access request...
|
||||
*/
|
||||
int
|
||||
process_spa_request(const fko_srv_options_t *opts, spa_data_t *spadat)
|
||||
process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_data_t *spadat)
|
||||
{
|
||||
unsigned short rule_num;
|
||||
|
||||
|
||||
+19
-13
@@ -479,9 +479,9 @@ fw_cleanup(const fko_srv_options_t *opts)
|
||||
/* Rule Processing - Create an access request...
|
||||
*/
|
||||
int
|
||||
process_spa_request(const fko_srv_options_t *opts, spa_data_t *spadat)
|
||||
process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_data_t *spadat)
|
||||
{
|
||||
char nat_ip[16] = {0};
|
||||
char nat_ip[MAX_IPV4_STR_LEN] = {0};
|
||||
char snat_target[SNAT_TARGET_BUFSIZE] = {0};
|
||||
char *ndx;
|
||||
|
||||
@@ -525,8 +525,8 @@ process_spa_request(const fko_srv_options_t *opts, spa_data_t *spadat)
|
||||
/* For straight access requests, we currently support multiple proto/port
|
||||
* request.
|
||||
*/
|
||||
if(spadat->message_type == FKO_ACCESS_MSG
|
||||
|| spadat->message_type == FKO_CLIENT_TIMEOUT_ACCESS_MSG)
|
||||
if((spadat->message_type == FKO_ACCESS_MSG
|
||||
|| spadat->message_type == FKO_CLIENT_TIMEOUT_ACCESS_MSG) && !acc->force_nat)
|
||||
{
|
||||
|
||||
/* Check to make sure that the jump rules exist for each
|
||||
@@ -578,7 +578,7 @@ process_spa_request(const fko_srv_options_t *opts, spa_data_t *spadat)
|
||||
in_chain->next_expire = exp_ts;
|
||||
}
|
||||
else
|
||||
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
|
||||
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
|
||||
|
||||
/* If we have to make an corresponding OUTPUT rule if out_chain target
|
||||
* is not NULL.
|
||||
@@ -631,19 +631,25 @@ process_spa_request(const fko_srv_options_t *opts, spa_data_t *spadat)
|
||||
else if(spadat->message_type == FKO_LOCAL_NAT_ACCESS_MSG
|
||||
|| spadat->message_type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG
|
||||
|| spadat->message_type == FKO_NAT_ACCESS_MSG
|
||||
|| spadat->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG )
|
||||
|| spadat->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG
|
||||
|| acc->force_nat)
|
||||
{
|
||||
/* Parse out the NAT IP and Port components.
|
||||
*/
|
||||
ndx = strchr(spadat->nat_access, ',');
|
||||
if(ndx != NULL)
|
||||
if(acc->force_nat)
|
||||
{
|
||||
strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1);
|
||||
nat_port = atoi(ndx+1);
|
||||
strlcpy(nat_ip, acc->force_nat_ip, MAX_IPV4_STR_LEN);
|
||||
nat_port = acc->force_nat_port;
|
||||
}
|
||||
else
|
||||
{
|
||||
ndx = strchr(spadat->nat_access, ',');
|
||||
if(ndx != NULL)
|
||||
{
|
||||
strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1);
|
||||
nat_port = atoi(ndx+1);
|
||||
}
|
||||
}
|
||||
|
||||
// --DSS temp
|
||||
//fprintf(stderr, "NAT IP: '%s', NAT PORT: '%i'\n", nat_ip, nat_port);
|
||||
|
||||
/* Make our FORWARD and NAT rules
|
||||
*/
|
||||
|
||||
+1
-1
@@ -204,7 +204,7 @@ fw_cleanup(const fko_srv_options_t *opts)
|
||||
/* Rule Processing - Create an access request...
|
||||
*/
|
||||
int
|
||||
process_spa_request(const fko_srv_options_t *opts, spa_data_t *spadat)
|
||||
process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_data_t *spadat)
|
||||
{
|
||||
char new_rule[MAX_PF_NEW_RULE_LEN];
|
||||
char write_cmd[CMD_BUFSIZE];
|
||||
|
||||
+1
-1
@@ -282,7 +282,7 @@ main(int argc, char **argv)
|
||||
if(strncasecmp(opts.config[CONF_ENABLE_TCP_SERVER], "Y", 1) == 0)
|
||||
{
|
||||
if(atoi(opts.config[CONF_TCPSERV_PORT]) <= 0
|
||||
|| atoi(opts.config[CONF_TCPSERV_PORT]) > 65535)
|
||||
|| atoi(opts.config[CONF_TCPSERV_PORT]) > MAX_PORT)
|
||||
{
|
||||
log_msg(LOG_WARNING,
|
||||
"WARNING: ENABLE_TCP_SERVER is set, but TCPSERV_PORT is not valid. TCP server not started!"
|
||||
|
||||
@@ -282,6 +282,10 @@ typedef struct acc_stanza
|
||||
acc_string_list_t *gpg_remote_id_list;
|
||||
time_t access_expire_time;
|
||||
int expired;
|
||||
unsigned char force_nat;
|
||||
char *force_nat_ip;
|
||||
char *force_nat_proto;
|
||||
unsigned int force_nat_port;
|
||||
struct acc_stanza *next;
|
||||
} acc_stanza_t;
|
||||
|
||||
@@ -386,8 +390,8 @@ typedef struct spa_data
|
||||
char *version;
|
||||
short message_type;
|
||||
char *spa_message;
|
||||
char spa_message_src_ip[MAX_IP_STR_LEN];
|
||||
char pkt_source_ip[MAX_IP_STR_LEN];
|
||||
char spa_message_src_ip[MAX_IPV4_STR_LEN];
|
||||
char pkt_source_ip[MAX_IPV4_STR_LEN];
|
||||
char spa_message_remain[1024]; /* --DSS FIXME: arbitrary bounds */
|
||||
char *nat_access;
|
||||
char *server_auth;
|
||||
|
||||
@@ -616,7 +616,7 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
* access stanza loop (first valid access stanza stops us looking
|
||||
* for others).
|
||||
*/
|
||||
process_spa_request(opts, &spadat);
|
||||
process_spa_request(opts, acc, &spadat);
|
||||
if(ctx != NULL)
|
||||
fko_destroy(ctx);
|
||||
break;
|
||||
|
||||
+3
-3
@@ -60,7 +60,7 @@ run_tcp_server(fko_srv_options_t *opts)
|
||||
fd_set sfd_set;
|
||||
struct sockaddr_in saddr, caddr;
|
||||
struct timeval tv;
|
||||
char sipbuf[MAX_IP_STR_LEN];
|
||||
char sipbuf[MAX_IPV4_STR_LEN];
|
||||
|
||||
unsigned short port = atoi(opts->config[CONF_TCPSERV_PORT]);
|
||||
|
||||
@@ -196,8 +196,8 @@ run_tcp_server(fko_srv_options_t *opts)
|
||||
|
||||
if(opts->verbose)
|
||||
{
|
||||
memset(sipbuf, 0x0, MAX_IP_STR_LEN);
|
||||
inet_ntop(AF_INET, &(caddr.sin_addr.s_addr), sipbuf, MAX_IP_STR_LEN);
|
||||
memset(sipbuf, 0x0, MAX_IPV4_STR_LEN);
|
||||
inet_ntop(AF_INET, &(caddr.sin_addr.s_addr), sipbuf, MAX_IPV4_STR_LEN);
|
||||
log_msg(LOG_INFO, "tcp_server: Got TCP connection from %s.", sipbuf);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SOURCE: ANY;
|
||||
KEY: fwknoptest;
|
||||
FW_ACCESS_TIMEOUT: 3;
|
||||
ACCESS_EXPIRE: 3/10/1999; ### very old
|
||||
ACCESS_EXPIRE: 3/10/01; ### very old
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
SOURCE: ANY;
|
||||
KEY: fwknoptest;
|
||||
FW_ACCESS_TIMEOUT: 3;
|
||||
FORCE_NAT: 192.168.1.123 22;
|
||||
@@ -0,0 +1,4 @@
|
||||
SOURCE: ANY;
|
||||
KEY: fwknoptest;
|
||||
FW_ACCESS_TIMEOUT: 3;
|
||||
ACCESS_EXPIRE: 3/10/2500; ### way in the future
|
||||
@@ -0,0 +1,4 @@
|
||||
SOURCE: ANY;
|
||||
KEY: fwknoptest;
|
||||
FW_ACCESS_TIMEOUT: 3;
|
||||
ACCESS_EXPIRE: 3-10-01; ### / separators required
|
||||
@@ -23,7 +23,10 @@ my $nat_conf = "$conf_dir/nat_fwknopd.conf";
|
||||
my $default_conf = "$conf_dir/default_fwknopd.conf";
|
||||
my $default_access_conf = "$conf_dir/default_access.conf";
|
||||
my $expired_access_conf = "$conf_dir/expired_stanza_access.conf";
|
||||
my $future_expired_access_conf = "$conf_dir/future_expired_stanza_access.conf";
|
||||
my $expired_epoch_access_conf = "$conf_dir/expired_epoch_stanza_access.conf";
|
||||
my $invalid_expire_access_conf = "$conf_dir/invalid_expire_access.conf";
|
||||
my $force_nat_access_conf = "$conf_dir/force_nat_access.conf";
|
||||
my $gpg_access_conf = "$conf_dir/gpg_access.conf";
|
||||
my $default_digest_file = "$run_dir/digest.cache";
|
||||
my $default_pid_file = "$run_dir/fwknopd.pid";
|
||||
@@ -53,6 +56,7 @@ my $gpg_client_key = '6A3FAD56';
|
||||
my $loopback_ip = '127.0.0.1';
|
||||
my $fake_ip = '127.0.0.2';
|
||||
my $internal_nat_host = '192.168.1.2';
|
||||
my $force_nat_host = '192.168.1.123';
|
||||
my $default_spa_port = 62201;
|
||||
my $non_std_spa_port = 12345;
|
||||
|
||||
@@ -626,6 +630,20 @@ my @tests = (
|
||||
'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
|
||||
'fatal' => $NO
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael SPA',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => 'invalid expire date (tcp/22 ssh)',
|
||||
'err_msg' => 'SPA packet accepted',
|
||||
'function' => \&spa_cycle,
|
||||
'cmdline' => $default_client_args,
|
||||
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
|
||||
"$fwknopdCmd -c $default_conf -a $invalid_expire_access_conf " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'server_positive_output_matches' => [qr/invalid\sdate\svalue/],
|
||||
'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
|
||||
'fatal' => $NO
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael SPA',
|
||||
'subcategory' => 'client+server',
|
||||
@@ -640,6 +658,20 @@ my @tests = (
|
||||
'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
|
||||
'fatal' => $NO
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael SPA',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => 'future expired stanza (tcp/22 ssh)',
|
||||
'err_msg' => 'SPA packet not accepted',
|
||||
'function' => \&spa_cycle,
|
||||
'cmdline' => $default_client_args,
|
||||
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
|
||||
"$fwknopdCmd -c $default_conf -a $future_expired_access_conf " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'fw_rule_created' => $NEW_RULE_REQUIRED,
|
||||
'fw_rule_removed' => $NEW_RULE_REMOVED,
|
||||
'fatal' => $NO
|
||||
},
|
||||
|
||||
{
|
||||
'category' => 'Rijndael SPA',
|
||||
@@ -866,6 +898,25 @@ my @tests = (
|
||||
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
|
||||
"$fwknopdCmd -c $nat_conf -a $open_ports_access_conf " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'server_positive_output_matches' => [qr/to\:$internal_nat_host\:22/i],
|
||||
'fw_rule_created' => $NEW_RULE_REQUIRED,
|
||||
'fw_rule_removed' => $NEW_RULE_REMOVED,
|
||||
'server_conf' => $nat_conf,
|
||||
'fatal' => $NO
|
||||
},
|
||||
|
||||
{
|
||||
'category' => 'Rijndael SPA',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => "force NAT $force_nat_host (tcp/22 ssh)",
|
||||
'err_msg' => "could not complete NAT SPA cycle",
|
||||
'function' => \&spa_cycle,
|
||||
'cmdline' => $default_client_args,
|
||||
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
|
||||
"$fwknopdCmd -c $nat_conf -a $force_nat_access_conf " .
|
||||
"-d $default_digest_file -p $default_pid_file $intf_str",
|
||||
'server_positive_output_matches' => [qr/to\:$force_nat_host\:22/i],
|
||||
'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
|
||||
'fw_rule_created' => $NEW_RULE_REQUIRED,
|
||||
'fw_rule_removed' => $NEW_RULE_REMOVED,
|
||||
'server_conf' => $nat_conf,
|
||||
@@ -932,6 +983,22 @@ my @tests = (
|
||||
'fw_rule_removed' => $NEW_RULE_REMOVED,
|
||||
'fatal' => $NO
|
||||
},
|
||||
|
||||
{
|
||||
'category' => 'Rijndael SPA',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => 'random SPA port (tcp/22 ssh)',
|
||||
'err_msg' => 'could not complete SPA cycle',
|
||||
'function' => \&spa_cycle,
|
||||
'cmdline' => "$default_client_args -r",
|
||||
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
|
||||
"$fwknopdCmd $default_server_conf_args $intf_str " .
|
||||
qq|-P "udp"|,
|
||||
'fw_rule_created' => $NEW_RULE_REQUIRED,
|
||||
'fw_rule_removed' => $NEW_RULE_REMOVED,
|
||||
'fatal' => $NO
|
||||
},
|
||||
|
||||
{
|
||||
'category' => 'Rijndael SPA',
|
||||
'subcategory' => 'client+server',
|
||||
@@ -2371,6 +2438,9 @@ sub init() {
|
||||
$multi_stanzas_access_conf,
|
||||
$expired_access_conf,
|
||||
$expired_epoch_access_conf,
|
||||
$future_expired_access_conf,
|
||||
$invalid_expire_access_conf,
|
||||
$force_nat_access_conf,
|
||||
) {
|
||||
die "[*] $file does not exist" unless -e $file;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user