ldns_rdf * ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key) { unsigned char *md5_hash; unsigned int siglen; ldns_rdf *sigdata_rdf; ldns_buffer *b64sig; b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); if (!b64sig) { return NULL; } md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign), ldns_buffer_position(to_sign), NULL); if (!md5_hash) { ldns_buffer_free(b64sig); return NULL; } RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH, (unsigned char*)ldns_buffer_begin(b64sig), &siglen, key); sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, ldns_buffer_begin(b64sig)); ldns_buffer_free(b64sig); return sigdata_rdf; }
ldns_status ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size) { ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); uint8_t *result = NULL; ldns_status status; *result_size = 0; *dest = NULL; if(!buffer) return LDNS_STATUS_MEM_ERR; status = ldns_pkt2buffer_wire(buffer, packet); if (status == LDNS_STATUS_OK) { *result_size = ldns_buffer_position(buffer); result = (uint8_t *) ldns_buffer_export(buffer); } else { ldns_buffer_free(buffer); return status; } if (result) { *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer)); if(!*dest) { ldns_buffer_free(buffer); return LDNS_STATUS_MEM_ERR; } memcpy(*dest, result, ldns_buffer_position(buffer)); } ldns_buffer_free(buffer); return status; }
static int l_pkt2string(lua_State *L) { ldns_buffer *b; luaL_Buffer lua_b; ldns_pkt *p = (ldns_pkt *)lua_touserdata(L, 1); if (!p) { return 0; } b = ldns_buffer_new(LDNS_MAX_PACKETLEN); luaL_buffinit(L,&lua_b); if (ldns_pkt2buffer_wire(b, p) != LDNS_STATUS_OK) { ldns_buffer_free(b); return 0; } /* this is a memcpy??? */ luaL_addlstring(&lua_b, (char*)ldns_buffer_begin(b), ldns_buffer_capacity(b) ); /* I hope so */ ldns_buffer_free(b); luaL_pushresult(&lua_b); return 1; }
ldns_rdf * ldns_sign_public_evp(ldns_buffer *to_sign, EVP_PKEY *key, const EVP_MD *digest_type) { unsigned int siglen; ldns_rdf *sigdata_rdf; ldns_buffer *b64sig; EVP_MD_CTX ctx; const EVP_MD *md_type; int r; siglen = 0; b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); if (!b64sig) { return NULL; } /* initializes a signing context */ md_type = digest_type; if(!md_type) { /* unknown message difest */ ldns_buffer_free(b64sig); return NULL; } EVP_MD_CTX_init(&ctx); r = EVP_SignInit(&ctx, md_type); if(r == 1) { r = EVP_SignUpdate(&ctx, (unsigned char*) ldns_buffer_begin(to_sign), ldns_buffer_position(to_sign)); } else { ldns_buffer_free(b64sig); return NULL; } if(r == 1) { r = EVP_SignFinal(&ctx, (unsigned char*) ldns_buffer_begin(b64sig), &siglen, key); } else { ldns_buffer_free(b64sig); return NULL; } if(r != 1) { ldns_buffer_free(b64sig); return NULL; } /* unfortunately, OpenSSL output is differenct from DNS DSA format */ if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) { sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen); } else { /* ok output for other types is the same */ sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, ldns_buffer_begin(b64sig)); } ldns_buffer_free(b64sig); EVP_MD_CTX_cleanup(&ctx); return sigdata_rdf; }
ldns_rdf * ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key) { unsigned char *sha1_hash; unsigned int siglen; ldns_rdf *sigdata_rdf; ldns_buffer *b64sig; int result; siglen = 0; b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); if (!b64sig) { return NULL; } sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign), ldns_buffer_position(to_sign), NULL); if (!sha1_hash) { ldns_buffer_free(b64sig); return NULL; } result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH, (unsigned char*)ldns_buffer_begin(b64sig), &siglen, key); if (result != 1) { ldns_buffer_free(b64sig); return NULL; } sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, ldns_buffer_begin(b64sig)); ldns_buffer_free(b64sig); /* can't free this buffer ?? */ return sigdata_rdf; }
/** * Sign data with DSA * * \param[in] to_sign The ldns_buffer containing raw data that is * to be signed * \param[in] key The DSA key structure to sign with * \return ldns_rdf for the RRSIG ldns_rr */ ldns_rdf * ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key) { unsigned char *sha1_hash; ldns_rdf *sigdata_rdf; ldns_buffer *b64sig; DSA_SIG *sig; uint8_t *data; size_t pad; b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); if (!b64sig) { return NULL; } sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign), ldns_buffer_position(to_sign), NULL); if (!sha1_hash) { ldns_buffer_free(b64sig); return NULL; } sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key); if(!sig) { ldns_buffer_free(b64sig); return NULL; } data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH); if(!data) { ldns_buffer_free(b64sig); DSA_SIG_free(sig); return NULL; } data[0] = 1; pad = 20 - (size_t) BN_num_bytes(sig->r); if (pad > 0) { memset(data + 1, 0, pad); } BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad); pad = 20 - (size_t) BN_num_bytes(sig->s); if (pad > 0) { memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad); } BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad)); sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, 1 + 2 * SHA_DIGEST_LENGTH, data); ldns_buffer_free(b64sig); LDNS_FREE(data); DSA_SIG_free(sig); return sigdata_rdf; }
ldns_status ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size) { ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); uint8_t *result = NULL; ldns_status status; *result_size = 0; *dest = NULL; status = ldns_rr2buffer_wire(buffer, rr, section); if (status == LDNS_STATUS_OK) { *result_size = ldns_buffer_position(buffer); result = (uint8_t *) ldns_buffer_export(buffer); } else { return status; } if (result) { *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer)); memcpy(*dest, result, ldns_buffer_position(buffer)); } ldns_buffer_free(buffer); return status; }
/** * Perform callback for fake pending message. */ static void fake_pending_callback(struct replay_runtime* runtime, struct replay_moment* todo, int error) { struct fake_pending* p = runtime->pending_list; struct comm_reply repinfo; struct comm_point c; void* cb_arg; comm_point_callback_t* cb; memset(&c, 0, sizeof(c)); if(!p) fatal_exit("No pending queries."); cb_arg = p->cb_arg; cb = p->callback; log_assert(todo->qname == NULL); /* or find that one */ c.buffer = ldns_buffer_new(runtime->bufsize); c.type = comm_udp; if(p->transport == transport_tcp) c.type = comm_tcp; if(todo->evt_type == repevt_back_reply && todo->match) { fill_buffer_with_reply(c.buffer, todo->match, p->pkt); } repinfo.c = &c; repinfo.addrlen = p->addrlen; memcpy(&repinfo.addr, &p->addr, p->addrlen); if(!p->serviced) pending_list_delete(runtime, p); if((*cb)(&c, cb_arg, error, &repinfo)) { fatal_exit("unexpected: pending callback returned 1"); } /* delete the pending item. */ ldns_buffer_free(c.buffer); }
/** * Perform range entry on pending message. * @param runtime: runtime buffer size preference. * @param entry: entry that codes for the reply to do. * @param pend: pending query that is answered, callback called. */ static void answer_callback_from_entry(struct replay_runtime* runtime, struct entry* entry, struct fake_pending* pend) { struct comm_point c; struct comm_reply repinfo; void* cb_arg = pend->cb_arg; comm_point_callback_t* cb = pend->callback; memset(&c, 0, sizeof(c)); c.fd = -1; c.buffer = ldns_buffer_new(runtime->bufsize); c.type = comm_udp; if(pend->transport == transport_tcp) c.type = comm_tcp; fill_buffer_with_reply(c.buffer, entry, pend->pkt); repinfo.c = &c; repinfo.addrlen = pend->addrlen; memcpy(&repinfo.addr, &pend->addr, pend->addrlen); if(!pend->serviced) pending_list_delete(runtime, pend); if((*cb)(&c, cb_arg, NETEVENT_NOERROR, &repinfo)) { fatal_exit("testbound: unexpected: callback returned 1"); } ldns_buffer_free(c.buffer); }
void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep) { /* not particularly fast but flexible, make wireformat and print */ ldns_buffer* buf = ldns_buffer_new(65535); struct regional* region = regional_create(); if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0, region, 65535, 1)) { log_info("%s: log_dns_msg: out of memory", str); } else { ldns_status s; ldns_pkt* pkt = NULL; s = ldns_buffer2pkt_wire(&pkt, buf); if(s != LDNS_STATUS_OK) { log_info("%s: log_dns_msg: ldns parse gave: %s", str, ldns_get_errorstr_by_id(s)); } else { ldns_buffer_clear(buf); s = ldns_pkt2buffer_str(buf, pkt); if(s != LDNS_STATUS_OK) { log_info("%s: log_dns_msg: ldns tostr gave: %s", str, ldns_get_errorstr_by_id(s)); } else { log_info("%s %s", str, (char*)ldns_buffer_begin(buf)); } } ldns_pkt_free(pkt); } ldns_buffer_free(buf); regional_destroy(region); }
/** verify DS matches DNSKEY from a file */ static void dstest_file(const char* fname) { /* * The file contains a list of ldns-testpkts entries. * The first entry must be a query for DNSKEY. * The answer rrset is the keyset that will be used for verification */ struct regional* region = regional_create(); struct alloc_cache alloc; ldns_buffer* buf = ldns_buffer_new(65535); struct entry* e; struct entry* list = read_datafile(fname); struct module_env env; if(!list) fatal_exit("could not read %s: %s", fname, strerror(errno)); alloc_init(&alloc, NULL, 1); memset(&env, 0, sizeof(env)); env.scratch = region; env.scratch_buffer = buf; unit_assert(region && buf); /* ready to go! */ for(e = list; e; e = e->next) { dstest_entry(e, &alloc, region, buf, &env); } delete_entry(list); regional_destroy(region); alloc_clear(&alloc); ldns_buffer_free(buf); }
/** * Convert salt to string. * */ const char* nsec3params_salt2str(nsec3params_type* nsec3params) { uint8_t *data; uint8_t salt_length = 0; uint8_t salt_pos = 0; int written = 0; char* str = NULL; ldns_buffer* buffer = NULL; salt_length = nsec3params->salt_len; data = nsec3params->salt_data; /* from now there are variable length entries so remember pos */ if (salt_length == 0) { buffer = ldns_buffer_new(2); written = ldns_buffer_printf(buffer, "-"); } else { buffer = ldns_buffer_new(salt_pos+1); for (salt_pos = 0; salt_pos < salt_length; salt_pos++) { written = ldns_buffer_printf(buffer, "%02x", data[salt_pos]); } } if (ldns_buffer_status(buffer) == LDNS_STATUS_OK) { str = ldns_buffer2str(buffer); } else if (written) { ods_log_error("[%s] unable to convert nsec3 salt to string: %s", nsec3_str, ldns_get_errorstr_by_id(ldns_buffer_status(buffer))); } else { ods_log_error("[%s] unable to convert nsec3 salt to string: zero " "bytes written", nsec3_str); } ldns_buffer_free(buffer); return (const char*) str; }
/** debug print a packet that failed */ static void print_packet_rrsets(struct query_info* qinfo, struct reply_info* rep) { size_t i; ldns_rr_list* l; ldns_buffer* buf = ldns_buffer_new(65536); log_query_info(0, "failed query", qinfo); printf(";; ANSWER SECTION (%d rrsets)\n", (int)rep->an_numrrsets); for(i=0; i<rep->an_numrrsets; i++) { l = packed_rrset_to_rr_list(rep->rrsets[i], buf); printf("; rrset %d\n", (int)i); ldns_rr_list_print(stdout, l); ldns_rr_list_deep_free(l); } printf(";; AUTHORITY SECTION (%d rrsets)\n", (int)rep->ns_numrrsets); for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) { l = packed_rrset_to_rr_list(rep->rrsets[i], buf); printf("; rrset %d\n", (int)i); ldns_rr_list_print(stdout, l); ldns_rr_list_deep_free(l); } printf(";; ADDITIONAL SECTION (%d rrsets)\n", (int)rep->ar_numrrsets); for(i=rep->an_numrrsets+rep->ns_numrrsets; i<rep->rrset_count; i++) { l = packed_rrset_to_rr_list(rep->rrsets[i], buf); printf("; rrset %d\n", (int)i); ldns_rr_list_print(stdout, l); ldns_rr_list_deep_free(l); } printf(";; packet end\n"); ldns_buffer_free(buf); }
int process_dns_answer(packetinfo *pi, ldns_pkt *dns_pkt) { int rrcount_query; int j; ldns_rr_list *dns_query_domains; ldns_buffer *dns_buff; dns_query_domains = ldns_pkt_question(dns_pkt); rrcount_query = ldns_rr_list_rr_count(dns_query_domains); dns_buff = ldns_buffer_new(LDNS_MIN_BUFLEN); dlog("[*] rrcount_query: %d\n", rrcount_query); // Do we ever have more than one Question? // If we do - are we handling it correct ? for (j = 0; j < rrcount_query; j++) { ldns_rdf *rdf_data; rdf_data = ldns_rr_owner(ldns_rr_list_rr(dns_query_domains, j)); dlog("[D] rdf_data: %p\n", rdf_data); if ( cache_dns_objects(pi, rdf_data, dns_buff, dns_pkt) != 0 ) { dlog("[D] cache_dns_objects() returned error\n"); } } ldns_buffer_free(dns_buff); update_dns_stats(pi,SUCCESS); return(0); }
void listen_delete(struct listen_dnsport* listen) { if(!listen) return; ldns_buffer_free(listen->udp_buff); free(listen); }
void outside_network_delete(struct outside_network* outnet) { if(!outnet) return; ldns_buffer_free(outnet->udp_buff); free(outnet); }
void comm_point_drop_reply(struct comm_reply* repinfo) { log_info("comm_point_drop_reply fake"); if(repinfo->c) { ldns_buffer_free(repinfo->c->buffer); free(repinfo->c); } }
/** delete a fake pending */ static void delete_fake_pending(struct fake_pending* pend) { if(!pend) return; ldns_buffer_free(pend->buffer); ldns_pkt_free(pend->pkt); free(pend); }
void listen_delete(struct listen_dnsport* front) { if(!front) return; listen_list_delete(front->cps); ldns_buffer_free(front->udp_buff); free(front); }
/* BUFFERs */ static int l_buf_free(lua_State *L) { ldns_buffer *b = (ldns_buffer *)lua_touserdata(L, 1); if (!b) { return 0; } ldns_buffer_free(b); return 0; }
/** delete the list of reply packets */ void delete_replylist(struct reply_packet* replist) { struct reply_packet *p=replist, *np; while(p) { np = p->next; ldns_pkt_free(p->reply); ldns_buffer_free(p->reply_from_hex); free(p); p=np; } }
void mesh_delete(struct mesh_area* mesh) { if(!mesh) return; /* free all query states */ while(mesh->all.count) mesh_delete_helper(mesh->all.root); timehist_delete(mesh->histogram); ldns_buffer_free(mesh->qbuf_bak); free(mesh); }
/** delete a replay answer */ static void delete_replay_answer(struct replay_answer* a) { if(!a) return; if(a->repinfo.c) { ldns_buffer_free(a->repinfo.c->buffer); free(a->repinfo.c); } ldns_pkt_free(a->pkt); free(a); }
/** create a query to test */ static ldns_buffer* make_query(char* nm, int tp) { /* with EDNS DO and CDFLAG */ ldns_buffer* b = ldns_buffer_new(512); ldns_pkt* p; ldns_status s; if(!b) { if(verb) printf("error: out of memory\n"); return NULL; } s = ldns_pkt_query_new_frm_str(&p, nm, tp, LDNS_RR_CLASS_IN, (uint16_t)(LDNS_RD|LDNS_CD)); if(s != LDNS_STATUS_OK) { if(verb) printf("error: %s\n", ldns_get_errorstr_by_id(s)); ldns_buffer_free(b); return NULL; } if(!p) { if(verb) printf("error: out of memory\n"); ldns_buffer_free(b); return NULL; } ldns_pkt_set_edns_do(p, 1); ldns_pkt_set_edns_udp_size(p, 4096); ldns_pkt_set_id(p, ldns_get_random()); if( (s=ldns_pkt2buffer_wire(b, p)) != LDNS_STATUS_OK) { if(verb) printf("error: %s\n", ldns_get_errorstr_by_id(s)); ldns_pkt_free(p); ldns_buffer_free(b); return NULL; } ldns_pkt_free(p); return b; }
/** main program for pktview */ int main(int argc, char* argv[]) { ldns_buffer* pkt = ldns_buffer_new(65553); if(argc != 1) { usage(argv); } if(!pkt) fatal_exit("out of memory"); read_input(pkt, stdin); analyze(pkt); ldns_buffer_free(pkt); return 0; }
void msgparse_test(void) { ldns_buffer* pkt = ldns_buffer_new(65553); ldns_buffer* out = ldns_buffer_new(65553); struct alloc_cache super_a, alloc; /* init */ alloc_init(&super_a, NULL, 0); alloc_init(&alloc, &super_a, 2); unit_show_feature("message parse"); simpletest(pkt, &alloc, out); /* plain hex dumps, like pcat */ testfromfile(pkt, &alloc, out, "testdata/test_packets.1"); testfromfile(pkt, &alloc, out, "testdata/test_packets.2"); testfromfile(pkt, &alloc, out, "testdata/test_packets.3"); /* like from drill -w - */ testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.4"); testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.5"); matches_nolocation = 1; /* RR order not important for the next test */ testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.6"); check_rrsigs = 1; testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.7"); check_rrsigs = 0; matches_nolocation = 0; check_formerr_gone = 1; testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.8"); check_formerr_gone = 0; /* cleanup */ alloc_clear(&alloc); alloc_clear(&super_a); ldns_buffer_free(pkt); ldns_buffer_free(out); }
/* Add new RR data */ int ub_ctx_data_add(struct ub_ctx* ctx, char *data) { ldns_buffer* buf; int res = ub_ctx_finalize(ctx); if (res) return res; lock_basic_lock(&ctx->cfglock); buf = ldns_buffer_new(ctx->env->cfg->msg_buffer_size); lock_basic_unlock(&ctx->cfglock); if(!buf) return UB_NOMEM; res = local_zones_add_RR(ctx->local_zones, data, buf); ldns_buffer_free(buf); return (!res) ? UB_NOMEM : UB_NOERROR; }
/** check if module works with config */ static void check_mod(struct config_file* cfg, struct module_func_block* fb) { struct module_env env; memset(&env, 0, sizeof(env)); env.cfg = cfg; env.scratch = regional_create(); env.scratch_buffer = ldns_buffer_new(BUFSIZ); if(!env.scratch || !env.scratch_buffer) fatal_exit("out of memory"); if(!(*fb->init)(&env, 0)) { fatal_exit("bad config for %s module", fb->name); } (*fb->deinit)(&env, 0); ldns_buffer_free(env.scratch_buffer); regional_destroy(env.scratch); }
static int l_pkt2buf(lua_State *L) { ldns_pkt *p = (ldns_pkt *)lua_touserdata(L, 1); ldns_buffer *b; if (!p) { return 0; } b = ldns_buffer_new(LDNS_MIN_BUFLEN); if (ldns_pkt2buffer_wire(b, p) != LDNS_STATUS_OK) { ldns_buffer_free(b); return 0; } lua_pushlightuserdata(L, b); return 1; }
/** verify from a file */ static void verifytest_file(const char* fname, const char* at_date) { /* * The file contains a list of ldns-testpkts entries. * The first entry must be a query for DNSKEY. * The answer rrset is the keyset that will be used for verification */ struct ub_packed_rrset_key* dnskey; struct regional* region = regional_create(); struct alloc_cache alloc; ldns_buffer* buf = ldns_buffer_new(65535); struct entry* e; struct entry* list = read_datafile(fname); struct module_env env; struct val_env ve; uint32_t now = time(NULL); if(!list) fatal_exit("could not read %s: %s", fname, strerror(errno)); alloc_init(&alloc, NULL, 1); memset(&env, 0, sizeof(env)); memset(&ve, 0, sizeof(ve)); env.scratch = region; env.scratch_buffer = buf; env.now = &now; ve.date_override = cfg_convert_timeval(at_date); unit_assert(region && buf); dnskey = extract_keys(list, &alloc, region, buf); if(vsig) log_nametypeclass(VERB_QUERY, "test dnskey", dnskey->rk.dname, ntohs(dnskey->rk.type), ntohs(dnskey->rk.rrset_class)); /* ready to go! */ for(e = list->next; e; e = e->next) { verifytest_entry(e, &alloc, region, buf, dnskey, &env, &ve); } ub_packed_rrset_parsedelete(dnskey, &alloc); delete_entry(list); regional_destroy(region); alloc_clear(&alloc); ldns_buffer_free(buf); }