170922Sdougb#!/bin/sh
270922Sdougb#
3240090Sdougb# Copyright (c) 2001-2006,2012 Douglas Barton, dougb@FreeBSD.org
470922Sdougb# All rights reserved.
570922Sdougb#
670922Sdougb# Redistribution and use in source and binary forms, with or without
770922Sdougb# modification, are permitted provided that the following conditions
870922Sdougb# are met:
970922Sdougb# 1. Redistributions of source code must retain the above copyright
1070922Sdougb#    notice, this list of conditions and the following disclaimer.
1170922Sdougb# 2. Redistributions in binary form must reproduce the above copyright
1270922Sdougb#    notice, this list of conditions and the following disclaimer in the
1370922Sdougb#    documentation and/or other materials provided with the distribution.
1470922Sdougb#
1570922Sdougb# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1670922Sdougb# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1770922Sdougb# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1870922Sdougb# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1970922Sdougb# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2070922Sdougb# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2170922Sdougb# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2270922Sdougb# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2370922Sdougb# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2470922Sdougb# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2570922Sdougb# SUCH DAMAGE.
2670922Sdougb#
2770922Sdougb# $FreeBSD: stable/11/libexec/save-entropy/save-entropy.sh 355749 2019-12-14 09:54:30Z delphij $
2870922Sdougb
2970922Sdougb# This script is called by cron to store bits of randomness which are
3070922Sdougb# then used to seed /dev/random on boot.
3170922Sdougb
32240090Sdougb# Originally developed by Doug Barton, dougb@FreeBSD.org
3371014Sdougb
3470922SdougbPATH=/bin:/usr/bin
3570922Sdougb
3670922Sdougb# If there is a global system configuration file, suck it in.
3770922Sdougb#
3870922Sdougbif [ -r /etc/defaults/rc.conf ]; then
3970922Sdougb	. /etc/defaults/rc.conf
40161683Sdougb	source_rc_confs 2>/dev/null
4170922Sdougbelif [ -r /etc/rc.conf ]; then
42161683Sdougb	. /etc/rc.conf 2>/dev/null
4370922Sdougbfi
4470922Sdougb
45268979Sdelphij[ $(/sbin/sysctl -n security.jail.jailed) = 0 ] || exit 0
46268979Sdelphij
4770922Sdougbcase ${entropy_dir} in
4870922Sdougb[Nn][Oo])
4970922Sdougb	exit 0
5070922Sdougb	;;
5170922Sdougb*)
5271014Sdougb	entropy_dir=${entropy_dir:-/var/db/entropy}
5370922Sdougb	;;
5470922Sdougbesac
5570922Sdougb
56273872Smarkmentropy_save_sz=${entropy_save_sz:-4096}
5770922Sdougbentropy_save_num=${entropy_save_num:-8}
5870922Sdougb
5970922Sdougbif [ ! -d "${entropy_dir}" ]; then
60240090Sdougb	install -d -o operator -g operator -m 0700 "${entropy_dir}" || {
61240090Sdougb		logger -is -t "$0" The entropy directory "${entropy_dir}" does \
62240090Sdougb		    not exist, and cannot be created. Therefore no entropy can \
63240090Sdougb		    be saved.; exit 1; }
6470922Sdougbfi
6570922Sdougb
66240090Sdougbcd "${entropy_dir}" || {
67240090Sdougb	logger -is -t "$0" Cannot cd to the entropy directory: "${entropy_dir}". \
68240090Sdougb	    Entropy file rotation is aborted.; exit 1; }
69240090Sdougb
70240090Sdougbfor f in saved-entropy.*; do
71240090Sdougb	case "${f}" in saved-entropy.\*) continue ;; esac	# No files match
72355749Sdelphij	[ ${f#saved-entropy\.} -gt ${entropy_save_num} ] && unlink ${f}
73240090Sdougbdone
74240090Sdougb
75355749Sdelphijumask 177
7670922Sdougb
77355749Sdelphij# Scan slots [1..$entropy_save_num), picking an empty slot or the oldest
78355749Sdelphij# existing file if no empty slot was available.
79355749Sdelphij#
80355749Sdelphij# 1. Find out the first regular file or empty slot (and its serial number)
81355749Sdelphij#
82355749Sdelphijn=1
83355749Sdelphijwhile [ ${n} -le ${entropy_save_num} ]; do
84355749Sdelphij	save_file="saved-entropy.${n}"
85355749Sdelphij	if [ ! -e "${save_file}" -o -f "${save_file}" ]; then
86355749Sdelphij		break
87355749Sdelphij	else
88240090Sdougb		logger -is -t "$0" \
89355749Sdelphij		    "${save_file}" is not a regular file, skipped.
9070922Sdougb	fi
91355749Sdelphij	n=$(( ${n} + 1 ))
9270922Sdougbdone
93355749Sdelphij#
94355749Sdelphij# 2. Start from (serial number + 1), and check if the slot is empty
95355749Sdelphij#    or is an older regular file, update save_file pointer in either
96355749Sdelphij#    case, and break early if we found an empty slot.
97355749Sdelphij#
98355749Sdelphijif [ -f ${save_file} ]; then
99355749Sdelphij	n=$(( ${n} + 1 ))
100355749Sdelphij	while [ ${n} -le ${entropy_save_num} ]; do
101355749Sdelphij		next_file=saved-entropy.${n}
102355749Sdelphij		if [ -f "${next_file}" ]; then
103355749Sdelphij			[ "${next_file}" -ot "${save_file}" ] && \
104355749Sdelphij			    save_file="${next_file}"
105355749Sdelphij		elif [ ! -e "${next_file}" ]; then
106355749Sdelphij			save_file="${next_file}"
107355749Sdelphij			break
108355749Sdelphij		else
109355749Sdelphij			logger -is -t "$0" \
110355749Sdelphij			    "${next_file}" is not a regular file, skipped.
111355749Sdelphij		fi
112355749Sdelphij		n=$(( ${n} + 1 ))
113355749Sdelphij	done
114355749Sdelphijfi
115355749Sdelphij#
116355749Sdelphij# 3. Check if the pointer we have in hand is really a regular file or
117355749Sdelphij#    an empty slot, and bail out as that means there is no available slot.
118355749Sdelphij#
119355749Sdelphijif [ -e "${save_file}" -a ! -f "${save_file}" ]; then
120355749Sdelphij	logger -is -t "$0" \
121355749Sdelphij		No available slot in "${entropy_dir}", save entropy is aborted.
122355749Sdelphij	exit 1
123355749Sdelphijfi
12470922Sdougb
125355749Sdelphij# Save entropy to the selected slot.
126355749Sdelphijchmod 600 "${save_file}" 2>/dev/null || :
127355749Sdelphijdd if=/dev/random of="${save_file}" bs=${entropy_save_sz} count=1 2>/dev/null
12870922Sdougb
12970922Sdougbexit 0
130