Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

#!/bin/sh
#
# $NetBSD: creds_msdos,v 1.5 2021/12/11 19:24:18 mrg Exp $
#
# Copyright (c) 2019 Matthew R. Green
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

#
# If "creds_msdos_partition" is an msdos partition and has a creds.txt
# in it, perform these commands:
#	"sshkeyfile <user> <path on msdos>"
#	"sshkey <user> <entry>"
# 	"useraddhash <user> <passwd hash>"
# 	"useradd <user> <passwd>"
# If the "useradd" method is used, this the creds.txt file will be
# shredded and deleted with rm -P.

# PROVIDE: creds_msdos
# REQUIRE: mountall

$_rc_subr_loaded . /etc/rc.subr

name="creds_msdos"
start_cmd="creds_msdos_start"
stop_cmd=":"

fail() {
	echo "$@" 1>&2
	exit 1
}

# This uses $ssh_userkeys global
sshkey_setup() {
	local user="$1"
	local group="wheel"

	# don't create existing users
	if ! id -u "${user}" > /dev/null 2>&1; then
		useradd -m -G "${group}" "${user}" || fail "Useradd failed."
	fi

	eval ssh_userdir=~"${user}/.ssh"
	mkdir -p -m 755 "${ssh_userdir}" || fail "mkdir ~/.ssh failed."
	chmod 755 "${ssh_userdir}"
	chown "${user}" "${ssh_userdir}"

	ssh_userkeys="${ssh_userdir}/authorized_keys"
}

sshkey_finish() {
	local user="$1"

	chmod 644 "${ssh_userkeys}"
	chown "${user}" "${ssh_userkeys}"
}

do_sshkeyfile() {
	local user="$1"
	local newkeys="${creds_msdos_partition}/$2"

	if [ ! -f "${newkeys}" ]; then
		return
	fi

	sshkey_setup "${user}"

	# check entry is not present
	while read type keydata name; do
		if fgrep -q "${keydata}" "${ssh_userkeys}" 2>/dev/null; then
			continue
		fi
		echo "${type} ${keydata} ${name}" >> "${ssh_userkeys}"
	done < "${newkeys}"

	sshkey_finish "${user}"
}

do_sshkey() {
	local user="$1"
	local newkey="$2"

	sshkey_setup "${user}"

	echo "${newkey}" >> "${ssh_userkeys}"

	sshkey_finish "${user}"
}

do_useraddpwhash() {
	local user="$1"
	local pwhash="$2"
	local group="wheel"

	# don't add to existing users
	if id -u "${user}" > /dev/null 2>&1; then
		return
	fi

	useradd -m -p "${pwhash}" -G "${group}" "${user}" || fail "Useradd failed."
}

do_useradd() {
	local user="$1"
	local password="$2"

	local pwhash=$(pwhash "$password")
	do_useraddpwhash "${user}" "${pwhash}"
}

creds_msdos_start()
{
	local fstab_file=/etc/fstab

	if [ -z "${creds_msdos_partition}" ]; then
		echo "Not looking for credentials on msdos"
		return
	fi
	while read junk1 mp fstype junk2; do
		if [ "${mp}" != "${creds_msdos_partition}" ]; then
			continue
		fi
		if [ "${fstype}" != "msdos" ]; then
			echo "Not checking for creds on ${creds_msdos_partition}: not an msdos file system"
			return
		fi
		break
	done < "${fstab_file}"

	local delete_creds=no
	local creds_file="${creds_msdos_partition}/creds.txt"

	if [ -f "${creds_file}" ]; then
		while read type user args; do
			# strip cr
			local clean_args=$(echo "$args" | tr -d '\015')
			case "$type" in
			\#*|'')
				continue
				;;
			sshkeyfile)
				echo "Added user ${user} via ssh key file method."
				do_sshkeyfile "${user}" "${clean_args}"
				;;
			sshkey)
				echo "Added user ${user} via ssh key string method."
				do_sshkey "${user}" "${clean_args}"
				;;
			useraddpwhash)
				echo "Added user ${user} via password hash method."
				do_useraddpwhash "${user}" "${clean_args}"
				;;
			useradd)
				echo "Added user ${user} via password method, shredding credentials file."
				do_useradd "${user}" "${clean_args}"
				delete_creds=yes
				;;
			*)
				echo "Do not understand '$type' creds" 1>&2
				exit 1
				;;
			esac
		done < "${creds_file}"
	fi

	if [ $delete_creds = yes ]; then
		rm -P -f "${creds_file}"
	fi
}

load_rc_config $name
run_rc_command "$1"