00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define _GNU_SOURCE
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <stdlib.h>
00032 #include <unistd.h>
00033 #include <errno.h>
00034 #include <fcntl.h>
00035 #include <limits.h>
00036
00037 #include "config.h"
00038
00039 #include <getopt.h>
00040 #include <string.h>
00041 #include <syslog.h>
00042 #include <sys/stat.h>
00043 #include <pwd.h>
00044 #include <grp.h>
00045
00046 #include <ksm/ksmutil.h>
00047 #include <ksm/ksm.h>
00048 #include <ksm/database.h>
00049 #include "ksm/database_statement.h"
00050 #include "ksm/db_fields.h"
00051 #include <ksm/datetime.h>
00052 #include <ksm/string_util.h>
00053 #include <ksm/string_util2.h>
00054 #include "ksm/kmemsg.h"
00055 #include "ksm/kmedef.h"
00056 #include "ksm/dbsmsg.h"
00057 #include "ksm/dbsdef.h"
00058 #include "ksm/message.h"
00059
00060 #include <libhsm.h>
00061 #include <libhsmdns.h>
00062 #include <ldns/ldns.h>
00063
00064 #include <libxml/tree.h>
00065 #include <libxml/parser.h>
00066 #include <libxml/xpointer.h>
00067 #include <libxml/xpath.h>
00068 #include <libxml/xpathInternals.h>
00069 #include <libxml/relaxng.h>
00070 #include <libxml/xmlreader.h>
00071 #include <libxml/xmlsave.h>
00072
00073 #define MAX(a, b) ((a) > (b) ? (a) : (b))
00074
00075
00076 #define INT_TYPE 0
00077 #define DURATION_TYPE 1
00078 #define BOOL_TYPE 2
00079 #define REPO_TYPE 3
00080 #define SERIAL_TYPE 4
00081 #define ROLLOVER_TYPE 5
00082 #define INT_TYPE_NO_FREE 6
00083
00084 #ifndef MAXPATHLEN
00085 # define MAXPATHLEN 4096
00086 #endif
00087
00088
00089 #ifdef LOG_DAEMON
00090 #define DEFAULT_LOG_FACILITY LOG_DAEMON
00091 #else
00092 #define DEFAULT_LOG_FACILITY LOG_USER
00093 #endif
00094
00095 extern char *optarg;
00096 extern int optind;
00097 const char *progname = NULL;
00098 char *config = (char *) OPENDNSSEC_CONFIG_FILE;
00099
00100 char *o_keystate = NULL;
00101 char *o_algo = NULL;
00102 char *o_input = NULL;
00103 char *o_cka_id = NULL;
00104 char *o_size = NULL;
00105 char *o_interval = NULL;
00106 char *o_output = NULL;
00107 char *o_policy = NULL;
00108 char *o_repository = NULL;
00109 char *o_signerconf = NULL;
00110 char *o_keytype = NULL;
00111 char *o_time = NULL;
00112 char *o_retire = NULL;
00113 char *o_zone = NULL;
00114 char *o_keytag = NULL;
00115 static int all_flag = 0;
00116 static int ds_flag = 0;
00117 static int retire_flag = 1;
00118 static int verbose_flag = 0;
00119 static int xml_flag = 1;
00120 static int td_flag = 0;
00121
00122 static int restart_enforcerd(void);
00123
00124 void
00125 usage_general ()
00126 {
00127 fprintf(stderr,
00128 " help\n"
00129 " --version aka -V\n");
00130 }
00131
00132 void
00133 usage_setup ()
00134 {
00135 fprintf(stderr,
00136 " setup\n"
00137 "\tImport config into a database (deletes current contents)\n");
00138 }
00139
00140 void
00141 usage_control ()
00142 {
00143 fprintf(stderr,
00144 " start|stop|notify\n"
00145 "\tStart, stop or SIGHUP the ods-enforcerd\n");
00146 }
00147
00148 void
00149 usage_update ()
00150 {
00151 fprintf(stderr,
00152 " update kasp\n"
00153 " update zonelist\n"
00154 " update conf\n"
00155 " update all\n"
00156 "\tUpdate database from config\n");
00157 }
00158
00159 void
00160 usage_zoneadd ()
00161 {
00162 fprintf(stderr,
00163 " zone add\n"
00164 "\t--zone <zone> aka -z\n"
00165 "\t[--policy <policy>] aka -p\n"
00166 "\t[--signerconf <signerconf.xml>] aka -s\n"
00167 "\t[--input <input>] aka -i\n"
00168 "\t[--output <output>] aka -o\n"
00169 "\t[--no-xml] aka -m\n");
00170 }
00171
00172 void
00173 usage_zonedel ()
00174 {
00175 fprintf(stderr,
00176 " zone delete\n"
00177 "\t--zone <zone> | --all aka -z / -a\n"
00178 "\t[--no-xml] aka -m\n");
00179 }
00180
00181 void
00182 usage_zonelist ()
00183 {
00184 fprintf(stderr,
00185 " zone list\n");
00186 }
00187
00188 void
00189 usage_zone ()
00190 {
00191 fprintf(stderr,
00192 "usage: %s [-f config] zone \n\n",
00193 progname);
00194 usage_zoneadd ();
00195 usage_zonedel ();
00196 usage_zonelist ();
00197 }
00198
00199 void
00200 usage_repo ()
00201 {
00202 fprintf(stderr,
00203 " repository list\n");
00204 }
00205
00206 void
00207 usage_policyexport ()
00208 {
00209 fprintf(stderr,
00210 " policy export\n"
00211 "\t--policy [policy_name] | --all aka -p / -a\n");
00212 }
00213
00214 void
00215 usage_policyimport ()
00216 {
00217 fprintf(stderr,
00218 " policy import\n");
00219 }
00220
00221 void
00222 usage_policylist ()
00223 {
00224 fprintf(stderr,
00225 " policy list\n");
00226 }
00227
00228 void
00229 usage_policypurge ()
00230 {
00231 fprintf(stderr,
00232 " policy purge\n");
00233 }
00234
00235 void
00236 usage_policy ()
00237 {
00238 fprintf(stderr,
00239 "usage: %s [-f config] \n\n",
00240 progname);
00241 usage_policyexport ();
00242 usage_policyimport ();
00243 usage_policylist ();
00244 usage_policypurge ();
00245 }
00246
00247 void
00248 usage_keylist ()
00249 {
00250 fprintf(stderr,
00251 " key list\n"
00252 "\t[--verbose]\n"
00253 "\t--zone <zone> | --all aka -z / -a\n"
00254 #if 0
00255 "\t(will appear soon:\n"
00256 "\t[--keystate <state>] aka -e\n"
00257 "\t[--keytype <type>] aka -t\n"
00258 "\t[--ds] aka -d)\n"
00259 #endif
00260 );
00261 }
00262
00263 void
00264 usage_keyexport ()
00265 {
00266 fprintf(stderr,
00267 " key export\n"
00268 "\t--zone <zone> | --all aka -z / -a\n"
00269 "\t[--keystate <state>] aka -e\n"
00270 "\t[--keytype <type>] aka -t\n"
00271 "\t[--ds] aka -d\n");
00272 }
00273
00274 void
00275 usage_keyimport ()
00276 {
00277 fprintf(stderr,
00278 " key import\n"
00279 "\t--cka_id <CKA_ID> aka -k\n"
00280 "\t--repository <repository> aka -r\n"
00281 "\t--zone <zone> aka -z\n"
00282 "\t--bits <size> aka -b\n"
00283 "\t--algorithm <algorithm> aka -g\n"
00284 "\t--keystate <state> aka -e\n"
00285 "\t--keytype <type> aka -t\n"
00286 "\t--time <time> aka -w\n"
00287 "\t[--retire <retire>] aka -y\n");
00288 }
00289
00290 void
00291 usage_keyroll ()
00292 {
00293 fprintf(stderr,
00294 " key rollover\n"
00295 "\t--zone zone [--keytype <type>] aka -z\n"
00296 " key rollover\n"
00297 "\t--policy policy [--keytype <type>] aka -p\n");
00298 }
00299
00300 void
00301 usage_keypurge ()
00302 {
00303 fprintf(stderr,
00304 " key purge\n"
00305 "\t--zone <zone> aka -z\n"
00306 " key purge\n"
00307 "\t--policy <policy> aka -p\n");
00308 }
00309
00310 void
00311 usage_keygen ()
00312 {
00313 fprintf(stderr,
00314 " key generate\n"
00315 "\t--policy <policy>\n"
00316 "\t--interval <interval>\n");
00317 }
00318
00319 void
00320 usage_keykskretire ()
00321 {
00322 fprintf(stderr,
00323 " key ksk-retire\n"
00324 "\t--zone <zone> aka -z\n"
00325 "\t--keytag <keytag> | --cka_id <CKA_ID> aka -x / -k\n");
00326 }
00327
00328 void
00329 usage_keydsseen ()
00330 {
00331 fprintf(stderr,
00332 " key ds-seen\n"
00333
00334 "\t--zone <zone> aka -z\n"
00335 "\t--keytag <keytag> | --cka_id <CKA_ID> aka -x / -k\n"
00336 "\t--no-retire\n");
00337 }
00338
00339 void
00340 usage_key ()
00341 {
00342 fprintf(stderr,
00343 "usage: %s [-f config] \n\n",
00344 progname);
00345 usage_keylist ();
00346 usage_keyexport ();
00347 usage_keyimport ();
00348 usage_keyroll ();
00349 usage_keypurge ();
00350 usage_keygen ();
00351 usage_keykskretire ();
00352 usage_keydsseen ();
00353 }
00354
00355 void
00356 usage_backup ()
00357 {
00358 fprintf(stderr,
00359 " backup prepare\n"
00360 "\t--repository <repository> aka -r\n"
00361 " backup commit\n"
00362 "\t--repository <repository> aka -r\n"
00363 " backup rollback\n"
00364 "\t--repository <repository> aka -r\n"
00365 " backup list\n"
00366 "\t--repository <repository> aka -r\n"
00367 " backup done\n"
00368 "\t--repository <repository> aka -r\n");
00369 }
00370
00371 void
00372 usage_rollover ()
00373 {
00374 fprintf(stderr,
00375 " rollover list\n"
00376 "\t[--zone <zone>]\n");
00377 }
00378
00379 void
00380 usage_database ()
00381 {
00382 fprintf(stderr,
00383 " database backup\n"
00384 "\t[--output <output>] aka -o\n");
00385 }
00386
00387 void
00388 usage_zonelist2 ()
00389 {
00390 fprintf(stderr,
00391 " zonelist export\n"
00392 " zonelist import\n");
00393 }
00394
00395 void
00396 usage ()
00397 {
00398 fprintf(stderr,
00399 "usage: %s [-f config] command [options]\n\n",
00400 progname);
00401
00402 usage_general ();
00403 usage_setup ();
00404 usage_control ();
00405 usage_update ();
00406 usage_zoneadd ();
00407 usage_zonedel ();
00408 usage_zonelist ();
00409 usage_repo ();
00410 usage_policyexport ();
00411 usage_policylist ();
00412 usage_policypurge ();
00413 usage_keylist ();
00414 usage_keyexport ();
00415 usage_keyimport ();
00416 usage_keyroll ();
00417 usage_keypurge ();
00418 usage_keygen ();
00419 usage_keykskretire ();
00420 usage_keydsseen ();
00421 usage_backup ();
00422 usage_rollover ();
00423 usage_database ();
00424 usage_zonelist2 ();
00425
00426 }
00427
00428 void
00429 date_help()
00430 {
00431 fprintf(stderr,
00432 "\n\tAllowed date/time strings are of the form:\n"
00433
00434 "\tYYYYMMDD[HH[MM[SS]]] (all numeric)\n"
00435 "\n"
00436 "\tor D-MMM-YYYY[:| ]HH[:MM[:SS]] (alphabetic month)\n"
00437 "\tor DD-MMM-YYYY[:| ]HH[:MM[:SS]] (alphabetic month)\n"
00438 "\tor YYYY-MMM-DD[:| ]HH[:MM[:SS]] (alphabetic month)\n"
00439 "\n"
00440 "\tD-MM-YYYY[:| ]HH[:MM[:SS]] (numeric month)\n"
00441 "\tDD-MM-YYYY[:| ]HH[:MM[:SS]] (numeric month)\n"
00442 "\tor YYYY-MM-DD[:| ]HH[:MM[:SS]] (numeric month)\n"
00443 "\n"
00444 "\t... and the distinction between them is given by the location of the\n"
00445 "\thyphens.\n");
00446 }
00447
00448 void
00449 states_help()
00450 {
00451 fprintf(stderr,
00452 "key states: GENERATE|PUBLISH|READY|ACTIVE|RETIRE|DEAD\n");
00453 }
00454
00455 void
00456 types_help()
00457 {
00458 fprintf(stderr,
00459 "key types: KSK|ZSK\n");
00460 }
00461
00462
00463
00464
00465 int
00466 cmd_setup ()
00467 {
00468 DB_HANDLE dbhandle;
00469 FILE* lock_fd = NULL;
00470 char* zone_list_filename;
00471 char* kasp_filename;
00472 int status = 0;
00473
00474
00475 char *dbschema = NULL;
00476 char *host = NULL;
00477 char *port = NULL;
00478 char *user = NULL;
00479 char *password = NULL;
00480
00481 char quoted_user[KSM_NAME_LENGTH];
00482 char quoted_password[KSM_NAME_LENGTH];
00483
00484 char* setup_command = NULL;
00485 char* lock_filename = NULL;
00486
00487 int user_certain;
00488 printf("*WARNING* This will erase all data in the database; are you sure? [y/N] ");
00489
00490 user_certain = getchar();
00491 if (user_certain != 'y' && user_certain != 'Y') {
00492 printf("Okay, quitting...\n");
00493 exit(0);
00494 }
00495
00496
00497
00498
00499 status = get_db_details(&dbschema, &host, &port, &user, &password);
00500 if (status != 0) {
00501 StrFree(host);
00502 StrFree(port);
00503 StrFree(dbschema);
00504 StrFree(user);
00505 StrFree(password);
00506 return(status);
00507 }
00508
00509
00510
00511
00512 if (DbFlavour() == SQLITE_DB) {
00513
00514
00515 StrAppend(&lock_filename, dbschema);
00516 StrAppend(&lock_filename, ".our_lock");
00517
00518 lock_fd = fopen(lock_filename, "w");
00519 status = get_lite_lock(lock_filename, lock_fd);
00520 if (status != 0) {
00521 printf("Error getting db lock\n");
00522 if (lock_fd != NULL) {
00523 fclose(lock_fd);
00524 }
00525 StrFree(lock_filename);
00526 StrFree(host);
00527 StrFree(port);
00528 StrFree(dbschema);
00529 StrFree(user);
00530 StrFree(password);
00531 return(1);
00532 }
00533 StrFree(lock_filename);
00534
00535
00536
00537 StrAppend(&setup_command, SQL_BIN);
00538 StrAppend(&setup_command, " ");
00539 StrAppend(&setup_command, dbschema);
00540 StrAppend(&setup_command, " < ");
00541 StrAppend(&setup_command, SQL_SETUP);
00542
00543 if (system(setup_command) != 0)
00544 {
00545 printf("Could not call db setup command:\n\t%s\n", setup_command);
00546 db_disconnect(lock_fd);
00547 StrFree(host);
00548 StrFree(port);
00549 StrFree(dbschema);
00550 StrFree(user);
00551 StrFree(password);
00552 StrFree(setup_command);
00553 return(1);
00554 }
00555 StrFree(setup_command);
00556
00557
00558
00559 if (fix_file_perms(dbschema) != 0)
00560 {
00561 printf("Couldn't fix permissions on file %s\n", dbschema);
00562 printf("Will coninue with setup, but you may need to manually change ownership\n");
00563 }
00564 }
00565 else {
00566
00567
00568
00569
00570 status = ShellQuoteString(user, quoted_user, KSM_NAME_LENGTH);
00571 if (status != 0) {
00572 printf("Failed to connect to database, username too long.\n");
00573 db_disconnect(lock_fd);
00574 StrFree(host);
00575 StrFree(port);
00576 StrFree(dbschema);
00577 StrFree(user);
00578 StrFree(password);
00579 return(1);
00580 }
00581
00582
00583 status = ShellQuoteString(password, quoted_password, KSM_NAME_LENGTH);
00584 if (status != 0) {
00585 printf("Failed to connect to database, password too long.\n");
00586 db_disconnect(lock_fd);
00587 StrFree(host);
00588 StrFree(port);
00589 StrFree(dbschema);
00590 StrFree(user);
00591 StrFree(password);
00592 return(1);
00593 }
00594
00595 StrAppend(&setup_command, SQL_BIN);
00596 StrAppend(&setup_command, " -u '");
00597 StrAppend(&setup_command, quoted_user);
00598 StrAppend(&setup_command, "'");
00599 if (host != NULL) {
00600 StrAppend(&setup_command, " -h ");
00601 StrAppend(&setup_command, host);
00602 if (port != NULL) {
00603 StrAppend(&setup_command, " -P ");
00604 StrAppend(&setup_command, port);
00605 }
00606 }
00607 if (password != NULL) {
00608 StrAppend(&setup_command, " -p'");
00609 StrAppend(&setup_command, quoted_password);
00610 StrAppend(&setup_command, "'");
00611 }
00612 StrAppend(&setup_command, " ");
00613 StrAppend(&setup_command, dbschema);
00614 StrAppend(&setup_command, " < ");
00615 StrAppend(&setup_command, SQL_SETUP);
00616
00617 if (system(setup_command) != 0)
00618 {
00619 printf("Could not call db setup command:\n\t%s\n", setup_command);
00620 StrFree(host);
00621 StrFree(port);
00622 StrFree(dbschema);
00623 StrFree(user);
00624 StrFree(password);
00625 StrFree(setup_command);
00626 return(1);
00627 }
00628 StrFree(setup_command);
00629 }
00630
00631
00632 status = DbConnect(&dbhandle, dbschema, host, password, user, port);
00633 if (status != 0) {
00634 printf("Failed to connect to database\n");
00635 db_disconnect(lock_fd);
00636 StrFree(host);
00637 StrFree(port);
00638 StrFree(dbschema);
00639 StrFree(user);
00640 StrFree(password);
00641 return(1);
00642 }
00643
00644
00645 StrFree(host);
00646 StrFree(port);
00647 StrFree(dbschema);
00648 StrFree(user);
00649 StrFree(password);
00650
00651
00652
00653
00654
00655 status = read_filenames(&zone_list_filename, &kasp_filename);
00656 if (status != 0) {
00657 printf("Failed to read conf.xml\n");
00658 db_disconnect(lock_fd);
00659 return(1);
00660 }
00661
00662
00663
00664
00665
00666 status = update_repositories();
00667 if (status != 0) {
00668 printf("Failed to update repositories\n");
00669 db_disconnect(lock_fd);
00670 StrFree(zone_list_filename);
00671 return(1);
00672 }
00673
00674
00675
00676
00677
00678 status = update_policies(kasp_filename);
00679 if (status != 0) {
00680 printf("Failed to update policies\n");
00681 printf("SETUP FAILED\n");
00682 db_disconnect(lock_fd);
00683 StrFree(zone_list_filename);
00684 return(1);
00685 }
00686
00687 StrFree(kasp_filename);
00688
00689
00690
00691
00692
00693 status = update_zones(zone_list_filename);
00694 StrFree(zone_list_filename);
00695 if (status != 0) {
00696 printf("Failed to update zones\n");
00697 db_disconnect(lock_fd);
00698 return(1);
00699 }
00700
00701
00702 db_disconnect(lock_fd);
00703
00704 DbDisconnect(dbhandle);
00705
00706 return 0;
00707 }
00708
00709
00710
00711
00712
00713
00714
00715 int
00716 cmd_update (const char* qualifier)
00717 {
00718 DB_HANDLE dbhandle;
00719 FILE* lock_fd = NULL;
00720 char* zone_list_filename = NULL;
00721 char* kasp_filename = NULL;
00722 int status = 0;
00723 int done_something = 0;
00724
00725
00726 status = db_connect(&dbhandle, &lock_fd, 1);
00727 if (status != 0) {
00728 printf("Failed to connect to database\n");
00729 db_disconnect(lock_fd);
00730 return(1);
00731 }
00732
00733
00734
00735
00736
00737 if (strncmp(qualifier, "ZONELIST", 8) == 0 ||
00738 strncmp(qualifier, "KASP", 4) == 0 ||
00739 strncmp(qualifier, "ALL", 3) == 0) {
00740 status = read_filenames(&zone_list_filename, &kasp_filename);
00741 if (status != 0) {
00742 printf("Failed to read conf.xml\n");
00743 db_disconnect(lock_fd);
00744 return(1);
00745 }
00746 }
00747
00748
00749
00750
00751
00752 if (strncmp(qualifier, "CONF", 4) == 0 ||
00753 strncmp(qualifier, "ALL", 3) == 0) {
00754 status = update_repositories();
00755 if (status != 0) {
00756 printf("Failed to update repositories\n");
00757 db_disconnect(lock_fd);
00758 if (strncmp(qualifier, "ALL", 3) == 0) {
00759 StrFree(kasp_filename);
00760 StrFree(zone_list_filename);
00761 }
00762 return(1);
00763 }
00764 done_something = 1;
00765 }
00766
00767
00768
00769
00770
00771 if (strncmp(qualifier, "KASP", 4) == 0 ||
00772 strncmp(qualifier, "ALL", 3) == 0) {
00773 status = update_policies(kasp_filename);
00774 if (status != 0) {
00775 printf("Failed to update policies\n");
00776 db_disconnect(lock_fd);
00777 StrFree(kasp_filename);
00778 StrFree(zone_list_filename);
00779 return(1);
00780 }
00781 done_something = 1;
00782 }
00783
00784
00785
00786
00787
00788 if (strncmp(qualifier, "ZONELIST", 8) == 0 ||
00789 strncmp(qualifier, "ALL", 3) == 0) {
00790 status = update_zones(zone_list_filename);
00791 if (status != 0) {
00792 printf("Failed to update zones\n");
00793 db_disconnect(lock_fd);
00794 StrFree(kasp_filename);
00795 StrFree(zone_list_filename);
00796 return(1);
00797 }
00798 done_something = 1;
00799 }
00800
00801
00802
00803
00804 if (done_something == 0) {
00805 printf("Unrecognised command update %s. Please specify one of:\n", qualifier);
00806 usage_update();
00807 } else {
00808
00809 if (restart_enforcerd() != 0)
00810 {
00811 fprintf(stderr, "Could not HUP ods-enforcerd\n");
00812 }
00813 }
00814
00815
00816
00817 db_disconnect(lock_fd);
00818
00819 DbDisconnect(dbhandle);
00820
00821 if (kasp_filename != NULL) {
00822 StrFree(kasp_filename);
00823 }
00824 if (zone_list_filename != NULL) {
00825 StrFree(zone_list_filename);
00826 }
00827
00828 return 0;
00829 }
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 int
00840 cmd_addzone ()
00841 {
00842 DB_HANDLE dbhandle;
00843 FILE* lock_fd = NULL;
00844 char* zonelist_filename = NULL;
00845 char* backup_filename = NULL;
00846
00847 char* sig_conf_name = NULL;
00848 char* input_name = NULL;
00849 char* output_name = NULL;
00850 int policy_id = 0;
00851 int new_zone;
00852
00853 DB_RESULT result;
00854 KSM_PARAMETER data;
00855
00856 xmlDocPtr doc = NULL;
00857
00858 int status = 0;
00859
00860 char *path = getcwd(NULL, MAXPATHLEN);
00861 if (path == NULL) {
00862 printf("Couldn't malloc path: %s\n", strerror(errno));
00863 exit(1);
00864 }
00865
00866
00867 if (o_zone == NULL) {
00868 printf("Please specify a zone with the --zone option\n");
00869 usage_zone();
00870 return(1);
00871 }
00872
00873 if (o_policy == NULL) {
00874 o_policy = StrStrdup("default");
00875 }
00876
00877
00878
00879
00880 if (o_signerconf == NULL) {
00881 StrAppend(&sig_conf_name, OPENDNSSEC_STATE_DIR);
00882 StrAppend(&sig_conf_name, "/signconf/");
00883 StrAppend(&sig_conf_name, o_zone);
00884 StrAppend(&sig_conf_name, ".xml");
00885 }
00886 else if (*o_signerconf != '/') {
00887 StrAppend(&sig_conf_name, path);
00888 StrAppend(&sig_conf_name, "/");
00889 StrAppend(&sig_conf_name, o_signerconf);
00890 } else {
00891 StrAppend(&sig_conf_name, o_signerconf);
00892 }
00893
00894 if (o_input == NULL) {
00895 StrAppend(&input_name, OPENDNSSEC_STATE_DIR);
00896 StrAppend(&input_name, "/unsigned/");
00897 StrAppend(&input_name, o_zone);
00898 }
00899 else if (*o_input != '/') {
00900 StrAppend(&input_name, path);
00901 StrAppend(&input_name, "/");
00902 StrAppend(&input_name, o_input);
00903 } else {
00904 StrAppend(&input_name, o_input);
00905 }
00906
00907 if (o_output == NULL) {
00908 StrAppend(&output_name, OPENDNSSEC_STATE_DIR);
00909 StrAppend(&output_name, "/signed/");
00910 StrAppend(&output_name, o_zone);
00911 }
00912 else if (*o_output != '/') {
00913 StrAppend(&output_name, path);
00914 StrAppend(&output_name, "/");
00915 StrAppend(&output_name, o_output);
00916 } else {
00917 StrAppend(&output_name, o_output);
00918 }
00919
00920 free(path);
00921
00922
00923 status = read_zonelist_filename(&zonelist_filename);
00924 if (status != 0) {
00925 printf("couldn't read zonelist\n");
00926 StrFree(zonelist_filename);
00927 StrFree(sig_conf_name);
00928 StrFree(input_name);
00929 StrFree(output_name);
00930 return(1);
00931 }
00932
00933
00934
00935
00936
00937
00938 status = db_connect(&dbhandle, &lock_fd, 1);
00939 if (status != 0) {
00940 printf("Failed to connect to database\n");
00941 db_disconnect(lock_fd);
00942 StrFree(zonelist_filename);
00943 StrFree(sig_conf_name);
00944 StrFree(input_name);
00945 StrFree(output_name);
00946 return(1);
00947 }
00948
00949
00950 status = KsmPolicyIdFromName(o_policy, &policy_id);
00951 if (status != 0) {
00952 printf("Error, can't find policy : %s\n", o_policy);
00953 printf("Failed to update zones\n");
00954 db_disconnect(lock_fd);
00955 StrFree(zonelist_filename);
00956 StrFree(sig_conf_name);
00957 StrFree(input_name);
00958 StrFree(output_name);
00959 return(1);
00960 }
00961 status = KsmImportZone(o_zone, policy_id, 1, &new_zone, sig_conf_name, input_name, output_name);
00962 if (status != 0) {
00963 if (status == -2) {
00964 printf("Failed to Import zone %s; it already exists\n", o_zone);
00965 } else if (status == -3) {
00966 printf("Failed to Import zone %s; it already exists both with and without a trailing dot\n", o_zone);
00967 } else {
00968 printf("Failed to Import zone\n");
00969 }
00970 db_disconnect(lock_fd);
00971 StrFree(zonelist_filename);
00972 StrFree(sig_conf_name);
00973 StrFree(input_name);
00974 StrFree(output_name);
00975 return(1);
00976 }
00977
00978
00979
00980 status = KsmParameterInit(&result, "zones_share_keys", "keys", policy_id);
00981 if (status != 0) {
00982 printf("Can't retrieve shared-keys parameter for policy\n");
00983 db_disconnect(lock_fd);
00984 StrFree(zonelist_filename);
00985 StrFree(sig_conf_name);
00986 StrFree(input_name);
00987 StrFree(output_name);
00988 return(1);
00989 }
00990 status = KsmParameter(result, &data);
00991 if (status != 0) {
00992 printf("Can't retrieve shared-keys parameter for policy\n");
00993 db_disconnect(lock_fd);
00994 StrFree(zonelist_filename);
00995 StrFree(sig_conf_name);
00996 StrFree(input_name);
00997 StrFree(output_name);
00998 return(1);
00999 }
01000 KsmParameterEnd(result);
01001
01002
01003 if (data.value == 1) {
01004 status = LinkKeys(o_zone, policy_id);
01005 if (status != 0) {
01006 printf("Failed to Link Keys to zone\n");
01007
01008
01009 if (status != 2) {
01010 db_disconnect(lock_fd);
01011 StrFree(zonelist_filename);
01012 StrFree(sig_conf_name);
01013 StrFree(input_name);
01014 StrFree(output_name);
01015 return(1);
01016 }
01017 }
01018 }
01019
01020
01021 db_disconnect(lock_fd);
01022 DbDisconnect(dbhandle);
01023
01024 if (xml_flag == 1) {
01025
01026
01027 xmlKeepBlanksDefault(0);
01028 xmlTreeIndentString = "\t";
01029 doc = add_zone_node(zonelist_filename, o_zone, o_policy, sig_conf_name, input_name, output_name);
01030
01031 StrFree(sig_conf_name);
01032 StrFree(input_name);
01033 StrFree(output_name);
01034
01035 if (doc == NULL) {
01036 StrFree(zonelist_filename);
01037 return(1);
01038 }
01039
01040
01041 StrAppend(&backup_filename, zonelist_filename);
01042 StrAppend(&backup_filename, ".backup");
01043 status = backup_file(zonelist_filename, backup_filename);
01044 StrFree(backup_filename);
01045 if (status != 0) {
01046 StrFree(zonelist_filename);
01047 return(status);
01048 }
01049
01050
01051 status = xmlSaveFormatFile(zonelist_filename, doc, 1);
01052 StrFree(zonelist_filename);
01053 xmlFreeDoc(doc);
01054
01055 if (status == -1) {
01056 printf("couldn't save zonelist\n");
01057 return(1);
01058 }
01059 }
01060
01061
01062
01063
01064 if (xml_flag == 0) {
01065 printf("Imported zone: %s into database only, please run \"ods-ksmutil zonelist export\" to update zonelist.xml\n", o_zone);
01066 } else {
01067 printf("Imported zone: %s\n", o_zone);
01068 }
01069
01070
01071 return 0;
01072 }
01073
01074
01075
01076
01077 int
01078 cmd_delzone ()
01079 {
01080
01081 char* zonelist_filename = NULL;
01082 char* backup_filename = NULL;
01083
01084 int zone_id = -1;
01085 int policy_id = -1;
01086 int zone_count = -1;
01087
01088 DB_RESULT result;
01089 DB_RESULT result2;
01090 KSM_PARAMETER shared;
01091
01092 xmlDocPtr doc = NULL;
01093
01094 int status = 0;
01095 int user_certain;
01096
01097
01098 DB_HANDLE dbhandle;
01099 FILE* lock_fd = NULL;
01100
01101
01102 if (all_flag && o_zone != NULL) {
01103 printf("can not use --all with --zone\n");
01104 return(1);
01105 }
01106 else if (!all_flag && o_zone == NULL) {
01107 printf("please specify either --zone <zone> or --all\n");
01108 return(1);
01109 }
01110
01111
01112 if (all_flag == 1) {
01113 printf("*WARNING* This will remove all zones from OpenDNSSEC; are you sure? [y/N] ");
01114
01115 user_certain = getchar();
01116 if (user_certain != 'y' && user_certain != 'Y') {
01117 printf("Okay, quitting...\n");
01118 exit(0);
01119 }
01120 }
01121
01122
01123 status = db_connect(&dbhandle, &lock_fd, 1);
01124 if (status != 0) {
01125 printf("Failed to connect to database\n");
01126 db_disconnect(lock_fd);
01127 return(1);
01128 }
01129
01130
01131 if (td_flag == 1) {
01132 StrAppend(&o_zone, ".");
01133 }
01134
01135
01136
01137
01138 if (xml_flag == 1) {
01139
01140 status = read_zonelist_filename(&zonelist_filename);
01141 if (status != 0) {
01142 printf("couldn't read zonelist\n");
01143 db_disconnect(lock_fd);
01144 StrFree(zonelist_filename);
01145 return(1);
01146 }
01147
01148
01149
01150 doc = del_zone_node(zonelist_filename, o_zone);
01151 if (doc == NULL) {
01152 db_disconnect(lock_fd);
01153 StrFree(zonelist_filename);
01154 return(1);
01155 }
01156
01157
01158 StrAppend(&backup_filename, zonelist_filename);
01159 StrAppend(&backup_filename, ".backup");
01160 status = backup_file(zonelist_filename, backup_filename);
01161 StrFree(backup_filename);
01162 if (status != 0) {
01163 StrFree(zonelist_filename);
01164 db_disconnect(lock_fd);
01165 return(status);
01166 }
01167
01168
01169 status = xmlSaveFormatFile(zonelist_filename, doc, 1);
01170 xmlFreeDoc(doc);
01171 StrFree(zonelist_filename);
01172 if (status == -1) {
01173 printf("Could not save %s\n", zonelist_filename);
01174 db_disconnect(lock_fd);
01175 return(1);
01176 }
01177 }
01178
01179
01180
01181
01182
01183
01184 if (all_flag == 0) {
01185 status = KsmZoneIdAndPolicyFromName(o_zone, &policy_id, &zone_id);
01186 if (status != 0) {
01187 printf("Couldn't find zone %s\n", o_zone);
01188 db_disconnect(lock_fd);
01189 return(1);
01190 }
01191
01192
01193 status = KsmParameterInit(&result, "zones_share_keys", "keys", policy_id);
01194 if (status != 0) {
01195 db_disconnect(lock_fd);
01196 return(status);
01197 }
01198 status = KsmParameter(result, &shared);
01199 if (status != 0) {
01200 db_disconnect(lock_fd);
01201 return(status);
01202 }
01203 KsmParameterEnd(result);
01204
01205
01206 status = KsmZoneCountInit(&result2, policy_id);
01207 if (status == 0) {
01208 status = KsmZoneCount(result2, &zone_count);
01209 }
01210 DbFreeResult(result2);
01211 }
01212
01213
01214 if (all_flag == 1 || (shared.value == 1 && zone_count == 1) || shared.value == 0) {
01215 status = KsmMarkKeysAsDead(zone_id);
01216 if (status != 0) {
01217 printf("Error: failed to mark keys as dead in database\n");
01218 db_disconnect(lock_fd);
01219 return(status);
01220 }
01221 }
01222
01223
01224 status = KsmDeleteZone(zone_id);
01225
01226 if (status != 0) {
01227 printf("Error: failed to remove zone%s from database\n", (all_flag == 1) ? "s" : "");
01228 db_disconnect(lock_fd);
01229 return status;
01230 }
01231
01232
01233
01234 if (all_flag == 0) {
01235 if (system(SIGNER_CLI_UPDATE) != 0)
01236 {
01237 printf("Could not call signer engine\n");
01238 }
01239 }
01240
01241
01242 db_disconnect(lock_fd);
01243
01244 if (xml_flag == 0) {
01245 printf("Deleted zone: %s from database only, please run \"ods-ksmutil zonelist export\" to update zonelist.xml\n", o_zone);
01246 }
01247
01248 return 0;
01249 }
01250
01251
01252
01253
01254 int
01255 cmd_listzone ()
01256 {
01257
01258 DB_HANDLE dbhandle;
01259 FILE* lock_fd = NULL;
01260
01261 char* zonelist_filename = NULL;
01262 int* zone_ids;
01263
01264 xmlTextReaderPtr reader = NULL;
01265 int ret = 0;
01266 char* tag_name = NULL;
01267
01268 int file_zone_count = 0;
01269 int j = 0;
01270 char buffer[256];
01271 char* sql = NULL;
01272 DB_RESULT result;
01273 DB_ROW row = NULL;
01274 char* temp_name = NULL;
01275
01276 int status = 0;
01277
01278
01279 status = read_zonelist_filename(&zonelist_filename);
01280 if (status != 0) {
01281 printf("couldn't read zonelist\n");
01282 if (zonelist_filename != NULL) {
01283 StrFree(zonelist_filename);
01284 }
01285 return(1);
01286 }
01287
01288
01289 status = db_connect(&dbhandle, &lock_fd, 1);
01290 if (status != 0) {
01291 printf("Failed to connect to database\n");
01292 db_disconnect(lock_fd);
01293 return(1);
01294 }
01295
01296
01297 reader = xmlNewTextReaderFilename(zonelist_filename);
01298 if (reader != NULL) {
01299 ret = xmlTextReaderRead(reader);
01300 while (ret == 1) {
01301 tag_name = (char*) xmlTextReaderLocalName(reader);
01302
01303 if (strncmp(tag_name, "Zone", 4) == 0
01304 && strncmp(tag_name, "ZoneList", 8) != 0
01305 && xmlTextReaderNodeType(reader) == 1) {
01306 file_zone_count++;
01307 }
01308
01309 ret = xmlTextReaderRead(reader);
01310 StrFree(tag_name);
01311 }
01312 xmlFreeTextReader(reader);
01313 if (ret != 0) {
01314 printf("%s : failed to parse\n", zonelist_filename);
01315 }
01316 } else {
01317 printf("Unable to open %s\n", zonelist_filename);
01318 }
01319
01320
01321 zone_ids = MemMalloc(file_zone_count * sizeof(int));
01322
01323
01324 list_zone_node(zonelist_filename, zone_ids);
01325
01326
01327 if (file_zone_count != 0) {
01328 StrAppend(&sql, "select name from zones where id not in (");
01329 for (j = 0; j < file_zone_count; ++j) {
01330 if (j != 0) {
01331 StrAppend(&sql, ",");
01332 }
01333 snprintf(buffer, sizeof(buffer), "%d", zone_ids[j]);
01334 StrAppend(&sql, buffer);
01335 }
01336 StrAppend(&sql, ")");
01337 } else {
01338 StrAppend(&sql, "select name from zones");
01339 }
01340
01341 status = DbExecuteSql(DbHandle(), sql, &result);
01342 if (status == 0) {
01343 status = DbFetchRow(result, &row);
01344 while (status == 0) {
01345
01346 DbString(row, 0, &temp_name);
01347
01348 printf("Found zone %s in DB but not zonelist.\n", temp_name);
01349 status = DbFetchRow(result, &row);
01350 file_zone_count++;
01351 }
01352
01353
01354
01355 if (status == -1) {
01356 status = 0;
01357 }
01358
01359 DbFreeResult(result);
01360 }
01361
01362 db_disconnect(lock_fd);
01363 DbDisconnect(dbhandle);
01364
01365 if (file_zone_count == 0) {
01366 printf("No zones in DB or zonelist.\n");
01367 }
01368
01369 MemFree(zone_ids);
01370 StrFree(sql);
01371 StrFree(zonelist_filename);
01372 StrFree(temp_name);
01373
01374 return 0;
01375 }
01376
01377
01378
01379
01380
01381 int
01382 cmd_exportkeys ()
01383 {
01384 int status = 0;
01385
01386 DB_HANDLE dbhandle;
01387
01388 int zone_id = -1;
01389 int state_id = -1;
01390 int keytype_id = KSM_TYPE_KSK;
01391
01392 char *case_keytype = NULL;
01393 char *case_keystate = NULL;
01394 char *zone_name = NULL;
01395
01396
01397 hsm_key_t *key = NULL;
01398 ldns_rr *dnskey_rr = NULL;
01399 ldns_rr *ds_sha1_rr = NULL;
01400 ldns_rr *ds_sha256_rr = NULL;
01401 hsm_sign_params_t *sign_params = NULL;
01402
01403 char* sql = NULL;
01404 KSM_KEYDATA data;
01405 DB_RESULT result;
01406 size_t nchar;
01407 char buffer[256];
01408
01409
01410
01411 if (o_keystate != NULL) {
01412 case_keystate = StrStrdup(o_keystate);
01413 (void) StrToUpper(case_keystate);
01414 if (strncmp(case_keystate, "KEYPUBLISH", 10) == 0 || strncmp(o_keystate, "10", 2) == 0) {
01415 state_id = KSM_STATE_KEYPUBLISH;
01416 }
01417 else if (strncmp(case_keystate, "GENERATE", 8) == 0 || strncmp(o_keystate, "1", 1) == 0) {
01418 state_id = KSM_STATE_GENERATE;
01419 }
01420 else if (strncmp(case_keystate, "PUBLISH", 7) == 0 || strncmp(o_keystate, "2", 1) == 0) {
01421 state_id = KSM_STATE_PUBLISH;
01422 }
01423 else if (strncmp(case_keystate, "READY", 5) == 0 || strncmp(o_keystate, "3", 1) == 0) {
01424 state_id = KSM_STATE_READY;
01425 }
01426 else if (strncmp(case_keystate, "ACTIVE", 6) == 0 || strncmp(o_keystate, "4", 1) == 0) {
01427 state_id = KSM_STATE_ACTIVE;
01428 }
01429 else if (strncmp(case_keystate, "RETIRE", 6) == 0 || strncmp(o_keystate, "5", 1) == 0) {
01430 state_id = KSM_STATE_RETIRE;
01431 }
01432 else if (strncmp(case_keystate, "DEAD", 4) == 0 || strncmp(o_keystate, "6", 1) == 0) {
01433 state_id = KSM_STATE_DEAD;
01434 }
01435 else if (strncmp(case_keystate, "DSSUB", 5) == 0 || strncmp(o_keystate, "7", 1) == 0) {
01436 state_id = KSM_STATE_DSSUB;
01437 }
01438 else if (strncmp(case_keystate, "DSPUBLISH", 9) == 0 || strncmp(o_keystate, "8", 1) == 0) {
01439 state_id = KSM_STATE_DSPUBLISH;
01440 }
01441 else if (strncmp(case_keystate, "DSREADY", 7) == 0 || strncmp(o_keystate, "9", 1) == 0) {
01442 state_id = KSM_STATE_DSREADY;
01443 }
01444 else {
01445 printf("Error: Unrecognised state %s; should be one of GENERATE, PUBLISH, READY, ACTIVE, RETIRE, DEAD, DSSUB, DSPUBLISH, DSREADY or KEYPUBLISH\n", o_keystate);
01446
01447 StrFree(case_keystate);
01448 return(1);
01449 }
01450 StrFree(case_keystate);
01451 }
01452
01453
01454 if (o_keytype != NULL) {
01455 case_keytype = StrStrdup(o_keytype);
01456 (void) StrToUpper(case_keytype);
01457 if (strncmp(case_keytype, "KSK", 3) == 0 || strncmp(o_keytype, "257", 3) == 0) {
01458 keytype_id = KSM_TYPE_KSK;
01459 }
01460 else if (strncmp(case_keytype, "ZSK", 3) == 0 || strncmp(o_keytype, "256", 3) == 0) {
01461 keytype_id = KSM_TYPE_ZSK;
01462 }
01463 else {
01464 printf("Error: Unrecognised keytype %s; should be one of KSK or ZSK\n", o_keytype);
01465
01466 StrFree(case_keytype);
01467 return(1);
01468 }
01469 StrFree(case_keytype);
01470 }
01471
01472
01473 status = db_connect(&dbhandle, NULL, 0);
01474 if (status != 0) {
01475 printf("Failed to connect to database\n");
01476 return(1);
01477 }
01478
01479
01480 if (o_zone != NULL) {
01481 status = KsmZoneIdFromName(o_zone, &zone_id);
01482 if (status != 0) {
01483
01484 StrAppend(&o_zone, ".");
01485 status = KsmZoneIdFromName(o_zone, &zone_id);
01486 if (status != 0) {
01487 printf("Error: unable to find a zone named \"%s\" in database\n", o_zone);
01488 return(status);
01489 }
01490 }
01491 }
01492
01493 status = hsm_open(config, hsm_prompt_pin, NULL);
01494 if (status) {
01495 hsm_print_error(NULL);
01496 exit(-1);
01497 }
01498
01499 sql = DqsSpecifyInit("KEYDATA_VIEW", DB_KEYDATA_FIELDS);
01500 if (state_id != -1) {
01501 DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, state_id, 0);
01502 } else {
01503 nchar = snprintf(buffer, sizeof(buffer), "(%d, %d, %d, %d, %d, %d)",
01504 KSM_STATE_READY, KSM_STATE_ACTIVE, KSM_STATE_DSSUB,
01505 KSM_STATE_DSPUBLISH, KSM_STATE_DSREADY, KSM_STATE_KEYPUBLISH);
01506 if (nchar >= sizeof(buffer)) {
01507 status = -1;
01508 return status;
01509 }
01510 DqsConditionKeyword(&sql, "STATE", DQS_COMPARE_IN, buffer, 0);
01511
01512 }
01513 DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype_id, 1);
01514 if (zone_id != -1) {
01515 DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, 2);
01516 }
01517 DqsOrderBy(&sql, "STATE");
01518 DqsEnd(&sql);
01519
01520 status = KsmKeyInitSql(&result, sql);
01521 if (status == 0) {
01522 status = KsmKey(result, &data);
01523 while (status == 0) {
01524
01525
01526 key = hsm_find_key_by_id(NULL, data.location);
01527
01528 if (!key) {
01529 printf("Key %s in DB but not repository\n", data.location);
01530 return -1;
01531 }
01532
01533 sign_params = hsm_sign_params_new();
01534
01535 if (zone_id == -1) {
01536 status = KsmZoneNameFromId(data.zone_id, &zone_name);
01537 if (status != 0) {
01538 printf("Error: unable to find zone name for id %d\n", zone_id);
01539 hsm_sign_params_free(sign_params);
01540 return(status);
01541 }
01542 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone_name);
01543 StrFree(zone_name);
01544 }
01545 else {
01546 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, o_zone);
01547 }
01548
01549 sign_params->algorithm = data.algorithm;
01550 sign_params->flags = LDNS_KEY_ZONE_KEY;
01551 if (keytype_id == KSM_TYPE_KSK) {
01552 sign_params->flags += LDNS_KEY_SEP_KEY;
01553 }
01554 dnskey_rr = hsm_get_dnskey(NULL, key, sign_params);
01555 sign_params->keytag = ldns_calc_keytag(dnskey_rr);
01556
01557 if (ds_flag == 0) {
01558 printf("\n;%s %s DNSKEY record:\n", KsmKeywordStateValueToName(data.state), (keytype_id == KSM_TYPE_KSK ? "KSK" : "ZSK"));
01559 ldns_rr_print(stdout, dnskey_rr);
01560 }
01561 else {
01562
01563 printf("\n;%s %s DS record (SHA1):\n", KsmKeywordStateValueToName(data.state), (keytype_id == KSM_TYPE_KSK ? "KSK" : "ZSK"));
01564 ds_sha1_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA1);
01565 ldns_rr_print(stdout, ds_sha1_rr);
01566
01567 printf("\n;%s %s DS record (SHA256):\n", KsmKeywordStateValueToName(data.state), (keytype_id == KSM_TYPE_KSK ? "KSK" : "ZSK"));
01568 ds_sha256_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA256);
01569 ldns_rr_print(stdout, ds_sha256_rr);
01570 }
01571
01572 hsm_sign_params_free(sign_params);
01573 hsm_key_free(key);
01574 status = KsmKey(result, &data);
01575
01576 }
01577
01578 if (status == -1) {
01579 status = 0;
01580 }
01581
01582 KsmKeyEnd(result);
01583 }
01584
01585
01586
01587 if (dnskey_rr != NULL) {
01588 ldns_rr_free(dnskey_rr);
01589 }
01590 if (ds_sha1_rr != NULL) {
01591 ldns_rr_free(ds_sha1_rr);
01592 }
01593 if (ds_sha256_rr != NULL) {
01594 ldns_rr_free(ds_sha256_rr);
01595 }
01596
01597 DbDisconnect(dbhandle);
01598
01599 return 0;
01600 }
01601
01602
01603
01604
01605
01606 int
01607 cmd_exportpolicy ()
01608 {
01609 int status = 0;
01610
01611 DB_HANDLE dbhandle;
01612
01613 xmlDocPtr doc = xmlNewDoc((const xmlChar *)"1.0");
01614 xmlNodePtr root;
01615 KSM_POLICY *policy;
01616
01617 DB_RESULT result;
01618
01619
01620 if (all_flag && o_policy != NULL) {
01621 printf("can not use --all with --policy\n");
01622 return(1);
01623 }
01624 else if (!all_flag && o_policy == NULL) {
01625 printf("please specify either --policy <policy> or --all\n");
01626 return(1);
01627 }
01628
01629
01630 status = db_connect(&dbhandle, NULL, 0);
01631 if (status != 0) {
01632 printf("Failed to connect to database\n");
01633 return(1);
01634 }
01635
01636
01637 policy = (KSM_POLICY *)malloc(sizeof(KSM_POLICY));
01638 policy->signer = (KSM_SIGNER_POLICY *)malloc(sizeof(KSM_SIGNER_POLICY));
01639 policy->signature = (KSM_SIGNATURE_POLICY *)malloc(sizeof(KSM_SIGNATURE_POLICY));
01640 policy->zone = (KSM_ZONE_POLICY *)malloc(sizeof(KSM_ZONE_POLICY));
01641 policy->parent = (KSM_PARENT_POLICY *)malloc(sizeof(KSM_PARENT_POLICY));
01642 policy->keys = (KSM_COMMON_KEY_POLICY *)malloc(sizeof(KSM_COMMON_KEY_POLICY));
01643 policy->ksk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
01644 policy->zsk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
01645 policy->denial = (KSM_DENIAL_POLICY *)malloc(sizeof(KSM_DENIAL_POLICY));
01646 policy->enforcer = (KSM_ENFORCER_POLICY *)malloc(sizeof(KSM_ENFORCER_POLICY));
01647
01648 policy->audit = (char *)calloc(KSM_POLICY_AUDIT_LENGTH, sizeof(char));
01649 policy->description = (char *)calloc(KSM_POLICY_DESC_LENGTH, sizeof(char));
01650 if (policy->signer == NULL || policy->signature == NULL ||
01651 policy->zone == NULL || policy->parent == NULL ||
01652 policy->keys == NULL ||
01653 policy->ksk == NULL || policy->zsk == NULL ||
01654 policy->denial == NULL || policy->enforcer == NULL) {
01655 fprintf(stderr, "Malloc for policy struct failed\n");
01656 exit(1);
01657 }
01658
01659
01660 xmlKeepBlanksDefault(0);
01661 xmlTreeIndentString = " ";
01662 root = xmlNewDocNode(doc, NULL, (const xmlChar *)"KASP", NULL);
01663 (void) xmlDocSetRootElement(doc, root);
01664
01665
01666 status = KsmPolicyInit(&result, o_policy);
01667 if (status == 0) {
01668
01669 status = KsmPolicy(result, policy);
01670 KsmPolicyRead(policy);
01671
01672 while (status == 0) {
01673 append_policy(doc, policy);
01674
01675
01676 status = KsmPolicy(result, policy);
01677 KsmPolicyRead(policy);
01678
01679 }
01680 }
01681
01682 xmlSaveFormatFile("-", doc, 1);
01683
01684 xmlFreeDoc(doc);
01685 KsmPolicyFree(policy);
01686
01687 DbDisconnect(dbhandle);
01688
01689 return 0;
01690 }
01691
01692
01693
01694
01695
01696 int
01697 cmd_exportzonelist ()
01698 {
01699 int status = 0;
01700
01701 DB_HANDLE dbhandle;
01702
01703 xmlDocPtr doc = xmlNewDoc((const xmlChar *)"1.0");
01704 xmlNodePtr root;
01705 KSM_ZONE *zone;
01706 int prev_policy_id = -1;
01707
01708 DB_RESULT result;
01709
01710
01711 status = db_connect(&dbhandle, NULL, 0);
01712 if (status != 0) {
01713 printf("Failed to connect to database\n");
01714 return(1);
01715 }
01716
01717
01718 zone = (KSM_ZONE *)malloc(sizeof(KSM_ZONE));
01719 if (zone == NULL) {
01720 fprintf(stderr, "Malloc for zone struct failed\n");
01721 exit(1);
01722 }
01723
01724
01725 xmlKeepBlanksDefault(0);
01726 xmlTreeIndentString = " ";
01727 root = xmlNewDocNode(doc, NULL, (const xmlChar *)"ZoneList", NULL);
01728 (void) xmlDocSetRootElement(doc, root);
01729
01730
01731 status = KsmZoneInit(&result, -1);
01732 if (status == 0) {
01733
01734 status = KsmZone(result, zone);
01735
01736 while (status == 0) {
01737 if (zone->policy_id != prev_policy_id) {
01738 prev_policy_id = zone->policy_id;
01739 status = get_policy_name_from_id(zone);
01740 if (status != 0) {
01741 fprintf(stderr, "Couldn't get name for policy with ID: %d, exiting...\n", zone->policy_id);
01742 return(1);
01743 }
01744 }
01745 append_zone(doc, zone);
01746
01747
01748 status = KsmZone(result, zone);
01749
01750 }
01751 }
01752
01753 xmlSaveFormatFile("-", doc, 1);
01754
01755 xmlFreeDoc(doc);
01756
01757
01758 DbDisconnect(dbhandle);
01759
01760 return 0;
01761 }
01762
01763
01764
01765
01766 int
01767 cmd_rollzone ()
01768 {
01769
01770 DB_HANDLE dbhandle;
01771 FILE* lock_fd = NULL;
01772 DB_RESULT result;
01773 KSM_PARAMETER data;
01774
01775 int key_type = -1;
01776 int zone_id = -1;
01777 int policy_id = -1;
01778
01779 int status = 0;
01780 int user_certain;
01781
01782
01783 if (o_keytype != NULL) {
01784 StrToLower(o_keytype);
01785 key_type = KsmKeywordTypeNameToValue(o_keytype);
01786 }
01787
01788
01789 status = db_connect(&dbhandle, &lock_fd, 1);
01790 if (status != 0) {
01791 printf("Failed to connect to database\n");
01792 db_disconnect(lock_fd);
01793 return(1);
01794 }
01795
01796 status = KsmZoneIdAndPolicyFromName(o_zone, &policy_id, &zone_id);
01797 if (status != 0) {
01798
01799 StrAppend(&o_zone, ".");
01800 status = KsmZoneIdAndPolicyFromName(o_zone, &policy_id, &zone_id);
01801 if (status != 0) {
01802 db_disconnect(lock_fd);
01803 return(status);
01804 }
01805 }
01806
01807
01808 status = KsmParameterInit(&result, "zones_share_keys", "keys", policy_id);
01809 if (status != 0) {
01810 db_disconnect(lock_fd);
01811 return(status);
01812 }
01813 status = KsmParameter(result, &data);
01814 if (status != 0) {
01815 db_disconnect(lock_fd);
01816 return(status);
01817 }
01818 KsmParameterEnd(result);
01819
01820
01821 if (data.value == 1) {
01822 printf("*WARNING* This zone shares keys with others, all instances of the active key on this zone will be retired; are you sure? [y/N] ");
01823
01824 user_certain = getchar();
01825 if (user_certain != 'y' && user_certain != 'Y') {
01826 printf("Okay, quitting...\n");
01827 db_disconnect(lock_fd);
01828 exit(0);
01829 }
01830 }
01831
01832 status = keyRoll(zone_id, -1, key_type);
01833 if (status != 0) {
01834 db_disconnect(lock_fd);
01835 return(status);
01836 }
01837
01838
01839 db_disconnect(lock_fd);
01840
01841
01842 if (restart_enforcerd() != 0)
01843 {
01844 fprintf(stderr, "Could not HUP ods-enforcerd\n");
01845 }
01846
01847 DbDisconnect(dbhandle);
01848
01849 return 0;
01850 }
01851
01852
01853
01854
01855 int
01856 cmd_rollpolicy ()
01857 {
01858
01859 DB_HANDLE dbhandle;
01860 FILE* lock_fd = NULL;
01861
01862 DB_RESULT result;
01863
01864 int zone_count = -1;
01865
01866 int key_type = 0;
01867 int policy_id = 0;
01868
01869 int status = 0;
01870 int user_certain;
01871
01872
01873 if (o_keytype != NULL) {
01874 StrToLower(o_keytype);
01875 key_type = KsmKeywordTypeNameToValue(o_keytype);
01876 }
01877
01878
01879 status = db_connect(&dbhandle, &lock_fd, 1);
01880 if (status != 0) {
01881 printf("Failed to connect to database\n");
01882 db_disconnect(lock_fd);
01883 return(1);
01884 }
01885
01886 status = KsmPolicyIdFromName(o_policy, &policy_id);
01887 if (status != 0) {
01888 printf("Error, can't find policy : %s\n", o_policy);
01889 db_disconnect(lock_fd);
01890 return(status);
01891 }
01892
01893
01894 printf("*WARNING* This will roll all keys on the policy; are you sure? [y/N] ");
01895
01896 user_certain = getchar();
01897 if (user_certain != 'y' && user_certain != 'Y') {
01898 printf("Okay, quitting...\n");
01899 db_disconnect(lock_fd);
01900 exit(0);
01901 }
01902
01903
01904
01905 status = KsmZoneCountInit(&result, policy_id);
01906 if (status == 0) {
01907 status = KsmZoneCount(result, &zone_count);
01908 }
01909 DbFreeResult(result);
01910
01911 if (status == 0) {
01912
01913 if (zone_count == 0) {
01914 printf("No zones on policy; nothing to roll\n");
01915 db_disconnect(lock_fd);
01916 return status;
01917 }
01918 } else {
01919 printf("Couldn't count zones on policy; quitting...\n");
01920 db_disconnect(lock_fd);
01921 exit(1);
01922 }
01923
01924 status = keyRoll(-1, policy_id, key_type);
01925
01926
01927 db_disconnect(lock_fd);
01928
01929
01930 if (restart_enforcerd() != 0)
01931 {
01932 fprintf(stderr, "Could not HUP ods-enforcerd\n");
01933 }
01934
01935 DbDisconnect(dbhandle);
01936
01937 return 0;
01938 }
01939
01940
01941
01942
01943 int
01944 cmd_keypurge ()
01945 {
01946 int status = 0;
01947
01948 int policy_id = -1;
01949 int zone_id = -1;
01950
01951
01952 DB_HANDLE dbhandle;
01953 FILE* lock_fd = NULL;
01954
01955
01956 status = db_connect(&dbhandle, &lock_fd, 1);
01957 if (status != 0) {
01958 printf("Failed to connect to database\n");
01959 db_disconnect(lock_fd);
01960 return(1);
01961 }
01962
01963
01964 if (o_policy != NULL) {
01965 status = KsmPolicyIdFromName(o_policy, &policy_id);
01966 if (status != 0) {
01967 printf("Error: unable to find a policy named \"%s\" in database\n", o_policy);
01968 db_disconnect(lock_fd);
01969 return status;
01970 }
01971 }
01972
01973
01974 if (o_zone != NULL) {
01975 status = KsmZoneIdFromName(o_zone, &zone_id);
01976 if (status != 0) {
01977
01978 StrAppend(&o_zone, ".");
01979 status = KsmZoneIdFromName(o_zone, &zone_id);
01980 if (status != 0) {
01981 printf("Error: unable to find a zone named \"%s\" in database\n", o_zone);
01982 db_disconnect(lock_fd);
01983 return(status);
01984 }
01985 }
01986 }
01987
01988 status = PurgeKeys(zone_id, policy_id);
01989
01990 if (status != 0) {
01991 printf("Error: failed to purge dead keys\n");
01992 db_disconnect(lock_fd);
01993 return status;
01994 }
01995
01996
01997 db_disconnect(lock_fd);
01998
01999 DbDisconnect(dbhandle);
02000 return 0;
02001 }
02002
02003
02004
02005
02006 int
02007 cmd_backup (const char* qualifier)
02008 {
02009 int status = 0;
02010
02011 int repo_id = -1;
02012
02013
02014 DB_HANDLE dbhandle;
02015 FILE* lock_fd = NULL;
02016
02017 char* datetime = DtParseDateTimeString("now");
02018
02019
02020 if (datetime == NULL) {
02021 printf("Couldn't turn \"now\" into a date, quitting...\n");
02022 exit(1);
02023 }
02024
02025
02026 status = db_connect(&dbhandle, &lock_fd, 1);
02027 if (status != 0) {
02028 printf("Failed to connect to database\n");
02029 db_disconnect(lock_fd);
02030 StrFree(datetime);
02031 return(1);
02032 }
02033
02034
02035 if (o_repository != NULL) {
02036 status = KsmSmIdFromName(o_repository, &repo_id);
02037 if (status != 0) {
02038 printf("Error: unable to find a repository named \"%s\" in database\n", o_repository);
02039 db_disconnect(lock_fd);
02040 StrFree(datetime);
02041 return status;
02042 }
02043 }
02044
02045
02046 if (strncmp(qualifier, "PREPARE", 7) == 0 ||
02047 strncmp(qualifier, "DONE", 4) == 0 ) {
02048 status = KsmMarkPreBackup(repo_id, datetime);
02049 if (status == -1) {
02050 printf("There were no keys to mark\n");
02051 }
02052 else if (status != 0) {
02053 printf("Error: failed to mark pre_backup as done\n");
02054 db_disconnect(lock_fd);
02055 StrFree(datetime);
02056 return status;
02057 } else {
02058 if (strncmp(qualifier, "PREPARE", 7) == 0) {
02059 if (o_repository != NULL) {
02060 printf("Marked repository %s as pre-backed up at %s\n", o_repository, datetime);
02061 } else {
02062 printf("Marked all repositories as pre-backed up at %s\n", datetime);
02063 }
02064 }
02065 }
02066 }
02067
02068
02069 if (strncmp(qualifier, "COMMIT", 6) == 0 ||
02070 strncmp(qualifier, "DONE", 4) == 0 ) {
02071 status = KsmMarkBackup(repo_id, datetime);
02072 if (status == -1) {
02073 printf("There were no keys to mark\n");
02074 }
02075 else if (status != 0) {
02076 printf("Error: failed to mark backup as done\n");
02077 db_disconnect(lock_fd);
02078 StrFree(datetime);
02079 return status;
02080 } else {
02081 if (o_repository != NULL) {
02082 printf("Marked repository %s as backed up at %s\n", o_repository, datetime);
02083 } else {
02084 printf("Marked all repositories as backed up at %s\n", datetime);
02085 }
02086 }
02087 }
02088
02089
02090 if (strncmp(qualifier, "ROLLBACK", 6) == 0 ) {
02091 status = KsmRollbackMarkPreBackup(repo_id);
02092 if (status == -1) {
02093 printf("There were no keys to rollback\n");
02094 }
02095 else if (status != 0) {
02096 printf("Error: failed to mark backup as done\n");
02097 db_disconnect(lock_fd);
02098 StrFree(datetime);
02099 return status;
02100 } else {
02101 if (o_repository != NULL) {
02102 printf("Rolled back pre-backup of repository %s\n", o_repository);
02103 } else {
02104 printf("Rolled back pre-backup of all repositories\n");
02105 }
02106 }
02107 }
02108
02109 StrFree(datetime);
02110
02111 db_disconnect(lock_fd);
02112
02113 DbDisconnect(dbhandle);
02114 return 0;
02115 }
02116
02117
02118
02119
02120 int
02121 cmd_listrolls ()
02122 {
02123 int status = 0;
02124
02125 int qualifier_id = -1;
02126
02127
02128 DB_HANDLE dbhandle;
02129 FILE* lock_fd = NULL;
02130
02131
02132 status = db_connect(&dbhandle, &lock_fd, 1);
02133 if (status != 0) {
02134 printf("Failed to connect to database\n");
02135 db_disconnect(lock_fd);
02136 return(1);
02137 }
02138
02139
02140 if (o_zone != NULL) {
02141 status = KsmZoneIdFromName(o_zone, &qualifier_id);
02142 if (status != 0) {
02143
02144 StrAppend(&o_zone, ".");
02145 status = KsmZoneIdFromName(o_zone, &qualifier_id);
02146 if (status != 0) {
02147 printf("Error: unable to find a zone named \"%s\" in database\n", o_zone);
02148 db_disconnect(lock_fd);
02149 return(status);
02150 }
02151 }
02152 }
02153
02154 printf("Rollovers:\n");
02155
02156 status = KsmListRollovers(qualifier_id);
02157
02158 if (status != 0) {
02159 printf("Error: failed to list rollovers\n");
02160 db_disconnect(lock_fd);
02161 return status;
02162 }
02163
02164 printf("\n");
02165
02166
02167 db_disconnect(lock_fd);
02168
02169 DbDisconnect(dbhandle);
02170 return 0;
02171 }
02172
02173
02174
02175
02176 int
02177 cmd_listbackups ()
02178 {
02179 int status = 0;
02180
02181 int qualifier_id = -1;
02182
02183
02184 DB_HANDLE dbhandle;
02185 FILE* lock_fd = NULL;
02186
02187
02188 status = db_connect(&dbhandle, &lock_fd, 0);
02189 if (status != 0) {
02190 printf("Failed to connect to database\n");
02191 db_disconnect(lock_fd);
02192 return(1);
02193 }
02194
02195
02196 if (o_repository != NULL) {
02197 status = KsmSmIdFromName(o_repository, &qualifier_id);
02198 if (status != 0) {
02199 printf("Error: unable to find a repository named \"%s\" in database\n", o_repository);
02200 db_disconnect(lock_fd);
02201 return status;
02202 }
02203 }
02204
02205 printf("Backups:\n");
02206 status = KsmListBackups(qualifier_id, verbose_flag);
02207
02208 if (status != 0) {
02209 printf("Error: failed to list backups\n");
02210 db_disconnect(lock_fd);
02211 return status;
02212 }
02213 printf("\n");
02214
02215
02216 db_disconnect(lock_fd);
02217
02218 DbDisconnect(dbhandle);
02219 return 0;
02220 }
02221
02222
02223
02224
02225 int
02226 cmd_listrepo ()
02227 {
02228 int status = 0;
02229
02230
02231 DB_HANDLE dbhandle;
02232 FILE* lock_fd = NULL;
02233
02234
02235 status = db_connect(&dbhandle, &lock_fd, 0);
02236 if (status != 0) {
02237 printf("Failed to connect to database\n");
02238 db_disconnect(lock_fd);
02239 return(1);
02240 }
02241
02242 printf("Repositories:\n");
02243
02244 status = KsmListRepos();
02245
02246 if (status != 0) {
02247 printf("Error: failed to list repositories\n");
02248 if (lock_fd != NULL) {
02249 fclose(lock_fd);
02250 }
02251 return status;
02252 }
02253
02254 printf("\n");
02255
02256
02257 db_disconnect(lock_fd);
02258
02259 DbDisconnect(dbhandle);
02260 return 0;
02261 }
02262
02263
02264
02265
02266 int
02267 cmd_listpolicy ()
02268 {
02269 int status = 0;
02270
02271
02272 DB_HANDLE dbhandle;
02273 FILE* lock_fd = NULL;
02274
02275
02276 status = db_connect(&dbhandle, &lock_fd, 0);
02277 if (status != 0) {
02278 printf("Failed to connect to database\n");
02279 db_disconnect(lock_fd);
02280 return(1);
02281 }
02282
02283 printf("Policies:\n");
02284
02285 status = KsmListPolicies();
02286
02287 if (status != 0) {
02288 printf("Error: failed to list policies\n");
02289 db_disconnect(lock_fd);
02290 return status;
02291 }
02292
02293 printf("\n");
02294
02295
02296 db_disconnect(lock_fd);
02297
02298 DbDisconnect(dbhandle);
02299 return 0;
02300 }
02301
02302
02303
02304
02305 int
02306 cmd_listkeys ()
02307 {
02308 int status = 0;
02309 int qualifier_id = -1;
02310
02311
02312 DB_HANDLE dbhandle;
02313 FILE* lock_fd = NULL;
02314
02315
02316 status = db_connect(&dbhandle, &lock_fd, 0);
02317 if (status != 0) {
02318 printf("Failed to connect to database\n");
02319 db_disconnect(lock_fd);
02320 return(1);
02321 }
02322
02323
02324 if (o_zone != NULL) {
02325 status = KsmZoneIdFromName(o_zone, &qualifier_id);
02326 if (status != 0) {
02327
02328 StrAppend(&o_zone, ".");
02329 status = KsmZoneIdFromName(o_zone, &qualifier_id);
02330 if (status != 0) {
02331 printf("Error: unable to find a zone named \"%s\" in database\n", o_zone);
02332 db_disconnect(lock_fd);
02333 return(status);
02334 }
02335 }
02336 }
02337
02338 printf("Keys:\n");
02339
02340 status = ListKeys(qualifier_id);
02341
02342 if (status != 0) {
02343 printf("Error: failed to list keys\n");
02344 db_disconnect(lock_fd);
02345 return status;
02346 }
02347
02348 printf("\n");
02349
02350
02351 db_disconnect(lock_fd);
02352
02353 DbDisconnect(dbhandle);
02354 return 0;
02355 }
02356
02357
02358
02359
02360
02361
02362
02363 int
02364 cmd_kskretire()
02365 {
02366 int status = 0;
02367 int zone_id = -1;
02368 int policy_id = -1;
02369 int key_count = -1;
02370 int keytag_int = -1;
02371 int temp_key_state = -1;
02372 int temp_keypair_id = -1;
02373 char* temp_cka_id = NULL;
02374 int user_certain;
02375
02376
02377 DB_HANDLE dbhandle;
02378 FILE* lock_fd = NULL;
02379
02380 char* datetime = DtParseDateTimeString("now");
02381
02382
02383 if (datetime == NULL) {
02384 printf("Couldn't turn \"now\" into a date, quitting...\n");
02385 StrFree(datetime);
02386 exit(1);
02387 }
02388
02389
02390 printf("*WARNING* This will retire the currently active KSK; are you sure? [y/N] ");
02391
02392 user_certain = getchar();
02393 if (user_certain != 'y' && user_certain != 'Y') {
02394 printf("Okay, quitting...\n");
02395 exit(0);
02396 }
02397
02398
02399 status = db_connect(&dbhandle, &lock_fd, 1);
02400 if (status != 0) {
02401 printf("Failed to connect to database\n");
02402 db_disconnect(lock_fd);
02403 StrFree(datetime);
02404 return(1);
02405 }
02406
02407
02408 if (o_zone != NULL) {
02409 status = KsmZoneIdFromName(o_zone, &zone_id);
02410 if (status != 0) {
02411
02412 StrAppend(&o_zone, ".");
02413 status = KsmZoneIdFromName(o_zone, &zone_id);
02414 if (status != 0) {
02415 printf("Error: unable to find a zone named \"%s\" in database\n", o_zone);
02416 db_disconnect(lock_fd);
02417 StrFree(datetime);
02418 return(status);
02419 }
02420 }
02421 }
02422
02423
02424 if (o_keytag != NULL) {
02425 if (StrIsDigits(o_keytag)) {
02426 status = StrStrtoi(o_keytag, &keytag_int);
02427 if (status != 0) {
02428 printf("Error: Unable to convert keytag \"%s\"; to an integer\n", o_keytag);
02429 db_disconnect(lock_fd);
02430 StrFree(datetime);
02431 return(status);
02432 }
02433 } else {
02434 printf("Error: keytag \"%s\"; should be numeric only\n", o_keytag);
02435 db_disconnect(lock_fd);
02436 StrFree(datetime);
02437 return(1);
02438 }
02439 }
02440
02441 if (o_keytag == NULL && o_cka_id == NULL) {
02442
02443 if (o_zone == NULL) {
02444 printf("Please provide a zone or details of the key to roll\n");
02445 usage_keykskretire();
02446 db_disconnect(lock_fd);
02447 StrFree(datetime);
02448 return(-1);
02449 }
02450
02451 status = CountKeysInState(KSM_TYPE_KSK, KSM_STATE_ACTIVE, &key_count, zone_id);
02452 if (status != 0) {
02453 printf("Error: failed to count active keys\n");
02454 db_disconnect(lock_fd);
02455 StrFree(datetime);
02456 return status;
02457 }
02458
02459
02460 if (key_count < 2) {
02461 printf("Error: completing this action would leave no active keys on zone, quitting...\n");
02462 db_disconnect(lock_fd);
02463 StrFree(datetime);
02464 return -1;
02465 }
02466
02467
02468 status = KsmPolicyIdFromZoneId(zone_id, &policy_id);
02469 if (status != 0) {
02470 printf("Error: failed to find policy for zone\n");
02471 db_disconnect(lock_fd);
02472 StrFree(datetime);
02473 return status;
02474 }
02475
02476 status = RetireOldKey(zone_id, policy_id, datetime);
02477
02478 if (status == 0) {
02479 printf("Old key retired\n");
02480 } else {
02481 printf("Old key NOT retired\n");
02482 }
02483 } else {
02484
02485
02486
02487
02488
02489 status = CountKeys(&zone_id, keytag_int, o_cka_id, &key_count, &temp_cka_id, &temp_key_state, &temp_keypair_id);
02490 if (status != 0) {
02491 printf("Error: failed to count keys\n");
02492 db_disconnect(lock_fd);
02493 StrFree(datetime);
02494 return status;
02495 }
02496
02497
02498 if (key_count > 1) {
02499 printf("More than one key matched your parameters, please include more information from the above keys\n");
02500 db_disconnect(lock_fd);
02501 StrFree(datetime);
02502 return -1;
02503 }
02504
02505
02506 if (key_count == 0 || temp_key_state != KSM_STATE_ACTIVE) {
02507 printf("No keys in the ACTIVE state matched your parameters, please check the parameters\n");
02508 db_disconnect(lock_fd);
02509 StrFree(datetime);
02510 return -1;
02511 }
02512
02513 status = CountKeysInState(KSM_TYPE_KSK, KSM_STATE_ACTIVE, &key_count, zone_id);
02514 if (status != 0) {
02515 printf("Error: failed to count active keys\n");
02516 db_disconnect(lock_fd);
02517 StrFree(datetime);
02518 return status;
02519 }
02520
02521
02522 if (key_count < 2) {
02523 printf("Error: completing this action would leave no active keys on zone, quitting...\n");
02524 db_disconnect(lock_fd);
02525 StrFree(datetime);
02526 return -1;
02527 }
02528
02529
02530 status = KsmPolicyIdFromZoneId(zone_id, &policy_id);
02531 if (status != 0) {
02532 printf("Error: failed to find policy for zone\n");
02533 db_disconnect(lock_fd);
02534 StrFree(datetime);
02535 return status;
02536 }
02537
02538
02539 status = ChangeKeyState(KSM_TYPE_KSK, temp_cka_id, zone_id, policy_id, datetime, KSM_STATE_RETIRE);
02540
02541
02542 if (status == 0) {
02543 printf("Key %s retired\n", temp_cka_id);
02544 }
02545 }
02546
02547
02548 db_disconnect(lock_fd);
02549
02550 DbDisconnect(dbhandle);
02551
02552 StrFree(datetime);
02553
02554 return status;
02555 }
02556
02557
02558
02559
02560
02561
02562
02563 int
02564 cmd_dsseen()
02565 {
02566 int status = 0;
02567 int zone_id = -1;
02568 int policy_id = -1;
02569 int key_count = -1;
02570 int retired_count = -1;
02571 int keytag_int = -1;
02572 int temp_key_state = -1;
02573 int temp_keypair_id = -1;
02574 char* temp_cka_id = NULL;
02575 int user_certain;
02576
02577
02578 DB_HANDLE dbhandle;
02579 FILE* lock_fd = NULL;
02580
02581 char logmsg[256];
02582
02583 char* datetime = DtParseDateTimeString("now");
02584
02585
02586 if (datetime == NULL) {
02587 printf("Couldn't turn \"now\" into a date, quitting...\n");
02588 StrFree(datetime);
02589 exit(1);
02590 }
02591
02592
02593 if (o_keytag == NULL && o_cka_id == NULL) {
02594 printf("Please provide a keytag or a CKA_ID for the key (CKA_ID will be used if both are provided\n");
02595 usage_keydsseen();
02596 StrFree(datetime);
02597 return(-1);
02598 }
02599
02600
02601 if (0) {
02602 printf("*WARNING* This will retire the currently active KSK; are you sure? [y/N] ");
02603
02604 user_certain = getchar();
02605 if (user_certain != 'y' && user_certain != 'Y') {
02606 printf("Okay, quitting...\n");
02607 exit(0);
02608 }
02609 }
02610
02611 status = db_connect(&dbhandle, &lock_fd, 1);
02612 if (status != 0) {
02613 printf("Failed to connect to database\n");
02614 db_disconnect(lock_fd);
02615 StrFree(datetime);
02616 return(1);
02617 }
02618
02619
02620
02621
02622
02623 if (o_zone == NULL) {
02624 printf("Please specify a zone using the --zone flag\n");
02625 usage_keydsseen();
02626 StrFree(datetime);
02627 db_disconnect(lock_fd);
02628 return(-1);
02629 }
02630 else if (o_zone != NULL) {
02631 status = KsmZoneIdFromName(o_zone, &zone_id);
02632 if (status != 0) {
02633
02634 StrAppend(&o_zone, ".");
02635 status = KsmZoneIdFromName(o_zone, &zone_id);
02636 if (status != 0) {
02637 printf("Error: unable to find a zone named \"%s\" in database\n", o_zone);
02638 db_disconnect(lock_fd);
02639 StrFree(datetime);
02640 return(status);
02641 }
02642 }
02643 }
02644 else if (all_flag) {
02645 printf("*WARNING* This will act on every zone where this key is in use; are you sure? [y/N] ");
02646
02647 user_certain = getchar();
02648 if (user_certain != 'y' && user_certain != 'Y') {
02649 printf("Okay, quitting...\n");
02650 exit(0);
02651 }
02652
02653 zone_id = -1;
02654 }
02655
02656
02657 if (o_keytag != NULL) {
02658 if (StrIsDigits(o_keytag)) {
02659 status = StrStrtoi(o_keytag, &keytag_int);
02660 if (status != 0) {
02661 printf("Error: Unable to convert keytag \"%s\"; to an integer\n", o_keytag);
02662 db_disconnect(lock_fd);
02663 StrFree(datetime);
02664 return(status);
02665 }
02666 } else {
02667 printf("Error: keytag \"%s\"; should be numeric only\n", o_keytag);
02668 db_disconnect(lock_fd);
02669 StrFree(datetime);
02670 return(1);
02671 }
02672 }
02673
02674
02675
02676
02677
02678 status = CountKeys(&zone_id, keytag_int, o_cka_id, &key_count, &temp_cka_id, &temp_key_state, &temp_keypair_id);
02679 if (status != 0) {
02680 printf("Error: failed to count keys\n");
02681 db_disconnect(lock_fd);
02682 StrFree(datetime);
02683 return status;
02684 }
02685
02686
02687 if (key_count > 1) {
02688 printf("More than one key matched your parameters, please include more information from the above keys\n");
02689 db_disconnect(lock_fd);
02690 StrFree(datetime);
02691 return -1;
02692 }
02693
02694
02695 if (temp_key_state == KSM_STATE_ACTIVE) {
02696 printf("Key is already active\n");
02697 db_disconnect(lock_fd);
02698 StrFree(datetime);
02699 return -1;
02700 }
02701
02702
02703 if (key_count == 0) {
02704 printf("No keys in the READY state matched your parameters, please check the parameters\n");
02705 db_disconnect(lock_fd);
02706 StrFree(datetime);
02707 return -1;
02708 }
02709
02710
02711 status = KsmPolicyIdFromZoneId(zone_id, &policy_id);
02712 if (status != 0) {
02713 printf("Error: failed to find policy for zone\n");
02714 db_disconnect(lock_fd);
02715 StrFree(datetime);
02716 return status;
02717 }
02718
02719
02720 status = MarkDSSeen(temp_keypair_id, zone_id, policy_id, datetime, temp_key_state);
02721
02722
02723 if (status == 0) {
02724 snprintf(logmsg, 256, "Key %s made %s", temp_cka_id, (temp_key_state == KSM_STATE_READY) ? "active" : "into standby");
02725 printf("%s\n", logmsg);
02726
02727
02728 openlog("ods-ksmutil", 0, DEFAULT_LOG_FACILITY);
02729 syslog(LOG_INFO, "%s", logmsg);
02730 closelog();
02731
02732 }
02733
02734
02735 if (temp_key_state == KSM_STATE_READY) {
02736 if (retire_flag == 1) {
02737
02738
02739 status = CountKeysInState(KSM_TYPE_KSK, KSM_STATE_ACTIVE, &key_count, zone_id);
02740 if (status != 0) {
02741 printf("Error: failed to count active keys\n");
02742 db_disconnect(lock_fd);
02743 StrFree(datetime);
02744 return status;
02745 }
02746
02747
02748 if (key_count < 2) {
02749
02750
02751 status = CountKeysInState(KSM_TYPE_KSK, KSM_STATE_RETIRE, &retired_count, zone_id);
02752 if (status != 0) {
02753 printf("Error: failed to count retired keys\n");
02754 db_disconnect(lock_fd);
02755 StrFree(datetime);
02756 return status;
02757 }
02758
02759
02760 db_disconnect(lock_fd);
02761 StrFree(datetime);
02762 if (retired_count != 0) {
02763 printf("Error: retiring a key would leave no active keys on zone, skipping...\n");
02764 return -1;
02765 } else {
02766
02767
02768 if (restart_enforcerd() != 0)
02769 {
02770 fprintf(stderr, "Could not HUP ods-enforcerd\n");
02771 }
02772 return 0;
02773 }
02774 }
02775
02776 status = RetireOldKey(zone_id, policy_id, datetime);
02777
02778
02779 if (status == 0) {
02780 printf("Old key retired\n");
02781 } else {
02782 printf("Old key NOT retired\n");
02783 }
02784 } else {
02785 printf("Old key NOT retired\n");
02786 }
02787 }
02788
02789
02790 if (restart_enforcerd() != 0)
02791 {
02792 fprintf(stderr, "Could not HUP ods-enforcerd\n");
02793 }
02794
02795
02796 db_disconnect(lock_fd);
02797
02798 DbDisconnect(dbhandle);
02799
02800 StrFree(datetime);
02801
02802 return status;
02803 }
02804
02805
02806
02807
02808 int
02809 cmd_import ()
02810 {
02811 int status = 0;
02812
02813
02814 char* case_keytype = NULL;
02815 char* case_algorithm = NULL;
02816 char* case_state = NULL;
02817
02818 int repo_id = -1;
02819 int zone_id = -1;
02820 int policy_id = -1;
02821 int cka_id_exists = -1;
02822 int keytype_id = -1;
02823 int size_int = -1;
02824 int algo_id = -1;
02825 int state_id = -1;
02826 char form_time[KSM_TIME_LENGTH];
02827 char form_opt_time[KSM_TIME_LENGTH];
02828
02829 DB_ID keypair_id = 0;
02830 DB_ID ignore = 0;
02831
02832 struct tm datetime;
02833
02834
02835 DB_HANDLE dbhandle;
02836 FILE* lock_fd = NULL;
02837
02838 DB_RESULT result;
02839 KSM_PARAMETER data;
02840
02841 int user_certain;
02842
02843
02844
02845 if (o_cka_id == NULL) {
02846 printf("Error: please specify a CKA_ID with the --cka_id <CKA_ID>\n");
02847 return(1);
02848 }
02849 if (o_repository == NULL) {
02850 printf("Error: please specify a repository with the --repository <repository>\n");
02851 return(1);
02852 }
02853 if (o_zone == NULL) {
02854 printf("Error: please specify a zone with the --zone <zone>\n");
02855 return(1);
02856 }
02857 if (o_size == NULL) {
02858 printf("Error: please specify the number of bits with the --bits <size>\n");
02859 return(1);
02860 }
02861 if (o_algo == NULL) {
02862 printf("Error: please specify the algorithm with the --algorithm <algorithm>\n");
02863 return(1);
02864 }
02865 if (o_keystate == NULL) {
02866 printf("Error: please specify the state with the --keystate <state>\n");
02867 return(1);
02868 }
02869 if (o_keytype == NULL) {
02870 printf("Error: please specify a keytype, KSK or ZSK, with the --keytype <type>\n");
02871 return(1);
02872 }
02873 if (o_time == NULL) {
02874 printf("Error: please specify the time of when the key entered the given state with the --time <time>\n");
02875 return(1);
02876 }
02877
02878
02879 status = db_connect(&dbhandle, &lock_fd, 1);
02880 if (status != 0) {
02881 printf("Failed to connect to database\n");
02882 db_disconnect(lock_fd);
02883 return(1);
02884 }
02885
02886
02887 status = KsmSmIdFromName(o_repository, &repo_id);
02888 if (status != 0) {
02889 printf("Error: unable to find a repository named \"%s\" in database\n", o_repository);
02890 db_disconnect(lock_fd);
02891 return status;
02892 }
02893
02894
02895 status = KsmZoneIdAndPolicyFromName(o_zone, &policy_id, &zone_id);
02896 if (status != 0) {
02897
02898 StrAppend(&o_zone, ".");
02899 status = KsmZoneIdAndPolicyFromName(o_zone, &policy_id, &zone_id);
02900 if (status != 0) {
02901 printf("Error: unable to find a zone named \"%s\" in database\n", o_zone);
02902 db_disconnect(lock_fd);
02903 return(status);
02904 }
02905 }
02906
02907
02908 status = (KsmCheckHSMkeyID(repo_id, o_cka_id, &cka_id_exists));
02909 if (status != 0) {
02910 db_disconnect(lock_fd);
02911 return(status);
02912 }
02913 if (cka_id_exists == 1) {
02914 printf("Error: key with CKA_ID \"%s\" already exists in database\n", o_cka_id);
02915 db_disconnect(lock_fd);
02916 return(1);
02917 }
02918
02919
02920 case_keytype = StrStrdup(o_keytype);
02921 (void) StrToUpper(case_keytype);
02922 if (strncmp(case_keytype, "KSK", 3) == 0 || strncmp(o_keytype, "257", 3) == 0) {
02923 keytype_id = 257;
02924 }
02925 else if (strncmp(case_keytype, "ZSK", 3) == 0 || strncmp(o_keytype, "256", 3) == 0) {
02926 keytype_id = 256;
02927 }
02928 else {
02929 printf("Error: Unrecognised keytype %s; should be one of KSK or ZSK\n", o_keytype);
02930
02931 db_disconnect(lock_fd);
02932 StrFree(case_keytype);
02933 return(1);
02934 }
02935 StrFree(case_keytype);
02936
02937
02938 if (StrIsDigits(o_size)) {
02939 status = StrStrtoi(o_size, &size_int);
02940 if (status != 0) {
02941 printf("Error: Unable to convert bits \"%s\"; to an integer\n", o_size);
02942 db_disconnect(lock_fd);
02943 return(status);
02944 }
02945 } else {
02946 printf("Error: Bits \"%s\"; should be numeric only\n", o_size);
02947 db_disconnect(lock_fd);
02948 return(1);
02949 }
02950
02951
02952 if (StrIsDigits(o_algo)) {
02953
02954 status = StrStrtoi(o_algo, &algo_id);
02955 } else {
02956
02957 case_algorithm = StrStrdup(o_algo);
02958 (void) StrToLower(case_algorithm);
02959
02960 algo_id = KsmKeywordAlgorithmNameToValue(case_algorithm);
02961 StrFree(case_algorithm);
02962 }
02963
02964 if (status != 0 || algo_id == 0 || hsm_supported_algorithm(algo_id) != 0) {
02965 printf("Error: Key algorithm %s not supported; try one of RSASHA1, RSASHA1-NSEC3-SHA1 or RSASHA256\n", o_algo);
02966 db_disconnect(lock_fd);
02967 return(status);
02968 }
02969
02970
02971 case_state = StrStrdup(o_keystate);
02972 (void) StrToUpper(case_state);
02973 if (strncmp(case_state, "GENERATE", 8) == 0 || strncmp(o_keystate, "1", 1) == 0) {
02974 state_id = 1;
02975 }
02976 else if (strncmp(case_state, "PUBLISH", 7) == 0 || strncmp(o_keystate, "2", 1) == 0) {
02977 state_id = 2;
02978 }
02979 else if (strncmp(case_state, "READY", 5) == 0 || strncmp(o_keystate, "3", 1) == 0) {
02980 state_id = 3;
02981 }
02982 else if (strncmp(case_state, "ACTIVE", 6) == 0 || strncmp(o_keystate, "4", 1) == 0) {
02983 state_id = 4;
02984 }
02985 else if (strncmp(case_state, "RETIRE", 6) == 0 || strncmp(o_keystate, "5", 1) == 0) {
02986 state_id = 5;
02987 }
02988 else {
02989 printf("Error: Unrecognised state %s; should be one of GENERATE, PUBLISH, READY, ACTIVE or RETIRE\n", o_keystate);
02990
02991 db_disconnect(lock_fd);
02992 StrFree(case_state);
02993 return(1);
02994 }
02995 StrFree(case_state);
02996
02997
02998 status = DtGeneral(o_time, &datetime);
02999 if (status != 0) {
03000 printf("Error: unable to convert \"%s\" into a date\n", o_time);
03001 date_help();
03002
03003 db_disconnect(lock_fd);
03004 return(status);
03005 }
03006 else {
03007 snprintf(form_time, KSM_TIME_LENGTH, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
03008 datetime.tm_year + 1900, datetime.tm_mon + 1, datetime.tm_mday,
03009 datetime.tm_hour, datetime.tm_min, datetime.tm_sec);
03010 }
03011
03012 if (o_retire != NULL) {
03013
03014 if (state_id != KSM_STATE_ACTIVE) {
03015 printf("Error: unable to specify retire time for a key in state \"%s\"\n", o_keystate);
03016 db_disconnect(lock_fd);
03017 return(status);
03018 }
03019
03020 status = DtGeneral(o_retire, &datetime);
03021 if (status != 0) {
03022 printf("Error: unable to convert retire time \"%s\" into a date\n", o_retire);
03023 date_help();
03024
03025 db_disconnect(lock_fd);
03026 return(status);
03027 }
03028 else {
03029 snprintf(form_opt_time, KSM_TIME_LENGTH, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
03030 datetime.tm_year + 1900, datetime.tm_mon + 1, datetime.tm_mday,
03031 datetime.tm_hour, datetime.tm_min, datetime.tm_sec);
03032 }
03033 } else {
03034 form_opt_time[0] = '\0';
03035 }
03036
03037
03038 status = KsmParameterInit(&result, "zones_share_keys", "keys", policy_id);
03039 if (status != 0) {
03040 db_disconnect(lock_fd);
03041 return(status);
03042 }
03043 status = KsmParameter(result, &data);
03044 if (status != 0) {
03045 db_disconnect(lock_fd);
03046 return(status);
03047 }
03048 KsmParameterEnd(result);
03049
03050
03051 if (data.value == 1) {
03052 printf("*WARNING* This zone shares keys with others, the key will be added to all; are you sure? [y/N] ");
03053
03054 user_certain = getchar();
03055 if (user_certain != 'y' && user_certain != 'Y') {
03056 printf("Okay, quitting...\n");
03057 db_disconnect(lock_fd);
03058 exit(0);
03059 }
03060 }
03061
03062
03063 status = KsmImportKeyPair(policy_id, o_cka_id, repo_id, size_int, algo_id, state_id, form_time, &keypair_id);
03064 if (status != 0) {
03065 printf("Error: couldn't import key\n");
03066 db_disconnect(lock_fd);
03067 return(status);
03068 }
03069
03070
03071
03072
03073
03074
03075 status = KsmDnssecKeyCreate(zone_id, (int) keypair_id, keytype_id, state_id, form_time, &ignore);
03076
03077 if (status != 0) {
03078 printf("Error: couldn't allocate key to zone(s)\n");
03079 db_disconnect(lock_fd);
03080 return(status);
03081 }
03082
03083 printf("Key imported into zone(s)\n");
03084
03085
03086 db_disconnect(lock_fd);
03087
03088 DbDisconnect(dbhandle);
03089 return 0;
03090 }
03091
03092
03093
03094
03095 int
03096 cmd_dbbackup ()
03097 {
03098
03099 FILE* lock_fd = NULL;
03100
03101
03102 char *dbschema = NULL;
03103 char *host = NULL;
03104 char *port = NULL;
03105 char *user = NULL;
03106 char *password = NULL;
03107
03108 int status;
03109
03110 char* backup_filename = NULL;
03111 char* lock_filename;
03112
03113 char *path = getenv("PWD");
03114
03115 if (DbFlavour() != SQLITE_DB) {
03116 printf("Sorry, currently this utility can only backup a sqlite database file\n");
03117 return -1;
03118 }
03119
03120
03121 status = get_db_details(&dbschema, &host, &port, &user, &password);
03122 if (status != 0) {
03123 StrFree(host);
03124 StrFree(port);
03125 StrFree(dbschema);
03126 StrFree(user);
03127 StrFree(password);
03128 return(status);
03129 }
03130
03131
03132 lock_filename = NULL;
03133 StrAppend(&lock_filename, dbschema);
03134 StrAppend(&lock_filename, ".our_lock");
03135
03136 lock_fd = fopen(lock_filename, "w");
03137 status = get_lite_lock(lock_filename, lock_fd);
03138 if (status != 0) {
03139 printf("Error getting db lock\n");
03140 if (lock_fd != NULL) {
03141 fclose(lock_fd);
03142 }
03143 StrFree(host);
03144 StrFree(port);
03145 StrFree(dbschema);
03146 StrFree(user);
03147 StrFree(password);
03148 return(1);
03149 }
03150 StrFree(lock_filename);
03151
03152
03153 if (o_output == NULL) {
03154 StrAppend(&backup_filename, dbschema);
03155 StrAppend(&backup_filename, ".backup");
03156 } else if (*o_output != '/') {
03157 StrAppend(&backup_filename, path);
03158 StrAppend(&backup_filename, "/");
03159 StrAppend(&backup_filename, o_output);
03160 } else {
03161 StrAppend(&backup_filename, o_output);
03162 }
03163
03164 status = backup_file(dbschema, backup_filename);
03165
03166 StrFree(backup_filename);
03167
03168
03169 StrFree(host);
03170 StrFree(port);
03171 StrFree(dbschema);
03172 StrFree(user);
03173 StrFree(password);
03174
03175
03176 db_disconnect(lock_fd);
03177
03178 return status;
03179 }
03180
03181
03182
03183
03184 int
03185 cmd_purgepolicy ()
03186 {
03187 int status = 0;
03188
03189 char* kasp_filename = NULL;
03190 char* zonelist_filename = NULL;
03191 char* backup_filename = NULL;
03192
03193 DB_HANDLE dbhandle;
03194 FILE* lock_fd = NULL;
03195 KSM_POLICY *policy;
03196 DB_RESULT result;
03197 DB_RESULT result2;
03198 char sql[KSM_SQL_SIZE];
03199 int size = -1;
03200 char* sql2;
03201
03202 FILE *test;
03203 int zone_count = -1;
03204
03205 xmlDocPtr doc = NULL;
03206
03207 int user_certain;
03208 printf("*WARNING* This feature is experimental and has not been fully tested; are you sure? [y/N] ");
03209
03210 user_certain = getchar();
03211 if (user_certain != 'y' && user_certain != 'Y') {
03212 printf("Okay, quitting...\n");
03213 exit(0);
03214 }
03215
03216
03217 status = read_filenames(&zonelist_filename, &kasp_filename);
03218 if (status != 0) {
03219 printf("Failed to read conf.xml\n");
03220 db_disconnect(lock_fd);
03221 return(1);
03222 }
03223
03224
03225 StrAppend(&backup_filename, kasp_filename);
03226 StrAppend(&backup_filename, ".backup");
03227 status = backup_file(kasp_filename, backup_filename);
03228 StrFree(backup_filename);
03229 if (status != 0) {
03230 StrFree(kasp_filename);
03231 db_disconnect(lock_fd);
03232 return(status);
03233 }
03234
03235
03236 if ((test = fopen(kasp_filename, "ab"))==NULL) {
03237 printf("Cannot open kasp.xml for writing: %s\n", strerror(errno));
03238 return(-1);
03239 } else {
03240 fclose(test);
03241 }
03242
03243
03244 status = db_connect(&dbhandle, &lock_fd, 1);
03245 if (status != 0) {
03246 printf("Failed to connect to database\n");
03247 db_disconnect(lock_fd);
03248 return(1);
03249 }
03250
03251
03252 status = DbBeginTransaction();
03253 if (status != 0) {
03254
03255
03256 MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
03257 db_disconnect(lock_fd);
03258 return status;
03259 }
03260
03261
03262 policy = KsmPolicyAlloc();
03263 if (policy == NULL) {
03264 printf("Malloc for policy struct failed\n");
03265 exit(1);
03266 }
03267
03268
03269 status = KsmPolicyInit(&result, NULL);
03270 if (status == 0) {
03271
03272 status = KsmPolicy(result, policy);
03273 while (status == 0) {
03274
03275 status = KsmZoneCountInit(&result2, policy->id);
03276 if (status == 0) {
03277 status = KsmZoneCount(result2, &zone_count);
03278 }
03279 DbFreeResult(result2);
03280
03281 if (status == 0) {
03282
03283 if (zone_count == 0) {
03284 printf("No zones on policy %s; purging...\n", policy->name);
03285
03286 size = snprintf(sql, KSM_SQL_SIZE, "update dnsseckeys set state = %d where keypair_id in (select id from keypairs where policy_id = %d)", KSM_STATE_DEAD, policy->id);
03287
03288
03289 if (size < 0 || size >= KSM_SQL_SIZE) {
03290 printf("Couldn't construct SQL to kill orphaned keys\n");
03291 db_disconnect(lock_fd);
03292 KsmPolicyFree(policy);
03293 return -1;
03294 }
03295
03296 status = DbExecuteSqlNoResult(DbHandle(), sql);
03297
03298
03299 if (status != 0) {
03300 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
03301 db_disconnect(lock_fd);
03302 KsmPolicyFree(policy);
03303 return status;
03304 }
03305
03306
03307 status = PurgeKeys(-1, policy->id);
03308 if (status != 0) {
03309 printf("Key purge failed for policy %s\n", policy->name);
03310 db_disconnect(lock_fd);
03311 KsmPolicyFree(policy);
03312 return status;
03313 }
03314
03315
03316 sql2 = DdsInit("parameters_policies");
03317 DdsConditionInt(&sql2, "policy_id", DQS_COMPARE_EQ, policy->id, 0);
03318 DdsEnd(&sql2);
03319 status = DbExecuteSqlNoResult(DbHandle(), sql2);
03320 DdsFree(sql2);
03321
03322 if (status != 0)
03323 {
03324 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
03325 db_disconnect(lock_fd);
03326 KsmPolicyFree(policy);
03327 return status;
03328 }
03329
03330 sql2 = DdsInit("policies");
03331 DdsConditionInt(&sql2, "id", DQS_COMPARE_EQ, policy->id, 0);
03332 DdsEnd(&sql2);
03333 status = DbExecuteSqlNoResult(DbHandle(), sql2);
03334 DdsFree(sql2);
03335
03336 if (status != 0)
03337 {
03338 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
03339 db_disconnect(lock_fd);
03340 KsmPolicyFree(policy);
03341 return status;
03342 }
03343
03344
03345
03346 doc = del_policy_node(kasp_filename, policy->name);
03347 if (doc == NULL) {
03348 db_disconnect(lock_fd);
03349 KsmPolicyFree(policy);
03350 StrFree(kasp_filename);
03351 return(1);
03352 }
03353
03354
03355 status = xmlSaveFormatFile(kasp_filename, doc, 1);
03356 xmlFreeDoc(doc);
03357 if (status == -1) {
03358 printf("Could not save %s\n", kasp_filename);
03359 StrFree(kasp_filename);
03360 db_disconnect(lock_fd);
03361 KsmPolicyFree(policy);
03362 return(1);
03363 }
03364
03365 }
03366 } else {
03367 printf("Couldn't count zones on policy; quitting...\n");
03368 db_disconnect(lock_fd);
03369 exit(1);
03370 }
03371
03372
03373 status = KsmPolicy(result, policy);
03374 }
03375
03376 if (status == -1) {
03377 status = 0;
03378 }
03379 DbFreeResult(result);
03380 }
03381
03382
03383 if (status == 0) {
03384
03385 DbCommit();
03386 } else {
03387
03388 DbRollback();
03389 }
03390
03391 StrFree(kasp_filename);
03392 db_disconnect(lock_fd);
03393 KsmPolicyFree(policy);
03394 return status;
03395 }
03396
03397
03398
03399
03400 int
03401 cmd_control(char *command)
03402 {
03403 int status = 0;
03404 char* ods_control_cmd = NULL;
03405 char* ptr = command;
03406
03407
03408 if (ptr) {
03409 while (*ptr) {
03410 *ptr = tolower((int) *ptr);
03411 ++ptr;
03412 }
03413 }
03414
03415
03416 StrAppend(&ods_control_cmd, ODS_EN_CONTROL);
03417 StrAppend(&ods_control_cmd, command);
03418
03419 status = system(ods_control_cmd);
03420 if (status != 0)
03421 {
03422 fprintf(stderr, "Couldn't run %s\n", ods_control_cmd);
03423 }
03424
03425 StrFree(ods_control_cmd);
03426
03427 return(status);
03428 }
03429
03430
03431
03432
03433 int
03434 main (int argc, char *argv[])
03435 {
03436 int result;
03437 int ch;
03438 char* case_command = NULL;
03439 char* case_verb = NULL;
03440
03441 int option_index = 0;
03442 static struct option long_options[] =
03443 {
03444 {"all", no_argument, 0, 'a'},
03445 {"bits", required_argument, 0, 'b'},
03446 {"config", required_argument, 0, 'c'},
03447 {"ds", no_argument, 0, 'd'},
03448 {"keystate", required_argument, 0, 'e'},
03449 {"no-retire", no_argument, 0, 'f'},
03450 {"algorithm", required_argument, 0, 'g'},
03451 {"help", no_argument, 0, 'h'},
03452 {"input", required_argument, 0, 'i'},
03453 {"cka_id", required_argument, 0, 'k'},
03454 {"no-xml", no_argument, 0, 'm'},
03455 {"interval", required_argument, 0, 'n'},
03456 {"output", required_argument, 0, 'o'},
03457 {"policy", required_argument, 0, 'p'},
03458 {"repository", required_argument, 0, 'r'},
03459 {"signerconf", required_argument, 0, 's'},
03460 {"keytype", required_argument, 0, 't'},
03461 {"time", required_argument, 0, 'w'},
03462 {"verbose", no_argument, 0, 'v'},
03463 {"version", no_argument, 0, 'V'},
03464 {"keytag", required_argument, 0, 'x'},
03465 {"retire", required_argument, 0, 'y'},
03466 {"zone", required_argument, 0, 'z'},
03467 {0,0,0,0}
03468 };
03469
03470 progname = argv[0];
03471
03472 while ((ch = getopt_long(argc, argv, "ab:c:de:fg:hi:k:n:o:p:r:s:t:vVw:x:y:z:", long_options, &option_index)) != -1) {
03473 switch (ch) {
03474 case 'a':
03475 all_flag = 1;
03476 break;
03477 case 'b':
03478 o_size = StrStrdup(optarg);
03479 break;
03480 case 'c':
03481 config = StrStrdup(optarg);
03482 break;
03483 case 'd':
03484 ds_flag = 1;
03485 break;
03486 case 'e':
03487 o_keystate = StrStrdup(optarg);
03488 break;
03489 case 'f':
03490 retire_flag = 0;
03491 break;
03492 case 'g':
03493 o_algo = StrStrdup(optarg);
03494 break;
03495 case 'h':
03496 usage();
03497 states_help();
03498 types_help();
03499 date_help();
03500 exit(0);
03501 break;
03502 case 'i':
03503 o_input = StrStrdup(optarg);
03504 break;
03505 case 'k':
03506 o_cka_id = StrStrdup(optarg);
03507 break;
03508 case 'm':
03509 xml_flag = 0;
03510 break;
03511 case 'n':
03512 o_interval = StrStrdup(optarg);
03513 break;
03514 case 'o':
03515 o_output = StrStrdup(optarg);
03516 break;
03517 case 'p':
03518 o_policy = StrStrdup(optarg);
03519 break;
03520 case 'r':
03521 o_repository = StrStrdup(optarg);
03522 break;
03523 case 's':
03524 o_signerconf = StrStrdup(optarg);
03525 break;
03526 case 't':
03527 o_keytype = StrStrdup(optarg);
03528 break;
03529 case 'V':
03530 printf("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
03531 exit(0);
03532 break;
03533 case 'v':
03534 verbose_flag = 1;
03535 break;
03536 case 'w':
03537 o_time = StrStrdup(optarg);
03538 break;
03539 case 'x':
03540 o_keytag = StrStrdup(optarg);
03541 break;
03542 case 'y':
03543 o_retire = StrStrdup(optarg);
03544 break;
03545 case 'z':
03546
03547 o_zone = StrStrdup(optarg);
03548 if (strlen(o_zone) > 1 && o_zone[strlen(o_zone)-1] == '.') {
03549 o_zone[strlen(o_zone)-1] = '\0';
03550 td_flag = 1;
03551 }
03552
03553 break;
03554 default:
03555 usage();
03556 exit(1);
03557 }
03558 }
03559 argc -= optind;
03560 argv += optind;
03561
03562 if (!argc) {
03563 usage();
03564 exit(1);
03565 }
03566
03567
03568
03569 MsgInit();
03570 MsgRegister(KME_MIN_VALUE, KME_MAX_VALUE, m_messages, ksm_log_msg);
03571 MsgRegister(DBS_MIN_VALUE, DBS_MAX_VALUE, d_messages, ksm_log_msg);
03572
03573
03574 case_command = StrStrdup(argv[0]);
03575 (void) StrToUpper(case_command);
03576 if (argc > 1) {
03577
03578 case_verb = StrStrdup(argv[1]);
03579 (void) StrToUpper(case_verb);
03580 } else {
03581 case_verb = StrStrdup("NULL");
03582 }
03583
03584
03585 if (!strncmp(case_command, "SETUP", 5)) {
03586 argc --;
03587 argv ++;
03588 result = cmd_setup();
03589 } else if (!strncmp(case_command, "UPDATE", 6)) {
03590 argc --;
03591 argv ++;
03592 result = cmd_update(case_verb);
03593 } else if (!strncmp(case_command, "START", 5) ||
03594 !strncmp(case_command, "STOP", 4) ||
03595 !strncmp(case_command, "NOTIFY", 6)) {
03596 argc --;
03597 argv ++;
03598 result = cmd_control(case_command);
03599 } else if (!strncmp(case_command, "ZONE", 4) && strlen(case_command) == 4) {
03600 argc --; argc --;
03601 argv ++; argv ++;
03602
03603
03604 if (!strncmp(case_verb, "ADD", 3)) {
03605 result = cmd_addzone();
03606 } else if (!strncmp(case_verb, "DELETE", 6)) {
03607 result = cmd_delzone();
03608 } else if (!strncmp(case_verb, "LIST", 4)) {
03609 result = cmd_listzone();
03610 } else {
03611 printf("Unknown command: zone %s\n", case_verb);
03612 usage_zone();
03613 result = -1;
03614 }
03615 } else if (!strncmp(case_command, "REPOSITORY", 10)) {
03616 argc --; argc --;
03617 argv ++; argv ++;
03618
03619 if (!strncmp(case_verb, "LIST", 4)) {
03620 result = cmd_listrepo();
03621 } else {
03622 printf("Unknown command: repository %s\n", case_verb);
03623 usage_repo();
03624 result = -1;
03625 }
03626 } else if (!strncmp(case_command, "POLICY", 6)) {
03627 argc --; argc --;
03628 argv ++; argv ++;
03629
03630 if (!strncmp(case_verb, "EXPORT", 6)) {
03631 result = cmd_exportpolicy();
03632 } else if (!strncmp(case_verb, "IMPORT", 6)) {
03633 result = cmd_update("KASP");
03634 } else if (!strncmp(case_verb, "LIST", 4)) {
03635 result = cmd_listpolicy();
03636 } else if (!strncmp(case_verb, "PURGE", 5)) {
03637 result = cmd_purgepolicy();
03638 } else {
03639 printf("Unknown command: policy %s\n", case_verb);
03640 usage_policy();
03641 result = -1;
03642 }
03643 } else if (!strncmp(case_command, "KEY", 3)) {
03644 argc --; argc --;
03645 argv ++; argv ++;
03646
03647 if (!strncmp(case_verb, "LIST", 4)) {
03648 result = cmd_listkeys();
03649 }
03650 else if (!strncmp(case_verb, "EXPORT", 6)) {
03651 result = cmd_exportkeys();
03652 }
03653 else if (!strncmp(case_verb, "IMPORT", 6)) {
03654 result = cmd_import();
03655 }
03656 else if (!strncmp(case_verb, "ROLLOVER", 8)) {
03657
03658 if (o_zone != NULL && o_policy == NULL) {
03659 result = cmd_rollzone();
03660 }
03661 else if (o_zone == NULL && o_policy != NULL) {
03662 result = cmd_rollpolicy();
03663 }
03664 else {
03665 printf("Please provide either a zone OR a policy to rollover\n");
03666 usage_keyroll();
03667 result = -1;
03668 }
03669 }
03670 else if (!strncmp(case_verb, "PURGE", 5)) {
03671 if ((o_zone != NULL && o_policy == NULL) ||
03672 (o_zone == NULL && o_policy != NULL)){
03673 result = cmd_keypurge();
03674 }
03675 else {
03676 printf("Please provide either a zone OR a policy to key purge\n");
03677 usage_keypurge();
03678 result = -1;
03679 }
03680 }
03681 else if (!strncmp(case_verb, "GENERATE", 8)) {
03682 result = cmd_genkeys();
03683 }
03684 else if (!strncmp(case_verb, "KSK-RETIRE", 10)) {
03685 result = cmd_kskretire();
03686 }
03687 else if (!strncmp(case_verb, "DS-SEEN", 7)) {
03688 result = cmd_dsseen();
03689 } else {
03690 printf("Unknown command: key %s\n", case_verb);
03691 usage_key();
03692 result = -1;
03693 }
03694 } else if (!strncmp(case_command, "BACKUP", 6)) {
03695 argc --; argc --;
03696 argv ++; argv ++;
03697
03698 if (!strncmp(case_verb, "DONE", 4) ||
03699 !strncmp(case_verb, "PREPARE", 7) ||
03700 !strncmp(case_verb, "COMMIT", 6) ||
03701 !strncmp(case_verb, "ROLLBACK", 8)) {
03702 result = cmd_backup(case_verb);
03703 }
03704 else if (!strncmp(case_verb, "LIST", 4)) {
03705 result = cmd_listbackups();
03706 } else {
03707 printf("Unknown command: backup %s\n", case_verb);
03708 usage_backup();
03709 result = -1;
03710 }
03711 } else if (!strncmp(case_command, "ROLLOVER", 8)) {
03712 argc --; argc --;
03713 argv ++; argv ++;
03714 if (!strncmp(case_verb, "LIST", 4)) {
03715 result = cmd_listrolls();
03716 } else {
03717 printf("Unknown command: rollover %s\n", case_verb);
03718 usage_rollover();
03719 result = -1;
03720 }
03721 } else if (!strncmp(case_command, "DATABASE", 8)) {
03722 argc --; argc --;
03723 argv ++; argv ++;
03724
03725 if (!strncmp(case_verb, "BACKUP", 6)) {
03726 result = cmd_dbbackup();
03727 } else {
03728 printf("Unknown command: database %s\n", case_verb);
03729 usage_database();
03730 result = -1;
03731 }
03732 } else if (!strncmp(case_command, "ZONELIST", 8)) {
03733 argc --; argc --;
03734 argv ++; argv ++;
03735
03736 if (!strncmp(case_verb, "EXPORT", 6)) {
03737 result = cmd_exportzonelist();
03738 }
03739 else if (!strncmp(case_verb, "IMPORT", 6)) {
03740 result = cmd_update("ZONELIST");
03741 } else {
03742 printf("Unknown command: zonelist %s\n", case_verb);
03743 usage_zonelist2();
03744 result = -1;
03745 }
03746 } else {
03747 printf("Unknown command: %s\n", argv[0]);
03748 usage();
03749 result = -1;
03750 }
03751
03752 StrFree(case_command);
03753 StrFree(case_verb);
03754
03755
03756
03757
03758 xmlCleanupParser();
03759 xmlCleanupGlobals();
03760 xmlCleanupThreads();
03761
03762 exit(result);
03763 }
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778 int
03779 db_connect(DB_HANDLE *dbhandle, FILE** lock_fd, int backup)
03780 {
03781
03782 char *dbschema = NULL;
03783 char *host = NULL;
03784 char *port = NULL;
03785 char *user = NULL;
03786 char *password = NULL;
03787
03788 int status;
03789
03790 char* backup_filename = NULL;
03791 char* lock_filename;
03792
03793
03794 status = get_db_details(&dbschema, &host, &port, &user, &password);
03795 if (status != 0) {
03796 StrFree(host);
03797 StrFree(port);
03798 StrFree(dbschema);
03799 StrFree(user);
03800 StrFree(password);
03801 return(status);
03802 }
03803
03804
03805
03806
03807 if (DbFlavour() == SQLITE_DB) {
03808
03809
03810 if (lock_fd != NULL) {
03811 lock_filename = NULL;
03812 StrAppend(&lock_filename, dbschema);
03813 StrAppend(&lock_filename, ".our_lock");
03814
03815 *lock_fd = fopen(lock_filename, "w");
03816 status = get_lite_lock(lock_filename, *lock_fd);
03817 if (status != 0) {
03818 printf("Error getting db lock\n");
03819 if (*lock_fd != NULL) {
03820 fclose(*lock_fd);
03821 }
03822 StrFree(host);
03823 StrFree(port);
03824 StrFree(dbschema);
03825 StrFree(user);
03826 StrFree(password);
03827 return(1);
03828 }
03829 StrFree(lock_filename);
03830 }
03831
03832
03833 if (backup == 1) {
03834 StrAppend(&backup_filename, dbschema);
03835 StrAppend(&backup_filename, ".backup");
03836
03837 status = backup_file(dbschema, backup_filename);
03838
03839 StrFree(backup_filename);
03840
03841 if (status == 1) {
03842 if (lock_fd != NULL) {
03843 fclose(*lock_fd);
03844 }
03845 StrFree(host);
03846 StrFree(port);
03847 StrFree(dbschema);
03848 StrFree(user);
03849 StrFree(password);
03850 return(status);
03851 }
03852 }
03853
03854 }
03855
03856
03857 status = DbConnect(dbhandle, dbschema, host, password, user, port);
03858
03859
03860 StrFree(host);
03861 StrFree(port);
03862 StrFree(dbschema);
03863 StrFree(user);
03864 StrFree(password);
03865
03866 return(status);
03867 }
03868
03869
03870
03871
03872
03873 void
03874 db_disconnect(FILE* lock_fd)
03875 {
03876 int status = 0;
03877
03878 if (DbFlavour() == SQLITE_DB) {
03879 if (lock_fd != NULL) {
03880 status = release_lite_lock(lock_fd);
03881 if (status != 0) {
03882 printf("Error releasing db lock");
03883
03884 return;
03885 }
03886 fclose(lock_fd);
03887 }
03888 }
03889 return;
03890 }
03891
03892
03893
03894
03895
03896
03897
03898 int get_lite_lock(char *lock_filename, FILE* lock_fd)
03899 {
03900 struct flock fl;
03901 struct timeval tv;
03902
03903 if (lock_fd == NULL) {
03904 printf("%s could not be opened\n", lock_filename);
03905 return 1;
03906 }
03907
03908 memset(&fl, 0, sizeof(struct flock));
03909 fl.l_type = F_WRLCK;
03910 fl.l_whence = SEEK_SET;
03911 fl.l_pid = getpid();
03912
03913 while (fcntl(fileno(lock_fd), F_SETLK, &fl) == -1) {
03914 if (errno == EACCES || errno == EAGAIN) {
03915 printf("%s already locked, sleep\n", lock_filename);
03916
03917
03918 tv.tv_sec = 10;
03919 tv.tv_usec = 0;
03920 select(0, NULL, NULL, NULL, &tv);
03921
03922 } else {
03923 printf("couldn't get lock on %s; %s\n", lock_filename, strerror(errno));
03924 return 1;
03925 }
03926 }
03927
03928 return 0;
03929
03930 }
03931
03932 int release_lite_lock(FILE* lock_fd)
03933 {
03934 struct flock fl;
03935
03936 if (lock_fd == NULL) {
03937 return 1;
03938 }
03939
03940 memset(&fl, 0, sizeof(struct flock));
03941 fl.l_type = F_UNLCK;
03942 fl.l_whence = SEEK_SET;
03943
03944 if (fcntl(fileno(lock_fd), F_SETLK, &fl) == -1) {
03945 return 1;
03946 }
03947
03948 return 0;
03949 }
03950
03951
03952
03953
03954
03955 int read_filenames(char** zone_list_filename, char** kasp_filename)
03956 {
03957 xmlTextReaderPtr reader = NULL;
03958 xmlDocPtr doc = NULL;
03959 xmlXPathContextPtr xpathCtx = NULL;
03960 xmlXPathObjectPtr xpathObj = NULL;
03961 int ret = 0;
03962 char* tag_name = NULL;
03963 char* temp_char = NULL;
03964
03965 xmlChar *zonelist_expr = (unsigned char*) "//Common/ZoneListFile";
03966 xmlChar *kaspfile_expr = (unsigned char*) "//Common/PolicyFile";
03967
03968
03969 reader = xmlNewTextReaderFilename(config);
03970 if (reader != NULL) {
03971 ret = xmlTextReaderRead(reader);
03972 while (ret == 1) {
03973 tag_name = (char*) xmlTextReaderLocalName(reader);
03974
03975 if (strncmp(tag_name, "Common", 6) == 0
03976 && xmlTextReaderNodeType(reader) == 1) {
03977
03978
03979 xmlTextReaderExpand(reader);
03980 doc = xmlTextReaderCurrentDoc(reader);
03981 if (doc == NULL) {
03982 printf("Error: can not read Common section\n");
03983
03984 ret = xmlTextReaderRead(reader);
03985 continue;
03986 }
03987
03988 xpathCtx = xmlXPathNewContext(doc);
03989 if(xpathCtx == NULL) {
03990 printf("Error: can not create XPath context for Common section\n");
03991
03992 ret = xmlTextReaderRead(reader);
03993 continue;
03994 }
03995
03996
03997 xpathObj = xmlXPathEvalExpression(zonelist_expr, xpathCtx);
03998 if(xpathObj == NULL) {
03999 printf("Error: unable to evaluate xpath expression: %s\n", zonelist_expr);
04000
04001 ret = xmlTextReaderRead(reader);
04002 continue;
04003 }
04004 *zone_list_filename = NULL;
04005 temp_char = (char*) xmlXPathCastToString(xpathObj);
04006 StrAppend(zone_list_filename, temp_char);
04007 StrFree(temp_char);
04008 xmlXPathFreeObject(xpathObj);
04009 printf("zonelist filename set to %s.\n", *zone_list_filename);
04010
04011
04012 xpathObj = xmlXPathEvalExpression(kaspfile_expr, xpathCtx);
04013 xmlXPathFreeContext(xpathCtx);
04014 if(xpathObj == NULL) {
04015 printf("Error: unable to evaluate xpath expression: %s\n", kaspfile_expr);
04016
04017 ret = xmlTextReaderRead(reader);
04018 continue;
04019 }
04020 *kasp_filename = NULL;
04021 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
04022
04023
04024
04025 temp_char = (char*) xmlXPathCastToString(xpathObj);
04026 StrAppend(kasp_filename, temp_char);
04027 StrFree(temp_char);
04028 } else {
04029
04030
04031
04032
04033 StrAppend(kasp_filename, OPENDNSSEC_CONFIG_DIR);
04034 StrAppend(kasp_filename, "/kasp.xml");
04035 }
04036 printf("kasp filename set to %s.\n", *kasp_filename);
04037
04038 xmlXPathFreeObject(xpathObj);
04039 }
04040
04041 ret = xmlTextReaderRead(reader);
04042
04043 StrFree(tag_name);
04044 }
04045 xmlFreeTextReader(reader);
04046 if (ret != 0) {
04047 printf("%s : failed to parse\n", config);
04048 return(1);
04049 }
04050 } else {
04051 printf("Unable to open %s\n", config);
04052 return(1);
04053 }
04054 if (doc) {
04055 xmlFreeDoc(doc);
04056 }
04057
04058 return 0;
04059 }
04060
04061
04062
04063
04064
04065 int update_repositories()
04066 {
04067 int status = 0;
04068 xmlDocPtr doc = NULL;
04069 xmlXPathContextPtr xpathCtx = NULL;
04070 xmlXPathObjectPtr xpathObj = NULL;
04071 xmlNode *curNode;
04072 char* repo_name = NULL;
04073 char* repo_capacity = NULL;
04074 int require_backup = 0;
04075 int i = 0;
04076
04077 xmlChar *node_expr = (unsigned char*) "//Configuration/RepositoryList/Repository";
04078
04079
04080
04081 doc = xmlParseFile(config);
04082 if (doc == NULL) {
04083 printf("Unable to open %s\n", config);
04084 return(1);
04085 }
04086
04087
04088 xpathCtx = xmlXPathNewContext(doc);
04089 if(xpathCtx == NULL) {
04090 xmlFreeDoc(doc);
04091 return(1);
04092 }
04093
04094
04095 xpathObj = xmlXPathEvalExpression(node_expr, xpathCtx);
04096 if(xpathObj == NULL) {
04097 xmlXPathFreeContext(xpathCtx);
04098 xmlFreeDoc(doc);
04099 return(1);
04100 }
04101
04102 if (xpathObj->nodesetval) {
04103 for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
04104
04105 require_backup = 0;
04106 StrAppend(&repo_capacity, "");
04107
04108 curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
04109 repo_name = (char *) xmlGetProp(xpathObj->nodesetval->nodeTab[i],
04110 (const xmlChar *)"name");
04111 while (curNode) {
04112 if (xmlStrEqual(curNode->name, (const xmlChar *)"Capacity")) {
04113 repo_capacity = (char *) xmlNodeGetContent(curNode);
04114 }
04115 if (xmlStrEqual(curNode->name, (const xmlChar *)"RequireBackup")) {
04116 require_backup = 1;
04117 }
04118
04119 curNode = curNode->next;
04120 }
04121
04122 if (strlen(repo_name) != 0) {
04123
04124 printf("Repository %s found\n", repo_name);
04125 if (strlen(repo_capacity) == 0) {
04126 printf("No Maximum Capacity set.\n");
04127
04128
04129
04130 status = KsmImportRepository(repo_name, "0", require_backup);
04131 } else {
04132 printf("Capacity set to %s.\n", repo_capacity);
04133
04134
04135
04136 status = KsmImportRepository(repo_name, repo_capacity, require_backup);
04137 }
04138 if (require_backup == 0) {
04139 printf("RequireBackup NOT set; please make sure that you know the potential problems of using keys which are not recoverable\n");
04140 } else {
04141 printf("RequireBackup set.\n");
04142 }
04143
04144 if (status != 0) {
04145 printf("Error Importing Repository %s", repo_name);
04146
04147 }
04148 } else {
04149 printf("WARNING: Repository found with NULL name, skipping...\n");
04150 }
04151 StrFree(repo_name);
04152 StrFree(repo_capacity);
04153 }
04154 }
04155
04156 if (xpathObj) {
04157 xmlXPathFreeObject(xpathObj);
04158 }
04159 if (xpathCtx) {
04160 xmlXPathFreeContext(xpathCtx);
04161 }
04162 if (doc) {
04163 xmlFreeDoc(doc);
04164 }
04165
04166 return 0;
04167 }
04168
04169
04170 int update_policies(char* kasp_filename)
04171 {
04172 int status;
04173
04174
04175 char *policy_name = NULL;
04176 char *policy_description = NULL;
04177
04178
04179 xmlDocPtr doc = NULL;
04180 xmlDocPtr pol_doc = NULL;
04181 xmlDocPtr rngdoc = NULL;
04182 xmlNode *curNode;
04183 xmlNode *childNode;
04184 xmlNode *childNode2;
04185 xmlNode *childNode3;
04186 xmlChar *opt_out_flag = (xmlChar *)"N";
04187 xmlChar *share_keys_flag = (xmlChar *)"N";
04188 xmlChar *man_roll_flag = (xmlChar *)"N";
04189 xmlChar *rfc5011_flag = (xmlChar *)"N";
04190 int standby_keys_flag = 0;
04191 xmlXPathContextPtr xpathCtx = NULL;
04192 xmlXPathObjectPtr xpathObj = NULL;
04193 xmlRelaxNGParserCtxtPtr rngpctx = NULL;
04194 xmlRelaxNGValidCtxtPtr rngctx = NULL;
04195 xmlRelaxNGPtr schema = NULL;
04196 int i = 0;
04197
04198 xmlChar *node_expr = (unsigned char*) "//Policy";
04199
04200
04201
04202 int audit_found = 0;
04203
04204 KSM_POLICY *policy;
04205
04206
04207 const char* rngfilename = OPENDNSSEC_SCHEMA_DIR "/kasp.rng";
04208 char* kaspcheck_cmd = NULL;
04209 char* kaspcheck_cmd_version = NULL;
04210
04211 StrAppend(&kaspcheck_cmd, ODS_AU_KASPCHECK);
04212 StrAppend(&kaspcheck_cmd, " -k ");
04213 StrAppend(&kaspcheck_cmd, kasp_filename);
04214
04215 StrAppend(&kaspcheck_cmd_version, ODS_AU_KASPCHECK);
04216 StrAppend(&kaspcheck_cmd_version, " -v > /dev/null");
04217
04218
04219 status = system(kaspcheck_cmd_version);
04220 if (status == 0)
04221 {
04222 status = system(kaspcheck_cmd);
04223 if (status != 0)
04224 {
04225 fprintf(stderr, "ods-kaspcheck returned an error, please check your policy\n");
04226 StrFree(kaspcheck_cmd);
04227 StrFree(kaspcheck_cmd_version);
04228 return(-1);
04229 }
04230 }
04231 else
04232 {
04233 fprintf(stderr, "Couldn't run ods-kaspcheck (Auditor is not installed), will carry on\n");
04234 }
04235
04236 StrFree(kaspcheck_cmd);
04237 StrFree(kaspcheck_cmd_version);
04238
04239
04240 doc = xmlParseFile(kasp_filename);
04241 if (doc == NULL) {
04242 printf("Error: unable to parse file \"%s\"\n", kasp_filename);
04243 return(-1);
04244 }
04245
04246
04247 rngdoc = xmlParseFile(rngfilename);
04248 if (rngdoc == NULL) {
04249 printf("Error: unable to parse file \"%s\"\n", rngfilename);
04250 return(-1);
04251 }
04252
04253
04254 rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc);
04255 if (rngpctx == NULL) {
04256 printf("Error: unable to create XML RelaxNGs parser context\n");
04257 return(-1);
04258 }
04259
04260
04261 schema = xmlRelaxNGParse(rngpctx);
04262 if (schema == NULL) {
04263 printf("Error: unable to parse a schema definition resource\n");
04264 return(-1);
04265 }
04266
04267
04268 rngctx = xmlRelaxNGNewValidCtxt(schema);
04269 if (rngctx == NULL) {
04270 printf("Error: unable to create RelaxNGs validation context based on the schema\n");
04271 return(-1);
04272 }
04273
04274
04275 status = xmlRelaxNGValidateDoc(rngctx,doc);
04276 if (status != 0) {
04277 printf("Error validating file \"%s\"\n", kasp_filename);
04278 return(-1);
04279 }
04280
04281
04282 policy = KsmPolicyAlloc();
04283 if (policy == NULL) {
04284 printf("Malloc for policy struct failed");
04285 exit(1);
04286 }
04287
04288
04289 xpathCtx = xmlXPathNewContext(doc);
04290 if(xpathCtx == NULL) {
04291 xmlFreeDoc(doc);
04292 KsmPolicyFree(policy);
04293 return(1);
04294 }
04295
04296
04297 xpathObj = xmlXPathEvalExpression(node_expr, xpathCtx);
04298 if(xpathObj == NULL) {
04299 xmlXPathFreeContext(xpathCtx);
04300 xmlFreeDoc(doc);
04301 KsmPolicyFree(policy);
04302 return(1);
04303 }
04304
04305 if (xpathObj->nodesetval) {
04306 for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
04307
04308 curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
04309 policy_name = (char *) xmlGetProp(xpathObj->nodesetval->nodeTab[i], (const xmlChar *)"name");
04310 if (strlen(policy_name) == 0) {
04311
04312 printf("Error extracting policy name from %s\n", kasp_filename);
04313 break;
04314 }
04315 audit_found = 0;
04316
04317 printf("Policy %s found\n", policy_name);
04318 while (curNode) {
04319 if (xmlStrEqual(curNode->name, (const xmlChar *)"Description")) {
04320 policy_description = (char *) xmlNodeGetContent(curNode);
04321
04322
04323
04324 SetPolicyDefaults(policy, policy_name);
04325 status = KsmPolicyExists(policy_name);
04326 if (status == 0) {
04327
04328 status = KsmPolicyRead(policy);
04329 if(status != 0) {
04330 printf("Error: unable to read policy %s; skipping\n", policy_name);
04331 curNode = curNode->next;
04332 break;
04333 }
04334
04335 }
04336 else {
04337
04338 status = KsmImportPolicy(policy_name, policy_description);
04339 if(status != 0) {
04340 printf("Error: unable to insert policy %s; skipping\n", policy_name);
04341
04342 continue;
04343 }
04344 status = KsmPolicySetIdFromName(policy);
04345
04346 if (status != 0) {
04347 printf("Error: unable to get policy id for %s; skipping\n", policy_name);
04348 continue;
04349 }
04350 }
04351 }
04352
04353 else if (xmlStrEqual(curNode->name, (const xmlChar *)"Signatures")) {
04354 childNode = curNode->children;
04355 while (childNode){
04356 if (xmlStrEqual(childNode->name, (const xmlChar *)"Resign")) {
04357 SetParamOnPolicy(xmlNodeGetContent(childNode), "resign", "signature", policy->signature->resign, policy->id, DURATION_TYPE);
04358 }
04359 else if (xmlStrEqual(childNode->name, (const xmlChar *)"Refresh")) {
04360 SetParamOnPolicy(xmlNodeGetContent(childNode), "refresh", "signature", policy->signer->refresh, policy->id, DURATION_TYPE);
04361 }
04362 else if (xmlStrEqual(childNode->name, (const xmlChar *)"Validity")) {
04363 childNode2 = childNode->children;
04364 while (childNode2){
04365 if (xmlStrEqual(childNode2->name, (const xmlChar *)"Default")) {
04366 SetParamOnPolicy(xmlNodeGetContent(childNode2), "valdefault", "signature", policy->signature->valdefault, policy->id, DURATION_TYPE);
04367 }
04368 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Denial")) {
04369 SetParamOnPolicy(xmlNodeGetContent(childNode2), "valdenial", "signature", policy->signature->valdenial, policy->id, DURATION_TYPE);
04370 }
04371 childNode2 = childNode2->next;
04372 }
04373 }
04374 else if (xmlStrEqual(childNode->name, (const xmlChar *)"Jitter")) {
04375 SetParamOnPolicy(xmlNodeGetContent(childNode), "jitter", "signature", policy->signer->jitter, policy->id, DURATION_TYPE);
04376 }
04377 else if (xmlStrEqual(childNode->name, (const xmlChar *)"InceptionOffset")) {
04378 SetParamOnPolicy(xmlNodeGetContent(childNode), "clockskew", "signature", policy->signature->clockskew, policy->id, DURATION_TYPE);
04379 }
04380 childNode = childNode->next;
04381 }
04382 }
04383 else if (xmlStrEqual(curNode->name, (const xmlChar *)"Denial")) {
04384 opt_out_flag = (xmlChar *)"N";
04385 childNode = curNode->children;
04386 while (childNode){
04387 if (xmlStrEqual(childNode->name, (const xmlChar *)"NSEC3")) {
04388
04389 status = KsmParameterSet("version", "denial", 3, policy->id);
04390 if (status != 0) {
04391 printf("Error: unable to insert/update %s for policy\n", "Denial version");
04392 }
04393 childNode2 = childNode->children;
04394 while (childNode2){
04395 if (xmlStrEqual(childNode2->name, (const xmlChar *)"OptOut")) {
04396 opt_out_flag = (xmlChar *)"Y";
04397 }
04398 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Resalt")) {
04399 SetParamOnPolicy(xmlNodeGetContent(childNode2), "resalt", "denial", policy->denial->resalt, policy->id, DURATION_TYPE);
04400 }
04401 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Hash")) {
04402 childNode3 = childNode2->children;
04403 while (childNode3){
04404 if (xmlStrEqual(childNode3->name, (const xmlChar *)"Algorithm")) {
04405 SetParamOnPolicy(xmlNodeGetContent(childNode3), "algorithm", "denial", policy->denial->algorithm, policy->id, INT_TYPE);
04406 }
04407 else if (xmlStrEqual(childNode3->name, (const xmlChar *)"Iterations")) {
04408 SetParamOnPolicy(xmlNodeGetContent(childNode3), "iterations", "denial", policy->denial->iteration, policy->id, INT_TYPE);
04409 }
04410 else if (xmlStrEqual(childNode3->name, (const xmlChar *)"Salt")) {
04411 SetParamOnPolicy(xmlGetProp(childNode3, (const xmlChar *)"length"), "saltlength", "denial", policy->denial->saltlength, policy->id, INT_TYPE);
04412 }
04413 childNode3 = childNode3->next;
04414 }
04415 }
04416
04417 childNode2 = childNode2->next;
04418 }
04419
04420 SetParamOnPolicy(opt_out_flag, "optout", "denial", policy->denial->optout, policy->id, BOOL_TYPE);
04421 }
04422 else if (xmlStrEqual(childNode->name, (const xmlChar *)"NSEC")) {
04423 status = KsmParameterSet("version", "denial", 1, policy->id);
04424 if (status != 0) {
04425 printf("Error: unable to insert/update %s for policy\n", "Denial version");
04426 }
04427 }
04428 childNode = childNode->next;
04429 }
04430 }
04431 else if (xmlStrEqual(curNode->name, (const xmlChar *)"Keys")) {
04432 share_keys_flag = (xmlChar *)"N";
04433 childNode = curNode->children;
04434 while (childNode){
04435 if (xmlStrEqual(childNode->name, (const xmlChar *)"TTL")) {
04436 SetParamOnPolicy(xmlNodeGetContent(childNode), "ttl", "keys", policy->keys->ttl, policy->id, DURATION_TYPE);
04437 }
04438 else if (xmlStrEqual(childNode->name, (const xmlChar *)"RetireSafety")) {
04439 SetParamOnPolicy(xmlNodeGetContent(childNode), "retiresafety", "keys", policy->keys->retire_safety, policy->id, DURATION_TYPE);
04440 }
04441 else if (xmlStrEqual(childNode->name, (const xmlChar *)"PublishSafety")) {
04442 SetParamOnPolicy(xmlNodeGetContent(childNode), "publishsafety", "keys", policy->keys->publish_safety, policy->id, DURATION_TYPE);
04443 }
04444 else if (xmlStrEqual(childNode->name, (const xmlChar *)"ShareKeys")) {
04445 share_keys_flag = (xmlChar *)"Y";
04446 }
04447 else if (xmlStrEqual(childNode->name, (const xmlChar *)"Purge")) {
04448 SetParamOnPolicy(xmlNodeGetContent(childNode), "purge", "keys", policy->keys->purge, policy->id, DURATION_TYPE);
04449 }
04450
04451 else if (xmlStrEqual(childNode->name, (const xmlChar *)"KSK")) {
04452 man_roll_flag = (xmlChar *)"N";
04453 rfc5011_flag = (xmlChar *)"N";
04454 childNode2 = childNode->children;
04455 while (childNode2){
04456 if (xmlStrEqual(childNode2->name, (const xmlChar *)"Algorithm")) {
04457 SetParamOnPolicy(xmlNodeGetContent(childNode2), "algorithm", "ksk", policy->ksk->algorithm, policy->id, INT_TYPE);
04458 SetParamOnPolicy(xmlGetProp(childNode2, (const xmlChar *)"length"), "bits", "ksk", policy->ksk->bits, policy->id, INT_TYPE);
04459
04460 }
04461 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Lifetime")) {
04462 SetParamOnPolicy(xmlNodeGetContent(childNode2), "lifetime", "ksk", policy->ksk->lifetime, policy->id, DURATION_TYPE);
04463 }
04464 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Repository")) {
04465 if (SetParamOnPolicy(xmlNodeGetContent(childNode2), "repository", "ksk", policy->ksk->sm, policy->id, REPO_TYPE) != 0) {
04466 printf("Please either add the repository to conf.xml or remove the reference to it from kasp.xml\n");
04467
04468 xmlFreeDoc(pol_doc);
04469 xmlXPathFreeContext(xpathCtx);
04470 xmlRelaxNGFree(schema);
04471 xmlRelaxNGFreeValidCtxt(rngctx);
04472 xmlRelaxNGFreeParserCtxt(rngpctx);
04473 xmlFreeDoc(doc);
04474 xmlFreeDoc(rngdoc);
04475 KsmPolicyFree(policy);
04476
04477 return(1);
04478 }
04479 }
04480 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Standby")) {
04481 SetParamOnPolicy(xmlNodeGetContent(childNode2), "standby", "ksk", policy->ksk->standby_keys, policy->id, INT_TYPE);
04482 standby_keys_flag = 1;
04483 }
04484 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"ManualRollover")) {
04485 man_roll_flag = (xmlChar *)"Y";
04486 }
04487 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"RFC5011")) {
04488 rfc5011_flag = (xmlChar *)"Y";
04489 }
04490
04491
04492
04493 childNode2 = childNode2->next;
04494 }
04495
04496 SetParamOnPolicy(man_roll_flag, "manual_rollover", "ksk", policy->ksk->manual_rollover, policy->id, BOOL_TYPE);
04497 SetParamOnPolicy(rfc5011_flag, "rfc5011", "ksk", policy->ksk->rfc5011, policy->id, BOOL_TYPE);
04498 if (standby_keys_flag == 0) {
04499 SetParamOnPolicy((xmlChar *)"0", "standby", "ksk", policy->ksk->standby_keys, policy->id, INT_TYPE_NO_FREE);
04500 } else {
04501 standby_keys_flag = 0;
04502 }
04503 }
04504
04505 else if (xmlStrEqual(childNode->name, (const xmlChar *)"ZSK")) {
04506 man_roll_flag = (xmlChar *)"N";
04507 childNode2 = childNode->children;
04508 while (childNode2){
04509 if (xmlStrEqual(childNode2->name, (const xmlChar *)"Algorithm")) {
04510 SetParamOnPolicy(xmlNodeGetContent(childNode2), "algorithm", "zsk", policy->zsk->algorithm, policy->id, INT_TYPE);
04511 SetParamOnPolicy(xmlGetProp(childNode2, (const xmlChar *)"length"), "bits", "zsk", policy->zsk->bits, policy->id, INT_TYPE);
04512
04513 }
04514 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Lifetime")) {
04515 SetParamOnPolicy(xmlNodeGetContent(childNode2), "lifetime", "zsk", policy->zsk->lifetime, policy->id, DURATION_TYPE);
04516 }
04517 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Repository")) {
04518 if (SetParamOnPolicy(xmlNodeGetContent(childNode2), "repository", "zsk", policy->zsk->sm, policy->id, REPO_TYPE) != 0) {
04519 printf("Please either add the repository to conf.xml or remove the reference to it from kasp.xml\n");
04520
04521 xmlFreeDoc(pol_doc);
04522 xmlXPathFreeContext(xpathCtx);
04523 xmlRelaxNGFree(schema);
04524 xmlRelaxNGFreeValidCtxt(rngctx);
04525 xmlRelaxNGFreeParserCtxt(rngpctx);
04526 xmlFreeDoc(doc);
04527 xmlFreeDoc(rngdoc);
04528 KsmPolicyFree(policy);
04529
04530 return(1);
04531 }
04532 }
04533 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Standby")) {
04534 SetParamOnPolicy(xmlNodeGetContent(childNode2), "standby", "zsk", policy->zsk->standby_keys, policy->id, INT_TYPE);
04535 standby_keys_flag = 1;
04536 }
04537 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"ManualRollover")) {
04538 man_roll_flag = (xmlChar *)"Y";
04539 }
04540 childNode2 = childNode2->next;
04541 }
04542
04543 SetParamOnPolicy(man_roll_flag, "manual_rollover", "zsk", policy->zsk->manual_rollover, policy->id, BOOL_TYPE);
04544 }
04545
04546 childNode = childNode->next;
04547 }
04548
04549 SetParamOnPolicy(share_keys_flag, "zones_share_keys", "keys", policy->keys->share_keys, policy->id, BOOL_TYPE);
04550 if (standby_keys_flag == 0) {
04551 SetParamOnPolicy((xmlChar *)"0", "standby", "zsk", policy->zsk->standby_keys, policy->id, INT_TYPE_NO_FREE);
04552 } else {
04553 standby_keys_flag = 0;
04554 }
04555
04556 }
04557
04558 else if (xmlStrEqual(curNode->name, (const xmlChar *)"Zone")) {
04559 childNode = curNode->children;
04560 while (childNode){
04561 if (xmlStrEqual(childNode->name, (const xmlChar *)"PropagationDelay")) {
04562 SetParamOnPolicy(xmlNodeGetContent(childNode), "propagationdelay", "zone", policy->zone->propdelay, policy->id, DURATION_TYPE);
04563 }
04564 else if (xmlStrEqual(childNode->name, (const xmlChar *)"SOA")) {
04565 childNode2 = childNode->children;
04566 while (childNode2){
04567 if (xmlStrEqual(childNode2->name, (const xmlChar *)"TTL")) {
04568 SetParamOnPolicy(xmlNodeGetContent(childNode2), "ttl", "zone", policy->zone->soa_ttl, policy->id, DURATION_TYPE);
04569 }
04570 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Minimum")) {
04571 SetParamOnPolicy(xmlNodeGetContent(childNode2), "min", "zone", policy->zone->soa_min, policy->id, DURATION_TYPE);
04572 }
04573 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Serial")) {
04574 SetParamOnPolicy(xmlNodeGetContent(childNode2), "serial", "zone", policy->zone->serial, policy->id, SERIAL_TYPE);
04575 }
04576 childNode2 = childNode2->next;
04577 }
04578 }
04579 childNode = childNode->next;
04580 }
04581 }
04582
04583 else if (xmlStrEqual(curNode->name, (const xmlChar *)"Parent")) {
04584 childNode = curNode->children;
04585 while (childNode){
04586 if (xmlStrEqual(childNode->name, (const xmlChar *)"PropagationDelay")) {
04587 SetParamOnPolicy(xmlNodeGetContent(childNode), "propagationdelay", "parent", policy->parent->propdelay, policy->id, DURATION_TYPE);
04588 }
04589 else if (xmlStrEqual(childNode->name, (const xmlChar *)"DS")) {
04590 childNode2 = childNode->children;
04591 while (childNode2){
04592 if (xmlStrEqual(childNode2->name, (const xmlChar *)"TTL")) {
04593 SetParamOnPolicy(xmlNodeGetContent(childNode2), "ttlds", "parent", policy->parent->ds_ttl, policy->id, DURATION_TYPE);
04594 }
04595 childNode2 = childNode2->next;
04596 }
04597 }
04598 else if (xmlStrEqual(childNode->name, (const xmlChar *)"SOA")) {
04599 childNode2 = childNode->children;
04600 while (childNode2){
04601 if (xmlStrEqual(childNode2->name, (const xmlChar *)"TTL")) {
04602 SetParamOnPolicy(xmlNodeGetContent(childNode2), "ttl", "parent", policy->parent->soa_ttl, policy->id, DURATION_TYPE);
04603 }
04604 else if (xmlStrEqual(childNode2->name, (const xmlChar *)"Minimum")) {
04605 SetParamOnPolicy(xmlNodeGetContent(childNode2), "min", "parent", policy->parent->soa_min, policy->id, DURATION_TYPE);
04606 }
04607 childNode2 = childNode2->next;
04608 }
04609 }
04610 childNode = childNode->next;
04611 }
04612 }
04613
04614 else if (xmlStrEqual(curNode->name, (const xmlChar *)"Audit")) {
04615 status = KsmImportAudit(policy->id, "");
04616 childNode = curNode->children;
04617 while (childNode){
04618 if (xmlStrEqual(childNode->name, (const xmlChar *)"Partial")) {
04619 status = KsmImportAudit(policy->id, "<Partial/>");
04620 }
04621 childNode = childNode->next;
04622 }
04623 audit_found = 1;
04624 if(status != 0) {
04625 printf("Error: unable to insert Audit info for policy %s\n", policy->name);
04626 }
04627 }
04628
04629 curNode = curNode->next;
04630 }
04631
04632 if (audit_found == 0) {
04633 status = KsmImportAudit(policy->id, "NULL");
04634 }
04635
04636
04637 StrFree(policy_name);
04638 StrFree(policy_description);
04639
04640 }
04641 }
04642
04643
04644 xmlXPathFreeContext(xpathCtx);
04645 xmlRelaxNGFree(schema);
04646 xmlRelaxNGFreeValidCtxt(rngctx);
04647 xmlRelaxNGFreeParserCtxt(rngpctx);
04648 xmlFreeDoc(doc);
04649 xmlFreeDoc(rngdoc);
04650 KsmPolicyFree(policy);
04651
04652 return(status);
04653 }
04654
04655
04656 int update_zones(char* zone_list_filename)
04657 {
04658 int status = 0;
04659 xmlTextReaderPtr reader = NULL;
04660 xmlDocPtr doc = NULL;
04661 xmlXPathContextPtr xpathCtx = NULL;
04662 xmlXPathObjectPtr xpathObj = NULL;
04663 int ret = 0;
04664 char* zone_name = NULL;
04665 char* policy_name = NULL;
04666 char* current_policy = NULL;
04667 char* current_signconf = NULL;
04668 char* current_input = NULL;
04669 char* current_output = NULL;
04670 char* temp_char = NULL;
04671 char* tag_name = NULL;
04672 int policy_id = 0;
04673 int new_zone = 0;
04674 int file_zone_count = 0;
04675 int db_zone_count = 0;
04676 int* zone_ids;
04677 int temp_id;
04678
04679 char* sql = NULL;
04680 DB_RESULT result;
04681 DB_RESULT result2;
04682 DB_RESULT result3;
04683 DB_ROW row = NULL;
04684 KSM_PARAMETER shared;
04685 int seen_zone = 0;
04686 int temp_count = 0;
04687 int i = 0;
04688
04689 xmlChar *name_expr = (unsigned char*) "name";
04690 xmlChar *policy_expr = (unsigned char*) "//Zone/Policy";
04691 xmlChar *signconf_expr = (unsigned char*) "//Zone/SignerConfiguration";
04692 xmlChar *input_expr = (unsigned char*) "//Zone/Adapters/Input/File";
04693 xmlChar *output_expr = (unsigned char*) "//Zone/Adapters/Output/File";
04694
04695
04696
04697 reader = xmlNewTextReaderFilename(zone_list_filename);
04698 if (reader != NULL) {
04699 ret = xmlTextReaderRead(reader);
04700 while (ret == 1) {
04701 tag_name = (char*) xmlTextReaderLocalName(reader);
04702
04703 if (strncmp(tag_name, "Zone", 4) == 0
04704 && strncmp(tag_name, "ZoneList", 8) != 0
04705 && xmlTextReaderNodeType(reader) == 1) {
04706 file_zone_count++;
04707 }
04708
04709 ret = xmlTextReaderRead(reader);
04710 StrFree(tag_name);
04711 }
04712 xmlFreeTextReader(reader);
04713 if (ret != 0) {
04714 printf("%s : failed to parse\n", zone_list_filename);
04715 }
04716 } else {
04717 printf("Unable to open %s\n", zone_list_filename);
04718 }
04719
04720
04721 zone_ids = MemMalloc(file_zone_count * sizeof(int));
04722
04723
04724 reader = xmlNewTextReaderFilename(zone_list_filename);
04725 if (reader != NULL) {
04726 ret = xmlTextReaderRead(reader);
04727 while (ret == 1) {
04728 tag_name = (char*) xmlTextReaderLocalName(reader);
04729
04730 if (strncmp(tag_name, "Zone", 4) == 0
04731 && strncmp(tag_name, "ZoneList", 8) != 0
04732 && xmlTextReaderNodeType(reader) == 1) {
04733
04734 zone_name = NULL;
04735 temp_char = (char*) xmlTextReaderGetAttribute(reader, name_expr);
04736 StrAppend(&zone_name, temp_char);
04737 StrFree(temp_char);
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749 if (zone_name == NULL) {
04750
04751 printf("Error extracting zone name from %s\n", zone_list_filename);
04752
04753 ret = xmlTextReaderRead(reader);
04754 continue;
04755 }
04756
04757 printf("Zone %s found\n", zone_name);
04758
04759
04760 xmlTextReaderExpand(reader);
04761 doc = xmlTextReaderCurrentDoc(reader);
04762 if (doc == NULL) {
04763 printf("Error: can not read zone \"%s\"; skipping\n", zone_name);
04764
04765 ret = xmlTextReaderRead(reader);
04766 continue;
04767 }
04768
04769 xpathCtx = xmlXPathNewContext(doc);
04770 if(xpathCtx == NULL) {
04771 printf("Error: can not create XPath context for \"%s\"; skipping zone\n", zone_name);
04772
04773 ret = xmlTextReaderRead(reader);
04774 continue;
04775 }
04776
04777
04778
04779 xpathObj = xmlXPathEvalExpression(policy_expr, xpathCtx);
04780 if(xpathObj == NULL) {
04781 printf("Error: unable to evaluate xpath expression: %s; skipping zone\n", policy_expr);
04782
04783 ret = xmlTextReaderRead(reader);
04784 continue;
04785 }
04786
04787 current_policy = NULL;
04788 temp_char = (char *)xmlXPathCastToString(xpathObj);
04789 StrAppend(¤t_policy, temp_char);
04790 StrFree(temp_char);
04791 printf("Policy set to %s.\n", current_policy);
04792 xmlXPathFreeObject(xpathObj);
04793
04794
04795 if (policy_name == NULL || strcmp(current_policy, policy_name) != 0) {
04796 StrFree(policy_name);
04797 StrAppend(&policy_name, current_policy);
04798
04799 status = KsmPolicyIdFromName(policy_name, &policy_id);
04800 if (status != 0) {
04801 printf("Error, can't find policy : %s\n", policy_name);
04802
04803 ret = xmlTextReaderRead(reader);
04804 continue;
04805 }
04806 }
04807
04808
04809
04810 xpathObj = xmlXPathEvalExpression(signconf_expr, xpathCtx);
04811 if(xpathObj == NULL) {
04812 printf("Error: unable to evaluate xpath expression: %s; skipping zone\n", signconf_expr);
04813
04814 ret = xmlTextReaderRead(reader);
04815 continue;
04816 }
04817
04818 current_signconf = NULL;
04819 temp_char = (char *)xmlXPathCastToString(xpathObj);
04820 StrAppend(¤t_signconf, temp_char);
04821 StrFree(temp_char);
04822 xmlXPathFreeObject(xpathObj);
04823
04824
04825
04826 xpathObj = xmlXPathEvalExpression(input_expr, xpathCtx);
04827 if(xpathObj == NULL) {
04828 printf("Error: unable to evaluate xpath expression: %s; skipping zone\n", input_expr);
04829
04830 ret = xmlTextReaderRead(reader);
04831 continue;
04832 }
04833
04834 current_input = NULL;
04835 temp_char = (char *)xmlXPathCastToString(xpathObj);
04836 StrAppend(¤t_input, temp_char);
04837 StrFree(temp_char);
04838 xmlXPathFreeObject(xpathObj);
04839
04840
04841
04842 xpathObj = xmlXPathEvalExpression(output_expr, xpathCtx);
04843 xmlXPathFreeContext(xpathCtx);
04844 if(xpathObj == NULL) {
04845 printf("Error: unable to evaluate xpath expression: %s; skipping zone\n", output_expr);
04846
04847 ret = xmlTextReaderRead(reader);
04848 continue;
04849 }
04850
04851 current_output = NULL;
04852 temp_char = (char *)xmlXPathCastToString(xpathObj);
04853 StrAppend(¤t_output, temp_char);
04854 StrFree(temp_char);
04855 xmlXPathFreeObject(xpathObj);
04856
04857
04858
04859
04860 status = KsmImportZone(zone_name, policy_id, 0, &new_zone, current_signconf, current_input, current_output);
04861 if (status != 0) {
04862 if (status == -3) {
04863 printf("Error Importing zone %s; it already exists both with and without a trailing dot\n", zone_name);
04864 } else {
04865 printf("Error Importing Zone %s\n", zone_name);
04866 }
04867
04868 ret = xmlTextReaderRead(reader);
04869 continue;
04870 }
04871
04872
04873 if (new_zone == 1) {
04874 printf("Added zone %s to database\n", zone_name);
04875
04876
04877
04878
04879
04880
04881
04882
04883 }
04884
04885
04886 status = KsmZoneIdFromName(zone_name, &temp_id);
04887 if (status != 0) {
04888 printf("Error: unable to find a zone named \"%s\" in database\n", zone_name);
04889 printf("Error: Possibly two domains differ only by having a trailing dot or not?\n");
04890 StrFree(zone_ids);
04891 return(status);
04892 }
04893
04894
04895 zone_ids[i] = temp_id;
04896 i++;
04897
04898 StrFree(zone_name);
04899 StrFree(current_policy);
04900 StrFree(current_signconf);
04901 StrFree(current_input);
04902 StrFree(current_output);
04903
04904 new_zone = 0;
04905
04906 }
04907
04908 ret = xmlTextReaderRead(reader);
04909 StrFree(tag_name);
04910 }
04911 xmlFreeTextReader(reader);
04912 if (ret != 0) {
04913 printf("%s : failed to parse\n", zone_list_filename);
04914 }
04915 } else {
04916 printf("Unable to open %s\n", zone_list_filename);
04917 }
04918 if (doc) {
04919 xmlFreeDoc(doc);
04920 }
04921 StrFree(policy_name);
04922
04923
04924 sql = DqsCountInit(DB_ZONE_TABLE);
04925 DqsEnd(&sql);
04926
04927
04928 status = DbIntQuery(DbHandle(), &db_zone_count, sql);
04929 DqsFree(sql);
04930
04931
04932 if (file_zone_count == db_zone_count) {
04933 StrFree(zone_ids);
04934 return 0;
04935 }
04936
04937 else if (file_zone_count > db_zone_count) {
04938 printf("Failed to add all zones from zonelist\n");
04939 StrFree(zone_ids);
04940 return(1);
04941 }
04942
04943
04944
04945
04946 sql = DqsSpecifyInit(DB_ZONE_TABLE, "id, name, policy_id");
04947 DqsOrderBy(&sql, "ID");
04948 DqsEnd(&sql);
04949
04950 status = DbExecuteSql(DbHandle(), sql, &result);
04951
04952 if (status == 0) {
04953 status = DbFetchRow(result, &row);
04954 while (status == 0) {
04955 DbInt(row, 0, &temp_id);
04956 DbString(row, 1, &zone_name);
04957 DbInt(row, 2, &policy_id);
04958
04959 seen_zone = 0;
04960 for (i = 0; i < db_zone_count; ++i) {
04961 if (temp_id == zone_ids[i]) {
04962 seen_zone = 1;
04963 break;
04964 }
04965 }
04966
04967 if (seen_zone == 0) {
04968
04969
04970 printf("Removing zone %s from database\n", zone_name);
04971
04972 status = KsmParameterInit(&result2, "zones_share_keys", "keys", policy_id);
04973 if (status != 0) {
04974 DbFreeRow(row);
04975 DbStringFree(zone_name);
04976 StrFree(zone_ids);
04977 return(status);
04978 }
04979 status = KsmParameter(result2, &shared);
04980 if (status != 0) {
04981 DbFreeRow(row);
04982 DbStringFree(zone_name);
04983 StrFree(zone_ids);
04984 return(status);
04985 }
04986 KsmParameterEnd(result2);
04987
04988
04989 status = KsmZoneCountInit(&result3, policy_id);
04990 if (status == 0) {
04991 status = KsmZoneCount(result3, &temp_count);
04992 }
04993 DbFreeResult(result3);
04994
04995
04996 if ((shared.value == 1 && temp_count == 1) || shared.value == 0) {
04997 status = KsmMarkKeysAsDead(temp_id);
04998 if (status != 0) {
04999 printf("Error: failed to mark keys as dead in database\n");
05000 StrFree(zone_ids);
05001 return(status);
05002 }
05003 }
05004
05005
05006 status = KsmDeleteZone(temp_id);
05007 }
05008
05009 status = DbFetchRow(result, &row);
05010 }
05011
05012
05013 if (status == -1) {
05014 status = 0;
05015 }
05016 DbFreeResult(result);
05017 }
05018
05019 DusFree(sql);
05020 DbFreeRow(row);
05021 DbStringFree(zone_name);
05022 StrFree(zone_ids);
05023
05024 return 0;
05025 }
05026
05027
05028
05029
05030
05031
05032
05033 int SetParamOnPolicy(const xmlChar* new_value, const char* name, const char* category, int current_value, int policy_id, int value_type)
05034 {
05035 int status = 0;
05036 int value = 0;
05037 char* temp_char = (char *)new_value;
05038
05039
05040 if (value_type == DURATION_TYPE) {
05041 if (strlen(temp_char) != 0) {
05042 status = DtXMLIntervalSeconds(temp_char, &value);
05043 if (status > 0) {
05044 printf("Error: unable to convert interval %s to seconds, error: %i\n", temp_char, status);
05045 StrFree(temp_char);
05046 return status;
05047 }
05048 else if (status == -1) {
05049 printf("Info: converting %s to seconds; M interpreted as 31 days, Y interpreted as 365 days\n", temp_char);
05050 }
05051 StrFree(temp_char);
05052 } else {
05053 value = -1;
05054 }
05055 }
05056 else if (value_type == BOOL_TYPE) {
05057
05058 if (strncmp(temp_char, "Y", 1) == 0) {
05059 value = 1;
05060 } else {
05061 value = 0;
05062 }
05063 }
05064 else if (value_type == REPO_TYPE) {
05065
05066 status = KsmSmIdFromName(temp_char, &value);
05067 if (status != 0) {
05068 printf("Error: unable to find repository %s\n", temp_char);
05069 StrFree(temp_char);
05070 return status;
05071 }
05072 StrFree(temp_char);
05073 }
05074 else if (value_type == SERIAL_TYPE) {
05075
05076 status = KsmSerialIdFromName(temp_char, &value);
05077 if (status != 0) {
05078 printf("Error: unable to find serial type %s\n", temp_char);
05079 StrFree(temp_char);
05080 return status;
05081 }
05082 StrFree(temp_char);
05083 }
05084 else if (value_type == ROLLOVER_TYPE) {
05085
05086 value = KsmKeywordRollNameToValue(temp_char);
05087 if (value == 0) {
05088 printf("Error: unable to find rollover scheme %s\n", temp_char);
05089 StrFree(temp_char);
05090 return status;
05091 }
05092 StrFree(temp_char);
05093 }
05094 else {
05095 status = StrStrtoi(temp_char, &value);
05096 if (status != 0) {
05097 printf("Error: unable to convert %s to int\n", temp_char);
05098 StrFree(temp_char);
05099 return status;
05100 }
05101 if (value_type != INT_TYPE_NO_FREE) {
05102 StrFree(temp_char);
05103 }
05104 }
05105
05106
05107 if (value != current_value || current_value == 0) {
05108 status = KsmParameterSet(name, category, value, policy_id);
05109 if (status != 0) {
05110 printf("Error: unable to insert/update %s for policy\n", name);
05111 printf("Error: Is your database schema up to date?\n");
05112 return status;
05113 }
05114
05115
05116
05117 if (strncmp(name, "saltlength", 10) == 0) {
05118 status = KsmPolicyNullSaltStamp(policy_id);
05119 if (status != 0) {
05120 printf("Error: unable to insert/update %s for policy\n", name);
05121 printf("Error: Is your database schema up to date?\n");
05122 return status;
05123 }
05124 }
05125 }
05126
05127 return 0;
05128 }
05129
05130 void SetPolicyDefaults(KSM_POLICY *policy, char *name)
05131 {
05132 if (policy == NULL) {
05133 printf("Error, no policy provided");
05134 return;
05135 }
05136
05137 if (name) {
05138 snprintf(policy->name, KSM_NAME_LENGTH, "%s", name);
05139 }
05140
05141 policy->signer->refresh = 0;
05142 policy->signer->jitter = 0;
05143 policy->signer->propdelay = 0;
05144 policy->signer->soamin = 0;
05145 policy->signer->soattl = 0;
05146 policy->signer->serial = 0;
05147
05148 policy->signature->clockskew = 0;
05149 policy->signature->resign = 0;
05150 policy->signature->valdefault = 0;
05151 policy->signature->valdenial = 0;
05152
05153 policy->denial->version = 0;
05154 policy->denial->resalt = 0;
05155 policy->denial->algorithm = 0;
05156 policy->denial->iteration = 0;
05157 policy->denial->optout = 0;
05158 policy->denial->ttl = 0;
05159 policy->denial->saltlength = 0;
05160
05161 policy->keys->ttl = 0;
05162 policy->keys->retire_safety = 0;
05163 policy->keys->publish_safety = 0;
05164 policy->keys->share_keys = 0;
05165 policy->keys->purge = -1;
05166
05167 policy->ksk->algorithm = 0;
05168 policy->ksk->bits = 0;
05169 policy->ksk->lifetime = 0;
05170 policy->ksk->sm = 0;
05171 policy->ksk->overlap = 0;
05172 policy->ksk->ttl = 0;
05173 policy->ksk->rfc5011 = 0;
05174 policy->ksk->type = KSM_TYPE_KSK;
05175 policy->ksk->standby_keys = 0;
05176 policy->ksk->manual_rollover = 0;
05177 policy->ksk->rollover_scheme = KSM_ROLL_DEFAULT;
05178
05179 policy->zsk->algorithm = 0;
05180 policy->zsk->bits = 0;
05181 policy->zsk->lifetime = 0;
05182 policy->zsk->sm = 0;
05183 policy->zsk->overlap = 0;
05184 policy->zsk->ttl = 0;
05185 policy->zsk->rfc5011 = 0;
05186 policy->zsk->type = KSM_TYPE_ZSK;
05187 policy->zsk->standby_keys = 0;
05188 policy->zsk->manual_rollover = 0;
05189 policy->zsk->rollover_scheme = 0;
05190
05191 policy->enforcer->keycreate = 0;
05192 policy->enforcer->backup_interval = 0;
05193 policy->enforcer->keygeninterval = 0;
05194
05195 policy->zone->propdelay = 0;
05196 policy->zone->soa_ttl = 0;
05197 policy->zone->soa_min = 0;
05198 policy->zone->serial = 0;
05199
05200 policy->parent->propdelay = 0;
05201 policy->parent->ds_ttl = 0;
05202 policy->parent->soa_ttl = 0;
05203 policy->parent->soa_min = 0;
05204
05205 }
05206
05207
05208
05209
05210
05211
05212 int backup_file(const char* orig_file, const char* backup_file)
05213 {
05214 FILE *from, *to;
05215 int ch;
05216
05217 errno = 0;
05218
05219 if((from = fopen( orig_file, "rb"))==NULL) {
05220 if (errno == ENOENT) {
05221 printf("File %s does not exist, nothing to backup\n", orig_file);
05222 return(0);
05223 }
05224 else {
05225 printf("Cannot open source file.\n");
05226 return(1);
05227 }
05228 }
05229
05230
05231 if((to = fopen(backup_file, "wb"))==NULL) {
05232 printf("Cannot open destination file, will not make backup.\n");
05233 fclose(from);
05234 return(-1);
05235 }
05236 else {
05237
05238 while(!feof(from)) {
05239 ch = fgetc(from);
05240 if(ferror(from)) {
05241 printf("Error reading source file.\n");
05242 fclose(from);
05243 fclose(to);
05244 return(1);
05245 }
05246 if(!feof(from)) fputc(ch, to);
05247 if(ferror(to)) {
05248 printf("Error writing destination file.\n");
05249 fclose(from);
05250 fclose(to);
05251 return(1);
05252 }
05253 }
05254
05255 if(fclose(from)==EOF) {
05256 printf("Error closing source file.\n");
05257 fclose(to);
05258 return(1);
05259 }
05260
05261 if(fclose(to)==EOF) {
05262 printf("Error closing destination file.\n");
05263 return(1);
05264 }
05265 }
05266 return(0);
05267 }
05268
05269
05270
05271
05272
05273
05274
05275
05276
05277
05278
05279 int
05280 get_db_details(char** dbschema, char** host, char** port, char** user, char** password)
05281 {
05282
05283 xmlDocPtr doc;
05284 xmlDocPtr rngdoc;
05285 xmlXPathContextPtr xpathCtx;
05286 xmlXPathObjectPtr xpathObj;
05287 xmlRelaxNGParserCtxtPtr rngpctx;
05288 xmlRelaxNGValidCtxtPtr rngctx;
05289 xmlRelaxNGPtr schema;
05290 xmlChar *litexpr = (unsigned char*) "//Configuration/Enforcer/Datastore/SQLite";
05291 xmlChar *mysql_host = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Host";
05292 xmlChar *mysql_port = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Host/@port";
05293 xmlChar *mysql_db = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Database";
05294 xmlChar *mysql_user = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Username";
05295 xmlChar *mysql_pass = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Password";
05296
05297 int status;
05298 int db_found = 0;
05299 char* temp_char = NULL;
05300
05301
05302 const char* rngfilename = OPENDNSSEC_SCHEMA_DIR "/conf.rng";
05303
05304
05305 doc = xmlParseFile(config);
05306 if (doc == NULL) {
05307 printf("Error: unable to parse file \"%s\"\n", config);
05308 return(-1);
05309 }
05310
05311
05312 rngdoc = xmlParseFile(rngfilename);
05313 if (rngdoc == NULL) {
05314 printf("Error: unable to parse file \"%s\"\n", rngfilename);
05315 xmlFreeDoc(doc);
05316 return(-1);
05317 }
05318
05319
05320 rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc);
05321 xmlFreeDoc(rngdoc);
05322 if (rngpctx == NULL) {
05323 printf("Error: unable to create XML RelaxNGs parser context\n");
05324 xmlFreeDoc(doc);
05325 return(-1);
05326 }
05327
05328
05329 schema = xmlRelaxNGParse(rngpctx);
05330 xmlRelaxNGFreeParserCtxt(rngpctx);
05331 if (schema == NULL) {
05332 printf("Error: unable to parse a schema definition resource\n");
05333 xmlFreeDoc(doc);
05334 return(-1);
05335 }
05336
05337
05338 rngctx = xmlRelaxNGNewValidCtxt(schema);
05339 if (rngctx == NULL) {
05340 printf("Error: unable to create RelaxNGs validation context based on the schema\n");
05341 xmlRelaxNGFree(schema);
05342 xmlFreeDoc(doc);
05343 return(-1);
05344 }
05345
05346
05347 status = xmlRelaxNGValidateDoc(rngctx,doc);
05348 xmlRelaxNGFreeValidCtxt(rngctx);
05349 xmlRelaxNGFree(schema);
05350 if (status != 0) {
05351 printf("Error validating file \"%s\"\n", config);
05352 xmlFreeDoc(doc);
05353 return(-1);
05354 }
05355
05356
05357
05358 xpathCtx = xmlXPathNewContext(doc);
05359 if(xpathCtx == NULL) {
05360 printf("Error: unable to create new XPath context\n");
05361 xmlFreeDoc(doc);
05362 return(-1);
05363 }
05364
05365
05366 xpathObj = xmlXPathEvalExpression(litexpr, xpathCtx);
05367 if(xpathObj == NULL) {
05368 printf("Error: unable to evaluate xpath expression: %s\n", litexpr);
05369 xmlXPathFreeContext(xpathCtx);
05370 xmlFreeDoc(doc);
05371 return(-1);
05372 }
05373 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
05374 db_found = SQLITE_DB;
05375 temp_char = (char *)xmlXPathCastToString(xpathObj);
05376 StrAppend(dbschema, temp_char);
05377 StrFree(temp_char);
05378 fprintf(stderr, "SQLite database set to: %s\n", *dbschema);
05379 }
05380 xmlXPathFreeObject(xpathObj);
05381
05382 if (db_found == 0) {
05383 db_found = MYSQL_DB;
05384
05385
05386
05387 xpathObj = xmlXPathEvalExpression(mysql_host, xpathCtx);
05388 if(xpathObj == NULL) {
05389 printf("Error: unable to evaluate xpath expression: %s\n", mysql_host);
05390 xmlXPathFreeContext(xpathCtx);
05391 xmlFreeDoc(doc);
05392 return(-1);
05393 }
05394 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
05395 temp_char = (char *)xmlXPathCastToString(xpathObj);
05396 StrAppend(host, temp_char);
05397 StrFree(temp_char);
05398 fprintf(stderr, "MySQL database host set to: %s\n", *host);
05399 }
05400 xmlXPathFreeObject(xpathObj);
05401
05402
05403 xpathObj = xmlXPathEvalExpression(mysql_port, xpathCtx);
05404 if(xpathObj == NULL) {
05405 printf("Error: unable to evaluate xpath expression: %s\n", mysql_port);
05406 xmlXPathFreeContext(xpathCtx);
05407 xmlFreeDoc(doc);
05408 return(-1);
05409 }
05410 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
05411 temp_char = (char *)xmlXPathCastToString(xpathObj);
05412 StrAppend(port, temp_char);
05413 StrFree(temp_char);
05414 fprintf(stderr, "MySQL database port set to: %s\n", *port);
05415 }
05416 xmlXPathFreeObject(xpathObj);
05417
05418
05419 xpathObj = xmlXPathEvalExpression(mysql_db, xpathCtx);
05420 if(xpathObj == NULL) {
05421 printf("Error: unable to evaluate xpath expression: %s\n", mysql_db);
05422 xmlXPathFreeContext(xpathCtx);
05423 xmlFreeDoc(doc);
05424 return(-1);
05425 }
05426 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
05427 temp_char = (char *)xmlXPathCastToString(xpathObj);
05428 StrAppend(dbschema, temp_char);
05429 StrFree(temp_char);
05430 fprintf(stderr, "MySQL database schema set to: %s\n", *dbschema);
05431 } else {
05432 db_found = 0;
05433 }
05434 xmlXPathFreeObject(xpathObj);
05435
05436
05437 xpathObj = xmlXPathEvalExpression(mysql_user, xpathCtx);
05438 if(xpathObj == NULL) {
05439 printf("Error: unable to evaluate xpath expression: %s\n", mysql_user);
05440 xmlXPathFreeContext(xpathCtx);
05441 xmlFreeDoc(doc);
05442 return(-1);
05443 }
05444 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
05445 temp_char = (char *)xmlXPathCastToString(xpathObj);
05446 StrAppend(user, temp_char);
05447 StrFree(temp_char);
05448 fprintf(stderr, "MySQL database user set to: %s\n", *user);
05449 } else {
05450 db_found = 0;
05451 }
05452 xmlXPathFreeObject(xpathObj);
05453
05454
05455 xpathObj = xmlXPathEvalExpression(mysql_pass, xpathCtx);
05456 if(xpathObj == NULL) {
05457 printf("Error: unable to evaluate xpath expression: %s\n", mysql_pass);
05458 xmlXPathFreeContext(xpathCtx);
05459 xmlFreeDoc(doc);
05460 return(-1);
05461 }
05462
05463 temp_char = (char *)xmlXPathCastToString(xpathObj);
05464 StrAppend(password, temp_char);
05465 StrFree(temp_char);
05466 xmlXPathFreeObject(xpathObj);
05467
05468 fprintf(stderr, "MySQL database password set\n");
05469
05470 }
05471
05472 xmlXPathFreeContext(xpathCtx);
05473 xmlFreeDoc(doc);
05474
05475
05476 if(db_found == 0) {
05477 printf("Error: unable to find complete database connection expression\n");
05478 return(-1);
05479 }
05480
05481
05482 if (db_found != DbFlavour()) {
05483 printf("Error: database in config file does not match libksm\n");
05484 return(-1);
05485 }
05486
05487 return(status);
05488 }
05489
05490
05491
05492
05493
05494
05495 int read_zonelist_filename(char** zone_list_filename)
05496 {
05497 xmlTextReaderPtr reader = NULL;
05498 xmlDocPtr doc = NULL;
05499 xmlXPathContextPtr xpathCtx = NULL;
05500 xmlXPathObjectPtr xpathObj = NULL;
05501 int ret = 0;
05502 char* temp_char = NULL;
05503 char* tag_name = NULL;
05504
05505 xmlChar *zonelist_expr = (unsigned char*) "//Common/ZoneListFile";
05506
05507
05508 reader = xmlNewTextReaderFilename(config);
05509 if (reader != NULL) {
05510 ret = xmlTextReaderRead(reader);
05511 while (ret == 1) {
05512 tag_name = (char*) xmlTextReaderLocalName(reader);
05513
05514 if (strncmp(tag_name, "Common", 6) == 0
05515 && xmlTextReaderNodeType(reader) == 1) {
05516
05517
05518 xmlTextReaderExpand(reader);
05519 doc = xmlTextReaderCurrentDoc(reader);
05520 if (doc == NULL) {
05521 printf("Error: can not read Common section\n");
05522
05523 ret = xmlTextReaderRead(reader);
05524 continue;
05525 }
05526
05527 xpathCtx = xmlXPathNewContext(doc);
05528 if(xpathCtx == NULL) {
05529 printf("Error: can not create XPath context for Common section\n");
05530
05531 ret = xmlTextReaderRead(reader);
05532 continue;
05533 }
05534
05535
05536 xpathObj = xmlXPathEvalExpression(zonelist_expr, xpathCtx);
05537 if(xpathObj == NULL) {
05538 printf("Error: unable to evaluate xpath expression: %s\n", zonelist_expr);
05539
05540 ret = xmlTextReaderRead(reader);
05541 continue;
05542 }
05543 *zone_list_filename = NULL;
05544 temp_char = (char *)xmlXPathCastToString(xpathObj);
05545 xmlXPathFreeObject(xpathObj);
05546 StrAppend(zone_list_filename, temp_char);
05547 StrFree(temp_char);
05548 printf("zonelist filename set to %s.\n", *zone_list_filename);
05549 }
05550
05551 ret = xmlTextReaderRead(reader);
05552 StrFree(tag_name);
05553 }
05554 xmlFreeTextReader(reader);
05555 if (ret != 0) {
05556 printf("%s : failed to parse\n", config);
05557 return(1);
05558 }
05559 } else {
05560 printf("Unable to open %s\n", config);
05561 return(1);
05562 }
05563 if (xpathCtx) {
05564 xmlXPathFreeContext(xpathCtx);
05565 }
05566 if (doc) {
05567 xmlFreeDoc(doc);
05568 }
05569
05570 return 0;
05571 }
05572
05573 xmlDocPtr add_zone_node(const char *docname,
05574 const char *zone_name,
05575 const char *policy_name,
05576 const char *sig_conf_name,
05577 const char *input_name,
05578 const char *output_name)
05579 {
05580 xmlDocPtr doc;
05581 xmlNodePtr cur;
05582 xmlNodePtr newzonenode;
05583 xmlNodePtr newadaptnode;
05584 xmlNodePtr newinputnode;
05585 xmlNodePtr newoutputnode;
05586 doc = xmlParseFile(docname);
05587 if (doc == NULL ) {
05588 fprintf(stderr,"Document not parsed successfully. \n");
05589 return (NULL);
05590 }
05591 cur = xmlDocGetRootElement(doc);
05592 if (cur == NULL) {
05593 fprintf(stderr,"empty document\n");
05594 xmlFreeDoc(doc);
05595 return (NULL);
05596 }
05597 if (xmlStrcmp(cur->name, (const xmlChar *) "ZoneList")) {
05598 fprintf(stderr,"document of the wrong type, root node != %s", "ZoneList");
05599 xmlFreeDoc(doc);
05600 return (NULL);
05601 }
05602 newzonenode = xmlNewTextChild(cur, NULL, (const xmlChar *)"Zone", NULL);
05603 (void) xmlNewProp(newzonenode, (const xmlChar *)"name", (const xmlChar *)zone_name);
05604
05605 (void) xmlNewTextChild (newzonenode, NULL, (const xmlChar *)"Policy", (const xmlChar *)policy_name);
05606
05607 (void) xmlNewTextChild (newzonenode, NULL, (const xmlChar *)"SignerConfiguration", (const xmlChar *)sig_conf_name);
05608
05609 newadaptnode = xmlNewChild (newzonenode, NULL, (const xmlChar *)"Adapters", NULL);
05610
05611 newinputnode = xmlNewChild (newadaptnode, NULL, (const xmlChar *)"Input", NULL);
05612
05613 (void) xmlNewTextChild (newinputnode, NULL, (const xmlChar *)"File", (const xmlChar *)input_name);
05614
05615 newoutputnode = xmlNewChild (newadaptnode, NULL, (const xmlChar *)"Output", NULL);
05616
05617 (void) xmlNewTextChild (newoutputnode, NULL, (const xmlChar *)"File", (const xmlChar *)output_name);
05618
05619 return(doc);
05620 }
05621
05622 xmlDocPtr del_zone_node(const char *docname,
05623 const char *zone_name)
05624 {
05625 xmlDocPtr doc;
05626 xmlNodePtr root;
05627 xmlNodePtr cur;
05628
05629 doc = xmlParseFile(docname);
05630 if (doc == NULL ) {
05631 fprintf(stderr,"Document not parsed successfully. \n");
05632 return (NULL);
05633 }
05634 root = xmlDocGetRootElement(doc);
05635 if (root == NULL) {
05636 fprintf(stderr,"empty document\n");
05637 xmlFreeDoc(doc);
05638 return (NULL);
05639 }
05640 if (xmlStrcmp(root->name, (const xmlChar *) "ZoneList")) {
05641 fprintf(stderr,"document of the wrong type, root node != %s", "ZoneList");
05642 xmlFreeDoc(doc);
05643 return (NULL);
05644 }
05645
05646
05647 if (all_flag == 1) {
05648 cur = root->children;
05649 while (cur != NULL)
05650 {
05651 xmlUnlinkNode(cur);
05652 xmlFreeNode(cur);
05653
05654 cur = root->children;
05655 }
05656 }
05657 else {
05658
05659
05660 for(cur = root->children; cur != NULL; cur = cur->next)
05661 {
05662
05663 if (xmlStrcmp( xmlGetProp(cur, (xmlChar *) "name"), (const xmlChar *) zone_name) == 0)
05664 {
05665 xmlUnlinkNode(cur);
05666
05667 cur = root->children;
05668 }
05669 }
05670 xmlFreeNode(cur);
05671 }
05672
05673 return(doc);
05674 }
05675
05676 void list_zone_node(const char *docname, int *zone_ids)
05677 {
05678 xmlDocPtr doc;
05679 xmlNodePtr root;
05680 xmlNodePtr cur;
05681 xmlNodePtr pol;
05682 xmlChar *polChar = NULL;
05683 xmlChar *propChar = NULL;
05684
05685 int temp_id;
05686 int i = 0;
05687 int status = 0;
05688
05689 doc = xmlParseFile(docname);
05690 if (doc == NULL ) {
05691 fprintf(stderr,"Document not parsed successfully. \n");
05692 return;
05693 }
05694 root = xmlDocGetRootElement(doc);
05695 if (root == NULL) {
05696 fprintf(stderr,"empty document\n");
05697 xmlFreeDoc(doc);
05698 return;
05699 }
05700 if (xmlStrcmp(root->name, (const xmlChar *) "ZoneList")) {
05701 fprintf(stderr,"document of the wrong type, root node != %s", "ZoneList");
05702 xmlFreeDoc(doc);
05703 return;
05704 }
05705
05706
05707 for(cur = root->children; cur != NULL; cur = cur->next)
05708 {
05709 if (xmlStrcmp( cur->name, (const xmlChar *)"Zone") == 0) {
05710 propChar = xmlGetProp(cur, (xmlChar *) "name");
05711 printf("Found Zone: %s", propChar);
05712
05713
05714 status = KsmZoneIdFromName((char *) propChar, &temp_id);
05715 xmlFree(propChar);
05716 if (status != 0) {
05717 printf(" (zone not in database)");
05718 zone_ids[i] = 0;
05719 } else {
05720 zone_ids[i] = temp_id;
05721 i++;
05722 }
05723
05724
05725 for(pol = cur->children; pol != NULL; pol = pol->next)
05726 {
05727 if (xmlStrcmp( pol->name, (const xmlChar *)"Policy") == 0)
05728 {
05729 polChar = xmlNodeGetContent(pol);
05730 printf("; on policy %s\n", polChar);
05731 xmlFree(polChar);
05732 }
05733 }
05734 }
05735 }
05736
05737 xmlFreeDoc(doc);
05738
05739 return;
05740 }
05741
05742
05743
05744
05745
05746 int append_policy(xmlDocPtr doc, KSM_POLICY *policy)
05747 {
05748 xmlNodePtr root;
05749 xmlNodePtr policy_node;
05750 xmlNodePtr signatures_node;
05751 xmlNodePtr validity_node;
05752 xmlNodePtr denial_node;
05753 xmlNodePtr nsec_node;
05754 xmlNodePtr hash_node;
05755 xmlNodePtr salt_node;
05756 xmlNodePtr keys_node;
05757 xmlNodePtr ksk_node;
05758 xmlNodePtr ksk_alg_node;
05759 xmlNodePtr zsk_node;
05760 xmlNodePtr zsk_alg_node;
05761 xmlNodePtr zone_node;
05762 xmlNodePtr zone_soa_node;
05763 xmlNodePtr parent_node;
05764 xmlNodePtr parent_ds_node;
05765 xmlNodePtr parent_soa_node;
05766
05767 char temp_time[32];
05768
05769 root = xmlDocGetRootElement(doc);
05770 if (root == NULL) {
05771 fprintf(stderr,"empty document\n");
05772 return(1);
05773 }
05774 if (xmlStrcmp(root->name, (const xmlChar *) "KASP")) {
05775 fprintf(stderr,"document of the wrong type, root node != %s", "KASP");
05776 return(1);
05777 }
05778
05779 policy_node = xmlNewTextChild(root, NULL, (const xmlChar *)"Policy", NULL);
05780 (void) xmlNewProp(policy_node, (const xmlChar *)"name", (const xmlChar *)policy->name);
05781 (void) xmlNewTextChild(policy_node, NULL, (const xmlChar *)"Description", (const xmlChar *)policy->description);
05782
05783
05784 signatures_node = xmlNewTextChild(policy_node, NULL, (const xmlChar *)"Signatures", NULL);
05785 snprintf(temp_time, 32, "PT%dS", policy->signature->resign);
05786 (void) xmlNewTextChild(signatures_node, NULL, (const xmlChar *)"Resign", (const xmlChar *)temp_time);
05787 snprintf(temp_time, 32, "PT%dS", policy->signer->refresh);
05788 (void) xmlNewTextChild(signatures_node, NULL, (const xmlChar *)"Refresh", (const xmlChar *)temp_time);
05789 validity_node = xmlNewTextChild(signatures_node, NULL, (const xmlChar *)"Validity", NULL);
05790 snprintf(temp_time, 32, "PT%dS", policy->signature->valdefault);
05791 (void) xmlNewTextChild(validity_node, NULL, (const xmlChar *)"Default", (const xmlChar *)temp_time);
05792 snprintf(temp_time, 32, "PT%dS", policy->signature->valdenial);
05793 (void) xmlNewTextChild(validity_node, NULL, (const xmlChar *)"Denial", (const xmlChar *)temp_time);
05794 snprintf(temp_time, 32, "PT%dS", policy->signer->jitter);
05795 (void) xmlNewTextChild(signatures_node, NULL, (const xmlChar *)"Jitter", (const xmlChar *)temp_time);
05796 snprintf(temp_time, 32, "PT%dS", policy->signature->clockskew);
05797 (void) xmlNewTextChild(signatures_node, NULL, (const xmlChar *)"InceptionOffset", (const xmlChar *)temp_time);
05798
05799
05800 denial_node = xmlNewTextChild(policy_node, NULL, (const xmlChar *)"Denial", NULL);
05801 if (policy->denial->version == 1)
05802 {
05803 (void) xmlNewTextChild(denial_node, NULL, (const xmlChar *)"NSEC", NULL);
05804 }
05805 else
05806 {
05807 nsec_node = xmlNewTextChild(denial_node, NULL, (const xmlChar *)"NSEC3", NULL);
05808 if (policy->denial->optout == 1)
05809 {
05810 (void) xmlNewTextChild(nsec_node, NULL, (const xmlChar *)"OptOut", NULL);
05811 }
05812 snprintf(temp_time, 32, "PT%dS", policy->denial->resalt);
05813 (void) xmlNewTextChild(nsec_node, NULL, (const xmlChar *)"Resalt", (const xmlChar *)temp_time);
05814 hash_node = xmlNewTextChild(nsec_node, NULL, (const xmlChar *)"Hash", NULL);
05815 snprintf(temp_time, 32, "%d", policy->denial->algorithm);
05816 (void) xmlNewTextChild(hash_node, NULL, (const xmlChar *)"Algorithm", (const xmlChar *)temp_time);
05817 snprintf(temp_time, 32, "%d", policy->denial->iteration);
05818 (void) xmlNewTextChild(hash_node, NULL, (const xmlChar *)"Iteration", (const xmlChar *)temp_time);
05819 snprintf(temp_time, 32, "%d", policy->denial->saltlength);
05820 salt_node = xmlNewTextChild(hash_node, NULL, (const xmlChar *)"Salt", NULL);
05821 (void) xmlNewProp(salt_node, (const xmlChar *)"length", (const xmlChar *)temp_time);
05822 }
05823
05824
05825 keys_node = xmlNewTextChild(policy_node, NULL, (const xmlChar *)"Keys", NULL);
05826 snprintf(temp_time, 32, "PT%dS", policy->keys->ttl);
05827 (void) xmlNewTextChild(keys_node, NULL, (const xmlChar *)"TTL", (const xmlChar *)temp_time);
05828 snprintf(temp_time, 32, "PT%dS", policy->keys->retire_safety);
05829 (void) xmlNewTextChild(keys_node, NULL, (const xmlChar *)"RetireSafety", (const xmlChar *)temp_time);
05830 snprintf(temp_time, 32, "PT%dS", policy->keys->publish_safety);
05831 (void) xmlNewTextChild(keys_node, NULL, (const xmlChar *)"PublishSafety", (const xmlChar *)temp_time);
05832 if (policy->keys->share_keys == 1)
05833 {
05834 (void) xmlNewTextChild(keys_node, NULL, (const xmlChar *)"ShareKeys", NULL);
05835 }
05836 if (policy->keys->purge != -1) {
05837 snprintf(temp_time, 32, "PT%dS", policy->keys->purge);
05838 (void) xmlNewTextChild(keys_node, NULL, (const xmlChar *)"Purge", (const xmlChar *)temp_time);
05839 }
05840
05841
05842 ksk_node = xmlNewTextChild(keys_node, NULL, (const xmlChar *)"KSK", NULL);
05843 snprintf(temp_time, 32, "%d", policy->ksk->algorithm);
05844 ksk_alg_node = xmlNewTextChild(ksk_node, NULL, (const xmlChar *)"Algorithm", (const xmlChar *)temp_time);
05845 snprintf(temp_time, 32, "%d", policy->ksk->bits);
05846 (void) xmlNewProp(ksk_alg_node, (const xmlChar *)"length", (const xmlChar *)temp_time);
05847 snprintf(temp_time, 32, "PT%dS", policy->ksk->lifetime);
05848 (void) xmlNewTextChild(ksk_node, NULL, (const xmlChar *)"Lifetime", (const xmlChar *)temp_time);
05849 (void) xmlNewTextChild(ksk_node, NULL, (const xmlChar *)"Repository", (const xmlChar *)policy->ksk->sm_name);
05850 snprintf(temp_time, 32, "%d", policy->ksk->standby_keys);
05851 (void) xmlNewTextChild(ksk_node, NULL, (const xmlChar *)"Standby", (const xmlChar *)temp_time);
05852 if (policy->ksk->manual_rollover == 1)
05853 {
05854 (void) xmlNewTextChild(ksk_node, NULL, (const xmlChar *)"ManualRollover", NULL);
05855 }
05856 if (policy->ksk->rfc5011 == 1)
05857 {
05858 (void) xmlNewTextChild(ksk_node, NULL, (const xmlChar *)"RFC5011", NULL);
05859 }
05860
05861
05862
05863
05864
05865
05866 zsk_node = xmlNewTextChild(keys_node, NULL, (const xmlChar *)"ZSK", NULL);
05867 snprintf(temp_time, 32, "%d", policy->zsk->algorithm);
05868 zsk_alg_node = xmlNewTextChild(zsk_node, NULL, (const xmlChar *)"Algorithm", (const xmlChar *)temp_time);
05869 snprintf(temp_time, 32, "%d", policy->zsk->bits);
05870 (void) xmlNewProp(zsk_alg_node, (const xmlChar *)"length", (const xmlChar *)temp_time);
05871 snprintf(temp_time, 32, "PT%dS", policy->zsk->lifetime);
05872 (void) xmlNewTextChild(zsk_node, NULL, (const xmlChar *)"Lifetime", (const xmlChar *)temp_time);
05873 (void) xmlNewTextChild(zsk_node, NULL, (const xmlChar *)"Repository", (const xmlChar *)policy->zsk->sm_name);
05874 snprintf(temp_time, 32, "%d", policy->zsk->standby_keys);
05875 (void) xmlNewTextChild(zsk_node, NULL, (const xmlChar *)"Standby", (const xmlChar *)temp_time);
05876 if (policy->zsk->manual_rollover == 1)
05877 {
05878 (void) xmlNewTextChild(zsk_node, NULL, (const xmlChar *)"ManualRollover", NULL);
05879 }
05880
05881
05882 zone_node = xmlNewTextChild(policy_node, NULL, (const xmlChar *)"Zone", NULL);
05883 snprintf(temp_time, 32, "PT%dS", policy->zone->propdelay);
05884 (void) xmlNewTextChild(zone_node, NULL, (const xmlChar *)"PropagationDelay", (const xmlChar *)temp_time);
05885 zone_soa_node = xmlNewTextChild(zone_node, NULL, (const xmlChar *)"SOA", NULL);
05886 snprintf(temp_time, 32, "PT%dS", policy->zone->soa_ttl);
05887 (void) xmlNewTextChild(zone_soa_node, NULL, (const xmlChar *)"TTL", (const xmlChar *)temp_time);
05888 snprintf(temp_time, 32, "PT%dS", policy->zone->soa_min);
05889 (void) xmlNewTextChild(zone_soa_node, NULL, (const xmlChar *)"Minimum", (const xmlChar *)temp_time);
05890 (void) xmlNewTextChild(zone_soa_node, NULL, (const xmlChar *)"Serial", (const xmlChar *) KsmKeywordSerialValueToName(policy->zone->serial));
05891
05892
05893 parent_node = xmlNewTextChild(policy_node, NULL, (const xmlChar *)"Parent", NULL);
05894 snprintf(temp_time, 32, "PT%dS", policy->parent->propdelay);
05895 (void) xmlNewTextChild(parent_node, NULL, (const xmlChar *)"PropagationDelay", (const xmlChar *)temp_time);
05896 parent_ds_node = xmlNewTextChild(parent_node, NULL, (const xmlChar *)"DS", NULL);
05897 snprintf(temp_time, 32, "PT%dS", policy->parent->ds_ttl);
05898 (void) xmlNewTextChild(parent_ds_node, NULL, (const xmlChar *)"TTL", (const xmlChar *)temp_time);
05899 parent_soa_node = xmlNewTextChild(parent_node, NULL, (const xmlChar *)"SOA", NULL);
05900 snprintf(temp_time, 32, "PT%dS", policy->parent->soa_ttl);
05901 (void) xmlNewTextChild(parent_soa_node, NULL, (const xmlChar *)"TTL", (const xmlChar *)temp_time);
05902 snprintf(temp_time, 32, "PT%dS", policy->parent->soa_min);
05903 (void) xmlNewTextChild(parent_soa_node, NULL, (const xmlChar *)"Minimum", (const xmlChar *)temp_time);
05904
05905
05906 if (strncmp(policy->audit, "NULL", 4) != 0) {
05907 (void) xmlNewChild(policy_node, NULL, (const xmlChar *)"Audit", NULL);
05908 }
05909
05910 return(0);
05911 }
05912
05913
05914
05915
05916 xmlDocPtr del_policy_node(const char *docname,
05917 const char *policy_name)
05918 {
05919 xmlDocPtr doc;
05920 xmlNodePtr root;
05921 xmlNodePtr cur;
05922
05923 doc = xmlParseFile(docname);
05924 if (doc == NULL ) {
05925 fprintf(stderr,"Document not parsed successfully. \n");
05926 return (NULL);
05927 }
05928 root = xmlDocGetRootElement(doc);
05929 if (root == NULL) {
05930 fprintf(stderr,"empty document\n");
05931 xmlFreeDoc(doc);
05932 return (NULL);
05933 }
05934 if (xmlStrcmp(root->name, (const xmlChar *) "KASP")) {
05935 fprintf(stderr,"document of the wrong type, root node != %s", "KASP");
05936 xmlFreeDoc(doc);
05937 return (NULL);
05938 }
05939
05940
05941
05942 for(cur = root->children; cur != NULL; cur = cur->next)
05943 {
05944
05945 if (xmlStrcmp( xmlGetProp(cur, (xmlChar *) "name"), (const xmlChar *) policy_name) == 0)
05946 {
05947 xmlUnlinkNode(cur);
05948
05949 cur = root->children;
05950 }
05951 }
05952 xmlFreeNode(cur);
05953
05954 return(doc);
05955 }
05956
05957
05958
05959
05960 int printKey(void* context, KSM_KEYDATA* key_data)
05961 {
05962 if (key_data->state == KSM_STATE_RETIRE && strcasecmp(key_data->retire, (char *)context) == 0) {
05963 if (key_data->keytype == KSM_TYPE_KSK)
05964 {
05965 fprintf(stdout, "KSK:");
05966 }
05967 if (key_data->keytype == KSM_TYPE_ZSK)
05968 {
05969 fprintf(stdout, "ZSK:");
05970 }
05971 fprintf(stdout, " %s Retired\n", key_data->location);
05972 }
05973
05974 return 0;
05975 }
05976
05977
05978
05979
05980 void
05981 ksm_log_msg(const char *format)
05982 {
05983 fprintf(stderr, "%s\n", format);
05984 }
05985
05986
05987
05988
05989
05990
05991
05992
05993
05994
05995
05996
05997
05998
05999
06000
06001 int ListKeys(int zone_id)
06002 {
06003 char* sql = NULL;
06004 int status = 0;
06005 char stringval[KSM_INT_STR_SIZE];
06006 DB_RESULT result;
06007 DB_ROW row = NULL;
06008 int done_row = 0;
06009
06010 char* temp_zone = NULL;
06011 int temp_type = 0;
06012 int temp_state = 0;
06013 char* temp_ready = NULL;
06014 char* temp_active = NULL;
06015 char* temp_retire = NULL;
06016 char* temp_dead = NULL;
06017 char* temp_loc = NULL;
06018 char* temp_hsm = NULL;
06019 int temp_alg = 0;
06020
06021
06022 hsm_key_t *key = NULL;
06023 ldns_rr *dnskey_rr = NULL;
06024 hsm_sign_params_t *sign_params = NULL;
06025
06026 if (verbose_flag) {
06027
06028 status = hsm_open(config, hsm_prompt_pin, NULL);
06029 if (status) {
06030 hsm_print_error(NULL);
06031 return(-1);
06032 }
06033 }
06034
06035
06036 StrAppend(&sql, "select z.name, k.keytype, k.state, k.ready, k.active, k.retire, k.dead, k.location, s.name, k.algorithm from securitymodules s, zones z, KEYDATA_VIEW k where z.id = k.zone_id and s.id = k.securitymodule_id and state != 6 and zone_id is not null ");
06037 if (zone_id != -1) {
06038 StrAppend(&sql, "and zone_id = ");
06039 snprintf(stringval, KSM_INT_STR_SIZE, "%d", zone_id);
06040 StrAppend(&sql, stringval);
06041 }
06042 StrAppend(&sql, " order by zone_id");
06043
06044 DusEnd(&sql);
06045
06046 status = DbExecuteSql(DbHandle(), sql, &result);
06047
06048 if (status == 0) {
06049 status = DbFetchRow(result, &row);
06050 if (verbose_flag == 1) {
06051 printf("Zone: Keytype: State: Date of next transition: CKA_ID: Repository: Keytag:\n");
06052 }
06053 else {
06054 printf("Zone: Keytype: State: Date of next transition:\n");
06055 }
06056 while (status == 0) {
06057
06058 DbString(row, 0, &temp_zone);
06059 DbInt(row, 1, &temp_type);
06060 DbInt(row, 2, &temp_state);
06061 DbString(row, 3, &temp_ready);
06062 DbString(row, 4, &temp_active);
06063 DbString(row, 5, &temp_retire);
06064 DbString(row, 6, &temp_dead);
06065 DbString(row, 7, &temp_loc);
06066 DbString(row, 8, &temp_hsm);
06067 DbInt(row, 9, &temp_alg);
06068 done_row = 0;
06069
06070 if (temp_state == KSM_STATE_PUBLISH) {
06071 printf("%-31s %-13s %-9s %-26s", temp_zone, (temp_type == KSM_TYPE_KSK) ? "KSK" : "ZSK", KsmKeywordStateValueToName(temp_state), (temp_ready == NULL) ? "(not scheduled)" : temp_ready);
06072 done_row = 1;
06073 }
06074 else if (temp_state == KSM_STATE_READY) {
06075 printf("%-31s %-13s %-9s %-26s", temp_zone, (temp_type == KSM_TYPE_KSK) ? "KSK" : "ZSK", KsmKeywordStateValueToName(temp_state), (temp_type == KSM_TYPE_KSK) ? "waiting for ds-seen" : "next rollover");
06076 done_row = 1;
06077 }
06078 else if (temp_state == KSM_STATE_ACTIVE) {
06079 printf("%-31s %-13s %-9s %-26s", temp_zone, (temp_type == KSM_TYPE_KSK) ? "KSK" : "ZSK", KsmKeywordStateValueToName(temp_state), (temp_retire == NULL) ? "(not scheduled)" : temp_retire);
06080 done_row = 1;
06081 }
06082 else if (temp_state == KSM_STATE_RETIRE) {
06083 printf("%-31s %-13s %-9s %-26s", temp_zone, (temp_type == KSM_TYPE_KSK) ? "KSK" : "ZSK", KsmKeywordStateValueToName(temp_state), (temp_dead == NULL) ? "(not scheduled)" : temp_dead);
06084 done_row = 1;
06085 }
06086 else if (temp_state == KSM_STATE_DSSUB) {
06087 printf("%-31s %-13s %-9s %-26s", temp_zone, "KSK", KsmKeywordStateValueToName(temp_state), "waiting for ds-seen");
06088 done_row = 1;
06089 }
06090 else if (temp_state == KSM_STATE_DSPUBLISH) {
06091 printf("%-31s %-13s %-9s %-26s", temp_zone, "KSK", KsmKeywordStateValueToName(temp_state), (temp_ready == NULL) ? "(not scheduled)" : temp_ready);
06092 done_row = 1;
06093 }
06094 else if (temp_state == KSM_STATE_DSREADY) {
06095 printf("%-31s %-13s %-9s %-26s", temp_zone, "KSK", KsmKeywordStateValueToName(temp_state), "When required");
06096 done_row = 1;
06097 }
06098 else if (temp_state == KSM_STATE_KEYPUBLISH) {
06099 printf("%-31s %-13s %-9s %-26s", temp_zone, "KSK", KsmKeywordStateValueToName(temp_state), (temp_active == NULL) ? "(not scheduled)" : temp_active);
06100 done_row = 1;
06101 }
06102
06103 if (done_row == 1 && verbose_flag == 1) {
06104 key = hsm_find_key_by_id(NULL, temp_loc);
06105 if (!key) {
06106 printf("%-33s %s NOT IN repository\n", temp_loc, temp_hsm);
06107 } else {
06108 sign_params = hsm_sign_params_new();
06109 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, temp_zone);
06110 sign_params->algorithm = temp_alg;
06111 sign_params->flags = LDNS_KEY_ZONE_KEY;
06112 if (temp_type == KSM_TYPE_KSK) {
06113 sign_params->flags += LDNS_KEY_SEP_KEY;
06114 }
06115 dnskey_rr = hsm_get_dnskey(NULL, key, sign_params);
06116 sign_params->keytag = ldns_calc_keytag(dnskey_rr);
06117
06118 printf("%-33s %-33s %d\n", temp_loc, temp_hsm, sign_params->keytag);
06119
06120 hsm_sign_params_free(sign_params);
06121 hsm_key_free(key);
06122 }
06123 }
06124 else if (done_row == 1) {
06125 printf("\n");
06126 }
06127
06128 status = DbFetchRow(result, &row);
06129 }
06130
06131
06132
06133 if (status == -1) {
06134 status = 0;
06135 }
06136
06137 DbFreeResult(result);
06138 }
06139
06140 DusFree(sql);
06141 DbFreeRow(row);
06142
06143 DbStringFree(temp_zone);
06144 DbStringFree(temp_ready);
06145 DbStringFree(temp_active);
06146 DbStringFree(temp_retire);
06147 DbStringFree(temp_dead);
06148 DbStringFree(temp_loc);
06149 DbStringFree(temp_hsm);
06150
06151 if (dnskey_rr != NULL) {
06152 ldns_rr_free(dnskey_rr);
06153 }
06154
06155 return status;
06156 }
06157
06158
06159
06160
06161
06162
06163
06164
06165
06166
06167
06168
06169
06170
06171
06172
06173
06174
06175
06176
06177
06178 int PurgeKeys(int zone_id, int policy_id)
06179 {
06180 char* sql = NULL;
06181 char* sql1 = NULL;
06182 char* sql2 = NULL;
06183 char* sql3 = NULL;
06184 int status = 0;
06185 char stringval[KSM_INT_STR_SIZE];
06186 DB_RESULT result;
06187 DB_ROW row = NULL;
06188
06189 int temp_id = -1;
06190 char* temp_loc = NULL;
06191 int count = 0;
06192
06193 int done_something = 0;
06194
06195
06196 hsm_key_t *key = NULL;
06197
06198 if ((zone_id == -1 && policy_id == -1) ||
06199 (zone_id != -1 && policy_id != -1)){
06200 printf("Please provide either a zone OR a policy to key purge\n");
06201 usage_keypurge();
06202 return(1);
06203 }
06204
06205
06206 status = hsm_open(config, hsm_prompt_pin, NULL);
06207 if (status) {
06208 hsm_print_error(NULL);
06209 return(-1);
06210 }
06211
06212
06213 StrAppend(&sql, "select distinct id, location from KEYDATA_VIEW where state = 6 ");
06214 if (zone_id != -1) {
06215 StrAppend(&sql, "and zone_id = ");
06216 snprintf(stringval, KSM_INT_STR_SIZE, "%d", zone_id);
06217 StrAppend(&sql, stringval);
06218 }
06219 if (policy_id != -1) {
06220 StrAppend(&sql, "and policy_id = ");
06221 snprintf(stringval, KSM_INT_STR_SIZE, "%d", policy_id);
06222 StrAppend(&sql, stringval);
06223 }
06224 DusEnd(&sql);
06225
06226 status = DbExecuteSql(DbHandle(), sql, &result);
06227
06228 if (status == 0) {
06229 status = DbFetchRow(result, &row);
06230 while (status == 0) {
06231
06232 DbInt(row, 0, &temp_id);
06233 DbString(row, 1, &temp_loc);
06234
06235 sql1 = DqsCountInit("dnsseckeys");
06236 DdsConditionInt(&sql1, "keypair_id", DQS_COMPARE_EQ, temp_id, 0);
06237 DdsConditionInt(&sql1, "state", DQS_COMPARE_NE, KSM_STATE_DEAD, 1);
06238 DqsEnd(&sql1);
06239
06240 status = DbIntQuery(DbHandle(), &count, sql1);
06241 DqsFree(sql1);
06242
06243 if (status != 0) {
06244 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
06245 DbStringFree(temp_loc);
06246 DbFreeRow(row);
06247 return status;
06248 }
06249
06250
06251 if (count == 0) {
06252
06253 done_something = 1;
06254
06255
06256 sql2 = DdsInit("dnsseckeys");
06257 DdsConditionInt(&sql2, "keypair_id", DQS_COMPARE_EQ, temp_id, 0);
06258 DdsEnd(&sql);
06259
06260 status = DbExecuteSqlNoResult(DbHandle(), sql2);
06261 DdsFree(sql2);
06262 if (status != 0)
06263 {
06264 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
06265 DbStringFree(temp_loc);
06266 DbFreeRow(row);
06267 return status;
06268 }
06269
06270
06271 sql3 = DdsInit("keypairs");
06272 DdsConditionInt(&sql3, "id", DQS_COMPARE_EQ, temp_id, 0);
06273 DdsEnd(&sql);
06274
06275 status = DbExecuteSqlNoResult(DbHandle(), sql3);
06276 DdsFree(sql3);
06277 if (status != 0)
06278 {
06279 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
06280 DbStringFree(temp_loc);
06281 DbFreeRow(row);
06282 return status;
06283 }
06284
06285
06286 key = hsm_find_key_by_id(NULL, temp_loc);
06287
06288 if (!key) {
06289 printf("Key not found: %s\n", temp_loc);
06290 DbStringFree(temp_loc);
06291 DbFreeRow(row);
06292 return -1;
06293 }
06294
06295 status = hsm_remove_key(NULL, key);
06296
06297 hsm_key_free(key);
06298
06299 if (!status) {
06300 printf("Key remove successful.\n");
06301 } else {
06302 printf("Key remove failed.\n");
06303 DbStringFree(temp_loc);
06304 DbFreeRow(row);
06305 return -1;
06306 }
06307 }
06308
06309
06310 status = DbFetchRow(result, &row);
06311 }
06312
06313
06314
06315 if (status == -1) {
06316 status = 0;
06317 }
06318
06319 DbFreeResult(result);
06320 }
06321
06322 if (done_something == 0) {
06323 printf("No keys to purge.\n");
06324 }
06325
06326 DusFree(sql);
06327 DbFreeRow(row);
06328
06329 DbStringFree(temp_loc);
06330
06331 return status;
06332 }
06333
06334 int cmd_genkeys()
06335 {
06336 int status = 0;
06337
06338 int interval = -1;
06339
06340 KSM_POLICY* policy;
06341 hsm_ctx_t *ctx = NULL;
06342
06343 char *rightnow;
06344 int i = 0;
06345 char *id;
06346 hsm_key_t *key = NULL;
06347 char *hsm_error_message = NULL;
06348 DB_ID ignore = 0;
06349 int ksks_needed = 0;
06350 int zsks_needed = 0;
06351 int keys_in_queue = 0;
06352 int new_keys = 0;
06353 unsigned int current_count = 0;
06354
06355 DB_RESULT result;
06356 int zone_count = 0;
06357
06358 int same_keys = 0;
06359 int ksks_created = 0;
06360
06361
06362 DB_HANDLE dbhandle;
06363 FILE* lock_fd = NULL;
06364
06365
06366 status = db_connect(&dbhandle, &lock_fd, 1);
06367 if (status != 0) {
06368 printf("Failed to connect to database\n");
06369 db_disconnect(lock_fd);
06370 return(1);
06371 }
06372
06373 policy = KsmPolicyAlloc();
06374 if (policy == NULL) {
06375 printf("Malloc for policy struct failed\n");
06376 db_disconnect(lock_fd);
06377 exit(1);
06378 }
06379
06380 if (o_policy == NULL) {
06381 printf("Please provide a policy name with the --policy option\n");
06382 db_disconnect(lock_fd);
06383 KsmPolicyFree(policy);
06384 return(1);
06385 }
06386 if (o_interval == NULL) {
06387 printf("Please provide an interval with the --interval option\n");
06388 db_disconnect(lock_fd);
06389 KsmPolicyFree(policy);
06390 return(1);
06391 }
06392
06393 SetPolicyDefaults(policy, o_policy);
06394
06395 status = KsmPolicyExists(o_policy);
06396 if (status == 0) {
06397
06398 status = KsmPolicyRead(policy);
06399 if(status != 0) {
06400 printf("Error: unable to read policy %s from database\n", o_policy);
06401 db_disconnect(lock_fd);
06402 KsmPolicyFree(policy);
06403 return status;
06404 }
06405 } else {
06406 printf("Error: policy %s doesn't exist in database\n", o_policy);
06407 db_disconnect(lock_fd);
06408 KsmPolicyFree(policy);
06409 return status;
06410 }
06411
06412 if (policy->shared_keys == 1 ) {
06413 printf("Key sharing is On\n");
06414 } else {
06415 printf("Key sharing is Off\n");
06416 }
06417
06418 status = DtXMLIntervalSeconds(o_interval, &interval);
06419 if (status > 0) {
06420 printf("Error: unable to convert Interval %s to seconds, error: ", o_interval);
06421 switch (status) {
06422 case 1:
06423 printf("invalid interval-type.\n");
06424 break;
06425 case 2:
06426 printf("unable to translate string.\n");
06427 break;
06428 case 3:
06429 printf("interval too long to be an int. E.g. Maximum is ~68 years on a system with 32-bit integers.\n");
06430 break;
06431 case 4:
06432 printf("invalid pointers or text string NULL.\n");
06433 break;
06434 default:
06435 printf("unknown\n");
06436 }
06437 db_disconnect(lock_fd);
06438 KsmPolicyFree(policy);
06439 return status;
06440 }
06441 else if (status == -1) {
06442 printf("Info: converting %s to seconds; M interpreted as 31 days, Y interpreted as 365 days\n", o_interval);
06443 }
06444
06445
06446 status = hsm_open(config, hsm_prompt_pin, NULL);
06447 if (status) {
06448 hsm_error_message = hsm_get_error(ctx);
06449 if (hsm_error_message) {
06450 printf("%s\n", hsm_error_message);
06451 free(hsm_error_message);
06452 } else {
06453
06454
06455 switch (status) {
06456 case HSM_ERROR:
06457 printf("hsm_open() result: HSM error\n");
06458 break;
06459 case HSM_PIN_INCORRECT:
06460 printf("hsm_open() result: incorrect PIN\n");
06461 break;
06462 case HSM_CONFIG_FILE_ERROR:
06463 printf("hsm_open() result: config file error\n");
06464 break;
06465 case HSM_REPOSITORY_NOT_FOUND:
06466 printf("hsm_open() result: repository not found\n");
06467 break;
06468 case HSM_NO_REPOSITORIES:
06469 printf("hsm_open() result: no repositories\n");
06470 break;
06471 default:
06472 printf("hsm_open() result: %d", status);
06473 }
06474 }
06475 db_disconnect(lock_fd);
06476 KsmPolicyFree(policy);
06477 exit(1);
06478 }
06479 printf("HSM opened successfully.\n");
06480 ctx = hsm_create_context();
06481
06482 rightnow = DtParseDateTimeString("now");
06483
06484
06485 if (rightnow == NULL) {
06486 printf("Couldn't turn \"now\" into a date, quitting...\n");
06487 db_disconnect(lock_fd);
06488 KsmPolicyFree(policy);
06489 exit(1);
06490 }
06491
06492 if (policy->ksk->sm == policy->zsk->sm && policy->ksk->bits == policy->zsk->bits && policy->ksk->algorithm == policy->zsk->algorithm) {
06493 same_keys = 1;
06494 } else {
06495 same_keys = 0;
06496 }
06497
06498
06499 status = KsmZoneCountInit(&result, policy->id);
06500 if (status == 0) {
06501 status = KsmZoneCount(result, &zone_count);
06502 }
06503 DbFreeResult(result);
06504
06505 if (status == 0) {
06506
06507 if (zone_count == 0) {
06508 printf("No zones on policy %s, skipping...", policy->name);
06509 db_disconnect(lock_fd);
06510 if (ctx) {
06511 hsm_destroy_context(ctx);
06512 }
06513 hsm_close();
06514 KsmPolicyFree(policy);
06515 return status;
06516 }
06517 } else {
06518 printf("Could not count zones on policy %s", policy->name);
06519 db_disconnect(lock_fd);
06520 if (ctx) {
06521 hsm_destroy_context(ctx);
06522 }
06523 hsm_close();
06524 KsmPolicyFree(policy);
06525 return status;
06526 }
06527
06528
06529 status = KsmKeyPredict(policy->id, KSM_TYPE_KSK, policy->shared_keys, interval, &ksks_needed, policy->ksk->rollover_scheme, zone_count);
06530 if (status != 0) {
06531 printf("Could not predict ksk requirement for next interval for %s\n", policy->name);
06532
06533 }
06534
06535 status = KsmKeyCountStillGood(policy->id, policy->ksk->sm, policy->ksk->bits, policy->ksk->algorithm, interval, rightnow, &keys_in_queue, KSM_TYPE_KSK);
06536 if (status != 0) {
06537 printf("Could not count current ksk numbers for policy %s\n", policy->name);
06538
06539 }
06540
06541 if (policy->shared_keys == KSM_KEYS_SHARED) {
06542 keys_in_queue /= zone_count;
06543 }
06544
06545 new_keys = ksks_needed - keys_in_queue;
06546
06547
06548
06549 if (policy->ksk->sm_capacity != 0 && new_keys > 0) {
06550 current_count = hsm_count_keys_repository(ctx, policy->ksk->sm_name);
06551 if (current_count >= policy->ksk->sm_capacity) {
06552 printf("Repository %s is full, cannot create more KSKs for policy %s\n", policy->ksk->sm_name, policy->name);
06553 new_keys = 0;
06554 }
06555 else if (current_count + new_keys > policy->ksk->sm_capacity) {
06556 printf("Repository %s is nearly full, will create %lu KSKs for policy %s (reduced from %d)\n", policy->ksk->sm_name, policy->ksk->sm_capacity - current_count, policy->name, new_keys);
06557 new_keys = policy->ksk->sm_capacity - current_count;
06558 }
06559 }
06560
06561
06562 for (i=new_keys ; i > 0 ; i--){
06563 if (hsm_supported_algorithm(policy->ksk->algorithm) == 0) {
06564
06565 key = hsm_generate_rsa_key(ctx, policy->ksk->sm_name, policy->ksk->bits);
06566 if (key) {
06567 if (verbose_flag) {
06568 printf("Created key in repository %s\n", policy->ksk->sm_name);
06569 }
06570 } else {
06571 printf("Error creating key in repository %s\n", policy->ksk->sm_name);
06572 hsm_error_message = hsm_get_error(ctx);
06573 if (hsm_error_message) {
06574 printf("%s\n", hsm_error_message);
06575 free(hsm_error_message);
06576 }
06577 db_disconnect(lock_fd);
06578 KsmPolicyFree(policy);
06579 exit(1);
06580 }
06581 id = hsm_get_key_id(ctx, key);
06582 hsm_key_free(key);
06583 status = KsmKeyPairCreate(policy->id, id, policy->ksk->sm, policy->ksk->bits, policy->ksk->algorithm, rightnow, &ignore);
06584 if (status != 0) {
06585 printf("Error creating key in Database\n");
06586 hsm_error_message = hsm_get_error(ctx);
06587 if (hsm_error_message) {
06588 printf("%s\n", hsm_error_message);
06589 free(hsm_error_message);
06590 }
06591 db_disconnect(lock_fd);
06592 KsmPolicyFree(policy);
06593 exit(1);
06594 }
06595 printf("Created KSK size: %i, alg: %i with id: %s in repository: %s and database.\n", policy->ksk->bits,
06596 policy->ksk->algorithm, id, policy->ksk->sm_name);
06597 free(id);
06598 } else {
06599 printf("Key algorithm %d unsupported by libhsm.\n", policy->ksk->algorithm);
06600 db_disconnect(lock_fd);
06601 KsmPolicyFree(policy);
06602 exit(1);
06603 }
06604 }
06605 ksks_created = new_keys;
06606
06607
06608 keys_in_queue = 0;
06609 new_keys = 0;
06610 current_count = 0;
06611
06612
06613 status = KsmKeyPredict(policy->id, KSM_TYPE_ZSK, policy->shared_keys, interval, &zsks_needed, 0, zone_count);
06614 if (status != 0) {
06615 printf("Could not predict zsk requirement for next interval for %s\n", policy->name);
06616
06617 }
06618
06619 status = KsmKeyCountStillGood(policy->id, policy->zsk->sm, policy->zsk->bits, policy->zsk->algorithm, interval, rightnow, &keys_in_queue, KSM_TYPE_ZSK);
06620 if (status != 0) {
06621 printf("Could not count current zsk numbers for policy %s\n", policy->name);
06622
06623 }
06624
06625 if (policy->shared_keys == KSM_KEYS_SHARED) {
06626 keys_in_queue /= zone_count;
06627 }
06628
06629 if (same_keys) {
06630 keys_in_queue -= ksks_needed;
06631 }
06632
06633 new_keys = zsks_needed - keys_in_queue;
06634
06635
06636
06637 if (policy->zsk->sm_capacity != 0 && new_keys > 0) {
06638 current_count = hsm_count_keys_repository(ctx, policy->zsk->sm_name);
06639 if (current_count >= policy->zsk->sm_capacity) {
06640 printf("Repository %s is full, cannot create more ZSKs for policy %s\n", policy->zsk->sm_name, policy->name);
06641 new_keys = 0;
06642 }
06643 else if (current_count + new_keys > policy->zsk->sm_capacity) {
06644 printf("Repository %s is nearly full, will create %lu ZSKs for policy %s (reduced from %d)\n", policy->zsk->sm_name, policy->zsk->sm_capacity - current_count, policy->name, new_keys);
06645 new_keys = policy->zsk->sm_capacity - current_count;
06646 }
06647 }
06648
06649
06650 for (i = new_keys ; i > 0 ; i--) {
06651 if (hsm_supported_algorithm(policy->zsk->algorithm) == 0) {
06652
06653 key = hsm_generate_rsa_key(ctx, policy->zsk->sm_name, policy->zsk->bits);
06654 if (key) {
06655 if (verbose_flag) {
06656 printf("Created key in repository %s\n", policy->zsk->sm_name);
06657 }
06658 } else {
06659 printf("Error creating key in repository %s\n", policy->zsk->sm_name);
06660 hsm_error_message = hsm_get_error(ctx);
06661 if (hsm_error_message) {
06662 printf("%s\n", hsm_error_message);
06663 free(hsm_error_message);
06664 }
06665 db_disconnect(lock_fd);
06666 KsmPolicyFree(policy);
06667 exit(1);
06668 }
06669 id = hsm_get_key_id(ctx, key);
06670 hsm_key_free(key);
06671 status = KsmKeyPairCreate(policy->id, id, policy->zsk->sm, policy->zsk->bits, policy->zsk->algorithm, rightnow, &ignore);
06672 if (status != 0) {
06673 printf("Error creating key in Database\n");
06674 hsm_error_message = hsm_get_error(ctx);
06675 if (hsm_error_message) {
06676 printf("%s\n", hsm_error_message);
06677 free(hsm_error_message);
06678 }
06679 db_disconnect(lock_fd);
06680 KsmPolicyFree(policy);
06681 exit(1);
06682 }
06683 printf("Created ZSK size: %i, alg: %i with id: %s in repository: %s and database.\n", policy->zsk->bits,
06684 policy->zsk->algorithm, id, policy->zsk->sm_name);
06685 free(id);
06686 } else {
06687 printf("Key algorithm %d unsupported by libhsm.\n", policy->zsk->algorithm);
06688 db_disconnect(lock_fd);
06689 KsmPolicyFree(policy);
06690 exit(1);
06691 }
06692 }
06693 StrFree(rightnow);
06694
06695
06696 if (ksks_created && policy->ksk->require_backup) {
06697 printf("NOTE: keys generated in repository %s will not become active until they have been backed up\n", policy->ksk->sm_name);
06698 }
06699 if (new_keys && policy->zsk->require_backup && (policy->zsk->sm != policy->ksk->sm)) {
06700 printf("NOTE: keys generated in repository %s will not become active until they have been backed up\n", policy->zsk->sm_name);
06701 }
06702
06703
06704
06705
06706 if (ctx) {
06707 hsm_destroy_context(ctx);
06708 }
06709 status = hsm_close();
06710 printf("all done! hsm_close result: %d\n", status);
06711
06712 KsmPolicyFree(policy);
06713
06714
06715 db_disconnect(lock_fd);
06716
06717 return status;
06718 }
06719
06720
06721
06722 int fix_file_perms(const char *dbschema)
06723 {
06724 struct stat stat_ret;
06725
06726 int status = 0;
06727
06728 xmlDocPtr doc = NULL;
06729 xmlDocPtr rngdoc = NULL;
06730 xmlXPathContextPtr xpathCtx = NULL;
06731 xmlXPathObjectPtr xpathObj = NULL;
06732 xmlRelaxNGParserCtxtPtr rngpctx = NULL;
06733 xmlRelaxNGValidCtxtPtr rngctx = NULL;
06734 xmlRelaxNGPtr schema = NULL;
06735 xmlChar *user_expr = (unsigned char*) "//Configuration/Enforcer/Privileges/User";
06736 xmlChar *group_expr = (unsigned char*) "//Configuration/Enforcer/Privileges/Group";
06737
06738 char* filename = OPENDNSSEC_CONFIG_FILE;
06739 char* rngfilename = OPENDNSSEC_SCHEMA_DIR "/conf.rng";
06740 char* temp_char = NULL;
06741
06742 struct passwd *pwd;
06743 struct group *grp;
06744
06745 int uid = -1;
06746 int gid = -1;
06747 char *username = NULL;
06748 char *groupname = NULL;
06749
06750 printf("fixing permissions on file %s\n", dbschema);
06751
06752 if (geteuid() != 0) {
06753 return 0;
06754 }
06755
06756
06757 if (stat(dbschema, &stat_ret) != 0) {
06758 printf("cannot stat file %s: %s", dbschema, strerror(errno));
06759 return -1;
06760 }
06761
06762
06763
06764 doc = xmlParseFile(filename);
06765 if (doc == NULL) {
06766 printf("Error: unable to parse file \"%s\"", filename);
06767 return(-1);
06768 }
06769
06770
06771 rngdoc = xmlParseFile(rngfilename);
06772 if (rngdoc == NULL) {
06773 printf("Error: unable to parse file \"%s\"", rngfilename);
06774 return(-1);
06775 }
06776
06777
06778 rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc);
06779 if (rngpctx == NULL) {
06780 printf("Error: unable to create XML RelaxNGs parser context");
06781 return(-1);
06782 }
06783
06784
06785 schema = xmlRelaxNGParse(rngpctx);
06786 if (schema == NULL) {
06787 printf("Error: unable to parse a schema definition resource");
06788 return(-1);
06789 }
06790
06791
06792 rngctx = xmlRelaxNGNewValidCtxt(schema);
06793 if (rngctx == NULL) {
06794 printf("Error: unable to create RelaxNGs validation context based on the schema");
06795 return(-1);
06796 }
06797
06798
06799 status = xmlRelaxNGValidateDoc(rngctx,doc);
06800 if (status != 0) {
06801 printf("Error validating file \"%s\"", filename);
06802 return(-1);
06803 }
06804
06805
06806
06807 xpathCtx = xmlXPathNewContext(doc);
06808 if(xpathCtx == NULL) {
06809 printf("Error: unable to create new XPath context");
06810 xmlFreeDoc(doc);
06811 return(-1);
06812 }
06813
06814
06815 xpathObj = xmlXPathEvalExpression(group_expr, xpathCtx);
06816 if(xpathObj == NULL) {
06817 printf("Error: unable to evaluate xpath expression: %s", group_expr);
06818 xmlXPathFreeContext(xpathCtx);
06819 xmlFreeDoc(doc);
06820 return(-1);
06821 }
06822 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
06823 temp_char = (char*) xmlXPathCastToString(xpathObj);
06824 StrAppend(&groupname, temp_char);
06825 StrFree(temp_char);
06826 xmlXPathFreeObject(xpathObj);
06827 } else {
06828 groupname = NULL;
06829 }
06830
06831
06832 xpathObj = xmlXPathEvalExpression(user_expr, xpathCtx);
06833 if(xpathObj == NULL) {
06834 printf("Error: unable to evaluate xpath expression: %s", user_expr);
06835 xmlXPathFreeContext(xpathCtx);
06836 xmlFreeDoc(doc);
06837 return(-1);
06838 }
06839 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
06840 temp_char = (char*) xmlXPathCastToString(xpathObj);
06841 StrAppend(&username, temp_char);
06842 StrFree(temp_char);
06843 xmlXPathFreeObject(xpathObj);
06844 } else {
06845 username = NULL;
06846 }
06847
06848
06849 xmlXPathFreeContext(xpathCtx);
06850 xmlRelaxNGFree(schema);
06851 xmlRelaxNGFreeValidCtxt(rngctx);
06852 xmlRelaxNGFreeParserCtxt(rngpctx);
06853 xmlFreeDoc(doc);
06854 xmlFreeDoc(rngdoc);
06855
06856
06857 if (username != NULL) {
06858
06859 if ((pwd = getpwnam(username)) == NULL) {
06860 printf("user '%s' does not exist. cannot chown %s...\n", username, dbschema);
06861 return(1);
06862 } else {
06863 uid = pwd->pw_uid;
06864 }
06865 endpwent();
06866 }
06867 if (groupname) {
06868
06869 if ((grp = getgrnam(groupname)) == NULL) {
06870 printf("group '%s' does not exist. cannot chown %s...\n", groupname, dbschema);
06871 exit(1);
06872 } else {
06873 gid = grp->gr_gid;
06874 }
06875 endgrent();
06876 }
06877
06878
06879 if (chown(dbschema, uid, gid) == -1) {
06880 printf("cannot chown(%u,%u) %s: %s",
06881 (unsigned) uid, (unsigned) gid, dbschema, strerror(errno));
06882 return -1;
06883 }
06884
06885
06886 temp_char = NULL;
06887 StrAppend(&temp_char, dbschema);
06888 StrAppend(&temp_char, ".our_lock");
06889
06890 if (chown(temp_char, uid, gid) == -1) {
06891 printf("cannot chown(%u,%u) %s: %s",
06892 (unsigned) uid, (unsigned) gid, temp_char, strerror(errno));
06893 StrFree(temp_char);
06894 return -1;
06895 }
06896
06897 StrFree(temp_char);
06898
06899 return 0;
06900 }
06901
06902
06903
06904
06905
06906
06907
06908
06909
06910
06911
06912
06913
06914
06915
06916
06917
06918
06919
06920
06921
06922
06923
06924
06925
06926
06927
06928
06929
06930
06931
06932
06933
06934 int CountKeys(int *zone_id, int keytag, const char *cka_id, int *key_count, char **temp_cka_id, int *temp_key_state, int *temp_keypair_id)
06935 {
06936 char* sql = NULL;
06937 int status = 0;
06938 char stringval[KSM_INT_STR_SIZE];
06939 DB_RESULT result;
06940 DB_ROW row = NULL;
06941
06942 char buffer[256];
06943 size_t nchar;
06944
06945 int done_row = 0;
06946
06947 int temp_zone_id = 0;
06948 char* temp_loc = NULL;
06949 int temp_alg = 0;
06950 int temp_state = 0;
06951 int temp_keypair = 0;
06952
06953 int temp_count = 0;
06954
06955
06956 hsm_key_t *key = NULL;
06957 ldns_rr *dnskey_rr = NULL;
06958 hsm_sign_params_t *sign_params = NULL;
06959
06960
06961 status = hsm_open(config, hsm_prompt_pin, NULL);
06962 if (status) {
06963 hsm_print_error(NULL);
06964 return(-1);
06965 }
06966
06967
06968 nchar = snprintf(buffer, sizeof(buffer), "(%d, %d, %d)",
06969 KSM_STATE_READY, KSM_STATE_ACTIVE, KSM_STATE_DSSUB);
06970 if (nchar >= sizeof(buffer)) {
06971 printf("Error: Overran buffer in CountKeys\n");
06972 return(-1);
06973 }
06974
06975
06976 StrAppend(&sql, "select k.zone_id, k.location, k.algorithm, k.state, k.id from KEYDATA_VIEW k where state in ");
06977 StrAppend(&sql, buffer);
06978 StrAppend(&sql, " and zone_id is not null and k.keytype = 257");
06979
06980 if (*zone_id != -1) {
06981 StrAppend(&sql, " and zone_id = ");
06982 snprintf(stringval, KSM_INT_STR_SIZE, "%d", *zone_id);
06983 StrAppend(&sql, stringval);
06984 }
06985 if (cka_id != NULL) {
06986 StrAppend(&sql, " and k.location = '");
06987 StrAppend(&sql, cka_id);
06988 StrAppend(&sql, "'");
06989 }
06990
06991 StrAppend(&sql, " group by location");
06992
06993 DusEnd(&sql);
06994
06995 status = DbExecuteSql(DbHandle(), sql, &result);
06996
06997
06998
06999
07000
07001 if (status == 0) {
07002 status = DbFetchRow(result, &row);
07003 while (status == 0) {
07004
07005 DbInt(row, 0, &temp_zone_id);
07006 DbString(row, 1, &temp_loc);
07007 DbInt(row, 2, &temp_alg);
07008 DbInt(row, 3, &temp_state);
07009 DbInt(row, 4, &temp_keypair);
07010
07011 done_row = 0;
07012
07013 if (keytag == -1 && cka_id == NULL)
07014 {
07015 *temp_key_state = temp_state;
07016 }
07017
07018 key = hsm_find_key_by_id(NULL, temp_loc);
07019 if (!key) {
07020 printf("cka_id %-33s in DB but NOT IN repository\n", temp_loc);
07021 } else if (keytag != -1) {
07022 sign_params = hsm_sign_params_new();
07023 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "temp_zone");
07024 sign_params->algorithm = temp_alg;
07025 sign_params->flags = LDNS_KEY_ZONE_KEY;
07026 sign_params->flags += LDNS_KEY_SEP_KEY;
07027
07028 dnskey_rr = hsm_get_dnskey(NULL, key, sign_params);
07029 sign_params->keytag = ldns_calc_keytag(dnskey_rr);
07030
07031
07032 if (keytag == sign_params->keytag) {
07033 temp_count++;
07034 done_row = 1;
07035 *temp_cka_id = NULL;
07036 StrAppend(temp_cka_id, temp_loc);
07037 *zone_id = temp_zone_id;
07038 *temp_key_state = temp_state;
07039 *temp_keypair_id = temp_keypair;
07040 printf("Found key with CKA_ID %s\n", temp_loc);
07041 }
07042
07043 hsm_sign_params_free(sign_params);
07044 }
07045 if (key && cka_id != NULL && strncmp(cka_id, temp_loc, strlen(temp_loc)) == 0) {
07046
07047 if (done_row == 0) {
07048 temp_count++;
07049 *temp_cka_id = NULL;
07050 StrAppend(temp_cka_id, temp_loc);
07051 *zone_id = temp_zone_id;
07052 *temp_key_state = temp_state;
07053 *temp_keypair_id = temp_keypair;
07054 printf("Found key with CKA_ID %s\n", temp_loc);
07055 }
07056 }
07057
07058 if (key) {
07059 hsm_key_free(key);
07060 }
07061
07062 status = DbFetchRow(result, &row);
07063 }
07064
07065
07066
07067 if (status == -1) {
07068 status = 0;
07069 }
07070
07071 DbFreeResult(result);
07072 }
07073
07074 *key_count = temp_count;
07075
07076 DusFree(sql);
07077 DbFreeRow(row);
07078
07079 DbStringFree(temp_loc);
07080
07081 if (dnskey_rr != NULL) {
07082 ldns_rr_free(dnskey_rr);
07083 }
07084
07085 return status;
07086 }
07087
07088
07089
07090
07091
07092
07093
07094
07095
07096
07097
07098
07099
07100
07101
07102
07103
07104
07105
07106
07107
07108
07109
07110
07111
07112
07113
07114
07115 int MarkDSSeen(int keypair_id, int zone_id, int policy_id, const char *datetime, int key_state)
07116 {
07117 char* sql1 = NULL;
07118 int status = 0;
07119
07120 char buffer[KSM_SQL_SIZE];
07121 unsigned int nchar;
07122
07123 KSM_PARCOLL collection;
07124 int deltat;
07125
07126 (void) zone_id;
07127
07128
07129 KsmCollectionInit(&collection);
07130
07131
07132 status = KsmParameterCollection(&collection, policy_id);
07133 if (status != 0) {
07134 printf("Error: failed to read policy\n");
07135 return status;
07136 }
07137
07138
07139 status = DbBeginTransaction();
07140 if (status != 0) {
07141
07142
07143 MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
07144 return status;
07145 }
07146
07147
07148 if (key_state == KSM_STATE_READY) {
07149
07150
07151
07152 deltat = collection.ksklife;
07153
07154 #ifdef USE_MYSQL
07155 nchar = snprintf(buffer, sizeof(buffer),
07156 "DATE_ADD('%s', INTERVAL %d SECOND) ", datetime, deltat);
07157 #else
07158 nchar = snprintf(buffer, sizeof(buffer),
07159 "DATETIME('%s', '+%d SECONDS') ", datetime, deltat);
07160 #endif
07161
07162 sql1 = DusInit("dnsseckeys");
07163 DusSetInt(&sql1, "STATE", KSM_STATE_ACTIVE, 0);
07164 DusSetString(&sql1, KsmKeywordStateValueToName(KSM_STATE_ACTIVE), datetime, 1);
07165 StrAppend(&sql1, ", RETIRE = ");
07166 StrAppend(&sql1, buffer);
07167
07168 DusConditionInt(&sql1, "KEYPAIR_ID", DQS_COMPARE_EQ, keypair_id, 0);
07169 DusConditionInt(&sql1, "ZONE_ID", DQS_COMPARE_EQ, zone_id, 1);
07170 DusEnd(&sql1);
07171 }
07172 else {
07173
07174
07175
07176 deltat = collection.kskttl + collection.kskpropdelay +
07177 collection.pub_safety;
07178
07179 #ifdef USE_MYSQL
07180 nchar = snprintf(buffer, sizeof(buffer),
07181 "DATE_ADD('%s', INTERVAL %d SECOND) ", datetime, deltat);
07182 #else
07183 nchar = snprintf(buffer, sizeof(buffer),
07184 "DATETIME('%s', '+%d SECONDS') ", datetime, deltat);
07185 #endif
07186
07187 sql1 = DusInit("dnsseckeys");
07188 DusSetInt(&sql1, "STATE", KSM_STATE_DSPUBLISH, 0);
07189 DusSetString(&sql1, KsmKeywordStateValueToName(KSM_STATE_PUBLISH), datetime, 1);
07190 StrAppend(&sql1, ", READY = ");
07191 StrAppend(&sql1, buffer);
07192
07193 DusConditionInt(&sql1, "KEYPAIR_ID", DQS_COMPARE_EQ, keypair_id, 0);
07194 DusConditionInt(&sql1, "ZONE_ID", DQS_COMPARE_EQ, zone_id, 1);
07195 DusEnd(&sql1);
07196 }
07197
07198 status = DbExecuteSqlNoResult(DbHandle(), sql1);
07199 DusFree(sql1);
07200
07201
07202 if (status != 0) {
07203 status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
07204 DbRollback();
07205 return status;
07206 }
07207
07208
07209 if (status == 0) {
07210
07211 DbCommit();
07212 } else {
07213
07214 DbRollback();
07215 }
07216
07217 return status;
07218 }
07219
07220
07221
07222
07223
07224
07225
07226
07227
07228
07229
07230
07231
07232
07233
07234
07235
07236
07237
07238
07239
07240
07241 int RetireOldKey(int zone_id, int policy_id, const char *datetime)
07242 {
07243 char* sql2 = NULL;
07244 int status = 0;
07245 char* where_clause = NULL;
07246 int id = -1;
07247
07248 char stringval[KSM_INT_STR_SIZE];
07249 char buffer[KSM_SQL_SIZE];
07250 unsigned int nchar;
07251
07252 KSM_PARCOLL collection;
07253 int deltat;
07254
07255
07256 KsmCollectionInit(&collection);
07257
07258
07259 status = KsmParameterCollection(&collection, policy_id);
07260 if (status != 0) {
07261 printf("Error: failed to read policy\n");
07262 return status;
07263 }
07264
07265
07266 status = DbBeginTransaction();
07267 if (status != 0) {
07268
07269
07270 MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
07271 return status;
07272 }
07273
07274
07275
07276 snprintf(stringval, KSM_INT_STR_SIZE, "%d", zone_id);
07277 StrAppend(&where_clause, "select id from KEYDATA_VIEW where state = 4 and keytype = 257 and zone_id = ");
07278 StrAppend(&where_clause, stringval);
07279 StrAppend(&where_clause, " and retire = (select min(retire) from KEYDATA_VIEW where state = 4 and keytype = 257 and zone_id = ");
07280 StrAppend(&where_clause, stringval);
07281 StrAppend(&where_clause, ")");
07282
07283
07284 status = DbIntQuery(DbHandle(), &id, where_clause);
07285 StrFree(where_clause);
07286 if (status != 0)
07287 {
07288 printf("Error: failed to find ID of key to retire\n");
07289 DbRollback();
07290 return status;
07291 }
07292
07293
07294 deltat = collection.dsttl + collection.kskpropdelay + collection.ret_safety;
07295
07296 #ifdef USE_MYSQL
07297 nchar = snprintf(buffer, sizeof(buffer),
07298 "DATE_ADD('%s', INTERVAL %d SECOND) ", datetime, deltat);
07299 #else
07300 nchar = snprintf(buffer, sizeof(buffer),
07301 "DATETIME('%s', '+%d SECONDS') ", datetime, deltat);
07302 #endif
07303
07304 sql2 = DusInit("dnsseckeys");
07305 DusSetInt(&sql2, "STATE", KSM_STATE_RETIRE, 0);
07306 DusSetString(&sql2, KsmKeywordStateValueToName(KSM_STATE_RETIRE), datetime, 1);
07307 StrAppend(&sql2, ", DEAD = ");
07308 StrAppend(&sql2, buffer);
07309 DusConditionInt(&sql2, "keypair_id", DQS_COMPARE_EQ, id, 0);
07310 DusConditionInt(&sql2, "ZONE_ID", DQS_COMPARE_EQ, zone_id, 1);
07311
07312 status = DbExecuteSqlNoResult(DbHandle(), sql2);
07313 DusFree(sql2);
07314
07315
07316 if (status != 0) {
07317 status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
07318 DbRollback();
07319 return status;
07320 }
07321
07322
07323 if (status == 0) {
07324
07325 DbCommit();
07326 } else {
07327
07328 DbRollback();
07329 }
07330
07331 return status;
07332 }
07333
07334
07335
07336
07337
07338
07339
07340
07341
07342
07343
07344
07345
07346
07347
07348
07349
07350
07351
07352
07353
07354
07355
07356
07357
07358
07359 int CountKeysInState(int keytype, int keystate, int* count, int zone_id)
07360 {
07361 int clause = 0;
07362 char* sql = NULL;
07363 int status;
07364
07365 sql = DqsCountInit("KEYDATA_VIEW");
07366 DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
07367 DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, keystate, clause++);
07368 if (zone_id != -1) {
07369 DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
07370 }
07371 DqsEnd(&sql);
07372
07373 status = DbIntQuery(DbHandle(), count, sql);
07374 DqsFree(sql);
07375
07376 if (status != 0) {
07377 printf("Error in CountKeysInState\n");
07378 }
07379
07380 return status;
07381 }
07382
07383
07384
07385
07386
07387
07388
07389
07390
07391
07392
07393
07394
07395
07396
07397
07398
07399
07400
07401
07402
07403
07404
07405
07406
07407
07408
07409
07410
07411
07412
07413
07414 int ChangeKeyState(int keytype, const char *cka_id, int zone_id, int policy_id, const char *datetime, int keystate)
07415 {
07416 char* sql1 = NULL;
07417 int status = 0;
07418
07419 int count = 0;
07420 char* sql = NULL;
07421 int where = 0;
07422 int i = 0;
07423 int j = 0;
07424 char* insql = NULL;
07425 int* keyids;
07426 DB_RESULT result;
07427 KSM_KEYDATA data;
07428
07429 char buffer[KSM_SQL_SIZE];
07430 unsigned int nchar;
07431
07432 KSM_PARCOLL collection;
07433 int deltat = 0;
07434
07435 (void) zone_id;
07436
07437
07438 KsmCollectionInit(&collection);
07439
07440
07441 status = KsmParameterCollection(&collection, policy_id);
07442 if (status != 0) {
07443 printf("Error: failed to read policy\n");
07444 return status;
07445 }
07446
07447
07448
07449 sql = DqsCountInit("KEYDATA_VIEW");
07450 DqsConditionString(&sql, "location", DQS_COMPARE_EQ, cka_id, where++);
07451 if (zone_id != -1) {
07452 DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, where++);
07453 }
07454 DqsEnd(&sql);
07455
07456 status = DbIntQuery(DbHandle(), &count, sql);
07457 DqsFree(sql);
07458
07459 if (status != 0) {
07460 status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
07461 return status;
07462 }
07463
07464 if (count == 0) {
07465
07466 return status;
07467 }
07468
07469
07470 keyids = MemMalloc(count * sizeof(int));
07471
07472
07473
07474 where = 0;
07475 sql = DqsSpecifyInit("KEYDATA_VIEW", DB_KEYDATA_FIELDS);
07476 DqsConditionString(&sql, "location", DQS_COMPARE_EQ, cka_id, where++);
07477 if (zone_id != -1) {
07478 DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, where++);
07479 }
07480 DqsEnd(&sql);
07481
07482 status = KsmKeyInitSql(&result, sql);
07483 DqsFree(sql);
07484
07485 if (status == 0) {
07486 while (status == 0) {
07487 status = KsmKey(result, &data);
07488 if (status == 0) {
07489 keyids[i] = data.keypair_id;
07490 i++;
07491 }
07492 }
07493
07494
07495
07496 if (status == -1) {
07497 status = 0;
07498 } else {
07499 status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
07500 StrFree(keyids);
07501 return status;
07502 }
07503
07504 KsmKeyEnd(result);
07505
07506 } else {
07507 status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
07508 StrFree(keyids);
07509 return status;
07510 }
07511
07512
07513
07514
07515
07516
07517 StrAppend(&insql, "(");
07518 for (j = 0; j < i; ++j) {
07519 if (j != 0) {
07520 StrAppend(&insql, ",");
07521 }
07522 snprintf(buffer, sizeof(buffer), "%d", keyids[j]);
07523 StrAppend(&insql, buffer);
07524 }
07525 StrAppend(&insql, ")");
07526
07527
07528 status = DbBeginTransaction();
07529 if (status != 0) {
07530
07531
07532 MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
07533 StrFree(keyids);
07534 return status;
07535 }
07536
07537
07538 if (keystate == KSM_STATE_ACTIVE) {
07539
07540
07541
07542 deltat = collection.ksklife;
07543
07544 #ifdef USE_MYSQL
07545 nchar = snprintf(buffer, sizeof(buffer),
07546 "DATE_ADD('%s', INTERVAL %d SECOND) ", datetime, deltat);
07547 #else
07548 nchar = snprintf(buffer, sizeof(buffer),
07549 "DATETIME('%s', '+%d SECONDS') ", datetime, deltat);
07550 #endif
07551
07552 sql1 = DusInit("dnsseckeys");
07553 DusSetInt(&sql1, "STATE", KSM_STATE_ACTIVE, 0);
07554 DusSetString(&sql1, KsmKeywordStateValueToName(KSM_STATE_ACTIVE), datetime, 1);
07555 StrAppend(&sql1, ", RETIRE = ");
07556 StrAppend(&sql1, buffer);
07557
07558 DusConditionKeyword(&sql1, "KEYPAIR_ID", DQS_COMPARE_IN, insql, 0);
07559 if (zone_id != -1) {
07560 DusConditionInt(&sql1, "ZONE_ID", DQS_COMPARE_EQ, zone_id, 1);
07561 }
07562 DusEnd(&sql1);
07563 }
07564 else if (keystate == KSM_STATE_RETIRE) {
07565
07566
07567
07568 if (keytype == KSM_TYPE_ZSK) {
07569 deltat = collection.zsksiglife + collection.propdelay + collection.ret_safety;
07570 }
07571 else if (keytype == KSM_TYPE_KSK) {
07572 deltat = collection.kskttl + collection.kskpropdelay +
07573 collection.ret_safety;
07574 }
07575
07576 #ifdef USE_MYSQL
07577 nchar = snprintf(buffer, sizeof(buffer),
07578 "DATE_ADD('%s', INTERVAL %d SECOND) ", datetime, deltat);
07579 #else
07580 nchar = snprintf(buffer, sizeof(buffer),
07581 "DATETIME('%s', '+%d SECONDS') ", datetime, deltat);
07582 #endif
07583
07584 sql1 = DusInit("dnsseckeys");
07585 DusSetInt(&sql1, "STATE", KSM_STATE_RETIRE, 0);
07586 DusSetString(&sql1, KsmKeywordStateValueToName(KSM_STATE_RETIRE), datetime, 1);
07587 StrAppend(&sql1, ", DEAD = ");
07588 StrAppend(&sql1, buffer);
07589
07590 DusConditionKeyword(&sql1, "KEYPAIR_ID", DQS_COMPARE_IN, insql, 0);
07591 if (zone_id != -1) {
07592 DusConditionInt(&sql1, "ZONE_ID", DQS_COMPARE_EQ, zone_id, 1);
07593 }
07594 DusEnd(&sql1);
07595 }
07596 else if (keystate == KSM_STATE_DSPUBLISH) {
07597
07598 deltat = collection.kskttl + collection.kskpropdelay +
07599 collection.pub_safety;
07600
07601 #ifdef USE_MYSQL
07602 nchar = snprintf(buffer, sizeof(buffer),
07603 "DATE_ADD('%s', INTERVAL %d SECOND) ", datetime, deltat);
07604 #else
07605 nchar = snprintf(buffer, sizeof(buffer),
07606 "DATETIME('%s', '+%d SECONDS') ", datetime, deltat);
07607 #endif
07608
07609 sql1 = DusInit("dnsseckeys");
07610 DusSetInt(&sql1, "STATE", KSM_STATE_DSPUBLISH, 0);
07611 DusSetString(&sql1, KsmKeywordStateValueToName(KSM_STATE_PUBLISH), datetime, 1);
07612 StrAppend(&sql1, ", READY = ");
07613 StrAppend(&sql1, buffer);
07614
07615 DusConditionKeyword(&sql1, "KEYPAIR_ID", DQS_COMPARE_IN, insql, 0);
07616 if (zone_id != -1) {
07617 DusConditionInt(&sql1, "ZONE_ID", DQS_COMPARE_EQ, zone_id, 1);
07618 }
07619 DusEnd(&sql1);
07620 }
07621 else {
07622 printf("Moving to keystate %s not implemented yet\n", KsmKeywordStateValueToName(keystate));
07623 StrFree(keyids);
07624 return -1;
07625 }
07626
07627 status = DbExecuteSqlNoResult(DbHandle(), sql1);
07628 DusFree(sql1);
07629
07630 StrFree(keyids);
07631
07632
07633 if (status != 0) {
07634 status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
07635 DbRollback();
07636 return status;
07637 }
07638
07639
07640 if (status == 0) {
07641
07642 DbCommit();
07643 } else {
07644
07645 DbRollback();
07646 }
07647
07648 return status;
07649 }
07650
07651 static int restart_enforcerd()
07652 {
07653
07654
07655 return system(RESTART_ENFORCERD_CMD);
07656 }
07657
07658
07659
07660
07661
07662
07663 int get_conf_key_info(int* interval, int* man_key_gen)
07664 {
07665 int status = 0;
07666 int mysec = 0;
07667 xmlDocPtr doc = NULL;
07668 xmlXPathContextPtr xpathCtx = NULL;
07669 xmlXPathObjectPtr xpathObj = NULL;
07670 char* temp_char = NULL;
07671
07672 xmlChar *iv_expr = (unsigned char*) "//Configuration/Enforcer/Interval";
07673 xmlChar *mk_expr = (unsigned char*) "//Configuration/Enforcer/ManualKeyGeneration";
07674
07675
07676 doc = xmlParseFile(config);
07677 if (doc == NULL) {
07678 printf("Error: unable to parse file \"%s\"\n", config);
07679 return(-1);
07680 }
07681
07682
07683 xpathCtx = xmlXPathNewContext(doc);
07684 if(xpathCtx == NULL) {
07685 printf("Error: unable to create new XPath context\n");
07686 xmlFreeDoc(doc);
07687 return(-1);
07688 }
07689
07690
07691 xpathObj = xmlXPathEvalExpression(iv_expr, xpathCtx);
07692 if(xpathObj == NULL) {
07693 printf("Error: unable to evaluate xpath expression: %s", iv_expr);
07694 xmlXPathFreeContext(xpathCtx);
07695 xmlFreeDoc(doc);
07696 return(-1);
07697 }
07698
07699 temp_char = (char *)xmlXPathCastToString(xpathObj);
07700 status = DtXMLIntervalSeconds(temp_char, &mysec);
07701 if (status > 0) {
07702 printf("Error: unable to convert Interval %s to seconds, error: %i\n", temp_char, status);
07703 StrFree(temp_char);
07704 return status;
07705 }
07706 else if (status == -1) {
07707 printf("Info: converting %s to seconds; M interpreted as 31 days, Y interpreted as 365 days\n", temp_char);
07708 }
07709 *interval = mysec;
07710 StrFree(temp_char);
07711 xmlXPathFreeObject(xpathObj);
07712
07713
07714 xpathObj = xmlXPathEvalExpression(mk_expr, xpathCtx);
07715 if(xpathObj == NULL) {
07716 printf("Error: unable to evaluate xpath expression: %s\n", mk_expr);
07717 xmlXPathFreeContext(xpathCtx);
07718 xmlFreeDoc(doc);
07719 return(-1);
07720 }
07721
07722 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
07723
07724 *man_key_gen = 1;
07725 }
07726 else {
07727
07728 *man_key_gen = 0;
07729 }
07730 xmlXPathFreeObject(xpathObj);
07731
07732 if (xpathCtx) {
07733 xmlXPathFreeContext(xpathCtx);
07734 }
07735 if (doc) {
07736 xmlFreeDoc(doc);
07737 }
07738
07739 return 0;
07740 }
07741
07742
07743
07744
07745
07746
07747
07748
07749
07750
07751
07752
07753
07754
07755
07756
07757
07758
07759
07760
07761
07762
07763
07764
07765
07766
07767
07768 int LinkKeys(const char* zone_name, int policy_id)
07769 {
07770 int status = 0;
07771
07772 int interval = -1;
07773 int man_key_gen = -1;
07774
07775 int zone_id = 0;
07776 KSM_POLICY* policy;
07777
07778
07779 (void)policy_id;
07780
07781
07782 status = get_conf_key_info(&interval, &man_key_gen);
07783 if (status != 0) {
07784 printf("Failed to Link Keys to zone\n");
07785 return(1);
07786 }
07787
07788 status = KsmZoneIdFromName(zone_name, &zone_id);
07789 if (status != 0) {
07790 return(status);
07791 }
07792
07793 policy = KsmPolicyAlloc();
07794 if (policy == NULL) {
07795 printf("Malloc for policy struct failed\n");
07796 exit(1);
07797 }
07798 SetPolicyDefaults(policy, o_policy);
07799
07800 status = KsmPolicyExists(o_policy);
07801 if (status == 0) {
07802
07803 status = KsmPolicyRead(policy);
07804 if(status != 0) {
07805 printf("Error: unable to read policy %s from database\n", o_policy);
07806 KsmPolicyFree(policy);
07807 return status;
07808 }
07809 } else {
07810 printf("Error: policy %s doesn't exist in database\n", o_policy);
07811 KsmPolicyFree(policy);
07812 return status;
07813 }
07814
07815
07816 status = allocateKeysToZone(policy, KSM_TYPE_ZSK, zone_id, interval, zone_name, man_key_gen, 0);
07817 if (status != 0) {
07818 printf("Error allocating zsks to zone %s", zone_name);
07819 KsmPolicyFree(policy);
07820 return(status);
07821 }
07822 status = allocateKeysToZone(policy, KSM_TYPE_KSK, zone_id, interval, zone_name, man_key_gen, policy->ksk->rollover_scheme);
07823 if (status != 0) {
07824 printf("Error allocating ksks to zone %s", zone_name);
07825 KsmPolicyFree(policy);
07826 return(status);
07827 }
07828
07829 KsmPolicyFree(policy);
07830 return 0;
07831 }
07832
07833
07834
07835
07836
07837
07838
07839
07840
07841
07842
07843
07844
07845
07846
07847
07848
07849
07850
07851
07852
07853
07854
07855
07856
07857
07858
07859
07860
07861
07862
07863 int allocateKeysToZone(KSM_POLICY *policy, int key_type, int zone_id, uint16_t interval, const char* zone_name, int man_key_gen, int rollover_scheme)
07864 {
07865 int status = 0;
07866 int keys_needed = 0;
07867 int keys_in_queue = 0;
07868 int keys_pending_retirement = 0;
07869 int new_keys = 0;
07870 int key_pair_id = 0;
07871 int i = 0;
07872 DB_ID ignore = 0;
07873 KSM_PARCOLL collection;
07874 char* datetime = DtParseDateTimeString("now");
07875
07876
07877 if (datetime == NULL) {
07878 printf("Couldn't turn \"now\" into a date, quitting...");
07879 exit(1);
07880 }
07881
07882 if (policy == NULL) {
07883 printf("NULL policy sent to allocateKeysToZone");
07884 StrFree(datetime);
07885 return 1;
07886 }
07887
07888 if (key_type != KSM_TYPE_KSK && key_type != KSM_TYPE_ZSK) {
07889 printf("Unknown keytype: %i in allocateKeysToZone", key_type);
07890 StrFree(datetime);
07891 return 1;
07892 }
07893
07894
07895 status = KsmParameterCollection(&collection, policy->id);
07896 if (status != 0) {
07897 StrFree(datetime);
07898 return status;
07899 }
07900
07901
07902
07903 status = KsmKeyPredict(policy->id, key_type, 1, interval, &keys_needed, rollover_scheme, 1);
07904 if (status != 0) {
07905 printf("Could not predict key requirement for next interval for %s", zone_name);
07906 StrFree(datetime);
07907 return 3;
07908 }
07909
07910
07911 status = KsmKeyCountQueue(key_type, &keys_in_queue, zone_id);
07912 if (status != 0) {
07913 printf("Could not count current key numbers for zone %s", zone_name);
07914 StrFree(datetime);
07915 return 3;
07916 }
07917
07918
07919 status = KsmRequestPendingRetireCount(key_type, datetime, &collection, &keys_pending_retirement, zone_id, interval);
07920 if (status != 0) {
07921 printf("Could not count keys which may retire before the next run (for zone %s)", zone_name);
07922 StrFree(datetime);
07923 return 3;
07924 }
07925
07926 StrFree(datetime);
07927 new_keys = keys_needed - (keys_in_queue - keys_pending_retirement);
07928
07929
07930
07931
07932 for (i=0 ; i < new_keys ; i++){
07933 key_pair_id = 0;
07934 if (key_type == KSM_TYPE_KSK) {
07935 status = KsmKeyGetUnallocated(policy->id, policy->ksk->sm, policy->ksk->bits, policy->ksk->algorithm, zone_id, policy->keys->share_keys, &key_pair_id);
07936 if (status == -1 || key_pair_id == 0) {
07937 if (man_key_gen == 0) {
07938 printf("Not enough keys to satisfy ksk policy for zone: %s", zone_name);
07939 printf("ods-enforcerd will create some more keys on its next run");
07940 }
07941 else {
07942 printf("Not enough keys to satisfy ksk policy for zone: %s", zone_name);
07943 printf("please use \"ods-ksmutil key generate\" to create some more keys.");
07944 }
07945 return 2;
07946 }
07947 else if (status != 0) {
07948 printf("Could not get an unallocated ksk for zone: %s", zone_name);
07949 return 3;
07950 }
07951 } else {
07952 status = KsmKeyGetUnallocated(policy->id, policy->zsk->sm, policy->zsk->bits, policy->zsk->algorithm, zone_id, policy->keys->share_keys, &key_pair_id);
07953 if (status == -1 || key_pair_id == 0) {
07954 if (man_key_gen == 0) {
07955 printf("Not enough keys to satisfy zsk policy for zone: %s", zone_name);
07956 printf("ods-enforcerd will create some more keys on its next run");
07957 }
07958 else {
07959 printf("Not enough keys to satisfy zsk policy for zone: %s", zone_name);
07960 printf("please use \"ods-ksmutil key generate\" to create some more keys.");
07961 }
07962 return 2;
07963 }
07964 else if (status != 0) {
07965 printf("Could not get an unallocated zsk for zone: %s", zone_name);
07966 return 3;
07967 }
07968 }
07969 if(key_pair_id > 0) {
07970 status = KsmDnssecKeyCreate(zone_id, key_pair_id, key_type, KSM_STATE_GENERATE, datetime, &ignore);
07971
07972 } else {
07973
07974 printf("KsmKeyGetUnallocated returned bad key_id %d for zone: %s; exiting...", key_pair_id, zone_name);
07975 exit(1);
07976 }
07977
07978 }
07979
07980 return status;
07981 }
07982
07983
07984
07985
07986
07987
07988
07989
07990
07991
07992
07993
07994
07995
07996
07997
07998
07999
08000
08001
08002 int keyRoll(int zone_id, int policy_id, int key_type)
08003 {
08004
08005 int status = 0;
08006 int size = -1;
08007
08008 char* sql = NULL;
08009 char* sql1 = NULL;
08010 char sql2[KSM_SQL_SIZE];
08011 DB_RESULT result1;
08012 DB_ROW row = NULL;
08013 int temp_id = -1;
08014 int temp_type = -1;
08015 int temp_zone_id = -1;
08016 int where = 0;
08017 int j = 0;
08018 DB_RESULT result2;
08019 DB_RESULT result3;
08020 DB_ROW row2 = NULL;
08021 char* insql1 = NULL;
08022 char* insql2 = NULL;
08023 char buffer[32];
08024
08025 char* datetime = DtParseDateTimeString("now");
08026
08027
08028 if (datetime == NULL) {
08029 printf("Couldn't turn \"now\" into a date, quitting...\n");
08030 StrFree(datetime);
08031 exit(1);
08032 }
08033
08034
08035
08036 sql = DqsSpecifyInit("KEYDATA_VIEW","id, keytype");
08037 if (zone_id != -1) {
08038 DqsConditionInt(&sql, "zone_id", DQS_COMPARE_EQ, zone_id, where++);
08039 }
08040 if (policy_id != -1) {
08041 DqsConditionInt(&sql, "policy_id", DQS_COMPARE_EQ, policy_id, where++);
08042 }
08043 DqsConditionInt(&sql, "state", DQS_COMPARE_EQ, KSM_STATE_ACTIVE, where++);
08044 if (key_type != -1) {
08045 DqsConditionInt(&sql, "keytype", DQS_COMPARE_EQ, key_type, where++);
08046 }
08047 DqsEnd(&sql);
08048
08049 status = DbExecuteSql(DbHandle(), sql, &result1);
08050
08051 if (status == 0) {
08052 status = DbFetchRow(result1, &row);
08053 while (status == 0) {
08054
08055 DbInt(row, 0, &temp_id);
08056 DbInt(row, 1, &temp_type);
08057
08058 sql1 = DusInit("keypairs");
08059 DusSetInt(&sql1, "fixedDate", 1, 0);
08060 DusSetInt(&sql1, "compromisedflag", 1, 1);
08061
08062 DusConditionInt(&sql1, "id", DQS_COMPARE_EQ, temp_id, 0);
08063 DusEnd(&sql1);
08064 status = DbExecuteSqlNoResult(DbHandle(), sql1);
08065 DusFree(sql1);
08066
08067
08068 if (status != 0) {
08069 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
08070 DbFreeRow(row);
08071 return status;
08072 }
08073
08074
08075
08076 sql1 = DusInit("dnsseckeys");
08077 DusSetString(&sql1, "RETIRE", datetime, 0);
08078
08079 DusConditionInt(&sql1, "keypair_id", DQS_COMPARE_EQ, temp_id, 0);
08080 DusConditionInt(&sql1, "state", DQS_COMPARE_EQ, KSM_STATE_ACTIVE, 1);
08081 DusEnd(&sql1);
08082 status = DbExecuteSqlNoResult(DbHandle(), sql1);
08083 DusFree(sql1);
08084
08085
08086 if (status != 0) {
08087 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
08088 DbFreeRow(row);
08089 return status;
08090 }
08091
08092
08093 sql1 = DusInit("dnsseckeys");
08094 DusSetString(&sql1, "DEAD", datetime, 0);
08095 DusSetInt(&sql1, "state", KSM_STATE_DEAD, 1);
08096
08097 DusConditionInt(&sql1, "keypair_id", DQS_COMPARE_EQ, temp_id, 0);
08098 DusConditionInt(&sql1, "state", DQS_COMPARE_NE, KSM_STATE_ACTIVE, 1);
08099 DusEnd(&sql1);
08100 status = DbExecuteSqlNoResult(DbHandle(), sql1);
08101 DusFree(sql1);
08102
08103
08104 if (status != 0) {
08105 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
08106 DbFreeRow(row);
08107 return status;
08108 }
08109
08110
08111
08112 if (temp_type == KSM_TYPE_KSK) {
08113
08114
08115
08116
08117
08118
08119
08120
08121 size = snprintf(sql2, KSM_SQL_SIZE, "select zone_id from dnsseckeys where retire = \"%s\" and keypair_id = %d", datetime, temp_id);
08122 status = DbExecuteSql(DbHandle(), sql2, &result2);
08123 if (status == 0) {
08124 status = DbFetchRow(result2, &row2);
08125 while (status == 0) {
08126
08127 DbInt(row2, 0, &temp_zone_id);
08128
08129 if (j != 0) {
08130 StrAppend(&insql1, ",");
08131 }
08132 snprintf(buffer, sizeof(buffer), "%d", temp_zone_id);
08133 StrAppend(&insql1, buffer);
08134 j++;
08135
08136 status = DbFetchRow(result2, &row2);
08137 }
08138
08139
08140
08141 if (status == -1) {
08142 status = 0;
08143 }
08144
08145 DbFreeResult(result2);
08146 }
08147
08148
08149
08150 size = snprintf(sql2, KSM_SQL_SIZE, "select zone_id from KEYDATA_VIEW where policy_id = %d and keytype = %d and state in (%d,%d)", policy_id, KSM_TYPE_KSK, KSM_STATE_PUBLISH, KSM_STATE_READY);
08151 j=0;
08152 status = DbExecuteSql(DbHandle(), sql2, &result3);
08153 if (status == 0) {
08154 status = DbFetchRow(result3, &row2);
08155 while (status == 0) {
08156
08157 DbInt(row2, 0, &temp_zone_id);
08158
08159 if (j != 0) {
08160 StrAppend(&insql2, ",");
08161 }
08162 snprintf(buffer, sizeof(buffer), "%d", temp_zone_id);
08163 StrAppend(&insql2, buffer);
08164 j++;
08165
08166 status = DbFetchRow(result3, &row2);
08167 }
08168
08169
08170
08171 if (status == -1) {
08172 status = 0;
08173 }
08174
08175 DbFreeResult(result3);
08176 }
08177 DbFreeRow(row2);
08178
08179
08180 size = snprintf(sql2, KSM_SQL_SIZE, "update dnsseckeys set state = %d where state = %d and zone_id in (%s) and zone_id not in (%s)", KSM_STATE_KEYPUBLISH, KSM_STATE_DSREADY, insql1, insql2);
08181
08182
08183 if (size < 0 || size >= KSM_SQL_SIZE) {
08184 printf("Couldn't construct SQL to promote standby key\n");
08185 DbFreeRow(row);
08186 return -1;
08187 }
08188
08189 status = DbExecuteSqlNoResult(DbHandle(), sql2);
08190
08191
08192 if (status != 0) {
08193 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
08194 DbFreeRow(row);
08195 return status;
08196 }
08197 }
08198
08199
08200 status = DbFetchRow(result1, &row);
08201 }
08202
08203
08204 if (status == -1) {
08205 status = 0;
08206 }
08207 DbFreeResult(result1);
08208 }
08209 DqsFree(sql);
08210 DbFreeRow(row);
08211
08212 StrFree(datetime);
08213
08214 return status;
08215 }
08216
08217 int get_policy_name_from_id(KSM_ZONE *zone)
08218 {
08219 int where = 0;
08220 char* sql = NULL;
08221 DB_RESULT result;
08222 DB_ROW row = NULL;
08223 int status = 0;
08224
08225
08226
08227 sql = DqsSpecifyInit("policies","id, name");
08228 DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, zone->policy_id, where++);
08229 DqsOrderBy(&sql, "id");
08230
08231
08232 status = DbExecuteSql(DbHandle(), sql, &result);
08233 DqsFree(sql);
08234
08235 if (status != 0)
08236 {
08237 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
08238 DbFreeResult(result);
08239 return status;
08240 }
08241
08242
08243 status = DbFetchRow(result, &row);
08244 if (status == 0) {
08245 DbStringBuffer(row, DB_POLICY_NAME, zone->policy_name, KSM_NAME_LENGTH*sizeof(char));
08246 }
08247 else if (status == -1) {}
08248
08249 else {
08250 printf("SQL failed: %s\n", DbErrmsg(DbHandle()));
08251 return status;
08252 }
08253
08254 DbFreeRow(row);
08255 DbFreeResult(result);
08256 return status;
08257 }
08258
08259 int append_zone(xmlDocPtr doc, KSM_ZONE *zone)
08260 {
08261 xmlNodePtr root;
08262 xmlNodePtr zone_node;
08263 xmlNodePtr adapters_node;
08264 xmlNodePtr input_node;
08265 xmlNodePtr output_node;
08266
08267 root = xmlDocGetRootElement(doc);
08268 if (root == NULL) {
08269 fprintf(stderr,"empty document\n");
08270 return(1);
08271 }
08272 if (xmlStrcmp(root->name, (const xmlChar *) "ZoneList")) {
08273 fprintf(stderr,"document of the wrong type, root node != %s", "ZoneList");
08274 return(1);
08275 }
08276
08277 zone_node = xmlNewTextChild(root, NULL, (const xmlChar *)"Zone", NULL);
08278 (void) xmlNewProp(zone_node, (const xmlChar *)"name", (const xmlChar *)zone->name);
08279
08280
08281 (void) xmlNewTextChild(zone_node, NULL, (const xmlChar *)"Policy", (const xmlChar *)zone->policy_name);
08282
08283
08284 (void) xmlNewTextChild(zone_node, NULL, (const xmlChar *)"SignerConfiguration", (const xmlChar *)zone->signconf);
08285
08286
08287 adapters_node = xmlNewTextChild(zone_node, NULL, (const xmlChar *)"Adapters", NULL);
08288
08289 input_node = xmlNewTextChild(adapters_node, NULL, (const xmlChar *)"Input", NULL);
08290 (void) xmlNewTextChild(input_node, NULL, (const xmlChar *)"File", (const xmlChar *)zone->input);
08291
08292 output_node = xmlNewTextChild(adapters_node, NULL, (const xmlChar *)"Output", NULL);
08293 (void) xmlNewTextChild(output_node, NULL, (const xmlChar *)"File", (const xmlChar *)zone->output);
08294
08295
08296 return(0);
08297 }
08298
08299 int ShellQuoteString(const char* string, char* buffer, size_t buflen)
08300 {
08301 size_t i;
08302 size_t j = 0;
08303
08304 size_t len = strlen(string);
08305
08306 if (string) {
08307 for (i = 0; i < len; ++i) {
08308 if (string[i] == '\'') {
08309 buffer[j++] = '\'';
08310 buffer[j++] = '\\';
08311 buffer[j++] = '\'';
08312 }
08313 buffer[j++] = string[i];
08314 }
08315 }
08316 buffer[j] = '\0';
08317 return ( (j <= buflen) ? 0 : 1);
08318 }
08319