
Listing 1: Programs to implement remote execution via e-mail
A: The cmd.filter script looks
for and verifies e-mail command files:
scriptfile=/tmp/$$
CHKCODE='/home/ray/chkcode'
trap 'rm -f /tmp/*$$* \$encodedfile' 0 1 2 3 15
while read line
do
if echo $line | grep '^Subject:' > /dev/null; then
# is this a script to execute?
if `echo $line | grep '[Ss]cript to run' > /dev/null`; then
while read line # skip rest of mail header
do
if [ -z "$line" ]; then
break # header ends at a blank line
fi
done
while read line # capture file name of uudecoded file
do
if echo "$line" | grep '^begin' > /dev/null; then
encodedfile=`echo "$line" | awk '{print $3}'`
break
fi
done
( echo "$line" ; cat) | uudecode # uudecode mail message
crypt `$CHKCODE` < $encodedfile > $scriptfile #decrypt msg
# does decrypted message have a return address?
if grep '[Rr]eturn [Aa]ddress:' < $scriptfile > /dev/null
then
retaddr=`awk -F: '/[Rr]eturn [Aa]ddress:/ {print $2}' $scriptfile`
fi
if [ -z "$retaddr" ]; then
exit # Return Address not found after decryption
fi
# create execution file
grep -v '[Rr]eturn [Aa]ddress:' < $scriptfile |
sh > /tmp/out.$$ 2>&1 # end of pipeline
mail $retaddr < /tmp/out.$$ # mail output back to $retaddr
exit
else
exit # exit because "Script to run" not Subject
fi
fi
done
B. The chkcode program both
prints one-time codes and verifies the code sent to
cmd.filter:
#include <stdio.h>
#if __STDC__ == 1
#include <stdlib.h>
#endif
#define STRLEN 50
#define ONETIMEPADFILE "/home/ray/otp"
#define STARTINGSEED 92834934
main(argc, argv)
int argc;
char *argv[];
{
FILE *codefile; /* file containing one-time count */
long codecnt; /* one time count */
long loopcnt; /* for loop counter */
unsigned long seed = STARTINGSEED; /* where to start */
char instr[STRLEN]; /* input string */
if (argc == 3 && strcmp(argv[1], "-l") == 0) { /* printing codes */
codecnt = atoi(argv[2]); /* get number of codes to print */
if (codecnt <= 0)
exit(1); /* fail, bad command line */
}
else if (argc == 1) { /* print current key */
if ( (codefile = fopen(ONETIMEPADFILE, "r")) == NULL)
exit(1); /* fail, can't open count file */
if (fgets(instr, STRLEN, codefile) == NULL)
exit(1); /* fail, can't read count file */
codecnt = atol(instr); /* get number of key */
fclose(codefile);
}
else
exit(1); /* fail because of bad command line */
for (loopcnt = 1; loopcnt <= codecnt; loopcnt++) {
seed = 1664525 * seed + 1; /* generate keys */
if (argc == 3) /* print list of keys */
printf("%u\n", seed);
}
if (argc == 3)
exit(0); /* finished printing codes */
else { /* update counting file index */
if ( (codefile = fopen(ONETIMEPADFILE, "w")) == NULL)
exit(1); /* fail, can't open count file */
if (fprintf(codefile, "%ld\n", codecnt + 1) == 0)
exit(1); /* fail, can't write to count file */
fclose(codefile);
printf("%u\n", seed); /* print current key */
exit(0); /* return success */
}
exit(1);
}
C. Entry to add to .forward file:
\ray, "|/home/ray/cmd.filter"
D. Commands for preparing a command file for e-mail:
$ chkcode -l 5
1735140863
227051508
1559109477
2843137570
3719064507
$ cat mail.msg
Return address: ray
date
cal
$ crypt 1735140863 < mail.msg > mail.msg.crypt
$ uuencode /home/ray/run.script < mail.msg.crypt > mail.msg.send
$ cat mail.msg.send
begin 644 /home/ray/run.script
?T)NMQJNQ"?TME'_F!O0FG<[BIQ[@Q4FB('4>;CYA.@(
...
end
$ []
|