Annotation of researchv10no/cmd/asd/asdrcv.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     asdrcv - receive sealed packages
                      3:  *
                      4:  *     This program will normally be installed as /etc/asd/asdrcv
                      5:  *     and will be run as root (!).  It is invoked as follows:
                      6:  *
                      7:  *             /etc/asdrcv machine uid
                      8:  *
                      9:  *     where the standard input is a sealed package.  First it
                     10:  *     verifies that machine and uid are valid: they must consist
                     11:  *     entirely of letters and digits and may not be empty.
                     12:  *     Next we look at the file /etc/asd/perm/machine/uid.
                     13:  *     If this file doesn't exist, reject.  If it does exist,
                     14:  *     it represents the uid and gid on the receiving machine
                     15:  *     to use.  The default is the uid/gid under which asdrcv
                     16:  *     invoked, usually (root, other).
                     17:  *
                     18:  *
                     19:  *     We next arrange to send all stderr output to machine!uid.
                     20:  *     Finally, operating as the appropriate user, we create the
                     21:  *     following pipeline:
                     22:  *
                     23:  *             unseal -K /etc/asd/keys/machine/uid | inspkg -v
                     24:  */
                     25: 
                     26: #include "asd.h"
                     27: 
                     28: static char *keybase = "/etc/asd/keys";
                     29: static char *permbase = "/etc/asd/perm";
                     30: static char *buildname();
                     31: 
                     32: main (argc, argv)
                     33:        int argc;
                     34:        char **argv;
                     35: {
                     36:        register int i;
                     37:        char *permfile, *keyfile, *user;
                     38:        register FILE *permfd;
                     39:        int pipefd[2];
                     40: 
                     41:        /* check for exactly two arguments */
                     42:        if (argc != 2 + 1) {
                     43:                fprintf (stderr, "asdrcv: arg count\n");
                     44:                exit (1);
                     45:        }
                     46: 
                     47:        /*
                     48:         * each argument must be nonempty,
                     49:         * begin with a letter or digit, and
                     50:         * contain only letters, digits, '.', or '-'
                     51:         */
                     52:        for (i = 1; i < argc; i++) {
                     53:                register char *p = argv[i];
                     54:                if (*p == '\0') {
                     55:                        fprintf (stderr, "asdrcv: null argument\n");
                     56:                        exit (1);
                     57:                }
                     58: 
                     59:                if (*p == '.' || *p == '-') {
                     60:                        fprintf (stderr, "asdrcv: invalid argument\n");
                     61:                        exit (1);
                     62:                }
                     63: 
                     64:                do {
                     65:                        register c = *p++;
                     66:                        if (!isalpha (c) && !isdigit (c) &&
                     67:                            c != '.' && c != '-') {
                     68:                                fprintf (stderr, "asdrcv: invalid argument\n");
                     69:                                exit (1);
                     70:                        }
                     71:                } while (*p != '\0');
                     72:        }
                     73: 
                     74:        /* develop the names of the permission file and keyfile */
                     75:        permfile = buildname (permbase, argv[1], argv[2]);
                     76:        keyfile = buildname (keybase, argv[1], argv[2]);
                     77: 
                     78:        /* now try to read the permission file */
                     79:        permfd = fopen (permfile, "r");
                     80:        if (permfd == NULL) {
                     81:                perror (permfile);
                     82:                exit (1);
                     83:        }
                     84: 
                     85:        /* the optional line represents a uid/gid pair */
                     86:        i = getc (permfd);
                     87:        if (i != EOF) {
                     88:                int uid, gid;
                     89:                ungetc (i, permfd);
                     90:                uid = numuid (getfield (permfd));
                     91:                gid = numgid (getfield (permfd));
                     92:                setgid (gid);
                     93:                setuid (uid);
                     94:        }
                     95: 
                     96:        /* we're done with the file */
                     97:        fclose (permfd);
                     98: 
                     99:        /* build the stderr pipe */
                    100:        if (pipe (pipefd) < 0) {
                    101:                perror ("stderr pipe");
                    102:                exit (1);
                    103:        }
                    104: 
                    105:        /* fork off a mail process */
                    106:        switch (fork()) {
                    107: 
                    108:        case 0:                 /* child */
                    109:                close (pipefd[1]);              /* close the write end */
                    110:                dup2 (pipefd[0], 0);            /* stdin := read end */
                    111:                if (pipefd[0] != 0)
                    112:                close (pipefd[0]);              /* close the read end */
                    113: 
                    114:                /* make a string for machine!user */
                    115:                user = alloc (strlen (argv[1]) + strlen (argv[2]) + 2);
                    116:                strcpy (user, argv[1]);
                    117:                strcat (user, "!");
                    118:                strcat (user, argv[2]);
                    119: 
                    120:                /* send mail */
                    121:                execl ("/bin/mail", "mail", user, (char *) 0);
                    122:                execl ("/usr/bin/mail", "mail", user, (char *) 0);
                    123:                exit (1);
                    124:        
                    125:        case -1:
                    126:                perror ("stderr fork");
                    127:                exit (1);
                    128:        
                    129:        default:                /* parent */
                    130:                close (pipefd[0]);              /* close the read end */
                    131:                dup2 (pipefd[1], 2);            /* stderr := write end */
                    132:                dup2 (pipefd[1], 1);            /* stdout := write end also */
                    133:                close (pipefd[1]);              /* close the write end */
                    134:        }
                    135: 
                    136:        /* build the next pipe */
                    137:        if (pipe (pipefd) < 0) {
                    138:                perror ("pipe");
                    139:                exit (1);
                    140:        }
                    141: 
                    142:        /* create the processes */
                    143:        fflush (stdout);
                    144:        switch (fork()) {
                    145: 
                    146:        case -1:                        /* error */
                    147:                perror ("fork");
                    148:                exit (1);
                    149: 
                    150:        case 0:                         /* child */
                    151:                close (pipefd[0]);
                    152:                if (dup2 (pipefd[1], 1) < 0) {
                    153:                        perror ("stdout dup");
                    154:                        exit (1);
                    155:                }
                    156:                close (pipefd[1]);
                    157:                execl ("/bin/unseal", "unseal", "-K", keyfile, (char *) 0);
                    158:                execl ("/usr/bin/unseal", "unseal", "-K", keyfile, (char *) 0);
                    159:                fprintf (stderr, "asdrcv: cannot exec unseal\n");
                    160:                exit (1);
                    161:        
                    162:        default:                        /* parent */
                    163:                close (pipefd[1]);
                    164:                if (dup2 (pipefd[0], 0) < 0) {
                    165:                        perror ("stdin dup");
                    166:                        exit (1);
                    167:                }
                    168:                close (pipefd[0]);
                    169:                execl ("/bin/inspkg", "inspkg", "-v", (char *) 0);
                    170:                execl ("/usr/bin/inspkg", "inspkg", "-v", (char *) 0);
                    171:                fprintf (stderr, "asdrcv: cannot exec inspkg\n");
                    172:                exit (1);
                    173:        }
                    174: }
                    175: 
                    176: /* return a name of the form dir/comp1/comp2 */
                    177: static char *
                    178: buildname (dir, comp1, comp2)
                    179:        char *dir, *comp1, *comp2;
                    180: {
                    181:        register char *r;
                    182: 
                    183:        r = alloc (
                    184:                strlen (dir) +          /* name of directory */
                    185:                strlen (comp1) +        /* first component */
                    186:                strlen (comp2) +        /* second component */
                    187:                3                       /* two slashes and ending null */
                    188:            );
                    189: 
                    190:        strcpy (r, dir);
                    191:        strcat (r, "/"); strcat (r, comp1);
                    192:        strcat (r, "/"); strcat (r, comp2);
                    193: 
                    194:        return r;
                    195: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.