|
|
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.