#! /bin/sh ### BEGIN INIT INFO # Provides: urandom # Required-Start: $local_fs $time # Required-Stop: $local_fs # Default-Start: S # Default-Stop: 0 6 # Short-Description: Save and restore random seed between restarts. # Description: This script saves the random seed between restarts. # It is called from the boot, halt and reboot scripts. ### END INIT INFO ## Assumption 1: We assume $SAVEDFILE is a file (or a symlink ## to a file) that resides on a non-volatile medium that persists ## across reboots. ## Case 1a: Ideally, it is readable and writeable. Its is unshared, ## i.e. its contents are unique to this machine. It is protected so ## that its contents are not known to attackers. ## Case 1b: Less than ideally, it is read-only. Its contents are ## unique to this machine and not known to attackers. global SAVEDFILE := '/var/lib/urandom/random-seed' test -c /dev/urandom || exit 0 global PATH := '/sbin:/bin' if ! global POOLBYTES := $( ($(cat /proc/sys/kernel/random/poolsize 2>/dev/null) + 7) / 8 ) { global POOLBYTES := '512' } source /lib/init/vars.sh source /lib/lsb/init-functions proc do_status { if test -f $SAVEDFILE { return 0 } else { return 4 } } matchstr $1 { start|"" { test $VERBOSE = no || log_action_begin_msg "Initializing random number generator" # Seed the RNG with date and time. # This is helpful in the less-than-ideal case where $SAVEDFILE # is read-only. # The value of this is greatly reduced if $SAVEDFILE is missing, # or its contents are shared machine-to-machine or known to # attackers (since they might well know at what time this # machine booted up). shell { date +%s.%N # Load and then save $POOLBYTES bytes, # which is the size of the entropy pool if test -f $SAVEDFILE { cat $SAVEDFILE } # Redirect output of subshell (not individual commands) # to cope with a misfeature in the FreeBSD (not Linux) # /dev/random, where every superuser write/close causes # an explicit reseed of the yarrow. } >/dev/urandom # Write a new seed into $SAVEDFILE because re-using a seed # compromises security. Each time we re-seed, we want the # seed to be as different as possible. # Write it now, in case the machine crashes without doing # an orderly shutdown. # The write will fail if $SAVEDFILE is read-only, but it # doesn't hurt to try. umask 077 dd if=/dev/urandom of=$SAVEDFILE bs=$POOLBYTES count=1 >/dev/null !2 > !1 global ES := $Status umask 022 test $VERBOSE = no || log_action_end_msg $ES } stop { # Carry a random seed from shut-down to start-up; # Write it on shutdown, in case the one written at startup # has been lost, snooped, or otherwise compromised. # see documentation in linux/drivers/char/random.c test $VERBOSE = no || log_action_begin_msg "Saving random seed" umask 077 dd if=/dev/urandom of=$SAVEDFILE bs=$POOLBYTES count=1 >/dev/null !2 > !1 global ES := $Status test $VERBOSE = no || log_action_end_msg $ES } status { do_status exit $Status } restart|reload|force-reload { echo "Error: argument '$1' not supported" > !2 exit 3 } * { echo "Usage: urandom start|stop" > !2 exit 3 } } : (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SAVEDFILE) op: Equal rhs: {(/var/lib/urandom/random-seed)} spids: [58] ) ] spids: [58] ) (AndOr children: [(C {(Lit_Other "[")} {(-c)} {(/dev/urandom)} {(Lit_Other "]")}) (C {(exit)} {(0)})] op_id: Op_DPipe ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:PATH) op: Equal rhs: {(/sbin) (Lit_Other ":") (/bin)} spids: [77] ) ] spids: [77] ) (If arms: [ (if_arm cond: [ (Sentence child: (Pipeline children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:POOLBYTES) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Slash left: (ArithBinary op_id: Arith_Plus left: (ArithWord w: { (CommandSubPart command_list: (CommandList children: [ (SimpleCommand words: [ {(cat)} {(/proc/sys/kernel/random/poolsize)} ] redirects: [ (Redir op_id: Redir_Great fd: 2 arg_word: {(/dev/null)} spids: [96] ) ] ) ] ) left_token: spids: [91 98] ) } ) right: (ArithWord w:{(Lit_Digits 7)}) ) right: (ArithWord w:{(Lit_Digits 8)}) ) spids: [87 110] ) } spids: [86] ) ] spids: [86] ) ] negated: True ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:POOLBYTES) op:Equal rhs:{(512)} spids:[117])] spids: [117] ) ] spids: [-1 114] ) ] spids: [-1 120] ) (C {(.)} {(/lib/init/vars.sh)}) (C {(.)} {(/lib/lsb/init-functions)}) (FuncDef name: do_status body: (BraceGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-f)} {($ VSub_Name "$SAVEDFILE")} {(Lit_Other "]")}) terminator: ) ] action: [(ControlFlow token: arg_word:{(0)})] spids: [-1 152] ) ] else_action: [(ControlFlow token: arg_word:{(4)})] spids: [160 168] ) ] spids: [137] ) spids: [132 136] ) (Case to_match: {(DQ ($ VSub_Number "$1"))} arms: [ (case_arm pat_list: [{(start)} {(DQ )}] action: [ (AndOr children: [ (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$VERBOSE"))} {(Lit_Other "=")} {(no)} {(Lit_Other "]")} ) (C {(log_action_begin_msg)} {(DQ ("Initializing random number generator"))}) ] op_id: Op_DPipe ) (Subshell child: (CommandList children: [ (C {(date)} {(Lit_Other "+") (Lit_Other "%") (s.) (Lit_Other "%") (N)}) (If arms: [ (if_arm cond: [ (C {(Lit_Other "[")} {(-f)} {(DQ ($ VSub_Name "$SAVEDFILE"))} {(Lit_Other "]")} ) ] action: [(C {(cat)} {(DQ ($ VSub_Name "$SAVEDFILE"))})] spids: [-1 272] ) ] spids: [-1 282] ) ] ) redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/urandom)} spids:[303])] spids: [238 301] ) (C {(umask)} {(077)}) (SimpleCommand words: [ {(dd)} {(Lit_VarLike "if=") (/dev/urandom)} {(Lit_VarLike "of=") ($ VSub_Name "$SAVEDFILE")} {(Lit_VarLike "bs=") ($ VSub_Name "$POOLBYTES")} {(Lit_VarLike "count=") (1)} ] redirects: [ (Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/null)} spids:[355]) (Redir op_id:Redir_GreatAnd fd:2 arg_word:{(1)} spids:[358]) ] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:ES) op: Equal rhs: {($ VSub_QMark "$?")} spids: [362] ) ] spids: [362] ) (C {(umask)} {(022)}) (AndOr children: [ (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$VERBOSE"))} {(Lit_Other "=")} {(no)} {(Lit_Other "]")} ) (C {(log_action_end_msg)} {($ VSub_Name "$ES")}) ] op_id: Op_DPipe ) ] spids: [182 186 390 -1] ) (case_arm pat_list: [{(stop)}] action: [ (AndOr children: [ (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$VERBOSE"))} {(Lit_Other "=")} {(no)} {(Lit_Other "]")} ) (C {(log_action_begin_msg)} {(DQ ("Saving random seed"))}) ] op_id: Op_DPipe ) (C {(umask)} {(077)}) (SimpleCommand words: [ {(dd)} {(Lit_VarLike "if=") (/dev/urandom)} {(Lit_VarLike "of=") ($ VSub_Name "$SAVEDFILE")} {(Lit_VarLike "bs=") ($ VSub_Name "$POOLBYTES")} {(Lit_VarLike "count=") (1)} ] redirects: [ (Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/null)} spids:[453]) (Redir op_id:Redir_GreatAnd fd:2 arg_word:{(1)} spids:[456]) ] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:ES) op: Equal rhs: {($ VSub_QMark "$?")} spids: [460] ) ] spids: [460] ) (AndOr children: [ (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$VERBOSE"))} {(Lit_Other "=")} {(no)} {(Lit_Other "]")} ) (C {(log_action_end_msg)} {($ VSub_Name "$ES")}) ] op_id: Op_DPipe ) ] spids: [393 394 483 -1] ) (case_arm pat_list: [{(status)}] action: [(C {(do_status)}) (C {(exit)} {($ VSub_QMark "$?")})] spids: [486 487 498 -1] ) (case_arm pat_list: [{(restart)} {(reload)} {(force-reload)}] action: [ (SimpleCommand words: [{(echo)} {(DQ ("Error: argument '") ($ VSub_Number "$1") ("' not supported"))}] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[517])] ) (C {(exit)} {(3)}) ] spids: [501 506 526 -1] ) (case_arm pat_list: [{(Lit_Other "*")}] action: [ (SimpleCommand words: [{(echo)} {(DQ ("Usage: urandom start|stop"))}] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[539])] ) (C {(exit)} {(3)}) ] spids: [529 530 548 -1] ) ] spids: [173 179 550] ) (C {(Lit_Other ":")}) ] )