4 * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 /* Id: ddns-confgen.c,v 1.9 2009/09/29 15:06:05 fdupont Exp */
24 * ddns-confgen generates configuration files for dynamic DNS. It can
25 * be used as a convenient alternative to writing the ddns.key file
26 * and the corresponding key and update-policy statements in named.conf.
34 #include <isc/assertions.h>
35 #include <isc/base64.h>
36 #include <isc/buffer.h>
37 #include <isc/commandline.h>
38 #include <isc/entropy.h>
40 #include <isc/keyboard.h>
43 #include <isc/print.h>
44 #include <isc/result.h>
45 #include <isc/string.h>
49 #include <dns/keyvalues.h>
53 #include <confgen/os.h>
58 #define DEFAULT_KEYNAME "ddns-key"
60 static char program
[256];
63 isc_boolean_t verbose
= ISC_FALSE
;
65 ISC_PLATFORM_NORETURN_PRE
static void
66 usage(int status
) ISC_PLATFORM_NORETURN_POST
;
73 %s [-a alg] [-k keyname] [-r randomfile] [-q] [-s name | -z zone]\n\
74 -a alg: algorithm (default hmac-sha256)\n\
75 -k keyname: name of the key as it will be used in named.conf\n\
76 -r randomfile: source of random data (use \"keyboard\" for key timing)\n\
77 -s name: domain name to be updated using the created key\n\
78 -z zone: name of the zone as it will be used in named.conf\n\
79 -q: quiet mode: print the key, with no explanatory text\n",
86 main(int argc
, char **argv
) {
87 isc_boolean_t show_final_mem
= ISC_FALSE
;
88 isc_boolean_t quiet
= ISC_FALSE
;
89 isc_buffer_t key_txtbuffer
;
90 char key_txtsecret
[256];
91 isc_mem_t
*mctx
= NULL
;
92 isc_result_t result
= ISC_R_SUCCESS
;
93 const char *randomfile
= NULL
;
94 const char *keyname
= NULL
;
95 const char *zone
= NULL
;
96 const char *self_domain
= NULL
;
98 dns_secalg_t alg
= DST_ALG_HMACSHA256
;
99 const char *algname
= alg_totext(alg
);
104 result
= isc_file_progname(*argv
, program
, sizeof(program
));
105 if (result
!= ISC_R_SUCCESS
)
106 memcpy(program
, "ddns-confgen", 13);
109 isc_commandline_errprint
= ISC_FALSE
;
111 while ((ch
= isc_commandline_parse(argc
, argv
,
112 "a:hk:Mmr:qs:Vy:z:")) != -1) {
115 algname
= isc_commandline_argument
;
116 alg
= alg_fromtext(algname
);
117 if (alg
== DST_ALG_UNKNOWN
)
118 fatal("Unsupported algorithm '%s'", algname
);
119 keysize
= alg_bits(alg
);
125 keyname
= isc_commandline_argument
;
128 isc_mem_debugging
= ISC_MEM_DEBUGTRACE
;
131 show_final_mem
= ISC_TRUE
;
137 randomfile
= isc_commandline_argument
;
140 self_domain
= isc_commandline_argument
;
146 zone
= isc_commandline_argument
;
149 if (isc_commandline_option
!= '?') {
150 fprintf(stderr
, "%s: invalid argument -%c\n",
151 program
, isc_commandline_option
);
157 fprintf(stderr
, "%s: unhandled option -%c\n",
158 program
, isc_commandline_option
);
163 argc
-= isc_commandline_index
;
164 argv
+= isc_commandline_index
;
166 if (self_domain
!= NULL
&& zone
!= NULL
)
167 usage(1); /* -s and -z cannot coexist */
172 DO("create memory context", isc_mem_create(0, 0, &mctx
));
174 if (keyname
== NULL
) {
175 const char *suffix
= NULL
;
177 keyname
= DEFAULT_KEYNAME
;
178 if (self_domain
!= NULL
)
179 suffix
= self_domain
;
180 else if (zone
!= NULL
)
182 if (suffix
!= NULL
) {
183 len
= strlen(keyname
) + strlen(suffix
) + 2;
184 keybuf
= isc_mem_get(mctx
, len
);
186 fatal("failed to allocate memory for keyname");
187 snprintf(keybuf
, len
, "%s.%s", keyname
, suffix
);
188 keyname
= (const char *) keybuf
;
192 isc_buffer_init(&key_txtbuffer
, &key_txtsecret
, sizeof(key_txtsecret
));
194 generate_key(mctx
, randomfile
, alg
, keysize
, &key_txtbuffer
);
199 # To activate this key, place the following in named.conf, and\n\
200 # in a separate keyfile on the system or systems from which nsupdate\n\
209 (int)isc_buffer_usedlength(&key_txtbuffer
),
210 (char *)isc_buffer_base(&key_txtbuffer
));
213 if (self_domain
!= NULL
) {
215 # Then, in the \"zone\" statement for the zone containing the\n\
216 # name \"%s\", place an \"update-policy\" statement\n\
217 # like this one, adjusted as needed for your preferred permissions:\n\
219 grant %s name %s ANY;\n\
221 self_domain
, keyname
, self_domain
);
222 } else if (zone
!= NULL
) {
224 # Then, in the \"zone\" definition statement for \"%s\",\n\
225 # place an \"update-policy\" statement like this one, adjusted as \n\
226 # needed for your preferred permissions:\n\
228 grant %s zonesub ANY;\n\
233 # Then, in the \"zone\" statement for each zone you wish to dynamically\n\
234 # update, place an \"update-policy\" statement granting update permission\n\
235 # to this key. For example, the following statement grants this key\n\
236 # permission to update any name within the zone:\n\
238 grant %s zonesub ANY;\n\
244 # After the keyfile has been placed, the following command will\n\
245 # execute nsupdate using this key:\n\
246 nsupdate -k <keyfile>\n");
251 isc_mem_put(mctx
, keybuf
, len
);
254 isc_mem_stats(mctx
, stderr
);
256 isc_mem_destroy(&mctx
);