Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#!/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(~ factotum $files){
        if(~ $flush yes){
                echo flushing old keys
                echo delkey > /mnt/factotum/ctl
        }
        if(~ $load yes){
                echo loading factotum keys
                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
        case [xXqQ]*
                exit
        case [nN]* *
                echo ''''$i'''' skipped
        }
}

exit ''