/** 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; }
/*! * 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; }
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; }