Annotation of src/external/mpl/bind/dist/bin/dnssec/dnssec-verify.c, Revision 1.1.1.4
1.1 christos 1: /* $NetBSD$ */
2:
3: /*
4: * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5: *
6: * This Source Code Form is subject to the terms of the Mozilla Public
7: * License, v. 2.0. If a copy of the MPL was not distributed with this
1.1.1.4 ! christos 8: * file, you can obtain one at https://mozilla.org/MPL/2.0/.
1.1 christos 9: *
10: * See the COPYRIGHT file distributed with this work for additional
11: * information regarding copyright ownership.
12: */
13:
14: /*! \file */
15:
1.1.1.2 christos 16: #include <stdbool.h>
1.1 christos 17: #include <stdlib.h>
18: #include <time.h>
19:
20: #include <isc/app.h>
21: #include <isc/base32.h>
22: #include <isc/commandline.h>
23: #include <isc/event.h>
24: #include <isc/file.h>
25: #include <isc/hash.h>
26: #include <isc/hex.h>
27: #include <isc/mem.h>
28: #include <isc/mutex.h>
29: #include <isc/os.h>
30: #include <isc/print.h>
31: #include <isc/random.h>
32: #include <isc/rwlock.h>
33: #include <isc/serial.h>
34: #include <isc/stdio.h>
35: #include <isc/string.h>
36: #include <isc/time.h>
37: #include <isc/util.h>
38:
39: #include <dns/db.h>
40: #include <dns/dbiterator.h>
41: #include <dns/diff.h>
42: #include <dns/dnssec.h>
43: #include <dns/ds.h>
44: #include <dns/fixedname.h>
45: #include <dns/keyvalues.h>
46: #include <dns/log.h>
47: #include <dns/master.h>
48: #include <dns/masterdump.h>
49: #include <dns/nsec.h>
50: #include <dns/nsec3.h>
51: #include <dns/rdata.h>
1.1.1.3 christos 52: #include <dns/rdataclass.h>
1.1 christos 53: #include <dns/rdatalist.h>
54: #include <dns/rdataset.h>
55: #include <dns/rdatasetiter.h>
56: #include <dns/rdatastruct.h>
57: #include <dns/rdatatype.h>
58: #include <dns/result.h>
59: #include <dns/soa.h>
60: #include <dns/time.h>
1.1.1.2 christos 61: #include <dns/zoneverify.h>
1.1 christos 62:
63: #include <dst/dst.h>
64:
1.1.1.2 christos 65: #if USE_PKCS11
1.1 christos 66: #include <pk11/result.h>
1.1.1.3 christos 67: #endif /* if USE_PKCS11 */
1.1 christos 68:
69: #include "dnssectool.h"
70:
71: const char *program = "dnssec-verify";
72:
73: static isc_stdtime_t now;
74: static isc_mem_t *mctx = NULL;
75: static dns_masterformat_t inputformat = dns_masterformat_text;
1.1.1.3 christos 76: static dns_db_t *gdb; /* The database */
77: static dns_dbversion_t *gversion; /* The database version */
78: static dns_rdataclass_t gclass; /* The class */
79: static dns_name_t *gorigin; /* The database origin */
1.1.1.2 christos 80: static bool ignore_kskflag = false;
81: static bool keyset_kskonly = false;
1.1 christos 82:
1.1.1.3 christos 83: static void
84: report(const char *format, ...) {
85: if (!quiet) {
1.1.1.4 ! christos 86: char buf[4096];
1.1.1.3 christos 87: va_list args;
1.1.1.4 ! christos 88:
1.1.1.3 christos 89: va_start(args, format);
1.1.1.4 ! christos 90: vsnprintf(buf, sizeof(buf), format, args);
1.1.1.3 christos 91: va_end(args);
1.1.1.4 ! christos 92: fprintf(stdout, "%s\n", buf);
1.1.1.3 christos 93: }
94: }
95:
1.1 christos 96: /*%
97: * Load the zone file from disk
98: */
99: static void
100: loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
101: isc_buffer_t b;
102: int len;
103: dns_fixedname_t fname;
104: dns_name_t *name;
105: isc_result_t result;
106:
107: len = strlen(origin);
108: isc_buffer_init(&b, origin, len);
109: isc_buffer_add(&b, len);
110:
111: name = dns_fixedname_initname(&fname);
112: result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
1.1.1.3 christos 113: if (result != ISC_R_SUCCESS) {
114: fatal("failed converting name '%s' to dns format: %s", origin,
115: isc_result_totext(result));
116: }
1.1 christos 117:
1.1.1.3 christos 118: result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, rdclass, 0,
119: NULL, db);
1.1 christos 120: check_result(result, "dns_db_create()");
121:
1.1.1.2 christos 122: result = dns_db_load(*db, file, inputformat, 0);
1.1 christos 123: switch (result) {
124: case DNS_R_SEENINCLUDE:
125: case ISC_R_SUCCESS:
126: break;
127: case DNS_R_NOTZONETOP:
128: /*
129: * Comparing pointers (vs. using strcmp()) is intentional: we
130: * want to check whether -o was supplied on the command line,
131: * not whether origin and file contain the same string.
132: */
133: if (origin == file) {
134: fatal("failed loading zone '%s' from file '%s': "
135: "use -o to specify a different zone origin",
136: origin, file);
137: }
1.1.1.3 christos 138: /* FALLTHROUGH */
1.1 christos 139: default:
1.1.1.3 christos 140: fatal("failed loading zone from '%s': %s", file,
141: isc_result_totext(result));
1.1 christos 142: }
143: }
144:
145: ISC_PLATFORM_NORETURN_PRE static void
146: usage(void) ISC_PLATFORM_NORETURN_POST;
147:
148: static void
149: usage(void) {
150: fprintf(stderr, "Usage:\n");
151: fprintf(stderr, "\t%s [options] zonefile [keys]\n", program);
152:
153: fprintf(stderr, "\n");
154:
155: fprintf(stderr, "Version: %s\n", VERSION);
156:
157: fprintf(stderr, "Options: (default value in parenthesis) \n");
158: fprintf(stderr, "\t-v debuglevel (0)\n");
1.1.1.3 christos 159: fprintf(stderr, "\t-q quiet\n");
1.1 christos 160: fprintf(stderr, "\t-V:\tprint version information\n");
161: fprintf(stderr, "\t-o origin:\n");
162: fprintf(stderr, "\t\tzone origin (name of zonefile)\n");
163: fprintf(stderr, "\t-I format:\n");
164: fprintf(stderr, "\t\tfile format of input zonefile (text)\n");
165: fprintf(stderr, "\t-c class (IN)\n");
166: fprintf(stderr, "\t-E engine:\n");
1.1.1.2 christos 167: #if USE_PKCS11
1.1.1.3 christos 168: fprintf(stderr,
169: "\t\tpath to PKCS#11 provider library "
170: "(default is %s)\n",
171: PK11_LIB_LOCATION);
172: #else /* if USE_PKCS11 */
1.1 christos 173: fprintf(stderr, "\t\tname of an OpenSSL engine to use\n");
1.1.1.3 christos 174: #endif /* if USE_PKCS11 */
1.1 christos 175: fprintf(stderr, "\t-x:\tDNSKEY record signed with KSKs only, "
176: "not ZSKs\n");
177: fprintf(stderr, "\t-z:\tAll records signed with KSKs\n");
178: exit(0);
179: }
180:
181: int
182: main(int argc, char *argv[]) {
183: char *origin = NULL, *file = NULL;
184: char *inputformatstr = NULL;
185: isc_result_t result;
186: isc_log_t *log = NULL;
187: const char *engine = NULL;
188: char *classname = NULL;
189: dns_rdataclass_t rdclass;
190: char *endp;
191: int ch;
192:
1.1.1.3 christos 193: #define CMDLINE_FLAGS "c:E:hm:o:I:qv:Vxz"
1.1 christos 194:
195: /*
196: * Process memory debugging argument first.
197: */
198: while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
199: switch (ch) {
200: case 'm':
201: if (strcasecmp(isc_commandline_argument, "record") == 0)
1.1.1.3 christos 202: {
1.1 christos 203: isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
1.1.1.3 christos 204: }
1.1 christos 205: if (strcasecmp(isc_commandline_argument, "trace") == 0)
1.1.1.3 christos 206: {
1.1 christos 207: isc_mem_debugging |= ISC_MEM_DEBUGTRACE;
1.1.1.3 christos 208: }
1.1 christos 209: if (strcasecmp(isc_commandline_argument, "usage") == 0)
1.1.1.3 christos 210: {
1.1 christos 211: isc_mem_debugging |= ISC_MEM_DEBUGUSAGE;
1.1.1.3 christos 212: }
213: if (strcasecmp(isc_commandline_argument, "size") == 0) {
1.1 christos 214: isc_mem_debugging |= ISC_MEM_DEBUGSIZE;
1.1.1.3 christos 215: }
216: if (strcasecmp(isc_commandline_argument, "mctx") == 0) {
1.1 christos 217: isc_mem_debugging |= ISC_MEM_DEBUGCTX;
1.1.1.3 christos 218: }
1.1 christos 219: break;
220: default:
221: break;
222: }
223: }
1.1.1.2 christos 224: isc_commandline_reset = true;
1.1 christos 225: check_result(isc_app_start(), "isc_app_start");
226:
1.1.1.3 christos 227: isc_mem_create(&mctx);
1.1 christos 228:
1.1.1.2 christos 229: #if USE_PKCS11
1.1 christos 230: pk11_result_register();
1.1.1.3 christos 231: #endif /* if USE_PKCS11 */
1.1 christos 232: dns_result_register();
233:
1.1.1.2 christos 234: isc_commandline_errprint = false;
1.1 christos 235:
236: while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
237: switch (ch) {
238: case 'c':
239: classname = isc_commandline_argument;
240: break;
241:
242: case 'E':
243: engine = isc_commandline_argument;
244: break;
245:
246: case 'I':
247: inputformatstr = isc_commandline_argument;
248: break;
249:
250: case 'm':
251: break;
252:
253: case 'o':
254: origin = isc_commandline_argument;
255: break;
256:
257: case 'v':
258: endp = NULL;
259: verbose = strtol(isc_commandline_argument, &endp, 0);
1.1.1.3 christos 260: if (*endp != '\0') {
1.1 christos 261: fatal("verbose level must be numeric");
1.1.1.3 christos 262: }
263: break;
264:
265: case 'q':
266: quiet = true;
1.1 christos 267: break;
268:
269: case 'x':
1.1.1.2 christos 270: keyset_kskonly = true;
1.1 christos 271: break;
272:
273: case 'z':
1.1.1.2 christos 274: ignore_kskflag = true;
1.1 christos 275: break;
276:
277: case '?':
1.1.1.3 christos 278: if (isc_commandline_option != '?') {
1.1 christos 279: fprintf(stderr, "%s: invalid argument -%c\n",
280: program, isc_commandline_option);
1.1.1.3 christos 281: }
1.1 christos 282: /* FALLTHROUGH */
283:
284: case 'h':
285: /* Does not return. */
286: usage();
287:
288: case 'V':
289: /* Does not return. */
290: version(program);
291:
292: default:
1.1.1.3 christos 293: fprintf(stderr, "%s: unhandled option -%c\n", program,
294: isc_commandline_option);
1.1 christos 295: exit(1);
296: }
297: }
298:
1.1.1.2 christos 299: result = dst_lib_init(mctx, engine);
1.1.1.3 christos 300: if (result != ISC_R_SUCCESS) {
1.1 christos 301: fatal("could not initialize dst: %s",
302: isc_result_totext(result));
1.1.1.3 christos 303: }
1.1 christos 304:
305: isc_stdtime_get(&now);
306:
307: rdclass = strtoclass(classname);
308:
309: setup_logging(mctx, &log);
310:
311: argc -= isc_commandline_index;
312: argv += isc_commandline_index;
313:
1.1.1.3 christos 314: if (argc < 1) {
1.1 christos 315: usage();
1.1.1.3 christos 316: }
1.1 christos 317:
318: file = argv[0];
319:
320: argc -= 1;
321: argv += 1;
322:
323: POST(argc);
324: POST(argv);
325:
1.1.1.3 christos 326: if (origin == NULL) {
1.1 christos 327: origin = file;
1.1.1.3 christos 328: }
1.1 christos 329:
330: if (inputformatstr != NULL) {
1.1.1.3 christos 331: if (strcasecmp(inputformatstr, "text") == 0) {
1.1 christos 332: inputformat = dns_masterformat_text;
1.1.1.3 christos 333: } else if (strcasecmp(inputformatstr, "raw") == 0) {
1.1 christos 334: inputformat = dns_masterformat_raw;
1.1.1.3 christos 335: } else {
1.1 christos 336: fatal("unknown file format: %s\n", inputformatstr);
1.1.1.3 christos 337: }
1.1 christos 338: }
339:
340: gdb = NULL;
1.1.1.3 christos 341: report("Loading zone '%s' from file '%s'\n", origin, file);
1.1 christos 342: loadzone(file, origin, rdclass, &gdb);
343: gorigin = dns_db_origin(gdb);
344: gclass = dns_db_class(gdb);
345:
346: gversion = NULL;
347: result = dns_db_newversion(gdb, &gversion);
348: check_result(result, "dns_db_newversion()");
349:
1.1.1.3 christos 350: result = dns_zoneverify_dnssec(NULL, gdb, gversion, gorigin, NULL, mctx,
351: ignore_kskflag, keyset_kskonly, report);
1.1 christos 352:
1.1.1.2 christos 353: dns_db_closeversion(gdb, &gversion, false);
1.1 christos 354: dns_db_detach(&gdb);
355:
356: cleanup_logging(&log);
357: dst_lib_destroy();
1.1.1.3 christos 358: if (verbose > 10) {
1.1 christos 359: isc_mem_stats(mctx, stdout);
1.1.1.3 christos 360: }
1.1 christos 361: isc_mem_destroy(&mctx);
362:
1.1.1.3 christos 363: (void)isc_app_finish();
1.1 christos 364:
1.1.1.2 christos 365: return (result == ISC_R_SUCCESS ? 0 : 1);
1.1 christos 366: }
CVSweb <webmaster@jp.NetBSD.org>