diff options
Diffstat (limited to 'libexec/rc/rc.d/random')
-rwxr-xr-x | libexec/rc/rc.d/random | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/libexec/rc/rc.d/random b/libexec/rc/rc.d/random new file mode 100755 index 000000000000..c34f0d1f86b4 --- /dev/null +++ b/libexec/rc/rc.d/random @@ -0,0 +1,158 @@ +#!/bin/sh +# +# + +# PROVIDE: random +# REQUIRE: FILESYSTEMS +# BEFORE: netif +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="random" +desc="Harvest and save entropy for random device" +start_cmd="random_start" +stop_cmd="random_stop" + +extra_commands="saveseed" +saveseed_cmd="${name}_stop" + +save_dev_random() +{ + oumask=`umask` + umask 077 + for f ; do + debug "saving entropy to $f" + dd if=/dev/random of="$f" bs=4096 count=1 status=none && + ( chflags nodump "$f" 2>/dev/null || : ) && + chmod 600 "$f" && + fsync "$f" "$(dirname "$f")" + done + umask ${oumask} +} + +feed_dev_random() +{ + for f ; do + if [ -f "$f" -a -r "$f" -a -s "$f" ] ; then + if dd if="$f" of=/dev/random bs=4096 2>/dev/null ; then + debug "entropy read from $f" + rm -f "$f" + fi + fi + done +} + +random_start() +{ + + if [ -n "${harvest_mask}" ]; then + echo -n 'Setting up harvesting: ' + ${SYSCTL} kern.random.harvest.mask=${harvest_mask} > /dev/null + ${SYSCTL_N} kern.random.harvest.mask_symbolic + fi + + echo -n 'Feeding entropy: ' + + if [ ! -w /dev/random ] ; then + warn "/dev/random is not writeable" + return 1 + fi + + # Reseed /dev/random with previously stored entropy. + case ${entropy_dir:=/var/db/entropy} in + [Nn][Oo]) + ;; + *) + if [ -d "${entropy_dir}" ] ; then + feed_dev_random "${entropy_dir}"/* + fi + ;; + esac + + case ${entropy_file:=/entropy} in + [Nn][Oo]) + ;; + *) + feed_dev_random "${entropy_file}" /var/db/entropy-file + save_dev_random "${entropy_file}" + ;; + esac + + case ${entropy_boot_file:=/boot/entropy} in + [Nn][Oo]) + ;; + *) + save_dev_random "${entropy_boot_file}" + ;; + esac + + echo '.' +} + +random_stop() +{ + # Write some entropy so when the machine reboots /dev/random + # can be reseeded + # + case ${entropy_file:=/entropy} in + [Nn][Oo]) + ;; + *) + echo -n 'Writing entropy file: ' + rm -f ${entropy_file} 2> /dev/null + oumask=`umask` + umask 077 + if touch ${entropy_file} 2> /dev/null; then + entropy_file_confirmed="${entropy_file}" + else + # Try this as a reasonable alternative for read-only + # roots, diskless workstations, etc. + rm -f /var/db/entropy-file 2> /dev/null + if touch /var/db/entropy-file 2> /dev/null; then + entropy_file_confirmed=/var/db/entropy-file + fi + fi + case ${entropy_file_confirmed} in + '') + warn 'write failed (read-only fs?)' + ;; + *) + save_dev_random "${entropy_file_confirmed}" + echo '.' + ;; + esac + umask ${oumask} + ;; + esac + case ${entropy_boot_file:=/boot/entropy} in + [Nn][Oo]) + ;; + *) + echo -n 'Writing early boot entropy file: ' + rm -f ${entropy_boot_file} 2> /dev/null + oumask=`umask` + umask 077 + if touch ${entropy_boot_file} 2> /dev/null; then + entropy_boot_file_confirmed="${entropy_boot_file}" + fi + case ${entropy_boot_file_confirmed} in + '') + warn 'write failed (read-only fs?)' + ;; + *) + save_dev_random "${entropy_boot_file_confirmed}" + echo '.' + ;; + esac + umask ${oumask} + ;; + esac +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +random_svcj="NO" + +run_rc_command "$1" |