#!/bin/ksh93 # # Author: Jens Elkner # License: Free as beer. : ${SMF_FMRI:=ssh:default} . /lib/svc/share/ipf_include.sh . /lib/svc/share/smf_include.sh # should be part of /lib/svc/share/smf_include.sh getprop() { PROPVAL=${ svcprop -p "$1" ${SMF_FMRI} 2>/dev/null; } [[ "${PROPVAL}" == '""' ]] && PROPVAL="" print "$PROPVAL" } SSHD=/usr/lib/ssh/sshd KEYGEN="/usr/bin/ssh-keygen -q" INSTANCE=:${SMF_FMRI##*:} INSTANCE=${INSTANCE%:default} PIDFILE=${SMF_SYSVOL_FS:-/var/run}/sshd${INSTANCE}.pid CFG=${ getprop config/config_file; } : ${CFG:=/etc/ssh/sshd_config$INSTANCE} create_key() { KFILE="$1" KTYPE="$2" [[ -z "$KFILE" ]] && return print "Creating new $KTYPE public/private host key pair: $KFILE" $KEYGEN -f "$KFILE" -t ${KTYPE:-rsa} -N '' || exit $SMF_EXIT_ERR_PERM } # Create very simple ipfilter rules wrt. the specified Port(s) in the given # sshd config file ($1). create_ipf_rules() { if [[ ! -f "$1" ]]; then print -u2 "Config file $1 not found" exit $SMF_EXIT_ERR_CONFIG fi FMRI=$2 IPF_FILE=${ fmri_to_file ${FMRI} $IPF_SUFFIX; } POLICY=${ get_policy ${FMRI}; } while read LINE; do if [[ "$LINE" == \ ~(Ei)^Port[[:space:]]*[[:space:]=][[:space:]]*([[:digit:]]+) ]] then generate_rules $FMRI $POLICY "tcp" "any" ${.sh.match[1]} $IPF_FILE fi done < "$1" } # Check, whether all HostKey files defined in the given sshd config file ($1) # exist and create all missing files. The last '_rsa_' or '_dsa_' found in the # hostkey filename determines the keytype (default: rsa). # If $2 == "rm" all defined and existing keyfiles are deleted instead. check_keys() { if [[ ! -f "$1" ]]; then print -u2 "Config file $1 not found" exit $SMF_EXIT_ERR_CONFIG fi ACTION="$2" while read LINE; do if [[ "$LINE" == \ ~(Ei)^HostKey[[:space:]]*[[:space:]=][[:space:]]*([^[:space:]]+) ]] then KEYFILE=${.sh.match[1]} if [[ "$ACTION" == "rm" ]]; then rm -f "$KEYFILE" || print -u2 "Removing $KEYFILE failed" elif [[ ! -f "$KEYFILE" ]]; then TYPE="" [[ $KEYFILE == @(*_(rsa|dsa)_*) ]] && TYPE=${.sh.match[2]} create_key $KEYFILE $TYPE fi fi done < "$1" } # This script is being used for two purposes: # - as part of an SMF start/stop/refresh method, and # - as a sysidconfig(1M)/sys-unconfig(1M) application case $1 in '-c') # sysidconfig. Create missing keys check_keys "$CFG" ;; '-u') # sys-unconfig. Knows how to remove the default ssh host keys, so # just for convinience. check_keys "$CFG" "rm" ;; 'ipfilter') # nwam ??? create_ipf_rules "$CFG" $2 ;; 'start') # SMF. Creates missing keyfiles. check_keys "$CFG" OPTS=${ getprop config/options; } $SSHD ${OPTS} -f "$CFG" -o "PidFile=$PIDFILE" ;; 'stop') # just for convinience [[ -f $PIDFILE ]] && /usr/bin/kill -TERM $(<$PIDFILE) ;; 'restart') # just for convinience [[ -f $PIDFILE ]] && /usr/bin/kill -HUP $(<$PIDFILE) ;; *) print "Usage: $0 { start | stop | restart }" exit $SMF_EXIT_ERR_OTHER ;; esac exit $? # vim:ts=4 filetype=sh