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