[server] additional work on splitting incoming_spa() loop into functions

This commit is contained in:
Michael Rash
2015-07-25 13:27:42 -07:00
parent 591d400216
commit c0330e5c8b

View File

@@ -50,7 +50,7 @@
* error code value if there is any indication the data is not valid spa data.
*/
static int
preprocess_spa_data(fko_srv_options_t *opts, spa_pkt_info_t *spa_pkt)
preprocess_spa_data(const fko_srv_options_t *opts, spa_pkt_info_t *spa_pkt)
{
char *ndx = (char *)&(spa_pkt->packet_data);
@@ -269,6 +269,29 @@ get_spa_data_fields(fko_ctx_t ctx, spa_data_t *spdat)
return(res);
}
static int
check_pkt_age(const fko_srv_options_t *opts, spa_data_t *spadat,
const int stanza_num, const int conf_pkt_age)
{
int ts_diff;
time_t now_ts;
if(strncasecmp(opts->config[CONF_ENABLE_SPA_PACKET_AGING], "Y", 1) == 0)
{
time(&now_ts);
ts_diff = labs(now_ts - spadat->timestamp);
if(ts_diff > conf_pkt_age)
{
log_msg(LOG_WARNING, "[%s] (stanza #%d) SPA data time difference is too great (%i seconds).",
spadat->pkt_source_ip, stanza_num, ts_diff);
return 0;
}
}
return 1;
}
static int
check_stanza_expiration(acc_stanza_t *acc, spa_data_t *spadat,
const int stanza_num)
@@ -489,173 +512,365 @@ process_cmd_msg(fko_srv_options_t *opts, acc_stanza_t *acc,
}
static int
handle_gpg_enc(acc_stanza_t *acc, spa_pkt_info_t *spa_pkt,
spa_data_t *spadat, fko_ctx_t *ctx, int *attempted_decrypt,
const int stanza_num, int *res)
check_mode_ctx(spa_data_t *spadat, fko_ctx_t *ctx, int attempted_decrypt,
const int enc_type, const int stanza_num, const int res)
{
/* For GPG we create the new context without decrypting on the fly
* so we can set some GPG parameters first.
*/
if(acc->gpg_decrypt_pw != NULL || acc->gpg_allow_no_pw)
if(attempted_decrypt == 0)
{
*res = fko_new_with_data(ctx, (char *)spa_pkt->packet_data, NULL,
0, FKO_ENC_MODE_ASYMMETRIC, acc->hmac_key,
acc->hmac_key_len, acc->hmac_type);
log_msg(LOG_ERR,
"[%s] (stanza #%d) No stanza encryption mode match for encryption type: %i.",
spadat->pkt_source_ip, stanza_num, enc_type);
return 0;
}
if(*res != FKO_SUCCESS)
/* Do we have a valid FKO context? Did the SPA decrypt properly?
*/
if(res != FKO_SUCCESS)
{
log_msg(LOG_WARNING, "[%s] (stanza #%d) Error creating fko context: %s",
spadat->pkt_source_ip, stanza_num, fko_errstr(res));
if(IS_GPG_ERROR(res))
log_msg(LOG_WARNING, "[%s] (stanza #%d) - GPG ERROR: %s",
spadat->pkt_source_ip, stanza_num, fko_gpg_errstr(*ctx));
return 0;
}
return 1;
}
static int
handle_rijndael_enc(acc_stanza_t *acc, spa_pkt_info_t *spa_pkt,
spa_data_t *spadat, fko_ctx_t *ctx, int *attempted_decrypt,
int *cmd_exec_success, const int enc_type, const int stanza_num,
int *res)
{
if(acc->use_rijndael)
{
if(acc->key == NULL)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error creating fko context (before decryption): %s",
spadat->pkt_source_ip, stanza_num, fko_errstr(*res)
log_msg(LOG_ERR,
"[%s] (stanza #%d) No KEY for RIJNDAEL encrypted messages",
spadat->pkt_source_ip, stanza_num
);
return 0;
}
/* Set whatever GPG parameters we have.
/* Command mode messages may be quite long
*/
if(acc->gpg_exe != NULL)
if(acc->enable_cmd_exec || enc_type == FKO_ENCRYPTION_RIJNDAEL)
{
*res = fko_set_gpg_exe(*ctx, acc->gpg_exe);
*res = fko_new_with_data(ctx, (char *)spa_pkt->packet_data,
acc->key, acc->key_len, acc->encryption_mode, acc->hmac_key,
acc->hmac_key_len, acc->hmac_type);
*attempted_decrypt = 1;
if(*res == FKO_SUCCESS)
*cmd_exec_success = 1;
}
}
return 1;
}
static int
handle_gpg_enc(acc_stanza_t *acc, spa_pkt_info_t *spa_pkt,
spa_data_t *spadat, fko_ctx_t *ctx, int *attempted_decrypt,
const int cmd_exec_success, const int enc_type,
const int stanza_num, int *res)
{
if(acc->use_gpg && enc_type == FKO_ENCRYPTION_GPG && cmd_exec_success == 0)
{
/* For GPG we create the new context without decrypting on the fly
* so we can set some GPG parameters first.
*/
if(acc->gpg_decrypt_pw != NULL || acc->gpg_allow_no_pw)
{
*res = fko_new_with_data(ctx, (char *)spa_pkt->packet_data, NULL,
0, FKO_ENC_MODE_ASYMMETRIC, acc->hmac_key,
acc->hmac_key_len, acc->hmac_type);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error setting GPG path %s: %s",
spadat->pkt_source_ip, stanza_num, acc->gpg_exe,
fko_errstr(*res)
"[%s] (stanza #%d) Error creating fko context (before decryption): %s",
spadat->pkt_source_ip, stanza_num, fko_errstr(*res)
);
return 0;
}
}
if(acc->gpg_home_dir != NULL)
{
*res = fko_set_gpg_home_dir(*ctx, acc->gpg_home_dir);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error setting GPG keyring path to %s: %s",
spadat->pkt_source_ip, stanza_num, acc->gpg_home_dir,
fko_errstr(*res)
);
return 0;
}
}
if(acc->gpg_decrypt_id != NULL)
fko_set_gpg_recipient(*ctx, acc->gpg_decrypt_id);
/* If GPG_REQUIRE_SIG is set for this acc stanza, then set
* the FKO context accordingly and check the other GPG Sig-
* related parameters. This also applies when REMOTE_ID is
* set.
*/
if(acc->gpg_require_sig)
{
fko_set_gpg_signature_verify(*ctx, 1);
/* Set whether or not to ignore signature verification errors.
/* Set whatever GPG parameters we have.
*/
fko_set_gpg_ignore_verify_error(*ctx, acc->gpg_ignore_sig_error);
}
else
{
fko_set_gpg_signature_verify(*ctx, 0);
fko_set_gpg_ignore_verify_error(*ctx, 1);
}
if(acc->gpg_exe != NULL)
{
*res = fko_set_gpg_exe(*ctx, acc->gpg_exe);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error setting GPG path %s: %s",
spadat->pkt_source_ip, stanza_num, acc->gpg_exe,
fko_errstr(*res)
);
return 0;
}
}
/* Now decrypt the data.
*/
*res = fko_decrypt_spa_data(*ctx, acc->gpg_decrypt_pw, 0);
*attempted_decrypt = 1;
if(acc->gpg_home_dir != NULL)
{
*res = fko_set_gpg_home_dir(*ctx, acc->gpg_home_dir);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error setting GPG keyring path to %s: %s",
spadat->pkt_source_ip, stanza_num, acc->gpg_home_dir,
fko_errstr(*res)
);
return 0;
}
}
if(acc->gpg_decrypt_id != NULL)
fko_set_gpg_recipient(*ctx, acc->gpg_decrypt_id);
/* If GPG_REQUIRE_SIG is set for this acc stanza, then set
* the FKO context accordingly and check the other GPG Sig-
* related parameters. This also applies when REMOTE_ID is
* set.
*/
if(acc->gpg_require_sig)
{
fko_set_gpg_signature_verify(*ctx, 1);
/* Set whether or not to ignore signature verification errors.
*/
fko_set_gpg_ignore_verify_error(*ctx, acc->gpg_ignore_sig_error);
}
else
{
fko_set_gpg_signature_verify(*ctx, 0);
fko_set_gpg_ignore_verify_error(*ctx, 1);
}
/* Now decrypt the data.
*/
*res = fko_decrypt_spa_data(*ctx, acc->gpg_decrypt_pw, 0);
*attempted_decrypt = 1;
}
}
return 1;
}
static int
handle_gpg_sigs(acc_stanza_t *acc, spa_data_t *spadat,
fko_ctx_t *ctx, const int stanza_num, int *res)
fko_ctx_t *ctx, const int enc_type, const int stanza_num, int *res)
{
char *gpg_id, *gpg_fpr;
acc_string_list_t *gpg_id_ndx;
acc_string_list_t *gpg_fpr_ndx;
unsigned char is_gpg_match = 0;
*res = fko_get_gpg_signature_id(*ctx, &gpg_id);
if(*res != FKO_SUCCESS)
if(enc_type == FKO_ENCRYPTION_GPG && acc->gpg_require_sig)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error pulling the GPG signature ID from the context: %s",
spadat->pkt_source_ip, stanza_num, fko_gpg_errstr(*ctx));
return 0;
}
*res = fko_get_gpg_signature_fpr(*ctx, &gpg_fpr);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error pulling the GPG fingerprint from the context: %s",
spadat->pkt_source_ip, stanza_num, fko_gpg_errstr(*ctx));
return 0;
}
log_msg(LOG_INFO, "[%s] (stanza #%d) Incoming SPA data signed by '%s' (fingerprint '%s').",
spadat->pkt_source_ip, stanza_num, gpg_id, gpg_fpr);
/* prefer GnuPG fingerprint match if so configured
*/
if(acc->gpg_remote_fpr != NULL)
{
is_gpg_match = 0;
for(gpg_fpr_ndx = acc->gpg_remote_fpr_list;
gpg_fpr_ndx != NULL; gpg_fpr_ndx=gpg_fpr_ndx->next)
{
*res = fko_gpg_signature_fpr_match(*ctx,
gpg_fpr_ndx->str, &is_gpg_match);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error in GPG signature comparision: %s",
spadat->pkt_source_ip, stanza_num, fko_gpg_errstr(*ctx));
return 0;
}
if(is_gpg_match)
break;
}
if(! is_gpg_match)
*res = fko_get_gpg_signature_id(*ctx, &gpg_id);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Incoming SPA packet signed by: %s, but that fingerprint is not in the GPG_FINGERPRINT_ID list.",
spadat->pkt_source_ip, stanza_num, gpg_fpr);
"[%s] (stanza #%d) Error pulling the GPG signature ID from the context: %s",
spadat->pkt_source_ip, stanza_num, fko_gpg_errstr(*ctx));
return 0;
}
*res = fko_get_gpg_signature_fpr(*ctx, &gpg_fpr);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error pulling the GPG fingerprint from the context: %s",
spadat->pkt_source_ip, stanza_num, fko_gpg_errstr(*ctx));
return 0;
}
log_msg(LOG_INFO,
"[%s] (stanza #%d) Incoming SPA data signed by '%s' (fingerprint '%s').",
spadat->pkt_source_ip, stanza_num, gpg_id, gpg_fpr);
/* prefer GnuPG fingerprint match if so configured
*/
if(acc->gpg_remote_fpr != NULL)
{
is_gpg_match = 0;
for(gpg_fpr_ndx = acc->gpg_remote_fpr_list;
gpg_fpr_ndx != NULL; gpg_fpr_ndx=gpg_fpr_ndx->next)
{
*res = fko_gpg_signature_fpr_match(*ctx,
gpg_fpr_ndx->str, &is_gpg_match);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error in GPG signature comparision: %s",
spadat->pkt_source_ip, stanza_num, fko_gpg_errstr(*ctx));
return 0;
}
if(is_gpg_match)
break;
}
if(! is_gpg_match)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Incoming SPA packet signed by: %s, but that fingerprint is not in the GPG_FINGERPRINT_ID list.",
spadat->pkt_source_ip, stanza_num, gpg_fpr);
return 0;
}
}
if(acc->gpg_remote_id != NULL)
{
is_gpg_match = 0;
for(gpg_id_ndx = acc->gpg_remote_id_list;
gpg_id_ndx != NULL; gpg_id_ndx=gpg_id_ndx->next)
{
*res = fko_gpg_signature_id_match(*ctx,
gpg_id_ndx->str, &is_gpg_match);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error in GPG signature comparision: %s",
spadat->pkt_source_ip, stanza_num, fko_gpg_errstr(*ctx));
return 0;
}
if(is_gpg_match)
break;
}
if(! is_gpg_match)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Incoming SPA packet signed by ID: %s, but that ID is not in the GPG_REMOTE_ID list.",
spadat->pkt_source_ip, stanza_num, gpg_id);
return 0;
}
}
}
return 1;
}
static int
check_src_access(acc_stanza_t *acc, spa_data_t *spadat, const int stanza_num)
{
if(strcmp(spadat->spa_message_src_ip, "0.0.0.0") == 0)
{
if(acc->require_source_address)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Got 0.0.0.0 when valid source IP was required.",
spadat->pkt_source_ip, stanza_num
);
return 0;
}
spadat->use_src_ip = spadat->pkt_source_ip;
}
else
spadat->use_src_ip = spadat->spa_message_src_ip;
return 1;
}
static int
check_username(acc_stanza_t *acc, spa_data_t *spadat, const int stanza_num)
{
if(acc->require_username != NULL)
{
if(strcmp(spadat->username, acc->require_username) != 0)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Username in SPA data (%s) does not match required username: %s",
spadat->pkt_source_ip, stanza_num, spadat->username, acc->require_username
);
return 0;
}
}
return 1;
}
if(acc->gpg_remote_id != NULL)
static int
check_nat_access_types(fko_srv_options_t *opts, acc_stanza_t *acc,
spa_data_t *spadat, const int stanza_num)
{
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)
{
is_gpg_match = 0;
for(gpg_id_ndx = acc->gpg_remote_id_list;
gpg_id_ndx != NULL; gpg_id_ndx=gpg_id_ndx->next)
{
*res = fko_gpg_signature_id_match(*ctx,
gpg_id_ndx->str, &is_gpg_match);
if(*res != FKO_SUCCESS)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Error in GPG signature comparision: %s",
spadat->pkt_source_ip, stanza_num, fko_gpg_errstr(*ctx));
return 0;
}
if(is_gpg_match)
break;
}
if(! is_gpg_match)
#if FIREWALL_FIREWALLD
if(strncasecmp(opts->config[CONF_ENABLE_FIREWD_FORWARDING], "Y", 1)!=0)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Incoming SPA packet signed by ID: %s, but that ID is not in the GPG_REMOTE_ID list.",
spadat->pkt_source_ip, stanza_num, gpg_id);
"(stanza #%d) SPA packet from %s requested NAT access, but is not enabled",
stanza_num, spadat->pkt_source_ip
);
return 0;
}
#elif FIREWALL_IPTABLES
if(strncasecmp(opts->config[CONF_ENABLE_IPT_FORWARDING], "Y", 1)!=0)
{
log_msg(LOG_WARNING,
"(stanza #%d) SPA packet from %s requested NAT access, but is not enabled",
stanza_num, spadat->pkt_source_ip
);
return 0;
}
#else
log_msg(LOG_WARNING,
"(stanza #%d) SPA packet from %s requested unsupported NAT access",
stanza_num, spadat->pkt_source_ip
);
return 0;
#endif
}
return 1;
}
static int
add_replay_cache(fko_srv_options_t *opts, acc_stanza_t *acc,
spa_data_t *spadat, char *raw_digest, int *added_replay_digest,
const int stanza_num, int *res)
{
if (!opts->test && added_replay_digest == 0
&& strncasecmp(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0)
{
*res = add_replay(opts, raw_digest);
if (*res != SPA_MSG_SUCCESS)
{
log_msg(LOG_WARNING, "[%s] (stanza #%d) Could not add digest to replay cache",
spadat->pkt_source_ip, stanza_num);
return 0;
}
*added_replay_digest = 1;
}
return 1;
}
static void
set_timeout(acc_stanza_t *acc, spa_data_t *spadat)
{
if(spadat->client_timeout > 0)
spadat->fw_access_timeout = spadat->client_timeout;
else if(acc->fw_access_timeout > 0)
spadat->fw_access_timeout = acc->fw_access_timeout;
else
spadat->fw_access_timeout = DEF_FW_ACCESS_TIMEOUT;
return;
}
static int
check_port_proto(acc_stanza_t *acc, spa_data_t *spadat, const int stanza_num)
{
if(! acc_check_port_access(acc, spadat->spa_message_remain))
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) One or more requested protocol/ports was denied per access.conf.",
spadat->pkt_source_ip, stanza_num
);
return 0;
}
return 1;
}
@@ -671,8 +886,7 @@ incoming_spa(fko_srv_options_t *opts)
fko_ctx_t ctx = NULL;
char *spa_ip_demark, *raw_digest = NULL;
time_t now_ts;
int res, ts_diff, enc_type, stanza_num=0;
int res, enc_type, stanza_num=0;
int added_replay_digest = 0;
int is_err, cmd_exec_success = 0, attempted_decrypt = 0;
int conf_pkt_age = 0;
@@ -761,80 +975,35 @@ incoming_spa(fko_srv_options_t *opts)
*/
enc_type = fko_encryption_type((char *)spa_pkt->packet_data);
if(acc->use_rijndael)
if(! handle_rijndael_enc(acc, spa_pkt, &spadat, &ctx,
&attempted_decrypt, &cmd_exec_success, enc_type,
stanza_num, &res))
{
if (acc->key == NULL)
{
log_msg(LOG_ERR,
"[%s] (stanza #%d) No KEY for RIJNDAEL encrypted messages",
spadat.pkt_source_ip, stanza_num
);
acc = acc->next;
continue;
}
/* Command mode messages may be quite long
*/
if(acc->enable_cmd_exec || enc_type == FKO_ENCRYPTION_RIJNDAEL)
{
res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data,
acc->key, acc->key_len, acc->encryption_mode, acc->hmac_key,
acc->hmac_key_len, acc->hmac_type);
attempted_decrypt = 1;
if(res == FKO_SUCCESS)
cmd_exec_success = 1;
}
}
if(acc->use_gpg && enc_type == FKO_ENCRYPTION_GPG && cmd_exec_success == 0)
{
if(! handle_gpg_enc(acc, spa_pkt, &spadat,
&ctx, &attempted_decrypt, stanza_num, &res))
{
acc = acc->next;
continue;
}
}
if(attempted_decrypt == 0)
{
log_msg(LOG_ERR,
"[%s] (stanza #%d) No stanza encryption mode match for encryption type: %i.",
spadat.pkt_source_ip, stanza_num, enc_type);
acc = acc->next;
continue;
}
/* Do we have a valid FKO context? Did the SPA decrypt properly?
*/
if(res != FKO_SUCCESS)
if(! handle_gpg_enc(acc, spa_pkt, &spadat, &ctx, &attempted_decrypt,
cmd_exec_success, enc_type, stanza_num, &res))
{
log_msg(LOG_WARNING, "[%s] (stanza #%d) Error creating fko context: %s",
spadat.pkt_source_ip, stanza_num, fko_errstr(res));
if(IS_GPG_ERROR(res))
log_msg(LOG_WARNING, "[%s] (stanza #%d) - GPG ERROR: %s",
spadat.pkt_source_ip, stanza_num, fko_gpg_errstr(ctx));
acc = acc->next;
continue;
}
if(! check_mode_ctx(&spadat, &ctx, attempted_decrypt,
enc_type, stanza_num, res))
{
acc = acc->next;
continue;
}
/* Add this SPA packet into the replay detection cache
*/
if (!opts->test && added_replay_digest == 0
&& strncasecmp(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0)
if(! add_replay_cache(opts, acc, &spadat, raw_digest,
&added_replay_digest, stanza_num, &res))
{
res = add_replay(opts, raw_digest);
if (res != SPA_MSG_SUCCESS)
{
log_msg(LOG_WARNING, "[%s] (stanza #%d) Could not add digest to replay cache",
spadat.pkt_source_ip, stanza_num);
acc = acc->next;
continue;
}
added_replay_digest = 1;
acc = acc->next;
continue;
}
/* At this point the SPA data is authenticated via the HMAC (if used
@@ -855,13 +1024,10 @@ incoming_spa(fko_srv_options_t *opts)
* an entry in the list.
*/
if(enc_type == FKO_ENCRYPTION_GPG && acc->gpg_require_sig)
if(! handle_gpg_sigs(acc, &spadat, &ctx, enc_type, stanza_num, &res))
{
if(! handle_gpg_sigs(acc, &spadat, &ctx, stanza_num, &res))
{
acc = acc->next;
continue;
}
acc = acc->next;
continue;
}
/* Populate our spa data struct for future reference.
@@ -881,29 +1047,14 @@ incoming_spa(fko_srv_options_t *opts)
* data, then use that. If not, try the FW_ACCESS_TIMEOUT from the
* access.conf file (if there is one). Otherwise use the default.
*/
if(spadat.client_timeout > 0)
spadat.fw_access_timeout = spadat.client_timeout;
else if(acc->fw_access_timeout > 0)
spadat.fw_access_timeout = acc->fw_access_timeout;
else
spadat.fw_access_timeout = DEF_FW_ACCESS_TIMEOUT;
set_timeout(acc, &spadat);
/* Check packet age if so configured.
*/
if(strncasecmp(opts->config[CONF_ENABLE_SPA_PACKET_AGING], "Y", 1) == 0)
if(! check_pkt_age(opts, &spadat, stanza_num, conf_pkt_age))
{
time(&now_ts);
ts_diff = labs(now_ts - spadat.timestamp);
if(ts_diff > conf_pkt_age)
{
log_msg(LOG_WARNING, "[%s] (stanza #%d) SPA data time difference is too great (%i seconds).",
spadat.pkt_source_ip, stanza_num, ts_diff);
acc = acc->next;
continue;
}
acc = acc->next;
continue;
}
/* At this point, we have enough to check the embedded (or packet source)
@@ -943,74 +1094,27 @@ incoming_spa(fko_srv_options_t *opts)
/* If use source IP was requested (embedded IP of 0.0.0.0), make sure it
* is allowed.
*/
if(strcmp(spadat.spa_message_src_ip, "0.0.0.0") == 0)
if(! check_src_access(acc, &spadat, stanza_num))
{
if(acc->require_source_address)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Got 0.0.0.0 when valid source IP was required.",
spadat.pkt_source_ip, stanza_num
);
acc = acc->next;
continue;
}
spadat.use_src_ip = spadat.pkt_source_ip;
acc = acc->next;
continue;
}
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(! check_username(acc, &spadat, stanza_num))
{
if(strcmp(spadat.username, acc->require_username) != 0)
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) Username in SPA data (%s) does not match required username: %s",
spadat.pkt_source_ip, stanza_num, spadat.username, acc->require_username
);
acc = acc->next;
continue;
}
acc = acc->next;
continue;
}
/* Take action based on SPA message type.
*/
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)
if(! check_nat_access_types(opts, acc, &spadat, stanza_num))
{
#if FIREWALL_FIREWALLD
if(strncasecmp(opts->config[CONF_ENABLE_FIREWD_FORWARDING], "Y", 1)!=0)
{
log_msg(LOG_WARNING,
"(stanza #%d) SPA packet from %s requested NAT access, but is not enabled",
stanza_num, spadat.pkt_source_ip
);
acc = acc->next;
continue;
}
#elif FIREWALL_IPTABLES
if(strncasecmp(opts->config[CONF_ENABLE_IPT_FORWARDING], "Y", 1)!=0)
{
log_msg(LOG_WARNING,
"(stanza #%d) SPA packet from %s requested NAT access, but is not enabled",
stanza_num, spadat.pkt_source_ip
);
acc = acc->next;
continue;
}
#else
log_msg(LOG_WARNING,
"(stanza #%d) SPA packet from %s requested unsupported NAT access",
stanza_num, spadat.pkt_source_ip
);
acc = acc->next;
continue;
#endif
}
/* Command messages.
@@ -1029,7 +1133,6 @@ incoming_spa(fko_srv_options_t *opts)
acc = acc->next;
continue;
}
}
/* From this point forward, we have some kind of access message. So
@@ -1038,12 +1141,8 @@ incoming_spa(fko_srv_options_t *opts)
*
* --DSS TODO: We should add BLACKLIST support here as well.
*/
if(! acc_check_port_access(acc, spadat.spa_message_remain))
if(! check_port_proto(acc, &spadat, stanza_num))
{
log_msg(LOG_WARNING,
"[%s] (stanza #%d) One or more requested protocol/ports was denied per access.conf.",
spadat.pkt_source_ip, stanza_num
);
acc = acc->next;
continue;
}
@@ -1066,6 +1165,9 @@ incoming_spa(fko_srv_options_t *opts)
process_spa_request(opts, acc, &spadat);
}
/* If we made it here, then the SPA packet was processed according
* to a matching access.conf stanza, so we're done with this packet.
*/
break;
}