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