yuri r7617 - in trunk/OpenDNSSEC/enforcer-ng/src: . keystate utils

commits at svn.opendnssec.org commits at svn.opendnssec.org
Mon Feb 3 17:32:08 CET 2014


Author: yuri
Date: Mon Feb  3 17:32:07 2014
New Revision: 7617
URL: http://fisheye.opendnssec.org/changelog/opendnssec?cs=7617

Log:
OPENDNSSEC-321

Modified:
   trunk/OpenDNSSEC/enforcer-ng/src/Makefile.am
   trunk/OpenDNSSEC/enforcer-ng/src/keystate/update_keyzones_cmd.cpp
   trunk/OpenDNSSEC/enforcer-ng/src/keystate/update_keyzones_task.cpp
   trunk/OpenDNSSEC/enforcer-ng/src/utils/kaspcheck.c
   trunk/OpenDNSSEC/enforcer-ng/src/utils/kaspcheck.h
   trunk/OpenDNSSEC/enforcer-ng/src/utils/kc_helper.c
   trunk/OpenDNSSEC/enforcer-ng/src/utils/kc_helper.h

Modified: trunk/OpenDNSSEC/enforcer-ng/src/Makefile.am
==============================================================================
--- trunk/OpenDNSSEC/enforcer-ng/src/Makefile.am	Mon Feb  3 15:30:42 2014	(r7616)
+++ trunk/OpenDNSSEC/enforcer-ng/src/Makefile.am	Mon Feb  3 17:32:07 2014	(r7617)
@@ -153,8 +153,9 @@
 	protobuf-orm/pb-orm-str.cc protobuf-orm/pb-orm-str.h \
 	protobuf-orm/pb-orm-transaction.cc protobuf-orm/pb-orm-transaction.h \
 	protobuf-orm/pb-orm-update.cc protobuf-orm/pb-orm-update.h \
-	protobuf-orm/pb-orm-value.cc protobuf-orm/pb-orm-value.h
-
+	protobuf-orm/pb-orm-value.cc protobuf-orm/pb-orm-value.h \
+	utils/kc_helper.c utils/kc_helper.h 
+	
 ods_enforcerd_LDADD = \
 	$(LIBHSM) \
     $(LIBCOMPAT) \

Modified: trunk/OpenDNSSEC/enforcer-ng/src/keystate/update_keyzones_cmd.cpp
==============================================================================
--- trunk/OpenDNSSEC/enforcer-ng/src/keystate/update_keyzones_cmd.cpp	Mon Feb  3 15:30:42 2014	(r7616)
+++ trunk/OpenDNSSEC/enforcer-ng/src/keystate/update_keyzones_cmd.cpp	Mon Feb  3 17:32:07 2014	(r7617)
@@ -66,11 +66,11 @@
     
     time_t tstart = time(NULL);
 	
-    perform_update_keyzones(sockfd,engine->config);
-
-	perform_hsmkey_gen(sockfd, engine->config, 0 /* automatic */,
-					   engine->config->automatic_keygen_duration);
-	
+    if (perform_update_keyzones(sockfd,engine->config))
+    {
+		perform_hsmkey_gen(sockfd, engine->config, 0 /* automatic */,
+			engine->config->automatic_keygen_duration);
+	}
     ods_printf(sockfd,"%s completed in %ld seconds.\n",scmd,time(NULL)-tstart);
 
     flush_enforce_task(engine);

Modified: trunk/OpenDNSSEC/enforcer-ng/src/keystate/update_keyzones_task.cpp
==============================================================================
--- trunk/OpenDNSSEC/enforcer-ng/src/keystate/update_keyzones_task.cpp	Mon Feb  3 15:30:42 2014	(r7616)
+++ trunk/OpenDNSSEC/enforcer-ng/src/keystate/update_keyzones_task.cpp	Mon Feb  3 17:32:07 2014	(r7617)
@@ -36,6 +36,7 @@
 
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/message.h>
+#include "utils/kc_helper.h"
 
 #include "keystate/keystate.pb.h"
 #include "policy/kasp.pb.h"
@@ -57,6 +58,14 @@
 load_zonelist_xml(int sockfd, const char * zonelistfile,
 				  std::auto_ptr< ::ods::keystate::ZoneListDocument >&doc)
 {
+	/* Validate zonelist with kaspcheck */
+	int zl_error = check_zonelist(zonelistfile, 0);
+	if (zl_error) {
+		ods_log_error_and_printf(sockfd, module_str,
+			"Unable to validate '%s' consistency.", zonelistfile);
+		return false;
+	}
+	
 	// Create a zonefile and load it with zones from the xml zonelist.xml
 	doc.reset(new ::ods::keystate::ZoneListDocument);
 	if (doc.get() == NULL) {

Modified: trunk/OpenDNSSEC/enforcer-ng/src/utils/kaspcheck.c
==============================================================================
--- trunk/OpenDNSSEC/enforcer-ng/src/utils/kaspcheck.c	Mon Feb  3 15:30:42 2014	(r7616)
+++ trunk/OpenDNSSEC/enforcer-ng/src/utils/kaspcheck.c	Mon Feb  3 17:32:07 2014	(r7617)
@@ -43,7 +43,6 @@
 #include <libxml/relaxng.h>
 
 const char *progname = NULL;
-int verbose = 0;
 
 #define StrFree(ptr) {if(ptr != NULL) {free(ptr); (ptr) = NULL;}}
 
@@ -77,7 +76,7 @@
 	int status = 0; /* Will be non-zero on error (NOT warning) */
 	char **repo_list = NULL;
 	int repo_count = 0;
-	int ch, i, option_index = 0;
+	int ch, i, verbose = 0, option_index = 0;
 	static struct option long_options[] =
 	{
 		{"config",  required_argument, 0, 'c'},
@@ -129,11 +128,12 @@
 	/* 0) Some basic setup */
 	log_init(DEFAULT_LOG_FACILITY, progname);
 	/* 1) Check on conf.xml - set kasp.xml (if -k flag not given) */
-	status = check_conf(conffile, &kaspfile, &zonelistfile, &repo_list, &repo_count);
+	status = check_conf(conffile, &kaspfile, &zonelistfile, &repo_list, 
+		&repo_count, verbose);
 	/* 2) Checks on kasp.xml */
-	status += check_kasp(kaspfile, repo_list, repo_count);
+	status += check_kasp(kaspfile, repo_list, repo_count, verbose);
 	/* 3) Checks on zonelist.xml */
-	status += check_zonelist(zonelistfile);
+	status += check_zonelist(zonelistfile, verbose);
 
 	xmlCleanupParser();
 	for (i = 0; i < repo_count; i++) StrFree(repo_list[i]);
@@ -146,369 +146,3 @@
 		dual_log("DEBUG: finished %d\n", status);
 	return status;
 }
-
-/** Check the conf.xml file
- * @param conf: config file to validate
- * @param kasp[in,out]: if NULL, will set it to kasp.xml found in config
- * @param zonelist[in,out]: if NULL, will set it to zonelist.xml found 
- * 		in config
- * @return status (0 == success; 1 == error) */
-int check_conf(char *conf, char **kasp, char **zonelist, 
-	char ***repo_listout, int *repo_countout)
-{
-	int status = 0;
-	int i = 0;
-	int j = 0;
-	int temp_status = 0;
-	char **repo_list;
-	int repo_count = 0;
-
-	xmlDocPtr doc;
-	xmlXPathContextPtr xpath_ctx;
-	xmlXPathObjectPtr xpath_obj;
-	xmlNode *curNode;
-	xmlChar *xexpr;
-	char* temp_char = NULL;
-
-	KC_REPO* repo = NULL;
-	int* repo_mods = NULL; /* To see if we have looked at this module before */
-
-	/* Check that the file is well-formed */
-	status = check_rng(conf, OPENDNSSEC_SCHEMA_DIR "/conf.rng");
-
-	/* Don't try to read the file if it is invalid */
-	if (status != 0) return status;
-	dual_log("INFO: The XML in %s is valid\n", conf);
-
-	 /* Load XML document */
-	doc = xmlParseFile(conf);
-	if (doc == NULL) return 1;
-
-	/* Create xpath evaluation context */
-	xpath_ctx = xmlXPathNewContext(doc);
-	if(xpath_ctx == NULL) {
-		xmlFreeDoc(doc);
-		return 1;
-	}
-
-	/* REPOSITORY section */
-	xexpr = (xmlChar *)"//Configuration/RepositoryList/Repository";
-	xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx);
-	if(xpath_obj == NULL) {
-		xmlXPathFreeContext(xpath_ctx);
-		xmlFreeDoc(doc);
-		return 1;
-	}
-
-	if (xpath_obj->nodesetval) {
-		repo_count = xpath_obj->nodesetval->nodeNr;
-		*repo_countout = repo_count;
-		
-		repo = (KC_REPO*)malloc(sizeof(KC_REPO) * repo_count);
-		repo_mods = (int*)malloc(sizeof(int) * repo_count);
-		repo_list = (char**)malloc(sizeof(char*) * repo_count);
-		*repo_listout = repo_list;
-
-		if (repo == NULL || repo_mods == NULL || repo_list == NULL) {
-			dual_log("ERROR: malloc for repo information failed\n");
-			exit(1);
-		}
-
-		for (i = 0; i < repo_count; i++) {
-			repo_mods[i] = 0;
-				 
-			curNode = xpath_obj->nodesetval->nodeTab[i]->xmlChildrenNode;
-			/* Default for capacity */
-
-			repo[i].name = (char *) xmlGetProp(xpath_obj->nodesetval->nodeTab[i],
-											 (const xmlChar *)"name");
-			repo_list[i] = StrStrdup(repo[i].name);
-
-			while (curNode) {
-				if (xmlStrEqual(curNode->name, (const xmlChar *)"TokenLabel"))
-					repo[i].TokenLabel = (char *) xmlNodeGetContent(curNode);
-				if (xmlStrEqual(curNode->name, (const xmlChar *)"Module"))
-					repo[i].module = (char *) xmlNodeGetContent(curNode);
-				curNode = curNode->next;
-			}
-		}
-	}
-	xmlXPathFreeObject(xpath_obj);
-
-	/* Now we have all the information we need do the checks */
-	for (i = 0; i < repo_count; i++) {
-		
-		if (repo_mods[i] == 0) {
-
-			/* 1) Check that the module exists */
-			status += check_file(repo[i].module, "Module");
-
-			repo_mods[i] = 1; /* Done this module */
-
-			/* 2) Check repos on the same modules have different TokenLabels */
-			for (j = i+1; j < repo_count; j++) {
-				if ( repo_mods[j] == 0 && 
-						(strcmp(repo[i].module, repo[j].module) == 0) ) {
-					repo_mods[j] = 1; /* done */
-
-					if (strcmp(repo[i].TokenLabel, repo[j].TokenLabel) == 0) {
-						dual_log("ERROR: Multiple Repositories (%s and %s) in %s have the same Module (%s) and TokenLabel (%s)\n", repo[i].name, repo[j].name, conf, repo[i].module, repo[i].TokenLabel);
-						status += 1;
-					}
-				}
-			}
-		}
-
-		/* 3) Check that the name is unique */
-		for (j = i+1; j < repo_count; j++) {
-			if (strcmp(repo[i].name, repo[j].name) == 0) {
-				dual_log("ERROR: Two repositories exist with the same name (%s)\n", repo[i].name);
-				status += 1;
-			}
-		}
-	}
-
-	/* COMMON section */
-	/* PolicyFile (aka KASP); we will validate it later */
-	if (*kasp == NULL) {
-		xexpr = (xmlChar *)"//Configuration/Common/PolicyFile";
-		xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx);
-		if(xpath_obj == NULL) {
-			xmlXPathFreeContext(xpath_ctx);
-			xmlFreeDoc(doc);
-
-			for (i = 0; i < repo_count; i++) {
-				free(repo[i].name);
-				free(repo[i].module);
-				free(repo[i].TokenLabel);
-			}
-			free(repo);
-			free(repo_mods);
-
-			return -1;
-		}
-		temp_char = (char*) xmlXPathCastToString(xpath_obj);
-		StrAppend(kasp, temp_char);
-		StrFree(temp_char);
-		xmlXPathFreeObject(xpath_obj);
-	}
-	
-	if (*zonelist == NULL) {
-		xexpr = (xmlChar *)"//Configuration/Common/ZoneListFile";
-		xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx);
-		if(xpath_obj == NULL) {
-			xmlXPathFreeContext(xpath_ctx);
-			xmlFreeDoc(doc);
-
-			for (i = 0; i < repo_count; i++) {
-				free(repo[i].name);
-				free(repo[i].module);
-				free(repo[i].TokenLabel);
-			}
-			free(repo);
-			free(repo_mods);
-
-			return -1;
-		}
-		temp_char = (char*) xmlXPathCastToString(xpath_obj);
-		StrAppend(zonelist, temp_char);
-		StrFree(temp_char);
-		xmlXPathFreeObject(xpath_obj);
-	}
-
-	/* ENFORCER section */
-
-	/* Check defined user/group */
-	status += check_user_group(xpath_ctx, 
-			(xmlChar *)"//Configuration/Enforcer/Privileges/User", 
-			(xmlChar *)"//Configuration/Enforcer/Privileges/Group");
-
-	/* Check datastore exists (if sqlite) */
-	/* TODO check datastore matches libksm without building against libksm */
-	temp_status = check_file_from_xpath(xpath_ctx, "SQLite datastore",
-			(xmlChar *)"//Configuration/Enforcer/Datastore/SQLite");
-	if (temp_status == -1) {
-		/* Configured for Mysql DB */
-		/*if (DbFlavour() != MYSQL_DB) {
-			dual_log("ERROR: libksm compiled for sqlite3 but conf.xml configured for MySQL\n");
-		}*/
-	} else {
-		status += temp_status;
-		/* Configured for sqlite DB */
-		/*if (DbFlavour() != SQLITE_DB) {
-			dual_log("ERROR: libksm compiled for MySQL but conf.xml configured for sqlite3\n");
-		}*/
-	}
-
-	/* Warn if Interval is M or Y */
-	status += check_time_def_from_xpath(xpath_ctx, (xmlChar *)"//Configuration/Enforcer/Interval", "Configuration", "Enforcer/Interval", conf);
-
-	/* Warn if RolloverNotification is M or Y */
-	status += check_time_def_from_xpath(xpath_ctx, (xmlChar *)"//Configuration/Enforcer/RolloverNotification", "Configuration", "Enforcer/RolloverNotification", conf);
-
-	status += check_interval(xpath_ctx, 
-		(xmlChar *)"//Configuration/Enforcer/Interval", conf);
-
-	/* Check DelegationSignerSubmitCommand exists (if set) */
-	temp_status = check_file_from_xpath(xpath_ctx, "DelegationSignerSubmitCommand",
-			(xmlChar *)"//Configuration/Enforcer/DelegationSignerSubmitCommand");
-	if (temp_status > 0) {
-		status += temp_status;
-	}
-
-	/* SIGNER section */
-	/* Check defined user/group */
-	status += check_user_group(xpath_ctx, 
-			(xmlChar *)"//Configuration/Signer/Privileges/User", 
-			(xmlChar *)"//Configuration/Signer/Privileges/Group");
-
-	/* Check WorkingDirectory exists (or default) */
-	temp_status = check_path_from_xpath(xpath_ctx, "WorkingDirectory",
-			(xmlChar *)"//Configuration/Signer/WorkingDirectory");
-	if (temp_status == -1) {
-		/* Check the default location */
-		check_path(OPENDNSSEC_STATE_DIR "/tmp", "default WorkingDirectory");
-	} else {
-		status += temp_status;
-	}
-		
-	xmlXPathFreeContext(xpath_ctx);
-	xmlFreeDoc(doc);
-
-	for (i = 0; i < repo_count; i++) {
-		free(repo[i].name);
-		free(repo[i].module);
-		free(repo[i].TokenLabel);
-	}
-	free(repo);
-	free(repo_mods);
-
-	return status;
-}
-
-/*
- * Check the zonelist.xml file
- * Return status (0 == success; 1 == error)
- */
-int check_zonelist(char *zonelist)
-{
-	if (!zonelist || !strncmp(zonelist, "", 1)) {
-		dual_log("ERROR: No location for zonelist.xml set\n");
-		return 1;
-	}
-
-	/* Check that the  Zonelist file is well-formed */
-	if (check_rng(zonelist, OPENDNSSEC_SCHEMA_DIR "/zonelist.rng") != 0)
-		return 1;
-	
-	dual_log("INFO: The XML in %s is valid\n", zonelist);
-	return 0;
-
-}
-
-/*
- * Check the kasp.xml file
- * Return status (0 == success; 1 == error)
- */
-int check_kasp(char *kasp, char **repo_list, int repo_count)
-{
-	int status = 0;
-	int i = 0;
-	int j = 0;
-	xmlDocPtr doc;
-	xmlXPathContextPtr xpath_ctx;
-	xmlXPathObjectPtr xpath_obj;
-	xmlNode *curNode;
-	xmlChar *xexpr;
-
-	int policy_count = 0;
-	char **policy_names = NULL;
-	int default_found = 0;
-
-	if (!kasp) {
-		dual_log("ERROR: No location for kasp.xml set\n");
-		return 1;
-	}
-
-/* Check that the file is well-formed */
-	status = check_rng(kasp, OPENDNSSEC_SCHEMA_DIR "/kasp.rng");
-
-	if (status ==0) {
-		dual_log("INFO: The XML in %s is valid\n", kasp);
-	} else {
-		return 1;
-	}
-
-	/* Load XML document */
-	doc = xmlParseFile(kasp);
-	if (doc == NULL) {
-		return 1;
-	}
-
-	/* Create xpath evaluation context */
-	xpath_ctx = xmlXPathNewContext(doc);
-	if(xpath_ctx == NULL) {
-		xmlFreeDoc(doc);
-		return 1;
-	}
-
-	/* First pass through the whole document to test for a policy called "default" and no duplicate names */
-
-	xexpr = (xmlChar *)"//KASP/Policy";
-	xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx);
-	if(xpath_obj == NULL) {
-		xmlXPathFreeContext(xpath_ctx);
-		xmlFreeDoc(doc);
-		return 1;
-	}
-
-	if (xpath_obj->nodesetval) {
-		policy_count = xpath_obj->nodesetval->nodeNr;
-
-		policy_names = (char**)malloc(sizeof(char*) * policy_count);
-		if (policy_names == NULL) {
-			dual_log("ERROR: Malloc for policy names failed\n");
-			exit(1);
-		}
-
-		for (i = 0; i < policy_count; i++) {
-
-			policy_names[i] = (char *) xmlGetProp(xpath_obj->nodesetval->nodeTab[i],
-					(const xmlChar *)"name");
-		}
-	}
-
-	/* Now we have all the information we need do the checks */
-	for (i = 0; i < policy_count; i++) {
-		if (strcmp(policy_names[i], "default") == 0) {
-			default_found = 1;
-		}
-		for (j = i+1; j < policy_count; j++) {
-			if ( (strcmp(policy_names[i], policy_names[j]) == 0) ) {
-				dual_log("ERROR: Two policies exist with the same name (%s)\n", policy_names[i]);
-				status += 1;
-			}
-		}
-	}
-	if (default_found == 0) {
-		dual_log("WARNING: No policy named 'default' in %s. This means you will need to refer explicitly to the policy for each zone\n", kasp);
-	}
-
-	/* Go again; this time check each policy */
-	for (i = 0; i < policy_count; i++) {
-		 curNode = xpath_obj->nodesetval->nodeTab[i]->xmlChildrenNode;
-
-		 status += check_policy(curNode, policy_names[i], repo_list, repo_count, kasp);
-	}
-
-	for (i = 0; i < policy_count; i++) {
-		free(policy_names[i]);
-	}
-	free(policy_names);
-
-	xmlXPathFreeObject(xpath_obj);
-	xmlXPathFreeContext(xpath_ctx);
-	xmlFreeDoc(doc);
-
-	return status;
-}

Modified: trunk/OpenDNSSEC/enforcer-ng/src/utils/kaspcheck.h
==============================================================================
--- trunk/OpenDNSSEC/enforcer-ng/src/utils/kaspcheck.h	Mon Feb  3 15:30:42 2014	(r7616)
+++ trunk/OpenDNSSEC/enforcer-ng/src/utils/kaspcheck.h	Mon Feb  3 17:32:07 2014	(r7617)
@@ -28,14 +28,5 @@
 #ifndef KASPCHECK_H
 #define KASPCHECK_H
 
-typedef struct {
-	char *name;
-	char *module;
-	char *TokenLabel;
-} KC_REPO;
-
-int check_conf(char *conf, char **kasp, char **zonelist, char ***repo_listout, int *repo_countout);
-int check_kasp(char *kasp, char **repo_list, int repo_count);
-int check_zonelist(char *zonelist);
 
 #endif /* KASPCHECK_H */

Modified: trunk/OpenDNSSEC/enforcer-ng/src/utils/kc_helper.c
==============================================================================
--- trunk/OpenDNSSEC/enforcer-ng/src/utils/kc_helper.c	Mon Feb  3 15:30:42 2014	(r7616)
+++ trunk/OpenDNSSEC/enforcer-ng/src/utils/kc_helper.c	Mon Feb  3 17:32:07 2014	(r7617)
@@ -37,16 +37,15 @@
 #include <limits.h>
 #include <ctype.h>
 
+#include "config.h"
+#include "kc_helper.h"
+
 #include <libxml/tree.h>
 #include <libxml/parser.h>
 #include <libxml/xpath.h>
 #include <libxml/xpathInternals.h>
 #include <libxml/relaxng.h>
 
-#include "kc_helper.h"
-
-extern int verbose;
-
 #define StrFree(ptr) {if(ptr != NULL) {free(ptr); (ptr) = NULL;}}
 
 void log_init(int facility, const char *program_name)
@@ -90,8 +89,8 @@
 }
 
 /* Check an XML file against its rng */
-int check_rng(const char *filename, const char *rngfilename) {
-
+int check_rng(const char *filename, const char *rngfilename, int verbose)
+{
 	xmlDocPtr doc = NULL;
 	xmlDocPtr rngdoc = NULL;
 	xmlRelaxNGParserCtxtPtr rngpctx = NULL;
@@ -99,7 +98,8 @@
 	xmlRelaxNGPtr schema = NULL;
 
 	if (verbose) {
-		dual_log("DEBUG: About to check XML validity in %s with %s\n", filename, rngfilename);
+		dual_log("DEBUG: About to check XML validity in %s with %s\n", 
+			filename, rngfilename);
 	}
 
    	/* Load XML document */
@@ -140,7 +140,8 @@
 		(xmlRelaxNGValidityWarningFunc) fprintf,
 		stderr);
 
-	/* parse a schema definition resource and build an internal XML Shema struture which can be used to validate instances. */
+	/* parse a schema definition resource and build an internal XML 
+	 * Shema struture which can be used to validate instances. */
 	schema = xmlRelaxNGParse(rngpctx);
 	if (schema == NULL) {
 		dual_log("ERROR: unable to parse a schema definition resource\n");
@@ -1442,3 +1443,371 @@
 	}
 	return ptr1;
 }
+
+
+
+/** Check the conf.xml file
+ * @param conf: config file to validate
+ * @param kasp[in,out]: if NULL, will set it to kasp.xml found in config
+ * @param zonelist[in,out]: if NULL, will set it to zonelist.xml found 
+ * 		in config
+ * @return status (0 == success; 1 == error) */
+int check_conf(char *conf, char **kasp, char **zonelist, 
+	char ***repo_listout, int *repo_countout, int verbose)
+{
+	int status = 0;
+	int i = 0;
+	int j = 0;
+	int temp_status = 0;
+	char **repo_list;
+	int repo_count = 0;
+
+	xmlDocPtr doc;
+	xmlXPathContextPtr xpath_ctx;
+	xmlXPathObjectPtr xpath_obj;
+	xmlNode *curNode;
+	xmlChar *xexpr;
+	char* temp_char = NULL;
+
+	KC_REPO* repo = NULL;
+	int* repo_mods = NULL; /* To see if we have looked at this module before */
+
+	/* Check that the file is well-formed */
+	status = check_rng(conf, OPENDNSSEC_SCHEMA_DIR "/conf.rng", verbose);
+
+	/* Don't try to read the file if it is invalid */
+	if (status != 0) return status;
+	dual_log("INFO: The XML in %s is valid\n", conf);
+
+	 /* Load XML document */
+	doc = xmlParseFile(conf);
+	if (doc == NULL) return 1;
+
+	/* Create xpath evaluation context */
+	xpath_ctx = xmlXPathNewContext(doc);
+	if(xpath_ctx == NULL) {
+		xmlFreeDoc(doc);
+		return 1;
+	}
+
+	/* REPOSITORY section */
+	xexpr = (xmlChar *)"//Configuration/RepositoryList/Repository";
+	xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx);
+	if(xpath_obj == NULL) {
+		xmlXPathFreeContext(xpath_ctx);
+		xmlFreeDoc(doc);
+		return 1;
+	}
+
+	if (xpath_obj->nodesetval) {
+		repo_count = xpath_obj->nodesetval->nodeNr;
+		*repo_countout = repo_count;
+		
+		repo = (KC_REPO*)malloc(sizeof(KC_REPO) * repo_count);
+		repo_mods = (int*)malloc(sizeof(int) * repo_count);
+		repo_list = (char**)malloc(sizeof(char*) * repo_count);
+		*repo_listout = repo_list;
+
+		if (repo == NULL || repo_mods == NULL || repo_list == NULL) {
+			dual_log("ERROR: malloc for repo information failed\n");
+			exit(1);
+		}
+
+		for (i = 0; i < repo_count; i++) {
+			repo_mods[i] = 0;
+				 
+			curNode = xpath_obj->nodesetval->nodeTab[i]->xmlChildrenNode;
+			/* Default for capacity */
+
+			repo[i].name = (char *) xmlGetProp(xpath_obj->nodesetval->nodeTab[i],
+											 (const xmlChar *)"name");
+			repo_list[i] = StrStrdup(repo[i].name);
+
+			while (curNode) {
+				if (xmlStrEqual(curNode->name, (const xmlChar *)"TokenLabel"))
+					repo[i].TokenLabel = (char *) xmlNodeGetContent(curNode);
+				if (xmlStrEqual(curNode->name, (const xmlChar *)"Module"))
+					repo[i].module = (char *) xmlNodeGetContent(curNode);
+				curNode = curNode->next;
+			}
+		}
+	}
+	xmlXPathFreeObject(xpath_obj);
+
+	/* Now we have all the information we need do the checks */
+	for (i = 0; i < repo_count; i++) {
+		
+		if (repo_mods[i] == 0) {
+
+			/* 1) Check that the module exists */
+			status += check_file(repo[i].module, "Module");
+
+			repo_mods[i] = 1; /* Done this module */
+
+			/* 2) Check repos on the same modules have different TokenLabels */
+			for (j = i+1; j < repo_count; j++) {
+				if ( repo_mods[j] == 0 && 
+						(strcmp(repo[i].module, repo[j].module) == 0) ) {
+					repo_mods[j] = 1; /* done */
+
+					if (strcmp(repo[i].TokenLabel, repo[j].TokenLabel) == 0) {
+						dual_log("ERROR: Multiple Repositories (%s and %s) in %s have the same Module (%s) and TokenLabel (%s)\n", repo[i].name, repo[j].name, conf, repo[i].module, repo[i].TokenLabel);
+						status += 1;
+					}
+				}
+			}
+		}
+
+		/* 3) Check that the name is unique */
+		for (j = i+1; j < repo_count; j++) {
+			if (strcmp(repo[i].name, repo[j].name) == 0) {
+				dual_log("ERROR: Two repositories exist with the same name (%s)\n", repo[i].name);
+				status += 1;
+			}
+		}
+	}
+
+	/* COMMON section */
+	/* PolicyFile (aka KASP); we will validate it later */
+	if (*kasp == NULL) {
+		xexpr = (xmlChar *)"//Configuration/Common/PolicyFile";
+		xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx);
+		if(xpath_obj == NULL) {
+			xmlXPathFreeContext(xpath_ctx);
+			xmlFreeDoc(doc);
+
+			for (i = 0; i < repo_count; i++) {
+				free(repo[i].name);
+				free(repo[i].module);
+				free(repo[i].TokenLabel);
+			}
+			free(repo);
+			free(repo_mods);
+
+			return -1;
+		}
+		temp_char = (char*) xmlXPathCastToString(xpath_obj);
+		StrAppend(kasp, temp_char);
+		StrFree(temp_char);
+		xmlXPathFreeObject(xpath_obj);
+	}
+	
+	if (*zonelist == NULL) {
+		xexpr = (xmlChar *)"//Configuration/Common/ZoneListFile";
+		xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx);
+		if(xpath_obj == NULL) {
+			xmlXPathFreeContext(xpath_ctx);
+			xmlFreeDoc(doc);
+
+			for (i = 0; i < repo_count; i++) {
+				free(repo[i].name);
+				free(repo[i].module);
+				free(repo[i].TokenLabel);
+			}
+			free(repo);
+			free(repo_mods);
+
+			return -1;
+		}
+		temp_char = (char*) xmlXPathCastToString(xpath_obj);
+		StrAppend(zonelist, temp_char);
+		StrFree(temp_char);
+		xmlXPathFreeObject(xpath_obj);
+	}
+
+	/* ENFORCER section */
+
+	/* Check defined user/group */
+	status += check_user_group(xpath_ctx, 
+			(xmlChar *)"//Configuration/Enforcer/Privileges/User", 
+			(xmlChar *)"//Configuration/Enforcer/Privileges/Group");
+
+	/* Check datastore exists (if sqlite) */
+	/* TODO check datastore matches libksm without building against libksm */
+	temp_status = check_file_from_xpath(xpath_ctx, "SQLite datastore",
+			(xmlChar *)"//Configuration/Enforcer/Datastore/SQLite");
+	if (temp_status == -1) {
+		/* Configured for Mysql DB */
+		/*if (DbFlavour() != MYSQL_DB) {
+			dual_log("ERROR: libksm compiled for sqlite3 but conf.xml configured for MySQL\n");
+		}*/
+	} else {
+		status += temp_status;
+		/* Configured for sqlite DB */
+		/*if (DbFlavour() != SQLITE_DB) {
+			dual_log("ERROR: libksm compiled for MySQL but conf.xml configured for sqlite3\n");
+		}*/
+	}
+
+	/* Warn if Interval is M or Y */
+	status += check_time_def_from_xpath(xpath_ctx, (xmlChar *)"//Configuration/Enforcer/Interval", "Configuration", "Enforcer/Interval", conf);
+
+	/* Warn if RolloverNotification is M or Y */
+	status += check_time_def_from_xpath(xpath_ctx, (xmlChar *)"//Configuration/Enforcer/RolloverNotification", "Configuration", "Enforcer/RolloverNotification", conf);
+
+	status += check_interval(xpath_ctx, 
+		(xmlChar *)"//Configuration/Enforcer/Interval", conf);
+
+	/* Check DelegationSignerSubmitCommand exists (if set) */
+	temp_status = check_file_from_xpath(xpath_ctx, "DelegationSignerSubmitCommand",
+			(xmlChar *)"//Configuration/Enforcer/DelegationSignerSubmitCommand");
+	if (temp_status > 0) {
+		status += temp_status;
+	}
+
+	/* SIGNER section */
+	/* Check defined user/group */
+	status += check_user_group(xpath_ctx, 
+			(xmlChar *)"//Configuration/Signer/Privileges/User", 
+			(xmlChar *)"//Configuration/Signer/Privileges/Group");
+
+	/* Check WorkingDirectory exists (or default) */
+	temp_status = check_path_from_xpath(xpath_ctx, "WorkingDirectory",
+			(xmlChar *)"//Configuration/Signer/WorkingDirectory");
+	if (temp_status == -1) {
+		/* Check the default location */
+		check_path(OPENDNSSEC_STATE_DIR "/tmp", "default WorkingDirectory");
+	} else {
+		status += temp_status;
+	}
+		
+	xmlXPathFreeContext(xpath_ctx);
+	xmlFreeDoc(doc);
+
+	for (i = 0; i < repo_count; i++) {
+		free(repo[i].name);
+		free(repo[i].module);
+		free(repo[i].TokenLabel);
+	}
+	free(repo);
+	free(repo_mods);
+
+	return status;
+}
+
+/*
+ * Check the zonelist.xml file
+ * Return status (0 == success; 1 == error)
+ */
+int check_zonelist(const char *zonelist, int verbose)
+{
+	if (!zonelist || !strncmp(zonelist, "", 1)) {
+		dual_log("ERROR: No location for zonelist.xml set\n");
+		return 1;
+	}
+
+	/* Check that the  Zonelist file is well-formed */
+	if (check_rng(zonelist, OPENDNSSEC_SCHEMA_DIR "/zonelist.rng", verbose) != 0)
+		return 1;
+	
+	dual_log("INFO: The XML in %s is valid\n", zonelist);
+	return 0;
+
+}
+
+/*
+ * Check the kasp.xml file
+ * Return status (0 == success; 1 == error)
+ */
+int check_kasp(char *kasp, char **repo_list, int repo_count, int verbose)
+{
+	int status = 0;
+	int i = 0;
+	int j = 0;
+	xmlDocPtr doc;
+	xmlXPathContextPtr xpath_ctx;
+	xmlXPathObjectPtr xpath_obj;
+	xmlNode *curNode;
+	xmlChar *xexpr;
+
+	int policy_count = 0;
+	char **policy_names = NULL;
+	int default_found = 0;
+
+	if (!kasp) {
+		dual_log("ERROR: No location for kasp.xml set\n");
+		return 1;
+	}
+
+/* Check that the file is well-formed */
+	status = check_rng(kasp, OPENDNSSEC_SCHEMA_DIR "/kasp.rng", verbose);
+
+	if (status ==0) {
+		dual_log("INFO: The XML in %s is valid\n", kasp);
+	} else {
+		return 1;
+	}
+
+	/* Load XML document */
+	doc = xmlParseFile(kasp);
+	if (doc == NULL) {
+		return 1;
+	}
+
+	/* Create xpath evaluation context */
+	xpath_ctx = xmlXPathNewContext(doc);
+	if(xpath_ctx == NULL) {
+		xmlFreeDoc(doc);
+		return 1;
+	}
+
+	/* First pass through the whole document to test for a policy called "default" and no duplicate names */
+
+	xexpr = (xmlChar *)"//KASP/Policy";
+	xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx);
+	if(xpath_obj == NULL) {
+		xmlXPathFreeContext(xpath_ctx);
+		xmlFreeDoc(doc);
+		return 1;
+	}
+
+	if (xpath_obj->nodesetval) {
+		policy_count = xpath_obj->nodesetval->nodeNr;
+
+		policy_names = (char**)malloc(sizeof(char*) * policy_count);
+		if (policy_names == NULL) {
+			dual_log("ERROR: Malloc for policy names failed\n");
+			exit(1);
+		}
+
+		for (i = 0; i < policy_count; i++) {
+
+			policy_names[i] = (char *) xmlGetProp(xpath_obj->nodesetval->nodeTab[i],
+					(const xmlChar *)"name");
+		}
+	}
+
+	/* Now we have all the information we need do the checks */
+	for (i = 0; i < policy_count; i++) {
+		if (strcmp(policy_names[i], "default") == 0) {
+			default_found = 1;
+		}
+		for (j = i+1; j < policy_count; j++) {
+			if ( (strcmp(policy_names[i], policy_names[j]) == 0) ) {
+				dual_log("ERROR: Two policies exist with the same name (%s)\n", policy_names[i]);
+				status += 1;
+			}
+		}
+	}
+	if (default_found == 0) {
+		dual_log("WARNING: No policy named 'default' in %s. This means you will need to refer explicitly to the policy for each zone\n", kasp);
+	}
+
+	/* Go again; this time check each policy */
+	for (i = 0; i < policy_count; i++) {
+		 curNode = xpath_obj->nodesetval->nodeTab[i]->xmlChildrenNode;
+
+		 status += check_policy(curNode, policy_names[i], repo_list, repo_count, kasp);
+	}
+
+	for (i = 0; i < policy_count; i++) {
+		free(policy_names[i]);
+	}
+	free(policy_names);
+
+	xmlXPathFreeObject(xpath_obj);
+	xmlXPathFreeContext(xpath_ctx);
+	xmlFreeDoc(doc);
+
+	return status;
+}

Modified: trunk/OpenDNSSEC/enforcer-ng/src/utils/kc_helper.h
==============================================================================
--- trunk/OpenDNSSEC/enforcer-ng/src/utils/kc_helper.h	Mon Feb  3 15:30:42 2014	(r7616)
+++ trunk/OpenDNSSEC/enforcer-ng/src/utils/kc_helper.h	Mon Feb  3 17:32:07 2014	(r7617)
@@ -40,11 +40,26 @@
 
 #define KC_NAME_LENGTH     256
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+	char *name;
+	char *module;
+	char *TokenLabel;
+} KC_REPO;
+
+int check_conf(char *conf, char **kasp, char **zonelist, 
+	char ***repo_listout, int *repo_countout, int verbose);
+int check_kasp(char *kasp, char **repo_list, int repo_count, int verbose);
+int check_zonelist(const char *zonelist, int verbose);
+
 void log_init(int facility, const char *program_name);
 void log_switch(int facility, const char *program_name);
 void dual_log(const char *format, ...);
 
-int check_rng(const char *filename, const char *rngfilename);
+int check_rng(const char *filename, const char *rngfilename, int verbose);
 
 int check_file(const char *filename, const char *log_string);
 int check_file_from_xpath(xmlXPathContextPtr xpath_ctx, const char *log_string, const xmlChar *file_xexpr);
@@ -73,5 +88,8 @@
 void* MemCalloc(size_t nmemb, size_t size);
 void* MemRealloc(void *ptr, size_t size);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* KC_HELPER_H */



More information about the Opendnssec-commits mailing list