/** 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; }
static int parse_rdata(struct entry *entry, const char *owner, const char *rrtype, const char *rdata, int ttl, knot_mm_t *mm) { knot_rdataset_init(&entry->data.rrs); int ret = knot_rrtype_from_string(rrtype, &entry->data.type); if (ret != KNOT_EOK) { return ret; } /* Synthetize RR line */ char *rr_line = sprintf_alloc("%s %u IN %s %s\n", owner, ttl, rrtype, rdata); if (zs_set_input_string(g_scanner, rr_line, strlen(rr_line)) != 0 || zs_parse_all(g_scanner) != 0) { free(rr_line); return KNOT_EPARSEFAIL; } free(rr_line); /* Write parsed RDATA. */ knot_rdata_t rr[knot_rdata_array_size(g_scanner->r_data_length)]; knot_rdata_init(rr, g_scanner->r_data_length, g_scanner->r_data, ttl); return knot_rdataset_add(&entry->data.rrs, rr, mm); }
/*! * 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; }