[server] Validate GPG sigs with libfko fko_gpg_signature_id_match() function
This commit is contained in:
@@ -28,6 +28,9 @@ fwknop-2.6.1 (//2014):
|
||||
|
||||
- [libfko] Better SPA packet dumping output to include GnuPG specifics
|
||||
whenever SPA packets are encrypted/authenticated via GnuPG.
|
||||
- [server] Validate SPA packet GnuPG signatures with the libfko
|
||||
fko_gpg_signature_id_match() function instead of server code doing this
|
||||
independently.
|
||||
- [client+server] Add --gpg-exe command line argument and GPG_EXE config
|
||||
variable to ~/.fwknoprc and the access.conf file so that the path to
|
||||
GnuPG can be changed from the default /usr/bin/gpg path.
|
||||
|
||||
@@ -1102,6 +1102,7 @@ fko_gpg_signature_id_match(fko_ctx_t ctx, const char * const id,
|
||||
{
|
||||
#if HAVE_LIBGPGME
|
||||
char *curr_id;
|
||||
int rv = FKO_SUCCESS;
|
||||
|
||||
/* Must be initialized
|
||||
*/
|
||||
@@ -1123,7 +1124,9 @@ fko_gpg_signature_id_match(fko_ctx_t ctx, const char * const id,
|
||||
if(ctx->gpg_sigs == NULL)
|
||||
return(FKO_ERROR_GPGME_NO_SIGNATURE);
|
||||
|
||||
fko_get_gpg_signature_id(ctx, &curr_id);
|
||||
rv = fko_get_gpg_signature_id(ctx, &curr_id);
|
||||
if(rv != FKO_SUCCESS)
|
||||
return rv;
|
||||
|
||||
*result = strcmp(id, curr_id) == 0 ? 1 : 0;
|
||||
|
||||
|
||||
@@ -1641,23 +1641,6 @@ cleanup_and_bail:
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Take a GPG ID string and check it against the list of allowed
|
||||
* GPG_REMOTE_ID's.
|
||||
*
|
||||
* Return 1 if we are allowed
|
||||
*/
|
||||
int
|
||||
acc_check_gpg_remote_id(acc_stanza_t *acc, const char *gpg_id)
|
||||
{
|
||||
acc_string_list_t *ndx;
|
||||
|
||||
for(ndx = acc->gpg_remote_id_list; ndx != NULL; ndx=ndx->next)
|
||||
if(strcasecmp(ndx->str, gpg_id) == 0)
|
||||
return(1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Dump the configuration
|
||||
*/
|
||||
void
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
void parse_access_file(fko_srv_options_t *opts);
|
||||
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);
|
||||
int expand_acc_port_list(acc_port_list_t **plist, char *plist_str);
|
||||
void free_acc_stanzas(fko_srv_options_t *opts);
|
||||
|
||||
+52
-7
@@ -143,6 +143,7 @@ get_raw_digest(char **digest, char *pkt_data)
|
||||
fko_ctx_t ctx = NULL;
|
||||
char *tmp_digest = NULL;
|
||||
int res = FKO_SUCCESS;
|
||||
short raw_digest_type = -1;
|
||||
|
||||
/* initialize an FKO context with no decryption key just so
|
||||
* we can get the outer message digest
|
||||
@@ -169,6 +170,27 @@ get_raw_digest(char **digest, char *pkt_data)
|
||||
return(SPA_MSG_DIGEST_ERROR);
|
||||
}
|
||||
|
||||
res = fko_get_raw_spa_digest_type(ctx, &raw_digest_type);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
log_msg(LOG_WARNING, "Error getting digest type for SPA data: %s",
|
||||
fko_errstr(res));
|
||||
fko_destroy(ctx);
|
||||
ctx = NULL;
|
||||
return(SPA_MSG_DIGEST_ERROR);
|
||||
}
|
||||
|
||||
/* Make sure the digest type is what we expect
|
||||
*/
|
||||
if(raw_digest_type != FKO_DEFAULT_DIGEST)
|
||||
{
|
||||
log_msg(LOG_WARNING, "Error setting digest type for SPA data: %s",
|
||||
fko_errstr(res));
|
||||
fko_destroy(ctx);
|
||||
ctx = NULL;
|
||||
return(SPA_MSG_DIGEST_ERROR);
|
||||
}
|
||||
|
||||
res = fko_set_raw_spa_digest(ctx);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
@@ -285,7 +307,9 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
|
||||
/* Loop through all access stanzas looking for a match
|
||||
*/
|
||||
acc_stanza_t *acc = opts->acc_stanzas;
|
||||
acc_stanza_t *acc = opts->acc_stanzas;
|
||||
acc_string_list_t *gpg_id_ndx;
|
||||
unsigned char is_gpg_match = 0;
|
||||
|
||||
inet_ntop(AF_INET, &(spa_pkt->packet_src_ip),
|
||||
spadat.pkt_source_ip, sizeof(spadat.pkt_source_ip));
|
||||
@@ -593,13 +617,34 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
log_msg(LOG_INFO, "[%s] (stanza #%d) Incoming SPA data signed by '%s'.",
|
||||
spadat.pkt_source_ip, stanza_num, gpg_id);
|
||||
|
||||
if(acc->gpg_remote_id != NULL && !acc_check_gpg_remote_id(acc, gpg_id))
|
||||
if(acc->gpg_remote_id != NULL)
|
||||
{
|
||||
log_msg(LOG_WARNING,
|
||||
"[%s] (stanza #%d) Incoming SPA packet signed by ID: %s, but that ID is not the GPG_REMOTE_ID list.",
|
||||
spadat.pkt_source_ip, stanza_num, gpg_id);
|
||||
acc = acc->next;
|
||||
continue;
|
||||
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 siganture comparision: %s",
|
||||
spadat.pkt_source_ip, stanza_num, fko_gpg_errstr(ctx));
|
||||
acc = acc->next;
|
||||
continue;
|
||||
}
|
||||
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 the GPG_REMOTE_ID list.",
|
||||
spadat.pkt_source_ip, stanza_num, gpg_id);
|
||||
acc = acc->next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user