|
|
1.1 root 1: /*
2: * unseal - disclose and verify the contents of a sealed package
3: */
4:
5: #include "asd.h"
6: #include "seal.h"
7: #include <ctype.h>
8:
9: static FILE *outfd;
10: static char outf[] = "/usr/tmp/usXXXXXX";
11: static char line[MAXULINE];
12:
13: main (argc, argv)
14: int argc;
15: char **argv;
16: {
17: int rc = 0;
18: int c;
19: char *keyfile;
20: static char stdbuf[BUFSIZ];
21:
22: setbuf (stdout, stdbuf);
23:
24: umask (077);
25: mktemp (outf);
26: outfd = fopen (outf, "w+");
27: if (outfd == NULL) {
28: fprintf (stderr, "unseal: can't create temp file\n");
29: exit (1);
30: }
31:
32: /* don't leave dregs */
33: unlink (outf);
34:
35: rc = getargs (argc, argv, "kK:", unseal);
36:
37: /* if successful, copy the temp file to the output */
38: if (rc == 0) {
39: register FILE *in = outfd, *out = stdout;
40: register int ch;
41:
42: rewind (in);
43:
44: while ((ch = getc (in)) != EOF)
45: putc (ch, out);
46:
47: fflush (out);
48:
49: if (ferror (in)) {
50: fprintf (stderr, "unseal: error reading temp file\n");
51: rc++;
52: }
53:
54: if (ferror (out)) {
55: fprintf (stderr, "unseal: error writing stdout\n");
56: rc++;
57: }
58: }
59:
60: return rc;
61: }
62:
63: static unsigned long length, checksum;
64:
65: unseal (f, fname)
66: FILE *f;
67: char *fname;
68: {
69: int intext = 0, rc = 0, nulltext = 1;
70:
71: length = checksum = 0;
72: resetN12();
73:
74: while (fgets (line, MAXULINE, f) != NULL) {
75:
76: /* check for a control line, which starts with "!" */
77: if (line[0] == '!') {
78: if (intext) {
79: /* only thing allowed is !end */
80: if (strncmp (line + 1, "end ", 4) == 0) {
81: rc += docksum (line, length, checksum);
82: intext = 0;
83: } else {
84: fprintf (stderr, "invalid control line %s", line);
85: rc++;
86: }
87: } else {
88: /* look for header, else quietly ignore */
89: if (strcmp (line + 1, "<seal>\n") == 0) {
90: intext++;
91: nulltext = 0;
92: }
93: }
94: /* data lines are quietly ignored if not in text */
95: } else if (intext) {
96: rc += dodata (line);
97: }
98: }
99:
100: if (nulltext) {
101: fprintf (stderr, "unseal: no contents\n");
102: rc++;
103: }
104:
105: if (intext) {
106: fprintf (stderr, "unseal: no checksum\n");
107: rc++;
108: }
109:
110: return rc;
111: }
112:
113: static char *
114: csverify (p, value)
115: register char *p;
116: register unsigned long value;
117: {
118: register unsigned long n = 0;
119:
120: while (isspace (*p))
121: p++;
122:
123: if (!isdigit (*p))
124: return NULL;
125:
126: do n = n * 10 + *p++ - '0';
127: while (isdigit (*p));
128:
129: if (!isspace (*p))
130: return NULL;
131:
132: if (n != value)
133: return NULL;
134:
135: return p;
136: }
137:
138: docksum (line, length, checksum)
139: char *line;
140: unsigned long length, checksum;
141: {
142: register char *p = line + 5;
143:
144: p = csverify (p, length);
145: if (p == NULL) {
146: fprintf (stderr, "unseal: invalid length\n");
147: return 1;
148: }
149: p = csverify (p, checksum);
150: if (p == NULL) {
151: fprintf (stderr, "unseal: invalid checksum\n");
152: return 1;
153: }
154: return 0;
155: }
156:
157: dodata (line)
158: char *line;
159: {
160: int hrout(), mrout();
161: char out[MAXULINE * 2];
162: int r;
163:
164: r = (*(line[0] == '.'? mrout: hrout)) (line, out);
165: if (r < 0)
166: return 1;
167: fwrite (out, sizeof(*out), r, outfd);
168: length += r;
169:
170: if (kflag || Kflag)
171: mangle (out, out + r);
172:
173: checksum = mkcsum (checksum, out, out + r);
174:
175: return 0;
176: }
177:
178: int
179: hrout (line, out)
180: char *line, *out;
181: {
182: register char *p, *q;
183: register int ch;
184:
185: p = line;
186: q = out;
187:
188: while ((ch = *p++) != '\0') {
189: if (ch != '\\') {
190: *q++ = ch;
191: } else {
192: ch = *p++;
193: if (ch == '\\' || ch == '.' || ch == '!' || ch == 'F') {
194: *q++ = ch;
195: } else if (ch != '\n') {
196: register int n = 0, i = 1;
197:
198: do {
199: ch = unhex (ch);
200: if (ch < 0) {
201: fprintf (stderr,
202: "bad hex char: %s", line);
203: return -1;
204: }
205: n = (n << 4) | ch;
206: if (i)
207: ch = *p++;
208: } while (--i >= 0);
209:
210: *q++ = n;
211: }
212: }
213: }
214:
215: return q - out;
216: }
217:
218: int
219: unhex (c)
220: register int c;
221: {
222: register char *p;
223:
224: p = hextab;
225: while (*p && *p != c)
226: p++;
227: if (*p)
228: return p - hextab;
229: return -1;
230: }
231:
232: int
233: mrout (line, out)
234: char *line, *out;
235: {
236: register char *p = line + 1;
237: char *q = out;
238:
239: while (*p != '\n' && *p != '\0') {
240: register unsigned long bits;
241: register int n;
242: register char *rq;
243:
244: n = 0;
245: bits = 0;
246: do {
247: register int ch = *p++;
248: if (ch == '\n')
249: break;
250: if (ch < RADBASE || ch >= RADBASE + RADIX) {
251: fprintf (stderr, "bad input char: %s", line);
252: return -1;
253: }
254: bits = bits * RADIX + ch - RADBASE;
255: n++;
256: } while (n < OUTCPW);
257:
258: n -= OUTCPW - INCPW;
259: if (n <= 0) {
260: fprintf (stderr, "non-positive output count: %s", line);
261: return -1;
262: }
263:
264: rq = q = q + n;
265: do {
266: *--rq = bits;
267: bits >>= BPC;
268: } while (--n > 0);
269: }
270:
271: return q - out;
272: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.