First cut at creating access rules and removing them when they expire (not sure I like this implementation but it is a start).

git-svn-id: file:///home/mbr/svn/fwknop/trunk@214 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart
2010-05-17 01:27:26 +00:00
parent bf9e165165
commit aad2daadbf
9 changed files with 447 additions and 134 deletions

View File

@@ -308,7 +308,7 @@ add_string_list_ent(acc_string_list_t **stlist, char *str_str)
/* Expand a proto/port access string to a list of access proto-port struct.
*/
static acc_port_list_t*
void
expand_acc_port_list(acc_port_list_t **plist, char *plist_str)
{
char *ndx, *start;
@@ -333,7 +333,7 @@ expand_acc_port_list(acc_port_list_t **plist, char *plist_str)
/* Expand a comma-separated string into a simple acc_string_list.
*/
static acc_string_list_t*
static void
expand_acc_string_list(acc_string_list_t **stlist, char *stlist_str)
{
char *ndx, *start;
@@ -374,7 +374,7 @@ free_acc_source_list(acc_int_list_t *sle)
/* Free a port_list
*/
static void
void
free_acc_port_list(acc_port_list_t *ple)
{
acc_port_list_t *last_ple;
@@ -616,7 +616,7 @@ parse_access_file(fko_srv_options_t *opts)
acc_stanza_t *curr_acc = NULL;
/* First see if the access file exists. If it doesn't, complain
* and go on with program defaults.
* and bail.
*/
if(stat(opts->config[CONF_ACCESS_FILE], &st) != 0)
{

View File

@@ -26,8 +26,8 @@
#ifndef ACCESS_H
#define ACCESS_H
#define PROTO_TCP 0
#define PROTO_UDP 1
#define PROTO_TCP 6
#define PROTO_UDP 17
/* Function Prototypes
*/
@@ -35,6 +35,8 @@ void parse_access_file(fko_srv_options_t *opts);
acc_stanza_t* acc_check_source(fko_srv_options_t *opts, uint32_t ip);
int acc_check_port_access(acc_stanza_t *acc, char *port_str);
void dump_access_list(fko_srv_options_t *opts);
void expand_acc_port_list(acc_port_list_t **plist, char *plist_str);
void free_acc_port_list(acc_port_list_t *plist);
#endif /* ACCESS_H */

View File

@@ -49,6 +49,8 @@ set_nonblock(int fd)
int
run_extcmd(char *cmd, char *so_buf, char *se_buf, size_t so_buf_sz, size_t se_buf_sz, int *status)
{
//--DSS temp
//return(0);
pid_t pid;
struct timeval tv;

View File

@@ -28,13 +28,14 @@
#include "log_msg.h"
#include "config_init.h" /* for the IS_EMPTY_LINE macro */
#include "extcmd.h"
#include "access.h"
static struct fw_config fwc;
static void
parse_extcmd_error(int retval, int status, char *se_buf)
{
char errmsg[256];
char errmsg[CMD_BUFSIZE];
char *emptr = errmsg;
if(retval < 0)
@@ -83,9 +84,9 @@ static int
jump_rule_exists(int chain_num)
{
int num, x, pos = 0;
char cmd_buf[256];
char target[256];
char line_buf[256] = {0};
char cmd_buf[CMD_BUFSIZE] = {0};
char target[CMD_BUFSIZE] = {0};
char line_buf[CMD_BUFSIZE] = {0};
FILE *ipt;
sprintf(cmd_buf, "%s " IPT_LIST_RULES_ARGS,
@@ -103,7 +104,7 @@ jump_rule_exists(int chain_num)
return(-1);
}
while((fgets(line_buf, 255, ipt)) != NULL)
while((fgets(line_buf, CMD_BUFSIZE-1, ipt)) != NULL)
{
/* Get past comments and empty lines (note: we only look at the
* first character.
@@ -133,8 +134,8 @@ delete_all_chains(void)
{
int i, pos, res, status;
int jump_rule_num;
char cmd_buf[256];
char err[256];
char cmd_buf[CMD_BUFSIZE] = {0};
char err[CMD_BUFSIZE] = {0};
for(i=0; i<(NUM_FWKNOP_CHAIN_TYPES-1); i++)
{
@@ -146,7 +147,7 @@ delete_all_chains(void)
*/
if((jump_rule_num = jump_rule_exists(i)) > 0)
{
sprintf(cmd_buf, "%s " IPT_DEL_RULE_ARGS,
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_DEL_RULE_ARGS,
fwc.fw_command,
fwc.chain[i].table,
fwc.chain[i].from_chain,
@@ -154,15 +155,17 @@ delete_all_chains(void)
);
//printf("CMD: '%s'\n", cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, 256, &status);
res = run_extcmd(cmd_buf, NULL, err, 0, CMD_BUFSIZE, &status);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
parse_extcmd_error(res, status, err);
}
memset(cmd_buf, 0x0, CMD_BUFSIZE);
/* Now flush and remove the chain.
*/
sprintf(cmd_buf,
snprintf(cmd_buf, CMD_BUFSIZE-1,
"(%s " IPT_FLUSH_CHAIN_ARGS "; %s " IPT_DEL_CHAIN_ARGS ")", // > /dev/null 2>&1",
fwc.fw_command,
fwc.chain[i].table,
@@ -173,7 +176,7 @@ delete_all_chains(void)
);
//printf("CMD: '%s'\n", cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, 256, &status);
res = run_extcmd(cmd_buf, NULL, err, 0, CMD_BUFSIZE, &status);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
parse_extcmd_error(res, status, err);
@@ -187,8 +190,8 @@ create_fw_chains(void)
{
int i;
int res, status, got_err = 0;
char cmd_buf[256];
char err[256];
char cmd_buf[CMD_BUFSIZE] = {0};
char err[CMD_BUFSIZE] = {0};
for(i=0; i<(NUM_FWKNOP_CHAIN_TYPES-1); i++)
{
@@ -197,14 +200,14 @@ create_fw_chains(void)
/* Create the custom chain.
*/
sprintf(cmd_buf, "%s " IPT_NEW_CHAIN_ARGS,
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_NEW_CHAIN_ARGS,
fwc.fw_command,
fwc.chain[i].table,
fwc.chain[i].to_chain
);
//printf("CMD: '%s'\n", cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, 256, &status);
res = run_extcmd(cmd_buf, NULL, err, 0, CMD_BUFSIZE, &status);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
@@ -212,9 +215,11 @@ create_fw_chains(void)
got_err++;
}
memset(cmd_buf, 0x0, CMD_BUFSIZE);
/* Then create the jump rule to that chain.
*/
sprintf(cmd_buf, "%s " IPT_ADD_JUMP_RULE_ARGS,
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_JUMP_RULE_ARGS,
fwc.fw_command,
fwc.chain[i].table,
fwc.chain[i].from_chain,
@@ -223,7 +228,7 @@ create_fw_chains(void)
);
//printf("CMD: '%s'\n", cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, 256, &status);
res = run_extcmd(cmd_buf, NULL, err, 0, CMD_BUFSIZE, &status);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
@@ -374,4 +379,248 @@ fw_cleanup(void)
delete_all_chains();
}
int
process_access_request(fko_srv_options_t *opts, spa_data_t *spadat)
{
char cmd_buf[CMD_BUFSIZE] = {0};
char err[CMD_BUFSIZE] = {0};
acc_port_list_t *port_list = NULL;
acc_port_list_t *ple;
unsigned int cproto;
unsigned int cport;
struct fw_chain *chain = &(opts->fw_config->chain[IPT_INPUT_ACCESS]);
int status, res;
time_t now, exp_ts;
/* Parse and expand our access message.
*/
expand_acc_port_list(&port_list, spadat->spa_message_remain);
/* Create an access command for each proto/port for the source ip.
*/
ple = port_list;
while(ple != NULL)
{
time(&now);
exp_ts = now + spadat->fw_access_timeout;
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_RULE_ARGS,
opts->fw_config->fw_command,
chain->table,
chain->to_chain,
ple->proto,
spadat->use_src_ip,
ple->port,
exp_ts,
chain->target
);
//--DSS tmp
//fprintf(stderr, "ADD CMD: %s", cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, CMD_BUFSIZE, &status);
if(EXTCMD_IS_SUCCESS(res))
{
log_msg(LOG_INFO, "Added Rule to %s for %s, %s expires at %u",
chain->to_chain, spadat->use_src_ip,
spadat->spa_message_remain, exp_ts
);
chain->active_rules++;
/* Reset the next expected expire time for this chain if it
* is warranted.
*/
if(chain->next_expire < now || exp_ts < chain->next_expire)
chain->next_expire = exp_ts;
}
else
parse_extcmd_error(res, status, err);
ple = ple->next;
}
/* Done with the port list.
*/
free_acc_port_list(port_list);
return(res);
}
void
check_firewall_rules(fko_srv_options_t *opts)
{
char cmd_buf[CMD_BUFSIZE] = {0};
char err[CMD_BUFSIZE] = {0};
char cmd_out[4096];
char exp_str[12];
char rule_num_str[6];
char *ndx, *rn_start, *rn_end, *tmp_mark;
int i, res, status, rn_offset;
time_t now, rule_exp, min_exp;
struct fw_chain *ch = opts->fw_config->chain;
time(&now);
/* Iterate over each chain and look for active rules to delete.
*/
for(i = 0; i < NUM_FWKNOP_CHAIN_TYPES; i++)
{
/* Just in case we somehow lose track and fall out-of-whack.
*/
if(ch[i].active_rules < 0)
ch[i].active_rules = 0;
/* If there are now active rules or we have not yet
* reached our expected next expire time, continue.
*/
if(ch[i].active_rules == 0 || ch[i].next_expire > now)
continue;
rn_offset = 0;
//fprintf(stderr, "CHAIN: %i, active_rules: %i, next_exp: %u, Now: %u\n",
// i, ch[i].active_rules, ch[i].next_expire, now);
/* There should be a rule to delete. Get the current list of
* rules for this chain and delete the ones that are expired.
*/
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_LIST_RULES_ARGS "\n",
opts->fw_config->fw_command,
ch[i].table,
ch[i].to_chain
);
memset(cmd_out, 0x0, 4096);
res = run_extcmd(cmd_buf, cmd_out, err, 4096, CMD_BUFSIZE, &status);
if(!EXTCMD_IS_SUCCESS(res))
{
parse_extcmd_error(res, status, err);
continue;
}
//fprintf(stderr, "RULES LIST:\n%s\n", cmd_out);
ndx = strstr(cmd_out, "_exp_");
if(ndx == NULL)
{
/* we did not find an expected rule.
*/
log_msg(LOG_ERR|LOG_STDERR,
"Did not find expire comment in rules list %i.\n", i);
ch[i].active_rules--;
continue;
}
/* walk the list and process rules as needed.
*/
while (ndx != NULL) {
/* Jump forward and extract the timestamp
*/
ndx +=5;
/* remember this spot for when we look for the next
* rule.
*/
tmp_mark = ndx;
strlcpy(exp_str, ndx, 11);
rule_exp = (time_t)atoll(exp_str);
//fprintf(stderr, "RULE_EXP=%u, NOW=%u\n", rule_exp, now);
if(rule_exp <= now)
{
/* Backtrack and get the rule number and delete it.
*/
rn_start = ndx;
while(--rn_start > cmd_out)
{
if(*rn_start == '\n')
break;
}
if(*rn_start != '\n')
{
/* This should not happen. But if it does, complain,
* decrement the active rule value, and go on.
*/
log_msg(LOG_ERR|LOG_STDERR,
"Rule parse error while finding rule line start in chain %i", i);
ch[i].active_rules--;
break;
}
rn_start++;
rn_end = strchr(rn_start, ' ');
if(rn_end == NULL)
{
/* This should not happen. But if it does, complain,
* decrement the active rule value, and go on.
*/
log_msg(LOG_ERR|LOG_STDERR,
"Rule parse error while finding rule number in chain %i", i);
ch[i].active_rules--;
break;
}
strlcpy(rule_num_str, rn_start, (rn_end - rn_start)+1);
memset(cmd_buf, 0x0, CMD_BUFSIZE);
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_DEL_RULE_ARGS,
opts->fw_config->fw_command,
ch[i].table,
ch[i].to_chain,
atoi(rule_num_str) - rn_offset
);
//fprintf(stderr, "DELETE RULE CMD: %s\n", cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, CMD_BUFSIZE, &status);
if(EXTCMD_IS_SUCCESS(res))
{
log_msg(LOG_INFO, "Removed rule %s from %s with expire time of %u.",
rule_num_str, ch[i].to_chain, rule_exp
);
rn_offset++;
ch[i].active_rules--;
}
else
parse_extcmd_error(res, status, err);
}
else
{
/* Track the minimum future rule expire time.
*/
if(rule_exp > now)
min_exp = (min_exp < rule_exp) ? min_exp : rule_exp;
}
/* Push our tracking index forward beyond (just processed) _exp_
* string so we can continue to the next rule in the list.
*/
ndx = strstr(tmp_mark, "_exp_");
}
/* Set the next pending expire time accordingly. 0 if there are no
* more rules, or whatever the next expected (min_exp) time will be.
*/
if(ch[i].active_rules < 1)
ch[i].next_expire = 0;
else
ch[i].next_expire = min_exp;
}
}
/***EOF***/

View File

@@ -26,10 +26,28 @@
#ifndef FW_UTIL_H
#define FW_UTIL_H
#define CMD_BUFSIZE 256
#define MAX_FW_COMMAND_ARGS_LEN 256
/* iptables command args
*/
//#define IPT_ADD_RULE_ARGS "-t %s -A %s -p %i -s %s --dport %i -j %s"
#define IPT_ADD_RULE_ARGS "-t %s -A %s -p %i -s %s --dport %i -m comment --comment _exp_%u -j %s"
#define IPT_DEL_RULE_ARGS "-t %s -D %s %i"
#define IPT_NEW_CHAIN_ARGS "-t %s -N %s"
#define IPT_FLUSH_CHAIN_ARGS "-t %s -F %s"
#define IPT_DEL_CHAIN_ARGS "-t %s -X %s"
#define IPT_ADD_JUMP_RULE_ARGS "-t %s -I %s %i -j %s"
#define IPT_LIST_RULES_ARGS "-t %s -L %s --line-numbers -n"
#define DEF_FW_ACCESS_TIMEOUT 60
/* Function prototypes
*/
void fw_initialize(fko_srv_options_t *opts);
void fw_cleanup(void);
int process_access_request(fko_srv_options_t *opts, spa_data_t *spdat);
void check_firewall_rules(fko_srv_options_t *opts);
#endif /* FW_UTIL_H */

View File

@@ -172,7 +172,7 @@ main(int argc, char **argv)
}
/* If we are a new process (just being started), proceed with normal
* startp. Otherwise, we are here as a result of a signal sent to an
* start-up. Otherwise, we are here as a result of a signal sent to an
* existing process and we want to restart.
*/
if(get_running_pid(&opts) != getpid())
@@ -581,10 +581,9 @@ get_running_pid(fko_srv_options_t *opts)
if(op_fd > 0)
{
if (read(op_fd, buf, 6) == 6)
{
if (read(op_fd, buf, 6) > 0)
rpid = (pid_t)atoi(buf);
}
close(op_fd);
}

View File

@@ -85,7 +85,7 @@ enum {
};
/* SPA message handling status code
*/
*/
enum {
SPA_MSG_SUCCESS = 0,
SPA_MSG_BAD_DATA,
@@ -99,6 +99,15 @@ enum {
SPA_MSG_ERROR
};
/* Firewall rule processing error codes
*/
enum {
FW_RULE_SUCCESS = 0,
FW_RULE_ADD_ERROR = 0x1000,
FW_RULE_DELETE_ERROR,
FW_RULE_UNKNOWN_ERROR
};
/* Configuration file parameter tags.
* This will correspond to entries in the configuration parameters
* array.
@@ -322,18 +331,6 @@ typedef struct acc_stanza
#define MAX_CHAIN_NAME_LEN 32
#define MAX_TARGET_NAME_LEN 32
#define MAX_FW_COMMAND_ARGS_LEN 256
/* iptables command args
*/
#define IPT_ADD_RULE_ARGS "-t %s -I %s %i -p %s -s %s -d %s --dport %s -j %s"
#define IPT_DEL_RULE_ARGS "-t %s -D %s %i"
#define IPT_NEW_CHAIN_ARGS "-t %s -N %s"
#define IPT_FLUSH_CHAIN_ARGS "-t %s -F %s"
#define IPT_DEL_CHAIN_ARGS "-t %s -X %s"
#define IPT_ADD_JUMP_RULE_ARGS "-t %s -I %s %i -j %s"
#define IPT_LIST_RULES_ARGS " -t %s -L %s --line-numbers -n"
/* Fwknop custom chain types
*/
enum {
@@ -370,6 +367,8 @@ struct fw_chain {
int jump_rule_pos;
char to_chain[MAX_CHAIN_NAME_LEN];
int rule_pos;
int active_rules;
time_t next_expire;
};
/* Based on the fw_chain fields (not counting type)
@@ -381,7 +380,6 @@ struct fw_config {
char fw_command[MAX_PATH_LEN];
};
/* SPA Packet info struct.
*/
typedef struct spa_pkt_info
@@ -391,6 +389,25 @@ typedef struct spa_pkt_info
unsigned char packet_data[MAX_SPA_PACKET_LEN+1];
} spa_pkt_info_t;
/* Struct for (processed and verified) SPA data used by the server.
*/
typedef struct spa_data
{
char *username;
time_t timestamp;
char *version;
short message_type;
char *spa_message;
char spa_message_src_ip[16];
char pkt_source_ip[16];
char spa_message_remain[1024]; /* --DSS arbitrary bounds */
char *nat_access;
char *server_auth;
unsigned int client_timeout;
unsigned int fw_access_timeout;
char *use_src_ip;
} spa_data_t;
/* fwknopd server configuration parameters and values
*/
typedef struct fko_srv_options

View File

@@ -28,6 +28,48 @@
#include "access.h"
#include "log_msg.h"
/* Popluate a spa_data struct from an initialized (and populated) FKO context.
*/
int
get_spa_data_fields(fko_ctx_t ctx, spa_data_t *spdat)
{
int res = FKO_SUCCESS;
res = fko_get_username(ctx, &(spdat->username));
if(res != FKO_SUCCESS)
return(res);
res = fko_get_timestamp(ctx, &(spdat->timestamp));
if(res != FKO_SUCCESS)
return(res);
res = fko_get_version(ctx, &(spdat->version));
if(res != FKO_SUCCESS)
return(res);
res = fko_get_spa_message_type(ctx, &(spdat->message_type));
if(res != FKO_SUCCESS)
return(res);
res = fko_get_spa_message(ctx, &(spdat->spa_message));
if(res != FKO_SUCCESS)
return(res);
res = fko_get_spa_nat_access(ctx, &(spdat->nat_access));
if(res != FKO_SUCCESS)
return(res);
res = fko_get_spa_server_auth(ctx, &(spdat->server_auth));
if(res != FKO_SUCCESS)
return(res);
res = fko_get_spa_client_timeout(ctx, &(spdat->client_timeout));
if(res != FKO_SUCCESS)
return(res);
return(res);
}
/* Process the SPA packet data
*/
int
@@ -39,32 +81,29 @@ incoming_spa(fko_srv_options_t *opts)
fko_ctx_t ctx = NULL;
char *spa_ip_demark;
char spa_msg_src_ip[16];
char spa_msg_remain[1024]; /* --DSS should not have arbitrary limit */
time_t now_ts;
int res, ts_diff, enc_type;
int got_spa_error = 0;
spa_pkt_info_t *spa_pkt = &(opts->spa_pkt);
/* SPA data fields we will want to pull:
/* This will hold our pertinent SPA data.
*/
time_t spa_ts;
short spa_msg_type;
char *spa_username;
char *spa_msg;
char *spa_nat_access;
int spa_client_timeout;
spa_data_t spadat;
/* Get the access.conf data for the stanza that matches this incoming
* source IP address.
*/
acc_stanza_t *acc = acc_check_source(opts, spa_pkt->packet_src_ip);
inet_ntop(AF_INET, &(spa_pkt->packet_src_ip),
spadat.pkt_source_ip, sizeof(spadat.pkt_source_ip));
log_msg(LOG_INFO, "SPA packet from IP: %s received.", spadat.pkt_source_ip);
if(acc == NULL)
{
log_msg(LOG_WARNING|LOG_STDERR,
"No access data found for source IP: %u", spa_pkt->packet_src_ip
"No access data found for source IP: %s", spadat.pkt_source_ip
);
return(SPA_MSG_ACCESS_DENIED);
@@ -76,7 +115,7 @@ incoming_spa(fko_srv_options_t *opts)
return(SPA_MSG_BAD_DATA);
/* --DSS temp */
fprintf(stderr, "SPA Packet: '%s'\n", spa_pkt->packet_data);
//fprintf(stderr, "SPA Packet: '%s'\n", spa_pkt->packet_data);
/* --DSS temp */
/* Reset the packet data length to 0. This our indicator to the rest of
@@ -127,7 +166,7 @@ fprintf(stderr, "SPA Packet: '%s'\n", spa_pkt->packet_data);
if(acc->gpg_decrypt_id != NULL)
fko_set_gpg_recipient(ctx, acc->gpg_decrypt_id);
/* If REMOTE_ID is set validate the check the signer. Otherwise,
/* If REMOTE_ID is set, validate and check the signer. Otherwise,
* skip and ignore verify errors.
*
* TODO: At present we are not checking signatures.
@@ -180,33 +219,45 @@ fprintf(stderr, "SPA Packet: '%s'\n", spa_pkt->packet_data);
goto clean_and_bail;
}
/* At this point, we assume the SPA data is valid. Now we need to see
* if it meets our access criteria.
*/
/* --DSS temp */
fprintf(stderr, "Decode res = %i\n", res);
display_ctx(ctx);
//fprintf(stderr, "Decode res = %i\n", res);
//display_ctx(ctx);
/* --DSS temp */
/* Check for replays if so configured.
*/
if(strncasecmp(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0)
{
res = replay_check(opts, ctx);
if(res != SPA_MSG_SUCCESS)
if(res != 0) /* non-zero means we have seen this packet before. */
goto clean_and_bail;
}
/* Populate our spa data struct for future reference.
*/
res = get_spa_data_fields(ctx, &spadat);
spadat.fw_access_timeout = (acc->fw_access_timeout > 0)
? acc->fw_access_timeout : DEF_FW_ACCESS_TIMEOUT;
if(res != FKO_SUCCESS)
{
log_msg(LOG_ERR|LOG_STDERR, "Unexpected error pulling SPA data from the context: %s",
fko_errstr(res));
res = SPA_MSG_ERROR;
goto clean_and_bail;
}
/* Check packet age if so configured.
*/
if(strncasecmp(opts->config[CONF_ENABLE_SPA_PACKET_AGING], "Y", 1) == 0)
{
if(fko_get_timestamp(ctx, &spa_ts) != FKO_SUCCESS)
{
log_msg(LOG_WARNING|LOG_STDERR, "Error getting SPA timestamp: %s",
fko_errstr(res));
res = SPA_MSG_ERROR;
goto clean_and_bail;
}
time(&now_ts);
ts_diff = now_ts - spa_ts;
ts_diff = now_ts - spadat.timestamp;
if(ts_diff > atoi(opts->config[CONF_MAX_SPA_PACKET_AGE]))
{
@@ -217,26 +268,11 @@ display_ctx(ctx);
}
}
/* Ok, we can pull the rest of the spa data we are interested in.
*/
if(fko_get_spa_message_type(ctx, &spa_msg_type) != FKO_SUCCESS)
{
log_msg(LOG_WARNING|LOG_STDERR, "Error getting SPA message type: %s",
fko_errstr(res));
got_spa_error++;
}
if(fko_get_spa_message(ctx, &spa_msg) != FKO_SUCCESS)
{
log_msg(LOG_WARNING|LOG_STDERR, "Error getting SPA message string: %s",
fko_errstr(res));
got_spa_error++;
}
/* At this point, we have enough to check the embedded (or packet source)
* IP address against the defined access rights. We start by splitting
* the spa msg source IP from the remainder of the message.
*/
spa_ip_demark = strchr(spa_msg, ',');
spa_ip_demark = strchr(spadat.spa_message, ',');
if(spa_ip_demark == NULL)
{
log_msg(LOG_WARNING|LOG_STDERR, "Error parsing SPA message string: %s",
@@ -245,68 +281,47 @@ display_ctx(ctx);
goto clean_and_bail;
}
strlcpy(spa_msg_src_ip, spa_msg, (spa_ip_demark-spa_msg)+1);
strlcpy(spa_msg_remain, spa_ip_demark+1, 1024);
strlcpy(spadat.spa_message_src_ip, spadat.spa_message, (spa_ip_demark - spadat.spa_message) + 1);
strlcpy(spadat.spa_message_remain, spa_ip_demark+1, 1024);
/* If use source IP was requested (embedded IP of 0.0.0.0), make sure it
* is allowed.
*/
if((strcmp(spa_msg_src_ip, "0.0.0.0") == 0) && acc->require_source_address)
if(strcmp(spadat.spa_message_src_ip, "0.0.0.0") == 0)
{
log_msg(LOG_WARNING|LOG_STDERR,
"Got 0.0.0.0 when valid source IP was required."
);
res = SPA_MSG_ACCESS_DENIED;
goto clean_and_bail;
if(acc->require_source_address)
{
log_msg(LOG_WARNING|LOG_STDERR,
"Got 0.0.0.0 when valid source IP was required."
);
res = SPA_MSG_ACCESS_DENIED;
goto clean_and_bail;
}
spadat.use_src_ip = spadat.pkt_source_ip;
}
else
spadat.use_src_ip = spadat.spa_message_src_ip;
/* If REQUIRE_USERNAME is set, make sure the username in this SPA data
* matches.
*/
if(acc->require_username != NULL)
{
if(fko_get_username(ctx, &spa_username) != FKO_SUCCESS)
{
log_msg(LOG_WARNING|LOG_STDERR, "Error getting SPA username string: %s",
fko_errstr(res));
got_spa_error++;
}
if(strcmp(spa_username, acc->require_username) != 0)
if(strcmp(spadat.username, acc->require_username) != 0)
{
log_msg(LOG_WARNING|LOG_STDERR,
"Username in SPA data (%s) does not match required username: %s",
spa_username, acc->require_username
spadat.username, acc->require_username
);
res = SPA_MSG_ACCESS_DENIED;
goto clean_and_bail;
}
}
/* Get the rest of our SPA data fields.
*/
if(fko_get_spa_nat_access(ctx, &spa_nat_access) != FKO_SUCCESS)
{
log_msg(LOG_WARNING|LOG_STDERR, "Error getting SPA nat access string: %s",
fko_errstr(res));
got_spa_error++;
}
if(fko_get_spa_client_timeout(ctx, &spa_client_timeout) != FKO_SUCCESS)
{
log_msg(LOG_WARNING|LOG_STDERR, "Error getting SPA client_timeout: %s",
fko_errstr(res));
got_spa_error++;
}
if(got_spa_error > 0)
{
res = SPA_MSG_ERROR;
goto clean_and_bail;
}
/* Take action based on SPA message type.
*/
switch(spa_msg_type)
switch(spadat.message_type)
{
/* Command messages.
*/
@@ -314,7 +329,7 @@ display_ctx(ctx);
if(!acc->enable_cmd_exec)
{
log_msg(LOG_WARNING|LOG_STDERR,
"SPA Command message are not yet allowed or supported."
"SPA Command message are not allowed in the current configuration."
);
res = SPA_MSG_ACCESS_DENIED;
}
@@ -356,17 +371,28 @@ display_ctx(ctx);
case FKO_CLIENT_TIMEOUT_ACCESS_MSG:
/* Check access against restrict_ports and open_ports.
*/
res = acc_check_port_access(acc, spa_msg_remain);
res = acc_check_port_access(acc, spadat.spa_message_remain);
// --DSS temp
log_msg(LOG_WARNING|LOG_STDERR,
"<<<< This SPA access msg would be %s >>>>",
res ? "allowed":"DENIED due to port restictions"
);
res = SPA_MSG_NOT_SUPPORTED;
/* --DSS TODO: Finish Me */
if(!res)
{
log_msg(LOG_WARNING|LOG_STDERR,
"One or more requested protocol/ports was denied per access.conf."
);
res = SPA_MSG_ACCESS_DENIED;
}
else
{
/* Process the access message.
*/
/* --DSS temp
log_msg(LOG_WARNING|LOG_STDERR,
"<<<< This SPA access msg would be %s >>>>",
res ? "allowed":"DENIED due to port restictions"
);
res = SPA_MSG_NOT_SUPPORTED;
*/
res = process_access_request(opts, &spadat);
}
break;
}

View File

@@ -31,6 +31,7 @@
#include "incoming_spa.h"
#include "config_init.h"
#include "sig_handler.h"
#include "fw_util.h"
#include "log_msg.h"
/* The pcap capture routine.
@@ -198,8 +199,7 @@ pcap_capture(fko_srv_options_t *opts)
/* Check for any expired firewall rules and deal with them.
*/
//--DSS TODO: still need to write this part...
//check_firewall_rules(opts);
check_firewall_rules(opts);
usleep(10000);
}