Open Computing ``Hands-On'': ``Answers to Unix'' Column: August 1994: Listings

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

Last Modified: