|
|
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
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: /* each argument must be nonempty and all letters or digits */
48: for (i = 1; i < argc; i++) {
49: register char *p = argv[i];
50: if (*p == '\0') {
51: fprintf (stderr, "asdrcv: null argument\n");
52: exit (1);
53: }
54:
55: do {
56: register c = *p++;
57: if (!isalpha (c) && !isdigit (c)) {
58: fprintf (stderr, "asdrcv: invalid argument\n");
59: exit (1);
60: }
61: } while (*p != '\0');
62: }
63:
64: /* develop the names of the permission file and keyfile */
65: permfile = buildname (permbase, argv[1], argv[2]);
66: keyfile = buildname (keybase, argv[1], argv[2]);
67:
68: /* now try to read the permission file */
69: permfd = fopen (permfile, "r");
70: if (permfd == NULL) {
71: perror (permfile);
72: exit (1);
73: }
74:
75: /* the optional line represents a uid/gid pair */
76: i = getc (permfd);
77: if (i != EOF) {
78: int uid, gid;
79: ungetc (i, permfd);
80: uid = numuid (getfield (permfd));
81: gid = numgid (getfield (permfd));
82: setgid (gid);
83: setuid (uid);
84: }
85:
86: /* we're done with the file */
87: fclose (permfd);
88:
89: /* build the stderr pipe */
90: if (pipe (pipefd) < 0) {
91: perror ("stderr pipe");
92: exit (1);
93: }
94:
95: /* fork off a mail process */
96: switch (fork()) {
97:
98: case 0: /* child */
99: close (pipefd[1]); /* close the write end */
100: dup2 (pipefd[0], 0); /* stdin := read end */
101: if (pipefd[0] != 0)
102: close (pipefd[0]); /* close the read end */
103:
104: /* make a string for machine!user */
105: user = alloc (strlen (argv[1]) + strlen (argv[2]) + 2);
106: strcpy (user, argv[1]);
107: strcat (user, "!");
108: strcat (user, argv[2]);
109:
110: /* send mail */
111: execl ("/bin/mail", "mail", user, (char *) 0);
112: execl ("/usr/bin/mail", "mail", user, (char *) 0);
113: exit (1);
114:
115: case -1:
116: perror ("stderr fork");
117: exit (1);
118:
119: default: /* parent */
120: close (pipefd[0]); /* close the read end */
121: dup2 (pipefd[1], 2); /* stderr := write end */
122: close (pipefd[1]); /* close the write end */
123: }
124:
125: /* build the next pipe */
126: if (pipe (pipefd) < 0) {
127: perror ("pipe");
128: exit (1);
129: }
130:
131: /* create the processes */
132: fflush (stdout);
133: switch (fork()) {
134:
135: case -1: /* error */
136: perror ("fork");
137: exit (1);
138:
139: case 0: /* child */
140: close (pipefd[0]);
141: if (dup2 (pipefd[1], 1) < 0) {
142: perror ("stdout dup");
143: exit (1);
144: }
145: close (pipefd[1]);
146: execl ("/bin/unseal", "unseal", "-K", keyfile, (char *) 0);
147: execl ("/usr/bin/unseal", "unseal", "-K", keyfile, (char *) 0);
148: fprintf (stderr, "asdrcv: cannot exec unseal\n");
149: exit (1);
150:
151: default: /* parent */
152: close (pipefd[1]);
153: if (dup2 (pipefd[0], 0) < 0) {
154: perror ("stdin dup");
155: exit (1);
156: }
157: close (pipefd[0]);
158: execl ("/bin/inspkg", "inspkg", (char *) 0);
159: execl ("/usr/bin/inspkg", "inspkg", (char *) 0);
160: fprintf (stderr, "asdrcv: cannot exec inspkg\n");
161: exit (1);
162: }
163: }
164:
165: /* return a name of the form dir/comp1/comp2 */
166: static char *
167: buildname (dir, comp1, comp2)
168: char *dir, *comp1, *comp2;
169: {
170: register char *r;
171:
172: r = alloc (
173: strlen (dir) + /* name of directory */
174: strlen (comp1) + /* first component */
175: strlen (comp2) + /* second component */
176: 3 /* two slashes and ending null */
177: );
178:
179: strcpy (r, dir);
180: strcat (r, "/"); strcat (r, comp1);
181: strcat (r, "/"); strcat (r, comp2);
182:
183: return r;
184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.