Permalink
Browse files

Added access stanza expiration feature, multiple access stanza bug fix

This commit does two major things:

1) Two new access.conf variables are added "ACCESS_EXPIRE" and
"ACCESS_EXPIRE_EPOCH" to allow access stanzas to be expired without having
to modify the access.conf file and restart fwknopd.

2) Allow an access stanza that matches the SPA source address to not
automatically short circuit other stanzas if there is an error (such as when
there are multiple encryption keys involved and an incoming SPA packet is
meant for, say, the second stanza and the first therefore doesn't allow
proper decryption).
  • Loading branch information...
mrash committed Nov 29, 2011
1 parent 9e884e9 commit b280f5cde0246cdef33dee3f8be66a2bcef77336
View
@@ -175,6 +175,17 @@ See the 'fwknopd.conf' file for the full list and corresponding details.
synchronization with the *fwknopd* server system (NTP is good). The
default age is 120 seconds (two minutes).
+*ACCESS_EXPIRE* '<MM/DD/YYYY>'::
+ Defines an expiration date for the access stanza in MM/DD/YYYY format.
+ All SPA packets that match an expired stanza will be ignored. This
+ parameter is optional.
+
+*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
+ that match an expired stanza will be ignored. This parameter is optional.
+
*ENABLE_DIGEST_PERSISTENCE* '<Y/N>'::
Track digest sums associated with previous SPA packets processed by
*fwknopd*. This allows digest sums to remain persistent across
View
@@ -71,6 +71,65 @@ add_acc_bool(unsigned char *var, const char *val)
return(*var = (strncasecmp(val, "Y", 1) == 0) ? 1 : 0);
}
+/* Add expiration time - convert date to epoch seconds
+*/
+static void
+add_acc_expire_time(fko_srv_options_t *opts, time_t *access_expire_time, const char *val)
+{
+ struct tm tm;
+
+ memset(&tm, 0, sizeof(struct tm));
+
+ if (sscanf(val, "%d/%d/%d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3)
+ {
+
+ log_msg(LOG_ERR,
+ "Fatal invalid epoch seconds value for access stanza expiration time"
+ );
+ clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
+ }
+
+ if(tm.tm_mon > 0)
+ tm.tm_mon -= 1; /* 0-11 */
+
+ /* number of years since 1900
+ */
+ if(tm.tm_year > 1900)
+ tm.tm_year -= 1900;
+ else
+ if(tm.tm_year < 100)
+ tm.tm_year += 100;
+
+ *access_expire_time = mktime(&tm);
+
+ return;
+}
+
+/* Add expiration time via epoch seconds defined in access.conf
+*/
+static void
+add_acc_expire_time_epoch(fko_srv_options_t *opts, time_t *access_expire_time, const char *val)
+{
+ char *endptr;
+ unsigned long expire_time = 0;
+
+ errno = 0;
+
+ expire_time = (time_t) strtoul(val, &endptr, 10);
+
+ if (errno == ERANGE || (errno != 0 && expire_time == 0))
+ {
+ log_msg(LOG_ERR,
+ "Fatal invalid epoch seconds value for access stanza expiration time"
+ );
+ clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
+ }
+
+ *access_expire_time = (time_t) expire_time;
+
+ return;
+}
+
/* Take an IP or Subnet/Mask and convert it to mask for later
* comparisons of incoming source IPs against this mask.
*/
@@ -848,6 +907,14 @@ parse_access_file(fko_srv_options_t *opts)
{
add_acc_string(&(curr_acc->gpg_remote_id), val);
}
+ else if(CONF_VAR_IS(var, "ACCESS_EXPIRE"))
+ {
+ add_acc_expire_time(opts, &(curr_acc->access_expire_time), val);
+ }
+ else if(CONF_VAR_IS(var, "ACCESS_EXPIRE_EPOCH"))
+ {
+ add_acc_expire_time_epoch(opts, &(curr_acc->access_expire_time), val);
+ }
else
{
fprintf(stderr,
@@ -894,7 +961,7 @@ parse_access_file(fko_srv_options_t *opts)
return;
}
-static int
+int
compare_addr_list(acc_int_list_t *source_list, const uint32_t ip)
{
int match = 0;
@@ -913,34 +980,6 @@ compare_addr_list(acc_int_list_t *source_list, const uint32_t ip)
return(match);
}
-/* Check an IP address against the list of allowed SOURCE stanzas.
- * return the a pointer to the access stanza that matches first or
- * NULL if no match is found.
-*/
-acc_stanza_t*
-acc_check_source(fko_srv_options_t *opts, const uint32_t ip)
-{
- acc_stanza_t *acc = opts->acc_stanzas;
-
- if(acc == NULL)
- {
- log_msg(LOG_WARNING,
- "Check access source called with no access stanzas defined."
- );
- return(NULL);
- }
-
- while(acc)
- {
- if(compare_addr_list(acc->source_list, ip))
- break;
-
- acc = acc->next;
- }
-
- return(acc);
-}
-
/* Compare the contents of 2 port lists. Return true on a match.
* Match depends on the match_any flag. if match_any is 1 then any
* entry in the incoming data need only match one item to return true.
@@ -1084,6 +1123,7 @@ dump_access_list(const fko_srv_options_t *opts)
" CMD_EXEC_USER: %s\n"
" REQUIRE_USERNAME: %s\n"
" REQUIRE_SOURCE_ADDRESS: %s\n"
+ " ACCESS_EXPIRE: %s" /* asctime() adds a newline */
" GPG_HOME_DIR: %s\n"
" GPG_DECRYPT_ID: %s\n"
" GPG_DECRYPT_PW: <see the access.conf file>\n"
@@ -1100,6 +1140,7 @@ dump_access_list(const fko_srv_options_t *opts)
(acc->cmd_exec_user == NULL) ? "<not set>" : acc->cmd_exec_user,
(acc->require_username == NULL) ? "<not set>" : acc->require_username,
acc->require_source_address ? "Yes" : "No",
+ (acc->access_expire_time > 0) ? asctime(localtime(&acc->access_expire_time)) : "<not set>",
(acc->gpg_home_dir == NULL) ? "<not set>" : acc->gpg_home_dir,
(acc->gpg_decrypt_id == NULL) ? "<not set>" : acc->gpg_decrypt_id,
//(acc->gpg_decrypt_pw == NULL) ? "<not set>" : acc->gpg_decrypt_pw,
View
@@ -37,7 +37,7 @@
/* Function Prototypes
*/
void parse_access_file(fko_srv_options_t *opts);
-acc_stanza_t* acc_check_source(fko_srv_options_t *opts, const uint32_t ip);
+int compare_addr_list(acc_int_list_t *source_list, const uint32_t ip);
int acc_check_port_access(acc_stanza_t *acc, char *port_str);
int acc_check_gpg_remote_id(acc_stanza_t *acc, const char *gpg_id);
void dump_access_list(const fko_srv_options_t *opts);
@@ -801,7 +801,7 @@ process_spa_request(const fko_srv_options_t *opts, spa_data_t *spadat)
snat_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);
}
}
View
@@ -280,6 +280,8 @@ typedef struct acc_stanza
unsigned char gpg_ignore_sig_error;
char *gpg_remote_id;
acc_string_list_t *gpg_remote_id_list;
+ time_t access_expire_time;
+ int expired;
struct acc_stanza *next;
} acc_stanza_t;
Oops, something went wrong.

0 comments on commit b280f5c

Please sign in to comment.