예제 #1
0
/** Enable/disable trust anchor. */
static int l_trustanchor(lua_State *L)
{
	struct engine *engine = engine_luaget(L);
	const char *anchor = lua_tostring(L, 1);
	bool enable = lua_isboolean(L, 2) ? lua_toboolean(L, 2) : true;
	if (!anchor || strlen(anchor) == 0) {
		return 0;
	}
	/* If disabling, parse the owner string only. */
	if (!enable) {
		knot_dname_t *owner = knot_dname_from_str(NULL, anchor, KNOT_DNAME_MAXLEN);
		if (!owner) {
			lua_pushstring(L, "invalid trust anchor owner");
			lua_error(L);
		}
		lua_pushboolean(L, kr_ta_del(&engine->resolver.trust_anchors, owner) == 0);
		free(owner);
		return 1;
	}

	/* Parse the record */
	zs_scanner_t *zs = malloc(sizeof(*zs));
	if (!zs || zs_init(zs, ".", 1, 0) != 0) {
		free(zs);
		lua_pushstring(L, "not enough memory");
		lua_error(L);
	}
	int ok = zs_set_input_string(zs, anchor, strlen(anchor)) == 0 &&
	         zs_parse_all(zs) == 0;
	/* Add it to TA set and cleanup */
	if (ok) {
		ok = kr_ta_add(&engine->resolver.trust_anchors,
		               zs->r_owner, zs->r_type, zs->r_ttl, zs->r_data, zs->r_data_length) == 0;
	}
	zs_deinit(zs);
	free(zs);
	/* Report errors */
	if (!ok) {
		lua_pushstring(L, "failed to process trust anchor RR");
		lua_error(L);
	}
	lua_pushboolean(L, true);
	return 1;
}
예제 #2
0
파일: pubkey.c 프로젝트: idtek/knot
/*!
 * Parse DNSKEY record.
 *
 * \todo Currently, the function waits for the first DNSKEY record, and skips
 * the others. We should be more strict and report other records as errors.
 */
static void parse_record(zs_scanner_t *scanner)
{
	assert(scanner);
	assert(scanner->process.data);

	dnssec_key_t *key = scanner->process.data;

	if (dnssec_key_get_dname(key) != NULL) {
		// should report error
		scanner->state = ZS_STATE_STOP;
		return;
	}

	if (scanner->r_type != RTYPE_DNSKEY) {
		// should report error
		scanner->state = ZS_STATE_STOP;
		return;
	}

	dnssec_binary_t rdata = {
		.data = scanner->r_data,
		.size = scanner->r_data_length
	};
	dnssec_key_set_dname(key, scanner->dname);
	dnssec_key_set_rdata(key, &rdata);
}

int legacy_pubkey_parse(const char *filename, dnssec_key_t **key_ptr)
{
	assert(filename);
	assert(key_ptr);

	dnssec_key_t *key = NULL;
	int result = dnssec_key_new(&key);
	if (result != DNSSEC_EOK) {
		return result;
	}

	uint16_t cls = CLASS_IN;
	uint32_t ttl = 0;
	zs_scanner_t *scanner = malloc(sizeof(zs_scanner_t));
	if (scanner == NULL) {
		dnssec_key_free(key);
		return DNSSEC_ENOMEM;
	}

	if (zs_init(scanner, ".", cls, ttl) != 0 ||
	    zs_set_input_file(scanner, filename) != 0 ||
	    zs_set_processing(scanner, parse_record, NULL, key) != 0 ||
	    zs_parse_all(scanner) != 0) {
		zs_deinit(scanner);
		free(scanner);
		dnssec_key_free(key);
		return DNSSEC_NOT_FOUND;
	}
	zs_deinit(scanner);
	free(scanner);

	if (dnssec_key_get_dname(key) == NULL) {
		dnssec_key_free(key);
		return DNSSEC_INVALID_PUBLIC_KEY;
	}

	*key_ptr = key;
	return DNSSEC_EOK;
}
예제 #3
0
파일: rosedb_tool.c 프로젝트: idtek/knot
int main(int argc, char *argv[])
{
	static const struct option options[] = {
		{ "version", no_argument, 0, 'V' },
		{ "help",    no_argument, 0, 'h' },
		{ NULL }
	};

	int opt = 0;
	int index = 0;
	while ((opt = getopt_long(argc, argv, "Vh", options, &index)) != -1) {
		switch (opt) {
		case 'V':
			printf("rosedb_tool (Knot DNS), version %s\n", PACKAGE_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			help(stdout);
			return EXIT_SUCCESS;
		default:
			help(stderr);
			return EXIT_FAILURE;
		}
	}

	if (argc < 3) {
		help(stderr);
		return EXIT_FAILURE;
	}

	/* Get mandatory parameters. */
	int ret = EXIT_SUCCESS;
	char *dbdir  = argv[1];
	char *action = argv[2];
	argv += 3;
	argc -= 3;

	g_scanner = malloc(sizeof(zs_scanner_t));
	if (g_scanner == NULL) {
		return EXIT_FAILURE;
	}

	if (zs_init(g_scanner, ".", KNOT_CLASS_IN, 0) != 0 ||
	    zs_set_processing(g_scanner, NULL, parse_err, NULL) != 0) {
		zs_deinit(g_scanner);
		free(g_scanner);
		return EXIT_FAILURE;
	}

	/* Open cache for operations. */
	struct cache *cache = cache_open(dbdir, 0, NULL);
	if (cache == NULL) {
		fprintf(stderr, "failed to open db '%s'\n", dbdir);
		zs_deinit(g_scanner);
		free(g_scanner);
		return EXIT_FAILURE;
	}

	/* Execute action. */
	bool found = false;
	for (unsigned i = 0; i < TOOL_ACTION_COUNT; ++i) {
		struct tool_action *ta = &TOOL_ACTION[i];
		if (strcmp(ta->name, action) == 0) {

			/* Check param count. */
			if (argc < ta->min_args) {
				break;
			}

			/* Now set as found. */
			found = true;

			MDB_txn *txn = NULL;
			int ret = mdb_txn_begin(cache->env, NULL, 0, &txn);
			if (ret != MDB_SUCCESS) {
				fprintf(stderr, "failed to open transaction, aborting\n");
				break;
			}

			/* Execute operation handler. */
			ret = ta->func(cache, txn, argc, argv);
			if (ret != 0) {
				fprintf(stderr, "'%s' failed, aborting transaction\n", action);
				mdb_txn_abort(txn);
			} else {
				mdb_txn_commit(txn);
			}

			break;
		}
	}

	cache_close(cache);
	zs_deinit(g_scanner);
	free(g_scanner);

	if (!found) {
		help(stderr);
		return EXIT_FAILURE;
	}

	return ret;
}