Enhance compatibility with Solaris

Some OpenSSH parameters are not compatible with Solaris SSH.
They do break if they are included into the configuration file(s).

This patch does not include them by default on Solaris anymore.

Changed parameters:
sshd_config_tcp_keepalive   (TCPKeepAlive in sshd_config)
sshd_config_permittunnel    (PermitTunnel in sshd_config)
sshd_config_maxsessions     (MaxSessions  in sshd_config)
ssh_config_hash_known_hosts (HashKnownHosts in ssh_config)
diff --git a/README.md b/README.md
index 1a13b86..160668a 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,14 @@
  * 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
@@ -63,6 +71,8 @@
 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
@@ -451,22 +461,29 @@
 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.
-The default is ``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.
+A value of 'unset' will not add this parameter to the configuration file.
 
-- *Default*: 'yes'
+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_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), or 'no'.
-Specifying 'yes' permits both 'point-to-point' and 'ethernet'.  The
-default is 'no'.
+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.
 
-- *Default*: 'no'
+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
 -------------------
@@ -519,6 +536,7 @@
 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
 
diff --git a/manifests/init.pp b/manifests/init.pp
index 809e911..a10df3f 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -109,8 +109,8 @@
   $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           = 'yes',
-  $sshd_config_permittunnel            = 'no',
+  $sshd_config_tcp_keepalive           = undef,
+  $sshd_config_permittunnel            = undef,
 ) {
 
   case $::osfamily {
@@ -136,6 +136,8 @@
       $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'
     }
     'Suse': {
       $default_packages                        = 'openssh'
@@ -157,6 +159,8 @@
       $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'
       case $::architecture {
         'x86_64': {
           if ($::operatingsystem == 'SLES') and ($::operatingsystemrelease =~ /^12\./) {
@@ -207,6 +211,8 @@
       $default_service_hasstatus               = true
       $default_sshd_config_serverkeybits       = '1024'
       $default_sshd_addressfamily              = 'any'
+      $default_sshd_config_tcp_keepalive       = 'yes'
+      $default_sshd_config_permittunnel        = 'no'
     }
     'Solaris': {
       $default_ssh_config_hash_known_hosts     = undef
@@ -225,6 +231,8 @@
       $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
       case $::kernelrelease {
         '5.11': {
           $default_packages                      = ['network/ssh',
@@ -285,10 +293,10 @@
     $packages_real = $packages
   }
 
-  if $ssh_config_hash_known_hosts == 'USE_DEFAULTS' {
-    $ssh_config_hash_known_hosts_real = $default_ssh_config_hash_known_hosts
-  } else {
-    $ssh_config_hash_known_hosts_real = $ssh_config_hash_known_hosts
+  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' {
@@ -459,6 +467,23 @@
     $sshd_addressfamily_real = $sshd_addressfamily
   }
 
+  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 }
+  }
+
   # validate params
   if $ssh_config_ciphers != undef {
     validate_array($ssh_config_ciphers)
@@ -485,7 +510,7 @@
   }
 
   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' or 'no' and is set to <${ssh_config_hash_known_hosts_real}>.")
+    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}>.")
@@ -582,13 +607,6 @@
       "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_maxsessions != undef {
-    $is_int_sshd_config_maxsessions = is_integer($sshd_config_maxsessions)
-    if $is_int_sshd_config_maxsessions == false {
-      fail("sshd_config_maxsessions must be an integer. Detected value is ${sshd_config_maxsessions}.")
-    }
-  }
-
   if $sshd_config_chrootdirectory != undef {
     validate_absolute_path($sshd_config_chrootdirectory)
   }
@@ -781,9 +799,14 @@
     validate_array($sshd_config_allowgroups_real)
   }
 
-  validate_re($sshd_config_tcp_keepalive, '^(yes|no)$', "ssh::sshd_config_tcp_keepalive may be either 'yes' or 'no' and is set to <${sshd_config_tcp_keepalive}>.")
 
-  validate_re($sshd_config_permittunnel, '^(yes|no|point-to-point|ethernet)$', "ssh::sshd_config_permittunnel may be either 'yes', 'point-to-point', 'ethernet' or 'no' and is set to <${sshd_config_permittunnel}>.")
+  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_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}>.")
+  }
 
   package { $packages_real:
     ensure    => installed,
diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb
index bb28fe4..a6f305e 100644
--- a/spec/classes/init_spec.rb
+++ b/spec/classes/init_spec.rb
@@ -806,13 +806,27 @@
     end
   end
 
-  context 'with ssh_config_hash_known_hosts set to invalid value on valid osfamily' do
-    let(:params) { { :ssh_config_hash_known_hosts => 'invalid' } }
+  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 } }
 
-    it 'should fail' do
-      expect {
-        should contain_class('ssh')
-      }.to raise_error(Puppet::Error,/ssh::ssh_config_hash_known_hosts may be either \'yes\' or \'no\' and is set to <invalid>\./)
+        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
 
@@ -971,11 +985,15 @@
   end
 
   describe 'sshd_config_permittunnel param' do
-    ['yes','point-to-point','ethernet','no'].each do |value|
+    ['yes','point-to-point','ethernet','no','unset'].each do |value|
       context "set to #{value}" do
         let (:params) { { :sshd_config_permittunnel => value } }
 
-        it { should contain_file('sshd_config').with_content(/^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
 
@@ -985,7 +1003,7 @@
       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\' or \'no\' and is set to <invalid>\./)
+        }.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
@@ -1812,6 +1830,12 @@
       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' } }
 
@@ -2267,13 +2291,25 @@
   end
 
   describe 'sshd_config_tcp_keepalive param' do
-    context 'when set to invalid' do
-      let(:params) { { :sshd_config_tcp_keepalive => 'invalid' } }
+    ['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\' or \'no\' and is set to <invalid>\./)
+        }.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
diff --git a/spec/fixtures/sshd_config_solaris b/spec/fixtures/sshd_config_solaris
index d9c4b60..653deb5 100644
--- a/spec/fixtures/sshd_config_solaris
+++ b/spec/fixtures/sshd_config_solaris
@@ -101,7 +101,6 @@
 PrintMotd yes
 #PrintLastLog yes
 #TCPKeepAlive yes
-TCPKeepAlive yes
 #UseLogin no
 #UsePrivilegeSeparation yes
 #PermitUserEnvironment no
@@ -115,7 +114,6 @@
 #MaxSessions 10
 
 #PermitTunnel no
-PermitTunnel no
 #ChrootDirectory none
 
 # no default banner path
diff --git a/templates/sshd_config.erb b/templates/sshd_config.erb
index 89752a1..51c3196 100644
--- a/templates/sshd_config.erb
+++ b/templates/sshd_config.erb
@@ -166,7 +166,9 @@
 PrintMotd <%= @sshd_config_print_motd %>
 #PrintLastLog yes
 #TCPKeepAlive yes
-TCPKeepAlive <%= @sshd_config_tcp_keepalive %>
+<% if @sshd_config_tcp_keepalive_real != nil -%>
+TCPKeepAlive <%= @sshd_config_tcp_keepalive_real %>
+<% end -%>
 #UseLogin no
 #UsePrivilegeSeparation yes
 #PermitUserEnvironment no
@@ -188,14 +190,16 @@
 <% else -%>
 #MaxStartups 10:30:100
 <% end -%>
-<% if @sshd_config_maxsessions -%>
-MaxSessions <%= @sshd_config_maxsessions %>
+<% if @sshd_config_maxsessions_integer != nil -%>
+MaxSessions <%= @sshd_config_maxsessions_integer %>
 <% else -%>
 #MaxSessions 10
 <% end -%>
 
 #PermitTunnel no
-PermitTunnel <%= @sshd_config_permittunnel %>
+<% if @sshd_config_permittunnel_real != nil -%>
+PermitTunnel <%= @sshd_config_permittunnel_real %>
+<% end -%>
 <% if @sshd_config_chrootdirectory -%>
 ChrootDirectory <%= @sshd_config_chrootdirectory %>
 <% else -%>