Annotation of researchv10no/cmd/asd/asdrcv.c, revision 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.