[client+server] verify GnuPG signatures by default

- [server] When GnuPG is used, the default now is to require that
incoming SPA packets are signed by a key listed in GPG_REMOTE_ID for each
access.conf stanza. In other words, the usage of GPG_REQUIRE_SIG
is no longer necessary in order to authenticate SPA packets via the
GnuPG signature. Verification of GnuPG signatures can be disabled with a
new access.conf variable GPG_DISABLE_SIG, but this is NOT a
recommended configuration.
- [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.
This commit is contained in:
Michael Rash 2014-03-19 23:12:01 -04:00
parent a52aa8d54a
commit 73bc473563
19 changed files with 267 additions and 15 deletions

View File

@ -3,6 +3,16 @@ fwknop-2.6.1 (//2014):
header which references both the AUTHORS and CREDITS files. The
specific language in this header was created by the Debian legal team at
the request of Franck Joncourt.
- [server] When GnuPG is used, the default now is to require that incoming
SPA packets are signed by a key listed in GPG_REMOTE_ID for each
access.conf stanza. In other words, the usage of GPG_REQUIRE_SIG is no
longer necessary in order to authenticate SPA packets via the GnuPG
signature. Verification of GnuPG signatures can be disabled with a new
access.conf variable GPG_DISABLE_SIG, but this is NOT a recommended
configuration.
- [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.
- [libfko] Allow usernames that are compatible with Microsoft guidelines as
defined here: http://technet.microsoft.com/en-us/library/bb726984.aspx
This allows for greater compatibility between fwknop clients on Windows

View File

@ -141,6 +141,7 @@ EXTRA_DIST = \
test/conf/portrange_fwknopd.conf \
test/conf/custom_input_chain_fwknopd.conf \
test/conf/custom_nat_chain_fwknopd.conf \
test/conf/gpg_invalid_exe_access.conf \
test/conf/disable_aging_fwknopd.conf \
test/conf/disable_aging_nat_fwknopd.conf \
test/conf/dual_key_usage_access.conf \
@ -157,6 +158,7 @@ EXTRA_DIST = \
test/conf/gpg_hmac_access.conf \
test/conf/gpg_no_pw_access.conf \
test/conf/gpg_no_pw_hmac_access.conf \
test/conf/fwknoprc_gpg_invalid_exe \
test/conf/fwknoprc_gpg_hmac_sha512_key \
test/conf/gpg_hmac_sha512_access.conf \
test/conf/fwknoprc_hmac_sha512_base64_key \

View File

@ -66,6 +66,7 @@ enum {
GPG_RECIP_KEY,
GPG_SIGNER_KEY,
GPG_HOME_DIR,
GPG_EXE_PATH,
GPG_AGENT,
GPG_ALLOW_NO_SIGNING_PW,
NOOP /* Just to be a marker for the end */
@ -99,6 +100,7 @@ static struct option cmd_opts[] =
{"gpg-recipient-key", 1, NULL, GPG_RECIP_KEY },
{"gpg-signer-key", 1, NULL, GPG_SIGNER_KEY },
{"gpg-home-dir", 1, NULL, GPG_HOME_DIR },
{"gpg-exe", 1, NULL, GPG_EXE_PATH },
{"gpg-agent", 0, NULL, GPG_AGENT },
{"gpg-no-signing-pw", 0, NULL, GPG_ALLOW_NO_SIGNING_PW },
{"get-key", 1, NULL, 'G'},

View File

@ -99,6 +99,7 @@ enum
FWKNOP_CLI_ARG_GPG_RECIPIENT,
FWKNOP_CLI_ARG_GPG_SIGNER,
FWKNOP_CLI_ARG_GPG_HOMEDIR,
FWKNOP_CLI_ARG_GPG_EXE_PATH,
FWKNOP_CLI_ARG_SPOOF_USER,
FWKNOP_CLI_ARG_SPOOF_SOURCE_IP,
FWKNOP_CLI_ARG_ACCESS,
@ -140,6 +141,7 @@ static fko_var_t fko_var_array[FWKNOP_CLI_LAST_ARG] =
{ "GPG_RECIPIENT", FWKNOP_CLI_ARG_GPG_RECIPIENT },
{ "GPG_SIGNER", FWKNOP_CLI_ARG_GPG_SIGNER },
{ "GPG_HOMEDIR", FWKNOP_CLI_ARG_GPG_HOMEDIR },
{ "GPG_EXE", FWKNOP_CLI_ARG_GPG_EXE_PATH },
{ "GPG_SIGNING_PW", FWKNOP_CLI_ARG_GPG_SIGNING_PW },
{ "GPG_SIGNING_PW_BASE64", FWKNOP_CLI_ARG_GPG_SIGNING_PW_BASE64 },
{ "GPG_NO_SIGNING_PW", FWKNOP_CLI_ARG_GPG_NO_SIGNING_PW },
@ -198,7 +200,7 @@ generate_keys(fko_cli_options_t *options)
memset(&(options->key_base64), 0x00, sizeof(options->key_base64));
memset(&(options->hmac_key_base64), 0x00, sizeof(options->hmac_key_base64));
/* Generate the key with through libfko */
/* Generate the key through libfko */
res = fko_key_gen(options->key_base64, options->key_len,
options->hmac_key_base64, options->hmac_key_len,
options->hmac_type);
@ -849,6 +851,7 @@ create_fwknoprc(const char *rcfile)
"#TIME_OFFSET 0\n"
"#USE_GPG N\n"
"#GPG_HOMEDIR /path/to/.gnupg\n"
"#GPG_EXE /path/to/gpg\n"
"#GPG_SIGNER <signer ID>\n"
"#GPG_RECIPIENT <recipient ID>\n"
"\n"
@ -1016,6 +1019,11 @@ parse_rc_param(fko_cli_options_t *options, const char *var_name, char * val)
{
strlcpy(options->gpg_home_dir, val, sizeof(options->gpg_home_dir));
}
/* GPG path */
else if (var->pos == FWKNOP_CLI_ARG_GPG_EXE_PATH)
{
strlcpy(options->gpg_exe, val, sizeof(options->gpg_exe));
}
/* Spoof User */
else if (var->pos == FWKNOP_CLI_ARG_SPOOF_USER)
{
@ -1286,6 +1294,9 @@ add_single_var_to_rc(FILE* fhandle, short var_pos, fko_cli_options_t *options)
case FWKNOP_CLI_ARG_GPG_HOMEDIR :
strlcpy(val, options->gpg_home_dir, sizeof(val));
break;
case FWKNOP_CLI_ARG_GPG_EXE_PATH :
strlcpy(val, options->gpg_exe, sizeof(val));
break;
case FWKNOP_CLI_ARG_GPG_NO_SIGNING_PW :
bool_to_yesno(options->gpg_no_signing_pw, val, sizeof(val));
break;
@ -2191,6 +2202,12 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
add_var_to_bitmask(FWKNOP_CLI_ARG_USE_GPG, &var_bitmask);
add_var_to_bitmask(FWKNOP_CLI_ARG_GPG_HOMEDIR, &var_bitmask);
break;
case GPG_EXE_PATH:
options->use_gpg = 1;
strlcpy(options->gpg_exe, optarg, sizeof(options->gpg_exe));
add_var_to_bitmask(FWKNOP_CLI_ARG_USE_GPG, &var_bitmask);
add_var_to_bitmask(FWKNOP_CLI_ARG_GPG_EXE_PATH, &var_bitmask);
break;
case GPG_AGENT:
options->use_gpg = 1;
options->use_gpg_agent = 1;
@ -2388,6 +2405,7 @@ usage(void)
" --gpg-signer-key Specify the signer's GPG key name or ID.\n"
" --gpg-home-dir Specify the GPG home directory.\n"
" --gpg-agent Use GPG agent if available.\n"
" --gpg-exe Set path to GPG binary.\n"
" --no-save-args Do not save fwknop command line args to the\n"
" $HOME/fwknop.run file\n"
" --rc-file Specify path to the fwknop rc file (default\n"

View File

@ -329,6 +329,19 @@ main(int argc, char **argv)
hmac_key, &hmac_key_len, EXIT_FAILURE);
}
/* Set gpg path if necessary
*/
if(strlen(options.gpg_exe) > 0)
{
res = fko_set_gpg_exe(ctx, options.gpg_exe);
if(res != FKO_SUCCESS)
{
errmsg("fko_set_gpg_exe", res);
clean_exit(ctx, &options, key, &key_len,
hmac_key, &hmac_key_len, EXIT_FAILURE);
}
}
/* If a GPG home dir was specified, set it here. Note: Setting
* this has to occur before calling any of the other GPG-related
* functions.

View File

@ -101,6 +101,7 @@ typedef struct fko_cli_options
char gpg_recipient_key[MAX_GPG_KEY_ID];
char gpg_signer_key[MAX_GPG_KEY_ID];
char gpg_home_dir[MAX_PATH_LEN];
char gpg_exe[MAX_PATH_LEN];
/* Encryption keys read from a .fwknoprc stanza
*/

View File

@ -692,6 +692,9 @@ description and its matching command-line option(s):
*GPG_HOMEDIR* '<dir>'::
Specify the GPG home directory ('--gpg-home-dir'). Defaults to '~/.gnupg'.
*GPG_EXE* '<path>'::
Specify the path to GPG ('--gpg-exe'). Defaults to '/usr/bin/gpg'.
*SPOOF_USER* '<user>'::
Set the username in the SPA data to the specified value ('-U,
--spoof-user').

View File

@ -267,12 +267,15 @@ See the '@sysconfdir@/fwknop/fwknopd.conf'' file for the full list and correspon
*GPG_HOME_DIR* '<path>'::
If GPG keys are used instead of a Rijndael symmetric key, this is
the default GPG keys directory. Note that each access block in
the default GPG keys directory. Note that each access stanza in
'@sysconfdir@/fwknop/access.conf' can specify its own GPG directory to override
this default. If not set here or in an 'access.conf' stanza, then
the '$HOME/.gnupg' directory of the user running *fwknopd* (most
likely root).
GPG_EXE* '<path>'::
Specify the path to GPG, and defaults to '/usr/bin/gpg' if not set.
*LOCALE* '<locale>'::
Set the locale (via the LC_ALL variable). This can be set to override
the default system locale.
@ -458,13 +461,6 @@ directive starts a new stanza.
necessary to also specify an IP address for SNAT rules because the
MASQUERADE target is used instead.
*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 '@sysconfdir@/fwknop/access.conf'
then *fwknopd* will default to using the '/root/.gnupg' directory for the
server key(s) for incoming SPA packets handled by the matching
'access.conf' stanza.
*GPG_DECRYPT_ID* '<keyID>'::
Define a GnuPG key ID to use for decrypting SPA messages that
have been encrypted by an *fwknop* client. This keyword is
@ -515,6 +511,17 @@ directive starts a new stanza.
This setting only applies if the ``GPG_REQUIRE_SIG'' is set to 'Y'.
Separate multiple entries with a comma.
*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 '@sysconfdir@/fwknop/access.conf'
then *fwknopd* will default to using the '/root/.gnupg' directory for the
server key(s) for incoming SPA packets handled by the matching
'access.conf' stanza.
*GPG_EXE* '<path>'::
Define the path to the GnuPG executable. If this keyword is not specified
within '@sysconfdir@/fwknop/access.conf' then *fwknopd* will default to
using '/usr/bin/gpg'.
FILES
-----
@ -532,7 +539,7 @@ binary distributions, and is a dedicated library developed by the fwknop
project.
For packet sniffing, *fwknopd* currently requires libpcap, but future versions
still remove this as a dependency.
will (optionally) remove this as a dependency.
For GPG functionality, GnuPG must also be correctly installed and configured
along with the libgpgme library.

View File

@ -628,7 +628,18 @@ dump_ctx_to_buffer(fko_ctx_t ctx, char *dump_buf, size_t dump_buf_len)
char *enc_data = NULL;
char *hmac_data = NULL;
char *spa_digest = NULL;
char *spa_data = NULL;
#if HAVE_LIBGPGME
char *gpg_signer = NULL;
char *gpg_recip = NULL;
char *gpg_sig_id = NULL;
unsigned char gpg_sig_verify = 0;
unsigned char gpg_ignore_verify = 0;
char *gpg_sig_fpr = NULL;
char *gpg_home_dir = NULL;
char *gpg_exe = NULL;
int gpg_sigsum = -1;
#endif
char *spa_data = NULL;
char digest_str[24] = {0};
char hmac_str[24] = {0};
char enc_mode_str[FKO_ENCRYPTION_MODE_BUFSIZE] = {0};
@ -669,6 +680,26 @@ dump_ctx_to_buffer(fko_ctx_t ctx, char *dump_buf, size_t dump_buf_len)
RETURN_ON_FKO_ERROR(err, fko_get_spa_digest(ctx, &spa_digest));
RETURN_ON_FKO_ERROR(err, fko_get_spa_data(ctx, &spa_data));
#if HAVE_LIBGPGME
if(encryption_mode == FKO_ENC_MODE_ASYMMETRIC)
{
/* Populate GPG variables
*/
RETURN_ON_FKO_ERROR(err, fko_get_gpg_signer(ctx, &gpg_signer));
RETURN_ON_FKO_ERROR(err, fko_get_gpg_recipient(ctx, &gpg_recip));
RETURN_ON_FKO_ERROR(err, fko_get_gpg_signature_verify(ctx, &gpg_sig_verify));
RETURN_ON_FKO_ERROR(err, fko_get_gpg_ignore_verify_error(ctx, &gpg_ignore_verify));
RETURN_ON_FKO_ERROR(err, fko_get_gpg_home_dir(ctx, &gpg_home_dir));
RETURN_ON_FKO_ERROR(err, fko_get_gpg_exe(ctx, &gpg_exe));
if(fko_get_gpg_signature_id(ctx, &gpg_sig_id) != FKO_SUCCESS)
gpg_sig_id = NULL;
if(fko_get_gpg_signature_summary(ctx, &gpg_sigsum) != FKO_SUCCESS)
gpg_sigsum = -1;
if(fko_get_gpg_signature_fpr(ctx, &gpg_sig_fpr) != FKO_SUCCESS)
gpg_sig_fpr = NULL;
}
#endif
/* Convert the digest integer to a string */
if (digest_inttostr(digest_type, digest_str, sizeof(digest_str)) != 0)
return (FKO_ERROR_INVALID_DIGEST_TYPE);
@ -699,6 +730,20 @@ dump_ctx_to_buffer(fko_ctx_t ctx, char *dump_buf, size_t dump_buf_len)
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " HMAC Type: %u (%s)\n", hmac_type, hmac_type == 0 ? "None" : hmac_str);
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "Encryption Type: %d (%s)\n", encryption_type, enc_type_inttostr(encryption_type));
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "Encryption Mode: %d (%s)\n", encryption_mode, enc_mode_str);
#if HAVE_LIBGPGME
if(encryption_mode == FKO_ENC_MODE_ASYMMETRIC)
{
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG signer: %s\n", gpg_signer == NULL ? NULL_STRING : gpg_signer);
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG recipient: %s\n", gpg_recip == NULL ? NULL_STRING : gpg_recip);
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG sig verify: %s\n", gpg_sig_verify == 0 ? "No" : "Yes");
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG ignore sig: %s\n", gpg_ignore_verify == 0 ? "No" : "Yes");
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG sig ID: %s\n", gpg_sig_id == NULL ? NULL_STRING : gpg_sig_id);
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG sig fpr: %s\n", gpg_sig_fpr == NULL ? NULL_STRING : gpg_sig_fpr);
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "GPG sig summary: %d\n", gpg_sigsum);
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG home dir: %s\n", gpg_home_dir == NULL ? NULL_STRING : gpg_home_dir);
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG exe: %s\n", gpg_exe == NULL ? GPG_EXE : gpg_exe);
}
#endif
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Encoded Data: %s\n", enc_data == NULL ? NULL_STRING : enc_data);
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "SPA Data Digest: %s\n", spa_digest == NULL ? NULL_STRING : spa_digest);
cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " HMAC: %s\n", hmac_data == NULL ? NULL_STRING : hmac_data);

View File

@ -741,6 +741,9 @@ free_acc_stanza_data(acc_stanza_t *acc)
if(acc->gpg_home_dir != NULL)
free(acc->gpg_home_dir);
if(acc->gpg_exe != NULL)
free(acc->gpg_exe);
if(acc->gpg_decrypt_id != NULL)
free(acc->gpg_decrypt_id);
@ -875,13 +878,14 @@ acc_stanza_add(fko_srv_options_t *opts)
return(new_acc);
}
/* Scan the access options for entries that have not bees set, but need
/* Scan the access options for entries that have not been set, but need
* a default value.
*/
static void
set_acc_defaults(fko_srv_options_t *opts)
{
acc_stanza_t *acc = opts->acc_stanzas;
int i=1;
if(!acc)
return;
@ -899,6 +903,33 @@ set_acc_defaults(fko_srv_options_t *opts)
{
if(acc->gpg_home_dir == NULL)
add_acc_string(&(acc->gpg_home_dir), opts->config[CONF_GPG_HOME_DIR]);
if(! acc->gpg_require_sig)
{
if (acc->gpg_disable_sig)
{
log_msg(LOG_INFO,
"Warning: GPG_REQUIRE_SIG should really be enabled for stanza source: '%s' (#%d)",
acc->source, i
);
}
else
{
/* Make this the default unless explicitly disabled
*/
acc->gpg_require_sig = 1;
}
}
else
{
if (acc->gpg_disable_sig)
{
log_msg(LOG_INFO,
"Warning: GPG_REQUIRE_SIG and GPG_DISABLE_SIG are both set, will check sigs (stanza source: '%s' #%d)",
acc->source, i
);
}
}
}
if(acc->encryption_mode == FKO_ENC_MODE_UNKNOWN)
@ -915,6 +946,7 @@ set_acc_defaults(fko_srv_options_t *opts)
}
acc = acc->next;
i++;
}
}
@ -1314,6 +1346,10 @@ parse_access_file(fko_srv_options_t *opts)
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
}
else if(CONF_VAR_IS(var, "GPG_EXE"))
{
add_acc_string(&(curr_acc->gpg_exe), val);
}
else if(CONF_VAR_IS(var, "GPG_DECRYPT_ID"))
{
add_acc_string(&(curr_acc->gpg_decrypt_id), val);
@ -1344,6 +1380,10 @@ parse_access_file(fko_srv_options_t *opts)
{
add_acc_bool(&(curr_acc->gpg_require_sig), val);
}
else if(CONF_VAR_IS(var, "GPG_DISABLE_SIG"))
{
add_acc_bool(&(curr_acc->gpg_disable_sig), val);
}
else if(CONF_VAR_IS(var, "GPG_IGNORE_SIG_VERIFY_ERROR"))
{
add_acc_bool(&(curr_acc->gpg_ignore_sig_error), val);
@ -1661,6 +1701,7 @@ dump_access_list(const fko_srv_options_t *opts)
" FORCE_MASQUERADE: %s\n"
" ACCESS_EXPIRE: %s" /* asctime() adds a newline */
" GPG_HOME_DIR: %s\n"
" GPG_EXE: %s\n"
" GPG_DECRYPT_ID: %s\n"
" GPG_DECRYPT_PW: %s\n"
" GPG_REQUIRE_SIG: %s\n"
@ -1689,6 +1730,7 @@ dump_access_list(const fko_srv_options_t *opts)
acc->force_masquerade ? "Yes" : "No",
(acc->access_expire_time > 0) ? asctime(localtime(&acc->access_expire_time)) : "<not set>\n",
(acc->gpg_home_dir == NULL) ? "<not set>" : acc->gpg_home_dir,
(acc->gpg_exe == NULL) ? "<not set>" : acc->gpg_exe,
(acc->gpg_decrypt_id == NULL) ? "<not set>" : acc->gpg_decrypt_id,
(acc->gpg_decrypt_pw == NULL) ? "<not set>" : "<see the access.conf file>",
acc->gpg_require_sig ? "Yes" : "No",

View File

@ -106,6 +106,7 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
"DIGEST_DB_FILE",
#endif
"GPG_HOME_DIR",
"GPG_EXE",
"FIREWALL_EXE",
"VERBOSE"
};
@ -118,6 +119,7 @@ enum {
FW_LIST_ALL,
FW_FLUSH,
GPG_HOME_DIR,
GPG_EXE_PATH,
PCAP_FILE,
ENABLE_PCAP_ANY_DIRECTION,
ROTATE_DIGEST_CACHE,
@ -147,6 +149,7 @@ static struct option cmd_opts[] =
{"fw-list", 0, NULL, FW_LIST },
{"fw-list-all", 0, NULL, FW_LIST_ALL },
{"gpg-home-dir", 1, NULL, GPG_HOME_DIR },
{"gpg-exe", 1, NULL, GPG_EXE_PATH },
{"locale", 1, NULL, 'l' },
{"rotate-digest-cache", 0, NULL, ROTATE_DIGEST_CACHE },
{"override-config", 1, NULL, 'O' },

View File

@ -639,6 +639,11 @@ validate_options(fko_srv_options_t *opts)
if(opts->config[CONF_GPG_HOME_DIR] == NULL)
set_config_entry(opts, CONF_GPG_HOME_DIR, DEF_GPG_HOME_DIR);
/* GPG executable
*/
if(opts->config[CONF_GPG_EXE] == NULL)
set_config_entry(opts, CONF_GPG_EXE, DEF_GPG_EXE);
/* Enable SPA over HTTP.
*/
if(opts->config[CONF_ENABLE_SPA_OVER_HTTP] == NULL)

View File

@ -91,12 +91,17 @@
#MAX_SNIFF_BYTES 1500;
# If GPG keys are used instead of a Rijndael symmetric key, this is
# the default GPG keys directory. Note that each access block in
# the default GPG keys directory. Note that each access stanza in
# fwknop access.conf can specify its own GPG directory to override
# this default.
#
#GPG_HOME_DIR /root/.gnupg;
# Set the default GPG path when GPG is used for SPA encryption and
# authentication.
#
#GPG_EXE /usr/bin/gpg;
# Allow fwknopd to acquire SPA data from HTTP requests (generated with the
# fwknop client in --HTTP mode). Note that the PCAP_FILTER variable would
# need to be updated when this is enabled to sniff traffic over TCP/80

View File

@ -93,6 +93,11 @@
#define DEF_ENABLE_DIGEST_PERSISTENCE "Y"
#define DEF_MAX_SNIFF_BYTES "1500"
#define DEF_GPG_HOME_DIR "/root/.gnupg"
#ifdef GPG_EXE
#define DEF_GPG_EXE GPG_EXE
#else
#define DEF_GPG_EXE "/usr/bin/gpg"
#endif
#define DEF_ENABLE_SPA_OVER_HTTP "N"
#define DEF_ENABLE_TCP_SERVER "N"
#define DEF_TCPSERV_PORT "62201"
@ -250,6 +255,7 @@ enum {
CONF_DIGEST_DB_FILE,
#endif
CONF_GPG_HOME_DIR,
CONF_GPG_EXE,
CONF_FIREWALL_EXE,
CONF_VERBOSE,
@ -310,9 +316,11 @@ typedef struct acc_stanza
char *require_username;
unsigned char require_source_address;
char *gpg_home_dir;
char *gpg_exe;
char *gpg_decrypt_id;
char *gpg_decrypt_pw;
unsigned char gpg_require_sig;
unsigned char gpg_disable_sig;
unsigned char gpg_ignore_sig_error;
unsigned char use_gpg;
unsigned char gpg_allow_no_pw;

View File

@ -462,6 +462,21 @@ incoming_spa(fko_srv_options_t *opts)
/* Set whatever GPG parameters we have.
*/
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)
);
acc = acc->next;
continue;
}
}
if(acc->gpg_home_dir != NULL)
{
res = fko_set_gpg_home_dir(ctx, acc->gpg_home_dir);
@ -469,7 +484,8 @@ incoming_spa(fko_srv_options_t *opts)
{
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)
spadat.pkt_source_ip, stanza_num, acc->gpg_home_dir,
fko_errstr(res)
);
acc = acc->next;
continue;

View File

@ -0,0 +1,4 @@
[default]
HMAC_DIGEST_TYPE sha256
HMAC_KEY_BASE64 Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
GPG_EXE /invalid/gpg/path

View File

@ -0,0 +1,9 @@
SOURCE ANY
FW_ACCESS_TIMEOUT 3
HMAC_DIGEST_TYPE sha256
HMAC_KEY_BASE64 Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
GPG_HOME_DIR conf/server-gpg
GPG_DECRYPT_ID 361BBAD4
GPG_DECRYPT_PW fwknoptest
GPG_REMOTE_ID 6A3FAD56
GPG_EXE /invalid/path/gpg

View File

@ -98,6 +98,7 @@ our %cf = (
'hmac_dual_key_access' => "$conf_dir/hmac_dual_key_usage_access.conf",
'gpg_access' => "$conf_dir/gpg_access.conf",
'gpg_hmac_access' => "$conf_dir/gpg_hmac_access.conf",
'gpg_invalid_exe_access' => "$conf_dir/gpg_invalid_exe_access.conf",
'gpg_hmac_sha512_access' => "$conf_dir/gpg_hmac_sha512_access.conf",
'legacy_iv_access' => "$conf_dir/legacy_iv_access.conf",
'legacy_iv_long_key_access' => "$conf_dir/legacy_iv_long_key_access.conf",
@ -143,6 +144,7 @@ our %cf = (
'rc_gpg_signing_pw' => "$conf_dir/fwknoprc_gpg_signing_pw",
'rc_gpg_named_signing_pw' => "$conf_dir/fwknoprc_named_gpg_signing_pw",
'rc_gpg_hmac_b64_key' => "$conf_dir/fwknoprc_gpg_hmac_key",
'rc_gpg_invalid_gpg_exe' => "$conf_dir/fwknoprc_gpg_invalid_exe",
'rc_gpg_hmac_sha512_b64_key' => "$conf_dir/fwknoprc_gpg_hmac_sha512_key",
'rc_gpg_args_hmac_b64_key' => "$conf_dir/fwknoprc_gpg_args_hmac_key",
'rc_gpg_args_no_pw_hmac_b64_key' => "$conf_dir/fwknoprc_gpg_args_no_pw_hmac_key",
@ -534,6 +536,11 @@ our $default_server_gpg_args_hmac = "$lib_view_str " .
"-a $cf{'gpg_hmac_access'} $intf_str " .
"-d $default_digest_file -p $default_pid_file";
our $invalid_gpg_exe_server_args = "$lib_view_str " .
"$valgrind_str $fwknopdCmd -c $cf{'def'} " .
"-a $cf{'gpg_invalid_exe_access'} $intf_str " .
"-d $default_digest_file -p $default_pid_file";
our $default_server_gpg_args_no_pw_hmac = "$lib_view_str " .
"$valgrind_str $fwknopdCmd -c $cf{'def'} " .
"-a $cf{'gpg_no_pw_hmac_access'} $intf_str " .
@ -628,6 +635,7 @@ my %test_keys = (
'set_legacy_iv' => $OPTIONAL,
'write_rc_file' => $OPTIONAL,
'save_rc_stanza' => $OPTIONAL,
'client_pkt_tries' => $OPTIONAL_NUMERIC,
'disable_valgrind' => $OPTIONAL,
'positive_output_matches' => $OPTIONAL,
'negative_output_matches' => $OPTIONAL,
@ -1673,7 +1681,11 @@ sub client_send_spa_packet() {
last if $server_receive_check == $NO_SERVER_RECEIVE_CHECK;
$tries++;
last if $tries == 10; ### should be plenty of time
if ($test_hr->{'client_pkt_tries'} > 0) {
last if $tries == $test_hr->{'client_pkt_tries'};
} else {
last if $tries == 10;
}
sleep 1;
}
} else {

View File

@ -22,6 +22,53 @@
'fw_rule_removed' => $NEW_RULE_REMOVED,
'key_file' => $cf{'rc_gpg_hmac_b64_key'},
},
{
'category' => 'GPG+HMAC',
'subcategory' => 'client+server',
'detail' => '--gpg-exe invalid path',
'function' => \&generic_exec,
'cmdline' => $default_client_gpg_args
. " --rc-file $cf{'rc_gpg_hmac_b64_key'} --gpg-exe /invalid/bin/gpg",
'positive_output_matches' => [qr/Unable\sto\sstat/i],
'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
'key_file' => $cf{'rc_gpg_hmac_b64_key'},
},
{
'category' => 'GPG+HMAC',
'subcategory' => 'client',
'detail' => '--gpg-exe invalid rc path',
'function' => \&generic_exec,
'cmdline' => $default_client_gpg_args
. " --rc-file $cf{'rc_gpg_invalid_gpg_exe'}",
'positive_output_matches' => [qr/Unable\sto\sstat/i],
'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
'key_file' => $cf{'rc_gpg_invalid_gpg_exe'},
},
{
'category' => 'GPG+HMAC',
'subcategory' => 'client+server',
'detail' => 'complete cycle invalid gpg path',
'function' => \&spa_cycle,
'cmdline' => $default_client_gpg_args
. " --rc-file $cf{'rc_gpg_hmac_b64_key'} --gpg-exe /usr/bin/gpg",
'fwknopd_cmdline' => $invalid_gpg_exe_server_args,
'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
'key_file' => $cf{'rc_gpg_hmac_b64_key'},
'client_pkt_tries' => 1,
},
{
'category' => 'GPG+HMAC',
'subcategory' => 'client+server',
'detail' => 'complete cycle --gpg-exe path',
'function' => \&spa_cycle,
'cmdline' => $default_client_gpg_args
. " --rc-file $cf{'rc_gpg_hmac_b64_key'} --gpg-exe /usr/bin/gpg",
'fwknopd_cmdline' => $default_server_gpg_args_hmac,
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'key_file' => $cf{'rc_gpg_hmac_b64_key'},
},
{
'category' => 'GPG+HMAC',
'subcategory' => 'client+server',