2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: dnssectool.c,v 1.31.2.5 2004/03/09 06:09:16 marka Exp $ */
24 #include <isc/buffer.h>
25 #include <isc/entropy.h>
26 #include <isc/string.h>
29 #include <isc/print.h>
33 #include <dns/rdatastruct.h>
34 #include <dns/rdatatype.h>
35 #include <dns/result.h>
36 #include <dns/secalg.h>
39 #include "dnssectool.h"
42 extern const char *program
;
44 static isc_entropysource_t
*source
= NULL
;
45 static fatalcallback_t
*fatalcallback
= NULL
;
48 fatal(const char *format
, ...) {
51 fprintf(stderr
, "%s: ", program
);
52 va_start(args
, format
);
53 vfprintf(stderr
, format
, args
);
55 fprintf(stderr
, "\n");
56 if (fatalcallback
!= NULL
)
62 setfatalcallback(fatalcallback_t
*callback
) {
63 fatalcallback
= callback
;
67 check_result(isc_result_t result
, const char *message
) {
68 if (result
!= ISC_R_SUCCESS
)
69 fatal("%s: %s", message
, isc_result_totext(result
));
73 vbprintf(int level
, const char *fmt
, ...) {
78 fprintf(stderr
, "%s: ", program
);
79 vfprintf(stderr
, fmt
, ap
);
84 type_format(const dns_rdatatype_t type
, char *cp
, unsigned int size
) {
89 isc_buffer_init(&b
, cp
, size
- 1);
90 result
= dns_rdatatype_totext(type
, &b
);
91 check_result(result
, "dns_rdatatype_totext()");
92 isc_buffer_usedregion(&b
, &r
);
97 alg_format(const dns_secalg_t alg
, char *cp
, unsigned int size
) {
102 isc_buffer_init(&b
, cp
, size
- 1);
103 result
= dns_secalg_totext(alg
, &b
);
104 check_result(result
, "dns_secalg_totext()");
105 isc_buffer_usedregion(&b
, &r
);
106 r
.base
[r
.length
] = 0;
110 sig_format(dns_rdata_sig_t
*sig
, char *cp
, unsigned int size
) {
111 char namestr
[DNS_NAME_FORMATSIZE
];
112 char algstr
[DNS_NAME_FORMATSIZE
];
114 dns_name_format(&sig
->signer
, namestr
, sizeof namestr
);
115 alg_format(sig
->algorithm
, algstr
, sizeof algstr
);
116 snprintf(cp
, size
, "%s/%s/%d", namestr
, algstr
, sig
->keyid
);
120 key_format(const dst_key_t
*key
, char *cp
, unsigned int size
) {
121 char namestr
[DNS_NAME_FORMATSIZE
];
122 char algstr
[DNS_NAME_FORMATSIZE
];
124 dns_name_format(dst_key_name(key
), namestr
, sizeof namestr
);
125 alg_format((dns_secalg_t
) dst_key_alg(key
), algstr
, sizeof algstr
);
126 snprintf(cp
, size
, "%s/%s/%d", namestr
, algstr
, dst_key_id(key
));
130 setup_logging(int verbose
, isc_mem_t
*mctx
, isc_log_t
**logp
) {
132 isc_logdestination_t destination
;
133 isc_logconfig_t
*logconfig
= NULL
;
134 isc_log_t
*log
= NULL
;
140 * We want to see warnings about things like out-of-zone
141 * data in the master file even when not verbose.
143 level
= ISC_LOG_WARNING
;
146 level
= ISC_LOG_INFO
;
149 level
= ISC_LOG_DEBUG(verbose
- 2 + 1);
153 RUNTIME_CHECK(isc_log_create(mctx
, &log
, &logconfig
) == ISC_R_SUCCESS
);
154 isc_log_setcontext(log
);
156 dns_log_setcontext(log
);
158 RUNTIME_CHECK(isc_log_settag(logconfig
, program
) == ISC_R_SUCCESS
);
161 * Set up a channel similar to default_stderr except:
162 * - the logging level is passed in
163 * - the program name and logging level are printed
164 * - no time stamp is printed
166 destination
.file
.stream
= stderr
;
167 destination
.file
.name
= NULL
;
168 destination
.file
.versions
= ISC_LOG_ROLLNEVER
;
169 destination
.file
.maximum_size
= 0;
170 result
= isc_log_createchannel(logconfig
, "stderr",
174 ISC_LOG_PRINTTAG
|ISC_LOG_PRINTLEVEL
);
175 check_result(result
, "isc_log_createchannel()");
177 RUNTIME_CHECK(isc_log_usechannel(logconfig
, "stderr",
178 NULL
, NULL
) == ISC_R_SUCCESS
);
184 cleanup_logging(isc_log_t
**logp
) {
187 REQUIRE(logp
!= NULL
);
192 isc_log_destroy(&log
);
193 isc_log_setcontext(NULL
);
194 dns_log_setcontext(NULL
);
199 setup_entropy(isc_mem_t
*mctx
, const char *randomfile
, isc_entropy_t
**ectx
) {
201 int usekeyboard
= ISC_ENTROPY_KEYBOARDMAYBE
;
203 REQUIRE(ectx
!= NULL
);
206 result
= isc_entropy_create(mctx
, ectx
);
207 if (result
!= ISC_R_SUCCESS
)
208 fatal("could not create entropy object");
211 if (randomfile
!= NULL
&& strcmp(randomfile
, "keyboard") == 0) {
212 usekeyboard
= ISC_ENTROPY_KEYBOARDYES
;
216 result
= isc_entropy_usebestsource(*ectx
, &source
, randomfile
,
219 if (result
!= ISC_R_SUCCESS
)
220 fatal("could not initialize entropy source: %s",
221 isc_result_totext(result
));
225 cleanup_entropy(isc_entropy_t
**ectx
) {
227 isc_entropy_destroysource(&source
);
228 isc_entropy_detach(ectx
);
232 strtotime(char *str
, isc_int64_t now
, isc_int64_t base
) {
233 isc_int64_t val
, offset
;
238 offset
= strtol(str
+ 1, &endp
, 0);
240 fatal("time value %s is invalid", str
);
242 } else if (strncmp(str
, "now+", 4) == 0) {
243 offset
= strtol(str
+ 4, &endp
, 0);
245 fatal("time value %s is invalid", str
);
247 } else if (strlen(str
) == 8U) {
249 sprintf(timestr
, "%s000000", str
);
250 result
= dns_time64_fromtext(timestr
, &val
);
251 if (result
!= ISC_R_SUCCESS
)
252 fatal("time value %s is invalid", str
);
254 result
= dns_time64_fromtext(str
, &val
);
255 if (result
!= ISC_R_SUCCESS
)
256 fatal("time value %s is invalid", str
);
259 return ((isc_stdtime_t
) val
);