From b7727ac11601d06e63fa67c8975994cfdbb7e62f Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Sat, 20 May 2017 05:19:04 +0000
Subject: [PATCH] Configure FIPS
New parameter: FipsMode yes/no
As soon as FipsMode option parsed FIPS_mode_set(1) will be called.
See Bug #1872327 for details.
---
readconf.c | 38 +++++++++++++++++++++++++++++++++++++-
readconf.h | 1 +
servconf.c | 34 +++++++++++++++++++++++++++++++++-
servconf.h | 1 +
ssh_config | 1 +
ssh_config.0 | 4 ++++
ssh_config.5 | 4 ++++
sshd_config | 2 ++
sshd_config.0 | 4 ++++
sshd_config.5 | 4 ++++
10 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/readconf.c b/readconf.c
index 7f401d6..2c970e2 100644
--- a/readconf.c
+++ b/readconf.c
@@ -171,7 +171,8 @@ typedef enum {
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
oPubkeyAcceptedKeyTypes, oProxyJump,
- oIgnoredUnknownOption, oDeprecated, oUnsupported
+ oIgnoredUnknownOption, oDeprecated, oUnsupported,
+ oFipsMode
} OpCodes;
/* Textual representations of the tokens. */
@@ -291,6 +292,7 @@ static struct {
{ "streamlocalbindunlink", oStreamLocalBindUnlink },
{ "revokedhostkeys", oRevokedHostKeys },
{ "fingerprinthash", oFingerprintHash },
+ { "fipsmode", oFipsMode },
{ "updatehostkeys", oUpdateHostkeys },
{ "hostbasedkeytypes", oHostbasedKeyTypes },
{ "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
@@ -965,6 +967,35 @@ parse_time:
intptr = &options->gss_deleg_creds;
goto parse_flag;
+ case oFipsMode:
+ if (options->ciphers != NULL || options->cipher != -1)
+ fatal("%.200s line %d: FipsMode should be set before "
+ "Ciphers option", filename, linenum);
+ intptr = &options->fips_mode;
+ multistate_ptr = multistate_flag;
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: missing argument.",
+ filename, linenum);
+ value = -1;
+ for (i = 0; multistate_ptr[i].key != NULL; i++) {
+ if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
+ value = multistate_ptr[i].value;
+ break;
+ }
+ }
+ if (value == -1)
+ fatal("%s line %d: unsupported option \"%s\".",
+ filename, linenum, arg);
+ if (*activep && *intptr == -1) {
+ *intptr = value;
+ /* Call FIPS_mode_set as soon as possible */
+ if (*intptr == 1)
+ if (!FIPS_mode_set(1))
+ fatal("FIPS mode could not be set");
+ }
+ break;
+
case oBatchMode:
intptr = &options->batch_mode;
goto parse_flag;
@@ -1857,6 +1888,7 @@ initialize_options(Options * options)
options->update_hostkeys = -1;
options->hostbased_key_types = NULL;
options->pubkey_key_types = NULL;
+ options->fips_mode = -1;
}
/*
@@ -2044,6 +2076,9 @@ fill_default_options(Options * options)
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
if (options->update_hostkeys == -1)
options->update_hostkeys = 0;
+ if (options->fips_mode == -1)
+ options->fips_mode = 0;
+
if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT
: KEX_CLIENT_ENCRYPT), &options->ciphers) != 0 ||
kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC
@@ -2535,6 +2570,7 @@ dump_client_config(Options *o, const char *host)
dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
+ dump_cfg_fmtint(oFipsMode, o->fips_mode);
/* Integer options */
dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
diff --git a/readconf.h b/readconf.h
index cef55f7..875931e 100644
--- a/readconf.h
+++ b/readconf.h
@@ -157,6 +157,7 @@ typedef struct {
char *revoked_host_keys;
int fingerprint_hash;
+ int fips_mode;
int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */
diff --git a/servconf.c b/servconf.c
index 4e5401c..107647a 100644
--- a/servconf.c
+++ b/servconf.c
@@ -164,6 +164,7 @@ initialize_server_options(ServerOptions *options)
options->version_addendum = NULL;
options->fingerprint_hash = -1;
options->disable_forwarding = -1;
+ options->fips_mode = -1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@@ -336,6 +337,8 @@ fill_default_server_options(ServerOptions *options)
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
if (options->disable_forwarding == -1)
options->disable_forwarding = 0;
+ if (options->fips_mode == -1)
+ options->fips_mode = 0;
assemble_algorithms(options);
@@ -421,7 +424,8 @@ typedef enum {
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
- sDeprecated, sIgnore, sUnsupported
+ sDeprecated, sIgnore, sUnsupported,
+ sFipsMode
} ServerOpCodes;
#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
@@ -564,6 +568,7 @@ static struct {
{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
+ { "fipsmode", sFipsMode, SSHCFG_GLOBAL },
{ NULL, sBadOption, 0 }
};
@@ -1839,6 +1844,32 @@ process_server_config_line(ServerOptions *options, char *line,
options->fingerprint_hash = value;
break;
+ case sFipsMode:
+ if (options->ciphers != NULL)
+ fatal("%.200s line %d: FipsMode should be set before "
+ "Ciphers option", filename, linenum);
+ intptr = &options->fips_mode;
+ arg = strdelim(&cp);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: missing yes/no argument.",
+ filename, linenum);
+ value = 0; /* silence compiler */
+ if (strcmp(arg, "yes") == 0)
+ value = 1;
+ else if (strcmp(arg, "no") == 0)
+ value = 0;
+ else
+ fatal("%s line %d: Bad yes/no argument: %s",
+ filename, linenum, arg);
+ if (*activep && *intptr == -1) {
+ *intptr = value;
+ /* Call FIPS_mode_set as soon as possible */
+ if (*intptr == 1)
+ if (!FIPS_mode_set(1))
+ fatal("FIPS mode could not be set");
+ }
+ break;
+
case sDeprecated:
case sIgnore:
case sUnsupported:
@@ -2280,6 +2311,7 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
+ dump_cfg_fmtint(sFipsMode, o->fips_mode);
/* string arguments */
dump_cfg_string(sPidFile, o->pid_file);
diff --git a/servconf.h b/servconf.h
index 5853a97..a9ec1a2 100644
--- a/servconf.h
+++ b/servconf.h
@@ -189,6 +189,7 @@ typedef struct {
char *auth_methods[MAX_AUTH_METHODS];
int fingerprint_hash;
+ int fips_mode;
} ServerOptions;
/* Information about the incoming connection as used by Match */
diff --git a/ssh_config b/ssh_config
index 90fb63f..fd6ab39 100644
--- a/ssh_config
+++ b/ssh_config
@@ -37,6 +37,7 @@
# IdentityFile ~/.ssh/id_ecdsa
# IdentityFile ~/.ssh/id_ed25519
# Port 22
+# FipsMode no
# Protocol 2
# Cipher 3des
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
diff --git a/ssh_config.0 b/ssh_config.0
index 4ca9a5f..33ac338 100644
--- a/ssh_config.0
+++ b/ssh_config.0
@@ -362,6 +362,10 @@ DESCRIPTION
Specifies the hash algorithm used when displaying key
fingerprints. Valid options are: md5 and sha256 (the default).
+ FipsMode
+ Enables or disables FIPS mode. Requires FIPS capable ssl modules.
+ The default is no.
+
ForwardAgent
Specifies whether the connection to the authentication agent (if
any) will be forwarded to the remote machine. The argument must
diff --git a/ssh_config.5 b/ssh_config.5
index 591365f..df46e0d 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -658,6 +658,10 @@ Valid options are:
and
.Cm sha256
(the default).
+.It Cm FipsMode
+Enables or disables FIPS mode. Requires FIPS capable ssl modules.
+The default is
+.Cm no .
.It Cm ForwardAgent
Specifies whether the connection to the authentication agent (if any)
will be forwarded to the remote machine.
diff --git a/sshd_config b/sshd_config
index 9f09e4a..1a0d68a 100644
--- a/sshd_config
+++ b/sshd_config
@@ -105,6 +105,8 @@ AuthorizedKeysFile .ssh/authorized_keys
#ChrootDirectory none
#VersionAddendum none
+#FipsMode no
+
# no default banner path
#Banner none
diff --git a/sshd_config.0 b/sshd_config.0
index 022c052..af813b2 100644
--- a/sshd_config.0
+++ b/sshd_config.0
@@ -331,6 +331,10 @@ DESCRIPTION
Specifies the hash algorithm used when logging key fingerprints.
Valid options are: md5 and sha256. The default is sha256.
+ FipsMode
+ Enables or disables FIPS mode. Requires FIPS capable ssl modules.
+ The default is no.
+
ForceCommand
Forces the execution of the command specified by ForceCommand,
ignoring any command supplied by the client and ~/.ssh/rc if
diff --git a/sshd_config.5 b/sshd_config.5
index 32b29d2..c618359 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -578,6 +578,10 @@ and
.Cm sha256 .
The default is
.Cm sha256 .
+.It Cm FipsMode
+Enables or disables FIPS mode. Requires FIPS capable ssl modules.
+The default is
+.Cm no .
.It Cm ForceCommand
Forces the execution of the command specified by
.Cm ForceCommand ,
--
2.8.1