|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.