[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:
parent
a52aa8d54a
commit
73bc473563
10
ChangeLog
10
ChangeLog
@ -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
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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'},
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
@ -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').
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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' },
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
4
test/conf/fwknoprc_gpg_invalid_exe
Normal file
4
test/conf/fwknoprc_gpg_invalid_exe
Normal file
@ -0,0 +1,4 @@
|
||||
[default]
|
||||
HMAC_DIGEST_TYPE sha256
|
||||
HMAC_KEY_BASE64 Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
|
||||
GPG_EXE /invalid/gpg/path
|
||||
9
test/conf/gpg_invalid_exe_access.conf
Normal file
9
test/conf/gpg_invalid_exe_access.conf
Normal 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
|
||||
@ -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 {
|
||||
|
||||
@ -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',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user