ERRORS=0
# Count the exit status of the last command
-function check () {
- ERRORS=$(($ERRORS+$?))
+function check() {
+ ERRORS=$(($ERRORS + $?))
}
-function dialog () {
+function dialog() {
echo -n "PLC: $*: " >&3
}
# Print result
-function result () {
- if [ $ERRORS -eq 0 ] ; then
+function result() {
+ if [ $ERRORS -eq 0 ]; then
success "$@" >&3
else
failure "$@" >&3
}
# Start up a program with a plc_ prefix
-function plc_daemon () {
+function plc_daemon() {
base=${1##*/}
# See if it's already running. Look *only* at the pid file.
if [ -f /var/run/plc_${base}.pid ]; then
local line p
- read line < /var/run/plc_${base}.pid
- for p in $line ; do
- [ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid $p"
+ read line </var/run/plc_${base}.pid
+ for p in $line; do
+ [ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid $p"
done
fi
# #1 0x003c2e7d in ___newselect_nocancel () from /lib/libc.so.6
# #2 0x004387b4 in main () from /usr/sbin/sshd
# So I figured the various file descriptors used were not properly closed
- (exec 3>&- 4>&- ; exec -a plc_${base} $*)
+ (
+ exec 3>&- 4>&-
+ exec -a plc_${base} $*
+ )
ret=$?
- if [ -f /var/run/${base}.pid ] ; then
+ if [ -f /var/run/${base}.pid ]; then
mv /var/run/${base}.pid /var/run/plc_${base}.pid
fi
}
# Print IP address of hostname if resolvable
-function gethostbyname () {
+function gethostbyname() {
local host="$1"; shift
python3 -c "import socket; import sys; print(socket.gethostbyname('${host}'))"
}
# Forcefully make a symlink
-function symlink () {
+function symlink() {
mkdir -p $(dirname $2)
rm -f $2
ln -s $1 $2
}
# Argument(s) or stdin to lowercase stdout
-function lower () {
- if [ ${#*} -ge 1 ] ; then
+function lower() {
+ if [ ${#*} -ge 1 ]; then
tr A-Z a-z <<<$*
else
tr A-Z a-z
}
# Argument(s) or stdin to uppercase stdout
-function upper () {
- if [ ${#*} -ge 1 ] ; then
+function upper() {
+ if [ ${#*} -ge 1 ]; then
tr a-z A-Z <<<$*
else
tr a-z A-Z
}
# Regenerate configuration files
-function plc_reload () {
+function plc_reload() {
force=$1
# Regenerate the main configuration file from default values
/etc/planetlab/configs/site.xml
)
- for file in "${files[@]}" ; do
- if [ -n "$force" -o $file -nt /etc/planetlab/plc_config.xml ] ; then
- tmp=$(mktemp /tmp/plc_config.xml.XXXXXX)
- plc-config --xml "${files[@]}" >$tmp
- if [ $? -eq 0 ] ; then
- mv $tmp /etc/planetlab/plc_config.xml
- chmod 444 /etc/planetlab/plc_config.xml
- else
- echo "PLC: Warning: Invalid configuration file(s) detected"
- rm -f $tmp
+ for file in "${files[@]}"; do
+ if [ -n "$force" -o $file -nt /etc/planetlab/plc_config.xml ]; then
+ tmp=$(mktemp /tmp/plc_config.xml.XXXXXX)
+ plc-config --xml "${files[@]}" >$tmp
+ if [ $? -eq 0 ]; then
+ mv $tmp /etc/planetlab/plc_config.xml
+ chmod 444 /etc/planetlab/plc_config.xml
+ else
+ echo "PLC: Warning: Invalid configuration file(s) detected"
+ rm -f $tmp
+ fi
+ break
fi
- break
- fi
done
# Convert configuration to various formats
- if [ -n "$force" -o /etc/planetlab/plc_config.xml -nt /etc/planetlab/plc_config ] ; then
- plc-config --shell >/etc/planetlab/plc_config
+ if [ -n "$force" -o /etc/planetlab/plc_config.xml -nt /etc/planetlab/plc_config ]; then
+ plc-config --shell >/etc/planetlab/plc_config
fi
- if [ -n "$force" -o /etc/planetlab/plc_config.xml -nt /etc/planetlab/plc_config.py ] ; then
- plc-config --python >/etc/planetlab/plc_config.py
+ if [ -n "$force" -o /etc/planetlab/plc_config.xml -nt /etc/planetlab/plc_config.py ]; then
+ plc-config --python >/etc/planetlab/plc_config.py
fi
- if [ -n "$force" -o /etc/planetlab/plc_config.xml -nt /etc/planetlab/php/plc_config.php ] ; then
- mkdir -p /etc/planetlab/php
- plc-config --php >/etc/planetlab/php/plc_config.php
+ if [ -n "$force" -o /etc/planetlab/plc_config.xml -nt /etc/planetlab/php/plc_config.php ]; then
+ mkdir -p /etc/planetlab/php
+ plc-config --php >/etc/planetlab/php/plc_config.php
fi
}
# Require all granted
# </Directory>
-function apache_newauth () {
+function apache_newauth() {
# somehow in 2019 apachectl stopped answering the -V option
# apache_version=$(apachectl -V 2> /dev/null | grep 'Server version' | cut -d ' ' -f3 | sed -e 's,^.*/,,')
apache_version=$(rpm -q --queryformat "%{VERSION}" httpd)
apache_minor=$(echo $apache_version | cut -d. -f2)
test "$apache_minor" -ge 4
}
-function apache_allow () {
+function apache_allow() {
if apache_newauth; then
echo -e "Require all granted"
else
echo -e "Order allow,deny\n Allow from all"
fi
}
-function apache_forbid () {
+function apache_forbid() {
if apache_newauth; then
echo -e "Require all denied"
else
php_fpm_dir=$(dirname $php_fpm_conf)
function disable_file () {
- file=$1; shift
+ local file=$1; shift
[ -f $file ] && mv -f $file $file.disabled
}
function enable_file () {
- file=$1; shift
+ local file=$1; shift
[ ! -f $file ] && mv -f $file.disabled $file
}
case "$1" in
start)
- if [ "$PLC_API_ENABLED" != "1" -a \
- "$PLC_BOOT_ENABLED" != "1" -a \
- "$PLC_WWW_ENABLED" != "1" ] ; then
- exit 0
- fi
-
- MESSAGE=$"Starting web server"
- dialog "$MESSAGE"
-
- # set document root - not really useful on fedora but just in case
- sed -i -e "s@^DocumentRoot.*@DocumentRoot \"$DocumentRoot\"@" $httpd_conf
- # whether WWW is enabled or not :
- if [ "$PLC_WWW_ENABLED" != "1" ] ; then
- # avoid hitting drupal, that would try to connect to the db and create noise
- disable_file $DocumentRoot/index.php
- else
- enable_file $DocumentRoot/index.php
- fi
-
- # Set the default include path
- include_path=".:$DocumentRoot/planetlab/includes:$DocumentRoot/plekit/php:$DocumentRoot/generated:/etc/planetlab/php:/usr/share/plc_api/php"
- sed -i -e "s@[;]*include_path = \"\.:.*\"@include_path = \"$include_path\"@" $php_ini
-
- # Set open_basedir so as to avoid leaks
- open_basedir="$DocumentRoot:/etc/planetlab/php:/usr/share/plc_api/php:/var/log/myslice:/var/tmp/bootmedium:/var/log/bm:/tmp"
- sed -i -e "s@[;]*open_basedir =.*@open_basedir = \"$open_basedir\"@" $php_ini
-
- # for php-5.3 under fedora12, otherwise issues tons of warning messages
- # Set timezone in php.ini if not already there
- if grep '^;date.timezone' $php_ini >& /dev/null; then
- dialog 'Setting PHP timezone to GMT'
- sed -i -e 's,^;date.timezone.*,date.timezone = GMT,' $php_ini
- fi
-
- if grep '^short_open_tag = Off' $php_ini >& /dev/null; then
- sed -i -e 's,^short_open_tag = Off,short_open_tag = On,' $php_ini
- fi
-
- ## patch php.ini
- # memory limit
- sed -i -e 's,^memory_limit = 32M *;,memory_limit = 80M ; patch myplc -- ,' $php_ini
- # log_errors : is On by default
- # error_log
- if ! grep '^error_log *=' $php_ini > /dev/null ; then
- sed -i -e '/^;error_log = syslog/a error_log = /var/log/php.log' $php_ini
- sed -i -e 's/display_errors =.*/display_errors = On/' $php_ini
- sed -i -e 's/display_startup_errors =.*/display_startup_errors = On/' $php_ini
- # create the log file and make it writable by apache
- touch /var/log/php.log
- chmod 666 /var/log/php.log
- fi
-
- # configure php-fpm as well if present (starting with f27)
- if [ -d $php_fpm_dir ] ; then
- cat > $php_fpm_conf << EOF
+ if [ "$PLC_API_ENABLED" != "1" -a \
+ "$PLC_BOOT_ENABLED" != "1" -a \
+ "$PLC_WWW_ENABLED" != "1" ] ; then
+ exit 0
+ fi
+
+ MESSAGE=$"Starting web server"
+ dialog "$MESSAGE"
+
+ # set document root - not really useful on fedora but just in case
+ sed -i -e "s@^DocumentRoot.*@DocumentRoot \"$DocumentRoot\"@" $httpd_conf
+ # whether WWW is enabled or not :
+ if [ "$PLC_WWW_ENABLED" != "1" ] ; then
+ # avoid hitting drupal, that would try to connect to the db and create noise
+ disable_file $DocumentRoot/index.php
+ else
+ enable_file $DocumentRoot/index.php
+ fi
+
+ # Set the default include path
+ include_path=".:$DocumentRoot/planetlab/includes:$DocumentRoot/plekit/php:$DocumentRoot/generated:/etc/planetlab/php:/usr/share/plc_api/php"
+ sed -i -e "s@[;]*include_path = \"\.:.*\"@include_path = \"$include_path\"@" $php_ini
+
+ # Set open_basedir so as to avoid leaks
+ open_basedir="$DocumentRoot:/etc/planetlab/php:/usr/share/plc_api/php:/var/log/myslice:/var/tmp/bootmedium:/var/log/bm:/tmp"
+ sed -i -e "s@[;]*open_basedir =.*@open_basedir = \"$open_basedir\"@" $php_ini
+
+ # for php-5.3 under fedora12, otherwise issues tons of warning messages
+ # Set timezone in php.ini if not already there
+ if grep '^;date.timezone' $php_ini >& /dev/null; then
+ dialog 'Setting PHP timezone to GMT'
+ sed -i -e 's,^;date.timezone.*,date.timezone = GMT,' $php_ini
+ fi
+
+ if grep '^short_open_tag = Off' $php_ini >& /dev/null; then
+ sed -i -e 's,^short_open_tag = Off,short_open_tag = On,' $php_ini
+ fi
+
+ ## patch php.ini
+ # memory limit
+ sed -i -e 's,^memory_limit = 32M *;,memory_limit = 80M ; patch myplc -- ,' $php_ini
+ # log_errors : is On by default
+ # error_log
+ if ! grep '^error_log *=' $php_ini > /dev/null ; then
+ sed -i -e '/^;error_log = syslog/a error_log = /var/log/php.log' $php_ini
+ sed -i -e 's/display_errors =.*/display_errors = On/' $php_ini
+ sed -i -e 's/display_startup_errors =.*/display_startup_errors = On/' $php_ini
+ # create the log file and make it writable by apache
+ touch /var/log/php.log
+ chmod 666 /var/log/php.log
+ fi
+
+ # configure php-fpm as well if present (starting with f27)
+ if [ -d $php_fpm_dir ] ; then
+ cat > $php_fpm_conf << EOF
[www]
php_value[include_path] = $include_path
php_value[open_basedir] = $open_basedir
php_value[short_open_tag] = On
php_value[memory_limit] = 80M
EOF
- # this is needed because otherwise, the first time
- # we do this configuration, the service is already up
- # and the config is usable only the second time
- systemctl restart php-fpm
- fi
-
- # Disable default Listen directive
- sed -i -e '/^Listen/d' $httpd_conf
-
- plc_api_path_noslash=$(echo $PLC_API_PATH | sed -e s,/,,g)
- # Set the port numbers
- for server in WWW API BOOT ; do
- enabled=PLC_${server}_ENABLED
- if [ "${!enabled}" != "1" ] ; then
- continue
- fi
- hostname=PLC_${server}_HOST
- http_port=PLC_${server}_PORT
- https_port=PLC_${server}_SSL_PORT
-
- # API should always be accessed via SSL
- if [ "$server" = "API" ] ; then
- https_port=${!http_port}
- http_port=
- fi
-
- # Check if we are already listening on these ports
- skip_http=0
- skip_https=0
- for previous_server in WWW API BOOT ; do
- if [ "$server" = "$previous_server" ] ; then
- break
- fi
- previous_enabled=PLC_${previous_server}_ENABLED
- if [ "${!previous_enabled}" != "1" ] ; then
- continue
+ # this is needed because otherwise, the first time
+ # we do this configuration, the service is already up
+ # and the config is usable only the second time
+ systemctl restart php-fpm
fi
- previous_http_port=PLC_${previous_server}_PORT
- previous_https_port=PLC_${previous_server}_SSL_PORT
-
- if [ -z "${http_port}" ]; then
- skip_http=1;
- elif [ -z "${!http_port}" ]; then
- skip_http=1;
- elif [ "${!http_port}" = "${!previous_http_port}" ] ; then
- skip_http=1
- fi
- if [ -z "${https_port}" ]; then
- skip_https=1
- elif [ -z "${!https_port}" ]; then
- skip_https=1
- elif [ "${!https_port}" = "${!previous_https_port}" ] ; then
- skip_https=1
- fi
- done
- # HTTP configuration
- if [ $skip_http -eq 0 ] ; then
- cat <<EOF
+ # Disable default Listen directive
+ sed -i -e '/^Listen/d' $httpd_conf
+
+ plc_api_path_noslash=$(echo $PLC_API_PATH | sed -e s,/,,g)
+ # Set the port numbers
+ for server in WWW API BOOT ; do
+ enabled=PLC_${server}_ENABLED
+ if [ "${!enabled}" != "1" ] ; then
+ continue
+ fi
+ hostname=PLC_${server}_HOST
+ http_port=PLC_${server}_PORT
+ https_port=PLC_${server}_SSL_PORT
+
+ # API should always be accessed via SSL
+ if [ "$server" = "API" ] ; then
+ https_port=${!http_port}
+ http_port=
+ fi
+
+ # Check if we are already listening on these ports
+ skip_http=0
+ skip_https=0
+ for previous_server in WWW API BOOT ; do
+ if [ "$server" = "$previous_server" ] ; then
+ break
+ fi
+ previous_enabled=PLC_${previous_server}_ENABLED
+ if [ "${!previous_enabled}" != "1" ] ; then
+ continue
+ fi
+ previous_http_port=PLC_${previous_server}_PORT
+ previous_https_port=PLC_${previous_server}_SSL_PORT
+
+ if [ -z "${http_port}" ]; then
+ skip_http=1;
+ elif [ -z "${!http_port}" ]; then
+ skip_http=1;
+ elif [ "${!http_port}" = "${!previous_http_port}" ] ; then
+ skip_http=1
+ fi
+ if [ -z "${https_port}" ]; then
+ skip_https=1
+ elif [ -z "${!https_port}" ]; then
+ skip_https=1
+ elif [ "${!https_port}" = "${!previous_https_port}" ] ; then
+ skip_https=1
+ fi
+ done
+
+ # HTTP configuration
+ if [ $skip_http -eq 0 ] ; then
+ cat <<EOF
Listen ${!http_port}
<VirtualHost *:${!http_port}>
# Make sure that the admin web pages are always accessed via SSL
</VirtualHost>
EOF
- fi
-
- # HTTPS configuration
- if [ $skip_https -eq 0 ] ; then
- # XXX Cannot support NameVirtualHost over SSL. If
- # the API, boot, and web servers are all running
- # on the same machine, the web server certificate
- # takes precedence.
- sed -i \
- -e "s/^Listen .*/Listen ${!https_port}/" \
- -e "s/<VirtualHost _default_:.*>/<VirtualHost _default_:${!https_port}>/" \
- $ssl_conf
- # this is used to locate the right certificates
- server_lower=$(echo $server | tr 'A-Z' 'a-z')
-
- # which one is used is currently configured in myplc.spec,
- # with mod_python preferred
- if rpm -q mod_python >& /dev/null ; then
- configure_for_mod_python=true
- elif rpm -q mod_wsgi >& /dev/null \
- || rpm -q python2-mod_wsgi >& /dev/null \
- || rpm -q python3-mod_wsgi >& /dev/null ; then
- configure_for_mod_wsgi=true
- else
- echo "Requires mod_python or mod_wsgi.... exiting"
- exit 1
- fi
-
- # It would be tempting to use <IfModule> here
- # but early tests showed this could be tricky/fragile
- # So let's hard-wire it for one module
- # A lot of trial-and -error was involved in getting this that way...
-
- if [ -n "$configure_for_mod_python" ] ; then
-#################### for mod_python
- cat <<EOF
+ fi
+
+ # HTTPS configuration
+ if [ $skip_https -eq 0 ] ; then
+ # XXX Cannot support NameVirtualHost over SSL. If
+ # the API, boot, and web servers are all running
+ # on the same machine, the web server certificate
+ # takes precedence.
+ sed -i \
+ -e "s/^Listen .*/Listen ${!https_port}/" \
+ -e "s/<VirtualHost _default_:.*>/<VirtualHost _default_:${!https_port}>/" \
+ $ssl_conf
+ # this is used to locate the right certificates
+ server_lower=$(echo $server | tr 'A-Z' 'a-z')
+
+ # which one is used is currently configured in myplc.spec,
+ # with mod_python preferred
+ if rpm -q mod_python >& /dev/null ; then
+ configure_for_mod_python=true
+ elif rpm -q mod_wsgi >& /dev/null \
+ || rpm -q python2-mod_wsgi >& /dev/null \
+ || rpm -q python3-mod_wsgi >& /dev/null ; then
+ configure_for_mod_wsgi=true
+ else
+ echo "Requires mod_python or mod_wsgi.... exiting"
+ exit 1
+ fi
+
+ # It would be tempting to use <IfModule> here
+ # but early tests showed this could be tricky/fragile
+ # So let's hard-wire it for one module
+ # A lot of trial-and -error was involved in getting this that way...
+
+ if [ -n "$configure_for_mod_python" ] ; then
+ #################### for mod_python
+ cat <<EOF
# mod_python location
<Location /PLCAPI/>
SetHandler mod_python
</Location>
EOF
- elif [ -n "$configure_for_mod_wsgi" ] ; then
-#################### for mod_wsgi
- cat <<EOF
+ elif [ -n "$configure_for_mod_wsgi" ] ; then
+ #################### for mod_wsgi
+ cat <<EOF
# create wsgi socket where we have the permission
WSGISocketPrefix run/wsgi
# xxx would be cool to be able to tweak this through config
WSGIDaemonProcess plcapi-wsgi-ssl user=apache group=apache processes=1 threads=25
WSGIProcessGroup plcapi-wsgi-ssl
+# needed since f41, see https://github.com/GrahamDumpleton/mod_wsgi/issues/915
+ WSGIApplicationGroup %{GLOBAL}
<Directory "/usr/share/plc_api/apache">
Options +ExecCGI
</VirtualHost>
EOF
- fi
- fi
- done >$plc_conf
-
- # Set custom Apache directives
- (
- # could be restricted to boot boxes but harmless..
- cat <<EOF
+ fi
+ fi
+ done >$plc_conf
+
+ # Set custom Apache directives
+ (
+ # could be restricted to boot boxes but harmless..
+ cat <<EOF
AddType application/octet-stream .iso
AddType application/octet-stream .usb
EOF
- # make sure /PLCAPI can't get accessed if API not enabled here
- if [ "$PLC_API_ENABLED" != "1" ] ; then
- cat <<EOF
+ # make sure /PLCAPI can't get accessed if API not enabled here
+ if [ "$PLC_API_ENABLED" != "1" ] ; then
+ cat <<EOF
# mod_wsgi location
<Location $PLC_API_PATH>
$(apache_forbid)
</Location>
EOF
- fi
+ fi
- # redirect www requests if not on the right server
- if [ "$PLC_WWW_ENABLED" != "1" ] ; then
- cat <<EOF
+ # redirect www requests if not on the right server
+ if [ "$PLC_WWW_ENABLED" != "1" ] ; then
+ cat <<EOF
Redirect /index.html http://$PLC_WWW_HOST:$PLC_WWW_PORT/
EOF
- fi
- ) >>$plc_conf
-
- # Make alpina-logs directory writable for bootmanager log upload
- chown apache:apache $DocumentRoot/alpina-logs/nodes
-
- # Make the Drupal files upload directory owned by Apache
- mkdir -p $DocumentRoot/files
- chown apache:apache $DocumentRoot/files
-
- # Symlink any (real) files or directories in
- # /data/var/www/html/* to /var/www/html/. We could descend
- # into subdirectories, but the code to do so properly would be
- # madness.
- for file in /data/$DocumentRoot/* ; do
- if [ -e "$file" -a ! -h "$file" ] ; then
- base=$(basename "$file")
- if [ ! -e "$DocumentRoot/$base" ] ; then
- ln -nsf "$file" "$DocumentRoot/$base"
- fi
- fi
- done
-
- # Cleanup broken symlinks
- for file in $DocumentRoot/* ; do
- if [ -h "$file" -a ! -e "$file" ] ; then
- rm -f "$file"
- fi
- done
-
- # Old style PHP constants
- mkdir -p /etc/planetlab/php
- cat >/etc/planetlab/php/site_constants.php <<"EOF"
+ fi
+ ) >>$plc_conf
+
+ # Make alpina-logs directory writable for bootmanager log upload
+ chown apache:apache $DocumentRoot/alpina-logs/nodes
+
+ # Make the Drupal files upload directory owned by Apache
+ mkdir -p $DocumentRoot/files
+ chown apache:apache $DocumentRoot/files
+
+ # Symlink any (real) files or directories in
+ # /data/var/www/html/* to /var/www/html/. We could descend
+ # into subdirectories, but the code to do so properly would be
+ # madness.
+ for file in /data/$DocumentRoot/* ; do
+ if [ -e "$file" -a ! -h "$file" ] ; then
+ base=$(basename "$file")
+ if [ ! -e "$DocumentRoot/$base" ] ; then
+ ln -nsf "$file" "$DocumentRoot/$base"
+ fi
+ fi
+ done
+
+ # Cleanup broken symlinks
+ for file in $DocumentRoot/* ; do
+ if [ -h "$file" -a ! -e "$file" ] ; then
+ rm -f "$file"
+ fi
+ done
+
+ # Old style PHP constants
+ mkdir -p /etc/planetlab/php
+ cat >/etc/planetlab/php/site_constants.php <<"EOF"
<?php
include('plc_config.php');
?>
EOF
- ## make room for logs
- touch /var/log/plcapi.log
- chmod 666 /var/log/plcapi.log
+ ## make room for logs
+ touch /var/log/plcapi.log
+ chmod 666 /var/log/plcapi.log
- plc_daemon httpd
- check
+ plc_daemon httpd
+ check
- result "$MESSAGE"
- ;;
+ result "$MESSAGE"
+ ;;
stop)
- MESSAGE=$"Stopping web server"
- dialog "$MESSAGE"
+ MESSAGE=$"Stopping web server"
+ dialog "$MESSAGE"
- pkill -f plc_httpd
- check
+ pkill -f plc_httpd
+ check
- result "$MESSAGE"
- ;;
+ result "$MESSAGE"
+ ;;
esac
exit $ERRORS
set -x
# Print the CNAME of an SSL certificate
-ssl_cname ()
-{
- openssl x509 -noout -in $1 -subject | \
- sed -e 's|.*CN *= *\([-_a-zA-Z0-9.]*\).*|\1|' | \
- lower
+function ssl_cname() {
+ local crt=$1; shift
+ openssl x509 -noout -in $crt -subject | \
+ sed -e 's|.*CN *= *\([-_a-zA-Z0-9.]*\).*|\1|' | \
+ lower
}
-backup_file ()
-{
- filepath=$1
- filename=$(basename ${filepath})
- dir=$(dirname ${filepath})
+function ssl_alt_names() {
+ local crt=$1; shift
+ openssl x509 -noout -in $crt -ext subjectAltName | \
+ tail -1 | \
+ sed -e 's|DNS:||g' -e 's|,||' | \
+ lower
+}
+
+function name_in_cert() {
+ local name=$1; shift
+ local crt=$1; shift
+ local cname=$(ssl_cname $crt)
+ local alt_names=$(ssl_alt_names $crt)
+ if [ "$name" = "$cname" ] ; then
+ return 0
+ fi
+ for alt_name in $alt_names; do
+ if [ "$name" = "$alt_name" ] ; then
+ return 0
+ fi
+ done
+ return 1
+}
+
+function cert_is_valid_and_about() {
+ local crt="$1"; shift
+ local ca="$1"; shift
+ local cname="$1"; shift
+
+ # needs to be about the right name
+ name_in_cert $cname $crt || return 1
+ # needs to be signed by CA
+ openssl verify -CAfile $ca $crt >& /dev/null || return 1
+ return 0
+
+}
+
+function backup_file() {
+ local filepath=$1
+ local filename=$(basename ${filepath})
+ local dir=$(dirname ${filepath})
mv -f ${filepath} ${dir}/${filename}-`date +%Y-%m-%d-%H-%M-%S`.bak
}
# Verify a certificate. If invalid, generate a new self-signed
# certificate.
-verify_or_generate_certificate() {
- crt=$1
- key=$2
- ca=$3
- cname=$(lower $4)
+function verify_or_generate_certificate() {
+ local crt=$1
+ local key=$2
+ local ca=$3
+ local cname=$(lower $4)
# If the CA certificate does not exist, assume that the
# certificate is self-signed.
if [ ! -f $ca ] ; then
- cp -a $crt $ca
+ cp -a $crt $ca
fi
- if [ -f $crt ] ; then
- # Check if certificate is valid
- # Backup if invalid or if the subject has changed
- if openssl verify -CAfile $ca $crt | grep -q "error" || \
- [ "$(ssl_cname $crt)" != "$cname" ] ; then
- backup_file $crt
- backup_file $ca
- backup_file $key
- fi
- fi
+ # 2024 nov 21
+ # turning this off as it is most of the time an impediment rather than a help
+ # particularly in the context of using /etc/dsissl/
+ # so the new behaviour is still to create a self-signed certificate
+ # if that's missing altogether, but otherwise let people manage their certs as they see fit
+ # in addition, the criteria that we used to use for checking the config
+ # i.e. openssl verify -CAfile $ca $crt
+ # doe not work with the certificates generated by the dsissl script
+ # although the resulting setup is perfectly valid, as far as chrome and safari at least
+ # if [ -f $crt ] ; then
+ # # Backup (i.e. move under other name) if invalid or if cname is not in that cert
+ # cert_is_valid_and_about $crt $ca $cname || {
+ # backup_file $crt
+ # backup_file $ca
+ # backup_file $key
+ # }
+ # fi
if [ ! -f $crt ] ; then
# Set subject
- subj=
- if [ -n "$cname" ] ; then
- subj="$subj/CN=$cname"
- fi
+ local subj=
+ if [ -n "$cname" ] ; then
+ subj="$subj/CN=$cname"
+ fi
- # Generate new self-signed certificate
- mkdir -p $(dirname $crt)
- openssl req -new -x509 -days 3650 -set_serial $RANDOM \
- -batch -subj "$subj" \
- -nodes -keyout $key -out $crt
- check
+ # Generate new self-signed certificate
+ mkdir -p $(dirname $crt)
+ openssl req -new -x509 -days 3650 -set_serial $RANDOM \
+ -batch -subj "$subj" \
+ -nodes -keyout $key -out $crt
+ check
- # The certificate it self-signed, so it is its own CA
- cp -a $crt $ca
+ # The certificate it self-signed, so it is its own CA
+ cp -a $crt $ca
fi
# Fix permissions
# certificate for each enabled server with a different
# hostname. These self-signed certificates may be overridden
# later.
- MESSAGE=$"Generating SSL certificates for"
- dialog "$MESSAGE"
+ local MESSAGE=$"Generating SSL certificates for"
+ dialog "$MESSAGE"
for server in WWW API BOOT MONITOR; do
- eval "a=\$PLC_${server}_ENABLED"
- echo $a
- if [ "$a" -ne 1 ] ; then
- echo "Skipping"
- continue
- fi
+ enabled=PLC_${server}_ENABLED
+ if [ "${!enabled}" != "1" ] ; then
+ echo "Skipping disabled server $server"
+ continue
+ fi
dialog "$server"
- ssl_key=PLC_${server}_SSL_KEY
+ # not local - we're not in a function
+ # plus, that breaks the ${!var} thing below
+ ssl_key=PLC_${server}_SSL_KEY
ssl_crt=PLC_${server}_SSL_CRT
ca_ssl_crt=PLC_${server}_CA_SSL_CRT
hostname=PLC_${server}_HOST
# Check if we have already generated a certificate for
# the same hostname.
for previous_server in WWW API BOOT MONITOR; do
- if [ "$server" = "$previous_server" ] ; then
- break
- fi
- previous_ssl_key=PLC_${previous_server}_SSL_KEY
- previous_ssl_crt=PLC_${previous_server}_SSL_CRT
- previous_ca_ssl_crt=PLC_${previous_server}_CA_SSL_CRT
- previous_hostname=PLC_${previous_server}_HOST
-
- if [ -f ${!previous_ssl_crt} ] && \
- [ "$(ssl_cname ${!previous_ssl_crt})" = "${!hostname}" ] ; then
- cp -a ${!previous_ssl_key} ${!ssl_key}
- cp -a ${!previous_ssl_crt} ${!ssl_crt}
- cp -a ${!previous_ca_ssl_crt} ${!ca_ssl_crt}
- break
- fi
+ if [ "$server" = "$previous_server" ] ; then
+ break
+ fi
+ previous_ssl_key=PLC_${previous_server}_SSL_KEY
+ previous_ssl_crt=PLC_${previous_server}_SSL_CRT
+ previous_ca_ssl_crt=PLC_${previous_server}_CA_SSL_CRT
+ previous_hostname=PLC_${previous_server}_HOST
+
+ if [ -f ${!previous_ssl_crt} ] && \
+ [ "$(ssl_cname ${!previous_ssl_crt})" = "${!hostname}" ] ; then
+ cp -a ${!previous_ssl_key} ${!ssl_key}
+ cp -a ${!previous_ssl_crt} ${!ssl_crt}
+ cp -a ${!previous_ca_ssl_crt} ${!ca_ssl_crt}
+ break
+ fi
done
- verify_or_generate_certificate \
- ${!ssl_crt} ${!ssl_key} ${!ca_ssl_crt} \
- ${!hostname}
+ verify_or_generate_certificate ${!ssl_crt} ${!ssl_key} ${!ca_ssl_crt} ${!hostname}
done
# Install HTTPS certificates into both /etc/pki (Fedora Core
for server in API BOOT MONITOR WWW; do
enabled=PLC_${server}_ENABLED
if [ "${!enabled}" != "1" ] ; then
- continue
+ continue
fi
- ssl_key=PLC_${server}_SSL_KEY
- ssl_crt=PLC_${server}_SSL_CRT
- ssl_ca_crt=PLC_${server}_CA_SSL_CRT
+ ssl_key=PLC_${server}_SSL_KEY
+ ssl_crt=PLC_${server}_SSL_CRT
+ ssl_ca_crt=PLC_${server}_CA_SSL_CRT
symlink ${!ssl_crt} /etc/pki/tls/certs/localhost.crt
symlink ${!ssl_key} /etc/pki/tls/private/localhost.key
symlink ${!ssl_ca_crt} /etc/pki/tls/certs/server-chain.crt
- symlink ${!ssl_crt} /etc/httpd/conf/ssl.crt/server.crt
- symlink ${!ssl_key} /etc/httpd/conf/ssl.key/server.key
+ # symlink ${!ssl_crt} /etc/httpd/conf/ssl.crt/server.crt
+ # symlink ${!ssl_key} /etc/httpd/conf/ssl.key/server.key
done
# Ensure that the server-chain gets used, as it is off by