changeset 385:d9009f54eb23

Migrate to a fully-fledged SSH module This handles lots of the server path differences for us
author IBBoard <dev@ibboard.co.uk>
date Mon, 03 Jan 2022 17:05:54 +0000
parents 22e45bb5ea97
children 3fce34f642f1
files manifests/templates.pp modules/ssh/CHANGELOG.md modules/ssh/Gemfile modules/ssh/LICENSE modules/ssh/README.md modules/ssh/Rakefile modules/ssh/checksums.json modules/ssh/lib/facter/ssh.rb modules/ssh/manifests/config_entry.pp modules/ssh/manifests/init.pp modules/ssh/metadata.json modules/ssh/spec/classes/init_spec.rb modules/ssh/spec/defines/config_entry_spec.rb modules/ssh/spec/fixtures/hiera/hiera.yaml modules/ssh/spec/fixtures/hiera/hieradata/fqdn/hieramerge.example.com.yaml modules/ssh/spec/fixtures/hiera/hieradata/specific/test_hiera_merge.yaml modules/ssh/spec/fixtures/ssh_config_debian modules/ssh/spec/fixtures/ssh_config_debian10 modules/ssh/spec/fixtures/ssh_config_debian8 modules/ssh/spec/fixtures/ssh_config_debian9 modules/ssh/spec/fixtures/ssh_config_rhel modules/ssh/spec/fixtures/ssh_config_rhel_old modules/ssh/spec/fixtures/ssh_config_solaris modules/ssh/spec/fixtures/ssh_config_suse modules/ssh/spec/fixtures/ssh_config_suse_old modules/ssh/spec/fixtures/ssh_config_ubuntu1604 modules/ssh/spec/fixtures/ssh_config_ubuntu1804 modules/ssh/spec/fixtures/ssh_config_ubuntu2004 modules/ssh/spec/fixtures/sshd_config_debian modules/ssh/spec/fixtures/sshd_config_debian10 modules/ssh/spec/fixtures/sshd_config_debian8 modules/ssh/spec/fixtures/sshd_config_debian9 modules/ssh/spec/fixtures/sshd_config_rhel modules/ssh/spec/fixtures/sshd_config_rhel7 modules/ssh/spec/fixtures/sshd_config_sles_12_x86_64 modules/ssh/spec/fixtures/sshd_config_solaris modules/ssh/spec/fixtures/sshd_config_suse_i386 modules/ssh/spec/fixtures/sshd_config_suse_x86_64 modules/ssh/spec/fixtures/sshd_config_ubuntu1604 modules/ssh/spec/fixtures/sshd_config_ubuntu1804 modules/ssh/spec/fixtures/sshd_config_ubuntu2004 modules/ssh/spec/spec_helper.rb modules/ssh/spec/unit/facter/ssh_spec.rb modules/ssh/templates/ssh_config.erb modules/ssh/templates/sshd_config.erb modules/ssh/tests/init.pp
diffstat 46 files changed, 8535 insertions(+), 121 deletions(-) [+]
line wrap: on
line diff
--- a/manifests/templates.pp	Sun Dec 19 20:10:16 2021 +0000
+++ b/manifests/templates.pp	Mon Jan 03 17:05:54 2022 +0000
@@ -76,7 +76,7 @@
 	include basenode
 	include privat
 	include dnsresolver
-	include ssh::server
+	include ::ssh
 	include vcs::server
 	include vcs::client
 	class { 'webserver':
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/CHANGELOG.md	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,117 @@
+### v3.62.0 - 2020-09-07
+  * Support Ubuntu 20.04 LTS
+
+### v3.61.0 - 2019-05-01
+  * Support Debian 8
+  * Support Ubuntu 18.04 LTS
+
+### v3.60.1 - 2019-04-29
+  * Fix screwed up metadata
+
+### v3.60.0 - 2019-04-29
+  * Support Debian 9
+  * Add ability for IPv6 addresses to be exported as part of the sshkey
+      for the FQDN.
+
+### v3.59.1 - 2019-02-28
+  * Put Match block at end of sshd_config
+
+### v3.59.0 - 2018-01-03
+  * Support Puppet 6
+
+### v3.58.0 - 2018-10-08
+  * Add RevokedKeys option to `sshd_config`
+
+### v3.57.1 - 2018-07-27
+  * Disable ServerkeyBits on RHEL 7.4 and later
+
+### v3.57.0 - 2017-12-10
+  * Add support for AuthenticationMethods and AllowAgentForwarding
+    options in sshd_config
+
+### v3.56.1 - 2017-11-20
+  * Fix regex bug with `sshd_config_maxstartups`
+
+### v3.56.0 - 2017-10-27
+  * Support puppetlabs/concat v3 and v4
+
+### v3.55.0 - 2017-09-26
+  * Add `ssh::config_entry` defined type to manage `~/.ssh/config`
+  * Add `config_entries` parameter to ssh class to allow specifying a
+    hash of multiple entries for `ssh::config_entry`.
+
+### v3.54.0 - 2017-07-24
+  * Allow sshd_config_hostcertificate to be an array. This fixes a bug
+    where you could have specified one cert and multiple HostKey's since
+    `sshd_config_hostkey` allows an array.
+  * Add parameter `sshd_config_authorized_principals_file` to manage the
+    `AuthorizedPrincipalsFile` setting in `sshd_config`.
+
+### v3.53.0 - 2017-07-24
+  * Support only latest Puppet v3
+  * Support only last few releases on Puppet v4
+  * Add support for Puppet v5
+
+### v3.52.0 - 2017-05-26
+  * Add params for Add PrintLastLog, UsePrivilegeSeparation, and
+    Compression options in sshd_config.
+
+### v3.51.1 - 2017-05-19
+  * Ensure that ssh_known_hosts requires the ssh packages
+
+### v3.51.0 - 2017-05-17
+  * Add params sshd_config_hostcertificate and
+    sshd_config_trustedusercakeys to set HostCertificate and TrustedUserCAKeys.
+
+### v3.50.0 - 2017-05-08
+  * Add param sshd_pubkeyacceptedkeytypes to set PubkeyAcceptedKeyTypes
+
+### v3.49.1 - 2017-02-27
+  * Fix parameters not compatible with Solaris
+  * Add support for Puppet v4.9
+
+### v3.49.0 - 2016-10-25
+  * Add support for PermitTunnel in sshd_config
+
+### v3.48.0 - 2016-10-20
+  * Add support for ProxyCommand
+
+### v3.47.0 - 2016-10-19
+  * Add support for KexAlgorithms
+
+### v3.46.0 - 2016-10-04
+  * Add sshd_x11_use_localhost parameter
+
+### v3.45.0 - 2016-08-30
+  * Add support for Ubuntu 16.04 LTS
+
+### v3.44.0 - 2016-08-28
+  * Add support for TCPKeepAlive in sshd_config
+
+### v3.43.0 - 2016-08-08
+  * Add support for Ruby 2.3.1 with Puppet v4
+
+### v3.42.0 - 2016-06-24
+  * Add support for managing sshd_config options PermitUserEnvironment and
+    PermitEmptyPasswords
+
+### v3.41.1 - 2016-06-20
+  * Update years in LICENSE
+
+### v3.41.0 - 2016-06-20
+  * Add ability to specify an array for GlobalKnownHostsFile in ssh_config.
+  * Add support for UserKnownHostsFile in ssh_config.
+
+### v3.40.0 - 2016-06-09
+  * Add ability to specify multiple ports
+
+### v3.39.0 - 2016-06-08
+  * Allow ecdsa-sha2-nistp256 hostkeys
+  * Add host_aliases attribute to sshkey resource
+  * Add support for PubkeyAuthentication in sshd_config
+
+### v3.38.0 - 2016-06-06
+  * Add param to manage MaxAuthTries in sshd_config
+
+### v2.0.0 - 2013-05-16 Garrett Honeycutt <code@garretthoneycutt.com>
+  * Rebirth
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/Gemfile	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,38 @@
+source ENV['GEM_SOURCE'] || 'https://rubygems.org'
+
+if puppetversion = ENV['PUPPET_GEM_VERSION']
+  gem 'puppet', puppetversion, :require => false
+else
+  gem 'puppet', :require => false
+end
+
+gem 'facter', '>= 1.7.0', :require => false
+gem 'rspec-puppet', '>= 2.4.0', :require => false
+gem 'puppet-lint', '~> 2.0', :require => false
+gem 'puppet-lint-absolute_classname-check', :require => false
+gem 'puppet-lint-alias-check', :require => false
+gem 'puppet-lint-empty_string-check', :require => false
+gem 'puppet-lint-file_ensure-check', :require => false
+gem 'puppet-lint-file_source_rights-check', :require => false
+gem 'puppet-lint-leading_zero-check', :require => false
+gem 'puppet-lint-spaceship_operator_without_tag-check', :require => false
+gem 'puppet-lint-trailing_comma-check', :require => false
+gem 'puppet-lint-undef_in_function-check', :require => false
+gem 'puppet-lint-unquoted_string-check', :require => false
+gem 'puppet-lint-variable_contains_upcase', :require => false
+
+gem 'rspec',     '~> 2.0', :require => false          if RUBY_VERSION >= '1.8.7' && RUBY_VERSION < '1.9'
+gem 'rake',      '~> 10.0', :require => false         if RUBY_VERSION >= '1.8.7' && RUBY_VERSION < '1.9'
+gem 'json',      '<= 1.8', :require => false          if RUBY_VERSION < '2.0.0'
+gem 'json_pure', '<= 2.0.1', :require => false        if RUBY_VERSION < '2.0.0'
+gem 'metadata-json-lint',     '0.0.11'   if RUBY_VERSION >= '1.8.7' && RUBY_VERSION < '1.9'
+gem 'metadata-json-lint',     '1.0.0'    if RUBY_VERSION >= '1.9' && RUBY_VERSION < '2.0'
+gem 'metadata-json-lint' if RUBY_VERSION >= '2.0'
+
+gem 'puppetlabs_spec_helper', '2.0.2',    :require => false if RUBY_VERSION >= '1.8.7' && RUBY_VERSION < '1.9'
+gem 'puppetlabs_spec_helper', '>= 2.0.0', :require => false if RUBY_VERSION >= '1.9'
+gem 'parallel_tests',         '<= 2.9.0', :require => false if RUBY_VERSION < '2.0.0'
+
+if puppetversion && puppetversion < '5.0'
+  gem 'semantic_puppet', :require => false
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/LICENSE	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,13 @@
+Copyright (C) 2010-2020 Garrett Honeycutt <code@garretthoneycutt.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/README.md	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,928 @@
+# puppet-module-ssh
+
+Manage ssh client and server.
+
+The module uses exported resources to manage ssh keys and removes ssh keys that
+are not managed by puppet. This behavior is managed by the parameters
+ssh_key_ensure and purge_keys.
+
+This module may be used with a simple `include ::ssh`
+
+The `ssh::config_entry` defined type may be used directly and is used to manage
+Host entries in a personal `~/.ssh/config` file.
+
+===
+
+### Table of Contents
+1. [Compatibility](#compatibility)
+1. [Parameters](#parameters)
+1. [Examples](#sample-usage)
+
+===
+
+# Compatibility
+
+This module has been tested to work on the following systems with the
+latest Puppet v3, v3 with future parser, v4, v5 and v6.  See `.travis.yml`
+for the exact matrix of supported Puppet and ruby versions.
+
+ * Debian 7
+ * Debian 8
+ * Debian 9
+ * Debian 10
+ * EL 5
+ * EL 6
+ * EL 7
+ * SLES 10
+ * SLES 11
+ * SLES 12
+ * Ubuntu 12.04 LTS
+ * Ubuntu 14.04 LTS
+ * Ubuntu 16.04 LTS
+ * Ubuntu 18.04 LTS
+ * Ubuntu 20.04 LTS
+ * Solaris 9
+ * Solaris 10
+ * Solaris 11
+
+If you use the Sun Solaris SSH, please keep in mind that not all parameters can be used.
+
+Unsupported parameters for ssh_config:
+AddressFamily, Tunnel, TunnelDevice, PermitLocalCommand, HashKnownHosts
+
+Unsupported parameters for sshd_config:
+KerberosOrLocalPasswd, KerberosTicketCleanup, KerberosGetAFSToken, TCPKeepAlive, ShowPatchLevel, MaxSessions, PermitTunnel
+
+===
+
+# Parameters
+A value of `'USE_DEFAULTS'` will use the defaults specified by the module.
+
+
+hiera_merge
+-----------
+Boolean to merges all found instances of ssh::keys and ssh::config_entries in Hiera.
+This is useful for specifying SSH keys at different levels of the hierarchy and having
+them all included in the catalog.
+
+This will default to 'true' in future versions.
+
+- *Default*: false
+
+ssh_config_hash_known_hosts
+---------------------------
+HashKnownHosts in ssh_config.
+Indicates that ssh should hash host names and addresses when they are added to ~/.ssh/known_hosts.
+These hashed names may be used normally by ssh and sshd, but they do not reveal identifying
+information should the file's contents be disclosed. The default is 'no' on Linux.
+
+Note that existing names and addresses in known hosts files will not be converted automatically,
+but may be manually hashed using ssh-keygen. Use of this option may break facilities such as
+tab-completion that rely on being able to read unhashed host names from ~/.ssh/known_hosts.
+
+A value of 'unset' will not add this parameter to the configuration file.
+
+- *Default*: 'USE_DEFAULTS'
+
+ssh_config_path
+---------------
+Path to ssh_config.
+
+- *Default*: '/etc/ssh/ssh_config'
+
+ssh_config_owner
+----------------
+ssh_config's owner.
+
+- *Default*: 'root'
+
+ssh_config_group
+----------------
+ssh_config's group.
+
+- *Default*: 'root'
+
+ssh_config_mode
+---------------
+ssh_config's mode.
+
+- *Default*: '0644'
+
+ssh_config_forward_x11
+----------------------
+ForwardX11 option in ssh_config. Not set by default.
+
+- *Default*: undef
+
+ssh_config_forward_agent
+------------------------
+ForwardAgent option in ssh_config. Not set by default.
+
+- *Default*: undef
+
+ssh_config_server_alive_interval
+--------------------------------
+ServerAliveInterval option in ssh_config. Not set by default.
+
+- *Default*: undef
+
+ssh_config_sendenv_xmodifiers
+-----------------------
+Boolean to set 'SendEnv XMODIFIERS' in ssh_config. This option is only valid on Linux.
+
+- *Default*: false
+
+ssh_config_template
+--------------------
+*string* The template used to generate ssh_config.
+
+- *Default*: 'ssh/ssh_config.erb'
+
+ssh_config_ciphers
+------------------
+Array of ciphers to be used with the Ciphers option in ssh_config.
+
+- *Default*: undef
+
+ssh_config_kexalgorithms
+------------------
+Array of key exchange algorithms to be used with the KexAlgorithms option in ssh_config.
+
+- *Default*: undef
+
+ssh_config_macs
+---------------
+Array of ciphers to be used with the MACs option in ssh_config.
+
+- *Default*: undef
+
+ssh_sendenv
+-------------
+Boolean to enable SendEnv options for specifying environment variables. Default is set to true on Linux.
+
+- *Default*: 'USE_DEFAULTS'
+
+ssh_gssapiauthentication
+-------------------------
+GSSAPIAuthentication: Enables/disables GSS-API user authentication in ssh_config. Valid values are 'yes' and 'no'.
+
+- *Default*: 'yes'
+
+ssh_gssapidelegatecredentials
+-----------------------------
+*string* For GSSAPIDelegateCredentials setting in ssh_config. Valid values are
+'yes' and 'no' or to leave undef which will ensure the setting is not present
+in ssh_config.
+
+- *Default*: undef
+
+ssh_hostbasedauthentication
+-------------------------
+String for HostbasedAuthentication option in ssh_config. Valid values are 'yes' and 'no'.
+
+- *Default*: undef
+
+ssh_config_proxy_command
+-------------------------
+String for ProxyCommand option in ssh_config.
+
+- *Default*: undef
+
+ssh_strict_host_key_checking
+-----------------------------
+*string* For StrictHostKeyChecking setting in ssh_config. Valid values are
+'yes', 'no' or 'ask'.
+
+- *Default*: undef
+
+ssh_enable_ssh_keysign
+-----------------------------
+*string* For EnableSSHKeysign setting in ssh_config. Valid values are
+'yes' and 'no' or to leave undef which will ensure the setting is not present
+in ssh_config.
+
+- *Default*: undef
+
+sshd_addressfamily
+----------------
+Specifies the value of the AddressFamily setting in sshd_config. Valid values are 'any', 'inet' (IPv4 only), 'inet6' (IPv6 only) and undef. A value of undef will ensure that AddressFamily is not in the configuration.
+
+- *Default*: 'any'
+
+sshd_config_path
+----------------
+Path to sshd_config.
+
+- *Default*: '/etc/ssh/sshd_config
+
+sshd_config_owner
+-----------------
+sshd_config's owner.
+
+- *Default*: 'root'
+
+sshd_config_group
+----------------
+sshd_config's group.
+
+- *Default*: 'root'
+
+sshd_config_loglevel
+---------------------------
+LogLevel option in sshd_config. Acceptable values are QUIET, FATAL, ERROR, INFO, VERBOSE.
+
+*DEBUG, DEBUG1, DEBUG2, and DEBUG3* are permitted values for sshd, however [setting the logging level to DEBUG or higher violates the privacy of users](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/sshd_config.5?query=sshd_config) and should not be done unless manually debugging.
+
+- *Default*: 'INFO'
+
+sshd_config_maxauthtries
+---------------
+MaxAuthTries option in sshd_config.  Specifies the maximum number of authentication attempts permitted per connection.  Once the number of failures reaches half this value, additional failures are logged.
+
+- *Default*: '6'
+
+sshd_config_mode
+---------------
+sshd_config's mode. The default is '0600' on Linux and '0644' on Solaris.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_listen_address
+-------------------
+String or Array to specify address(es) for which sshd will bind. Corresponds to ListenAddress in sshd_config.
+
+- *Default*: undef
+
+sshd_config_permitemptypasswords
+--------------------------------
+PermitEmptyPasswords option in sshd_config.  When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings.
+Valid values are 'yes' and 'no'.
+
+- *Default*: undef
+
+sshd_config_permituserenvironment
+---------------------------------
+PermitUserEnvironment option in sshd_config.  Specifies whether ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by sshd(8).  The default is “no”.  Enabling environment processing may enable users to bypass access restrictions in some configurations using mechanisms such as LD_PRELOAD.
+Valid values are 'yes' and 'no'.
+
+
+- *Default*: undef
+
+sshd_config_compression
+---------------------------------
+Compression option in sshd_config.
+Specifies whether compression is allowed in an SSH connection prior to authentication.
+If specified, valid values are 'yes', 'no' and 'delayed'.
+
+
+- *Default*: undef
+
+sshd_config_port
+---------------------------
+String, Integer or Array to specify listen port[s] for sshd. Port option in sshd_config.
+
+- *Default*: '22'
+
+sshd_config_syslog_facility
+---------------------------
+SyslogFacility option in sshd_config.
+
+- *Default*: 'AUTH'
+
+sshd_config_template
+--------------------
+*string* The template used to generate sshd_config.
+
+- *Default*: 'ssh/sshd_config.erb'
+
+sshd_config_login_grace_time
+----------------------------
+LoginGraceTime option in sshd_config.
+
+- *Default*: '120'
+
+sshd_config_challenge_resp_auth
+-------------------------------
+ChallengeResponseAuthentication option in sshd_config. RedHat defaults
+to setting this to no for EL 5, 6 and 7, though the module will set it
+to 'yes'. Suggest setting to 'no' with Hiera on EL systems. This will
+default to 'no' for those platforms in the next major release.
+
+- *Default*: 'yes'
+
+sshd_config_print_motd
+----------------------
+PrintMotd option in sshd_config.
+
+- *Default*: 'yes'
+
+sshd_config_print_last_log
+----------------------
+PrintLastLog option in sshd_config.
+Verify SSH provides users with feedback on when account accesses last occurred.
+If specified, valid values are 'yes' and 'no'.
+
+- *Default*: undef
+
+sshd_config_use_dns
+-------------------
+UseDNS option in sshd_config. The default is 'yes' on Linux.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_config_authkey_location
+----------------------------
+Specify location of authorized_keys file. Default is to not specify.
+
+- *Default*: undef
+
+sshd_config_hostkey
+----------------------------
+Specify an array of server side HostKey files to use. Default is to use only /etc/ssh/ssh_host_rsa_key
+
+- *Default*: /etc/ssh/ssh_host_rsa_key
+
+sshd_config_strictmodes
+----------------------------
+Specifies whether sshd should check file modes and ownership of the user's files and home directory before accepting login. Valid values are yes and no.
+
+- *Default*: undef
+
+sshd_config_serverkeybits
+----------------------------
+Defines the number of bits in the ephemeral protocol version 1 server key.  The minimum value is 512, and the default is 1024 except for Solaris default value is 768.
+
+- *Default*: '1024' except for Solaris which is '768'
+
+sshd_config_banner
+------------------
+Banner option in sshd_config.
+
+- *Default*: 'none'
+
+sshd_banner_content
+-------------------
+content parameter for file specified in sshd_config_banner
+
+- *Default*: undef
+
+sshd_banner_owner
+-----------------
+owner parameter for file specified in sshd_config_banner
+
+- *Default*: 'root'
+
+sshd_banner_group
+-----------------
+group parameter for file specified in sshd_config_banner
+
+- *Default*: 'root'
+
+sshd_banner_mode
+----------------
+mode parameter for file specified in sshd_config_banner
+
+- *Default*: '0644'
+
+sshd_config_xauth_location
+--------------------------
+XAuthLocation option in sshd_config.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_config_subsystem_sftp
+--------------------------
+Path to sftp file transfer subsystem in sshd_config.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_password_authentication
+-----------------------------
+PasswordAuthentication in sshd_config. Specifies whether password authentication is allowed.
+
+- *Default*: 'yes'
+
+sshd_allow_tcp_forwarding
+-------------------------
+AllowTcpForwarding in sshd_config. Specifies whether TCP forwarding is permitted.
+
+- *Default*: 'yes'
+
+sshd_authorized_keys_command
+----------------------------
+Fully qualified path to command for AuthorizedKeysCommand in sshd_config.
+
+- *Default*: undef
+
+sshd_authorized_keys_command_user
+---------------------------------
+String of user for AuthorizedKeysCommandUser in sshd_config.
+
+- *Default*: undef
+
+sshd_x11_forwarding
+-------------------
+X11Forwarding in sshd_config. Specifies whether X11 forwarding is permitted.
+
+- *Default*: 'yes'
+
+sshd_x11_use_localhost
+----------------------
+X11UseLocalhost in sshd_config. Specifies if sshd should bind the X11 forwarding server
+to the loopback address or to the wildcard address.
+
+- *Default*: 'yes'
+
+sshd_use_pam
+------------
+UsePam in sshd_config.
+Enables the Pluggable Authentication Module interface. If set to 'yes' this will enable PAM
+authentication using ChallengeResponseAuthentication and PasswordAuthentication in addition
+to PAM account and session module processing for all authentication types.
+This module sets this option to 'yes' on Linux and undef on Solaris.
+
+- *Default*: 'USE_DEFAULTS'
+
+ssh_config_use_roaming
+----------------------
+String to enable or disable UseRoaming in client configuration ssh_config.
+Valid values are 'yes', 'no' and 'unset'. Using 'unset' will not use (print)
+this configuration parameter at all. Default is set to 'no' on Linux and
+'unset' on Solaris. If you have OpenSSH >= version 5.4, this should be set to
+'no' to mitigate CVE-2016-0777 and CVE-2016-0778.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_client_alive_interval
+--------------------------
+ClientAliveInterval in sshd_config.
+Sets a timeout interval in seconds after which if no data has been received from the client,
+sshd(8) will send a message through the encrypted channel to request a response from the
+client. The default is 0, indicating that these messages will not be sent to the client.
+This option applies to protocol version 2 only.
+
+- *Default*: '0'
+
+sshd_client_alive_count_max
+--------------------------
+ClientAliveCountMax in sshd_config.
+Sets the number of client alive messages (see below) which may be sent without sshd(8)
+receiving any messages back from the client. If this threshold is reached while client alive
+messages are being sent, sshd will disconnect the client, terminating the session.  It is
+important to note that the use of client alive messages is very different from TCPKeepAlive
+(below).  The client alive messages are sent through the encrypted channel and therefore will
+not be spoofable.  The TCP keepalive option enabled by TCPKeepAlive is spoofable.  The client
+alive mechanism is valuable when the client or server depend on knowing when a connection has
+become inactive. The default value is 3.  If ClientAliveInterval (see below) is set to 15,
+and ClientAliveCountMax is left at the default, unresponsive SSH clients will be disconnected
+after approximately 45 seconds.  This option applies to protocol version 2 only.
+
+- *Default*: '3'
+
+sshd_config_tcp_keepalive
+------------------------
+TCPKeepAlive in sshd_config.
+Specifies  whether the system should send TCP keepalive messages to the other side.  If they
+are sent, death of the connection or crash of one of the machines will be properly noticed.
+However, this means that connections will die if the route is down temporarily, and some
+people find it annoying.  On the other hand, if TCP keepalives are not sent, sessions may
+hang indefinitely on the server, leaving ``ghost'' users and consuming server resources.
+A value of 'unset' will not add this parameter to the configuration file.
+
+On Linux the default is set to ``yes'' (to send TCP keepalive messages), and the server will
+notice if the network goes down or the client host crashes.  This avoids infinitely hanging
+sessions.
+On Solaris the default is to not add this parameter to the configuration file.
+
+- *Default*: undef
+
+sshd_config_use_privilege_separation
+----------------------
+UsePrivilegeSeparation in sshd_config.
+Causes the SSH process to drop root privileges when not needed.
+If specified, valid values are 'yes', 'no' and 'sandbox'.
+
+- *Default*: undef
+
+sshd_config_permittunnel
+-----------------------
+PermitTunnel in sshd_config.
+Specifies whether tun(4) device forwarding is allowed.  The argument must be 'yes',
+'point-to-point' (layer 3), 'ethernet' (layer 2), 'no', or 'unset' (parameter not used).
+Specifying 'yes' permits both 'point-to-point' and 'ethernet'.
+Independent of this setting, the permissions of the selected tun(4) device must
+allow access to the user.
+A value of 'unset' will not add this parameter to the configuration file.
+
+On Linux the default is set to ``no''.
+On Solaris the default is to not add this parameter to the configuration file.
+
+- *Default*: undef
+
+sshd_config_ciphers
+-------------------
+Array of ciphers for the Ciphers setting in sshd_config.
+
+- *Default*: undef
+
+sshd_config_kexalgorithms
+-------------------
+Array of key exchange algorithms for the KexAlgorithms setting in sshd_config.
+
+- *Default*: undef
+
+sshd_config_macs
+----------------
+Array of macs for the MACs setting in sshd_config.
+
+- *Default*: undef
+
+sshd_config_denyusers
+---------------------
+Array of users for the DenyUsers setting in sshd_config.
+
+- *Default*: undef
+
+sshd_config_denygroups
+---------------------
+Array of groups for the DenyGroups setting in sshd_config.
+
+- *Default*: undef
+
+sshd_config_allowgroups
+-----------------------
+Array of users for the AllowGroups setting in sshd_config.
+
+- *Default*: undef
+
+sshd_config_allowusers
+-----------------------
+Array of users for the AllowUsers setting in sshd_config.
+
+- *Default*: undef
+
+sshd_config_maxstartups (string)
+-----------------------
+Specifies the maximum number of concurrent unauthenticated connections
+to the SSH daemon. Must be a stringified integer or a string with three
+integers separated by colons, such as '10:30:100'.
+
+- *Default*: undef
+
+sshd_config_maxsessions
+-----------------------
+Specifies the maximum number of open sessions permitted per network connection.
+A value of 'unset' or undef will not add this parameter to the configuration file.
+
+- *Default*: undef
+
+sshd_config_chrootdirectory
+---------------------------
+String with absolute path for the ChrootDirectory directive for the SSH daemon.
+
+- *Default*: undef
+
+sshd_config_forcecommand
+---------------------------
+String with command for the ForceCommand directive for the SSH daemon.
+
+- *Default*: undef
+
+sshd_config_match
+-----------------
+Hash for matches with nested arrays for options for the Match directive for the SSH daemon.
+Match directive is supported on SSH >= 5.x.
+
+- *Default*: undef
+
+- *Hiera example*:
+
+``` yaml
+ssh::sshd_config_match:
+  'User JohnDoe':
+    - 'AllowTcpForwarding yes'
+  'Address 2.4.2.0':
+    - 'X11Forwarding yes'
+    - 'PasswordAuthentication no'
+```
+
+sshd_config_hostcertificate
+---------------------------
+An Absolute Path or Array of Absolute Paths to the Host CA Public Key. Each entry *MUST* be tied 1:1 to a Host CA Private Key (see [sshd_config_hostkey](#sshd_config_hostkey))
+
+- *Default*: undefined
+
+sshd_config_trustedusercakeys
+-----------------------------
+Absolute path to the OpenSSH User CA Certificate (TrustedUserCAKeys) for use with SSH CA Validation for Users or the string 'none'.
+
+- *Default*: undefined
+
+sshd_config_key_revocation_list
+-----------------------------
+Absolute path to a key revocation list (RevokedKeys) for use with SSH CA Validation for Users or the string 'none'.
+
+- *Default*: undefined
+
+sshd_config_authorized_principals_file
+--------------------------------------
+String path (relative or absolute) to the `authorized_principals` file. Sets the `AuthorizedPrincipalsFile` setting in `sshd_config`
+
+See `sshd_config(5)` for more details
+
+- *Default*: undefined
+
+sshd_config_allowagentforwarding
+--------------------------------
+AllowAgentForwarding option in sshd_config. Specifies if ssh-agent(1)
+forwarding is permitted. Valid values are 'yes' and 'no'.
+
+- *Default*: undef
+
+config_entries
+--------------
+Hash of config entries for a specific user's ~/.ssh/config. Please check the docs for ssd::config_entry for a list and details of the parameters usable here.
+Setting hiera_merge to true will activate merging entries through all levels of hiera.
+
+- *Hiera example*:
+
+``` yaml
+ssh::config_entries:
+  'root':
+    owner: 'root'
+    group: 'root'
+    path:  '/root/.ssh/config'
+    host:  'host.example.local'
+```
+
+- *Default*: {}
+
+keys
+----
+Hash of keys for user's ~/.ssh/authorized_keys
+
+- *Default*: undefined
+
+packages
+--------
+Array of package names used for installation.
+
+- *Default*: Based on OS
+
+permit_root_login
+-----------------
+Allow root login. Valid values are 'yes', 'without-password', 'forced-commands-only', and 'no'.
+
+- *Default*: yes
+
+ssh_config_forward_x11_trusted
+------------------------------
+ForwardX11Trusted. Determine remote X11 client access to the original X11 display. The option is set to 'yes' on Linux. Valid values are 'yes', 'no', and undef.
+
+- *Default*: 'USE_DEFAULTS' (Not valid on Solaris.)
+
+ssh_package_source
+------------------
+Source to SSH packages.
+
+- *Default*: 'USE_DEFAULTS'
+
+ssh_package_adminfile
+---------------------
+Path to admin file for SSH packages.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_gssapiauthentication
+-------------------------
+GSSAPIAuthentication: Enables/disables GSS-API user authentication. Valid values are 'yes' and 'no'.
+
+- *Default*: 'yes'
+
+sshd_gssapikeyexchange
+----------------------
+GSSAPIKeyExchange: Enables/disables GSS-API-authenticated key exchanges. Valid values are 'yes', 'no', and undef.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_pamauthenticationviakbdint
+-------------------------------
+PAMAuthenticationViaKBDInt: Use PAM via keyboard interactive method for authentication. Valid values are 'yes', 'no', and undef.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_gssapicleanupcredentials
+-----------------------------
+GSSAPICleanupCredentials: Specifies whether to automatically destroy the user's credentials on logout. Default is 'yes' on Linux. Valid values are 'yes', 'no', and undef.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_acceptenv
+-------------
+Boolean to enable AcceptEnv options for specifying environment variables. Default is set to true on Linux.
+
+- *Default*: 'USE_DEFAULTS'
+
+sshd_hostbasedauthentication
+-------------------------
+String for HostbasedAuthentication option in sshd_config. Valid values are 'yes' and 'no'. Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed (host-based authentication). This option is similar to RhostsRSAAuthentication and applies to protocol version 2 only.
+
+- *Default*: 'no'
+
+sshd_pubkeyacceptedkeytypes
+-------------------------
+Array of public key types to be used with the PubkeyAcceptedKeyTypes option in sshd_config.
+
+- *Default*: undef
+
+sshd_pubkeyauthentication
+-------------------------
+String for PubkeyAuthentication option in sshd_config. Valid values are 'yes' and 'no'.
+
+- *Default*: 'yes'
+
+sshd_ignoreuserknownhosts
+-------------------------
+String for IgnoreUserKnownHosts option in sshd_config. Valid values are 'yes' and 'no'. Specifies whether sshd(8) should ignore the user's ~/.ssh/known_hosts during RhostsRSAAuthentication or HostbasedAuthentication.
+
+- *Default*: 'no'
+
+sshd_config_authenticationmethods
+-------------------------
+Array of AuthenticationMethods in sshd_config.
+
+- *Default*: undef
+
+sshd_ignorerhosts
+-------------------------
+String for IgnoreRhosts option in sshd_config. Valid values are 'yes' and 'no'. Specifies that .rhosts and .shosts files will not be used in RhostsRSAAuthentication or HostbasedAuthentication though /etc/hosts.equiv and /etc/ssh/shosts.equiv are still used.
+
+- *Default*: 'yes'
+
+purge_keys
+----------
+Remove keys not managed by puppet.
+
+- *Default*: 'true'
+
+manage_firewall
+---------------
+Open firewall for SSH service. Not used on Solaris.
+
+- *Default*: false
+
+service_ensure
+--------------
+Ensure SSH service is running. Valid values are 'stopped' and 'running'.
+
+- *Default*: 'running'
+
+service_name
+------------
+Name of the SSH service.
+
+- *Default*: Based on OS
+
+service_enable
+--------------
+Start SSH at boot. Valid values are 'true', 'false' and 'manual'.
+
+- *Default*: 'true'
+
+service_hasrestart
+------------------
+Specify that the init script has a restart command. Valid values are 'true' and 'false'.
+
+- *Default*: 'true'
+
+service_hasstatus
+-----------------
+Boolean to declare whether the service's init script has a functional status command.
+
+- *Default*: 'USE_DEFAULTS'
+
+ssh_key_ensure
+--------------
+Export node SSH key. Valid values are 'present' and 'absent'.
+
+- *Default*: 'present'
+
+ssh_key_import
+--------------
+Import all exported node SSH keys. Valid values are 'true' and 'false'.
+
+- *Default*: 'true'
+
+ssh_key_type
+------------
+Encryption type for SSH key. Valid values are 'ecdsa-sha2-nistp256', 'rsa', 'dsa', 'ssh-dss' and 'ssh-rsa'
+
+- *Default*: 'ssh-rsa'
+
+ssh_config_global_known_hosts_file
+----------------------------------
+File of the global known_hosts file
+
+- *Default*: '/etc/ssh/ssh_known_hosts'
+
+ssh_config_global_known_hosts_list
+----------------------------------
+Array of additional known_hosts files to be added to GlobalKnownHostsFile
+option together with `ssh_config_global_known_hosts_file`.
+
+- *Default*: undef
+
+ssh_config_global_known_hosts_owner
+----------------------------------
+Owner of the global known_hosts file
+
+- *Default*: 'root'
+
+ssh_config_global_known_hosts_group
+----------------------------------
+Group of the global known_hosts file
+
+- *Default*: 'root'
+
+ssh_config_global_known_hosts_mode
+----------------------------------
+File mode of the global known_hosts file
+
+- *Default*: '0644'
+
+ssh_config_user_known_hosts_file
+--------------------------------
+Array of user's known_hosts files used in the ssh config option
+UserKnownHostsFile.
+
+- *Default*: undef
+
+manage_root_ssh_config
+----------------------
+Manage SSH config of root. Valid values are 'true' and 'false'.
+
+- *Default*: 'false'
+
+root_ssh_config_content
+-----------------------
+Content of root's ~/.ssh/config.
+
+- *Default*: "# This file is being maintained by Puppet.\n# DO NOT EDIT\n"
+
+manage_service
+--------------
+Manage the sshd service through this module or not.  Valid values are 'true' and 'false'.
+
+- *Default*: 'true'
+
+===
+# Manage user's ssh_authorized_keys
+This works by passing the ssh::keys hash to the ssh_authorized_keys type with create_resources(). Because of this, you may specify any valid parameter for ssh_authorized_key. See the [Type Reference](http://docs.puppetlabs.com/references/stable/type.html#ssh_authorized_key) for a complete list.
+
+## Sample usage:
+Push authorized key "root_for_userX" and remove key "root_for_userY" through Hiera.
+
+``` yaml
+ssh::keys:
+  root_for_userX:
+    ensure: present
+    user: root
+    type: dsa
+    key: AAAA...==
+  apachehup:
+    ensure: present
+    user: apachehup
+    type: rsa
+    key: 'AAAA...=='
+    options: 'command="/sbin/service httpd restart"'
+  root_for_userY:
+    ensure: absent
+    user: root
+```
+
+Manage config entries in a personal ssh/config file.
+
+```
+Ssh::Config_entry {
+  ensure => present,
+  path   => '/home/jenkins/.ssh/config',
+  owner  => 'jenkins',
+  group  => 'jenkins',
+}
+
+
+ssh::config_entry { 'jenkins *':
+  host  => '*',
+  lines => [
+    '  ForwardX11 no',
+    '  StrictHostKeyChecking no',
+  ],
+  order => '10',
+}
+
+ssh::config_entry { 'jenkins github.com':
+  host  => 'github.com',
+  lines => ["  IdentityFile /home/jenkins/.ssh/jenkins-gihub.key"],
+  order => '20',
+}
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/Rakefile	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,14 @@
+require 'puppetlabs_spec_helper/rake_tasks'
+require 'puppet-lint/tasks/puppet-lint'
+PuppetLint.configuration.send('disable_80chars')
+PuppetLint.configuration.send('disable_140chars')
+PuppetLint.configuration.send('disable_relative_classname_inclusion')
+PuppetLint.configuration.relative = true
+PuppetLint.configuration.ignore_paths = ['spec/**/*.pp', 'pkg/**/*.pp', 'vendor/**/*.pp']
+
+desc 'Validate manifests, templates, ruby files and shell scripts'
+task :validate do
+  Dir['spec/**/*.rb', 'lib/**/*.rb'].each do |ruby_file|
+    sh "ruby -c #{ruby_file}" unless ruby_file =~ /spec\/fixtures/
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/checksums.json	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,46 @@
+{
+  "CHANGELOG.md": "39842153ecbc93719c9decfb5e42cd29",
+  "Gemfile": "0fa76785ecc048612226d244398478e9",
+  "LICENSE": "834fb8390f13d7e30490e90f7b5d9ee0",
+  "README.md": "65a4546716e6eb27ab14721996b48716",
+  "Rakefile": "d08d16d1747c98c2214371140f28eabf",
+  "lib/facter/ssh.rb": "90c8b6a2584af828705a6c2a8f2543af",
+  "manifests/config_entry.pp": "95a8b6b9e6158bd5219c857f3bfc0f14",
+  "manifests/init.pp": "f274330ddfea80937f3dda4873ca1612",
+  "metadata.json": "6d782fbaddefc4f2535b3cd7b46a4971",
+  "spec/classes/init_spec.rb": "c0ab5f27eb46da4f4eba759d30953736",
+  "spec/defines/config_entry_spec.rb": "5c851cb3e6aef8d0313f79be4b935ef9",
+  "spec/fixtures/hiera/hiera.yaml": "afd005f8cc148b09cf7e22c99939fedf",
+  "spec/fixtures/hiera/hieradata/fqdn/hieramerge.example.com.yaml": "99094cc414a52464f7cfa3240b2ccf3d",
+  "spec/fixtures/hiera/hieradata/specific/test_hiera_merge.yaml": "21c72185d6280cba9ca30d44cc88e38d",
+  "spec/fixtures/ssh_config_debian": "08cc71e013e8ba01c7d1f03d212f1ee5",
+  "spec/fixtures/ssh_config_debian10": "2ff55286f1fdae6b41f37cd95b21dbf4",
+  "spec/fixtures/ssh_config_debian8": "2ff55286f1fdae6b41f37cd95b21dbf4",
+  "spec/fixtures/ssh_config_debian9": "2ff55286f1fdae6b41f37cd95b21dbf4",
+  "spec/fixtures/ssh_config_rhel": "08cc71e013e8ba01c7d1f03d212f1ee5",
+  "spec/fixtures/ssh_config_rhel_old": "a1ea3fe028f4df9735166529ce2970c4",
+  "spec/fixtures/ssh_config_solaris": "a0cae90d169fe6c2df6ce0e9d603def6",
+  "spec/fixtures/ssh_config_suse": "08cc71e013e8ba01c7d1f03d212f1ee5",
+  "spec/fixtures/ssh_config_suse_old": "a1ea3fe028f4df9735166529ce2970c4",
+  "spec/fixtures/ssh_config_ubuntu1604": "2ff55286f1fdae6b41f37cd95b21dbf4",
+  "spec/fixtures/ssh_config_ubuntu1804": "2ff55286f1fdae6b41f37cd95b21dbf4",
+  "spec/fixtures/ssh_config_ubuntu2004": "d3f184e92cf23b165c5f44e63d93401e",
+  "spec/fixtures/sshd_config_debian": "1a79014d4d4a409e854eb18b798e660b",
+  "spec/fixtures/sshd_config_debian10": "6786b988dce33249cd430e690d9bfeb7",
+  "spec/fixtures/sshd_config_debian8": "7f0704abba19719cbc4e8dd359b787c4",
+  "spec/fixtures/sshd_config_debian9": "6786b988dce33249cd430e690d9bfeb7",
+  "spec/fixtures/sshd_config_rhel": "969b46c8fab7a5f007418e872bfc365d",
+  "spec/fixtures/sshd_config_rhel7": "8e2379048e31038cbb35195bc53c9e43",
+  "spec/fixtures/sshd_config_sles_12_x86_64": "3b614288dab63f558a533967edb5001d",
+  "spec/fixtures/sshd_config_solaris": "44bfa0a9bcca28b6d9cf21a6465d0d36",
+  "spec/fixtures/sshd_config_suse_i386": "3b614288dab63f558a533967edb5001d",
+  "spec/fixtures/sshd_config_suse_x86_64": "0c02d37e3485b231ba1691c60fe6530b",
+  "spec/fixtures/sshd_config_ubuntu1604": "a0954e744f184b52156b10ba66a07892",
+  "spec/fixtures/sshd_config_ubuntu1804": "a0954e744f184b52156b10ba66a07892",
+  "spec/fixtures/sshd_config_ubuntu2004": "6f57ddefcf34e431225d5343a1461ae2",
+  "spec/spec_helper.rb": "63a6a4e0cb806d5f46095edb8bb4c08f",
+  "spec/unit/facter/ssh_spec.rb": "d39d0ce8f3d2aaecf9115e96da838959",
+  "templates/ssh_config.erb": "24e1045e1cbf326159b267be7cef5c73",
+  "templates/sshd_config.erb": "35926d076b2563e6c31d194a674f7e31",
+  "tests/init.pp": "f6931420bc8054d207fecf4b0855f5a7"
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/lib/facter/ssh.rb	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,16 @@
+Facter.add('ssh_version') do
+  setcode do
+    if Facter::Util::Resolution.which('ssh')
+      Facter::Util::Resolution.exec('ssh -V 2>&1').match(/^[A-Za-z0-9._]+/)[0]
+    end
+  end
+end
+
+Facter.add('ssh_version_numeric') do
+  setcode do
+    ssh_version = Facter.value(:ssh_version)
+    if ssh_version
+      ssh_version.match(/(\d+\.\d+\.\d+|\d+\.\d+)/)[0]
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/manifests/config_entry.pp	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,36 @@
+# == Define: ssh::config_entry
+#
+# Manage an entry in ~/.ssh/config for a particular user.  Lines model the lines
+# in each Host block.
+define ssh::config_entry (
+  $owner,
+  $group,
+  $path,
+  $host,
+  $order  = '10',
+  $ensure = 'present',
+  $lines  = [],
+) {
+
+  # All lines including the host line.  This will be joined with "\n  " for
+  # indentation.
+  $entry = concat(["Host ${host}"], $lines)
+  $content = join($entry, "\n")
+
+  if ! defined(Concat[$path]) {
+    concat { $path:
+      ensure         => present,
+      owner          => $owner,
+      group          => $group,
+      mode           => '0644',
+      ensure_newline => true,
+    }
+  }
+
+  concat::fragment { "${path} Host ${host}":
+    target  => $path,
+    content => $content,
+    order   => $order,
+    tag     => "${owner}_ssh_config",
+  }
+}
--- a/modules/ssh/manifests/init.pp	Sun Dec 19 20:10:16 2021 +0000
+++ b/modules/ssh/manifests/init.pp	Mon Jan 03 17:05:54 2022 +0000
@@ -1,140 +1,1248 @@
-# This is an example proposed Puppet Common Module for SSH
+# == Class: ssh
+#
+# Manage ssh client and server
 #
-# Usage Requirements:
-# 1) Set $server in site.pp
-#    Allows for a different fileserver than the real puppetmaster
-# 2) Set $os to $operatingsystem
-#    Saves typing, purely cosmetic
-# 3) Set $osver to $operatingsystemrelease or $lsbdistrelease
-#    $operatingsystemrelease is not available on all platforms
-#
-#Taken from the the Puppet Wiki - http://projects.puppetlabs.com/projects/1/wiki/puppet_common_modules_ssh
+class ssh (
+  $hiera_merge                                = false,
+  $packages                                   = 'USE_DEFAULTS',
+  $permit_root_login                          = 'yes',
+  $purge_keys                                 = true,
+  $manage_firewall                            = false,
+  $ssh_package_source                         = 'USE_DEFAULTS',
+  $ssh_package_adminfile                      = 'USE_DEFAULTS',
+  $ssh_config_hash_known_hosts                = 'USE_DEFAULTS',
+  $ssh_config_path                            = '/etc/ssh/ssh_config',
+  $ssh_config_owner                           = 'root',
+  $ssh_config_group                           = 'root',
+  $ssh_config_mode                            = '0644',
+  $ssh_config_forward_x11                     = undef,
+  $ssh_config_forward_x11_trusted             = 'USE_DEFAULTS',
+  $ssh_config_forward_agent                   = undef,
+  $ssh_config_server_alive_interval           = undef,
+  $ssh_config_sendenv_xmodifiers              = false,
+  $ssh_hostbasedauthentication                = undef,
+  $ssh_config_proxy_command                   = undef,
+  $ssh_strict_host_key_checking               = undef,
+  $ssh_config_ciphers                         = undef,
+  $ssh_config_kexalgorithms                   = undef,
+  $ssh_config_macs                            = undef,
+  $ssh_config_use_roaming                     = 'USE_DEFAULTS',
+  $ssh_config_template                        = 'ssh/ssh_config.erb',
+  $ssh_sendenv                                = 'USE_DEFAULTS',
+  $ssh_gssapiauthentication                   = 'yes',
+  $ssh_gssapidelegatecredentials              = undef,
+  $sshd_config_path                           = '/etc/ssh/sshd_config',
+  $sshd_config_owner                          = 'root',
+  $sshd_config_group                          = 'root',
+  $sshd_config_loglevel                       = 'INFO',
+  $sshd_config_mode                           = 'USE_DEFAULTS',
+  $sshd_config_permitemptypasswords           = undef,
+  $sshd_config_permituserenvironment          = undef,
+  $sshd_config_compression                    = undef,
+  $sshd_config_port                           = '22',
+  $sshd_config_syslog_facility                = 'AUTH',
+  $sshd_config_template                       = 'ssh/sshd_config.erb',
+  $sshd_config_login_grace_time               = '120',
+  $sshd_config_challenge_resp_auth            = 'yes',
+  $sshd_config_print_motd                     = 'yes',
+  $sshd_config_print_last_log                 = undef,
+  $sshd_config_use_dns                        = 'USE_DEFAULTS',
+  $sshd_config_authkey_location               = undef,
+  $sshd_config_strictmodes                    = undef,
+  $sshd_config_serverkeybits                  = 'USE_DEFAULTS',
+  $sshd_config_banner                         = 'none',
+  $sshd_config_ciphers                        = undef,
+  $sshd_config_kexalgorithms                  = undef,
+  $sshd_config_macs                           = undef,
+  $ssh_enable_ssh_keysign                     = undef,
+  $sshd_config_allowgroups                    = [],
+  $sshd_config_allowusers                     = [],
+  $sshd_config_denygroups                     = [],
+  $sshd_config_denyusers                      = [],
+  $sshd_config_maxauthtries                   = undef,
+  $sshd_config_maxstartups                    = undef,
+  $sshd_config_maxsessions                    = undef,
+  $sshd_config_chrootdirectory                = undef,
+  $sshd_config_forcecommand                   = undef,
+  $sshd_config_match                          = undef,
+  $sshd_authorized_keys_command               = undef,
+  $sshd_authorized_keys_command_user          = undef,
+  $sshd_banner_content                        = undef,
+  $sshd_banner_owner                          = 'root',
+  $sshd_banner_group                          = 'root',
+  $sshd_banner_mode                           = '0644',
+  $sshd_config_xauth_location                 = 'USE_DEFAULTS',
+  $sshd_config_subsystem_sftp                 = 'USE_DEFAULTS',
+  $sshd_kerberos_authentication               = undef,
+  $sshd_password_authentication               = 'yes',
+  $sshd_allow_tcp_forwarding                  = 'yes',
+  $sshd_x11_forwarding                        = 'yes',
+  $sshd_x11_use_localhost                     = 'yes',
+  $sshd_use_pam                               = 'USE_DEFAULTS',
+  $sshd_client_alive_count_max                = '3',
+  $sshd_client_alive_interval                 = '0',
+  $sshd_gssapiauthentication                  = 'yes',
+  $sshd_gssapikeyexchange                     = 'USE_DEFAULTS',
+  $sshd_pamauthenticationviakbdint            = 'USE_DEFAULTS',
+  $sshd_gssapicleanupcredentials              = 'USE_DEFAULTS',
+  $sshd_acceptenv                             = 'USE_DEFAULTS',
+  $sshd_config_hostkey                        = 'USE_DEFAULTS',
+  $sshd_listen_address                        = undef,
+  $sshd_hostbasedauthentication               = 'no',
+  $sshd_pubkeyacceptedkeytypes                = undef,
+  $sshd_pubkeyauthentication                  = 'yes',
+  $sshd_ignoreuserknownhosts                  = 'no',
+  $sshd_ignorerhosts                          = 'yes',
+  $sshd_config_authenticationmethods          = undef,
+  $manage_service                             = true,
+  $sshd_addressfamily                         = 'USE_DEFAULTS',
+  $service_ensure                             = 'running',
+  $service_name                               = 'USE_DEFAULTS',
+  $service_enable                             = true,
+  $service_hasrestart                         = true,
+  $service_hasstatus                          = 'USE_DEFAULTS',
+  $ssh_key_ensure                             = 'present',
+  $ssh_key_import                             = true,
+  $ssh_key_type                               = 'ssh-rsa',
+  $ssh_config_global_known_hosts_file         = '/etc/ssh/ssh_known_hosts',
+  $ssh_config_global_known_hosts_list         = undef,
+  $ssh_config_global_known_hosts_owner        = 'root',
+  $ssh_config_global_known_hosts_group        = 'root',
+  $ssh_config_global_known_hosts_mode         = '0644',
+  $ssh_config_user_known_hosts_file           = undef,
+  $ssh_config_include                         = 'USE_DEFAULTS',
+  $config_entries                             = {},
+  $keys                                       = undef,
+  $manage_root_ssh_config                     = false,
+  $root_ssh_config_content                    = "# This file is being maintained by Puppet.\n# DO NOT EDIT\n",
+  $sshd_config_tcp_keepalive                  = undef,
+  $sshd_config_use_privilege_separation       = undef,
+  $sshd_config_permittunnel                   = undef,
+  $sshd_config_hostcertificate                = undef,
+  $sshd_config_trustedusercakeys              = undef,
+  $sshd_config_key_revocation_list            = undef,
+  $sshd_config_authorized_principals_file     = undef,
+  $sshd_config_allowagentforwarding           = undef,
+  $sshd_config_include                        = 'USE_DEFAULTS',
+) {
+
+  case $::osfamily {
+    'RedHat': {
+      $default_packages                        = ['openssh-server',
+                                                  'openssh-clients']
+      $default_service_name                    = 'sshd'
+      $default_ssh_config_hash_known_hosts     = 'no'
+      $default_ssh_config_forward_x11_trusted  = 'yes'
+      $default_ssh_package_source              = undef
+      $default_ssh_package_adminfile           = undef
+      $default_ssh_sendenv                     = true
+      $default_ssh_config_include              = undef
+      $default_sshd_config_subsystem_sftp      = '/usr/libexec/openssh/sftp-server'
+      $default_sshd_config_mode                = '0600'
+      $default_sshd_config_use_dns             = 'yes'
+      $default_sshd_config_xauth_location      = '/usr/bin/xauth'
+      $default_sshd_use_pam                    = 'yes'
+      $default_sshd_gssapikeyexchange          = undef
+      $default_sshd_pamauthenticationviakbdint = undef
+      $default_sshd_gssapicleanupcredentials   = 'yes'
+      $default_sshd_acceptenv                  = true
+      $default_service_hasstatus               = true
+      if versioncmp($::operatingsystemrelease, '7.4') < 0 {
+        $default_sshd_config_serverkeybits = '1024'
+      } else {
+        $default_sshd_config_serverkeybits = undef
+      }
+      $default_sshd_config_hostkey             = [ '/etc/ssh/ssh_host_rsa_key' ]
+      $default_sshd_addressfamily              = 'any'
+      $default_sshd_config_tcp_keepalive       = 'yes'
+      $default_sshd_config_permittunnel        = 'no'
+      $default_sshd_config_include             = undef
+    }
+    'Suse': {
+      $default_packages                        = 'openssh'
+      $default_service_name                    = 'sshd'
+      $default_ssh_config_hash_known_hosts     = 'no'
+      $default_ssh_package_source              = undef
+      $default_ssh_package_adminfile           = undef
+      $default_ssh_sendenv                     = true
+      $default_ssh_config_forward_x11_trusted  = 'yes'
+      $default_ssh_config_include              = undef
+      $default_sshd_config_mode                = '0600'
+      $default_sshd_config_use_dns             = 'yes'
+      $default_sshd_config_xauth_location      = '/usr/bin/xauth'
+      $default_sshd_use_pam                    = 'yes'
+      $default_sshd_gssapikeyexchange          = undef
+      $default_sshd_pamauthenticationviakbdint = undef
+      $default_sshd_gssapicleanupcredentials   = 'yes'
+      $default_sshd_acceptenv                  = true
+      $default_service_hasstatus               = true
+      $default_sshd_config_serverkeybits       = '1024'
+      $default_sshd_config_hostkey             = [ '/etc/ssh/ssh_host_rsa_key' ]
+      $default_sshd_addressfamily              = 'any'
+      $default_sshd_config_tcp_keepalive       = 'yes'
+      $default_sshd_config_permittunnel        = 'no'
+      $default_sshd_config_include             = undef
+      case $::architecture {
+        'x86_64': {
+          if ($::operatingsystem == 'SLES') and ($::operatingsystemrelease =~ /^12\./) {
+            $default_sshd_config_subsystem_sftp = '/usr/lib/ssh/sftp-server'
+          } else {
+            $default_sshd_config_subsystem_sftp = '/usr/lib64/ssh/sftp-server'
+          }
+        }
+        'i386' : {
+          $default_sshd_config_subsystem_sftp = '/usr/lib/ssh/sftp-server'
+      }
+        default: {
+          fail("ssh supports architectures x86_64 and i386 for Suse. Detected architecture is <${::architecture}>.")
+        }
+      }
+    }
+    'Debian': {
+      # common for debian and ubuntu
+      $default_packages                        = ['openssh-server',
+                                                  'openssh-client']
+      $default_service_name                    = 'ssh'
 
-class ssh {
-    # Distribution independent packages
-    # See also our Operating System specific sub-classes
-    @package { [
-            "openssh-clients",
-            "openssh-server",
-#            "denyhosts"
-        ]:
-        ensure => installed
+      case $::operatingsystemrelease {
+        '16.04': {
+          $default_sshd_config_hostkey = [
+            '/etc/ssh/ssh_host_rsa_key',
+            '/etc/ssh/ssh_host_dsa_key',
+            '/etc/ssh/ssh_host_ecdsa_key',
+            '/etc/ssh/ssh_host_ed25519_key',
+          ]
+          $default_ssh_config_hash_known_hosts        = 'yes'
+          $default_sshd_config_xauth_location         = undef
+          $default_ssh_config_forward_x11_trusted     = 'yes'
+          $default_ssh_package_source                 = undef
+          $default_ssh_package_adminfile              = undef
+          $default_ssh_sendenv                        = true
+          $default_ssh_config_include                 = undef
+          $default_sshd_config_subsystem_sftp         = '/usr/lib/openssh/sftp-server'
+          $default_sshd_config_mode                   = '0600'
+          $default_sshd_config_use_dns                = 'yes'
+          $default_sshd_use_pam                       = 'yes'
+          $default_sshd_gssapikeyexchange             = undef
+          $default_sshd_pamauthenticationviakbdint    = undef
+          $default_sshd_gssapicleanupcredentials      = 'yes'
+          $default_sshd_acceptenv                     = true
+          $default_service_hasstatus                  = true
+          $default_sshd_config_serverkeybits          = '1024'
+          $default_sshd_addressfamily                 = 'any'
+          $default_sshd_config_tcp_keepalive          = 'yes'
+          $default_sshd_config_permittunnel           = 'no'
+          $default_sshd_config_include                = undef
+        }
+        '18.04': {
+          $default_sshd_config_hostkey = [
+            '/etc/ssh/ssh_host_rsa_key',
+            '/etc/ssh/ssh_host_dsa_key',
+            '/etc/ssh/ssh_host_ecdsa_key',
+            '/etc/ssh/ssh_host_ed25519_key',
+          ]
+          $default_ssh_config_hash_known_hosts        = 'yes'
+          $default_sshd_config_xauth_location         = undef
+          $default_ssh_config_forward_x11_trusted     = 'yes'
+          $default_ssh_package_source                 = undef
+          $default_ssh_package_adminfile              = undef
+          $default_ssh_sendenv                        = true
+          $default_ssh_config_include                 = undef
+          $default_sshd_config_subsystem_sftp         = '/usr/lib/openssh/sftp-server'
+          $default_sshd_config_mode                   = '0600'
+          $default_sshd_config_use_dns                = 'yes'
+          $default_sshd_use_pam                       = 'yes'
+          $default_sshd_gssapikeyexchange             = undef
+          $default_sshd_pamauthenticationviakbdint    = undef
+          $default_sshd_gssapicleanupcredentials      = 'yes'
+          $default_sshd_acceptenv                     = true
+          $default_service_hasstatus                  = true
+          $default_sshd_config_serverkeybits          = '1024'
+          $default_sshd_addressfamily                 = 'any'
+          $default_sshd_config_tcp_keepalive          = 'yes'
+          $default_sshd_config_permittunnel           = 'no'
+          $default_sshd_config_include                = undef
+        }
+        '20.04': {
+          $default_service_hasstatus                  = true
+          $default_ssh_config_forward_x11_trusted     = 'yes'
+          $default_ssh_config_hash_known_hosts        = 'yes'
+          $default_ssh_config_include                 = '/etc/ssh/ssh_config.d/*.conf'
+          $default_ssh_gssapiauthentication           = 'yes'
+          $default_ssh_package_adminfile              = undef
+          $default_ssh_package_source                 = undef
+          $default_ssh_sendenv                        = true
+          $default_sshd_acceptenv                     = true
+          $default_sshd_addressfamily                 = 'any'
+          $default_sshd_config_hostkey                = []
+          $default_sshd_config_include                = '/etc/ssh/sshd_config.d/*.conf'
+          $default_sshd_config_mode                   = '0600'
+          $default_sshd_config_permittunnel           = undef
+          $default_sshd_config_print_motd             = 'no'
+          $default_sshd_config_serverkeybits          = undef
+          $default_sshd_config_subsystem_sftp         = '/usr/lib/openssh/sftp-server'
+          $default_sshd_config_tcp_keepalive          = undef
+          $default_sshd_config_use_dns                = 'yes'
+          $default_sshd_config_xauth_location         = undef
+          $default_sshd_gssapiauthentication          = 'yes'
+          $default_sshd_gssapicleanupcredentials      = 'yes'
+          $default_sshd_gssapikeyexchange             = undef
+          $default_sshd_pamauthenticationviakbdint    = undef
+          $default_sshd_use_pam                       = 'yes'
+          $default_sshd_x11_forwarding                = 'yes'
+        }
+        /^10.*/: {
+          $default_sshd_config_hostkey = [
+            '/etc/ssh/ssh_host_rsa_key',
+            '/etc/ssh/ssh_host_ecdsa_key',
+            '/etc/ssh/ssh_host_ed25519_key',
+          ]
+          $default_sshd_config_mode                = '0600'
+          $default_sshd_use_pam                    = 'yes'
+          $default_ssh_config_forward_x11_trusted  = 'yes'
+          $default_ssh_config_include              = undef
+          $default_sshd_acceptenv                  = true
+          $default_sshd_config_subsystem_sftp      = '/usr/lib/openssh/sftp-server'
+          $default_ssh_config_hash_known_hosts     = 'yes'
+          $default_ssh_sendenv                     = true
+          $default_sshd_addressfamily              = undef
+          $default_sshd_config_serverkeybits       = undef
+          $default_sshd_gssapicleanupcredentials   = undef
+          $default_sshd_config_use_dns             = undef
+          $default_sshd_config_xauth_location      = undef
+          $default_sshd_config_permittunnel        = undef
+          $default_sshd_config_tcp_keepalive       = undef
+          $default_ssh_package_source              = undef
+          $default_ssh_package_adminfile           = undef
+          $default_sshd_gssapikeyexchange          = undef
+          $default_sshd_pamauthenticationviakbdint = undef
+          $default_service_hasstatus               = true
+          $default_sshd_config_include             = undef
+        }
+        /^9.*/: {
+          $default_sshd_config_hostkey = [
+            '/etc/ssh/ssh_host_rsa_key',
+            '/etc/ssh/ssh_host_ecdsa_key',
+            '/etc/ssh/ssh_host_ed25519_key',
+          ]
+          $default_sshd_config_mode                = '0600'
+          $default_sshd_use_pam                    = 'yes'
+          $default_ssh_config_forward_x11_trusted  = 'yes'
+          $default_sshd_acceptenv                  = true
+          $default_sshd_config_subsystem_sftp      = '/usr/lib/openssh/sftp-server'
+          $default_ssh_config_hash_known_hosts     = 'yes'
+          $default_ssh_sendenv                     = true
+          $default_ssh_config_include              = undef
+          $default_sshd_addressfamily              = undef
+          $default_sshd_config_serverkeybits       = undef
+          $default_sshd_gssapicleanupcredentials   = undef
+          $default_sshd_config_use_dns             = undef
+          $default_sshd_config_xauth_location      = undef
+          $default_sshd_config_permittunnel        = undef
+          $default_sshd_config_tcp_keepalive       = undef
+          $default_ssh_package_source              = undef
+          $default_ssh_package_adminfile           = undef
+          $default_sshd_gssapikeyexchange          = undef
+          $default_sshd_pamauthenticationviakbdint = undef
+          $default_sshd_config_include             = undef
+          $default_service_hasstatus               = true
+        }
+        /^7.*/: {
+          $default_sshd_config_hostkey             = [ '/etc/ssh/ssh_host_rsa_key' ]
+          $default_ssh_config_hash_known_hosts     = 'no'
+          $default_sshd_config_xauth_location      = '/usr/bin/xauth'
+          $default_ssh_config_forward_x11_trusted  = 'yes'
+          $default_ssh_package_source              = undef
+          $default_ssh_package_adminfile           = undef
+          $default_ssh_sendenv                     = true
+          $default_ssh_config_include              = undef
+          $default_sshd_config_subsystem_sftp      = '/usr/lib/openssh/sftp-server'
+          $default_sshd_config_mode                = '0600'
+          $default_sshd_config_use_dns             = 'yes'
+          $default_sshd_use_pam                    = 'yes'
+          $default_sshd_gssapikeyexchange          = undef
+          $default_sshd_pamauthenticationviakbdint = undef
+          $default_sshd_gssapicleanupcredentials   = 'yes'
+          $default_sshd_acceptenv                  = true
+          $default_service_hasstatus               = true
+          $default_sshd_config_serverkeybits       = '1024'
+          $default_sshd_addressfamily              = 'any'
+          $default_sshd_config_tcp_keepalive       = 'yes'
+          $default_sshd_config_permittunnel        = 'no'
+          $default_sshd_config_include             = undef
+        }
+        /^8.*/: {
+
+          $default_ssh_config_hash_known_hosts     = 'yes'
+          $default_ssh_config_forward_x11_trusted  = 'yes'
+          $default_ssh_package_source              = undef
+          $default_ssh_package_adminfile           = undef
+          $default_ssh_sendenv                     = true
+          $default_ssh_config_include              = undef
+          $default_sshd_config_hostkey = [
+          '/etc/ssh/ssh_host_rsa_key',
+          '/etc/ssh/ssh_host_dsa_key',
+          '/etc/ssh/ssh_host_ecdsa_key',
+          '/etc/ssh/ssh_host_ed25519_key',
+          ]
+          $default_sshd_config_subsystem_sftp      = '/usr/lib/openssh/sftp-server'
+          $default_sshd_config_mode                = '0600'
+          $default_sshd_config_use_dns             = 'yes'
+          $default_sshd_use_pam                    = 'yes'
+          $default_sshd_gssapikeyexchange          = undef
+          $default_sshd_pamauthenticationviakbdint = undef
+          $default_sshd_gssapicleanupcredentials   = undef
+          $default_sshd_acceptenv                  = true
+          $default_sshd_config_xauth_location      = undef
+          $default_sshd_config_serverkeybits       = '1024'
+          $default_sshd_addressfamily              = 'any'
+          $default_sshd_config_tcp_keepalive       = 'yes'
+          $default_sshd_config_permittunnel        = 'no'
+          $default_service_hasstatus               = true
+          $default_sshd_config_include             = undef
+        }
+        default: { fail ("Operating System : ${::operatingsystemrelease} not supported") }
+      }
     }
+    'Solaris': {
+      $default_ssh_config_hash_known_hosts     = undef
+      $default_ssh_sendenv                     = false
+      $default_ssh_config_forward_x11_trusted  = undef
+      $default_ssh_config_include              = undef
+      $default_sshd_config_subsystem_sftp      = '/usr/lib/ssh/sftp-server'
+      $default_sshd_config_mode                = '0644'
+      $default_sshd_config_use_dns             = undef
+      $default_sshd_config_xauth_location      = '/usr/openwin/bin/xauth'
+      $default_sshd_use_pam                    = undef
+      $default_sshd_gssapikeyexchange          = 'yes'
+      $default_sshd_pamauthenticationviakbdint = 'yes'
+      $default_sshd_gssapicleanupcredentials   = undef
+      $default_sshd_acceptenv                  = false
+      $default_sshd_config_serverkeybits       = '768'
+      $default_ssh_package_adminfile           = undef
+      $default_sshd_config_hostkey             = [ '/etc/ssh/ssh_host_rsa_key' ]
+      $default_sshd_addressfamily              = undef
+      $default_sshd_config_tcp_keepalive       = undef
+      $default_sshd_config_permittunnel        = undef
+      $default_sshd_config_include             = undef
+      case $::kernelrelease {
+        '5.11': {
+          $default_packages                      = ['network/ssh',
+                                                    'network/ssh/ssh-key',
+                                                    'service/network/ssh']
+          $default_service_name                  = 'ssh'
+          $default_service_hasstatus             = true
+          $default_ssh_package_source            = undef
+        }
+        '5.10': {
+          $default_packages                      = ['SUNWsshcu',
+                                                    'SUNWsshdr',
+                                                    'SUNWsshdu',
+                                                    'SUNWsshr',
+                                                    'SUNWsshu']
+          $default_service_name                  = 'ssh'
+          $default_service_hasstatus             = true
+          $default_ssh_package_source            = '/var/spool/pkg'
+        }
+        '5.9' : {
+          $default_packages                      = ['SUNWsshcu',
+                                                    'SUNWsshdr',
+                                                    'SUNWsshdu',
+                                                    'SUNWsshr',
+                                                    'SUNWsshu']
+          $default_service_name                  = 'sshd'
+          $default_service_hasstatus             = false
+          $default_ssh_package_source            = '/var/spool/pkg'
+        }
+        default: {
+          fail('ssh module supports Solaris kernel release 5.9, 5.10 and 5.11.')
+        }
+      }
+    }
+    default: {
+      fail("ssh supports osfamilies RedHat, Suse, Debian and Solaris. Detected osfamily is <${::osfamily}>.")
+    }
+  }
 
-    # Virtual Resources get defined before we include $operatingsystem specific
-    # classes, so that there is at least something to add and/or override.
-    # 
-    # Additionally, this way we can realize() in sub-classes as much as we want
-    # to, and not concern ourselves with duplicate type definitions
-    #
+  if "${::ssh_version}" =~ /^OpenSSH/  { # lint:ignore:only_variable_string
+    $ssh_version_array = split($::ssh_version_numeric, '\.')
+    $ssh_version_maj_int = 0 + $ssh_version_array[0]
+    $ssh_version_min_int = 0 + $ssh_version_array[1]
+    if $ssh_version_maj_int > 5 {
+      $default_ssh_config_use_roaming = 'no'
+    } elsif $ssh_version_maj_int == 5 and $ssh_version_min_int >= 4 {
+      $default_ssh_config_use_roaming = 'no'
+    } else {
+      $default_ssh_config_use_roaming = 'unset'
+    }
+  } else {
+      $default_ssh_config_use_roaming = 'unset'
+  }
+
+  if $packages == 'USE_DEFAULTS' {
+    $packages_real = $default_packages
+  } else {
+    $packages_real = $packages
+  }
+
+  case $ssh_config_hash_known_hosts {
+    'unset':        { $ssh_config_hash_known_hosts_real = undef }
+    'USE_DEFAULTS': { $ssh_config_hash_known_hosts_real = $default_ssh_config_hash_known_hosts }
+    default:        { $ssh_config_hash_known_hosts_real = $ssh_config_hash_known_hosts }
+  }
+
+  if $service_name == 'USE_DEFAULTS' {
+    $service_name_real = $default_service_name
+  } else {
+    $service_name_real = $service_name
+  }
+
+  if $sshd_config_subsystem_sftp == 'USE_DEFAULTS' {
+    $sshd_config_subsystem_sftp_real = $default_sshd_config_subsystem_sftp
+  } else {
+    $sshd_config_subsystem_sftp_real = $sshd_config_subsystem_sftp
+  }
+
+  if $sshd_config_mode    == 'USE_DEFAULTS' {
+    $sshd_config_mode_real = $default_sshd_config_mode
+  } else {
+    $sshd_config_mode_real = $sshd_config_mode
+  }
+
+  if $sshd_config_xauth_location == 'USE_DEFAULTS' {
+    $sshd_config_xauth_location_real = $default_sshd_config_xauth_location
+  } else {
+    $sshd_config_xauth_location_real = $sshd_config_xauth_location
+  }
+
+  if $sshd_config_xauth_location_real != undef {
+    validate_absolute_path($sshd_config_xauth_location_real)
+  }
+
+  if $ssh_package_source == 'USE_DEFAULTS' {
+    $ssh_package_source_real = $default_ssh_package_source
+  } else {
+    $ssh_package_source_real = $ssh_package_source
+  }
+
+  if $ssh_package_source_real != undef {
+    validate_absolute_path($ssh_package_source_real)
+  }
+
+  if $ssh_package_adminfile == 'USE_DEFAULTS' {
+    $ssh_package_adminfile_real = $default_ssh_package_adminfile
+  } else {
+    $ssh_package_adminfile_real = $ssh_package_adminfile
+  }
+
+  if $ssh_package_adminfile_real != undef {
+    validate_absolute_path($ssh_package_adminfile_real)
+  }
+
+  if $sshd_config_use_dns == 'USE_DEFAULTS' {
+    $sshd_config_use_dns_real = $default_sshd_config_use_dns
+  } else {
+    $sshd_config_use_dns_real = $sshd_config_use_dns
+  }
+
+  if $sshd_use_pam == 'USE_DEFAULTS' {
+    $sshd_use_pam_real = $default_sshd_use_pam
+  } else {
+    $sshd_use_pam_real = $sshd_use_pam
+  }
+
+  if $sshd_config_serverkeybits == 'USE_DEFAULTS' {
+    $sshd_config_serverkeybits_real = $default_sshd_config_serverkeybits
+  } else {
+    $sshd_config_serverkeybits_real = $sshd_config_serverkeybits
+  }
+
+  if $ssh_config_forward_x11_trusted == 'USE_DEFAULTS' {
+    $ssh_config_forward_x11_trusted_real = $default_ssh_config_forward_x11_trusted
+  } else {
+    $ssh_config_forward_x11_trusted_real = $ssh_config_forward_x11_trusted
+  }
+  if $ssh_config_forward_x11_trusted_real != undef {
+    validate_re($ssh_config_forward_x11_trusted_real, '^(yes|no)$', "ssh::ssh_config_forward_x11_trusted may be either 'yes' or 'no' and is set to <${ssh_config_forward_x11_trusted_real}>.")
+  }
+
+  if $sshd_gssapikeyexchange == 'USE_DEFAULTS' {
+    $sshd_gssapikeyexchange_real = $default_sshd_gssapikeyexchange
+  } else {
+    $sshd_gssapikeyexchange_real = $sshd_gssapikeyexchange
+  }
 
-#    @file { "/etc/denyhosts.conf":
-#        notify => Service["denyhosts"],
-#        require => Package["denyhosts"],
-#        source => [
-#            "puppet://$server/private/$domain/denyhosts/denyhosts.conf",
-#            "puppet://$server/files/denyhosts/denyhosts.conf",
-#            "puppet://$server/denyhosts/denyhosts.conf"
-#        ]
-#    }
+  if $sshd_pamauthenticationviakbdint == 'USE_DEFAULTS' {
+    $sshd_pamauthenticationviakbdint_real = $default_sshd_pamauthenticationviakbdint
+  } else {
+    $sshd_pamauthenticationviakbdint_real = $sshd_pamauthenticationviakbdint
+  }
+
+  if $sshd_gssapicleanupcredentials == 'USE_DEFAULTS' {
+    $sshd_gssapicleanupcredentials_real = $default_sshd_gssapicleanupcredentials
+  } else {
+    $sshd_gssapicleanupcredentials_real = $sshd_gssapicleanupcredentials
+  }
+
+  if $ssh_config_use_roaming == 'USE_DEFAULTS' {
+    $ssh_config_use_roaming_real = $default_ssh_config_use_roaming
+  } else {
+    $ssh_config_use_roaming_real = $ssh_config_use_roaming
+  }
+
+  if $ssh_config_include == 'USE_DEFAULTS' {
+    $ssh_config_include_real = $default_ssh_config_include
+  } else {
+    case type3x($ssh_config_include) {
+      'array': {
+        validate_array($ssh_config_include)
+      }
+      'string': {
+        validate_string($ssh_config_include)
+      }
+      default: {
+        fail('ssh::ssh_config_include type must be a strting or array.')
+      }
+    }
+    $ssh_config_include_real = $ssh_config_include
+  }
+
+  if $ssh_sendenv == 'USE_DEFAULTS' {
+    $ssh_sendenv_real = $default_ssh_sendenv
+  } else {
+    case type3x($ssh_sendenv) {
+      'string': {
+        validate_re($ssh_sendenv, '^(true|false)$', "ssh::ssh_sendenv may be either 'true' or 'false' and is set to <${ssh_sendenv}>.")
+        $ssh_sendenv_real = str2bool($ssh_sendenv)
+      }
+      'boolean': {
+        $ssh_sendenv_real = $ssh_sendenv
+      }
+      default: {
+        fail('ssh::ssh_sendenv type must be true or false.')
+      }
+    }
+  }
+
+  if $sshd_acceptenv == 'USE_DEFAULTS' {
+    $sshd_acceptenv_real = $default_sshd_acceptenv
+  } else {
+    case type3x($sshd_acceptenv) {
+      'string': {
+        validate_re($sshd_acceptenv, '^(true|false)$', "ssh::sshd_acceptenv may be either 'true' or 'false' and is set to <${sshd_acceptenv}>.")
+        $sshd_acceptenv_real = str2bool($sshd_acceptenv)
+      }
+      'boolean': {
+        $sshd_acceptenv_real = $sshd_acceptenv
+      }
+      default: {
+        fail('ssh::sshd_acceptenv type must be true or false.')
+      }
+    }
+  }
+
+  if $sshd_config_hostkey == 'USE_DEFAULTS' {
+    $sshd_config_hostkey_real = $default_sshd_config_hostkey
+  } else {
+    validate_array($sshd_config_hostkey)
+    validate_absolute_path($sshd_config_hostkey)
+    $sshd_config_hostkey_real = $sshd_config_hostkey
+  }
+
+  if $sshd_listen_address {
+    validate_array($sshd_listen_address)
+  }
+
+  if $service_hasstatus == 'USE_DEFAULTS' {
+    $service_hasstatus_real = $default_service_hasstatus
+  } else {
+    case type3x($service_hasstatus) {
+      'string': {
+        validate_re($service_hasstatus, '^(true|false)$', "ssh::service_hasstatus must be 'true' or 'false' and is set to <${service_hasstatus}>.")
+        $service_hasstatus_real = str2bool($service_hasstatus)
+      }
+      'boolean': {
+        $service_hasstatus_real = $service_hasstatus
+      }
+      default: {
+        fail('ssh::service_hasstatus must be true or false.')
+      }
+    }
+  }
+
+  if $sshd_addressfamily == 'USE_DEFAULTS' {
+    $sshd_addressfamily_real = $default_sshd_addressfamily
+  } else {
+    $sshd_addressfamily_real = $sshd_addressfamily
+  }
+
+  if $sshd_config_include == 'USE_DEFAULTS' {
+    $sshd_config_include_real = $default_sshd_config_include
+  } else {
+    case type3x($sshd_config_include) {
+      'array': {
+        validate_array($sshd_config_include)
+      }
+      'string': {
+        validate_string($sshd_config_include)
+      }
+      default: {
+        fail('ssh::sshd_config_include type must be a strting or array.')
+      }
+    }
+    $sshd_config_include_real = $sshd_config_include
+  }
+
+  case $sshd_config_maxsessions {
+    'unset', undef: { $sshd_config_maxsessions_integer = undef }
+    default:        { $sshd_config_maxsessions_integer = floor($sshd_config_maxsessions) }
+  }
+
+  case $sshd_config_tcp_keepalive {
+    'unset': { $sshd_config_tcp_keepalive_real = undef }
+    undef:   { $sshd_config_tcp_keepalive_real = $default_sshd_config_tcp_keepalive }
+    default: { $sshd_config_tcp_keepalive_real = $sshd_config_tcp_keepalive }
+  }
+
+  case $sshd_config_permittunnel {
+    'unset': { $sshd_config_permittunnel_real = undef }
+    undef:   { $sshd_config_permittunnel_real = $default_sshd_config_permittunnel }
+    default: { $sshd_config_permittunnel_real = $sshd_config_permittunnel }
+  }
+
+  case $sshd_config_hostcertificate {
+    'unset', undef: { $sshd_config_hostcertificate_real = undef }
+    default: { $sshd_config_hostcertificate_real = $sshd_config_hostcertificate }
+  }
+
+  case $sshd_config_trustedusercakeys {
+    'unset', undef: { $sshd_config_trustedusercakeys_real = undef }
+    default: { $sshd_config_trustedusercakeys_real = $sshd_config_trustedusercakeys }
+  }
+
+  case $sshd_config_key_revocation_list {
+    'unset', undef: { $sshd_config_key_revocation_list_real = undef }
+    default: { $sshd_config_key_revocation_list_real = $sshd_config_key_revocation_list }
+  }
+
+  case $sshd_config_authorized_principals_file {
+    'unset', undef: { $sshd_config_authorized_principals_file_real = undef }
+    default: { $sshd_config_authorized_principals_file_real = $sshd_config_authorized_principals_file }
+  }
+
+  # validate params
+  if $ssh_config_ciphers != undef {
+    validate_array($ssh_config_ciphers)
+  }
+
+  if $sshd_config_ciphers != undef {
+    validate_array($sshd_config_ciphers)
+  }
+
+  if $ssh_config_kexalgorithms != undef {
+    validate_array($ssh_config_kexalgorithms)
+  }
+
+  if $sshd_config_kexalgorithms != undef {
+    validate_array($sshd_config_kexalgorithms)
+  }
+
+  if $ssh_config_macs != undef {
+    validate_array($ssh_config_macs)
+  }
+
+  if $sshd_config_macs != undef {
+    validate_array($sshd_config_macs)
+  }
+
+  if $ssh_config_hash_known_hosts_real != undef {
+    validate_re($ssh_config_hash_known_hosts_real, '^(yes|no)$', "ssh::ssh_config_hash_known_hosts may be either 'yes', 'no' or 'unset' and is set to <${ssh_config_hash_known_hosts_real}>.")
+  }
+  if $sshd_config_permitemptypasswords != undef {
+    validate_re($sshd_config_permitemptypasswords, '^(yes|no)$', "ssh::sshd_config_permitemptypasswords may be either 'yes' or 'no' and is set to <${sshd_config_permitemptypasswords}>.")
+  }
+  if $sshd_config_permituserenvironment != undef {
+    validate_re($sshd_config_permituserenvironment, '^(yes|no)$', "ssh::sshd_config_permituserenvironment may be either 'yes' or 'no' and is set to <${sshd_config_permituserenvironment}>.")
+  }
+  if $sshd_config_compression != undef {
+    validate_re($sshd_config_compression, '^(yes|no|delayed)$', "ssh::sshd_config_compression may be either 'yes', 'no' or 'delayed' and is set to <${sshd_config_compression}>.")
+  }
+  case type3x($sshd_config_port) {
+    'string': {
+      validate_re($sshd_config_port, '^\d+$', "ssh::sshd_config_port must be a valid number and is set to <${sshd_config_port}>.")
+      $sshd_config_port_array = [ str2num($sshd_config_port) ]
+    }
+    'array': {
+      $sshd_config_port_array = $sshd_config_port
+    }
+    'integer': {
+      $sshd_config_port_array = [ $sshd_config_port ]
+    }
+    default: {
+      fail('ssh:sshd_config_port must be a string, an integer or an array. ')
+    }
+  }
+  validate_numeric($sshd_config_port_array, 65535, 1)
+  if $sshd_kerberos_authentication != undef {
+    validate_re($sshd_kerberos_authentication, '^(yes|no)$', "ssh::sshd_kerberos_authentication may be either 'yes' or 'no' and is set to <${sshd_kerberos_authentication}>.")
+  }
+  validate_re($sshd_password_authentication, '^(yes|no)$', "ssh::sshd_password_authentication may be either 'yes' or 'no' and is set to <${sshd_password_authentication}>.")
+  validate_re($sshd_allow_tcp_forwarding, '^(yes|no)$', "ssh::sshd_allow_tcp_forwarding may be either 'yes' or 'no' and is set to <${sshd_allow_tcp_forwarding}>.")
+  validate_re($sshd_x11_forwarding, '^(yes|no)$', "ssh::sshd_x11_forwarding may be either 'yes' or 'no' and is set to <${sshd_x11_forwarding}>.")
+  validate_re($sshd_x11_use_localhost, '^(yes|no)$', "ssh::sshd_x11_use_localhost may be either 'yes' or 'no' and is set to <${sshd_x11_use_localhost}>.")
+  if $sshd_config_print_last_log != undef {
+    validate_re($sshd_config_print_last_log, '^(yes|no)$', "ssh::sshd_config_print_last_log may be either 'yes' or 'no' and is set to <${sshd_config_print_last_log}>.")
+  }
+  if $sshd_use_pam_real != undef {
+    validate_re($sshd_use_pam_real, '^(yes|no)$', "ssh::sshd_use_pam may be either 'yes' or 'no' and is set to <${sshd_use_pam_real}>.")
+  }
+  if $sshd_config_serverkeybits_real != undef {
+    if is_integer($sshd_config_serverkeybits_real) == false { fail("ssh::sshd_config_serverkeybits must be an integer and is set to <${sshd_config_serverkeybits}>.") }
+  }
+  if $ssh_config_use_roaming_real != undef {
+    validate_re($ssh_config_use_roaming_real, '^(yes|no|unset)$', "ssh::ssh_config_use_roaming may be either 'yes', 'no' or 'unset' and is set to <${$ssh_config_use_roaming}>.")
+  }
+  if is_integer($sshd_client_alive_interval) == false { fail("ssh::sshd_client_alive_interval must be an integer and is set to <${sshd_client_alive_interval}>.") }
+  if is_integer($sshd_client_alive_count_max) == false { fail("ssh::sshd_client_alive_count_max must be an integer and is set to <${sshd_client_alive_count_max}>.") }
+
+  if $sshd_config_banner != 'none' {
+    validate_absolute_path($sshd_config_banner)
+  }
+  if $sshd_banner_content != undef and $sshd_config_banner == 'none' {
+    fail('ssh::sshd_config_banner must be set to be able to use sshd_banner_content.')
+  }
+
+  validate_re($ssh_gssapiauthentication, '^(yes|no)$', "ssh::ssh_gssapiauthentication may be either 'yes' or 'no' and is set to <${ssh_gssapiauthentication}>.")
+
+  if $ssh_gssapidelegatecredentials != undef {
+    validate_re($ssh_gssapidelegatecredentials, '^(yes|no)$', "ssh::ssh_gssapidelegatecredentials may be either 'yes' or 'no' and is set to <${ssh_gssapidelegatecredentials}>.")
+  }
+
+  validate_re($sshd_gssapiauthentication, '^(yes|no)$', "ssh::sshd_gssapiauthentication may be either 'yes' or 'no' and is set to <${sshd_gssapiauthentication}>.")
+
+  if $sshd_gssapikeyexchange_real != undef {
+    validate_re($sshd_gssapikeyexchange_real, '^(yes|no)$', "ssh::sshd_gssapikeyexchange may be either 'yes' or 'no' and is set to <${sshd_gssapikeyexchange_real}>.")
+  }
+
+  if $sshd_pamauthenticationviakbdint_real != undef {
+    validate_re($sshd_pamauthenticationviakbdint_real, '^(yes|no)$', "ssh::sshd_pamauthenticationviakbdint may be either 'yes' or 'no' and is set to <${sshd_pamauthenticationviakbdint_real}>.")
+  }
+
+  if $sshd_gssapicleanupcredentials_real != undef {
+    validate_re($sshd_gssapicleanupcredentials_real, '^(yes|no)$', "ssh::sshd_gssapicleanupcredentials may be either 'yes' or 'no' and is set to <${sshd_gssapicleanupcredentials_real}>.")
+  }
+
+  if $ssh_strict_host_key_checking != undef {
+    validate_re($ssh_strict_host_key_checking, '^(yes|no|ask)$', "ssh::ssh_strict_host_key_checking may be 'yes', 'no' or 'ask' and is set to <${ssh_strict_host_key_checking}>.")
+  }
+
+  if $ssh_config_proxy_command != undef {
+    validate_string($ssh_config_proxy_command)
+  }
+
+  if $ssh_enable_ssh_keysign != undef {
+    validate_re($ssh_enable_ssh_keysign, '^(yes|no)$', "ssh::ssh_enable_ssh_keysign may be either 'yes' or 'no' and is set to <${ssh_enable_ssh_keysign}>.")
+  }
+
+  if $sshd_config_authkey_location != undef {
+    validate_string($sshd_config_authkey_location)
+  }
+
+  if $sshd_config_maxauthtries != undef {
+    if is_integer($sshd_config_maxauthtries) == false {
+      fail("ssh::sshd_config_maxauthtries must be a valid number and is set to <${sshd_config_maxauthtries}>.")
+    }
+  }
+
+  if $sshd_config_maxstartups != undef {
+    validate_re($sshd_config_maxstartups,'^((\d+)|(\d+?:\d+?:\d+)?)$',
+      "ssh::sshd_config_maxstartups may be either an integer or three integers separated with colons, such as 10:30:100. Detected value is <${sshd_config_maxstartups}>.")
+  }
+
+  if $sshd_config_chrootdirectory != undef {
+    validate_absolute_path($sshd_config_chrootdirectory)
+  }
 
-    @file { "/etc/ssh/ssh_config":
-        owner => "root",
-        mode => '0644',
-        require => Package["openssh-clients"],
-        source => [
-            #
-            # See rationale for an explanation on this list of sources
-            # http://reductivelabs.com/trac/puppet/wiki/PuppetCommonModules/SSH
-            #
-           "puppet://$server/private/$domain/ssh/$operatingsystem/$osver/ssh_config.$hostname",
-            "puppet://$server/private/$domain/ssh/$operatingsystem/$osver/ssh_config",
-            "puppet://$server/private/$domain/ssh/$operatingsystem/ssh_config.$hostname",
-            "puppet://$server/private/$domain/ssh/$operatingsystem/ssh_config",
-            "puppet://$server/private/$domain/ssh/ssh_config.$hostname",
-            "puppet://$server/private/$domain/ssh/ssh_config",
-            "puppet://$server/files/ssh/$operatingsystem/$osver/ssh_config.$hostname",
-            "puppet://$server/files/ssh/$operatingsystem/$osver/ssh_config",
-            "puppet://$server/files/ssh/$operatingsystem/ssh_config.$hostname",
-            "puppet://$server/files/ssh/$operatingsystem/ssh_config",
-            "puppet://$server/files/ssh/ssh_config.$hostname",
-            "puppet://$server/files/ssh/ssh_config",
-            "puppet://$server/ssh/$operatingsystem/$osver/ssh_config",
-            "puppet://$server/ssh/$operatingsystem/ssh_config",
-            "puppet://$server/ssh/ssh_config"
-        ],
-        sourceselect => first
+  if $sshd_config_forcecommand != undef {
+    validate_string($sshd_config_forcecommand)
+  }
+
+  if $sshd_authorized_keys_command != undef {
+    validate_absolute_path($sshd_authorized_keys_command)
+  }
+
+  if $sshd_authorized_keys_command_user != undef {
+    validate_string($sshd_authorized_keys_command_user)
+  }
+
+  if $sshd_config_match != undef {
+    validate_hash($sshd_config_match)
+  }
+
+  if $sshd_config_strictmodes != undef {
+    validate_re($sshd_config_strictmodes, '^(yes|no)$', "ssh::sshd_config_strictmodes may be either 'yes' or 'no' and is set to <${sshd_config_strictmodes}>.")
+  }
+  if $ssh_hostbasedauthentication != undef {
+    validate_re($ssh_hostbasedauthentication, '^(yes|no)$', "ssh::ssh_hostbasedauthentication may be either 'yes' or 'no' and is set to <${ssh_hostbasedauthentication}>.")
+  }
+
+  validate_re($sshd_hostbasedauthentication, '^(yes|no)$', "ssh::sshd_hostbasedauthentication may be either 'yes' or 'no' and is set to <${sshd_hostbasedauthentication}>.")
+
+  if $sshd_pubkeyacceptedkeytypes != undef {
+    validate_array($sshd_pubkeyacceptedkeytypes)
+  }
+
+  if $sshd_config_authenticationmethods != undef {
+    validate_array($sshd_config_authenticationmethods)
+  }
+
+  validate_re($sshd_pubkeyauthentication, '^(yes|no)$', "ssh::sshd_pubkeyauthentication may be either 'yes' or 'no' and is set to <${sshd_pubkeyauthentication}>.")
+
+  validate_re($sshd_ignoreuserknownhosts, '^(yes|no)$', "ssh::sshd_ignoreuserknownhosts may be either 'yes' or 'no' and is set to <${sshd_ignoreuserknownhosts}>.")
+
+  validate_re($sshd_ignorerhosts, '^(yes|no)$', "ssh::sshd_ignorerhosts may be either 'yes' or 'no' and is set to <${sshd_ignorerhosts}>.")
+
+  case type3x($hiera_merge) {
+    'string': {
+      validate_re($hiera_merge, '^(true|false)$', "ssh::hiera_merge may be either 'true' or 'false' and is set to <${hiera_merge}>.")
+      $hiera_merge_real = str2bool($hiera_merge)
+    }
+    'boolean': {
+      $hiera_merge_real = $hiera_merge
+    }
+    default: {
+      fail('ssh::hiera_merge type must be true or false.')
+    }
+  }
+
+  case type3x($ssh_key_import) {
+    'string': {
+      validate_re($ssh_key_import, '^(true|false)$', "ssh::ssh_key_import may be either 'true' or 'false' and is set to <${ssh_key_import}>.")
+      $ssh_key_import_real = str2bool($ssh_key_import)
+    }
+    'boolean': {
+      $ssh_key_import_real = $ssh_key_import
+    }
+    default: {
+      fail('ssh::ssh_key_import type must be true or false.')
+    }
+  }
+  validate_bool($ssh_key_import_real)
+
+  case type3x($ssh_config_sendenv_xmodifiers) {
+    'string': {
+      $ssh_config_sendenv_xmodifiers_real = str2bool($ssh_config_sendenv_xmodifiers)
+    }
+    'boolean': {
+      $ssh_config_sendenv_xmodifiers_real = $ssh_config_sendenv_xmodifiers
+    }
+    default: {
+      fail('ssh::ssh_config_sendenv_xmodifiers type must be true or false.')
+    }
+  }
+
+  case $permit_root_login {
+    'no', 'yes', 'without-password', 'forced-commands-only': {
+      # noop
+    }
+    default: {
+      fail("ssh::permit_root_login may be either 'yes', 'without-password', 'forced-commands-only' or 'no' and is set to <${permit_root_login}>.")
+    }
+  }
+
+  case $ssh_key_type {
+    'ssh-rsa','rsa': {
+      $key = $::sshrsakey
+    }
+    'ssh-dsa','dsa': {
+      $key = $::sshdsakey
+    }
+    'ecdsa-sha2-nistp256': {
+          $key = $::sshecdsakey
+    }
+    default: {
+      fail("ssh::ssh_key_type must be 'ecdsa-sha2-nistp256', 'ssh-rsa', 'rsa', 'ssh-dsa', or 'dsa' and is <${ssh_key_type}>.")
+    }
+  }
+
+  validate_absolute_path($ssh_config_global_known_hosts_file)
+  $ssh_config_global_known_hosts_file_real = any2array($ssh_config_global_known_hosts_file)
+
+  if $ssh_config_global_known_hosts_list != undef {
+    validate_array($ssh_config_global_known_hosts_list)
+    validate_absolute_path($ssh_config_global_known_hosts_list)
+    $ssh_config_global_known_hosts_list_real = concat($ssh_config_global_known_hosts_file_real, $ssh_config_global_known_hosts_list)
+  } else {
+    $ssh_config_global_known_hosts_list_real = $ssh_config_global_known_hosts_file_real
+  }
+
+  if $ssh_config_user_known_hosts_file != undef {
+    validate_array($ssh_config_user_known_hosts_file)
+  }
+
+  validate_string($ssh_config_global_known_hosts_owner)
+  validate_string($ssh_config_global_known_hosts_group)
+  validate_re($ssh_config_global_known_hosts_mode, '^[0-7]{4}$',
+    "ssh::ssh_config_global_known_hosts_mode must be a valid 4 digit mode in octal notation. Detected value is <${ssh_config_global_known_hosts_mode}>.")
+
+  if type3x($purge_keys) == 'string' {
+    $purge_keys_real = str2bool($purge_keys)
+  } else {
+    $purge_keys_real = $purge_keys
+  }
+  validate_bool($purge_keys_real)
+
+  if type3x($manage_service) == 'string' {
+    $manage_service_real = str2bool($manage_service)
+  } else {
+    $manage_service_real = $manage_service
+  }
+  validate_bool($manage_service_real)
+
+  if type3x($service_enable) == 'string' {
+    $service_enable_real = str2bool($service_enable)
+  } else {
+    $service_enable_real = $service_enable
+  }
+  validate_bool($service_enable_real)
+
+  if type3x($service_hasrestart) == 'string' {
+    $service_hasrestart_real = str2bool($service_hasrestart)
+  } else {
+    $service_hasrestart_real = $service_hasrestart
+  }
+  validate_bool($service_hasrestart_real)
+
+  if type3x($manage_root_ssh_config) == 'string' {
+    $manage_root_ssh_config_real = str2bool($manage_root_ssh_config)
+  } else {
+    $manage_root_ssh_config_real = $manage_root_ssh_config
+  }
+  validate_bool($manage_root_ssh_config_real)
+
+  #ssh_config template
+  validate_string($ssh_config_template)
+
+  #sshd_config template
+  validate_string($sshd_config_template)
+
+  #loglevel
+  $supported_loglevel_vals=['QUIET', 'FATAL', 'ERROR', 'INFO', 'VERBOSE']
+  validate_re($sshd_config_loglevel, $supported_loglevel_vals)
+
+  #enable hiera merging for groups, users, and config_entries
+  if $hiera_merge_real == true {
+    $sshd_config_allowgroups_real = hiera_array('ssh::sshd_config_allowgroups',[])
+    $sshd_config_allowusers_real  = hiera_array('ssh::sshd_config_allowusers',[])
+    $sshd_config_denygroups_real  = hiera_array('ssh::sshd_config_denygroups',[])
+    $sshd_config_denyusers_real   = hiera_array('ssh::sshd_config_denyusers',[])
+    $config_entries_real          = hiera_hash('ssh::config_entries',{})
+  } else {
+    $sshd_config_allowgroups_real = $sshd_config_allowgroups
+    $sshd_config_allowusers_real  = $sshd_config_allowusers
+    $sshd_config_denygroups_real  = $sshd_config_denygroups
+    $sshd_config_denyusers_real   = $sshd_config_denyusers
+    $config_entries_real          = $config_entries
+  }
+  validate_hash($config_entries_real)
+
+  if $sshd_config_denyusers_real != [] {
+    validate_array($sshd_config_denyusers_real)
+  }
+
+  if $sshd_config_denygroups_real != [] {
+    validate_array($sshd_config_denygroups_real)
+  }
+
+  if $sshd_config_allowusers_real != [] {
+    validate_array($sshd_config_allowusers_real)
+  }
+
+  if $sshd_config_allowgroups_real != [] {
+    validate_array($sshd_config_allowgroups_real)
+  }
+
+
+  if $sshd_config_tcp_keepalive_real != undef {
+    validate_re($sshd_config_tcp_keepalive_real, '^(yes|no)$', "ssh::sshd_config_tcp_keepalive may be either 'yes', 'no' or 'unset' and is set to <${sshd_config_tcp_keepalive_real}>.")
+  }
+
+  if $sshd_config_use_privilege_separation != undef {
+    validate_re($sshd_config_use_privilege_separation, '^(yes|no|sandbox)$', "ssh::sshd_config_use_privilege_separation may be either 'yes', 'no' or 'sandbox' and is set to <${sshd_config_use_privilege_separation}>.")
+  }
+
+  if $sshd_config_permittunnel_real != undef {
+    validate_re($sshd_config_permittunnel_real, '^(yes|no|point-to-point|ethernet|unset)$', "ssh::sshd_config_permittunnel may be either 'yes', 'point-to-point', 'ethernet', 'no' or 'unset' and is set to <${sshd_config_permittunnel_real}>.")
+  }
+
+  if $sshd_config_hostcertificate_real != undef {
+    if is_array($sshd_config_hostcertificate_real) {
+      validate_array($sshd_config_hostcertificate_real)
+    }
+    validate_absolute_path($sshd_config_hostcertificate_real)
+  }
+
+  if $sshd_config_trustedusercakeys_real != undef {
+    # TrustedUserCAKeys may be a path to the keys or 'none'
+    if $sshd_config_trustedusercakeys_real != 'none' {
+      validate_absolute_path($sshd_config_trustedusercakeys_real)
+    }
+  }
+  if $sshd_config_key_revocation_list_real != undef {
+    # RevokedKeys may be a path to the key revocation list or 'none'
+    if $sshd_config_key_revocation_list_real != 'none' {
+      validate_absolute_path($sshd_config_key_revocation_list)
+    }
+  }
+
+  if $sshd_config_authorized_principals_file_real != undef {
+    validate_string($sshd_config_authorized_principals_file_real)
+  }
+
+  if $sshd_config_allowagentforwarding != undef {
+    validate_re($sshd_config_allowagentforwarding, '^(yes|no)$', "ssh::sshd_config_allowagentforwarding may be either 'yes' or 'no' and is set to <${sshd_config_allowagentforwarding}>.")
+  }
+
+  package { $packages_real:
+    ensure    => installed,
+    source    => $ssh_package_source_real,
+    adminfile => $ssh_package_adminfile_real,
+  }
+
+  file  { 'ssh_config' :
+    ensure  => file,
+    path    => $ssh_config_path,
+    owner   => $ssh_config_owner,
+    group   => $ssh_config_group,
+    mode    => $ssh_config_mode,
+    content => template($ssh_config_template),
+    require => Package[$packages_real],
+  }
+
+  file  { 'sshd_config' :
+    ensure  => file,
+    path    => $sshd_config_path,
+    mode    => $sshd_config_mode_real,
+    owner   => $sshd_config_owner,
+    group   => $sshd_config_group,
+    content => template($sshd_config_template),
+    require => Package[$packages_real],
+  }
+
+  if $sshd_config_banner != 'none' and $sshd_banner_content != undef {
+    file { 'sshd_banner' :
+      ensure  => file,
+      path    => $sshd_config_banner,
+      owner   => $sshd_banner_owner,
+      group   => $sshd_banner_group,
+      mode    => $sshd_banner_mode,
+      content => $sshd_banner_content,
+      require => Package[$packages_real],
+    }
+  }
+
+  if $manage_root_ssh_config_real == true {
+
+    include ::common
+
+    common::mkdir_p { "${::root_home}/.ssh": }
+
+    file { 'root_ssh_dir':
+      ensure  => directory,
+      path    => "${::root_home}/.ssh",
+      owner   => 'root',
+      group   => 'root',
+      mode    => '0700',
+      require => Common::Mkdir_p["${::root_home}/.ssh"],
     }
 
-    @file { "/etc/ssh/sshd_config":
-        owner => "root",
-        mode => '0644',
-        notify => Service["openssh-server"],
-        require => Package["openssh-server"],
-        source => [
-            #
-            # See rationale for an explanation on this list of sources
-            # http://reductivelabs.com/trac/puppet/wiki/PuppetCommonModules/SSH
-            #
-            "puppet://$server/private/$domain/ssh/$operatingsystem/$osver/sshd_config.$hostname",
-            "puppet://$server/private/$domain/ssh/$operatingsystem/$osver/sshd_config",
-            "puppet://$server/private/$domain/ssh/$operatingsystem/sshd_config.$hostname",
-            "puppet://$server/private/$domain/ssh/$operatingsystem/sshd_config",
-            "puppet://$server/private/$domain/ssh/sshd_config.$hostname",
-            "puppet://$server/private/$domain/ssh/sshd_config",
-            "puppet://$server/files/ssh/$operatingsystem/$osver/sshd_config.$hostname",
-            "puppet://$server/files/ssh/$operatingsystem/$osver/sshd_config",
-            "puppet://$server/files/ssh/$operatingsystem/sshd_config.$hostname",
-            "puppet://$server/files/ssh/$operatingsystem/sshd_config",
-            "puppet://$server/files/ssh/sshd_config.$hostname",
-            "puppet://$server/files/ssh/sshd_config",
-            "puppet://$server/ssh/$operatingsystem/$osver/sshd_config",
-            "puppet://$server/ssh/$operatingsystem/sshd_config",
-            "puppet://$server/ssh/sshd_config"
-        ],
-        sourceselect => first
+    file { 'root_ssh_config':
+      ensure  => file,
+      path    => "${::root_home}/.ssh/config",
+      content => $root_ssh_config_content,
+      owner   => 'root',
+      group   => 'root',
+      mode    => '0600',
+    }
+  }
+
+  if $manage_service_real {
+    service { 'sshd_service' :
+      ensure     => $service_ensure,
+      name       => $service_name_real,
+      enable     => $service_enable_real,
+      hasrestart => $service_hasrestart_real,
+      hasstatus  => $service_hasstatus_real,
+      subscribe  => File['sshd_config'],
     }
+  }
 
-    @service { "openssh-server":
-        enable => true,
-        ensure => running,
-        require => [
-            File["/etc/ssh/sshd_config"],
+  if $manage_firewall == true {
+    firewall { '22 open port 22 for SSH':
+      action => 'accept',
+      dport  => 22,
+      proto  => 'tcp',
+    }
+  }
+
+  # If either IPv4 or IPv6 stack is not configured on the agent, the
+  # corresponding $::ipaddress(6)? fact is not present. So, we cannot assume
+  # these variables are defined. Getvar (Stdlib 4.13+, ruby 1.8.7+) handles
+  # this correctly.
+  if getvar('::ipaddress') and getvar('::ipaddress6') { $host_aliases = [$::hostname, $::ipaddress, $::ipaddress6] }
+  elsif getvar('::ipaddress6') { $host_aliases = [$::hostname, $::ipaddress6] }
+  else { $host_aliases = [$::hostname, $::ipaddress] }
+
+  # export each node's ssh key
+  @@sshkey { $::fqdn :
+    ensure       => $ssh_key_ensure,
+    host_aliases => $host_aliases,
+    type         => $ssh_key_type,
+    key          => $key,
+  }
 
-            Package["openssh-server"]
-        ]
-    }
-
+  file { 'ssh_known_hosts':
+    ensure  => file,
+    path    => $ssh_config_global_known_hosts_file,
+    owner   => $ssh_config_global_known_hosts_owner,
+    group   => $ssh_config_global_known_hosts_group,
+    mode    => $ssh_config_global_known_hosts_mode,
+    require => Package[$packages_real],
+  }
 
-    # Include operatingsystem specific subclass
-    case $::osfamily {
-        'Redhat': {
-            include ssh::centos
-        }
-        default:{fail("Invalid OS type for SSH - $osfamily")}
+  # import all nodes' ssh keys
+  if $ssh_key_import_real == true {
+    Sshkey <<||>> {
+      target => $ssh_config_global_known_hosts_file,
     }
-}
+  }
 
-class ssh::client inherits ssh {
-    realize(Package["openssh-clients"])
-}
+  # remove ssh key's not managed by puppet
+  resources  { 'sshkey':
+    purge => $purge_keys_real,
+  }
 
-class ssh::server inherits ssh {
-    realize(File["/etc/ssh/sshd_config"])
-    realize(Package["openssh-server"])
-    realize(Service["openssh-server"])
-}
+  # manage users' ssh config entries if present
+  create_resources('ssh::config_entry',$config_entries_real)
 
-class ssh::centos inherits ssh {
-    File["/etc/ssh/ssh_config"] {
-        group => "root"
+  # manage users' ssh authorized keys if present
+  if $keys != undef {
+    if $hiera_merge_real == true {
+      $keys_real = hiera_hash('ssh::keys')
+    } else {
+      $keys_real = $keys
+      notice('Future versions of the ssh module will default ssh::hiera_merge_real to true')
     }
+    validate_hash($keys_real)
+    create_resources('ssh_authorized_key', $keys_real)
+  }
 
-    Service["openssh-server"] {
-        name => "sshd",
-        hasrestart => true,
-        hasstatus => true,
-#        restart => "/etc/init.d/sshd restart",
-#        status => "/etc/init.d/sshd status"
+  if $sshd_addressfamily_real != undef {
+    if $::osfamily == 'Solaris' {
+      fail("ssh::sshd_addressfamily is not supported on Solaris and is set to <${sshd_addressfamily}>.")
+    } else {
+      validate_re($sshd_addressfamily_real, '^(any|inet|inet6)$',
+        "ssh::sshd_addressfamily can be undef, 'any', 'inet' or 'inet6' and is set to ${sshd_addressfamily_real}.")
     }
+  }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/metadata.json	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,117 @@
+{
+  "name": "ghoneycutt-ssh",
+  "version": "3.62.0",
+  "author": "ghoneycutt",
+  "summary": "Manages SSH",
+  "license": "Apache-2.0",
+  "source": "git://github.com/ghoneycutt/puppet-module-ssh.git",
+  "project_page": "https://github.com/ghoneycutt/puppet-module-ssh",
+  "issues_url": "https://github.com/ghoneycutt/puppet-module-ssh/issues",
+  "dependencies": [
+    {
+      "name": "puppetlabs/stdlib",
+      "version_requirement": ">= 4.6.0 < 7.0.0"
+    },
+    {
+      "name": "puppetlabs/concat",
+      "version_requirement": ">= 2.0.0 < 7.0.0"
+    },
+    {
+      "name": "ghoneycutt/common",
+      "version_requirement": ">= 1.4.1 < 2.0.0"
+    },
+    {
+      "name": "puppetlabs/firewall",
+      "version_requirement": ">= 1.9.0 < 3.0.0"
+    },
+    {
+      "name": "puppetlabs/sshkeys_core",
+      "version_requirement": ">= 1.0.1 < 3.0.0"
+    }
+  ],
+  "data_provider": null,
+  "requirements": [
+    {
+      "name": "puppet",
+      "version_requirement": ">= 3.8.7 < 7.0.0"
+    }
+  ],
+  "operatingsystem_support": [
+    {
+      "operatingsystem": "Debian",
+      "operatingsystemrelease": [
+        "7",
+        "8",
+        "9",
+        "10"
+      ]
+    },
+    {
+      "operatingsystem": "RedHat",
+      "operatingsystemrelease": [
+        "5",
+        "6",
+        "7"
+      ]
+    },
+    {
+      "operatingsystem": "CentOS",
+      "operatingsystemrelease": [
+        "5",
+        "6",
+        "7"
+      ]
+    },
+    {
+      "operatingsystem": "OracleLinux",
+      "operatingsystemrelease": [
+        "5",
+        "6",
+        "7"
+      ]
+    },
+    {
+      "operatingsystem": "Scientific",
+      "operatingsystemrelease": [
+        "5",
+        "6",
+        "7"
+      ]
+    },
+    {
+      "operatingsystem": "Solaris",
+      "operatingsystemrelease": [
+        "9",
+        "10",
+        "11"
+      ]
+    },
+    {
+      "operatingsystem": "SLES",
+      "operatingsystemrelease": [
+        "10",
+        "11",
+        "12"
+      ]
+    },
+    {
+      "operatingsystem": "SLED",
+      "operatingsystemrelease": [
+        "10",
+        "11",
+        "12"
+      ]
+    },
+    {
+      "operatingsystem": "Ubuntu",
+      "operatingsystemrelease": [
+        "12.04",
+        "14.04",
+        "16.04",
+        "18.04",
+        "20.04"
+      ]
+    }
+  ],
+  "description": "Manage SSH"
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/classes/init_spec.rb	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,2846 @@
+require 'spec_helper'
+
+describe 'ssh' do
+
+  default_facts = {
+    :fqdn                   => 'monkey.example.com',
+    :hostname               => 'monkey',
+    :ipaddress              => '127.0.0.1',
+    :ipaddress6             => nil,
+    :lsbmajdistrelease      => '6',
+    :operatingsystemrelease => '6.7',
+    :osfamily               => 'RedHat',
+    :root_home              => '/root',
+    :specific               => 'dummy',
+    :ssh_version            => 'OpenSSH_6.6p1',
+    :ssh_version_numeric    => '6.6',
+    :sshrsakey              => 'AAAAB3NzaC1yc2EAAAABIwAAAQEArGElx46pD6NNnlxVaTbp0ZJMgBKCmbTCT3RaeCk0ZUJtQ8wkcwTtqIXmmiuFsynUT0DFSd8UIodnBOPqitimmooAVAiAi30TtJVzADfPScMiUnBJKZajIBkEMkwUcqsfh630jyBvLPE/kyQcxbEeGtbu1DG3monkeymanOBW1AKc5o+cJLXcInLnbowMG7NXzujT3BRYn/9s5vtT1V9cuZJs4XLRXQ50NluxJI7sVfRPVvQI9EMbTS4AFBXUej3yfgaLSV+nPZC/lmJ2gR4t/tKvMFF9m16f8IcZKK7o0rK7v81G/tREbOT5YhcKLK+0wBfR6RsmHzwy4EddZloyLQ==',
+  }
+
+  default_solaris_facts = {
+    :fqdn                => 'monkey.example.com',
+    :hostname            => 'monkey',
+    :ipaddress           => '127.0.0.1',
+    :kernelrelease       => '5.10',
+    :osfamily            => 'Solaris',
+    :root_home           => '/root',
+    :specific            => 'dummy',
+    :ssh_version         => 'Sun_SSH_2.2',
+    :ssh_version_numeric => '2.2',
+    :sshrsakey           => 'AAAAB3NzaC1yc2EAAAABIwAAAQEArGElx46pD6NNnlxVaTbp0ZJMgBKCmbTCT3RaeCk0ZUJtQ8wkcwTtqIXmmiuFsynUT0DFSd8UIodnBOPqitimmooAVAiAi30TtJVzADfPScMiUnBJKZajIBkEMkwUcqsfh630jyBvLPE/kyQcxbEeGtbu1DG3monkeymanOBW1AKc5o+cJLXcInLnbowMG7NXzujT3BRYn/9s5vtT1V9cuZJs4XLRXQ50NluxJI7sVfRPVvQI9EMbTS4AFBXUej3yfgaLSV+nPZC/lmJ2gR4t/tKvMFF9m16f8IcZKK7o0rK7v81G/tREbOT5YhcKLK+0wBfR6RsmHzwy4EddZloyLQ==',
+  }
+
+  let(:facts) { default_facts }
+
+  osfamily_matrix = {
+    'Debian-7' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Debian',
+      :operatingsystemrelease => '7',
+      :ssh_version            => 'OpenSSH_6.0p1',
+      :ssh_version_numeric    => '6.0',
+      :ssh_packages           => ['openssh-server', 'openssh-client'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'ssh',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_debian',
+      :ssh_config_fixture     => 'ssh_config_debian',
+    },
+    'Debian-8' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Debian',
+      :operatingsystemrelease => '8',
+      :ssh_version            => 'OpenSSH_6.7p1',
+      :ssh_version_numeric    => '8.11',
+      :ssh_packages           => ['openssh-server', 'openssh-client'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'ssh',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_debian8',
+      :ssh_config_fixture     => 'ssh_config_debian8',
+    },
+    'Debian-9' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Debian',
+      :operatingsystemrelease => '9',
+      :ssh_version            => 'OpenSSH_7.4p1',
+      :ssh_version_numeric    => '7.4',
+      :ssh_packages           => ['openssh-server', 'openssh-client'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'ssh',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_debian9',
+      :ssh_config_fixture     => 'ssh_config_debian9',
+    },
+    'Debian-10' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Debian',
+      :operatingsystemrelease => '10',
+      :ssh_version            => 'OpenSSH_7.9p1',
+      :ssh_version_numeric    => '7.9',
+      :ssh_packages           => ['openssh-server', 'openssh-client'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'ssh',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_debian10',
+      :ssh_config_fixture     => 'ssh_config_debian10',
+    },
+    'RedHat-5' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'RedHat',
+      :operatingsystemrelease => '5.11',
+      :ssh_version            => 'OpenSSH_4.3p2',
+      :ssh_version_numeric    => '4.3',
+      :ssh_packages           => ['openssh-server', 'openssh-clients'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_rhel',
+      :ssh_config_fixture     => 'ssh_config_rhel_old',
+    },
+    'RedHat-6' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'RedHat',
+      :operatingsystemrelease => '6.7',
+      :ssh_version            => 'OpenSSH_5.3p1',
+      :ssh_version_numeric    => '5.3',
+      :ssh_packages           => ['openssh-server', 'openssh-clients'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_rhel',
+      :ssh_config_fixture     => 'ssh_config_rhel_old',
+    },
+    'RedHat-7' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'RedHat',
+      :operatingsystemrelease => '7.2',
+      :ssh_version            => 'OpenSSH_6.6p1',
+      :ssh_version_numeric    => '6.6',
+      :ssh_packages           => ['openssh-server', 'openssh-clients'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_rhel',
+      :ssh_config_fixture     => 'ssh_config_rhel',
+    },
+    'RedHat-7.4' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'RedHat',
+      :operatingsystemrelease => '7.4',
+      :ssh_version            => 'OpenSSH_6.6p1',
+      :ssh_version_numeric    => '6.6',
+      :ssh_packages           => ['openssh-server', 'openssh-clients'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_rhel7',
+      :ssh_config_fixture     => 'ssh_config_rhel',
+    },
+    'Suse-10-x86_64' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Suse',
+      :operatingsystem        => 'SLES',
+      :operatingsystemrelease => '10.4',
+      :ssh_version            => 'OpenSSH_5.1p1',
+      :ssh_version_numeric    => '5.1',
+      :ssh_packages           => ['openssh'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_suse_x86_64',
+      :ssh_config_fixture     => 'ssh_config_suse_old',
+    },
+    'Suse-10-i386' => {
+      :architecture           => 'i386',
+      :osfamily               => 'Suse',
+      :operatingsystem        => 'SLES',
+      :operatingsystemrelease => '10.4',
+      :ssh_version            => 'OpenSSH_5.1p1',
+      :ssh_version_numeric    => '5.1',
+      :ssh_packages           => ['openssh'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_suse_i386',
+      :ssh_config_fixture     => 'ssh_config_suse_old',
+    },
+    'Suse-11-x86_64' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Suse',
+      :operatingsystem        => 'SLES',
+      :operatingsystemrelease => '11.4',
+      :ssh_version            => 'OpenSSH_6.6.1p1',
+      :ssh_version_numeric    => '6.6',
+      :ssh_packages           => ['openssh'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_suse_x86_64',
+      :ssh_config_fixture     => 'ssh_config_suse',
+    },
+    'Suse-11-i386' => {
+      :architecture           => 'i386',
+      :osfamily               => 'Suse',
+      :operatingsystem        => 'SLES',
+      :operatingsystemrelease => '11.4',
+      :ssh_version            => 'OpenSSH_6.6.1p1',
+      :ssh_version_numeric    => '6.6',
+      :ssh_packages           => ['openssh'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_suse_i386',
+      :ssh_config_fixture     => 'ssh_config_suse',
+    },
+    'Suse-12-x86_64' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Suse',
+      :operatingsystem        => 'SLES',
+      :operatingsystemrelease => '12.0',
+      :ssh_version            => 'OpenSSH_6.6.1p1',
+      :ssh_version_numeric    => '6.6',
+      :ssh_packages           => ['openssh'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_sles_12_x86_64',
+      :ssh_config_fixture     => 'ssh_config_suse',
+    },
+    'Solaris-5.11' => {
+      :architecture           => 'i86pc',
+      :osfamily               => 'Solaris',
+      :kernelrelease          => '5.11',
+      :ssh_version            => 'Sun_SSH_2.2',
+      :ssh_version_numeric    => '2.2',
+      :ssh_packages           => ['network/ssh', 'network/ssh/ssh-key', 'service/network/ssh'],
+      :sshd_config_mode       => '0644',
+      :sshd_service_name      => 'ssh',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_solaris',
+      :ssh_config_fixture     => 'ssh_config_solaris',
+    },
+    'Solaris-5.10' => {
+      :architecture           => 'i86pc',
+      :osfamily               => 'Solaris',
+      :kernelrelease          => '5.10',
+      :ssh_version            => 'Sun_SSH_2.2',
+      :ssh_version_numeric    => '2.2',
+      :ssh_packages           => ['SUNWsshcu', 'SUNWsshdr', 'SUNWsshdu', 'SUNWsshr', 'SUNWsshu'],
+      :sshd_config_mode       => '0644',
+      :sshd_service_name      => 'ssh',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_solaris',
+      :ssh_config_fixture     => 'ssh_config_solaris',
+    },
+    'Solaris-5.9' => {
+      :architecture           => 'i86pc',
+      :osfamily               => 'Solaris',
+      :kernelrelease          => '5.9',
+      :ssh_version            => 'Sun_SSH_2.2',
+      :ssh_version_numeric    => '2.2',
+      :ssh_packages           => ['SUNWsshcu', 'SUNWsshdr', 'SUNWsshdu', 'SUNWsshr', 'SUNWsshu'],
+      :sshd_config_mode       => '0644',
+      :sshd_service_name      => 'sshd',
+      :sshd_service_hasstatus => false,
+      :sshd_config_fixture    => 'sshd_config_solaris',
+      :ssh_config_fixture     => 'ssh_config_solaris',
+    },
+    'Ubuntu-1604' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Debian',
+      :operatingsystemrelease => '16.04',
+      :ssh_version            => 'OpenSSH_7.2p2',
+      :ssh_version_numeric    => '7.2',
+      :ssh_packages           => ['openssh-server', 'openssh-client'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'ssh',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_ubuntu1604',
+      :ssh_config_fixture     => 'ssh_config_ubuntu1604',
+    },
+    'Ubuntu-1804' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Debian',
+      :operatingsystemrelease => '18.04',
+      :ssh_version            => 'OpenSSH_7.6p1',
+      :ssh_version_numeric    => '7.6',
+      :ssh_packages           => ['openssh-server', 'openssh-client'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'ssh',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_ubuntu1804',
+      :ssh_config_fixture     => 'ssh_config_ubuntu1804',
+    },
+    'Ubuntu-2004' => {
+      :architecture           => 'x86_64',
+      :osfamily               => 'Debian',
+      :operatingsystemrelease => '20.04',
+      :ssh_version            => 'OpenSSH_7.6p1',
+      :ssh_version_numeric    => '7.6',
+      :ssh_packages           => ['openssh-server', 'openssh-client'],
+      :sshd_config_mode       => '0600',
+      :sshd_service_name      => 'ssh',
+      :sshd_service_hasstatus => true,
+      :sshd_config_fixture    => 'sshd_config_ubuntu2004',
+      :ssh_config_fixture     => 'ssh_config_ubuntu2004',
+    },
+  }
+
+  osfamily_matrix.each do |os, facts|
+    context "with default params on osfamily #{os}" do
+      let(:facts) { default_facts.merge( facts )}
+
+      it { should compile.with_all_deps }
+
+      it { should contain_class('ssh')}
+
+      it { should_not contain_class('common')}
+
+      facts[:ssh_packages].each do |pkg|
+        it {
+          should contain_package(pkg).with({
+            'ensure' => 'installed',
+          })
+        }
+      end
+
+      it {
+        should contain_file('ssh_known_hosts').with({
+          'ensure' => 'file',
+          'path'   => '/etc/ssh/ssh_known_hosts',
+          'owner'  => 'root',
+          'group'  => 'root',
+          'mode'   => '0644',
+        })
+      }
+
+      facts[:ssh_packages].each do |pkg|
+        it {
+          should contain_file('ssh_known_hosts').that_requires("Package[#{pkg}]")
+        }
+      end
+
+      it {
+        should contain_file('ssh_config').with({
+          'ensure'  => 'file',
+          'path'    => '/etc/ssh/ssh_config',
+          'owner'   => 'root',
+          'group'   => 'root',
+          'mode'    => '0644',
+        })
+      }
+
+      ssh_config_fixture = File.read(fixtures(facts[:ssh_config_fixture]))
+      it { should contain_file('ssh_config').with_content(ssh_config_fixture) }
+
+      facts[:ssh_packages].each do |pkg|
+        it {
+          should contain_file('ssh_config').that_requires("Package[#{pkg}]")
+        }
+      end
+
+      it {
+        should contain_file('sshd_config').with({
+          'ensure'  => 'file',
+          'path'    => '/etc/ssh/sshd_config',
+          'owner'   => 'root',
+          'group'   => 'root',
+          'mode'    => facts[:sshd_config_mode],
+        })
+      }
+
+      facts[:ssh_packages].each do |pkg|
+        it {
+          should contain_file('sshd_config').that_requires("Package[#{pkg}]")
+        }
+      end
+
+      sshd_config_fixture = File.read(fixtures(facts[:sshd_config_fixture]))
+      it { should contain_file('sshd_config').with_content(sshd_config_fixture) }
+
+      it {
+        should contain_service('sshd_service').with({
+          'ensure'     => 'running',
+          'name'       => facts[:sshd_service_name],
+          'enable'     => 'true',
+          'hasrestart' => 'true',
+          'hasstatus'  => facts[:sshd_service_hasstatus],
+          'subscribe'  => 'File[sshd_config]',
+        })
+      }
+
+      it {
+        should contain_resources('sshkey').with({
+          'purge' => 'true',
+        })
+      }
+
+      it { should have_ssh__config_entry_resource_count(0) }
+
+      context 'with exported sshkey resources' do
+        subject { exported_resources}
+        context 'With only IPv4 address' do
+          let(:facts) { default_facts.merge( facts )}
+          it { should contain_sshkey('monkey.example.com').with(
+            'ensure' => 'present',
+            'host_aliases' => ['monkey', '127.0.0.1']
+          )}
+        end
+        context 'With dual stack IP' do
+          let(:facts) { default_facts.merge({ :ipaddress6 => 'dead:beef::1/64' }) }
+          it { should contain_sshkey('monkey.example.com').with(
+            'ensure' => 'present',
+            'host_aliases' => ['monkey', '127.0.0.1', 'dead:beef::1/64']
+          )}
+        end
+        context 'With only IPv6 address' do
+          let(:facts) { default_facts.merge({ :ipaddress6 => 'dead:beef::1/64', :ipaddress => nil }) }
+          it { should contain_sshkey('monkey.example.com').with(
+            'ensure' => 'present',
+            'host_aliases' => ['monkey', 'dead:beef::1/64']
+          )}
+        end
+      end
+
+    end
+  end
+
+  context 'with default params on invalid osfamily' do
+    let(:facts) { default_facts.merge({ :osfamily => 'C64' }) }
+    let(:params) { { :manage_root_ssh_config => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh supports osfamilies RedHat, Suse, Debian and Solaris\. Detected osfamily is <C64>\./)
+    end
+  end
+
+  context 'with optional params used in ssh_config set on valid osfamily' do
+    let(:params) do
+      {
+        :ssh_config_hash_known_hosts        => 'yes',
+        :ssh_config_forward_agent           => 'yes',
+        :ssh_config_forward_x11             => 'yes',
+        :ssh_config_use_roaming             => 'yes',
+        :ssh_config_server_alive_interval   => '300',
+        :ssh_config_sendenv_xmodifiers      => true,
+        :ssh_config_ciphers                 => [ 'aes128-cbc',
+                                                 '3des-cbc',
+                                                 'blowfish-cbc',
+                                                 'cast128-cbc',
+                                                 'arcfour',
+                                                 'aes192-cbc',
+                                                 'aes256-cbc',
+        ],
+        :ssh_config_kexalgorithms          => [ 'curve25519-sha256@libssh.org',
+            'ecdh-sha2-nistp256',
+            'ecdh-sha2-nistp384',
+            'ecdh-sha2-nistp521',
+            'diffie-hellman-group-exchange-sha256',
+            'diffie-hellman-group-exchange-sha1',
+            'diffie-hellman-group14-sha1',
+            'diffie-hellman-group1-sha1',
+  ],
+        :ssh_config_macs                    => [ 'hmac-md5-etm@openssh.com',
+                                                 'hmac-sha1-etm@openssh.com',
+        ],
+        :ssh_config_proxy_command           => 'ssh -W %h:%p firewall.example.org',
+        :ssh_config_global_known_hosts_file => '/etc/ssh/ssh_known_hosts2',
+        :ssh_config_global_known_hosts_list => [ '/etc/ssh/ssh_known_hosts3',
+                   '/etc/ssh/ssh_known_hosts4',
+  ],
+        :ssh_config_user_known_hosts_file   => [ '.ssh/known_hosts1',
+                                                 '.ssh/known_hosts2',
+        ],
+        :ssh_hostbasedauthentication        => 'yes',
+        :ssh_strict_host_key_checking       => 'ask',
+        :ssh_enable_ssh_keysign             => 'yes',
+      }
+    end
+
+    it { should compile.with_all_deps }
+
+    it {
+      should contain_file('ssh_config').with({
+        'ensure'  => 'file',
+        'path'    => '/etc/ssh/ssh_config',
+        'owner'   => 'root',
+        'group'   => 'root',
+        'mode'    => '0644',
+        'require' => ['Package[openssh-server]', 'Package[openssh-clients]'],
+      })
+    }
+
+    it { should contain_file('ssh_config').with_content(/^# This file is being maintained by Puppet.\n# DO NOT EDIT\n\n# \$OpenBSD: ssh_config,v 1.21 2005\/12\/06 22:38:27 reyk Exp \$/) }
+    it { should contain_file('ssh_config').with_content(/^   Protocol 2$/) }
+    it { should contain_file('ssh_config').with_content(/^   HashKnownHosts yes$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*SendEnv L.*$/) }
+    it { should contain_file('ssh_config').with_content(/^  ForwardAgent yes$/) }
+    it { should contain_file('ssh_config').with_content(/^  ForwardX11 yes$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*GSSAPIAuthentication yes$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*UseRoaming yes$/) }
+    it { should contain_file('ssh_config').with_content(/^  ServerAliveInterval 300$/) }
+    it { should contain_file('ssh_config').with_content(/^  SendEnv XMODIFIERS$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*MACs hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*ProxyCommand ssh -W %h:%p firewall\.example\.org$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*GlobalKnownHostsFile \/etc\/ssh\/ssh_known_hosts2 \/etc\/ssh\/ssh_known_hosts3 \/etc\/ssh\/ssh_known_hosts4$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*UserKnownHostsFile \.ssh\/known_hosts1 \.ssh\/known_hosts2$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*HostbasedAuthentication yes$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*StrictHostKeyChecking ask$/) }
+    it { should contain_file('ssh_config').with_content(/^\s*EnableSSHKeysign yes$/) }
+  end
+
+  context 'with params used in sshd_config set on valid osfamily' do
+    let(:params) do
+      {
+        :sshd_config_port                     => '22222',
+        :sshd_config_syslog_facility          => 'DAEMON',
+        :sshd_config_login_grace_time         => '60',
+        :permit_root_login                    => 'no',
+        :sshd_config_chrootdirectory          => '/chrootdir',
+        :sshd_config_forcecommand             => '/force/command --with-parameter 242',
+        :sshd_config_match                    => { 'User JohnDoe' => [ 'AllowTcpForwarding yes', ], },
+        :sshd_config_challenge_resp_auth      => 'no',
+        :sshd_config_print_motd               => 'no',
+  :sshd_config_print_last_log           => 'no',
+        :sshd_config_use_dns                  => 'no',
+        :sshd_config_banner                   => '/etc/sshd_banner',
+        :sshd_authorized_keys_command         => '/path/to/command',
+        :sshd_authorized_keys_command_user    => 'asdf',
+        :sshd_banner_content                  => 'textinbanner',
+        :sshd_config_xauth_location           => '/opt/ssh/bin/xauth',
+        :sshd_config_subsystem_sftp           => '/opt/ssh/bin/sftp',
+        :sshd_kerberos_authentication         => 'no',
+        :sshd_password_authentication         => 'no',
+        :sshd_config_permitemptypasswords     => 'no',
+        :sshd_config_permituserenvironment    => 'no',
+  :sshd_config_compression              => 'no',
+        :sshd_pubkeyacceptedkeytypes          => [ 'ecdsa-sha2-nistp256',
+                                                   'ecdsa-sha2-nistp384',
+                                                   'ecdsa-sha2-nistp521',
+                                                   'ssh-ed25519',
+                                                   'ssh-rsa',
+        ],
+        :sshd_config_authenticationmethods    => [ 'publickey',
+                                                   'keyboard-interactive',
+        ],
+        :sshd_pubkeyauthentication            => 'no',
+        :sshd_allow_tcp_forwarding            => 'no',
+        :sshd_x11_forwarding                  => 'no',
+        :sshd_x11_use_localhost               => 'no',
+        :sshd_use_pam                         => 'no',
+        :sshd_client_alive_interval           => '242',
+        :sshd_config_serverkeybits            => '1024',
+        :sshd_client_alive_count_max          => '0',
+        :sshd_config_authkey_location         => '.ssh/authorized_keys',
+        :sshd_config_hostkey                  => [ '/etc/ssh/ssh_host_rsa_key',
+                                                '/etc/ssh/ssh_host_dsa_key',
+        ],
+        :sshd_config_strictmodes              => 'yes',
+        :sshd_config_ciphers                  => [ 'aes128-cbc',
+                                                   '3des-cbc',
+                                                   'blowfish-cbc',
+                                                   'cast128-cbc',
+                                                   'arcfour',
+                                                   'aes192-cbc',
+                                                   'aes256-cbc',
+        ],
+        :sshd_config_kexalgorithms            => [ 'curve25519-sha256@libssh.org',
+               'ecdh-sha2-nistp256',
+               'ecdh-sha2-nistp384',
+               'ecdh-sha2-nistp521',
+               'diffie-hellman-group-exchange-sha256',
+               'diffie-hellman-group-exchange-sha1',
+               'diffie-hellman-group14-sha1',
+               'diffie-hellman-group1-sha1',
+  ],
+        :sshd_config_macs                     => [ 'hmac-md5-etm@openssh.com',
+                                                   'hmac-sha1-etm@openssh.com',
+        ],
+        :sshd_config_denyusers                => [ 'root',
+                                                   'lusers',
+        ],
+        :sshd_config_denygroups               => [ 'nossh',
+                                                   'wheel',
+        ],
+        :sshd_config_allowusers               => [ 'foo',
+                                                   'bar',
+        ],
+        :sshd_config_allowgroups              => [ 'ssh',
+                                                   'security',
+        ],
+        :sshd_listen_address                  => [ '192.168.1.1',
+                                                   '2001:db8::dead:f00d',
+        ],
+        :sshd_config_tcp_keepalive            => 'yes',
+  :sshd_config_use_privilege_separation => 'no',
+        :sshd_config_permittunnel             => 'no',
+        :sshd_config_allowagentforwarding     => 'no',
+        :sshd_config_key_revocation_list      => '/path/to/revocation_list',
+      }
+    end
+
+    it { should compile.with_all_deps }
+
+    it {
+      should contain_file('sshd_config').with({
+        'ensure'  => 'file',
+        'path'    => '/etc/ssh/sshd_config',
+        'owner'   => 'root',
+        'group'   => 'root',
+        'mode'    => '0600',
+        'require' => ['Package[openssh-server]', 'Package[openssh-clients]'],
+      })
+    }
+
+    it { should contain_file('sshd_config').with_content(/^Port 22222$/) }
+    it { should contain_file('sshd_config').with_content(/^SyslogFacility DAEMON$/) }
+    it { should contain_file('sshd_config').with_content(/^LogLevel INFO$/) }
+    it { should contain_file('sshd_config').with_content(/^LoginGraceTime 60$/) }
+    it { should contain_file('sshd_config').with_content(/^PermitRootLogin no$/) }
+    it { should contain_file('sshd_config').with_content(/^ChallengeResponseAuthentication no$/) }
+    it { should contain_file('sshd_config').with_content(/^PrintMotd no$/) }
+    it { should contain_file('sshd_config').with_content(/^PrintLastLog no$/) }
+    it { should contain_file('sshd_config').with_content(/^UseDNS no$/) }
+    it { should contain_file('sshd_config').with_content(/^Banner \/etc\/sshd_banner$/) }
+    it { should contain_file('sshd_config').with_content(/^XAuthLocation \/opt\/ssh\/bin\/xauth$/) }
+    it { should contain_file('sshd_config').with_content(/^Subsystem sftp \/opt\/ssh\/bin\/sftp$/) }
+    it { should contain_file('sshd_config').with_content(/^PasswordAuthentication no$/) }
+    it { should contain_file('sshd_config').with_content(/^KerberosAuthentication no$/) }
+    it { should contain_file('sshd_config').with_content(/^AllowTcpForwarding no$/) }
+    it { should contain_file('sshd_config').with_content(/^X11Forwarding no$/) }
+    it { should contain_file('sshd_config').with_content(/^X11UseLocalhost no$/) }
+    it { should contain_file('sshd_config').with_content(/^UsePAM no$/) }
+    it { should contain_file('sshd_config').with_content(/^ClientAliveInterval 242$/) }
+    it { should contain_file('sshd_config').with_content(/^ServerKeyBits 1024$/) }
+    it { should contain_file('sshd_config').with_content(/^ClientAliveCountMax 0$/) }
+    it { should contain_file('sshd_config').with_content(/^GSSAPIAuthentication yes$/) }
+    it { should contain_file('sshd_config').with_content(/^GSSAPICleanupCredentials yes$/) }
+    it { should_not contain_file('sshd_config').with_content(/^\s*PAMAuthenticationViaKBDInt yes$/) }
+    it { should_not contain_file('sshd_config').with_content(/^\s*GSSAPIKeyExchange yes$/) }
+    it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) }
+    it { should contain_file('sshd_config').with_content(/^AuthorizedKeysFile .ssh\/authorized_keys/) }
+    it { should contain_file('sshd_config').with_content(/^HostKey \/etc\/ssh\/ssh_host_rsa_key/) }
+    it { should contain_file('sshd_config').with_content(/^HostKey \/etc\/ssh\/ssh_host_dsa_key/) }
+    it { should contain_file('sshd_config').with_content(/^StrictModes yes$/) }
+    it { should contain_file('sshd_config').with_content(/^PermitUserEnvironment no/) }
+    it { should contain_file('sshd_config').with_content(/^Compression no$/) }
+    it { should contain_file('sshd_config').with_content(/^PermitEmptyPasswords no/) }
+    it { should_not contain_file('sshd_config').with_content(/^MaxAuthTries/) }
+    it { should_not contain_file('sshd_config').with_content(/^MaxStartups/) }
+    it { should_not contain_file('sshd_config').with_content(/^MaxSessions/) }
+    it { should contain_file('sshd_config').with_content(/^AuthorizedKeysCommand \/path\/to\/command$/) }
+    it { should contain_file('sshd_config').with_content(/^AuthorizedKeysCommandUser asdf$/) }
+    it { should contain_file('sshd_config').with_content(/^HostbasedAuthentication no$/) }
+    it { should contain_file('sshd_config').with_content(/^PubkeyAcceptedKeyTypes ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,ssh-rsa$/) }
+    it { should contain_file('sshd_config').with_content(/^AuthenticationMethods publickey,keyboard-interactive$/) }
+    it { should contain_file('sshd_config').with_content(/^PubkeyAuthentication no$/) }
+    it { should contain_file('sshd_config').with_content(/^IgnoreUserKnownHosts no$/) }
+    it { should contain_file('sshd_config').with_content(/^IgnoreRhosts yes$/) }
+    it { should contain_file('sshd_config').with_content(/^ChrootDirectory \/chrootdir$/) }
+    it { should contain_file('sshd_config').with_content(/^ForceCommand \/force\/command --with-parameter 242$/) }
+    it { should contain_file('sshd_config').with_content(/^Match User JohnDoe\n  AllowTcpForwarding yes\Z/) }
+    it { should contain_file('sshd_config').with_content(/^\s*Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc$/) }
+    it { should contain_file('sshd_config').with_content(/^\s*KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1$/) }
+    it { should contain_file('sshd_config').with_content(/^\s*MACs hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com$/) }
+    it { should contain_file('sshd_config').with_content(/^\s*DenyUsers root lusers$/) }
+    it { should contain_file('sshd_config').with_content(/^\s*DenyGroups nossh wheel$/) }
+    it { should contain_file('sshd_config').with_content(/^\s*AllowUsers foo bar$/) }
+    it { should contain_file('sshd_config').with_content(/^\s*AllowGroups ssh security$/) }
+    it { should contain_file('sshd_config').with_content(/^ListenAddress 192.168.1.1\nListenAddress 2001:db8::dead:f00d$/) }
+    it { should contain_file('sshd_config').with_content(/^TCPKeepAlive yes$/) }
+    it { should contain_file('sshd_config').with_content(/^UsePrivilegeSeparation no$/) }
+    it { should contain_file('sshd_config').with_content(/^PermitTunnel no$/) }
+    it { should contain_file('sshd_config').with_content(/^RevokedKeys \/path\/to\/revocation_list$/) }
+
+    it {
+      should contain_file('sshd_banner').with({
+        'ensure'  => 'file',
+        'path'    => '/etc/sshd_banner',
+        'owner'   => 'root',
+        'group'   => 'root',
+        'mode'    => '0644',
+        'content' => 'textinbanner',
+        'require' => ['Package[openssh-server]', 'Package[openssh-clients]'],
+      })
+    }
+  end
+
+  describe 'sshd_config_chrootdirectory param' do
+    ['/chrootdir/subdir','/baby/one/more/test',].each do |value|
+      context "set to valid #{value} (as #{value.class})" do
+        let(:params) { {'sshd_config_chrootdirectory' => value } }
+
+        it { should contain_file('sshd_config').with_content(/^ChrootDirectory #{value}$/) }
+      end
+    end
+
+    [true,'invalid','invalid/path/',3,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "set to invalid #{value} (as #{value.class})" do
+        let(:params) { {'sshd_config_chrootdirectory' => value } }
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error, /is not an absolute path/)
+        end
+      end
+    end
+
+  end
+
+  describe 'sshd_config_forcecommand param' do
+    ['/bin/command','/bin/command -parameters','/bin/command --parameters','/bin/command /parameters'].each do |value|
+      context "set to valid #{value} (as #{value.class})" do
+        let(:params) { {'sshd_config_forcecommand' => value } }
+
+        it { should contain_file('sshd_config').with_content(/^ForceCommand #{value}$/) }
+      end
+    end
+
+    [true,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "set to invalid #{value} (as #{value.class})" do
+        let(:params) { {'sshd_config_forcecommand' => value } }
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error, /is not a string/)
+        end
+      end
+    end
+
+  end
+
+  describe 'sshd_config_match param' do
+  # match and rules get alphabetically sorted by template, matches should be the last options in sshd_config (regex verify with= \Z)
+    context 'set to valid hash containing nested arrays' do
+      let(:params) do
+        { :sshd_config_match      => {
+            'User JohnDoe'        => [ 'AllowTcpForwarding yes', ],
+            'Addresss 2.4.2.0'    => [ 'X11Forwarding yes', 'PasswordAuthentication no', ],
+          },
+        }
+      end
+
+      it { should contain_file('sshd_config').with_content(/^Match Addresss 2.4.2.0\n  PasswordAuthentication no\n  X11Forwarding yes\nMatch User JohnDoe\n  AllowTcpForwarding yes\Z/) }
+    end
+
+    [true,'string',3,2.42,['array']].each do |value|
+      context "set to invalid #{value} (as #{value.class})" do
+        let(:params) { {'sshd_config_match' => value } }
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error, /is not a Hash/)
+        end
+      end
+    end
+
+  end
+
+describe 'sshd_config_print_last_log param' do
+    ['yes','no'].each do |value|
+      context "set to #{value}" do
+        let (:params) { { :sshd_config_print_last_log => value } }
+
+        it { should contain_file('sshd_config').with_content(/^PrintLastLog #{value}$/) }
+      end
+    end
+
+    context 'when set to an invalid value' do
+      let (:params) { { :sshd_config_print_last_log => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_print_last_log may be either \'yes\' or \'no\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+  describe 'sshd_listen_address param' do
+    context 'when set to an array' do
+      let(:params) { {'sshd_listen_address' => ['192.168.1.1','2001:db8::dead:f00d'] } }
+
+      it { should contain_file('sshd_config').with_content(/^ListenAddress 192.168.1.1\nListenAddress 2001:db8::dead:f00d$/) }
+    end
+
+    context 'when set to a string' do
+      let(:params) { {'sshd_listen_address' => ['192.168.1.1'] } }
+
+      it { should contain_file('sshd_config').with_content(/^ListenAddress 192.168.1.1$/) }
+    end
+
+    context 'when not set' do
+      it { should_not contain_file('sshd_config').with_content(/^\s*ListenAddress/) }
+    end
+
+
+    context 'when set to an invalid type (not string or array)' do
+      let(:params) { {'sshd_listen_address' => true } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  describe 'sshd_loglevel param' do
+    context 'when set to an invalid value' do
+      let(:params) { {'sshd_config_loglevel' => 'BOGON'} }
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error, /"BOGON" does not match/)
+      end
+    end
+    ['QUIET', 'FATAL', 'ERROR', 'INFO', 'VERBOSE'].each do |supported_val|
+      context "when set to #{supported_val}" do
+        let(:params) { { 'sshd_config_loglevel' => supported_val} }
+        it { should contain_file('sshd_config').with_content(/^LogLevel #{supported_val}$/) }
+      end
+    end
+  end
+
+  describe 'with sshd_kerberos_authentication' do
+    ['yes','no'].each do |value|
+      context "set to #{value}" do
+        let(:params) { { 'sshd_kerberos_authentication' => value } }
+
+        it { should contain_file('sshd_config').with_content(/^KerberosAuthentication #{value}$/) }
+      end
+    end
+
+    context 'set to invalid value on valid osfamily' do
+      let(:params) { { :sshd_kerberos_authentication => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_kerberos_authentication may be either \'yes\' or \'no\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+  context 'when ssh_config_template has a nonstandard value' do
+    context 'and that value is not valid' do
+      let(:params) { {'ssh_config_template' => false} }
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error, /is not a string/)
+      end
+    end
+    context 'and that value is valid' do
+      let(:params) { {'ssh_config_template' => 'ssh/sshd_config.erb'} }
+      it 'should lay down the ssh_config file from the specified template' do
+        should contain_file('ssh_config').with_content(/OpenBSD: sshd_config/)
+      end
+    end
+  end
+
+  context 'when sshd_config_template has a nonstandard value' do
+    context 'and that value is not valid' do
+      let(:params) { {'sshd_config_template' => false} }
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error, /is not a string/)
+      end
+    end
+    context 'and that value is valid' do
+      let(:params) { {'sshd_config_template' => 'ssh/ssh_config.erb'} }
+      it 'should lay down the sshd_config file from the specified template' do
+        should contain_file('sshd_config').with_content(/OpenBSD: ssh_config/)
+      end
+    end
+  end
+
+  ['true',true].each do |value|
+    context "with manage_root_ssh_config set to #{value} on valid osfamily" do
+      let(:params) { { :manage_root_ssh_config => value } }
+
+      it { should compile.with_all_deps }
+
+      it { should contain_class('ssh')}
+
+      it { should contain_class('common')}
+
+      it {
+        should contain_file('root_ssh_dir').with({
+          'ensure'  => 'directory',
+          'path'    => '/root/.ssh',
+          'owner'   => 'root',
+          'group'   => 'root',
+          'mode'    => '0700',
+          'require' => 'Common::Mkdir_p[/root/.ssh]',
+        })
+      }
+
+      it {
+        should contain_file('root_ssh_config').with({
+          'ensure' => 'file',
+          'path'   => '/root/.ssh/config',
+          'owner'  => 'root',
+          'group'  => 'root',
+          'mode'   => '0600',
+        })
+      }
+    end
+  end
+
+  ['false',false].each do |value|
+    context "with manage_root_ssh_config set to #{value} on valid osfamily" do
+      let(:params) { { :manage_root_ssh_config => value } }
+
+      it { should compile.with_all_deps }
+
+      it { should contain_class('ssh')}
+
+      it { should_not contain_class('common')}
+
+      it { should_not contain_file('root_ssh_dir') }
+
+      it { should_not contain_file('root_ssh_config') }
+    end
+  end
+
+  [true,'invalid'].each do |ciphers|
+    context "with ssh_config_ciphers set to invalid value #{ciphers}" do
+      let(:params) { { :ssh_config_ciphers => ciphers } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |kexalgorithms|
+    context "with ssh_config_kexalgorithms set to invalid value #{kexalgorithms}" do
+      let(:params) { { :ssh_config_kexalgorithms => kexalgorithms } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |macs|
+    context "with ssh_config_macs set to invalid value #{macs}" do
+      let(:params) { { :ssh_config_macs => macs } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  [true, ['not','a','string']].each do |proxy_command|
+    context "with ssh_config_proxy_command set to invalid value #{proxy_command}" do
+      let(:params) { { :ssh_config_proxy_command => proxy_command } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  describe 'with ssh_config_hash_known_hosts param' do
+    ['yes','no','unset'].each do |value|
+      context "set to #{value}" do
+        let (:params) { { :ssh_config_hash_known_hosts => value } }
+
+        if value == 'unset'
+          it { should contain_file('ssh_config').without_content(/^\s*HashKnownHosts/) }
+        else
+          it { should contain_file('ssh_config').with_content(/^\s*HashKnownHosts #{value}$/) }
+        end
+      end
+    end
+
+    context 'when set to an invalid value' do
+      let (:params) { { :ssh_config_hash_known_hosts => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::ssh_config_hash_known_hosts may be either \'yes\', \'no\' or \'unset\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |ciphers|
+    context "with sshd_config_ciphers set to invalid value #{ciphers}" do
+      let(:params) { { :sshd_config_ciphers => ciphers } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |kexalgorithms|
+    context "with sshd_config_kexalgorithms set to invalid value #{kexalgorithms}" do
+      let(:params) { { :sshd_config_kexalgorithms => kexalgorithms } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |denyusers|
+    context "with sshd_config_denyusers set to invalid value #{denyusers}" do
+      let(:params) { { :sshd_config_denyusers => denyusers } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not an Array/)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |denygroups|
+    context "with sshd_config_denygroups set to invalid value #{denygroups}" do
+      let(:params) { { :sshd_config_denygroups => denygroups } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not an Array/)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |allowusers|
+    context "with sshd_config_allowusers set to invalid value #{allowusers}" do
+      let(:params) { { :sshd_config_allowusers => allowusers } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not an Array/)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |allowgroups|
+    context "with sshd_config_allowgroups set to invalid value #{allowgroups}" do
+      let(:params) { { :sshd_config_allowgroups => allowgroups } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not an Array/)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |macs|
+    context "with sshd_config_macs set to invalid value #{macs}" do
+      let(:params) { { :sshd_config_macs => macs } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  describe 'with sshd_config_permitemptypasswords' do
+    ['yes','no'].each do |value|
+      context "set to #{value}" do
+        let(:params) { { 'sshd_config_permitemptypasswords' => value } }
+
+        it { should contain_file('sshd_config').with_content(/^PermitEmptyPasswords #{value}$/) }
+      end
+    end
+
+    context 'set to invalid value on valid osfamily' do
+      let(:params) { { :sshd_config_permitemptypasswords => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_permitemptypasswords may be either \'yes\' or \'no\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+  describe 'with sshd_config_permituserenvironment' do
+    ['yes','no'].each do |value|
+      context "set to #{value}" do
+        let(:params) { { 'sshd_config_permituserenvironment' => value } }
+
+        it { should contain_file('sshd_config').with_content(/^PermitUserEnvironment #{value}$/) }
+      end
+    end
+
+    context 'set to invalid value on valid osfamily' do
+      let(:params) { { :sshd_config_permituserenvironment => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_permituserenvironment may be either \'yes\' or \'no\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+  describe 'sshd_config_compression param' do
+    ['yes','no','delayed'].each do |value|
+      context "set to #{value}" do
+        let (:params) { { :sshd_config_compression => value } }
+
+        it { should contain_file('sshd_config').with_content(/^Compression #{value}$/) }
+      end
+    end
+
+    context 'when set to an invalid value' do
+      let (:params) { { :sshd_config_compression => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_compression may be either \'yes\', \'no\' or \'delayed\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+  describe 'sshd_config_port param' do
+    context 'when set to an array' do
+      let(:params) { {'sshd_config_port' => ['22222', '22223'] } }
+
+      it { should contain_file('sshd_config').with_content(/^Port 22222\nPort 22223$/) }
+    end
+
+    context 'when set to a string' do
+      let(:params) { {'sshd_config_port' => '22222' } }
+
+      it { should contain_file('sshd_config').with_content(/^Port 22222$/) }
+    end
+
+    context 'when set to an integer' do
+      let(:params) { {'sshd_config_port' => 22222 } }
+
+      it { should contain_file('sshd_config').with_content(/^Port 22222$/) }
+    end
+
+    context 'when not set to a valid number' do
+      let(:params) { {'sshd_config_port' => '22invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_port must be a valid number and is set to <22invalid>\./)
+      end
+    end
+  end
+
+  describe 'sshd_config_permittunnel param' do
+    ['yes','point-to-point','ethernet','no','unset'].each do |value|
+      context "set to #{value}" do
+        let (:params) { { :sshd_config_permittunnel => value } }
+
+        if value == 'unset'
+          it { should contain_file('sshd_config').without_content(/^\s*PermitTunnel/) }
+        else
+          it { should contain_file('sshd_config').with_content(/^PermitTunnel #{value}$/) }
+        end
+      end
+    end
+
+    context 'when set to an invalid value' do
+      let (:params) { { :sshd_config_permittunnel => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_permittunnel may be either \'yes\', \'point-to-point\', \'ethernet\', \'no\' or \'unset\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+  describe 'sshd_config_key_revocation_list param' do
+    ['/path/to','unset'].each do |value|
+      context "set to #{value}" do
+        let (:params) { { :sshd_config_key_revocation_list => value } }
+
+        if value == 'unset'
+          it { should contain_file('sshd_config').without_content(/^\s*RevokedKeys/) }
+        else
+          it { should contain_file('sshd_config').with_content(/^RevokedKeys #{value}$/) }
+        end
+      end
+    end
+
+    context 'when set to an invalid value' do
+      let (:params) { { :sshd_config_key_revocation_list => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/while evaluating a Function Call|is not an absolute path/)
+      end
+    end
+  end
+
+  describe 'sshd_config_hostcertificate param' do
+    context 'unset value' do
+      let(:params) { { :sshd_config_hostcertificate => 'unset' } }
+
+      it { should contain_file('sshd_config').without_content(/^\s*HostCertificate/) }
+    end
+
+    context 'with a certificate' do
+      let(:params) { { :sshd_config_hostcertificate => '/etc/ssh/ssh_host_key-cert.pub' } }
+
+      it { should contain_file('sshd_config').with_content(/^HostCertificate \/etc\/ssh\/ssh_host_key-cert\.pub/) }
+    end
+
+    context 'with multiple certs' do
+      let(:params) { { :sshd_config_hostcertificate => [ '/etc/ssh/ssh_host_key-cert.pub', '/etc/ssh/ssh_host_key-cert2.pub'] } }
+
+      it { should contain_file('sshd_config').with_content(/^HostCertificate \/etc\/ssh\/ssh_host_key-cert\.pub\nHostCertificate \/etc\/ssh\/ssh_host_key-cert2\.pub/)}
+    end
+  end
+
+  context 'with sshd_config_hostcertificate set to invalid value on valid osfamily' do
+    context 'with string' do
+      let(:params) { { :sshd_config_hostcertificate => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/"invalid" is not an absolute path/)
+      end
+    end
+  end
+
+  context 'with sshd_config_authorized_principals_file param' do
+    ['unset', '.ssh/authorized_principals'].each do |value|
+      context "set to #{value}" do
+        let (:params) { { :sshd_config_authorized_principals_file => value } }
+
+        if value == 'unset'
+          it { should contain_file('sshd_config').without_content(/^\s*AuthorizedPrincipalsFile/)}
+        else
+          it { should contain_file('sshd_config').with_content(/^AuthorizedPrincipalsFile \.ssh\/authorized_principals/)}
+        end
+      end
+    end
+  end
+
+  describe 'sshd_config_trustedusercakeys param' do
+    ['unset', '/etc/ssh/authorized_users_ca.pub', 'none'].each do |value|
+      context "set to #{value}" do
+        let (:params) { { :sshd_config_trustedusercakeys => value } }
+
+        if value == 'unset'
+          it { should contain_file('sshd_config').without_content(/^\s*TrustedUserCAKeys/) }
+        else
+          it { should contain_file('sshd_config').with_content(/^TrustedUserCAKeys #{value}/) }
+        end
+      end
+    end
+  end
+
+  context 'with sshd_config_trustedusercakeys set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_config_trustedusercakeys => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/"invalid" is not an absolute path/)
+    end
+  end
+
+  context 'with manage_root_ssh_config set to invalid value on valid osfamily' do
+    let(:params) { { :manage_root_ssh_config => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/Unknown type of boolean/)
+    end
+  end
+
+  context 'with sshd_password_authentication set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_password_authentication => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_password_authentication may be either \'yes\' or \'no\' and is set to <invalid>\./)
+    end
+  end
+
+  context 'with sshd_allow_tcp_forwarding set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_allow_tcp_forwarding => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_allow_tcp_forwarding may be either \'yes\' or \'no\' and is set to <invalid>\./)
+    end
+  end
+
+  context 'with sshd_x11_forwarding set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_x11_forwarding => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_x11_forwarding may be either \'yes\' or \'no\' and is set to <invalid>\./)
+    end
+  end
+
+  context 'with sshd_x11_use_localhost set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_x11_use_localhost => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_x11_use_localhost may be either \'yes\' or \'no\' and is set to <invalid>\./)
+    end
+  end
+
+  context 'with sshd_use_pam set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_use_pam => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_use_pam may be either \'yes\' or \'no\' and is set to <invalid>\./)
+    end
+  end
+
+  context 'with sshd_config_serverkeybits set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_config_serverkeybits => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_config_serverkeybits must be an integer and is set to <invalid>\./)
+    end
+  end
+
+  context 'with sshd_client_alive_interval set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_client_alive_interval => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_client_alive_interval must be an integer and is set to <invalid>\./)
+    end
+  end
+
+  context 'with sshd_client_alive_count_max set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_client_alive_count_max => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_client_alive_count_max must be an integer and is set to <invalid>\./)
+    end
+  end
+
+  context 'with sshd_config_banner set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_config_banner => 'invalid/path' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/is not an absolute path/)
+    end
+  end
+
+  context 'with sshd_config_authkey_location set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_config_authkey_location => false } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/is not a string/)
+    end
+  end
+
+  context 'with sshd_config_hostkey set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_config_hostkey => false } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/is not an Array/)
+    end
+  end
+
+  context 'with sshd_config_hostkey set to invalid path on valid osfamily' do
+    let(:params) { { :sshd_config_hostkey => ['not_a_path'] } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/is not an absolute path./)
+    end
+  end
+
+  describe 'with sshd_config_allowagentforwarding' do
+    ['yes','no'].each do |value|
+      context "set to #{value}" do
+        let(:params) { { 'sshd_config_allowagentforwarding' => value } }
+
+        it { should contain_file('sshd_config').with_content(/^AllowAgentForwarding #{value}$/) }
+      end
+    end
+
+    context 'set to invalid value on valid osfamily' do
+      let(:params) { { :sshd_config_allowagentforwarding => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_allowagentforwarding may be either \'yes\' or \'no\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+
+  context 'with sshd_config_strictmodes set to invalid value on valid osfamily' do
+    let(:params) { { :sshd_config_strictmodes => 'invalid' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_config_strictmodes may be either \'yes\' or \'no\' and is set to <invalid>\./)
+    end
+  end
+
+  context 'with sshd_authorized_keys_command specified with an invalid path' do
+    let(:params) { { :sshd_authorized_keys_command => 'invalid/path' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/"invalid\/path" is not an absolute path/)
+    end
+  end
+
+  context 'with sshd_authorized_keys_command_user specified with an invalid type (non-string)' do
+    let(:params) { { :sshd_authorized_keys_command_user => ['invalid','type'] } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/\["invalid", "type"\] is not a string/)
+    end
+  end
+
+  context 'with sshd_banner_content set and with default value on sshd_config_banner on valid osfamily' do
+    let(:params) { { :sshd_banner_content => 'textinbanner' } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::sshd_config_banner must be set to be able to use sshd_banner_content\./)
+    end
+  end
+
+
+  context 'with ssh_config_sendenv_xmodifiers set to invalid type, array' do
+    let(:params) { { :ssh_config_sendenv_xmodifiers => ['invalid','type'] } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error,/ssh::ssh_config_sendenv_xmodifiers type must be true or false\./)
+    end
+  end
+
+  context 'with ssh_config_sendenv_xmodifiers set to stringified \'true\'' do
+    let(:params) { { :ssh_config_sendenv_xmodifiers => 'true' } }
+
+    it { should compile.with_all_deps }
+
+    it { should contain_file('ssh_config').with_content(/^  SendEnv XMODIFIERS$/) }
+  end
+
+  context 'with manage_firewall set to true on valid osfamily' do
+    let(:params) { { :manage_firewall => true } }
+
+    it { should compile.with_all_deps }
+
+    it { should contain_class('ssh')}
+
+    it { should_not contain_class('common')}
+
+    it {
+      should contain_firewall('22 open port 22 for SSH').with({
+        'action' => 'accept',
+        'dport'  => '22',
+        'proto'  => 'tcp',
+      })
+    }
+  end
+
+  context 'with config_entries defined on valid osfamily' do
+    let(:params) do
+      {
+        :config_entries => {
+          'root' => {
+            'owner' => 'root',
+            'group' => 'root',
+            'path'  => '/root/.ssh/config',
+            'host'  => 'test_host1',
+          },
+          'user' => {
+            'owner' => 'user',
+            'group' => 'group',
+            'path'  => '/home/user/.ssh/config',
+            'host'  => 'test_host2',
+            'order' => '242',
+            'lines' => [ 'ForwardX11 no', 'StrictHostKeyChecking no' ],
+          },
+        }
+      }
+    end
+
+    it { should compile.with_all_deps }
+    it { should have_ssh__config_entry_resource_count(2) }
+    it do
+      should contain_ssh__config_entry('root').with({
+        'owner' => 'root',
+        'group' => 'root',
+        'path'  => '/root/.ssh/config',
+        'host'  => 'test_host1',
+      })
+    end
+    it do
+      should contain_ssh__config_entry('user').with({
+        'owner' => 'user',
+        'group' => 'group',
+        'path'  => '/home/user/.ssh/config',
+        'host'  => 'test_host2',
+        'order' => '242',
+        'lines' => [ 'ForwardX11 no', 'StrictHostKeyChecking no' ],
+      })
+    end
+  end
+
+  describe 'with hiera providing data from multiple levels' do
+    let(:facts) do
+      default_facts.merge({
+        :fqdn     => 'hieramerge.example.com',
+        :specific => 'test_hiera_merge',
+      })
+    end
+
+    context 'with defaults for all parameters' do
+      it { should have_ssh__config_entry_resource_count(1) }
+      it { should contain_ssh__config_entry('user_from_fqdn') }
+    end
+
+    context 'with hiera_merge set to valid <true>' do
+      let(:params) { { :hiera_merge => true } }
+      it { should have_ssh__config_entry_resource_count(2) }
+      it { should contain_ssh__config_entry('user_from_fqdn') }
+      it { should contain_ssh__config_entry('user_from_fact') }
+    end
+  end
+
+  context 'with keys defined on valid osfamily' do
+    let(:params) { { :keys => {
+      'root_for_userX' => {
+        'ensure' => 'present',
+        'user'   => 'root',
+        'type'   => 'dsa',
+        'key'    => 'AAAA==',
+      },
+      'apache_hup' => {
+        'ensure'  => 'present',
+        'user'    => 'apachehup',
+        'type'    => 'dsa',
+        'key'     => 'AAAA==',
+        'options' => 'command="/sbin/service httpd restart"',
+      },
+      'root_for_userY' => {
+        'ensure' => 'absent',
+        'user'   => 'root',
+      }
+    } } }
+
+    it { should compile.with_all_deps }
+
+    it {
+      should contain_ssh_authorized_key('root_for_userX').with({
+        'ensure' => 'present',
+        'user'   => 'root',
+        'type'   => 'dsa',
+        'key'    => 'AAAA==',
+      })
+    }
+
+    it {
+      should contain_ssh_authorized_key('apache_hup').with({
+        'ensure'  => 'present',
+        'user'    => 'apachehup',
+        'type'    => 'dsa',
+        'key'     => 'AAAA==',
+        'options' => 'command="/sbin/service httpd restart"',
+      })
+    }
+
+    it {
+      should contain_ssh_authorized_key('root_for_userY').with({
+        'ensure' => 'absent',
+        'user'   => 'root',
+      })
+    }
+  end
+
+  context 'with keys specified as not of type hash' do
+    let(:params) { { :keys => [ 'not', 'a', 'hash' ] } }
+
+    it 'should fail' do
+      expect {
+        should contain_class('ssh')
+      }.to raise_error(Puppet::Error)
+    end
+  end
+
+  describe 'with hiera_merge parameter specified' do
+    context 'as a non-boolean or non-string' do
+      let(:facts) { default_facts.merge( { :fqdn => 'hieramerge.example.com'} )}
+      let(:params) { { :hiera_merge => ['not_a_boolean','or_a_string'] } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+
+    context 'as an invalid string' do
+      let(:params) { { :hiera_merge => 'invalid_string' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::hiera_merge may be either 'true' or 'false' and is set to <invalid_string>./)
+      end
+    end
+
+    ['true',true].each do |value|
+      context "as #{value} with hiera data getting collected" do
+        let(:facts) { default_facts.merge( { :fqdn => 'hieramerge.example.com'} )}
+        let(:params) { { :hiera_merge => value } }
+
+        it { should compile.with_all_deps }
+
+        it { should contain_class('ssh') }
+
+        it { should contain_file('sshd_config').with_content(/^\s*DenyUsers denyuser_from_fqdn/) }
+        it { should contain_file('sshd_config').with_content(/^\s*DenyGroups denygroup_from_fqdn/) }
+        it { should contain_file('sshd_config').with_content(/^\s*AllowUsers allowuser_from_fqdn/) }
+        it { should contain_file('sshd_config').with_content(/^\s*AllowGroups allowgroup_from_fqdn/) }
+
+      end
+    end
+
+    context "as true with with hiera data getting merged through levels" do
+      let(:facts) do
+        default_facts.merge(
+          {
+            :fqdn              => 'hieramerge.example.com',
+            :specific          => 'test_hiera_merge',
+          }
+        )
+      end
+      let(:params) { { :hiera_merge => true } }
+
+      it { should compile.with_all_deps }
+
+      it { should contain_class('ssh') }
+
+      it { should contain_file('sshd_config').with_content(/^\s*DenyUsers denyuser_from_fqdn denyuser_from_fact/) }
+      it { should contain_file('sshd_config').with_content(/^\s*DenyGroups denygroup_from_fqdn denygroup_from_fact/) }
+      it { should contain_file('sshd_config').with_content(/^\s*AllowUsers allowuser_from_fqdn allowuser_from_fact/) }
+      it { should contain_file('sshd_config').with_content(/^\s*AllowGroups allowgroup_from_fqdn allowgroup_from_fact/) }
+
+    end
+
+    context "as true with no hiera data provided" do
+      let(:facts) do
+        default_facts.merge(
+          {
+            :osfamily               => 'Suse',
+            :operatingsystem        => 'SLES',
+            :operatingsystemrelease => '11.4',
+            :architecture           => 'x86_64',
+          }
+        )
+      end
+      let(:params) { { :hiera_merge => true } }
+
+      it { should compile.with_all_deps }
+
+      it { should contain_class('ssh') }
+
+      it { should contain_file('sshd_config').without_content(/^\s*DenyUsers/) }
+      it { should contain_file('sshd_config').without_content(/^\s*DenyGroups/) }
+      it { should contain_file('sshd_config').without_content(/^\s*AllowUsers/) }
+      it { should contain_file('sshd_config').without_content(/^\s*AllowGroups/) }
+
+    end
+
+    ['false',false].each do |value|
+      context "as #{value}" do
+        let(:params) { { :hiera_merge => value } }
+
+        it { should compile.with_all_deps }
+
+        it { should contain_class('ssh') }
+      end
+    end
+  end
+
+  describe 'with ssh_package_adminfile parameter specified' do
+    context 'as a valid path' do
+      let(:facts) { default_solaris_facts }
+      let(:params) { { :ssh_package_adminfile => '/var/tmp/admin' } }
+
+      ['SUNWsshcu','SUNWsshdr','SUNWsshdu','SUNWsshr','SUNWsshu'].each do |pkg|
+        it {
+          should contain_package(pkg).with({
+            'ensure'    => 'installed',
+            'source'    => '/var/spool/pkg',
+            'adminfile' => '/var/tmp/admin',
+          })
+        }
+      end
+    end
+
+    context 'as an invalid path' do
+      let(:facts) { default_solaris_facts }
+      let(:params) { { :ssh_package_adminfile => 'invalid/path' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not an absolute path/)
+      end
+    end
+  end
+
+  describe 'with sshd_config_xauth_location parameter specified' do
+    context 'as a valid path' do
+      let(:params) { { :sshd_config_xauth_location => '/opt/ssh/bin/xauth' } }
+
+      it { should contain_file('sshd_config').with_content(/^XAuthLocation \/opt\/ssh\/bin\/xauth$/) }
+    end
+
+    context 'as an invalid path' do
+      let(:params) { { :sshd_config_xauth_location => 'invalid/path' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not an absolute path/)
+      end
+    end
+
+    context 'as an invalid type' do
+      let(:params) { { :sshd_config_xauth_location => true } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  describe 'with ssh_package_source parameter specified' do
+    let(:facts) { default_solaris_facts }
+    context 'as a valid path' do
+      let(:params) { { :ssh_package_source => '/mnt/packages' } }
+
+      ['SUNWsshcu','SUNWsshdr','SUNWsshdu','SUNWsshr','SUNWsshu'].each do |pkg|
+        it {
+          should contain_package(pkg).with({
+            'ensure'    => 'installed',
+            'source'    => '/mnt/packages',
+            'adminfile' => nil,
+          })
+        }
+      end
+    end
+
+    context 'as an invalid path' do
+      let(:params) { { :ssh_package_source => 'invalid/path' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not an absolute path/)
+      end
+    end
+
+    context 'as an invalid type' do
+      let(:params) { { :ssh_package_source => true } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  describe 'with parameter ssh_config_forward_x11_trusted' do
+    ['yes','no'].each do |value|
+      context "specified as #{value}" do
+        let(:params) { { :ssh_config_forward_x11_trusted => value } }
+
+        it { should contain_file('ssh_config').with_content(/^\s*ForwardX11Trusted #{value}$/) }
+      end
+    end
+
+    context 'not specified' do
+      let(:facts) { default_solaris_facts }
+      it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11Trusted/) }
+    end
+
+    ['YES',true].each do |value|
+      context "specified an invalid value #{value}" do
+        let(:params) { { :ssh_config_forward_x11_trusted => value } }
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::ssh_config_forward_x11_trusted may be either 'yes' or 'no' and is set to <#{value}>\./)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter ssh_gssapidelegatecredentials' do
+    ['yes','no'].each do |value|
+      context "specified as #{value}" do
+        let(:facts) { default_solaris_facts }
+        let(:params) { { :ssh_gssapidelegatecredentials => value } }
+
+        it { should contain_file('ssh_config').with_content(/^GSSAPIDelegateCredentials #{value}$/) }
+      end
+    end
+
+    ['YES',true].each do |value|
+      context "specified an invalid value #{value}" do
+        let(:params) { { :ssh_gssapidelegatecredentials => value } }
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::ssh_gssapidelegatecredentials may be either 'yes' or 'no' and is set to <#{value}>\./)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter ssh_gssapiauthentication' do
+    ['yes','no'].each do |value|
+      context "specified as valid #{value} (as #{value.class})" do
+        let(:params) { { :ssh_gssapiauthentication => value } }
+
+        it { should contain_file('ssh_config').with_content(/^\s*GSSAPIAuthentication #{value}$/) }
+      end
+    end
+
+    ['YES',true,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :ssh_gssapiauthentication => value } }
+
+        if value.is_a?(Array)
+          value = value.join
+        elsif value.is_a?(Hash)
+          value = '{ha => sh}'
+        end
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::ssh_gssapiauthentication may be either 'yes' or 'no' and is set to <#{Regexp.escape(value.to_s)}>\./)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter ssh_hostbasedauthentication' do
+    ['yes','no'].each do |value|
+      context "specified as valid #{value} (as #{value.class})" do
+        let(:params) { { :ssh_hostbasedauthentication => value } }
+
+        it { should contain_file('ssh_config').with_content(/^\s*HostbasedAuthentication #{value}$/) }
+      end
+    end
+
+    ['YES',true,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :ssh_hostbasedauthentication => value } }
+
+        if value.is_a?(Array)
+          value = value.join
+        elsif value.is_a?(Hash)
+          value = '{ha => sh}'
+        end
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::ssh_hostbasedauthentication may be either 'yes' or 'no' and is set to <#{Regexp.escape(value.to_s)}>\./)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter ssh_strict_host_key_checking' do
+    ['yes','no', 'ask'].each do |value|
+      context "specified as valid #{value} (as #{value.class})" do
+        let(:params) { { :ssh_strict_host_key_checking => value } }
+
+        it { should contain_file('ssh_config').with_content(/^\s*StrictHostKeyChecking #{value}$/) }
+      end
+    end
+
+    ['YES',true,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :ssh_strict_host_key_checking => value } }
+
+        if value.is_a?(Array)
+          value = value.join
+        elsif value.is_a?(Hash)
+          value = '{ha => sh}'
+        end
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::ssh_strict_host_key_checking may be 'yes', 'no' or 'ask' and is set to <#{Regexp.escape(value.to_s)}>\./)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter ssh_enable_ssh_keysign' do
+    ['yes','no'].each do |value|
+      context "specified as valid #{value} (as #{value.class})" do
+        let(:params) { { :ssh_enable_ssh_keysign => value } }
+
+        it { should contain_file('ssh_config').with_content(/^\s*EnableSSHKeysign #{value}$/) }
+      end
+    end
+
+    ['YES',true,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :ssh_enable_ssh_keysign => value } }
+
+        if value.is_a?(Array)
+          value = value.join
+        elsif value.is_a?(Hash)
+          value = '{ha => sh}'
+        end
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::ssh_enable_ssh_keysign may be either 'yes' or 'no' and is set to <#{Regexp.escape(value.to_s)}>\./)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter sshd_gssapiauthentication' do
+    ['yes','no'].each do |value|
+      context "specified as valid #{value} (as #{value.class})" do
+        let(:params) { { :sshd_gssapiauthentication => value } }
+
+        it { should contain_file('sshd_config').with_content(/^GSSAPIAuthentication #{value}$/) }
+      end
+    end
+
+    ['YES',true,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :sshd_gssapiauthentication => value } }
+
+        if value.is_a?(Array)
+          value = value.join
+        elsif value.is_a?(Hash)
+          value = '{ha => sh}'
+        end
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_gssapiauthentication may be either 'yes' or 'no' and is set to <#{Regexp.escape(value.to_s)}>\./)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter sshd_gssapikeyexchange' do
+    ['yes','no'].each do |value|
+      context "specified as #{value}" do
+        let(:params) { { :sshd_gssapikeyexchange => value } }
+
+        it { should contain_file('sshd_config').with_content(/^GSSAPIKeyExchange #{value}$/) }
+      end
+    end
+
+    context 'not specified' do
+
+      it { should_not contain_file('sshd_config').with_content(/^\s*GSSAPIKeyExchange/) }
+    end
+
+    ['YES',true].each do |value|
+      context "specified an invalid value #{value}" do
+        let(:params) { { :sshd_gssapikeyexchange => value } }
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_gssapikeyexchange may be either 'yes' or 'no' and is set to <#{value}>\./)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter sshd_pamauthenticationviakbdint' do
+    ['yes','no'].each do |value|
+      context "specified as #{value}" do
+        let(:params) { { :sshd_pamauthenticationviakbdint => value } }
+
+        it { should contain_file('sshd_config').with_content(/^PAMAuthenticationViaKBDInt #{value}$/) }
+      end
+    end
+
+    context 'not specified' do
+
+      it { should_not contain_file('sshd_config').with_content(/^\s*PAMAuthenticationViaKBDInt/) }
+    end
+
+    ['YES',true].each do |value|
+      context "specified an invalid value #{value}" do
+        let(:params) { { :sshd_pamauthenticationviakbdint => value } }
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_pamauthenticationviakbdint may be either 'yes' or 'no' and is set to <#{value}>\./)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter sshd_gssapicleanupcredentials' do
+    ['yes','no'].each do |value|
+      context "specified as #{value}" do
+        let(:params) { { :sshd_gssapicleanupcredentials => value } }
+
+        it { should contain_file('sshd_config').with_content(/^GSSAPICleanupCredentials #{value}$/) }
+      end
+    end
+
+    context 'not specified' do
+      let(:facts) { default_solaris_facts }
+
+      it { should_not contain_file('sshd_config').with_content(/^\s*GSSAPICleanupCredentials/) }
+    end
+
+    ['YES',true].each do |value|
+      context "specified an invalid value #{value}" do
+        let(:params) { { :sshd_gssapicleanupcredentials => value } }
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_gssapicleanupcredentials may be either 'yes' or 'no' and is set to <#{value}>\./)
+        end
+      end
+    end
+  end
+
+
+  describe 'with parameter ssh_sendenv specified' do
+    ['true',true].each do |value|
+      context "as #{value}" do
+        let(:params) { { :ssh_sendenv => value } }
+
+        it { should contain_file('ssh_config').with_content(/^\s*SendEnv/) }
+      end
+    end
+
+    ['false',false].each do |value|
+      context "as #{value}" do
+        let(:params) { { :ssh_sendenv => value } }
+
+        it { should_not contain_file('ssh_config').with_content(/^\s*SendEnv/) }
+      end
+    end
+
+    context 'as an invalid string' do
+      let(:params) { { :ssh_sendenv => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::ssh_sendenv may be either 'true' or 'false' and is set to <invalid>\./)
+      end
+    end
+
+    context 'as an invalid type' do
+      let(:params) { { :ssh_sendenv => ['invalid','type'] } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::ssh_sendenv type must be true or false\./)
+      end
+    end
+  end
+
+  describe 'with paramter sshd_config_maxauthtries specified'  do
+    context 'as a valid integer' do
+     let(:params) { { :sshd_config_maxauthtries => 6}}
+     it { should contain_file('sshd_config').with_content(/^MaxAuthTries 6$/)}
+    end
+    context 'as an invalid type' do
+      let(:params) { { :sshd_config_maxauthtries => 'BOGUS'} }
+      it 'should fail' do
+        expect{
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_maxauthtries must be a valid number and is set to <BOGUS>\./)
+      end
+    end
+ end
+
+  describe 'with parameter sshd_config_maxstartups specified' do
+    ['10','10:30:100'].each do |value|
+      context "as a valid string - #{value}" do
+        let(:params) { { :sshd_config_maxstartups => value } }
+
+        it { should contain_file('sshd_config').with_content(/^MaxStartups #{value}$/) }
+      end
+    end
+
+    ['10a',true,'10:30:1a'].each do |value|
+      context "as an invalid string - #{value}" do
+        let(:params) { { :sshd_config_maxstartups => value } }
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_config_maxstartups may be either an integer or three integers separated with colons, such as 10:30:100\. Detected value is <#{value}>\./)
+        end
+      end
+    end
+
+    context 'as an invalid type' do
+      let(:params) { { :sshd_config_maxstartups => true } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  describe 'with parameter sshd_config_maxsessions specified' do
+    context 'as a valid integer' do
+      let(:params) { { :sshd_config_maxsessions => 10 } }
+
+      it { should contain_file('sshd_config').with_content(/^MaxSessions 10$/) }
+    end
+
+    context 'as a valid string <unset>' do
+      let(:params) { { :sshd_config_maxsessions => 'unset' } }
+
+      it { should contain_file('sshd_config').without_content(/^\s*MaxSessions/) }
+    end
+
+    context 'as an invalid type' do
+      let(:params) { { :sshd_config_maxsessions => 'BOGUS' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  describe 'with parameter sshd_acceptenv specified' do
+    ['true',true].each do |value|
+      context "as #{value}" do
+        let(:params) { { :sshd_acceptenv => value } }
+
+        it { should contain_file('sshd_config').with_content(/^\s*AcceptEnv/) }
+      end
+    end
+
+    ['false',false].each do |value|
+      context "as #{value}" do
+        let(:params) { { :sshd_acceptenv => value } }
+
+        it { should_not contain_file('sshd_config').with_content(/^\s*AcceptEnv/) }
+      end
+    end
+
+    context 'as an invalid string' do
+      let(:params) { { :sshd_acceptenv => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_acceptenv may be either 'true' or 'false' and is set to <invalid>\./)
+      end
+    end
+
+    context 'as an invalid type' do
+      let(:params) { { :sshd_acceptenv => ['invalid','type'] } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_acceptenv type must be true or false\./)
+      end
+    end
+  end
+
+  describe 'with parameter service_hasstatus' do
+    ['true',true,'false',false].each do |value|
+      context "specified as #{value}" do
+        let(:params) { { :service_hasstatus => value } }
+
+        it {
+          should contain_service('sshd_service').with({
+            'ensure'     => 'running',
+            'name'       => 'sshd',
+            'enable'     => 'true',
+            'hasrestart' => 'true',
+            'hasstatus'  => value,
+            'subscribe'  => 'File[sshd_config]',
+          })
+        }
+      end
+    end
+
+    context 'specified as an invalid string' do
+      let(:params) { { :service_hasstatus => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::service_hasstatus must be 'true' or 'false' and is set to <invalid>\./)
+      end
+    end
+
+    context 'specified as an invalid type' do
+      let(:params) { { :service_hasstatus => ['invalid','type'] } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::service_hasstatus must be true or false\./)
+      end
+    end
+  end
+
+  describe 'with parameter ssh_config_global_known_hosts_file' do
+    context 'specified as a valid path' do
+      let(:params) { { :ssh_config_global_known_hosts_file => '/valid/path' } }
+
+      it {
+        should contain_file('ssh_known_hosts').with({
+          'ensure' => 'file',
+          'path'   => '/valid/path',
+          'owner'  => 'root',
+          'group'  => 'root',
+          'mode'   => '0644',
+          'require' => ['Package[openssh-server]', 'Package[openssh-clients]'],
+        })
+      }
+
+      it { should contain_file('ssh_config').with_content(/^\s*GlobalKnownHostsFile \/valid\/path$/) }
+    end
+
+    context 'specified as an invalid path' do
+      let(:params) { { :ssh_config_global_known_hosts_file => 'invalid/path' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/\"invalid\/path\" is not an absolute path\./)
+      end
+    end
+
+    context 'specified as an invalid type' do
+      let(:params) { { :ssh_config_global_known_hosts_file => { 'invalid' => 'type'} } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not an absolute path/)
+      end
+    end
+  end
+
+  describe 'with parameter ssh_config_global_known_hosts_list' do
+    context 'when set to an array of valid absolute paths' do
+      let(:params) { {'ssh_config_global_known_hosts_list' => ['/valid/path1','/valid/path2'] } }
+
+      it { should contain_file('ssh_config').with_content(/^\s*GlobalKnownHostsFile.*\/valid\/path1 \/valid\/path2$/) }
+    end
+
+    context 'specified as an invalid path' do
+      let(:params) { { :ssh_config_global_known_hosts_list => ['/valid/path','invalid/path'] } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/\"invalid\/path\" is not an absolute path\./)
+      end
+    end
+
+    ['YES',true,2.42,a = { 'ha' => 'sh' }].each do |value|
+       context "specified as invalid value #{value} (as #{value.class})" do
+         let(:params) { { :ssh_config_global_known_hosts_list => value } }
+
+         if value.is_a?(Hash)
+           value = '{ha => sh}'
+         end
+
+         it 'should fail' do
+           expect {
+             should contain_class('ssh')
+           }.to raise_error(Puppet::Error, /is not an Array/)
+         end
+       end
+     end
+  end
+
+  describe 'with parameter ssh_config_user_known_hosts_file' do
+    context 'when set to an array of paths' do
+      let(:params) { {'ssh_config_user_known_hosts_file' => ['valid/path1','/valid/path2'] } }
+
+      it { should contain_file('ssh_config').with_content(/^\s*UserKnownHostsFile valid\/path1 \/valid\/path2$/) }
+    end
+
+    ['YES',true,2.42,a = { 'ha' => 'sh' }].each do |value|
+       context "specified as invalid value #{value} (as #{value.class})" do
+         let(:params) { { :ssh_config_user_known_hosts_file => value } }
+
+         if value.is_a?(Hash)
+           value = '{ha => sh}'
+         end
+
+         it 'should fail' do
+           expect {
+             should contain_class('ssh')
+           }.to raise_error(Puppet::Error, /is not an Array/)
+         end
+       end
+     end
+  end
+
+  describe 'with parameter ssh_config_global_known_hosts_owner' do
+    context 'specified as a valid string' do
+      let(:params) { { :ssh_config_global_known_hosts_owner => 'gh' } }
+
+      it {
+        should contain_file('ssh_known_hosts').with({
+          'ensure' => 'file',
+          'path'   => '/etc/ssh/ssh_known_hosts',
+          'owner'  => 'gh',
+          'group'  => 'root',
+          'mode'   => '0644',
+          'require' => ['Package[openssh-server]', 'Package[openssh-clients]'],
+        })
+      }
+    end
+
+    context 'specified as an invalid type [non-string]' do
+      let(:params) { { :ssh_config_global_known_hosts_owner => ['invalid','type'] } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/\[\"invalid\", \"type\"\] is not a string\.  It looks to be a Array/)
+      end
+    end
+  end
+
+  describe 'with parameter ssh_config_global_known_hosts_group' do
+    context 'specified as a valid string' do
+      let(:params) { { :ssh_config_global_known_hosts_group => 'gh' } }
+
+      it {
+        should contain_file('ssh_known_hosts').with({
+          'ensure' => 'file',
+          'path'   => '/etc/ssh/ssh_known_hosts',
+          'owner'  => 'root',
+          'group'  => 'gh',
+          'mode'   => '0644',
+          'require' => ['Package[openssh-server]', 'Package[openssh-clients]'],
+        })
+      }
+    end
+
+    context 'specified as an invalid type [non-string]' do
+      let(:params) { { :ssh_config_global_known_hosts_group => ['invalid','type'] } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/\[\"invalid\", \"type\"\] is not a string\.  It looks to be a Array/)
+      end
+    end
+  end
+
+  describe 'with parameter ssh_config_global_known_hosts_mode' do
+    context 'specified as a valid mode' do
+      let(:params) { { :ssh_config_global_known_hosts_mode => '0666' } }
+
+      it {
+        should contain_file('ssh_known_hosts').with({
+          'ensure' => 'file',
+          'path'   => '/etc/ssh/ssh_known_hosts',
+          'owner'  => 'root',
+          'group'  => 'root',
+          'mode'   => '0666',
+          'require' => ['Package[openssh-server]', 'Package[openssh-clients]'],
+        })
+      }
+    end
+
+    ['666','0842','06666'].each do |value|
+      context "specified as invalid mode - #{value}" do
+        let(:params) { { :ssh_config_global_known_hosts_mode => value } }
+
+        it 'should fail' do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::ssh_config_global_known_hosts_mode must be a valid 4 digit mode in octal notation\. Detected value is <#{value}>\./)
+        end
+      end
+    end
+
+    context 'specified as an invalid type [non-string]' do
+      let(:params) { { :ssh_config_global_known_hosts_mode => ['invalid','type'] } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::ssh_config_global_known_hosts_mode must be a valid 4 digit mode in octal notation\. Detected value is <[\[]?invalid.*type[\]]?/)
+      end
+    end
+  end
+
+  describe 'with ssh_key_import parameter specified' do
+    context 'as a non-boolean or non-string' do
+    let(:params) { { :ssh_key_import => ['not_a_boolean','or_a_string'] } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+
+    context 'as an invalid string' do
+      let(:params) { { :ssh_key_import => 'invalid_string' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::ssh_key_import may be either 'true' or 'false' and is set to <invalid_string>\./)
+      end
+    end
+
+    ['true',true].each do |value|
+      context "as #{value}" do
+        let(:params) { { :ssh_key_import => value } }
+
+        it { should compile.with_all_deps }
+
+        it { should contain_class('ssh') }
+
+        it {
+          should contain_file('ssh_known_hosts').with({
+            'ensure'  => 'file',
+            'path'    => '/etc/ssh/ssh_known_hosts',
+            'owner'   => 'root',
+            'group'   => 'root',
+            'mode'    => '0644',
+            'require' => ['Package[openssh-server]', 'Package[openssh-clients]'],
+          })
+        }
+      end
+    end
+
+    ['false',false].each do |value|
+      context "as #{value}" do
+        let(:params) { { :ssh_key_import => value } }
+
+        it { should compile.with_all_deps }
+
+        it { should contain_class('ssh') }
+      end
+    end
+  end
+
+  describe 'with parameter sshd_hostbasedauthentication' do
+    ['yes','no'].each do |value|
+      context "specified as valid #{value} (as #{value.class})" do
+        let(:params) { { :sshd_hostbasedauthentication => value } }
+
+        it { should contain_file('sshd_config').with_content(/^HostbasedAuthentication #{value}$/) }
+      end
+    end
+
+    ['YES',true,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :sshd_hostbasedauthentication => value } }
+
+        if value.is_a?(Array)
+          value = value.join
+        end
+
+        it do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_hostbasedauthentication may be either 'yes' or 'no' and is set to/)
+        end
+      end
+    end
+  end
+
+  [true,'invalid'].each do |pubkeyacceptedkeytypes|
+    context "with sshd_pubkeyacceptedkeytypes set to invalid value #{pubkeyacceptedkeytypes}" do
+      let(:params) { { :sshd_pubkeyacceptedkeytypes => pubkeyacceptedkeytypes } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not/)
+      end
+    end
+  end
+
+  [true,'invalid'].each do |authenticationmethods|
+    context "with sshd_config_authenticationmethods set to invalid value #{authenticationmethods}" do
+      let(:params) { { :sshd_config_authenticationmethods => authenticationmethods } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/is not/)
+      end
+    end
+  end
+
+  describe 'with parameter sshd_pubkeyauthentication' do
+    ['yes','no'].each do |value|
+      context "specified as valid #{value} (as #{value.class})" do
+        let(:params) { { :sshd_pubkeyauthentication => value } }
+
+        it { should contain_file('sshd_config').with_content(/^PubkeyAuthentication #{value}$/) }
+      end
+    end
+
+    ['YES',true,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :sshd_pubkeyauthentication => value } }
+        if value.is_a?(Array)
+          value = value.join
+        end
+
+        it do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_pubkeyauthentication may be either 'yes' or 'no' and is set to/)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter sshd_ignoreuserknownhosts' do
+    ['yes','no'].each do |value|
+      context "specified as valid #{value} (as #{value.class})" do
+        let(:params) { { :sshd_ignoreuserknownhosts => value } }
+
+        it { should contain_file('sshd_config').with_content(/^IgnoreUserKnownHosts #{value}$/) }
+      end
+    end
+
+    ['YES',true,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :sshd_ignoreuserknownhosts => value } }
+        if value.is_a?(Array)
+          value = value.join
+        end
+
+        it do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_ignoreuserknownhosts may be either 'yes' or 'no' and is set to/)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter sshd_ignorerhosts' do
+    ['yes','no'].each do |value|
+      context "specified as valid #{value} (as #{value.class})" do
+        let(:params) { { :sshd_ignorerhosts => value } }
+
+        it { should contain_file('sshd_config').with_content(/^IgnoreRhosts #{value}$/) }
+      end
+    end
+
+    ['YES',true,2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :sshd_ignorerhosts => value } }
+        if value.is_a?(Array)
+          value = value.join
+        end
+
+        it do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_ignorerhosts may be either 'yes' or 'no' and is set to/)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter manage_service' do
+    ['YES','badvalue',2.42,['array'],a = { 'ha' => 'sh' }].each do |value|
+      context "specified as invalid value #{value} (as #{value.class})" do
+        let(:params) { { :manage_service => value } }
+        it do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/(is not a boolean|Unknown type of boolean)/)
+        end
+      end
+    end
+
+    ['true', true].each do |value|
+      context "specified as valid true value #{value} (as #{value.class})" do
+        let(:params) { { :manage_service => value } }
+        it { should contain_service('sshd_service') }
+      end
+    end
+
+    ['false', false].each do |value|
+      context "specified as valid false value #{value} (as #{value.class})" do
+        let(:params) { { :manage_service => value } }
+        it { should_not contain_service('sshd_service') }
+      end
+    end
+  end
+
+  describe 'sshd_config_tcp_keepalive param' do
+    ['yes','no','unset'].each do |value|
+      context "set to #{value}" do
+        let (:params) { { :sshd_config_tcp_keepalive => value } }
+
+        if value == 'unset'
+          it { should contain_file('sshd_config').without_content(/^\s*TCPKeepAlive/) }
+        else
+          it { should contain_file('sshd_config').with_content(/^TCPKeepAlive #{value}$/) }
+        end
+      end
+    end
+
+    context 'when set to an invalid value' do
+      let (:params) { { :sshd_config_tcp_keepalive => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_tcp_keepalive may be either \'yes\', \'no\' or \'unset\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+  describe 'sshd_config_use_privilege_separation param' do
+    ['yes','no','sandbox'].each do |value|
+      context "set to #{value}" do
+        let (:params) { { :sshd_config_use_privilege_separation => value } }
+
+        it { should contain_file('sshd_config').with_content(/^UsePrivilegeSeparation #{value}$/) }
+      end
+    end
+
+    context 'when set to an invalid value' do
+      let (:params) { { :sshd_config_use_privilege_separation => 'invalid' } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error,/ssh::sshd_config_use_privilege_separation may be either \'yes\', \'no\' or \'sandbox\' and is set to <invalid>\./)
+      end
+    end
+  end
+
+  describe 'with parameter sshd_addressfamily' do
+    ['any','inet','inet6'].each do |value|
+      context "set to a valid entry of #{value}" do
+        let(:params) { { :sshd_addressfamily => value } }
+        it { should contain_file('sshd_config').with_content(/^AddressFamily #{value}$/) }
+      end
+    end
+
+    ['foo','bar',123].each do |value|
+      context "specified as invalid value #{value}" do
+        let(:params) { { :sshd_addressfamily => value } }
+        it do
+          expect {
+            should contain_class('ssh')
+          }.to raise_error(Puppet::Error,/ssh::sshd_addressfamily can be undef, 'any', 'inet' or 'inet6' and is set to/)
+        end
+      end
+    end
+  end
+
+  describe 'with parameter ssh_config_use_roaming' do
+    ['yes','no','unset'].each do |value|
+      context "set to valid value #{value}" do
+        let(:params) { { :ssh_config_use_roaming => value } }
+        if value == 'unset'
+          it { should contain_file('ssh_config').without_content(/^\s*UseRoaming/) }
+        else
+          it { should contain_file('ssh_config').with_content(/^\s*UseRoaming #{value}$/) }
+        end
+      end
+    end
+  end
+
+  describe 'variable type and content validations' do
+    mandatory_params = {} if mandatory_params.nil?
+
+    validations = {
+      'hash' => {
+        :name    => %w[config_entries],
+        :valid   => [], # valid hashes are to complex to block test them here. types::mount should have its own spec tests anyway.
+        :invalid => ['string', %w[array], 3, 2.42, true],
+        :message => 'is not a Hash',
+      },
+      'regex (yes|no|unset)' => {
+        :name    => %w(ssh_config_use_roaming),
+        :valid   => ['yes', 'no', 'unset'],
+        :invalid => ['string', %w(array), { 'ha' => 'sh' }, 3, 2.42, true, false, nil],
+        :message => 'may be either \'yes\', \'no\' or \'unset\'',
+      },
+    }
+
+    validations.sort.each do |type, var|
+      var[:name].each do |var_name|
+        var[:params] = {} if var[:params].nil?
+        var[:valid].each do |valid|
+          context "when #{var_name} (#{type}) is set to valid #{valid} (as #{valid.class})" do
+            let(:params) { [mandatory_params, var[:params], { :"#{var_name}" => valid, }].reduce(:merge) }
+            it { should compile }
+          end
+        end
+
+        var[:invalid].each do |invalid|
+          context "when #{var_name} (#{type}) is set to invalid #{invalid} (as #{invalid.class})" do
+            let(:params) { [mandatory_params, var[:params], { :"#{var_name}" => invalid, }].reduce(:merge) }
+            it { is_expected.to compile.and_raise_error(/#{var[:message]}/) }
+          end
+        end
+      end # var[:name].each
+    end # validations.sort.each
+  end # describe 'variable type and content validations'
+
+  describe 'sshd_config_include' do
+    context 'when set to an array' do
+      let(:params) { {'sshd_config_include' => ['file1','file2'] } }
+
+      it { should contain_file('sshd_config').with_content(/^Include file1 file2$/) }
+    end
+
+    context 'when set to a string' do
+      let(:params) { {'sshd_config_include' => 'file1' } }
+
+      it { should contain_file('sshd_config').with_content(/^Include file1$/) }
+    end
+
+    context 'when not set' do
+      it { should_not contain_file('sshd_config').with_content(/^\s*Include/) }
+    end
+
+    context 'when set to an invalid type (not string or array)' do
+      let(:params) { {'sshd_config_include' => true } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+  describe 'ssh_config_include' do
+    context 'when set to an array' do
+      let(:params) { {'ssh_config_include' => ['file1','file2'] } }
+
+      it { should contain_file('ssh_config').with_content(/^Include file1 file2$/) }
+    end
+
+    context 'when set to a string' do
+      let(:params) { {'ssh_config_include' => 'file1' } }
+
+      it { should contain_file('ssh_config').with_content(/^Include file1$/) }
+    end
+
+    context 'when not set' do
+      it { should_not contain_file('ssh_config').with_content(/^\s*Include/) }
+    end
+
+    context 'when set to an invalid type (not string or array)' do
+      let(:params) { {'ssh_config_include' => true } }
+
+      it 'should fail' do
+        expect {
+          should contain_class('ssh')
+        }.to raise_error(Puppet::Error)
+      end
+    end
+  end
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/defines/config_entry_spec.rb	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,83 @@
+require 'spec_helper'
+describe 'ssh::config_entry' do
+  mandatory_params = {
+    :owner => 'test_owner',
+    :group => 'test_group',
+    :path  => '/test/path',
+    :host  => 'test_host',
+  }
+
+  let(:title) { 'example' }
+  let(:params) { mandatory_params }
+
+  context 'with no paramater is provided' do
+    let(:params) { {} }
+    it 'should fail' do
+      expect do
+        should contain_define(subject)
+      end.to raise_error(Puppet::Error, /(Must pass|expects a value for parameter)/) # Puppet4/5
+    end
+  end
+
+  context 'with mandatory params set' do
+    let(:params) { mandatory_params }
+    it { should compile.with_all_deps }
+
+    it do
+      should contain_concat('/test/path').with({
+        'ensure'         => 'present',
+        'owner'          => 'test_owner',
+        'group'          => 'test_group',
+        'mode'           => '0644',
+        'ensure_newline' => true,
+      })
+    end
+
+    it do
+      should contain_concat__fragment('/test/path Host test_host').with({
+        'target'  => '/test/path',
+        'content' => 'Host test_host',
+        'order'   => '10',
+        'tag'     => 'test_owner_ssh_config',
+      })
+    end
+  end
+
+  context 'with owner set to valid string <other_owner>' do
+    let(:params) { mandatory_params.merge({ :owner => 'other_owner' }) }
+    it { should contain_concat('/test/path').with_owner('other_owner') }
+    it { should contain_concat__fragment('/test/path Host test_host').with_tag('other_owner_ssh_config') }
+  end
+
+  context 'with group set to valid string <other_group>' do
+    let(:params) { mandatory_params.merge({ :group => 'other_group' }) }
+    it { should contain_concat('/test/path').with_group('other_group') }
+  end
+
+  context 'with path set to valid string </other/path>' do
+    let(:params) { mandatory_params.merge({ :path => '/other/path' }) }
+    it { should contain_concat('/other/path') }
+    it { should contain_concat__fragment('/other/path Host test_host') }
+  end
+
+  context 'with host set to valid string <other_host>' do
+    let(:params) { mandatory_params.merge({ :host => 'other_host' }) }
+    it { should contain_concat__fragment('/test/path Host other_host').with_content('Host other_host') }
+  end
+
+  context 'with order set to valid string <242>' do
+    let(:params) { mandatory_params.merge({ :order => '242' }) }
+    it { should contain_concat__fragment('/test/path Host test_host').with_order('242') }
+  end
+
+# /!\ no functionality for $ensure implemented yet
+#  context 'with ensure set to valid string <absent>' do
+#    let(:params) { mandatory_params.merge({ :ensure => 'absent' }) }
+#    it { should contain_concat('/test/path').with_ensure('absent') }
+#  end
+
+  context 'with lines set to valid array [ <ForwardX11 no>, <StrictHostKeyChecking no> ]' do
+    let(:params) { mandatory_params.merge({ :lines => ['ForwardX11 no', 'StrictHostKeyChecking no'] }) }
+    it { should contain_concat__fragment('/test/path Host test_host').with_content("Host test_host\nForwardX11 no\nStrictHostKeyChecking no") }
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/hiera/hiera.yaml	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,8 @@
+---
+:backends:
+  - yaml
+:yaml:
+  :datadir: 'spec/fixtures/hiera/hieradata'
+:hierarchy:
+  - fqdn/%{fqdn}
+  - specific/%{specific}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/hiera/hieradata/fqdn/hieramerge.example.com.yaml	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,15 @@
+---
+ssh::sshd_config_allowgroups:
+  - allowgroup_from_fqdn
+ssh::sshd_config_allowusers:
+  - allowuser_from_fqdn
+ssh::sshd_config_denygroups:
+  - denygroup_from_fqdn
+ssh::sshd_config_denyusers:
+  - denyuser_from_fqdn
+ssh::config_entries:
+  'user_from_fqdn':
+    owner: 'fqdn_user'
+    group: 'fqdn_user'
+    path:  '/home/fqdn_user/.ssh/config'
+    host:  'fqdn_host.example.local'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/hiera/hieradata/specific/test_hiera_merge.yaml	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,15 @@
+---
+ssh::sshd_config_allowgroups:
+  - allowgroup_from_fact
+ssh::sshd_config_allowusers:
+  - allowuser_from_fact
+ssh::sshd_config_denygroups:
+  - denygroup_from_fact
+ssh::sshd_config_denyusers:
+  - denyuser_from_fact
+ssh::config_entries:
+  'user_from_fact':
+    owner: 'fact_user'
+    group: 'fact_user'
+    path:  '/home/fact_user/.ssh/config'
+    host:  'fact_host.example.local'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_debian	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,61 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts no
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+  UseRoaming no
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_debian10	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,61 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts yes
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+  UseRoaming no
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_debian8	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,61 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts yes
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+  UseRoaming no
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_debian9	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,61 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts yes
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+  UseRoaming no
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_rhel	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,61 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts no
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+  UseRoaming no
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_rhel_old	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,60 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts no
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_solaris	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,54 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_suse	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,61 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts no
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+  UseRoaming no
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_suse_old	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,60 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts no
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_ubuntu1604	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,61 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts yes
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+  UseRoaming no
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_ubuntu1804	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,61 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts yes
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+  UseRoaming no
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/ssh_config_ubuntu2004	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,63 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+Include /etc/ssh/ssh_config.d/*.conf
+
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+   HashKnownHosts yes
+   GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication yes
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+  ForwardX11Trusted yes
+  UseRoaming no
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_debian	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,143 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+#XAuthLocation /usr/bin/xauth
+XAuthLocation /usr/bin/xauth
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/openssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_debian10	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,133 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_ecdsa_key
+HostKey /etc/ssh/ssh_host_ed25519_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/openssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_debian8	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,141 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_ecdsa_key
+HostKey /etc/ssh/ssh_host_ed25519_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/openssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_debian9	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,133 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_ecdsa_key
+HostKey /etc/ssh/ssh_host_ed25519_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/openssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_rhel	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,143 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+#XAuthLocation /usr/bin/xauth
+XAuthLocation /usr/bin/xauth
+
+# override default of no subsystems
+Subsystem sftp /usr/libexec/openssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_rhel7	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,142 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+#XAuthLocation /usr/bin/xauth
+XAuthLocation /usr/bin/xauth
+
+# override default of no subsystems
+Subsystem sftp /usr/libexec/openssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_sles_12_x86_64	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,143 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+#XAuthLocation /usr/bin/xauth
+XAuthLocation /usr/bin/xauth
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/ssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_solaris	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,128 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+ServerKeyBits 768
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+# Use PAM via keyboard interactive method for authentication.
+# Depending on the setup of pam.conf(4) this may allow tunneled clear text
+# passwords even when PasswordAuthentication is set to no. This is dependent
+# on what the individual modules request and is out of the control of sshd
+# or the protocol.
+PAMAuthenticationViaKBDInt yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+GSSAPIKeyExchange yes
+
+
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+#XAuthLocation /usr/bin/xauth
+XAuthLocation /usr/openwin/bin/xauth
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/ssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_suse_i386	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,143 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+#XAuthLocation /usr/bin/xauth
+XAuthLocation /usr/bin/xauth
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/ssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_suse_x86_64	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,143 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+#XAuthLocation /usr/bin/xauth
+XAuthLocation /usr/bin/xauth
+
+# override default of no subsystems
+Subsystem sftp /usr/lib64/ssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_ubuntu1604	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,143 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_ecdsa_key
+HostKey /etc/ssh/ssh_host_ed25519_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/openssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_ubuntu1804	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,143 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_dsa_key
+HostKey /etc/ssh/ssh_host_ecdsa_key
+HostKey /etc/ssh/ssh_host_ed25519_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/openssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/fixtures/sshd_config_ubuntu2004	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,138 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+Include /etc/ssh/sshd_config.d/*.conf
+
+#Port 22
+Port 22
+#Protocol 2,1
+Protocol 2
+#AddressFamily any
+AddressFamily any
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility AUTH
+#LogLevel INFO
+LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime 120
+#PermitRootLogin yes
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication yes
+#PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication yes
+
+# Kerberos options
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication yes
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM yes
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+#AllowTcpForwarding yes
+AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost yes
+#PrintMotd yes
+PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+ClientAliveInterval 0
+ClientAliveCountMax 3
+#ShowPatchLevel no
+#UseDNS yes
+UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#MaxSessions 10
+
+#PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+Banner none
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/openssh/sftp-server
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/spec_helper.rb	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,16 @@
+require 'puppetlabs_spec_helper/module_spec_helper'
+
+RSpec.configure do |config|
+  config.hiera_config = 'spec/fixtures/hiera/hiera.yaml'
+  config.before :each do
+    # Ensure that we don't accidentally cache facts and environment between
+    # test cases.  This requires each example group to explicitly load the
+    # facts being exercised with something like
+    # Facter.collection.loader.load(:ipaddress)
+    Facter.clear
+    Facter.clear_messages
+  end
+  config.default_facts = {
+    :environment => 'rp_env',
+  }
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/spec/unit/facter/ssh_spec.rb	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+describe 'Facter::Util::Fact' do
+
+  version_matrix = {
+    'OpenSSH_5.1p1, OpenSSL 0.9.8a 11 Oct 2005' => { :ssh_version => 'OpenSSH_5.1p1', :ssh_version_numeric => '5.1' }, # SLES 10.4 i586
+    'OpenSSH_5.1p1, OpenSSL 0.9.8j-fips 07 Jan 2009' => { :ssh_version => 'OpenSSH_5.1p1', :ssh_version_numeric => '5.1' }, # SLES 11.2 x86_64
+    'OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013' => { :ssh_version => 'OpenSSH_5.3p1', :ssh_version_numeric => '5.3' }, # CentOS 6.5 / RedHat 6.7 x86_64
+    'OpenSSH_6.2p2, OpenSSL 0.9.8j-fips 07 Jan 2009' => { :ssh_version => 'OpenSSH_6.2p2', :ssh_version_numeric => '6.2' },
+    'OpenSSH_6.6.1p1, OpenSSL 0.9.8j-fips 07 Jan 2009' => { :ssh_version => 'OpenSSH_6.6.1p1', :ssh_version_numeric => '6.6.1' }, # SLES 11.4 x86_64
+    'Sun_SSH_1.1, SSH protocols 1.5/2.0, OpenSSL 0x0090700f' => { :ssh_version => 'Sun_SSH_1.1', :ssh_version_numeric => '1.1' }, # Solaris 9 SPARC
+    'Sun_SSH_1.1.5, SSH protocols 1.5/2.0, OpenSSL 0x0090704f' => { :ssh_version => 'Sun_SSH_1.1.5', :ssh_version_numeric => '1.1.5' }, # Solaris 10 SPARC
+    'broken string' => { :ssh_version => 'broken', :ssh_version_numeric => nil },
+  }
+
+  describe 'ssh_version' do
+    version_matrix.sort.each do |ssh_version_string, result|
+      context "with <#{ssh_version_string}>" do
+        before do
+          Facter.clear
+          # Stub exec for older Facter Otherwise this spec will fail with
+          # unexpected invocation: Facter::Util::Resolution.exec('uname -s')
+          Facter::Util::Resolution.stubs(:exec)
+          Facter::Util::Resolution.stubs(:exec).with('ssh -V 2>&1').returns("#{ssh_version_string}")
+        end
+
+        context "ssh_version should return <#{result[:ssh_version]}>" do
+          it do
+            expect(Facter.fact(:ssh_version).value).to eq(result[:ssh_version])
+          end
+        end
+
+        context "ssh_version_numeric should return <#{result[:ssh_version_numeric]}>" do
+          it do
+            expect(Facter.fact(:ssh_version_numeric).value).to eq(result[:ssh_version_numeric])
+          end
+        end
+      end
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/templates/ssh_config.erb	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,119 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+<% if defined?(@ssh_config_include_real) -%>
+<% if @ssh_config_include_real.is_a? Array -%>
+Include <%= @ssh_config_include_real.join(' ') %>
+<% else -%>
+Include <%= @ssh_config_include_real %>
+<% end -%>
+
+<% end -%>
+# Host *
+#   ForwardAgent no
+#   ForwardX11 no
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+   PasswordAuthentication yes
+   PubkeyAuthentication yes
+#   HostbasedAuthentication no
+<% if @ssh_hostbasedauthentication -%>
+   HostbasedAuthentication <%= @ssh_hostbasedauthentication %>
+<% end -%>
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+<% if @ssh_strict_host_key_checking -%>
+   StrictHostKeyChecking <%= @ssh_strict_host_key_checking %>
+<% end -%>
+#   IdentityFile ~/.ssh/identity
+   IdentityFile ~/.ssh/id_rsa
+   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+   Protocol 2
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+<% if @ssh_config_ciphers -%>
+    Ciphers <%= @ssh_config_ciphers.join(',') %>
+<% end -%>
+<% if @ssh_config_kexalgorithms -%>
+    KexAlgorithms <%= @ssh_config_kexalgorithms.join(',') %>
+<% end -%>
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+#   HashKnownHosts no
+<% if @ssh_config_hash_known_hosts_real != nil -%>
+   HashKnownHosts <%= @ssh_config_hash_known_hosts_real %>
+<% end -%>
+<% if @ssh_config_global_known_hosts_list_real -%>
+   GlobalKnownHostsFile <%= @ssh_config_global_known_hosts_list_real.join(' ') %>
+<% end -%>
+<% if @ssh_config_proxy_command -%>
+   ProxyCommand <%= @ssh_config_proxy_command %>
+<% end -%>
+Host *
+#  GSSAPIAuthentication yes
+  GSSAPIAuthentication <%= @ssh_gssapiauthentication %>
+<% if @ssh_gssapidelegatecredentials != nil -%>
+GSSAPIDelegateCredentials <%= @ssh_gssapidelegatecredentials %>
+<% end -%>
+# If this option is set to yes then remote X11 clients will have full access
+# to the original X11 display. As virtually no X11 client supports the untrusted
+# mode correctly we set this to yes.
+<% if defined?(@ssh_config_forward_x11_trusted_real) -%>
+  ForwardX11Trusted <%= @ssh_config_forward_x11_trusted_real %>
+<% end -%>
+<% if @ssh_config_forward_agent != nil -%>
+  ForwardAgent <%= @ssh_config_forward_agent %>
+<% end -%>
+<% if @ssh_config_forward_x11 != nil -%>
+  ForwardX11 <%= @ssh_config_forward_x11 %>
+<% end -%>
+<% if (@ssh_config_use_roaming_real == 'yes') or (@ssh_config_use_roaming_real == 'no') -%>
+  UseRoaming <%= @ssh_config_use_roaming_real %>
+<% end -%>
+<% if @ssh_config_server_alive_interval != nil -%>
+  ServerAliveInterval <%= @ssh_config_server_alive_interval %>
+<% end -%>
+<% if @ssh_sendenv_real == true -%>
+# Send locale-related environment variables
+  SendEnv LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+  SendEnv LC_IDENTIFICATION LC_ALL
+<% if @ssh_config_sendenv_xmodifiers_real == true -%>
+  SendEnv XMODIFIERS
+<% end -%>
+<% end -%>
+<% if @ssh_config_macs -%>
+  MACs <%= @ssh_config_macs.join(',') %>
+<% end -%>
+<% if not @ssh_enable_ssh_keysign.nil? -%>
+# EnableSSHKeysign no
+  EnableSSHKeysign <%= @ssh_enable_ssh_keysign %>
+<% end -%>
+<% if @ssh_config_user_known_hosts_file -%>
+  UserKnownHostsFile <%= @ssh_config_user_known_hosts_file.join(' ') %>
+<% end -%>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/templates/sshd_config.erb	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,296 @@
+# This file is being maintained by Puppet.
+# DO NOT EDIT
+
+# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+
+# This is the sshd server system-wide configuration file.  See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+<% if defined?(@sshd_config_include_real) -%>
+<% if @sshd_config_include_real.is_a? Array -%>
+Include <%= @sshd_config_include_real.join(' ') %>
+<% else -%>
+Include <%= @sshd_config_include_real %>
+<% end -%>
+
+<% end -%>
+#Port 22
+<% @sshd_config_port_array.each do |p| -%>
+<%= "Port #{p}" %>
+<% end -%>
+#Protocol 2,1
+Protocol 2
+<% if defined?(@sshd_addressfamily_real) -%>
+#AddressFamily any
+AddressFamily <%= @sshd_addressfamily_real %>
+<% end -%>
+<% if @sshd_listen_address.class == Array -%>
+<% @sshd_listen_address.each do |val| -%>
+ListenAddress <%= val %>
+<% end -%>
+<% elsif @sshd_listen_address.class == String -%>
+ListenAddress <%= @sshd_listen_address %>
+<% end -%>
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+<% @sshd_config_hostkey_real.each do |hostkey| -%>
+HostKey <%= hostkey %>
+<% end -%>
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+<% if @sshd_config_serverkeybits_real != nil -%>
+ServerKeyBits <%= @sshd_config_serverkeybits_real %>
+<% end -%>
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+SyslogFacility <%= @sshd_config_syslog_facility %>
+#LogLevel INFO
+LogLevel <%= @sshd_config_loglevel %>
+
+# Authentication:
+
+#LoginGraceTime 120
+LoginGraceTime <%= @sshd_config_login_grace_time %>
+#PermitRootLogin yes
+PermitRootLogin <%= @permit_root_login %>
+#StrictModes yes
+<% if @sshd_config_strictmodes -%>
+StrictModes <%= @sshd_config_strictmodes %>
+<% end -%>
+#MaxAuthTries 6
+<% if @sshd_config_maxauthtries %>
+MaxAuthTries <%= @sshd_config_maxauthtries %>
+<% end -%>
+
+#RSAAuthentication yes
+<% if @sshd_pubkeyacceptedkeytypes -%>
+PubkeyAcceptedKeyTypes <%= @sshd_pubkeyacceptedkeytypes.join(',') %>
+<% end -%>
+#PubkeyAuthentication yes
+PubkeyAuthentication <%= @sshd_pubkeyauthentication %>
+#AuthorizedKeysFile .ssh/authorized_keys
+<% if @sshd_config_authkey_location -%>
+AuthorizedKeysFile <%= @sshd_config_authkey_location %>
+<% end -%>
+<% if @sshd_authorized_keys_command -%>
+AuthorizedKeysCommand <%= @sshd_authorized_keys_command %>
+<% end -%>
+<% if @sshd_authorized_keys_command_user -%>
+AuthorizedKeysCommandUser <%= @sshd_authorized_keys_command_user %>
+<% end -%>
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+HostbasedAuthentication <%= @sshd_hostbasedauthentication %>
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+IgnoreUserKnownHosts <%= @sshd_ignoreuserknownhosts %>
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+IgnoreRhosts <%= @sshd_ignorerhosts %>
+
+<%- if @sshd_config_authenticationmethods -%>
+AuthenticationMethods <%= @sshd_config_authenticationmethods.join(',') %>
+<%- end -%>
+# To disable tunneled clear text passwords, change to no here!
+#PasswordAuthentication yes
+PasswordAuthentication <%= @sshd_password_authentication %>
+<% if @sshd_pamauthenticationviakbdint_real != nil -%>
+# Use PAM via keyboard interactive method for authentication.
+# Depending on the setup of pam.conf(4) this may allow tunneled clear text
+# passwords even when PasswordAuthentication is set to no. This is dependent
+# on what the individual modules request and is out of the control of sshd
+# or the protocol.
+PAMAuthenticationViaKBDInt <%= @sshd_pamauthenticationviakbdint_real %>
+<% end -%>
+#PermitEmptyPasswords no
+<% if @sshd_config_permitemptypasswords != nil -%>
+PermitEmptyPasswords <%= @sshd_config_permitemptypasswords %>
+<% end -%>
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication <%= @sshd_config_challenge_resp_auth %>
+
+# Kerberos options
+<% if @sshd_kerberos_authentication != nil -%>
+#KerberosAuthentication no
+KerberosAuthentication <%= @sshd_kerberos_authentication %>
+<% end -%>
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+GSSAPIAuthentication <%= @sshd_gssapiauthentication %>
+<% if @sshd_gssapikeyexchange_real != nil -%>
+GSSAPIKeyExchange <%= @sshd_gssapikeyexchange_real %>
+<% end -%>
+<% if @sshd_gssapicleanupcredentials_real != nil -%>
+#GSSAPICleanupCredentials yes
+GSSAPICleanupCredentials <%= @sshd_gssapicleanupcredentials_real %>
+<% end -%>
+
+<% if @sshd_use_pam_real != nil -%>
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication mechanism.
+# Depending on your PAM configuration, this may bypass the setting of
+# PasswordAuthentication, PermitEmptyPasswords, and
+# "PermitRootLogin without-password". If you just want the PAM account and
+# session checks to run without PAM authentication, then enable this but set
+# ChallengeResponseAuthentication=no
+#UsePAM no
+UsePAM <%= @sshd_use_pam_real %>
+<% end -%>
+
+<% if @sshd_acceptenv_real == true -%>
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL
+<% end -%>
+#AllowTcpForwarding yes
+AllowTcpForwarding <%= @sshd_allow_tcp_forwarding %>
+#GatewayPorts no
+#X11Forwarding no
+X11Forwarding <%= @sshd_x11_forwarding %>
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+X11UseLocalhost <%= @sshd_x11_use_localhost %>
+#PrintMotd yes
+PrintMotd <%= @sshd_config_print_motd %>
+#PrintLastLog yes
+<% if @sshd_config_print_last_log != nil -%>
+PrintLastLog <%= @sshd_config_print_last_log %>
+<% end -%>
+#TCPKeepAlive yes
+<% if @sshd_config_tcp_keepalive_real != nil -%>
+TCPKeepAlive <%= @sshd_config_tcp_keepalive_real %>
+<% end -%>
+#UseLogin no
+#UsePrivilegeSeparation yes
+<% if @sshd_config_use_privilege_separation != nil -%>
+UsePrivilegeSeparation <%= @sshd_config_use_privilege_separation %>
+<% end -%>
+#PermitUserEnvironment no
+<% if @sshd_config_permituserenvironment != nil -%>
+PermitUserEnvironment <%= @sshd_config_permituserenvironment %>
+<% end -%>
+#Compression delayed
+<% if @sshd_config_compression != nil -%>
+Compression <%= @sshd_config_compression %>
+<% end -%>
+#ClientAliveInterval 0
+ClientAliveInterval <%= @sshd_client_alive_interval %>
+ClientAliveCountMax <%= @sshd_client_alive_count_max %>
+#ShowPatchLevel no
+<% if @sshd_config_use_dns_real != nil -%>
+#UseDNS yes
+UseDNS <%= @sshd_config_use_dns_real %>
+<% end -%>
+#PidFile /var/run/sshd.pid
+<% if @sshd_config_maxstartups -%>
+MaxStartups <%= @sshd_config_maxstartups %>
+<% else -%>
+#MaxStartups 10:30:100
+<% end -%>
+<% if @sshd_config_maxsessions_integer != nil -%>
+MaxSessions <%= @sshd_config_maxsessions_integer %>
+<% else -%>
+#MaxSessions 10
+<% end -%>
+
+#PermitTunnel no
+<% if @sshd_config_permittunnel_real != nil -%>
+PermitTunnel <%= @sshd_config_permittunnel_real %>
+<% end -%>
+<% if @sshd_config_chrootdirectory -%>
+ChrootDirectory <%= @sshd_config_chrootdirectory %>
+<% else -%>
+#ChrootDirectory none
+<% end -%>
+<% if @sshd_config_forcecommand -%>
+ForceCommand <%= @sshd_config_forcecommand %>
+<% end -%>
+<% if @sshd_config_allowagentforwarding != nil -%>
+#AllowAgentForwarding yes
+AllowAgentForwarding <%= @sshd_config_allowagentforwarding %>
+<% end -%>
+
+# no default banner path
+#Banner none
+Banner <%= @sshd_config_banner %>
+
+<% if @sshd_config_xauth_location_real -%>
+#XAuthLocation /usr/bin/xauth
+XAuthLocation <%= @sshd_config_xauth_location_real %>
+
+<% end -%>
+# override default of no subsystems
+Subsystem sftp <%= @sshd_config_subsystem_sftp_real %>
+
+<% if @sshd_config_ciphers -%>
+Ciphers <%= @sshd_config_ciphers.join(',') %>
+<% end -%>
+<% if @sshd_config_kexalgorithms -%>
+KexAlgorithms <%= @sshd_config_kexalgorithms.join(',') %>
+<% end -%>
+<% if @sshd_config_macs -%>
+MACs <%= @sshd_config_macs.join(',') %>
+<% end -%>
+<% if @sshd_config_denyusers_real != [] -%>
+DenyUsers <%= @sshd_config_denyusers_real.join(' ') %>
+<% end -%>
+<% if @sshd_config_denygroups_real != [] -%>
+DenyGroups <%= @sshd_config_denygroups_real.join(' ') %>
+<% end -%>
+<% if @sshd_config_allowusers_real != [] -%>
+AllowUsers <%= @sshd_config_allowusers_real.join(' ') %>
+<% end -%>
+<% if @sshd_config_allowgroups_real != [] -%>
+AllowGroups <%= @sshd_config_allowgroups_real.join(' ') %>
+<% end -%>
+<% if @sshd_config_key_revocation_list_real -%>
+RevokedKeys <%= @sshd_config_key_revocation_list_real %>
+<% end -%>
+<% if @sshd_config_hostcertificate_real.class == Array -%>
+<%   @sshd_config_hostcertificate_real.each do |cert| -%>
+HostCertificate <%= cert %>
+<%   end -%>
+<% elsif @sshd_config_hostcertificate_real.class == String -%>
+HostCertificate <%= @sshd_config_hostcertificate_real %>
+<% end -%>
+<% if @sshd_config_trustedusercakeys_real -%>
+TrustedUserCAKeys <%= @sshd_config_trustedusercakeys_real %>
+<% end -%>
+<% if @sshd_config_authorized_principals_file_real -%>
+AuthorizedPrincipalsFile <%= @sshd_config_authorized_principals_file_real %>
+<% end -%>
+<% if @sshd_config_match -%>
+
+<%   @sshd_config_match.sort.each do |key, hash| -%>
+Match <%= key %>
+<%     hash.sort.each do |values| -%>
+  <%= values %>
+<%     end -%>
+<%   end -%>
+<% end -%>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ssh/tests/init.pp	Mon Jan 03 17:05:54 2022 +0000
@@ -0,0 +1,1 @@
+include ::ssh