[net.sources] cmdbymail - repost

jaakov%wisdom.bitnet@WISCVM.ARPA (07/08/85)

From: Jacob Levy  <jaakov%wisdom.bitnet@WISCVM.ARPA>

This is a repost of 'cmdbymail'. Run everything below the dashed line through
'sh' and enjoy. Installation should be done by SU.

#--- cut here --- cut here --- cut here --- cut here --- cut here ---
#
# This a shell archive, containing the following files :-
#
#       makefile        cmdbymail.c     cmdbymail.1
#

echo extracting makefile
cat << 'FoO ThE BaR' > makefile
DESTDIR = -DDESTDIR=\"/bin\"
CFILES = cmdbymail.c
OFILES = cmdbymail.o
CFLAGS = -O

all: cmdbymail cmdbymail.n

cmdbymail.o: cmdbymail.c
        cc $(CFLAGS) $(DESTDIR) -c cmdbymail.c

cmdbymail: $(OFILES)
        cc -o cmdbymail $(OFILES)

cmdbymail.n: cmdbymail.1
        rm -f cmdbymail.n
        nroff -man -Tla12 cmdbymail.1 > cmdbymail.n

cmdbymail.shar: makefile $(CFILES) cmdbymail.1
        rm -f cmdbymail.shar
        shar makefile $(CFILES) cmdbymail.1 > cmdbymail.shar

install: all
        @-echo installing cmdbymail in a public directory
        @-echo if you are not SU, this will fail...
        /bin/cp cmdbymail /usr/bin
        /bin/cp cmdbymail /bin
        /bin/cp cmdbymail /etc
        /bin/cp cmdbymail.1 /usr/man/man1
        @-echo installed it, have fun
FoO ThE BaR
echo extracting cmdbymail.c
cat << 'FoO ThE BaR' > cmdbymail.c
#include        <stdio.h>

#define DESTDIR         "/bin"
#define BUF_SIZE        1024000

char msgbuffer[BUF_SIZE];

char *
getline(l, here)
char *l, *here;
{
        register char *run = l;

        if (*here == 0)
                return 0;
        for (; *here && *here != '\n'; *run++ = *here++);
        here++;
        *run = 0;
        return here;
}

char *
command_message(passwd, subject)
char *passwd, *subject;
{
        char    sbuf[256],
                l[256];
        char    *run = msgbuffer;
        char    *lrun = l;

        sprintf(sbuf, "Subject: %s", subject);

        for (; (run = getline(lrun, run)) != 0; )
                if (strncmp(l, "Subject: ", strlen("Subject: ")) == 0) {
                        if (strcmp(l, sbuf) != 0)
                                return 0;
                        else
                                break;
                }
        if (run == 0)
                return 0;
        for (; (run = getline(lrun, run)) != 0 && *lrun == '\0'; )
        if (run == 0)
                return 0;
        if (strcmp(lrun,passwd) == 0)
                return run;
        return 0;
}

setup(pname, appending)
char *pname;
{
        FILE            *fd;
        int             appending;
        register char   *run;
        char            pbuf[256],
                        sbuf[256],
                        fbuf[256];

        printf("enter password to identify legal command files: ");
        run = pbuf;
        for (*run = getchar(); *run != '\n'; *run = getchar())
                run++;
        *run = 0;

        printf("enter subject to identify legal command files (one word!!): ");
        run = sbuf;
        for (*run = getchar(); *run != '\n'; *run = getchar())
                run++;
        *run = 0;

repeat: printf("write a new '.forward' or append? [aw] ");
        switch (getchar()) {
        case 'w' : case 'W' :
                appending = 0;
                for (; getchar() != '\n'; );
                break;
        case '\n' :
                appending = 1;
                break;
        case 'a' : case 'A' :
                appending = 1;
                for (; getchar() != '\n'; );
                break;
        default :
                for (; getchar() != '\n'; );
                goto repeat;
        }

        sprintf(fbuf, "%s/.forward", getenv("HOME"));
        if ((fd = fopen(fbuf, appending ? "a" : "w")) == NULL) {
                printf("cannot open .forward file for %s\n",
                       appending ? "appending" : "writing");
                exit(0);
        }

        fprintf(fd, "\\%s\n\"|%s/%s %s %s\"\n",DESTDIR,getenv("USER"),
                pname,pbuf,sbuf);
        fclose(fd);
        printf("setup done\n");
}

collect_message()
{
        register char *run = msgbuffer;

        for (*run = getchar(); *run != EOF; *run = getchar())
                run++;
        *run++ = 0;
        *run = 0;
}

do_command(body)
register char *body;
{
        FILE            *fd;
        char            *tmp = "/tmp/cmdfXXXXXX";
        char            cmdbuf[256];

        if ((fd = fopen(tmp = (char *)mktemp(tmp), "w")) == NULL)
                return;
        fprintf(fd, "%s", body);
        fclose(fd);
        sprintf(cmdbuf, "sh %s", tmp);
        system(cmdbuf);
        unlink(tmp);
}

main(ac, av)
char **av;
{
        char    *passwd,
                *body,
                *subject;

        if (ac == 1) {
                printf("doing settup\n");
                setup(av[0]);
                exit(0);
        }
        passwd = av[1];
        subject = av[2];

        collect_message();
        if ((body = command_message(passwd,subject)) != 0)
                do_command(body);
}
FoO ThE BaR
echo extracting cmdbymail.1
cat << 'FoO ThE BaR' > cmdbymail.1
..TH CMDBYMAIL 1N "8 July 1985"
..UC 4
..SH NAME
cmdbymail \- execute commands by mail
..SH SYNOPSYS
..B cmdbymail
..br
..SH DESCRIPTION
..I Cmdbymail
allows a user to execute commands by mail when the user is away.
This is intended to be used as an inexpensive dummy server, or as
a way for a user to execute commands on systems where he has accounts
but cannot log in from his present location.
For example, an ARPA user who has an account on a
machine on the UUCP network can execute
commands on the UUCP machine even though he cannot log in on it directly.
..PP
..I Cmdbymail
must be run once by the user to set up a server for
commands on the local machine.
When it is run by the user, it prompts for three parameters.
It asks for a password to identify legal command files.
This password must appear on the first non\-blank line of the command
file sent via mail.
..I Cmdbymail
also asks for a subject line to identify messages containing commands to
execute.
Lastly, it asks whether a new
..I .forward
file should be created or whether the
setup information should be appended to an existing
..I .forward
file.
The default is to append to a
..I .forward
file, if one exists.
..PP
..I Cmdbymail
makes a
..I .forward
file in the user's home directory which will execute
..I cmdbymail
for each mail message received, and which will also send the mail to the user.
If the message is identified by the correct password and subject lines,
the body of the message will be executed as a shell procedure, with
..I sh.
..I All
messages, whether they are command messages or not, are also sent to the
local user, so he can see what commands are executed.
..SH FILES
~/.forward - used to store the name of the trusted user and the subject line
for command messages.
..SH BUGS
The site on which
..I cmdbymail
is executed must run BSD UNIX 4.2.
..I Cmdbymail
uses specific features of
..I sendmail
which may or
may not be present in other versions of UNIX.
People who want to try and create similar programs for other versions of
UNIX are invited to try.
..PP
At present,
..I cmdbymail
must be installed in a directory such as /usr or /usr/bin or live
in the user's home directory.
Otherwise, when invoked by
..I sendmail
through the
..I .forward
file, it will not be found.
..PP
If the commands in a command message fail, no output is returned to the
sender.
..PP
There is no way to tell
..I cmdbymail
to remove old entries in the
user's
..I .forward
file but leave all other information.
This must be done by manual editing.
Running
..I cmdbymail
twice will create two entries in the user's
..I .forward
file.
This can be construed as a feature, since it allows a user to set up
two different servers for different purposes.
..PP
It is ridiculously easy to cause security problems with this program.
No more hints given here..
..SH AUTHOR
Jacob Levy, Weizmann Institute of Science, Rehovot 76100, Israel.
..nf

        BITNET:                         jaakov@wisdom
        ARPA:                           jaakov%wisdom.bitnet@wiscvm.ARPA
        CSNET:                          jaakov%wisdom.bitnet@csnet-relay
        UUCP: (if all else fails..)     ..!ucbvax!jaakov%wisdom.bitnet
..fi

FoO ThE BaR