diff --git a/root/usr/share/perl5/vendor_perl/esmith/ssl.pm b/root/usr/share/perl5/vendor_perl/esmith/ssl.pm index d35390f..85449ff 100644 --- a/root/usr/share/perl5/vendor_perl/esmith/ssl.pm +++ b/root/usr/share/perl5/vendor_perl/esmith/ssl.pm @@ -6,18 +6,26 @@ use esmith::ConfigDB; our @ISA = qw(Exporter); -our @EXPORT = qw( key_exists_good_size cert_exists_good_size cert_is_cert key_is_key related_key_cert); +our @EXPORT = qw( key_exists_good_size cert_exists_good_size cert_is_cert key_is_key related_key_cert SSLproto SSLprotoApache SSLprotoComa SSLprotoHyphen SSLprotoMin SSLprotoLDAP SSLprotoQpsmtpd $smeCiphers $smeSSLprotocol %existingSSLprotos); my $configdb = esmith::ConfigDB->open_ro or die "Could not open accounts db"; our $SystemName = $configdb->get('SystemName')->value; our $DomainName = $configdb->get('DomainName')->value; our $FQDN = "$SystemName.$DomainName"; -# test key size -# test key exists +#default cipher list +our $smeCiphers = "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:!ADH:!SSLv2:!ADH:!aNULL:!MD5:!RC4"; +#default protocol list +# 2024 phase out : TLS 1.1 and 1.0 ; insuficient: SSL 3.0, 2.0 and 1.0 +our $smeSSLprotocol = "TLSv1.2 TLSv1.3"; + +# SSLv2 and SSLv3 are not available in el8 openssl-1.1.1, while -ssl3 still in man page +# it will throw Option unknown option -ssl3 +our %existingSSLprotos=%{ {'SSLv3'=>1, 'TLSv1'=>1, 'TLSv1.1'=>1, 'TLSv1.2'=>1, 'TLSv1.3'=>1}}; + =head1 NAME -esmith::php - A few tools to help with php-fpm installed versions +esmith::ssl - A few tools to help with ssl handling =head1 SYNOPSIS @@ -42,6 +50,7 @@ returns 0 if key is missing or wrong size returns 1 if key exists and key size is correct =cut + sub key_exists_good_size { my $configdb = esmith::ConfigDB->open_ro or die "Could not open accounts db"; my %modSSL = $configdb->as_hash('modSSL'); @@ -74,8 +83,8 @@ sub key_exists_good_size { # check cert size Public-Key # openssl rsa -noout -modulus -in domain.key | openssl md5 # openssl x509 -noout -modulus -in domain.crt | openssl md5 - =cut + sub cert_exists_good_size { my $configdb = esmith::ConfigDB->open_ro or die "Could not open accounts db"; my %modSSL = $configdb->as_hash('modSSL'); @@ -99,6 +108,10 @@ sub cert_exists_good_size { return 0; } +=head2 cert_is_cert +check if file is really a certificate +=cut + sub cert_is_cert { my $crt = shift || "/home/e-smith/ssl.crt/$FQDN.crt"; if ( -f $crt ) @@ -115,6 +128,10 @@ sub cert_is_cert { return 0; } +=head2 key_is_key +check if file is really a key +=cut + sub key_is_key { my $key = shift || "/home/e-smith/ssl.key/$FQDN.key"; if ( -f $key ) @@ -144,7 +161,8 @@ sub related_key_cert { } return 0; } -##TODO migrate those actions from + +##TODO write sub and migrate those actions from template fragments # check cert is related to key # => /etc/e-smith/templates/home/e-smith/ssl.crt # check cert domain and alt @@ -152,3 +170,125 @@ sub related_key_cert { # check is valid / expiry date # => /etc/e-smith/templates/home/e-smith/ssl.crt ################################### + +=head2 SSLprotoApache +output a list of allowed protocols with apache format +e.g. -all +TLSv1.2 +TLSv1.3 +=cut + +sub SSLprotoApache{ + my $protocols = " -all +".join(" +",split(" ",$smeSSLprotocol)) ." "; + my $configdb = esmith::ConfigDB->open_ro or die "Could not open accounts db"; + my $httpd = $configdb->get('httpd-e-smith'); + # SSLv2 and SSLv3 are not available in el8 openssl-1.1.1, while -ssl3 still referenced + # it will throw Option unknown option -ssl3 + #$protocols .= " +SSLv3" if ($httpd->{'SSLv3'} || 'disabled') eq 'enabled'; + # TODO: a loop using existingSSLprotos + $protocols .= " +TLSv1" if ($httpd->{'TLSv1'} || 'disabled') eq 'enabled'; + $protocols .= " +TLSv1.1" if ($httpd->{'TLSv1.1'} || 'disabled') eq 'enabled'; + # look closely this is to remove what has been added on first line, + # hence the minus sign and reverse logic. + $protocols .= " -TLSv1.2" unless ($httpd->{'TLSv1.2'} || 'enabled') eq 'enabled'; + $protocols .= " -TLSv1.3" unless ($httpd->{'TLSv1.3'} || 'enabled') eq 'enabled'; + return $protocols; +} + +=head2 SSLprotoQpsmtpd +output an expected IO::Socket::SSL string to enable +only the wanted TLS versions +SSLv23:!SSLv2:!SSLv3:!TLSv1:!TLSv1_1 +=cut + +sub SSLprotoQpsmtpd{ + my $configdb = esmith::ConfigDB->open_ro or die "Could not open accounts db"; + my %qpsmtpd = %{$configdb->get('httpd-e-smith')}; + # SSLv2 and SSLv3 are not available in el8 openssl-1.1.1, while -ssl3 still referenced + # it will throw Option unknown option -ssl3 + my $protocols = "SSLv23:!SSLv2:!SSLv3"; + # TODO: a loop using existingSSLprotos and SSLprotoHyphen() + $protocols .= ':!TLSv1' unless ($qpsmtpd{'TLSv1'} || 'disabled') eq 'enabled'; + $protocols .= ':!TLSv1_1' unless ($qpsmtpd{'TLSv1.1'} || 'disabled') eq 'enabled'; + $protocols .= ':!TLSv1_2' unless ($qpsmtpd{'TLSv1.2'} || 'enabled') eq 'enabled'; + $protocols .= ':!TLSv1_3' unless ($qpsmtpd{'TLSv1.3'} || 'enabled') eq 'enabled'; + return $protocols; +} + +=head2 SSLproto +default display of list of protocol. This is how it will be displayed in +httpd.conf and proftpd.conf +e.g. TLSv1.2 TLSv1.3 +=cut + +sub SSLproto{ +return $smeSSLprotocol; +} + +=head2 SSLprotoComa +way to display protocols in Mariadb as a string list separated by coma +e.g. TLSv1.2,TLSv1.3 +=cut + +sub SSLprotoComa{ +my $string = shift || $smeSSLprotocol; +$string =~ s/[ :]/,/g; +return $string; +} + +=head2 SSLprotoHyphen +convert TLSv1.2 to TLSv1_2 +This is the format required by perl IO::Socket::SSL; and as the result by +qpsmtpd, uqpsmtpd, sqpsmtpd SME Server services +=cut + +sub SSLprotoHyphen { +my $string = shift || $smeSSLprotocol; +$string =~ s/[ ,]/:/g; +$string =~ s/\./_/g; +return $string; +} + +=head2 SSLprotoMin +display only the lower protocol, as expected for dovecot +ssl_min_protocol = TLSv1.2 +# limit : will not handle all or sslv23 as input +=cut + +sub SSLprotoMin{ + my @SSLarray = split(" ",shift || $smeSSLprotocol); + my %hash ; + foreach my $value (@SSLarray) { + my $toto = $value =~ s/(.*)(\d{1})+$/$2/r; + # hack for TLS > SSL + $toto = ($value =~ /^TLS/) ? "2$toto" : "1$toto"; + $hash{$toto}=$value ; + } + my @keys_sorted_by_value = sort { $a <=> $b } keys %hash; + my $lowest_value = $keys_sorted_by_value[0] ; + return $hash{$lowest_value}; +} + +=head2 SSLprotoLDAP +convert min protocol suported to LDAP format +TLSProtocolMin 3.3 +To require TLS 1.x or higher, set this option to 3.(x+1), e.g., TLSProtocolMin 3.2 would require TLS 1.1. +from $smeSSLprotocol = "TLSv1.2 TLSv1.3"; +=cut + +sub SSLprotoLDAP{ + # convert to array + my @SSLarray = split(" ",shift || $smeSSLprotocol); + return "3.0" if (grep /^SSLv3$/, @SSLarray); + # TLSv1 + return "3.1" if (grep /^TLSv1$/ , @SSLarray); + # keep only digit after . + @SSLarray = grep{ $_ =~ s/(.*)(\d{1})+$/$2/ } @SSLarray; + # order + @SSLarray = sort @SSLarray; + # get lower + my $num = $SSLarray[0]; + # sum 3.1 + 0.$x + $num = "0.".$num; + # return + $num = $num +3.1; + return $num; +} diff --git a/smeserver-base.spec b/smeserver-base.spec index 3a9a8c9..5023529 100644 --- a/smeserver-base.spec +++ b/smeserver-base.spec @@ -4,7 +4,7 @@ Summary: smeserver server and gateway - base module %define name smeserver-base Name: %{name} %define version 11.0.0 -%define release 21 +%define release 22 Version: %{version} Release: %{release}%{?dist} License: GPL @@ -184,6 +184,11 @@ fi %changelog +* Sat Jan 18 2025 Jean-Philippe Pialasse 11.0.0-22.sme +- handle all ssl ciphers and protocol in one place esmith::ssl [SME: 12827] + this will allow to sync all service default protocol and ciphers + in one place. + * Fri Jan 03 2025 Jean-Philippe Pialasse 11.0.0-21.sme - improve support of systemd service with instance service@instance.service [SME: 12859]