}
/*%
- * Reject key names that would not embed safely into a named.conf
- * 'key "<name>" { ... };' clause. Allowed: alphanumerics, '.', '-', '_'.
+ * Reject invalid key names and make them safe for embedding into
+ * rndc.conf and named.conf.
*/
void
-validate_keyname(const char *keyname) {
+makesafe_keyname(const char *keyname, char *namebuf, size_t length) {
dns_fixedname_t fixed;
dns_name_t *name = dns_fixedname_initname(&fixed);
isc_result_t result;
+ isc_buffer_t b;
if (keyname == NULL || keyname[0] == '\0') {
fatal("key name must not be empty");
}
-
result = dns_name_fromstring(name, keyname, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
fatal("invalid key name: %s", isc_result_totext(result));
}
+
+ isc_buffer_init(&b, namebuf, length);
+ result = dns_name_totext(name, DNS_NAME_QUOTED | DNS_NAME_OMITFINALDOT,
+ &b);
+ if (result != ISC_R_SUCCESS) {
+ fatal("invalid key name: %s", isc_result_totext(result));
+ }
}
/*%
#include <dns/secalg.h>
void
-validate_keyname(const char *keyname);
+makesafe_keyname(const char *keyname, char *namebuf, size_t length);
void
generate_key(isc_mem_t *mctx, dns_secalg_t alg, int keysize,
bool show_final_mem = false;
isc_buffer_t key_txtbuffer;
char key_txtsecret[256];
+ char namebuf[DNS_NAME_FORMATSIZE];
const char *keyname = NULL;
const char *serveraddr = NULL;
dns_secalg_t alg;
usage(EXIT_FAILURE);
}
- validate_keyname(keyname);
+ makesafe_keyname(keyname, namebuf, sizeof(namebuf));
if (alg == DST_ALG_HMACMD5) {
fprintf(stderr, "warning: use of hmac-md5 for RNDC keys "
if (keyonly) {
write_key_file(keyfile, chrootdir == NULL ? user : NULL,
- keyname, &key_txtbuffer, alg);
+ namebuf, &key_txtbuffer, alg);
if (!quiet) {
printf("wrote key file \"%s\"\n", keyfile);
}
snprintf(buf, len, "%s%s%s", chrootdir,
(*keyfile != '/') ? "/" : "", keyfile);
- write_key_file(buf, user, keyname, &key_txtbuffer, alg);
+ write_key_file(buf, user, namebuf, &key_txtbuffer, alg);
if (!quiet) {
printf("wrote key file \"%s\"\n", buf);
}
# allow { %s; } keys { \"%s\"; };\n\
# };\n\
# End of named.conf\n",
- keyname, algname,
+ namebuf, algname,
(int)isc_buffer_usedlength(&key_txtbuffer),
- (char *)isc_buffer_base(&key_txtbuffer), keyname,
- serveraddr, port, keyname, algname,
+ (char *)isc_buffer_base(&key_txtbuffer), namebuf,
+ serveraddr, port, namebuf, algname,
(int)isc_buffer_usedlength(&key_txtbuffer),
(char *)isc_buffer_base(&key_txtbuffer), serveraddr,
- port, serveraddr, keyname);
+ port, serveraddr, namebuf);
}
if (show_final_mem) {
.. option:: -k keyname
- This option specifies the key name of the :iscman:`rndc` authentication key. This must be a
- valid domain name. The default is ``rndc-key``.
+ This option specifies the key name of the :iscman:`rndc`
+ authentication key. This must be a valid domain name and will
+ be sanitized using the domain name semantics. The default is
+ ``rndc-key``.
.. option:: -p port
bool quiet = false;
isc_buffer_t key_txtbuffer;
char key_txtsecret[256];
+ char namebuf[DNS_NAME_FORMATSIZE];
const char *keyname = NULL;
const char *zone = NULL;
const char *self_domain = NULL;
}
}
- validate_keyname(keyname);
+ makesafe_keyname(keyname, namebuf, sizeof(namebuf));
isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret));
algorithm %s;\n\
secret \"%.*s\";\n\
};\n",
- keyname, algname, (int)isc_buffer_usedlength(&key_txtbuffer),
+ namebuf, algname, (int)isc_buffer_usedlength(&key_txtbuffer),
(char *)isc_buffer_base(&key_txtbuffer));
if (!quiet) {
update-policy {\n\
grant %s name %s ANY;\n\
};\n",
- self_domain, keyname, self_domain);
+ self_domain, namebuf, self_domain);
} else if (zone != NULL) {
printf("\n\
# Then, in the \"zone\" definition statement for \"%s\",\n\
update-policy {\n\
grant %s zonesub ANY;\n\
};\n",
- zone, keyname);
+ zone, namebuf);
} else {
printf("\n\
# Then, in the \"zone\" statement for each zone you wish to dynamically\n\
update-policy {\n\
grant %s zonesub ANY;\n\
};\n",
- keyname);
+ namebuf);
}
printf("\n\