From 06a23d2cea6e57cca82c47e14a7b6d038b8e4286 Mon Sep 17 00:00:00 2001
From: Alex Wilson <alex.wilson@joyent.com>
Date: Fri, 7 Aug 2015 12:19:47 -0700
Subject: [PATCH 25/36] Add SMF manifest and method, and install them

---
 Makefile.in      |   6 ++
 smf/manifest.xml | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 smf/method.sh    | 121 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 smf/manifest.xml
 create mode 100644 smf/method.sh

diff --git a/Makefile.in b/Makefile.in
index 66c4585..7130542 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -27,6 +27,8 @@ SFTP_SERVER=$(libexecdir)/sftp-server
 SSH_KEYSIGN=$(libexecdir)/ssh-keysign
 SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
 ROOTDLIBDIR64=$(DESTDIR)/usr/lib/dtrace/64
+SMFMETHODDIR=$(DESTDIR)/lib/svc/method
+SMFNETMANIDIR=$(DESTDIR)/lib/svc/manifest/network
 PRIVSEP_PATH=@PRIVSEP_PATH@
 SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
 STRIP_OPT=@STRIP_OPT@
@@ -359,6 +361,10 @@ install-files:
 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
 	ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
 	mkdir -p $(ROOTDLIBDIR64) && cp $(srcdir)/sftp64.d $(ROOTDLIBDIR64)/sftp64.d
+	$(srcdir)/mkinstalldirs $(SMFMETHODDIR)
+	$(srcdir)/mkinstalldirs $(SMFNETMANIDIR)
+	$(INSTALL) -m 555 smf/method.sh $(SMFMETHODDIR)/sshd
+	$(INSTALL) -m 444 smf/manifest.xml $(SMFNETMANIDIR)/ssh.xml
 
 install-sysconf:
 	if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \
diff --git a/smf/manifest.xml b/smf/manifest.xml
new file mode 100644
index 0000000..5045296
--- /dev/null
+++ b/smf/manifest.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+	CDDL HEADER START
+
+	The contents of this file are subject to the terms of the
+	Common Development and Distribution License (the "License").
+	You may not use this file except in compliance with the License.
+
+	You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+	or http://www.opensolaris.org/os/licensing.
+	See the License for the specific language governing permissions
+	and limitations under the License.
+
+	When distributing Covered Code, include this CDDL HEADER in each
+	file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+	If applicable, add the following below this CDDL HEADER, with the
+	fields enclosed by brackets "[]" replaced with your own identifying
+	information: Portions Copyright [yyyy] [name of copyright owner]
+
+	CDDL HEADER END
+
+	Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+	Use is subject to license terms.
+
+	NOTE:  This service manifest is not editable; its contents will
+	be overwritten by package or patch operations, including
+	operating system upgrade.  Make customizations in a different
+	file.
+-->
+
+<service_bundle type='manifest' name='SUNWsshdr:ssh'>
+
+<service
+	name='network/ssh'
+	type='service'
+	version='1'>
+
+	<create_default_instance enabled='false' />
+
+	<single_instance />
+
+	<dependency name='fs-local'
+		grouping='require_all'
+		restart_on='none'
+		type='service'>
+		<service_fmri
+			value='svc:/system/filesystem/local' />
+	</dependency>
+
+	<dependency name='fs-autofs'
+		grouping='optional_all'
+		restart_on='none'
+		type='service'>
+		<service_fmri value='svc:/system/filesystem/autofs' />
+	</dependency>
+
+	<dependency name='net-loopback'
+		grouping='require_all'
+		restart_on='none'
+		type='service'>
+		<service_fmri value='svc:/network/loopback' />
+	</dependency>
+
+	<dependency name='net-physical'
+		grouping='require_all'
+		restart_on='none'
+		type='service'>
+		<service_fmri value='svc:/network/physical' />
+	</dependency>
+
+	<dependency name='cryptosvc'
+		grouping='require_all'
+		restart_on='none'
+		type='service'>
+		<service_fmri value='svc:/system/cryptosvc' />
+	</dependency>
+
+	<dependency name='utmp'
+		grouping='require_all'
+		restart_on='none'
+		type='service'>
+		<service_fmri value='svc:/system/utmp' />
+	</dependency>
+
+	<dependency name='network_ipfilter'
+		grouping='optional_all'
+		restart_on='error'
+		type='service'>
+		<service_fmri value='svc:/network/ipfilter:default' />
+	</dependency>
+
+	<dependency name='config_data'
+		grouping='require_all'
+		restart_on='restart'
+		type='path'>
+		<service_fmri
+		    value='file://localhost/etc/ssh/sshd_config' />
+	</dependency>
+
+	<dependent
+		name='ssh_multi-user-server'
+		grouping='optional_all'
+		restart_on='none'>
+			<service_fmri
+			    value='svc:/milestone/multi-user-server' />
+	</dependent>
+
+	<exec_method
+		type='method'
+		name='start'
+		exec='/lib/svc/method/sshd start'
+		timeout_seconds='60'/>
+
+	<exec_method
+		type='method'
+		name='stop'
+		exec=':kill'
+		timeout_seconds='60' />
+
+	<exec_method
+		type='method'
+		name='refresh'
+		exec='/lib/svc/method/sshd restart'
+		timeout_seconds='60' />
+
+	<property_group name='startd'
+		type='framework'>
+		<!-- sub-process core dumps shouldn't restart session -->
+		<propval name='ignore_error'
+		    type='astring' value='core,signal' />
+	</property_group>
+
+        <property_group name='general' type='framework'>
+                <!-- to start stop sshd -->
+                <propval name='action_authorization' type='astring'
+                        value='solaris.smf.manage.ssh' />
+        </property_group>
+
+	<property_group name='firewall_context' type='com.sun,fw_definition'>
+		<propval name='name' type='astring' value='ssh' />
+		<propval name='ipf_method' type='astring'
+		    value='/lib/svc/method/sshd ipfilter' />
+	</property_group>
+
+	<property_group name='firewall_config' type='com.sun,fw_configuration'>
+		<propval name='policy' type='astring' value='use_global' />
+		<propval name='apply_to' type='astring' value='' />
+		<propval name='exceptions' type='astring' value='' />
+		<propval name='value_authorization' type='astring'
+			value='solaris.smf.value.firewall.config' />
+	</property_group>
+
+	<stability value='Unstable' />
+
+	<template>
+		<common_name>
+			<loctext xml:lang='C'>
+			SSH server
+			</loctext>
+		</common_name>
+		<documentation>
+			<manpage title='sshd' section='1M' manpath='/usr/share/man' />
+		</documentation>
+	</template>
+
+</service>
+
+</service_bundle>
\ No newline at end of file
diff --git a/smf/method.sh b/smf/method.sh
new file mode 100644
index 0000000..e91ed55
--- /dev/null
+++ b/smf/method.sh
@@ -0,0 +1,121 @@
+#!/sbin/sh
+#
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. /lib/svc/share/ipf_include.sh
+. /lib/svc/share/smf_include.sh
+
+SSHDIR=/etc/ssh
+SSHKEYDIR=/var/ssh
+KEYGEN="/usr/bin/ssh-keygen -q"
+PIDFILE=/var/run/sshd.pid
+
+# Checks to see if RSA, and DSA host keys are available
+# if any of these keys are not present, the respective keys are created.
+create_key()
+{
+	keypath=$1
+	keytype=$2
+
+	if [ ! -f $keypath ]; then
+		#
+		# HostKey keywords in sshd_config may be preceded or
+		# followed by a mix of any number of space or tabs,
+		# and optionally have an = between keyword and
+		# argument.  We use two grep invocations such that we
+		# can match HostKey case insensitively but still have
+		# the case of the path name be significant, keeping
+		# the pattern somewhat more readable.
+		#
+		# The character classes below contain one literal
+		# space and one literal tab.
+		#
+		grep -i "^[ 	]*HostKey[ 	]*=\{0,1\}[ 	]*$keypath" \
+		    $SSHDIR/sshd_config | grep "$keypath" > /dev/null 2>&1
+
+		if [ $? -eq 0 ]; then
+			echo Creating new $keytype public/private host key pair
+			$KEYGEN -f $keypath -t $keytype -N ''
+			if [ $? -ne 0 ]; then
+				echo "Could not create $keytype key: $keypath"
+				exit $SMF_EXIT_ERR_CONFIG
+			fi
+		fi
+	fi
+}
+
+create_ipf_rules()
+{
+	FMRI=$1
+	ipf_file=`fmri_to_file ${FMRI} $IPF_SUFFIX`
+	policy=`get_policy ${FMRI}`
+
+	#
+	# Get port from /etc/ssh/sshd_config
+	#
+	tports=`grep "^Port" /etc/ssh/sshd_config 2>/dev/null | \
+	    awk '{print $2}'`
+
+	echo "# $FMRI" >$ipf_file
+	for port in $tports; do
+		generate_rules $FMRI $policy "tcp" "any" $port $ipf_file
+	done
+}
+
+# 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.
+#
+# Both, the SMF methods and sysidconfig/sys-unconfig use different
+# arguments..
+
+case $1 in
+	# sysidconfig/sys-unconfig arguments (-c and -u)
+'-c')
+	create_key $SSHDIR/ssh_host_rsa_key rsa
+	create_key $SSHDIR/ssh_host_dsa_key dsa
+	create_key $SSHDIR/ssh_host_ecdsa_key ecdsa
+	create_key $SSHDIR/ssh_host_ed25519_key ed25519
+	;;
+
+'-u')
+	# sys-unconfig(1M) knows how to remove ssh host keys, so there's
+	# nothing to do here.
+	:
+	;;
+
+	# SMF arguments (start and restart [really "refresh"])
+
+'ipfilter')
+	create_ipf_rules $2
+	;;
+
+'start')
+	#
+	# If host keys don't exist when the service is started, create
+	# them; sysidconfig is not run in every situation (such as on
+	# the install media).
+	#
+	create_key $SSHKEYDIR/ssh_host_rsa_key rsa
+	create_key $SSHKEYDIR/ssh_host_dsa_key dsa
+	create_key $SSHKEYDIR/ssh_host_ecdsa_key ecdsa
+	create_key $SSHKEYDIR/ssh_host_ed25519_key ed25519
+
+	/usr/lib/ssh/sshd
+	;;
+
+'restart')
+	if [ -f "$PIDFILE" ]; then
+		/usr/bin/kill -HUP `/usr/bin/cat $PIDFILE`
+	fi
+	;;
+
+*)
+	echo "Usage: $0 { start | restart }"
+	exit 1
+	;;
+esac
+
+exit $?
\ No newline at end of file
-- 
2.5.4 (Apple Git-61)

