"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.16.7/bin/confgen/ddns-confgen.c" (4 Sep 2020, 7340 Bytes) of package /linux/misc/dns/bind9/9.16.7/bind-9.16.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ddns-confgen.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 /*! \file */
   13 
   14 /**
   15  * ddns-confgen generates configuration files for dynamic DNS. It can
   16  * be used as a convenient alternative to writing the ddns.key file
   17  * and the corresponding key and update-policy statements in named.conf.
   18  */
   19 
   20 #include <stdarg.h>
   21 #include <stdbool.h>
   22 #include <stdlib.h>
   23 
   24 #include <isc/assertions.h>
   25 #include <isc/base64.h>
   26 #include <isc/buffer.h>
   27 #include <isc/commandline.h>
   28 #include <isc/file.h>
   29 #include <isc/mem.h>
   30 #include <isc/net.h>
   31 #include <isc/print.h>
   32 #include <isc/result.h>
   33 #include <isc/string.h>
   34 #include <isc/time.h>
   35 #include <isc/util.h>
   36 
   37 #if USE_PKCS11
   38 #include <pk11/result.h>
   39 #endif /* if USE_PKCS11 */
   40 
   41 #include <dns/keyvalues.h>
   42 #include <dns/name.h>
   43 #include <dns/result.h>
   44 
   45 #include <dst/dst.h>
   46 
   47 #include <confgen/os.h>
   48 
   49 #include "keygen.h"
   50 #include "util.h"
   51 
   52 #define KEYGEN_DEFAULT  "tsig-key"
   53 #define CONFGEN_DEFAULT "ddns-key"
   54 
   55 static char program[256];
   56 const char *progname;
   57 static enum { progmode_keygen, progmode_confgen } progmode;
   58 bool verbose = false; /* needed by util.c but not used here */
   59 
   60 ISC_PLATFORM_NORETURN_PRE static void
   61 usage(int status) ISC_PLATFORM_NORETURN_POST;
   62 
   63 static void
   64 usage(int status) {
   65     if (progmode == progmode_confgen) {
   66         fprintf(stderr, "\
   67 Usage:\n\
   68  %s [-a alg] [-k keyname] [-q] [-s name | -z zone]\n\
   69   -a alg:        algorithm (default hmac-sha256)\n\
   70   -k keyname:    name of the key as it will be used in named.conf\n\
   71   -s name:       domain name to be updated using the created key\n\
   72   -z zone:       name of the zone as it will be used in named.conf\n\
   73   -q:            quiet mode: print the key, with no explanatory text\n",
   74             progname);
   75     } else {
   76         fprintf(stderr, "\
   77 Usage:\n\
   78  %s [-a alg] [keyname]\n\
   79   -a alg:        algorithm (default hmac-sha256)\n\n",
   80             progname);
   81     }
   82 
   83     exit(status);
   84 }
   85 
   86 int
   87 main(int argc, char **argv) {
   88     isc_result_t result = ISC_R_SUCCESS;
   89     bool show_final_mem = false;
   90     bool quiet = false;
   91     isc_buffer_t key_txtbuffer;
   92     char key_txtsecret[256];
   93     isc_mem_t *mctx = NULL;
   94     const char *keyname = NULL;
   95     const char *zone = NULL;
   96     const char *self_domain = NULL;
   97     char *keybuf = NULL;
   98     dns_secalg_t alg = DST_ALG_HMACSHA256;
   99     const char *algname;
  100     int keysize = 256;
  101     int len = 0;
  102     int ch;
  103 
  104 #if USE_PKCS11
  105     pk11_result_register();
  106 #endif /* if USE_PKCS11 */
  107     dns_result_register();
  108 
  109     result = isc_file_progname(*argv, program, sizeof(program));
  110     if (result != ISC_R_SUCCESS) {
  111         memmove(program, "tsig-keygen", 11);
  112     }
  113     progname = program;
  114 
  115     /*
  116      * Libtool doesn't preserve the program name prior to final
  117      * installation.  Remove the libtool prefix ("lt-").
  118      */
  119     if (strncmp(progname, "lt-", 3) == 0) {
  120         progname += 3;
  121     }
  122 
  123 #define PROGCMP(X) \
  124     (strcasecmp(progname, X) == 0 || strcasecmp(progname, X ".exe") == 0)
  125 
  126     if (PROGCMP("tsig-keygen")) {
  127         progmode = progmode_keygen;
  128         quiet = true;
  129     } else if (PROGCMP("ddns-confgen")) {
  130         progmode = progmode_confgen;
  131     } else {
  132         INSIST(0);
  133         ISC_UNREACHABLE();
  134     }
  135 
  136     isc_commandline_errprint = false;
  137 
  138     while ((ch = isc_commandline_parse(argc, argv, "a:hk:Mmr:qs:y:z:")) !=
  139            -1) {
  140         switch (ch) {
  141         case 'a':
  142             algname = isc_commandline_argument;
  143             alg = alg_fromtext(algname);
  144             if (alg == DST_ALG_UNKNOWN) {
  145                 fatal("Unsupported algorithm '%s'", algname);
  146             }
  147             keysize = alg_bits(alg);
  148             break;
  149         case 'h':
  150             usage(0);
  151         case 'k':
  152         case 'y':
  153             if (progmode == progmode_confgen) {
  154                 keyname = isc_commandline_argument;
  155             } else {
  156                 usage(1);
  157             }
  158             break;
  159         case 'M':
  160             isc_mem_debugging = ISC_MEM_DEBUGTRACE;
  161             break;
  162         case 'm':
  163             show_final_mem = true;
  164             break;
  165         case 'q':
  166             if (progmode == progmode_confgen) {
  167                 quiet = true;
  168             } else {
  169                 usage(1);
  170             }
  171             break;
  172         case 'r':
  173             fatal("The -r option has been deprecated.");
  174             break;
  175         case 's':
  176             if (progmode == progmode_confgen) {
  177                 self_domain = isc_commandline_argument;
  178             } else {
  179                 usage(1);
  180             }
  181             break;
  182         case 'z':
  183             if (progmode == progmode_confgen) {
  184                 zone = isc_commandline_argument;
  185             } else {
  186                 usage(1);
  187             }
  188             break;
  189         case '?':
  190             if (isc_commandline_option != '?') {
  191                 fprintf(stderr, "%s: invalid argument -%c\n",
  192                     program, isc_commandline_option);
  193                 usage(1);
  194             } else {
  195                 usage(0);
  196             }
  197             break;
  198         default:
  199             fprintf(stderr, "%s: unhandled option -%c\n", program,
  200                 isc_commandline_option);
  201             exit(1);
  202         }
  203     }
  204 
  205     if (progmode == progmode_keygen) {
  206         keyname = argv[isc_commandline_index++];
  207     }
  208 
  209     POST(argv);
  210 
  211     if (self_domain != NULL && zone != NULL) {
  212         usage(1); /* -s and -z cannot coexist */
  213     }
  214 
  215     if (argc > isc_commandline_index) {
  216         usage(1);
  217     }
  218 
  219     /* Use canonical algorithm name */
  220     algname = alg_totext(alg);
  221 
  222     isc_mem_create(&mctx);
  223 
  224     if (keyname == NULL) {
  225         const char *suffix = NULL;
  226 
  227         keyname = ((progmode == progmode_keygen) ? KEYGEN_DEFAULT
  228                              : CONFGEN_DEFAULT);
  229         if (self_domain != NULL) {
  230             suffix = self_domain;
  231         } else if (zone != NULL) {
  232             suffix = zone;
  233         }
  234         if (suffix != NULL) {
  235             len = strlen(keyname) + strlen(suffix) + 2;
  236             keybuf = isc_mem_get(mctx, len);
  237             snprintf(keybuf, len, "%s.%s", keyname, suffix);
  238             keyname = (const char *)keybuf;
  239         }
  240     }
  241 
  242     isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret));
  243 
  244     generate_key(mctx, alg, keysize, &key_txtbuffer);
  245 
  246     if (!quiet) {
  247         printf("\
  248 # To activate this key, place the following in named.conf, and\n\
  249 # in a separate keyfile on the system or systems from which nsupdate\n\
  250 # will be run:\n");
  251     }
  252 
  253     printf("\
  254 key \"%s\" {\n\
  255     algorithm %s;\n\
  256     secret \"%.*s\";\n\
  257 };\n",
  258            keyname, algname, (int)isc_buffer_usedlength(&key_txtbuffer),
  259            (char *)isc_buffer_base(&key_txtbuffer));
  260 
  261     if (!quiet) {
  262         if (self_domain != NULL) {
  263             printf("\n\
  264 # Then, in the \"zone\" statement for the zone containing the\n\
  265 # name \"%s\", place an \"update-policy\" statement\n\
  266 # like this one, adjusted as needed for your preferred permissions:\n\
  267 update-policy {\n\
  268       grant %s name %s ANY;\n\
  269 };\n",
  270                    self_domain, keyname, self_domain);
  271         } else if (zone != NULL) {
  272             printf("\n\
  273 # Then, in the \"zone\" definition statement for \"%s\",\n\
  274 # place an \"update-policy\" statement like this one, adjusted as \n\
  275 # needed for your preferred permissions:\n\
  276 update-policy {\n\
  277       grant %s zonesub ANY;\n\
  278 };\n",
  279                    zone, keyname);
  280         } else {
  281             printf("\n\
  282 # Then, in the \"zone\" statement for each zone you wish to dynamically\n\
  283 # update, place an \"update-policy\" statement granting update permission\n\
  284 # to this key.  For example, the following statement grants this key\n\
  285 # permission to update any name within the zone:\n\
  286 update-policy {\n\
  287     grant %s zonesub ANY;\n\
  288 };\n",
  289                    keyname);
  290         }
  291 
  292         printf("\n\
  293 # After the keyfile has been placed, the following command will\n\
  294 # execute nsupdate using this key:\n\
  295 nsupdate -k <keyfile>\n");
  296     }
  297 
  298     if (keybuf != NULL) {
  299         isc_mem_put(mctx, keybuf, len);
  300     }
  301 
  302     if (show_final_mem) {
  303         isc_mem_stats(mctx, stderr);
  304     }
  305 
  306     isc_mem_destroy(&mctx);
  307 
  308     return (0);
  309 }