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#if __STDC__ == 1 #include #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.scriptmail.msg.send $ cat mail.msg.send begin 644 /home/ray/run.script ?T)NMQJNQ"?TME'_F!O0FG<[BIQ[@Q4FB('4>;CYA.@( ... end $ []