code: plan9front

ref: 28f76455d39d990b47c6e46e18158f0a9ba09d25
dir: /rc/bin/ipso/

View raw version
#!/bin/rc
# ipso - edit secstore files, reload factotum keys
if(! ~ $service terminal &&
    ! ~ $user `{ ls -ld /mnt/factotum/ctl | awk '{print $4}' }){
	echo >[1=2] ipso should be run only on the terminal
	exit terminal
}

rfork e
path=(/bin)
home=(/tmp)
editor = (acme -c1)
name = secstore
get = secstoreget
put = secstoreput
edit = no
load = no
flush = no

fn secstoreget{
	auth/secstore -i -g $1 <_password
}

fn secstoreput{
	auth/secstore -i -p $1 <_password
}

fn aesget{
	if(! ~ $1 /*){
		echo >[1=2] ipso: aescbc requires fully qualified pathname
		exit usage
	}
	auth/aescbc -i -d < $1 > `{basename $1} <[3] _password
}

fn aesput{
	auth/aescbc -i -e > $1 < `{basename $1} <[3] _password
}

fn editedfiles{
	if(~ $get aesget){
		for(i in $files)
			if(ls -tr | sed '1,/^_timestamp$/d' | grep -s '^'^`{basename $i}^'$')
				echo $i
	}
	if not
		ls -tr | sed '1,/^_timestamp$/d'
}

edexp=`{grep '^editor=' /mnt/plumb/rules >[2]/dev/null}
if(~ $#edexp 1)
	eval $edexp

while(~ $1 -*){
	switch($1){
	case -s
		editor = sam
	case -a
		name = aescbc
		get = aesget
		put = aesput
	case -f
		flush = yes
	case -e
		edit = yes
	case -l
		load = yes
	case *
		echo >[2=1] 'usage: ipso [-a -f -e -l] [-s] [file ...]'
		exit usage
	}
	shift
}

if(~ $flush no && ~ $edit no && ~ $load no){
	load = yes
	edit = yes
	flush = yes
}

if(~ $flush yes && ~ $edit no && ~ $load no){
	echo flushing old keys
	echo delkey > /mnt/factotum/ctl
	exit 0
}

if(~ $get aesget && ~ $#* 0){
	echo >[2=1] ipso: must specify a fully qualified file name for aescbc '(-a)'
	exit usage
}

rfork ne
ramfs -p >[2] /dev/null # silence 'i/o on hungup channel' message at exit
unmount /mnt/plumb
bind -c /tmp /srv
builtin cd /tmp

if ( ~ $edit yes ) echo '
	Warning: The editor will display the secret contents of
	your '$name' files in the clear.
'
# get password and remember it
{
	echo rawon
	echo -n $name password: >/dev/cons
	read > _password
	echo > /dev/cons
}</dev/cons > /dev/consctl

# get list of files
if(~ $#* 0){
	if(! auth/secstore -G . -i < _password > _listing){
		echo 'secstore read failed - bad password?'
		sleep 2
		exit password
	}
	files=`{sed 's/[ 	]+.*//' _listing}
}
if not
	files = $*

# copy the files to local ramfs
for(i in $files){
	if(! $get $i){
		echo $name ' read failed - bad password?'
		sleep 2
		exit password
	}
}
sleep 2; date > _timestamp	# so we can find which files have been edited.

# edit the files
if(~ $edit yes) $editor `{for(i in $files) basename $i}
if(~ $flush yes ){
	echo flushing old keys
	echo delkey > /mnt/factotum/ctl
}
if(~ $load yes){
	echo loading factotum keys
	if (~ factotum $files) read -m < factotum > /mnt/factotum/ctl
}

# copy the files back
for(i in `{editedfiles}){
	echo -n copy ''''`{basename $i}^'''' back?' [y/n/x]'
	switch(`{read}){
	case [yY]*
		if(! $put $i){
			echo $name ' read failed - bad password?'
			sleep 2
			exit password
		}
		echo ''''$i'''' copied to $name
		if(~ $i factotum)
			read -m < $i > /mnt/factotum/ctl
	case [xXqQ]*
		exit
	case [nN]* *
		echo ''''$i'''' skipped
	}
}

exit ''