コード例 #1
0
ファイル: dnspkt.c プロジェクト: cathuhoo/cernet-dnsmon
void dnspkt_printqry (ldns_rr *rr, struct timeval ts, host_t *src, host_t *dst) {
    FILE *output = dnsfile_qry();
    __print_ts(output, ts);
    __print_ip(output, src);
    __print_ip(output, dst);
    ldns_rr_print(output, rr);
}
コード例 #2
0
ファイル: lua.c プロジェクト: benlaurie/ldns
static int
l_rr_print(lua_State *L)
{
	/* we always print to stdout */
	ldns_rr *toprint = (ldns_rr*)lua_touserdata(L, 1); /* pop from the stack */
	if (!toprint) {
		return 0;
	}

	ldns_rr_print(stdout, toprint);
	return 0;
}
コード例 #3
0
ファイル: dnspkt.c プロジェクト: cathuhoo/cernet-dnsmon
void dnspkt_printrr (ldns_rr *rr, struct timeval ts, host_t *src, host_t *dst, uint16_t section) {
    FILE *output = dnsfile_rr();
    __print_ts(output, ts);
    __print_ip(output, src);
    __print_ip(output, dst);
    if (section == 0) {
        fprintf(output, "AN\t");
    } else if (section == 1) {
        fprintf(output, "NS\t");
    } else if (section == 2) {
        fprintf(output, "AR\t");
    } else {
        fprintf(output, "\t");
    }
    ldns_rr_print(output, rr);
}
コード例 #4
0
ファイル: dnspkt.c プロジェクト: cathuhoo/cernet-dnsmon
void dnspkt_printresp (ldns_pkt *pkt, struct timeval ts, host_t *src, host_t *dst) {
    FILE *output = dnsfile_resp();
    __print_ts(output, ts);
    __print_ip(output, src);
    __print_ip(output, dst);
    fprintf(output, "%u\t", (uint16_t)ldns_pkt_size(pkt));
    fprintf(output, "%u\t", ldns_pkt_aa(pkt));
    fprintf(output, "%u\t", ldns_pkt_tc(pkt));
    fprintf(output, "%u\t", ldns_pkt_rd(pkt));
    fprintf(output, "%u\t", ldns_pkt_ra(pkt));
    fprintf(output, "%u\t", ldns_pkt_get_rcode(pkt));
    fprintf(output, "%u\t", ldns_pkt_qdcount(pkt));
    fprintf(output, "%u\t", ldns_pkt_ancount(pkt));
    fprintf(output, "%u\t", ldns_pkt_nscount(pkt));
    fprintf(output, "%u\t", ldns_pkt_arcount(pkt));
    ldns_rr_list *rrlist = ldns_pkt_question(pkt);
    if (ldns_rr_list_rr_count(rrlist) > 0) {
        ldns_rr_print(output, ldns_rr_list_rr(rrlist, 0));
    } else {
        fprintf(output, "\t\t\n");
    }
}
コード例 #5
0
/**
 * Main function of drill
 * parse the arguments and prepare a query
 */
int
main(int argc, char *argv[])
{
        ldns_resolver	*res = NULL;
        ldns_resolver   *cmdline_res = NULL; /* only used to resolv @name names */
	ldns_rr_list	*cmdline_rr_list = NULL;
	ldns_rdf	*cmdline_dname = NULL;
        ldns_rdf 	*qname, *qname_tmp;
        ldns_pkt	*pkt;
        ldns_pkt	*qpkt;
        char 		*serv;
        const char 	*name;
        char 		*name2;
	char		*progname;
	char 		*query_file = NULL;
	char		*answer_file = NULL;
	ldns_buffer	*query_buffer = NULL;
	ldns_rdf 	*serv_rdf;
        ldns_rr_type 	type;
        ldns_rr_class	clas;
#if 0
	ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
#endif
	int 		i, c;
	int 		int_type;
	int		int_clas;
	int		PURPOSE;
	char		*tsig_name = NULL;
	char		*tsig_data = NULL;
	char 		*tsig_algorithm = NULL;
	size_t		tsig_separator;
	size_t		tsig_separator2;
	ldns_rr		*axfr_rr;
	ldns_status	status;
	char *type_str;
	
	/* list of keys used in dnssec operations */
	ldns_rr_list	*key_list = ldns_rr_list_new(); 
	/* what key verify the current answer */
	ldns_rr_list 	*key_verified;

	/* resolver options */
	uint16_t	qflags;
	uint16_t 	qbuf;
	uint16_t	qport;
	uint8_t		qfamily;
	bool		qdnssec;
	bool		qfallback;
	bool		qds;
	bool		qusevc;
	bool 		qrandom;
	
	char		*resolv_conf_file = NULL;
	
	ldns_rdf *trace_start_name = NULL;

	int		result = 0;

#ifdef USE_WINSOCK
	int r;
	WSADATA wsa_data;
#endif

	int_type = -1; serv = NULL; type = 0; 
	int_clas = -1; name = NULL; clas = 0;
	qname = NULL; 
	progname = strdup(argv[0]);

#ifdef USE_WINSOCK
	r = WSAStartup(MAKEWORD(2,2), &wsa_data);
	if(r != 0) {
		printf("Failed WSAStartup: %d\n", r);
		result = EXIT_FAILURE;
		goto exit;
	}
#endif /* USE_WINSOCK */
		
	
	PURPOSE = DRILL_QUERY;
	qflags = LDNS_RD;
	qport = LDNS_PORT;
	verbosity = 2;
	qdnssec = false;
	qfamily = LDNS_RESOLV_INETANY;
	qfallback = false;
	qds = false;
	qbuf = 0;
	qusevc = false;
	qrandom = true;
	key_verified = NULL;

	ldns_init_random(NULL, 0);

	if (argc == 0) {
		usage(stdout, progname);
		result = EXIT_FAILURE;
		goto exit;
	}

	/* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
	/* global first, query opt next, option with parm's last
	 * and sorted */ /*  "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
	                               
	while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:Ik:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
		switch(c) {
			/* global options */
			case '4':
				qfamily = LDNS_RESOLV_INET;
				break;
			case '6':
				qfamily = LDNS_RESOLV_INET6;
				break;
			case 'D':
				qdnssec = true;
				break;
			case 'I':
				/* reserved for backward compatibility */
				break;
			case 'T':
				if (PURPOSE == DRILL_CHASE) {
					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
					exit(EXIT_FAILURE);
				}
				PURPOSE = DRILL_TRACE;
				break;
#ifdef HAVE_SSL
			case 'S':
				if (PURPOSE == DRILL_TRACE) {
					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
					exit(EXIT_FAILURE);
				}
				PURPOSE = DRILL_CHASE;
				break;
#endif /* HAVE_SSL */
			case 'V':
				if (strtok(optarg, "0123456789") != NULL) {
					fprintf(stderr, "-V expects an number as an argument.\n");
					exit(EXIT_FAILURE);
				}
				verbosity = atoi(optarg);
				break;
			case 'Q':
				verbosity = -1;
				break;
			case 'f':
				query_file = optarg;
				break;
			case 'i':
				answer_file = optarg;
				PURPOSE = DRILL_AFROMFILE;
				break;
			case 'w':
				answer_file = optarg;
				break;
			case 'q':
				query_file = optarg;
				PURPOSE = DRILL_QTOFILE;
				break;
			case 'r':
				if (global_dns_root) {
					fprintf(stderr, "There was already a series of root servers set\n");
					exit(EXIT_FAILURE);
				}
				global_dns_root = read_root_hints(optarg);
				if (!global_dns_root) {
					fprintf(stderr, "Unable to read root hints file %s, aborting\n", optarg);
					exit(EXIT_FAILURE);
				}
				break;
			/* query options */
			case 'a':
				qfallback = true;
				break;
			case 'b':
				qbuf = (uint16_t)atoi(optarg);
				if (qbuf == 0) {
					error("%s", "<bufsize> could not be converted");
				}
				break;
			case 'c':
				resolv_conf_file = optarg;
				break;
			case 't':
				qusevc = true;
				break;
			case 'k':
				status = read_key_file(optarg,
						key_list, false);
				if (status != LDNS_STATUS_OK) {
					error("Could not parse the key file %s: %s", optarg, ldns_get_errorstr_by_id(status));
				}
				qdnssec = true; /* enable that too */
				break;
			case 'o':
				/* only looks at the first hit: capital=ON, lowercase=OFF*/
				if (strstr(optarg, "QR")) {
					DRILL_ON(qflags, LDNS_QR);
				}
				if (strstr(optarg, "qr")) {
					DRILL_OFF(qflags, LDNS_QR);
				}
				if (strstr(optarg, "AA")) {
					DRILL_ON(qflags, LDNS_AA);
				}
				if (strstr(optarg, "aa")) {
					DRILL_OFF(qflags, LDNS_AA);
				}
				if (strstr(optarg, "TC")) {
					DRILL_ON(qflags, LDNS_TC);
				}
				if (strstr(optarg, "tc")) {
					DRILL_OFF(qflags, LDNS_TC);
				}
				if (strstr(optarg, "RD")) {
					DRILL_ON(qflags, LDNS_RD);
				}
				if (strstr(optarg, "rd")) {
					DRILL_OFF(qflags, LDNS_RD);
				}
				if (strstr(optarg, "CD")) {
					DRILL_ON(qflags, LDNS_CD);
				}
				if (strstr(optarg, "cd")) {
					DRILL_OFF(qflags, LDNS_CD);
				}
				if (strstr(optarg, "RA")) {
					DRILL_ON(qflags, LDNS_RA);
				}
				if (strstr(optarg, "ra")) {
					DRILL_OFF(qflags, LDNS_RA);
				}
				if (strstr(optarg, "AD")) {
					DRILL_ON(qflags, LDNS_AD);
				}
				if (strstr(optarg, "ad")) {
					DRILL_OFF(qflags, LDNS_AD);
				}
				break;
			case 'p':
				qport = (uint16_t)atoi(optarg);
				if (qport == 0) {
					error("%s", "<port> could not be converted");
				}
				break;
			case 's':
				qds = true;
				break;
			case 'u':
				qusevc = false;
				break;
			case 'v':
				version(stdout, progname);
				result = EXIT_SUCCESS;
				goto exit;
			case 'x':
				PURPOSE = DRILL_REVERSE;
				break;
			case 'y':
#ifdef HAVE_SSL
				if (strchr(optarg, ':')) {
					tsig_separator = (size_t) (strchr(optarg, ':') - optarg);
					if (strchr(optarg + tsig_separator + 1, ':')) {
						tsig_separator2 = (size_t) (strchr(optarg + tsig_separator + 1, ':') - optarg);
						tsig_algorithm = xmalloc(strlen(optarg) - tsig_separator2);
						strncpy(tsig_algorithm, optarg + tsig_separator2 + 1, strlen(optarg) - tsig_separator2);
						tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
					} else {
						tsig_separator2 = strlen(optarg);
						tsig_algorithm = xmalloc(26);
						strncpy(tsig_algorithm, "hmac-md5.sig-alg.reg.int.", 25);
						tsig_algorithm[25] = '\0';
					}
					tsig_name = xmalloc(tsig_separator + 1);
					tsig_data = xmalloc(tsig_separator2 - tsig_separator);
					strncpy(tsig_name, optarg, tsig_separator);
					strncpy(tsig_data, optarg + tsig_separator + 1, tsig_separator2 - tsig_separator - 1);
					/* strncpy does not append \0 if source is longer than n */
					tsig_name[tsig_separator] = '\0';
					tsig_data[ tsig_separator2 - tsig_separator - 1] = '\0';
				}
#else
				fprintf(stderr, "TSIG requested, but SSL is not supported\n");
				result = EXIT_FAILURE;
				goto exit;
#endif /* HAVE_SSL */
				break;
			case 'z':
				qrandom = false;
				break;
			case 'd':
				trace_start_name = ldns_dname_new_frm_str(optarg);
				if (!trace_start_name) {
					fprintf(stderr, "Unable to parse argument for -%c\n", c);
					result = EXIT_FAILURE;
					goto exit;
				}
				break;
			case 'h':
				version(stdout, progname);
				usage(stdout, progname);
				result = EXIT_SUCCESS;
				goto exit;
				break;
			default:
				fprintf(stderr, "Unknown argument: -%c, use -h to see usage\n", c);
				result = EXIT_FAILURE;
				goto exit;
		}
	}
	argc -= optind;
	argv += optind;

	if ((PURPOSE == DRILL_CHASE || (PURPOSE == DRILL_TRACE && qdnssec)) &&
			ldns_rr_list_rr_count(key_list) == 0) {

		(void) read_key_file(LDNS_TRUST_ANCHOR_FILE, key_list, true);
	}
	if (ldns_rr_list_rr_count(key_list) > 0) {
		printf(";; Number of trusted keys: %d\n",
				(int) ldns_rr_list_rr_count(key_list));
	}
	/* do a secure trace when requested */
	if (PURPOSE == DRILL_TRACE && qdnssec) {
#ifdef HAVE_SSL
		if (ldns_rr_list_rr_count(key_list) == 0) {
			warning("%s", "No trusted keys were given. Will not be able to verify authenticity!");
		}
		PURPOSE = DRILL_SECTRACE;
#else
		fprintf(stderr, "ldns has not been compiled with OpenSSL support. Secure trace not available\n");
		exit(1);
#endif /* HAVE_SSL */
	}

	/* parse the arguments, with multiple arguments, the last argument
	 * found is used */
	for(i = 0; i < argc; i++) {

		/* if ^@ then it's a server */
		if (argv[i][0] == '@') {
			if (strlen(argv[i]) == 1) {
				warning("%s", "No nameserver given");
				exit(EXIT_FAILURE);
			}
			serv = argv[i] + 1;
			continue;
		}
		/* if has a dot, it's a name */
		if (strchr(argv[i], '.')) {
			name = argv[i];
			continue;
		}
		/* if it matches a type, it's a type */
		if (int_type == -1) {
			type = ldns_get_rr_type_by_name(argv[i]);
			if (type != 0) {
				int_type = 0;
				continue;
			}
		}
		/* if it matches a class, it's a class */
		if (int_clas == -1) {
			clas = ldns_get_rr_class_by_name(argv[i]);
			if (clas != 0) {
				int_clas = 0;
				continue;
			}
		}
		/* it all fails assume it's a name */
		name = argv[i];
	}
	/* act like dig and use for . NS */
	if (!name) {
		name = ".";
		int_type = 0;
		type = LDNS_RR_TYPE_NS;
	}
	
	/* defaults if not given */
	if (int_clas == -1) {
		clas = LDNS_RR_CLASS_IN;
	}
	if (int_type == -1) {
		if (PURPOSE != DRILL_REVERSE) {
			type = LDNS_RR_TYPE_A;
		} else {
			type = LDNS_RR_TYPE_PTR;
		}
	}

	/* set the nameserver to use */
	if (!serv) {
		/* no server given make a resolver from /etc/resolv.conf */
		status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
		if (status != LDNS_STATUS_OK) {
			warning("Could not create a resolver structure: %s (%s)\n"
					"Try drill @localhost if you have a resolver running on your machine.",
				    ldns_get_errorstr_by_id(status), resolv_conf_file);
			result = EXIT_FAILURE;
			goto exit;
		}
	} else {
		res = ldns_resolver_new();
		if (!res || strlen(serv) <= 0) {
			warning("Could not create a resolver structure");
			result = EXIT_FAILURE;
			goto exit;
		}
		/* add the nameserver */
		serv_rdf = ldns_rdf_new_addr_frm_str(serv);
		if (!serv_rdf) {
			/* try to resolv the name if possible */
			status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
			
			if (status != LDNS_STATUS_OK) {
				error("%s", "@server ip could not be converted");
			}
			ldns_resolver_set_dnssec(cmdline_res, qdnssec);
			ldns_resolver_set_ip6(cmdline_res, qfamily);
			ldns_resolver_set_fallback(cmdline_res, qfallback);
			ldns_resolver_set_usevc(cmdline_res, qusevc);

			cmdline_dname = ldns_dname_new_frm_str(serv);

			cmdline_rr_list = ldns_get_rr_list_addr_by_name(
						cmdline_res, 
						cmdline_dname,
						LDNS_RR_CLASS_IN,
						qflags);
			ldns_rdf_deep_free(cmdline_dname);
			if (!cmdline_rr_list) {
				/* This error msg is not always accurate */
				error("%s `%s\'", "could not find any address for the name:", serv);
			} else {
				if (ldns_resolver_push_nameserver_rr_list(
						res, 
						cmdline_rr_list
					) != LDNS_STATUS_OK) {
					error("%s", "pushing nameserver");
				}
			}
		} else {
			if (ldns_resolver_push_nameserver(res, serv_rdf) != LDNS_STATUS_OK) {
				error("%s", "pushing nameserver");
			} else {
				ldns_rdf_deep_free(serv_rdf);
			}
		}
	}
	/* set the resolver options */
	ldns_resolver_set_port(res, qport);
	if (verbosity >= 5) {
		ldns_resolver_set_debug(res, true);
	} else {
		ldns_resolver_set_debug(res, false);
	}
	ldns_resolver_set_dnssec(res, qdnssec);
/*	ldns_resolver_set_dnssec_cd(res, qdnssec);*/
	ldns_resolver_set_ip6(res, qfamily);
	ldns_resolver_set_fallback(res, qfallback);
	ldns_resolver_set_usevc(res, qusevc);
	ldns_resolver_set_random(res, qrandom);
	if (qbuf != 0) {
		ldns_resolver_set_edns_udp_size(res, qbuf);
	}

	if (!name && 
	    PURPOSE != DRILL_AFROMFILE &&
	    !query_file
	   ) {
		usage(stdout, progname);
		result = EXIT_FAILURE;
		goto exit;
	}

	if (tsig_name && tsig_data) {
		ldns_resolver_set_tsig_keyname(res, tsig_name);
		ldns_resolver_set_tsig_keydata(res, tsig_data);
		ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
	}
	
	/* main switching part of drill */
	switch(PURPOSE) {
		case DRILL_TRACE:
			/* do a trace from the root down */
			if (!global_dns_root) {
				init_root();
			}
			qname = ldns_dname_new_frm_str(name);
			if (!qname) {
				error("%s", "parsing query name");
			}
			/* don't care about return packet */
			(void)do_trace(res, qname, type, clas);
			clear_root();
			break;
		case DRILL_SECTRACE:
			/* do a secure trace from the root down */
			if (!global_dns_root) {
				init_root();
			}
			qname = ldns_dname_new_frm_str(name);
			if (!qname) {
				error("%s", "making qname");
			}
			/* don't care about return packet */
#ifdef HAVE_SSL
			result = do_secure_trace(res, qname, type, clas, key_list, trace_start_name);
#endif /* HAVE_SSL */
			clear_root();
			break;
		case DRILL_CHASE:
			qname = ldns_dname_new_frm_str(name);
			if (!qname) {
				error("%s", "making qname");
			}
			
			ldns_resolver_set_dnssec(res, true);
			ldns_resolver_set_dnssec_cd(res, true);
			/* set dnssec implies udp_size of 4096 */
			ldns_resolver_set_edns_udp_size(res, 4096);
			pkt = ldns_resolver_query(res, qname, type, clas, qflags);
			
			if (!pkt) {
				error("%s", "error pkt sending");
				result = EXIT_FAILURE;
			} else {
				if (verbosity >= 3) {
					ldns_pkt_print(stdout, pkt);
				}
				
				if (!ldns_pkt_answer(pkt)) {
					mesg("No answer in packet");
				} else {
#ifdef HAVE_SSL
					ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
					result = do_chase(res, qname, type,
					                  clas, key_list, 
					                  pkt, qflags, NULL,
								   verbosity);
					if (result == LDNS_STATUS_OK) {
						if (verbosity != -1) {
							mesg("Chase successful");
						}
						result = 0;
					} else {
						if (verbosity != -1) {
							mesg("Chase failed.");
						}
					}
#endif /* HAVE_SSL */
				}
				ldns_pkt_free(pkt);
			}
			break;
		case DRILL_AFROMFILE:
			pkt = read_hex_pkt(answer_file);
			if (pkt) {
				if (verbosity != -1) {
					ldns_pkt_print(stdout, pkt);
				}
				ldns_pkt_free(pkt);
			}
			
			break;
		case DRILL_QTOFILE:
			qname = ldns_dname_new_frm_str(name);
			if (!qname) {
				error("%s", "making qname");
			}

			status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
			if(status != LDNS_STATUS_OK) {
				error("%s", "making query: %s", 
					ldns_get_errorstr_by_id(status));
			}
			dump_hex(qpkt, query_file);
			ldns_pkt_free(qpkt);
			break;
		case DRILL_NSEC:
			break;
		case DRILL_REVERSE:
			/* ipv4 or ipv6 addr? */
			if (strchr(name, ':')) {
				if (strchr(name, '.')) {
					error("Syntax error: both '.' and ':' seen in address\n");
				}
				name2 = malloc(IP6_ARPA_MAX_LEN + 20);
				c = 0;
				for (i=0; i<(int)strlen(name); i++) {
					if (i >= IP6_ARPA_MAX_LEN) {
						error("%s", "reverse argument to long");
					}
					if (name[i] == ':') {
						if (i < (int) strlen(name) && name[i + 1] == ':') {
							error("%s", ":: not supported (yet)");
						} else {
							if (i + 2 == (int) strlen(name) || name[i + 2] == ':') {
								name2[c++] = '0';
								name2[c++] = '.';
								name2[c++] = '0';
								name2[c++] = '.';
								name2[c++] = '0';
								name2[c++] = '.';
							} else if (i + 3 == (int) strlen(name) || name[i + 3] == ':') {
								name2[c++] = '0';
								name2[c++] = '.';
								name2[c++] = '0';
								name2[c++] = '.';
							} else if (i + 4 == (int) strlen(name) || name[i + 4] == ':') {
								name2[c++] = '0';
								name2[c++] = '.';
							}
						}
					} else {
						name2[c++] = name[i];
						name2[c++] = '.';
					}
				}
				name2[c++] = '\0';

				qname = ldns_dname_new_frm_str(name2);
				qname_tmp = ldns_dname_reverse(qname);
				ldns_rdf_deep_free(qname);
				qname = qname_tmp;
				qname_tmp = ldns_dname_new_frm_str("ip6.arpa.");
				status = ldns_dname_cat(qname, qname_tmp);
				if (status != LDNS_STATUS_OK) {
					error("%s", "could not create reverse address for ip6: %s\n", ldns_get_errorstr_by_id(status));
				}
				ldns_rdf_deep_free(qname_tmp);

				free(name2);
			} else {
				qname = ldns_dname_new_frm_str(name);
				qname_tmp = ldns_dname_reverse(qname);
				ldns_rdf_deep_free(qname);
				qname = qname_tmp;
				qname_tmp = ldns_dname_new_frm_str("in-addr.arpa.");
				status = ldns_dname_cat(qname, qname_tmp);
				if (status != LDNS_STATUS_OK) {
					error("%s", "could not create reverse address for ip4: %s\n", ldns_get_errorstr_by_id(status));
				}
				ldns_rdf_deep_free(qname_tmp);
			}
			if (!qname) {
				error("%s", "-x implies an ip address");
			}
			
			/* create a packet and set the RD flag on it */
			pkt = ldns_resolver_query(res, qname, type, clas, qflags);
			if (!pkt)  {
				error("%s", "pkt sending");
				result = EXIT_FAILURE;
			} else {
				if (verbosity != -1) {
					ldns_pkt_print(stdout, pkt);
				}
				ldns_pkt_free(pkt);
			}
			break;
		case DRILL_QUERY:
		default:
			if (query_file) {
				/* this old way, the query packet needed
				   to be parseable, but we want to be able
				   to send mangled packets, so we need
				   to do it directly */
				#if 0
				qpkt = read_hex_pkt(query_file);
				if (qpkt) {
					status = ldns_resolver_send_pkt(&pkt, res, qpkt);
					if (status != LDNS_STATUS_OK) {
						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
						exit(1);
					}
				} else {
					/* qpkt was bogus, reset pkt */
					pkt = NULL;
				}
				#endif
				query_buffer = read_hex_buffer(query_file);
				if (query_buffer) {
					status = ldns_send_buffer(&pkt, res, query_buffer, NULL);
					ldns_buffer_free(query_buffer);
					if (status != LDNS_STATUS_OK) {
						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
						exit(1);
					}
				} else {
					printf("NO BUFFER\n");
					pkt = NULL;
				}
			} else {
				qname = ldns_dname_new_frm_str(name);
				if (!qname) {
					error("%s", "error in making qname");
				}

				if (type == LDNS_RR_TYPE_AXFR) {
					status = ldns_axfr_start(res, qname, clas);
					if(status != LDNS_STATUS_OK) {
						error("Error starting axfr: %s", 
							ldns_get_errorstr_by_id(status));
					}
					axfr_rr = ldns_axfr_next(res);
					if(!axfr_rr) {
						fprintf(stderr, "AXFR failed.\n");
						ldns_pkt_print(stdout,
							ldns_axfr_last_pkt(res));
						goto exit;
					}
					while (axfr_rr) {
						if (verbosity != -1) {
							ldns_rr_print(stdout, axfr_rr);
						}
						ldns_rr_free(axfr_rr);
						axfr_rr = ldns_axfr_next(res);
					}

					goto exit;
				} else {
					/* create a packet and set the RD flag on it */
					pkt = ldns_resolver_query(res, qname, type, clas, qflags);
				}
			}
			
			if (!pkt)  {
				mesg("No packet received");
				result = EXIT_FAILURE;
			} else {
				if (verbosity != -1) {
					ldns_pkt_print(stdout, pkt);
					if (ldns_pkt_tc(pkt)) {
						fprintf(stdout,
							"\n;; WARNING: The answer packet was truncated; you might want to\n");
						fprintf(stdout,
							";; query again with TCP (-t argument), or EDNS0 (-b for buffer size)\n");
					}
				}
				if (qds) {
					if (verbosity != -1) {
						print_ds_of_keys(pkt);
						printf("\n");
					}
				}
			
				if (ldns_rr_list_rr_count(key_list) > 0) {
					/* -k's were given on the cmd line */
					ldns_rr_list *rrset_verified;
					uint16_t key_count;

					rrset_verified = ldns_pkt_rr_list_by_name_and_type(
							pkt, qname, type, 
							LDNS_SECTION_ANY_NOQUESTION);

					if (type == LDNS_RR_TYPE_ANY) {
						/* don't verify this */
						break;
					}

					if (verbosity != -1) {
						printf("; ");
						ldns_rr_list_print(stdout, rrset_verified);
					}

					/* verify */
#ifdef HAVE_SSL
					key_verified = ldns_rr_list_new();
					result = ldns_pkt_verify(pkt, type, qname, key_list, NULL, key_verified);

					if (result == LDNS_STATUS_ERR) {
						/* is the existence denied then? */
						result = ldns_verify_denial(pkt, qname, type, NULL, NULL);
						if (result == LDNS_STATUS_OK) {
							if (verbosity != -1) {
								printf("Existence denied for ");
								ldns_rdf_print(stdout, qname);
								type_str = ldns_rr_type2str(type);
								printf("\t%s\n", type_str);
								LDNS_FREE(type_str);
							}
						} else {
							if (verbosity != -1) {
								printf("Bad data; RR for name and "
								       "type not found or failed to "
								       "verify, and denial of "
								       "existence failed.\n");
							}
						}
					} else if (result == LDNS_STATUS_OK) {
						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_verified);
								key_count++) {
							if (verbosity != -1) {
								printf("; VALIDATED by id = %u, owner = ",
										(unsigned int)ldns_calc_keytag(
												      ldns_rr_list_rr(key_verified, key_count)));
								ldns_rdf_print(stdout, ldns_rr_owner(
											ldns_rr_list_rr(key_list, key_count)));
								printf("\n");
							}
						}
					} else {
						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_list);
								key_count++) {
							if (verbosity != -1) {
								printf("; %s for id = %u, owner = ",
								       ldns_get_errorstr_by_id(result),
								       (unsigned int)ldns_calc_keytag(
												      ldns_rr_list_rr(key_list, key_count)));
								ldns_rdf_print(stdout, ldns_rr_owner(

								ldns_rr_list_rr(key_list,
								key_count)));
								printf("\n");
							}
						}
					}
					ldns_rr_list_free(key_verified);
#else
					(void) key_count;
#endif /* HAVE_SSL */
				}
				if (answer_file) {
					dump_hex(pkt, answer_file);
				}
				ldns_pkt_free(pkt); 
			}
			
			break;
	}

	exit:
	ldns_rdf_deep_free(qname);
	ldns_resolver_deep_free(res);
	ldns_resolver_deep_free(cmdline_res);
	ldns_rr_list_deep_free(key_list);
	ldns_rr_list_deep_free(cmdline_rr_list);
	ldns_rdf_deep_free(trace_start_name);
	xfree(progname);
	xfree(tsig_name);
	xfree(tsig_data);
	xfree(tsig_algorithm);

#ifdef HAVE_SSL
	ERR_remove_state(0);
	CRYPTO_cleanup_all_ex_data();
	ERR_free_strings();
	EVP_cleanup();
#endif
#ifdef USE_WINSOCK
	WSACleanup();
#endif

	return result;
}
コード例 #6
0
ファイル: ldns-testpkts.c プロジェクト: RS-liuyang/rsdns
/*
 * Parses data buffer to a query, finds the correct answer 
 * and calls the given function for every packet to send.
 */
void
handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count,
	enum transport_type transport, void (*sendfunc)(uint8_t*, size_t, void*),
	void* userdata, FILE* verbose_out)
{
	ldns_status status;
	ldns_pkt *query_pkt = NULL;
	ldns_pkt *answer_pkt = NULL;
	struct reply_packet *p;
	ldns_rr *query_rr = NULL;
	uint8_t *outbuf = NULL;
	size_t answer_size = 0;
	struct entry* entry = NULL;
	ldns_rdf *stop_command = ldns_dname_new_frm_str("server.stop.");

	status = ldns_wire2pkt(&query_pkt, inbuf, (size_t)inlen);
	if (status != LDNS_STATUS_OK) {
		verbose(1, "Got bad packet: %s\n", ldns_get_errorstr_by_id(status));
		ldns_rdf_free(stop_command);
		return;
	}
	
	query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0);
	verbose(1, "query %d: id %d: %s %d bytes: ", ++(*count), (int)ldns_pkt_id(query_pkt), 
		(transport==transport_tcp)?"TCP":"UDP", (int)inlen);
	if(verbose_out) ldns_rr_print(verbose_out, query_rr);
	if(verbose_out) ldns_pkt_print(verbose_out, query_pkt);

	if (ldns_rr_get_type(query_rr) == LDNS_RR_TYPE_TXT &&
	    ldns_rr_get_class(query_rr) == LDNS_RR_CLASS_CH &&
	    ldns_dname_compare(ldns_rr_owner(query_rr), stop_command) == 0) {
		exit(0);
        }
	
	/* fill up answer packet */
	entry = find_match(entries, query_pkt, transport);
	if(!entry || !entry->reply_list) {
		verbose(1, "no answer packet for this query, no reply.\n");
		ldns_pkt_free(query_pkt);
		ldns_rdf_free(stop_command);
		return;
	}
	for(p = entry->reply_list; p; p = p->next)
	{
		verbose(3, "Answer pkt:\n");
		if (p->reply_from_hex) {
			/* try to parse the hex packet, if it can be
			 * parsed, we can use adjust rules. if not,
			 * send packet literally */
			status = ldns_buffer2pkt_wire(&answer_pkt, p->reply_from_hex);
			if (status == LDNS_STATUS_OK) {
				adjust_packet(entry, answer_pkt, query_pkt);
				if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt);
				status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
				verbose(2, "Answer packet size: %u bytes.\n", (unsigned int)answer_size);
				if (status != LDNS_STATUS_OK) {
					verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
					ldns_pkt_free(query_pkt);
					ldns_rdf_free(stop_command);
					return;
				}
				ldns_pkt_free(answer_pkt);
				answer_pkt = NULL;
			} else {
				verbose(3, "Could not parse hex data (%s), sending hex data directly.\n", ldns_get_errorstr_by_id(status));
				/* still try to adjust ID */
				answer_size = ldns_buffer_capacity(p->reply_from_hex);
				outbuf = LDNS_XMALLOC(uint8_t, answer_size);
				memcpy(outbuf, ldns_buffer_export(p->reply_from_hex), answer_size);
				if(entry->copy_id) {
					ldns_write_uint16(outbuf, 
						ldns_pkt_id(query_pkt));
				}
			}
		} else {
			answer_pkt = ldns_pkt_clone(p->reply);
			adjust_packet(entry, answer_pkt, query_pkt);
			if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt);
			status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
			verbose(1, "Answer packet size: %u bytes.\n", (unsigned int)answer_size);
			if (status != LDNS_STATUS_OK) {
				verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
				ldns_pkt_free(query_pkt);
				ldns_rdf_free(stop_command);
				return;
			}
			ldns_pkt_free(answer_pkt);
			answer_pkt = NULL;
		}
		if(p->packet_sleep) {
			verbose(3, "sleeping for next packet %d secs\n", 
				p->packet_sleep);
#ifdef HAVE_SLEEP
			sleep(p->packet_sleep);
#else
			Sleep(p->packet_sleep * 1000);
#endif
			verbose(3, "wakeup for next packet "
				"(slept %d secs)\n", p->packet_sleep);
		}
		sendfunc(outbuf, answer_size, userdata);
		LDNS_FREE(outbuf);
		outbuf = NULL;
		answer_size = 0;
	}
	ldns_pkt_free(query_pkt);
	ldns_rdf_free(stop_command);
}
コード例 #7
0
ファイル: ldnsd.c プロジェクト: benlaurie/ldns
int
main(int argc, char **argv)
{
	/* arguments */
	int port;
	const char *zone_file;

	/* network */
	int sock;
	ssize_t nb;
	struct sockaddr addr_me;
	struct sockaddr addr_him;
	socklen_t hislen = (socklen_t) sizeof(addr_him);
	uint8_t inbuf[INBUF_SIZE];
	uint8_t *outbuf;

	/* dns */
	ldns_status status;
	ldns_pkt *query_pkt;
	ldns_pkt *answer_pkt;
	size_t answer_size;
	ldns_rr *query_rr;
	ldns_rr_list *answer_qr;
	ldns_rr_list *answer_an;
	ldns_rr_list *answer_ns;
	ldns_rr_list *answer_ad;
	ldns_rdf *origin = NULL;
	
	/* zone */
	ldns_zone *zone;
	int line_nr;
	FILE *zone_fp;
	
	/* use this to listen on specified interfaces later? */
	char *my_address = NULL;
		
	if (argc < 5) {
		usage(stderr);
		exit(EXIT_FAILURE);
	} else {
	    my_address = argv[1];
		port = atoi(argv[2]);
		if (port < 1) {
			usage(stderr);
			exit(EXIT_FAILURE);
		}
		if (ldns_str2rdf_dname(&origin, argv[3]) != LDNS_STATUS_OK) {
			fprintf(stderr, "Bad origin, not a correct domain name\n");
			usage(stderr);
			exit(EXIT_FAILURE);
		}
		zone_file = argv[4];
	}
	
	printf("Reading zone file %s\n", zone_file);
	zone_fp = fopen(zone_file, "r");
	if (!zone_fp) {
		fprintf(stderr, "Unable to open %s: %s\n", zone_file, strerror(errno));
		exit(EXIT_FAILURE);
	}
	
	line_nr = 0;
	status = ldns_zone_new_frm_fp_l(&zone, zone_fp, origin, 0, LDNS_RR_CLASS_IN, &line_nr);

	if (status != LDNS_STATUS_OK) {
		printf("Zone reader failed, aborting\n");
		exit(EXIT_FAILURE);
	} else {
		printf("Read %u resource records in zone file\n", (unsigned int) ldns_zone_rr_count(zone));
	}
	fclose(zone_fp);

	printf("Listening on port %d\n", port);
	sock =  socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0) {
		fprintf(stderr, "%s: socket(): %s\n", argv[0], strerror(errno));
		exit(1);
	}
	memset(&addr_me, 0, sizeof(addr_me));

	/* bind: try all ports in that range */
	if (udp_bind(sock, port, my_address)) {
		fprintf(stderr, "%s: cannot bind(): %s\n", argv[0], strerror(errno));
		exit(errno);
	}

	/* Done. Now receive */
	while (1) {
		nb = recvfrom(sock, (void*)inbuf, INBUF_SIZE, 0, 
			&addr_him, &hislen);
		if (nb < 1) {
			fprintf(stderr, "%s: recvfrom(): %s\n",
			argv[0], strerror(errno));
			exit(1);
		}

		/*
		show(inbuf, nb, nn, hp, sp, ip, bp);
		*/
		printf("Got query of %u bytes\n", (unsigned int) nb);
		status = ldns_wire2pkt(&query_pkt, inbuf, (size_t) nb);
		if (status != LDNS_STATUS_OK) {
			printf("Got bad packet: %s\n", ldns_get_errorstr_by_id(status));
		} else {
			ldns_pkt_print(stdout, query_pkt);
		}

		query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0);
		printf("QUERY RR: \n");
		ldns_rr_print(stdout, query_rr);
		
		answer_qr = ldns_rr_list_new();
		ldns_rr_list_push_rr(answer_qr, ldns_rr_clone(query_rr));

		answer_an = get_rrset(zone, ldns_rr_owner(query_rr), ldns_rr_get_type(query_rr), ldns_rr_get_class(query_rr));
		answer_pkt = ldns_pkt_new();
		answer_ns = ldns_rr_list_new();
		answer_ad = ldns_rr_list_new();
		
		ldns_pkt_set_qr(answer_pkt, 1);
		ldns_pkt_set_aa(answer_pkt, 1);
		ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt));

		ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_QUESTION, answer_qr);
		ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ANSWER, answer_an);
		ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_AUTHORITY, answer_ns);
		ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ADDITIONAL, answer_ad);

		status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
		
		printf("Answer packet size: %u bytes.\n", (unsigned int) answer_size);
		if (status != LDNS_STATUS_OK) {
			printf("Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
		} else {
			nb = sendto(sock, (void*)outbuf, answer_size, 0, 
				&addr_him, hislen);
		}
		
		ldns_pkt_free(query_pkt);
		ldns_pkt_free(answer_pkt);
		LDNS_FREE(outbuf);
		ldns_rr_list_free(answer_qr);
		ldns_rr_list_free(answer_an);
		ldns_rr_list_free(answer_ns);
		ldns_rr_list_free(answer_ad);
	}
	
	/* No cleanup because of the infinite loop
	 *
	 * ldns_rdf_deep_free(origin);
	 * ldns_zone_deep_free(zone);
	 * return 0;
	 */
}
コード例 #8
0
int
main (int argc, char *argv[])
{
    int result;
    hsm_ctx_t *ctx;
    hsm_key_t **keys;
    hsm_key_t *key = NULL;
    char *id;
    size_t key_count = 0;
    size_t i;
    ldns_rr_list *rrset;
    ldns_rr *rr, *sig, *dnskey_rr;
    ldns_status status;
    hsm_sign_params_t *sign_params;

    int do_generate = 0;
    int do_sign = 0;
    int do_delete = 0;
    int do_random = 0;

    int res;
    uint32_t r32;
    uint64_t r64;

    char *config = NULL;
    const char *repository = "default";

    int ch;

    progname = argv[0];

    while ((ch = getopt(argc, argv, "hgsdrc:")) != -1) {
        switch (ch) {
        case 'c':
            config = strdup(optarg);
            break;
        case 'g':
            do_generate = 1;
            break;
        case 'h':
            usage();
            exit(0);
            break;
        case 's':
            do_sign = 1;
            break;
        case 'd':
            do_delete = 1;
            break;
        case 'r':
            do_random = 1;
            break;
        default:
            usage();
            exit(1);
        }
    }

    if (!config) {
        usage();
        exit(1);
    }

    /*
     * Open HSM library
     */
    fprintf(stdout, "Starting HSM lib test\n");
    result = hsm_open(config, hsm_prompt_pin);
    fprintf(stdout, "hsm_open result: %d\n", result);

    /*
     * Create HSM context
     */
    ctx = hsm_create_context();
    printf("global: ");
    hsm_print_ctx(NULL);
    printf("my: ");
    hsm_print_ctx(ctx);

    /*
     * Generate a new key OR find any key with an ID
     */
    if (do_generate) {
        key = hsm_generate_rsa_key(ctx, repository, 1024);

        if (key) {
            printf("\nCreated key!\n");
            hsm_print_key(key);
            printf("\n");
        } else {
            printf("Error creating key, bad token name?\n");
            hsm_print_error(ctx);
            exit(1);
        }
    } else if (do_sign || do_delete) {
        keys = hsm_list_keys(ctx, &key_count);
        printf("I have found %u keys\n", (unsigned int) key_count);

        /* let's just use the very first key we find and throw away the rest */
        for (i = 0; i < key_count && !key; i++) {
            printf("\nFound key!\n");
            hsm_print_key(keys[i]);

            id = hsm_get_key_id(ctx, keys[i]);

            if (id) {
                printf("Using key ID: %s\n", id);
                if (key) hsm_key_free(key);
                key = hsm_find_key_by_id(ctx, id);
                printf("ptr: 0x%p\n", (void *) key);
                free(id);
            } else {
                printf("Got no key ID (broken key?), skipped...\n");
            }

            hsm_key_free(keys[i]);
        }
        free(keys);

        if (!key) {
            printf("Failed to find useful key\n");
            exit(1);
        }
    }

    /*
     * Do some signing
     */
    if (do_sign) {
        printf("\nSigning with:\n");
        hsm_print_key(key);
        printf("\n");

        rrset = ldns_rr_list_new();

        status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 123.123.123.123", 0, NULL, NULL);
        if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr);
        status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 124.124.124.124", 0, NULL, NULL);
        if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr);

        sign_params = hsm_sign_params_new();
        sign_params->algorithm = LDNS_RSASHA1;
        sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "opendnssec.se.");
        dnskey_rr = hsm_get_dnskey(ctx, key, sign_params);
        sign_params->keytag = ldns_calc_keytag(dnskey_rr);

        sig = hsm_sign_rrset(ctx, rrset, key, sign_params);
        if (sig) {
            ldns_rr_list_print(stdout, rrset);
            ldns_rr_print(stdout, sig);
            ldns_rr_print(stdout, dnskey_rr);
            ldns_rr_free(sig);
        } else {
            hsm_print_error(ctx);
            exit(-1);
        }

        /* cleanup */
        ldns_rr_list_deep_free(rrset);
        hsm_sign_params_free(sign_params);
        ldns_rr_free(dnskey_rr);
    }

    /*
     * Delete key
     */
    if (do_delete) {
        printf("\nDelete key:\n");
        hsm_print_key(key);
        /* res = hsm_remove_key(ctx, key); */
        res = hsm_remove_key(ctx, key);
        printf("Deleted key. Result: %d\n", res);
        printf("\n");
    }

    if (key) hsm_key_free(key);

    /*
     * Test random{32,64} functions
     */
    if (do_random) {
        r32 = hsm_random32(ctx);
        printf("random 32: %u\n", r32);
        r64 = hsm_random64(ctx);
        printf("random 64: %llu\n", (long long unsigned int)r64);
    }

    /*
     * Destroy HSM context
     */
    if (ctx) {
        hsm_destroy_context(ctx);
    }

    /*
     * Close HSM library
     */
    result = hsm_close();
    fprintf(stdout, "all done! hsm_close result: %d\n", result);

    if (config) free(config);
    
    return 0;
}
コード例 #9
0
int
main(int argc, char *argv[])
{
	ldns_resolver *res;
	ldns_rdf *name;
	ldns_rdf *version, *id;
	ldns_pkt *p;
	ldns_rr_list *addr;
	ldns_rr_list *info;
	ldns_status s;
	ldns_rdf *pop;
	size_t i;
	
	if (argc != 2) {
		usage(stdout, argv[0]);
		exit(EXIT_FAILURE);
	} else {
		/* create a rdf from the command line arg */
		name = ldns_dname_new_frm_str(argv[1]);
		if (!name) {
			usage(stdout, argv[0]);
			exit(EXIT_FAILURE);
		}
	}

	/* create rdf for what we are going to ask */
	version = ldns_dname_new_frm_str("version.bind");
	id      = ldns_dname_new_frm_str("hostname.bind");

	/* create a new resolver from /etc/resolv.conf */
	s = ldns_resolver_new_frm_file(&res, NULL);
	if (s != LDNS_STATUS_OK) {
		ldns_rdf_deep_free(name);
		exit(EXIT_FAILURE);
	}
	ldns_resolver_set_retry(res, 1); /* don't want to wait too long */
	
	/* use the resolver to send it a query for the a/aaaa of name */
	addr = ldns_get_rr_list_addr_by_name(res, name, LDNS_RR_CLASS_IN, LDNS_RD);
	if (!addr) {
		fprintf(stderr, " *** could not get an address for %s\n", argv[1]);
		ldns_rdf_deep_free(name);
		ldns_resolver_deep_free(res);
		exit(EXIT_FAILURE);
	}

	/* remove current list of nameservers from resolver */
	while((pop = ldns_resolver_pop_nameserver(res))) { ldns_rdf_deep_free(pop); }


	/* can be multihomed */
	for(i = 0; i < ldns_rr_list_rr_count(addr); i++) {
		if (i > 0) {
			fprintf(stdout, "\n");
		}
			
		if (ldns_resolver_push_nameserver_rr(res,
				ldns_rr_list_rr(addr, i)) != LDNS_STATUS_OK) {
			printf("Error adding nameserver to resolver\n");
		}

		ldns_rr_print(stdout, ldns_rr_list_rr(addr, i));
		fprintf(stdout, "\n");

		p = ldns_resolver_query(res, version, LDNS_RR_TYPE_TXT,
				LDNS_RR_CLASS_CH, LDNS_RD);
		if (p) {
			ldns_pkt_print(stdout, p);
			info = ldns_pkt_rr_list_by_type(p,
					LDNS_RR_TYPE_TXT, LDNS_SECTION_ANSWER);

			if (info) {
				ldns_rr_list_print(stdout, info);
				ldns_rr_list_deep_free(info);
			} else {
				printf(" *** version retrieval failed\n");
			}
			ldns_pkt_free(p);
		} else {
			printf(" *** query failed\n");
		}

		p = ldns_resolver_query(res, id, LDNS_RR_TYPE_TXT,
				LDNS_RR_CLASS_CH, LDNS_RD);
		if (p) {
			info = ldns_pkt_rr_list_by_type(p,
					LDNS_RR_TYPE_TXT, LDNS_SECTION_ANSWER);
			if (info) {
				ldns_rr_list_print(stdout, info);
				ldns_rr_list_deep_free(info);
			} else {
				printf(" *** id retrieval failed\n");
			}
			ldns_pkt_free(p);
		} else {
			printf(" *** query failed for\n");
		}
		ldns_rdf_deep_free(ldns_resolver_pop_nameserver(res));

	}
	
	ldns_rdf_deep_free(name);
	ldns_resolver_deep_free(res);
	exit(EXIT_SUCCESS);
}
コード例 #10
0
static bool 
retract_dnskey_by_id(int sockfd,
					const char *ds_retract_command,
					const char *id,
					::ods::keystate::keyrole role,
					const char *zone,
					int algorithm)
{
    /* Code to output the DNSKEY record  (stolen from hsmutil) */
    hsm_ctx_t *hsm_ctx = hsm_create_context();
    if (!hsm_ctx) {
		ods_log_error_and_printf(sockfd,
								 module_str,
								 "could not connect to HSM");
        return false;
    }
    hsm_key_t *key = hsm_find_key_by_id(hsm_ctx, id);
    
    if (!key) {
        ods_log_error_and_printf(sockfd,
								 module_str,
								 "key %s not found in any HSM",
								 id);
        hsm_destroy_context(hsm_ctx);
        return false;
    }
    
    bool bOK = false;
    char *dnskey_rr_str;
	
    hsm_sign_params_t *sign_params = hsm_sign_params_new();
    sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone);
    sign_params->algorithm = (ldns_algorithm)algorithm;
    sign_params->flags = LDNS_KEY_ZONE_KEY;
    sign_params->flags += LDNS_KEY_SEP_KEY; /*KSK=>SEP*/
    
    ldns_rr *dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params);
#if 0
    ldns_rr_print(stdout, dnskey_rr);
#endif        
    dnskey_rr_str = ldns_rr2str(dnskey_rr);
    
    hsm_sign_params_free(sign_params);
    ldns_rr_free(dnskey_rr);
    hsm_key_free(key);
	
    /* Replace tab with white-space */
    for (int i = 0; dnskey_rr_str[i]; ++i) {
        if (dnskey_rr_str[i] == '\t') {
            dnskey_rr_str[i] = ' ';
        }
    }
    
    /* We need to strip off trailing comments before we send
     to any clients that might be listening */
    for (int i = 0; dnskey_rr_str[i]; ++i) {
        if (dnskey_rr_str[i] == ';') {
            dnskey_rr_str[i] = '\n';
            dnskey_rr_str[i+1] = '\0';
            break;
        }
    }

    // pass the dnskey rr string to a configured
    // delegation signer retract program.
    if (ds_retract_command && ds_retract_command[0] != '\0') {
        /* send records to the configured command */
        FILE *fp = popen(ds_retract_command, "w");
        if (fp == NULL) {
            ods_log_error_and_printf(sockfd,
									 module_str,
									 "failed to run command: %s: %s",
									 ds_retract_command,
									 strerror(errno));
        } else {
            int bytes_written = fprintf(fp, "%s", dnskey_rr_str);
            if (bytes_written < 0) {
                ods_log_error_and_printf(sockfd,
										 module_str,
										 "[%s] Failed to write to %s: %s",
										 ds_retract_command,
										 strerror(errno));
            } else {
				
                if (pclose(fp) == -1) {
                    ods_log_error_and_printf(sockfd,
											 module_str,
											 "failed to close %s: %s",
											 ds_retract_command,
											 strerror(errno));
                } else {
                    bOK = true;
                    ods_printf(sockfd,
							   "key %s retracted by %s\n",
							   id,
							   ds_retract_command);
                }
            }
        }
    } else {
        ods_log_error_and_printf(sockfd,
								 module_str,
								 "no \"DelegationSignerRetractCommand\" binary "
								 "configured in conf.xml.");
    }
	
    LDNS_FREE(dnskey_rr_str);
    hsm_destroy_context(hsm_ctx);
    return bOK;
}
コード例 #11
0
static uint16_t 
dnskey_from_id(std::string &dnskey,
               const char *id,
               ::ods::keystate::keyrole role,
               const char *zone,
               int algorithm,
               int bDS,
               uint32_t ttl)
{
    hsm_key_t *key;
    hsm_sign_params_t *sign_params;
    ldns_rr *dnskey_rr;
    ldns_algorithm algo = (ldns_algorithm)algorithm;
    
    /* Code to output the DNSKEY record  (stolen from hsmutil) */
    hsm_ctx_t *hsm_ctx = hsm_create_context();
    if (!hsm_ctx) {
        ods_log_error("[%s] Could not connect to HSM", module_str);
        return false;
    }
    key = hsm_find_key_by_id(hsm_ctx, id);
    
    if (!key) {
        // printf("Key %s in DB but not repository\n", id);
        hsm_destroy_context(hsm_ctx);
        return 0;
    }
    
    /*
     * Sign params only need to be kept around 
     * for the hsm_get_dnskey() call.
     */
    sign_params = hsm_sign_params_new();
    sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone);
    sign_params->algorithm = algo;
    sign_params->flags = LDNS_KEY_ZONE_KEY;
    if (role == ::ods::keystate::KSK)
        sign_params->flags += LDNS_KEY_SEP_KEY; /*KSK=>SEP*/
    /* Get the DNSKEY record */
    dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params);
    hsm_sign_params_free(sign_params);
    /* Calculate the keytag for this key, we return it. */
    uint16_t keytag = ldns_calc_keytag(dnskey_rr);
    /* Override the TTL in the dnskey rr */
    if (ttl)
        ldns_rr_set_ttl(dnskey_rr, ttl);
    
    char *rrstr;
    if (!bDS) {
#if 0
        ldns_rr_print(stdout, dnskey_rr);
#endif
        rrstr = ldns_rr2str(dnskey_rr);
        dnskey = rrstr;
        LDNS_FREE(rrstr);
    } else {
    
        switch (algo) {
            case LDNS_RSASHA1: // 5
            {
                /* DS record (SHA1) */
                ldns_rr *ds_sha1_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA1);
#if 0
                ldns_rr_print(stdout, ds_sha1_rr);
#endif
                rrstr = ldns_rr2str(ds_sha1_rr);
                dnskey = rrstr;
                LDNS_FREE(rrstr);

                ldns_rr_free(ds_sha1_rr);
                break;
            }
            case LDNS_RSASHA256: // 8 - RFC 5702
            {
        
                /* DS record (SHA256) */
                ldns_rr *ds_sha256_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA256);
#if 0
                ldns_rr_print(stdout, ds_sha256_rr);
#endif
                rrstr = ldns_rr2str(ds_sha256_rr);
                dnskey = rrstr;
                LDNS_FREE(rrstr);

                ldns_rr_free(ds_sha256_rr);
                break;
            }
            default:
                keytag = 0;
        }
    }
    ldns_rr_free(dnskey_rr);
    hsm_key_free(key);
    hsm_destroy_context(hsm_ctx);
    
    return keytag;
}
コード例 #12
0
ファイル: nsd-ldnsd.c プロジェクト: benlaurie/ldns
int
main(int argc, char **argv)
{
	/* arguments */
	int port;
	int soa;
	ldns_rdf *zone_name;
	size_t count;
	size_t maxcount;

	/* network */
	int sock;
	ssize_t nb;
	struct sockaddr addr_me;
	struct sockaddr addr_him;
	socklen_t hislen = sizeof(addr_him);
	const char *my_address;
	uint8_t inbuf[INBUF_SIZE];
	uint8_t *outbuf;

	/* dns */
	ldns_status status;
	ldns_pkt *query_pkt;
	ldns_pkt *answer_pkt;
	size_t answer_size;
	ldns_rr *query_rr;
	ldns_rr *rr;
	char rr_string[MAX_LEN + 1];
	ldns_rr *soa_rr;
	char soa_string[MAX_LEN + 1];
	
	/* use this to listen on specified interfaces later? */
	my_address = NULL;

	if(argc == 5) {
		/* -# num given */
		if (argv[1][0] == '-') {
			maxcount = atoi(argv[1] + 1);
			if (maxcount == 0) {
				usage(stdout);
				exit(EXIT_FAILURE);
			} else {
				fprintf(stderr, "quiting after %d qs\n", (int)maxcount);
			}
		} else {
			fprintf(stderr, "Use -Number for max count\n");
			exit(EXIT_FAILURE);
		}
		argc--;
		argv++;
	} else {
		maxcount = 0;
	}
	
	if (argc != 4) {
		usage(stdout);
		exit(EXIT_FAILURE);
	} else {
		port = atoi(argv[1]);
		if (port < 1) {
			fprintf(stderr, "Use a number for the port\n");
			usage(stdout);
			exit(EXIT_FAILURE);
		}
		
		zone_name = ldns_dname_new_frm_str(argv[2]);
		if (!zone_name) {
			fprintf(stderr, "Illegal domain name: %s\n", argv[2]);
			usage(stdout);
			exit(EXIT_FAILURE);
		}
		soa =  atoi(argv[3]);
		if (soa < 1) {
			fprintf(stderr, "Illegal soa number\n");
			usage(stdout);
			exit(EXIT_FAILURE);
		}
			
	}
	
	printf("Listening on port %d\n", port);
	sock =  socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0) {
		fprintf(stderr, "%s: socket(): %s\n", argv[0], strerror(errno));
		exit(EXIT_FAILURE);
	}

	memset(&addr_me, 0, sizeof(addr_me));

	/* bind: try all ports in that range */
	if (udp_bind(sock, port, my_address)) {
		fprintf(stderr, "%s: cannot bind(): %s\n", argv[0], strerror(errno));
	}

	/* create our ixfr answer */
	answer_pkt = ldns_pkt_new();

	snprintf(rr_string, MAX_LEN, "%s IN IXFR", argv[2]);
	(void)ldns_rr_new_frm_str(&rr, rr_string , 0, NULL, NULL);
	(void)ldns_pkt_push_rr(answer_pkt, LDNS_SECTION_QUESTION, rr);

	 /* next add some rrs, with SOA stuff so that we mimic or ixfr reply */
	snprintf(soa_string, MAX_LEN, "%s IN SOA miek.miek.nl elektron.atoom.net %d 1 2 3000 4",
			argv[2], soa);

        (void)ldns_rr_new_frm_str(&soa_rr, soa_string, 0, NULL, NULL);
	snprintf(rr_string, MAX_LEN, "%s IN A 127.0.0.1", argv[2]);
        (void)ldns_rr_new_frm_str(&rr, rr_string , 0, NULL, NULL);

        /* compose the ixfr pkt */
        (void)ldns_pkt_push_rr(answer_pkt, LDNS_SECTION_ANSWER, soa_rr);
        (void)ldns_pkt_push_rr(answer_pkt, LDNS_SECTION_ANSWER, rr);
        (void)ldns_pkt_push_rr(answer_pkt, LDNS_SECTION_ANSWER, soa_rr);

	/* Done. Now receive */
	count = 0;
	while (1) {
		nb = recvfrom(sock, inbuf, INBUF_SIZE, 0, &addr_him, &hislen);
		if (nb < 1) {
			fprintf(stderr, "%s: recvfrom(): %s\n",
				argv[0], strerror(errno));
			exit(EXIT_FAILURE);
		}
		
		printf("Got query of %d bytes\n", (int)nb);
		status = ldns_wire2pkt(&query_pkt, inbuf, nb);
		if (status != LDNS_STATUS_OK) {
			printf("Got bad packet: %s\n", ldns_get_errorstr_by_id(status));
			continue;
		}
		
		query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0);
		printf("%d QUERY RR +%d: \n", (int)++count, ldns_pkt_id(query_pkt));
		ldns_rr_print(stdout, query_rr);
		
		ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt));

		status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
		
		printf("Answer packet size: %u bytes.\n", (unsigned int) answer_size);
		if (status != LDNS_STATUS_OK) {
			printf("Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
		} else {
			nb = (size_t) sendto(sock, outbuf, answer_size, 0, &addr_him, hislen);
		}

		if (maxcount > 0  && count >= maxcount) {
			fprintf(stderr, "%d queries seen... goodbye\n", (int)count);
			exit(EXIT_SUCCESS);
		}
	}
        return 0;
}
コード例 #13
0
int
main(int argc, char *argv[])
{
	ldns_resolver *res;
	ldns_rdf *ns;
	ldns_rdf *domain;
	ldns_rr_list *l = NULL;

	ldns_rr_list *dns_root = NULL;
	const char *root_file = "/etc/named.root";

	ldns_status status;
	
	int i;

	char *domain_str;
	char *outputfile_str;
	ldns_buffer *outputfile_buffer;
	FILE *outputfile;
	ldns_rr *k;
	
	bool insecure = false;
	ldns_pkt *pkt;

	domain = NULL;
	res = NULL;

	if (argc < 2) {
		usage(stdout, argv[0]);
		exit(EXIT_FAILURE);
	} else {
		for (i = 1; i < argc; i++) {
			if (strncmp("-4", argv[i], 3) == 0) {
				if (address_family != 0) {
					fprintf(stderr, "Options -4 and -6 cannot be specified at the same time\n");
					exit(EXIT_FAILURE);
				}
				address_family = 1;
			} else if (strncmp("-6", argv[i], 3) == 0) {
				if (address_family != 0) {
					fprintf(stderr, "Options -4 and -6 cannot be specified at the same time\n");
					exit(EXIT_FAILURE);
				}
				address_family = 2;
			} else if (strncmp("-h", argv[i], 3) == 0) {
				usage(stdout, argv[0]);
				exit(EXIT_SUCCESS);
			} else if (strncmp("-i", argv[i], 2) == 0) {
				insecure = true;
			} else if (strncmp("-r", argv[i], 2) == 0) {
				if (strlen(argv[i]) > 2) {
					root_file = argv[i]+2;
				} else if (i+1 >= argc) {
					usage(stdout, argv[0]);
					exit(EXIT_FAILURE);
				} else {
					root_file = argv[i+1];
					i++;
				}
			} else if (strncmp("-s", argv[i], 3) == 0) {
				store_in_file = true;
			} else if (strncmp("-v", argv[i], 2) == 0) {
				if (strlen(argv[i]) > 2) {
					verbosity = atoi(argv[i]+2);
				} else if (i+1 > argc) {
					usage(stdout, argv[0]);
					exit(EXIT_FAILURE);
				} else {
					verbosity = atoi(argv[i+1]);
					i++;
				}
			} else {
				/* create a rdf from the command line arg */
				if (domain) {
					fprintf(stdout, "You can only specify one domain at a time\n");
					exit(EXIT_FAILURE);
				}

				domain = ldns_dname_new_frm_str(argv[i]);
			}

		}
		if (!domain) {
			usage(stdout, argv[0]);
			exit(EXIT_FAILURE);
		}
	}

	dns_root = read_root_hints(root_file);
	if (!dns_root) {
		fprintf(stderr, "cannot read the root hints file\n");
		exit(EXIT_FAILURE);
	}

	/* create a new resolver from /etc/resolv.conf */
	status = ldns_resolver_new_frm_file(&res, NULL);

	if (status != LDNS_STATUS_OK) {
		fprintf(stderr, "Warning: Unable to create stub resolver from /etc/resolv.conf:\n");
		fprintf(stderr, "%s\n", ldns_get_errorstr_by_id(status));
		fprintf(stderr, "defaulting to nameserver at 127.0.0.1 for separate nameserver name lookups\n");
		res = ldns_resolver_new();
		ns = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, "127.0.0.1");
		status = ldns_resolver_push_nameserver(res, ns);
		if (status != LDNS_STATUS_OK) {
			fprintf(stderr, "Unable to create stub resolver: %s\n", ldns_get_errorstr_by_id(status));
			exit(EXIT_FAILURE);
		}
		ldns_rdf_deep_free(ns);
	}

	ldns_resolver_set_ip6(res, address_family);

	if (insecure) {
		pkt = ldns_resolver_query(res, domain, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
		if (pkt) {
		l = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_DNSKEY, LDNS_SECTION_ANY_NOQUESTION);
		}
	} else {
		l = retrieve_dnskeys(res, domain, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, dns_root);
	}
	
	/* separator for result data and verbosity data */
	if (verbosity > 0) {
		fprintf(stdout, "; ---------------------------\n");
		fprintf(stdout, "; Got the following keys:\n");
	}
	if (l) {
		if (store_in_file) {
			/* create filename:
			 * K<domain>.+<alg>.+<id>.key
			 */
			for (i = 0; (size_t) i < ldns_rr_list_rr_count(l); i++) {
				k = ldns_rr_list_rr(l, (size_t) i);
				
				outputfile_buffer = ldns_buffer_new(300);
				domain_str = ldns_rdf2str(ldns_rr_owner(k));
				ldns_buffer_printf(outputfile_buffer, "K%s+%03u+%05u.key", domain_str, ldns_rdf2native_int8(ldns_rr_rdf(k, 2)),
					(unsigned int) ldns_calc_keytag(k));
				outputfile_str = ldns_buffer_export(outputfile_buffer);
				
				if (verbosity >= 1) {
					fprintf(stdout, "Writing key to file %s\n", outputfile_str);
				}
				
				outputfile = fopen(outputfile_str, "w");
				if (!outputfile) {
					fprintf(stderr, "Error writing key to file %s: %s\n", outputfile_str, strerror(errno));
				} else {
					ldns_rr_print(outputfile, k);
					fclose(outputfile);
				}
				
				LDNS_FREE(domain_str);
				LDNS_FREE(outputfile_str);
				LDNS_FREE(outputfile_buffer);
			}
		} else {
			ldns_rr_list_print(stdout, l);
		}
	} else {
		fprintf(stderr, "no answer packet received, stub resolver config:\n");
		ldns_resolver_print(stderr, res);
	}
	printf("\n");

	ldns_rdf_deep_free(domain);
	ldns_resolver_deep_free(res);
	ldns_rr_list_deep_free(l);
	ldns_rr_list_deep_free(dns_root);
	return EXIT_SUCCESS;
}
コード例 #14
0
ファイル: dnssec_zone.c プロジェクト: Der-Jan/freebsd-crypto
ldns_status
ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
{
	ldns_status result = LDNS_STATUS_OK;
	ldns_dnssec_name *cur_name;
	ldns_rbnode_t *cur_node;
	ldns_rr_type type_covered = 0;

	if (!zone || !rr) {
		return LDNS_STATUS_ERR;
	}

	if (!zone->names) {
		zone->names = ldns_rbtree_create(ldns_dname_compare_v);
                if(!zone->names) return LDNS_STATUS_MEM_ERR;
	}

	/* we need the original of the hashed name if this is
	   an NSEC3, or an RRSIG that covers an NSEC3 */
	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
		type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
	}
	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
	    type_covered == LDNS_RR_TYPE_NSEC3) {
		cur_node = ldns_dnssec_zone_find_nsec3_original(zone,
					 						   rr);
		if (!cur_node) {
			return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND;
		}
	} else {
		cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
	}

	if (!cur_node) {
		/* add */
		cur_name = ldns_dnssec_name_new_frm_rr(rr);
                if(!cur_name) return LDNS_STATUS_MEM_ERR;
		cur_node = LDNS_MALLOC(ldns_rbnode_t);
                if(!cur_node) {
                        ldns_dnssec_name_free(cur_name);
                        return LDNS_STATUS_MEM_ERR;
                }
		cur_node->key = ldns_rr_owner(rr);
		cur_node->data = cur_name;
		(void)ldns_rbtree_insert(zone->names, cur_node);
	} else {
		cur_name = (ldns_dnssec_name *) cur_node->data;
		result = ldns_dnssec_name_add_rr(cur_name, rr);
	}

	if (result != LDNS_STATUS_OK) {
		fprintf(stderr, "error adding rr: ");
		ldns_rr_print(stderr, rr);
	}

	/*TODO ldns_dnssec_name_print_names(stdout, zone->names, 0);*/
	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
		zone->soa = cur_name;
	}

	return result;
}
コード例 #15
0
int
main(int argc, char *argv[])
{
	FILE *keyfp;
	char *keyname;
	ldns_rr *k;
	uint16_t flags;
	char *program = argv[0];
	int nofile = 0;
	ldns_rdf *origin = NULL;
	ldns_status result;

	argv++, argc--;
	while (argc && argv[0][0] == '-') {
		if (strcmp(argv[0], "-n") == 0) {
			nofile=1;
		}
		else {
			usage(stderr, program);
			exit(EXIT_FAILURE);
		}
		argv++, argc--;
	}

	if (argc != 1) {
		usage(stderr, program);
		exit(EXIT_FAILURE);
	}
	keyname = strdup(argv[0]);

	keyfp = fopen(keyname, "r");
	if (!keyfp) {
		fprintf(stderr, "Failed to open public key file %s: %s\n", keyname,
				strerror(errno));
		exit(EXIT_FAILURE);
	}

	result = ldns_rr_new_frm_fp(&k, keyfp, 0, &origin, NULL);
	/* what does this while loop do? */
	while (result == LDNS_STATUS_SYNTAX_ORIGIN) {
		result = ldns_rr_new_frm_fp(&k, keyfp, 0, &origin, NULL);
	}
	if (result != LDNS_STATUS_OK) {
		fprintf(stderr, "Could not read public key from file %s: %s\n", keyname, ldns_get_errorstr_by_id(result));
		exit(EXIT_FAILURE);
	}
	fclose(keyfp);

	flags = ldns_read_uint16(ldns_rdf_data(ldns_rr_dnskey_flags(k)));
	flags |= LDNS_KEY_REVOKE_KEY;

	if (!ldns_rr_dnskey_set_flags(k,
		ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, flags)))
	{
		fprintf(stderr, "Revocation failed\n");
		exit(EXIT_FAILURE);
	}

	/* print the public key RR to .key */

	if (nofile)
		ldns_rr_print(stdout,k);
	else {
		keyfp = fopen(keyname, "w");
		if (!keyfp) {
			fprintf(stderr, "Unable to open %s: %s\n", keyname,
				strerror(errno));
			exit(EXIT_FAILURE);
		} else {
			ldns_rr_print(keyfp, k);
			fclose(keyfp);
			fprintf(stdout, "DNSKEY revoked\n");
		}
	}

	free(keyname);
	ldns_rr_free(k);

        exit(EXIT_SUCCESS);
}
コード例 #16
0
ファイル: hsmutil.c プロジェクト: opendnssec/opendnssec-svn
int
cmd_dnskey (int argc, char *argv[])
{
    char *id;
    char *name;
    int type;
    int algo;

    hsm_key_t *key = NULL;
    ldns_rr *dnskey_rr;
    hsm_sign_params_t *sign_params;

    if (argc != 4) {
        usage();
        return -1;
    }

    id = strdup(argv[0]);
    name = strdup(argv[1]);
    type = atoi(argv[2]);
    algo = atoi(argv[3]);

    key = hsm_find_key_by_id(NULL, id);

    if (!key) {
        printf("Key not found: %s\n", id);
        free(name);
        free(id);
        return -1;
    }

    if (type != LDNS_KEY_ZONE_KEY && type != LDNS_KEY_ZONE_KEY + LDNS_KEY_SEP_KEY) {
        printf("Invalid key type: %i\n", type);
        printf("Please use: %i or %i\n", LDNS_KEY_ZONE_KEY, LDNS_KEY_ZONE_KEY + LDNS_KEY_SEP_KEY);
        free(name);
        free(id);
        return -1;
    }

    hsm_key_info_t *key_info = hsm_get_key_info(NULL, key);
    switch (algo) {
        case LDNS_SIGN_RSAMD5:
        case LDNS_SIGN_RSASHA1:
        case LDNS_SIGN_RSASHA1_NSEC3:
        case LDNS_SIGN_RSASHA256:
        case LDNS_SIGN_RSASHA512:
            if (strcmp(key_info->algorithm_name, "RSA") != 0) {
                printf("Not an RSA key, the key is of algorithm %s.\n", key_info->algorithm_name);
                hsm_key_info_free(key_info);
                free(name);
                free(id);
                return -1;
            }
            break;
        case LDNS_SIGN_DSA:
        case LDNS_SIGN_DSA_NSEC3:
            if (strcmp(key_info->algorithm_name, "DSA") != 0) {
                printf("Not a DSA key, the key is of algorithm %s.\n", key_info->algorithm_name);
                hsm_key_info_free(key_info);
                free(name);
                free(id);
                return -1;
            }
            break;
        case LDNS_SIGN_ECC_GOST:
            if (strcmp(key_info->algorithm_name, "GOST") != 0) {
                printf("Not a GOST key, the key is of algorithm %s.\n", key_info->algorithm_name);
                hsm_key_info_free(key_info);
                free(name);
                free(id);
                return -1;
            }
            break;
/* TODO: We can remove the directive if we require LDNS >= 1.6.13 */
#if !defined LDNS_BUILD_CONFIG_USE_ECDSA || LDNS_BUILD_CONFIG_USE_ECDSA
        case LDNS_SIGN_ECDSAP256SHA256:
            if (strcmp(key_info->algorithm_name, "ECDSA") != 0) {
                printf("Not an ECDSA key, the key is of algorithm %s.\n", key_info->algorithm_name);
                hsm_key_info_free(key_info);
                free(name);
                free(id);
                return -1;
            }
            if (key_info->keysize != 256) {
                printf("The key is a ECDSA/%lu, expecting ECDSA/256 for this algorithm.\n", key_info->keysize);
                hsm_key_info_free(key_info);
                free(name);
                free(id);
                return -1;
            }
            break;
        case LDNS_SIGN_ECDSAP384SHA384:
            if (strcmp(key_info->algorithm_name, "ECDSA") != 0) {
                printf("Not an ECDSA key, the key is of algorithm %s.\n", key_info->algorithm_name);
                hsm_key_info_free(key_info);
                free(name);
                free(id);
                return -1;
            }
            if (key_info->keysize != 384) {
                printf("The key is a ECDSA/%lu, expecting ECDSA/384 for this algorithm.\n", key_info->keysize);
                hsm_key_info_free(key_info);
                free(name);
                free(id);
                return -1;
            }
            break;
#endif
        default:
            printf("Invalid algorithm: %i\n", algo);
            hsm_key_info_free(key_info);
            free(name);
            free(id);
            return -1;
    }
    hsm_key_info_free(key_info);

    sign_params = hsm_sign_params_new();
    sign_params->algorithm = algo;
    sign_params->flags = type;
    sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, name);
    dnskey_rr = hsm_get_dnskey(NULL, key, sign_params);
    sign_params->keytag = ldns_calc_keytag(dnskey_rr);

    ldns_rr_print(stdout, dnskey_rr);

    hsm_sign_params_free(sign_params);
    ldns_rr_free(dnskey_rr);
    hsm_key_free(key);
    free(name);
    free(id);

    return 0;
}
コード例 #17
0
int 
main(int argc, char **argv)
{
	char           *fn1, *fn2;
	FILE           *fp1, *fp2;
	ldns_zone      *z1, *z2;
	ldns_status	s;
	size_t		i      , j;
	ldns_rr_list   *rrl1, *rrl2;
	int		rr_cmp, rr_chg = 0;
	ldns_rr        *rr1 = NULL, *rr2 = NULL, *rrx = NULL;
	int		line_nr1 = 0, line_nr2 = 0;
	size_t		rrc1   , rrc2;
	size_t		num_ins = 0, num_del = 0, num_chg = 0;
	int		c;
	bool		opt_deleted = false, opt_inserted = false, opt_changed = false;
        bool		sort = true, inc_soa = false;
	char		op = 0;

	while ((c = getopt(argc, argv, "ahvdicsz")) != -1) {
		switch (c) {
		case 'h':
			usage(argc, argv);
			exit(EXIT_SUCCESS);
			break;
		case 'v':
			printf("%s version %s (ldns version %s)\n",
				  argv[0],
				  LDNS_VERSION,
				  ldns_version());
			exit(EXIT_SUCCESS);
			break;
		case 's':
			inc_soa = true;
			break;
		case 'z':
			sort = false;
                        break;
		case 'd':
			opt_deleted = true;
			break;
		case 'i':
			opt_inserted = true;
			break;
		case 'c':
			opt_changed = true;
			break;
		case 'a':
			opt_deleted = true;
			opt_inserted = true;
			opt_changed = true;
			break;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 2) {
		argc -= optind;
		argv -= optind;
		usage(argc, argv);
		exit(EXIT_FAILURE);
	}
	fn1 = argv[0];
	fp1 = fopen(fn1, "r");
	if (!fp1) {
		fprintf(stderr, "Unable to open %s: %s\n", fn1, strerror(errno));
		exit(EXIT_FAILURE);
	}
	/* Read first zone */
	s = ldns_zone_new_frm_fp_l(&z1, fp1, NULL, 0, 
						  LDNS_RR_CLASS_IN, &line_nr1);
	if (s != LDNS_STATUS_OK) {
		fclose(fp1);
		fprintf(stderr, "%s: %s at %d\n",
			   fn1,
			   ldns_get_errorstr_by_id(s),
			   line_nr1);
		exit(EXIT_FAILURE);
	}
	fclose(fp1);

	fn2 = argv[1];
	fp2 = fopen(fn2, "r");
	if (!fp2) {
		fprintf(stderr, "Unable to open %s: %s\n", fn2, strerror(errno));
		exit(EXIT_FAILURE);
	}
	/* Read second zone */
	s = ldns_zone_new_frm_fp_l(&z2, fp2, NULL, 0,
						  LDNS_RR_CLASS_IN, &line_nr2);
	if (s != LDNS_STATUS_OK) {
		ldns_zone_deep_free(z1);
		fclose(fp2);
		fprintf(stderr, "%s: %s at %d\n",
			   fn2,
			   ldns_get_errorstr_by_id(s),
			   line_nr2);
		exit(EXIT_FAILURE);
	}
	fclose(fp2);

	rrl1 = ldns_zone_rrs(z1);
	rrc1 = ldns_rr_list_rr_count(rrl1);

	rrl2 = ldns_zone_rrs(z2);
	rrc2 = ldns_rr_list_rr_count(rrl2);

        if (sort) {
		/* canonicalize zone 1 */
		ldns_rr2canonical(ldns_zone_soa(z1));
                for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(z1)); i++) {
                	ldns_rr2canonical(ldns_rr_list_rr(ldns_zone_rrs(z1), i));
		}
                /* sort zone 1 */
                ldns_zone_sort(z1);
		/* canonicalize zone 2 */
		ldns_rr2canonical(ldns_zone_soa(z2));
                for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(z2)); i++) {
                	ldns_rr2canonical(ldns_rr_list_rr(ldns_zone_rrs(z2), i));
		}
                /* sort zone 2 */
                ldns_zone_sort(z2);
        }

	if(inc_soa) {
		ldns_rr_list* wsoa = ldns_rr_list_new();
		ldns_rr_list_push_rr(wsoa, ldns_zone_soa(z1));
		ldns_rr_list_cat(wsoa, rrl1);
		rrl1 = wsoa;
		rrc1 = ldns_rr_list_rr_count(rrl1);
		wsoa = ldns_rr_list_new();
		ldns_rr_list_push_rr(wsoa, ldns_zone_soa(z2));
		ldns_rr_list_cat(wsoa, rrl2);
		rrl2 = wsoa;
		rrc2 = ldns_rr_list_rr_count(rrl2);
		if(sort) {
			ldns_rr_list_sort(rrl1);
			ldns_rr_list_sort(rrl2);
		}
	}

	/*
	 * Walk through both zones. The previously seen resource record is
	 * kept (in the variable rrx) so that we can recognize when we are
	 * handling a new owner name. If the owner name changes, we have to
	 * set the operator again.
	 */
	for (i = 0, j = 0; i < rrc1 || j < rrc2;) {
		rr_cmp = 0;
		if (i < rrc1 && j < rrc2) {
			rr1 = ldns_rr_list_rr(rrl1, i);
			rr2 = ldns_rr_list_rr(rrl2, j);
			rr_cmp = ldns_rr_compare(rr1, rr2);

			/* Completely skip if the rrs are equal */
			if (rr_cmp == 0) {
				i++;
				j++;
				continue;
			}
			rr_chg = ldns_dname_compare(ldns_rr_owner(rr1),
								   ldns_rr_owner(rr2));
		} else if (i >= rrc1) {
			/* we have reached the end of zone 1, so the current record
			 * from zone 2 automatically sorts higher
			 */
			rr1 = NULL;
			rr2 = ldns_rr_list_rr(rrl2, j);
			rr_chg = rr_cmp = 1;
		} else if (j >= rrc2) {
			/* we have reached the end of zone 2, so the current record
			 * from zone 1 automatically sorts lower
			 */
			rr1 = ldns_rr_list_rr(rrl1, i);
			rr2 = NULL;
			rr_chg = rr_cmp = -1;
		}
		if (rr_cmp < 0) {
			i++;
			if ((rrx != NULL) && (ldns_dname_compare(ldns_rr_owner(rr1), 
											 ldns_rr_owner(rrx)
											 ) != 0)) {
				/* The owner name is different, forget previous rr */
				rrx = NULL;
			}
			if (rrx == NULL) {
				if (rr_chg == 0) {
					num_chg++;
					op = OP_CHG;
				} else {
					num_del++;
					op = OP_DEL;
				}
				rrx = rr1;
			}
			if (((op == OP_DEL) && opt_deleted) ||
			    ((op == OP_CHG) && opt_changed)) {
				printf("%c-", op);
				ldns_rr_print(stdout, rr1);
			}
		} else if (rr_cmp > 0) {
			j++;
			if ((rrx != NULL) && (ldns_dname_compare(ldns_rr_owner(rr2),
											 ldns_rr_owner(rrx)
											 ) != 0)) {
				rrx = NULL;
			}
			if (rrx == NULL) {
				if (rr_chg == 0) {
					num_chg++;
					op = OP_CHG;
				} else {
					num_ins++;
					op = OP_INS;
				}
				/* remember this rr for it's name in the next iteration */
				rrx = rr2;
			}
			if (((op == OP_INS) && opt_inserted) ||
			    ((op == OP_CHG) && opt_changed)) {
				printf("%c+", op);
				ldns_rr_print(stdout, rr2);
			}
		}
	}

	printf("\t%c%u\t%c%u\t%c%u\n", 
		  OP_INS, 
		  (unsigned int) num_ins, 
		  OP_DEL,
		  (unsigned int) num_del, 
		  OP_CHG, 
		  (unsigned int) num_chg);

	/* Free resources */
	if(inc_soa) {
		ldns_rr_list_free(rrl1);
		ldns_rr_list_free(rrl2);
	}
	ldns_zone_deep_free(z2);
	ldns_zone_deep_free(z1);

	return 0;
}
コード例 #18
0
int
main(int argc, char **argv)
{
	char *filename;
	FILE *fp;
	ldns_zone *z;
	int line_nr = 0;
	int c;
	bool canonicalize = false;
	bool sort = false;
	bool strip = false;
	bool only_dnssec = false;
	bool print_soa = true;
	ldns_status s;
	size_t i;
	ldns_rr_list *stripped_list;
	ldns_rr *cur_rr;
	ldns_rr_type cur_rr_type;

        while ((c = getopt(argc, argv, "cdhnsvz")) != -1) {
                switch(c) {
                	case 'c':
                		canonicalize = true;
                		break;
                	case 'd':
                		only_dnssec = true;
                		if (strip) {
                			fprintf(stderr, "Warning: stripping both DNSSEC and non-DNSSEC records. Output will be sparse.\n");
				}
				break;
			case 'h':
				printf("Usage: %s [-c] [-v] [-z] <zonefile>\n", argv[0]);
				printf("\tReads the zonefile and prints it.\n");
				printf("\tThe RR count of the zone is printed to stderr.\n");
				printf("\t-c canonicalize all rrs in the zone.\n");
				printf("\t-d only show DNSSEC data from the zone\n");
				printf("\t-h show this text\n");
				printf("\t-n do not print the SOA record\n");
				printf("\t-s strip DNSSEC data from the zone\n");
				printf("\t-v shows the version and exits\n");
				printf("\t-z sort the zone (implies -c).\n");
				printf("\nif no file is given standard input is read\n");
				exit(EXIT_SUCCESS);
				break;
			case 'n':
				print_soa = false;
				break;
                        case 's':
                        	strip = true;
                		if (only_dnssec) {
                			fprintf(stderr, "Warning: stripping both DNSSEC and non-DNSSEC records. Output will be sparse.\n");
				}
                        	break;
			case 'v':
				printf("read zone version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
				exit(EXIT_SUCCESS);
				break;
                        case 'z':
                		canonicalize = true;
                                sort = true;
                                break;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 0) {
		fp = stdin;
	} else {
		filename = argv[0];

		fp = fopen(filename, "r");
		if (!fp) {
			fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}
	
	s = ldns_zone_new_frm_fp_l(&z, fp, NULL, 0, LDNS_RR_CLASS_IN, &line_nr);

	if (strip) {
		stripped_list = ldns_rr_list_new();
		while ((cur_rr = ldns_rr_list_pop_rr(ldns_zone_rrs(z)))) {
			cur_rr_type = ldns_rr_get_type(cur_rr);
			if (cur_rr_type == LDNS_RR_TYPE_RRSIG ||
			    cur_rr_type == LDNS_RR_TYPE_NSEC ||
			    cur_rr_type == LDNS_RR_TYPE_NSEC3 ||
			    cur_rr_type == LDNS_RR_TYPE_NSEC3PARAMS
			   ) {
				ldns_rr_free(cur_rr);
			} else {
				ldns_rr_list_push_rr(stripped_list, cur_rr);
			}
		}
		ldns_rr_list_free(ldns_zone_rrs(z));
		ldns_zone_set_rrs(z, stripped_list);
	}
	if (only_dnssec) {
		stripped_list = ldns_rr_list_new();
		while ((cur_rr = ldns_rr_list_pop_rr(ldns_zone_rrs(z)))) {
			cur_rr_type = ldns_rr_get_type(cur_rr);
			if (cur_rr_type == LDNS_RR_TYPE_RRSIG ||
			    cur_rr_type == LDNS_RR_TYPE_NSEC ||
			    cur_rr_type == LDNS_RR_TYPE_NSEC3 ||
			    cur_rr_type == LDNS_RR_TYPE_NSEC3PARAMS
			   ) {
				ldns_rr_list_push_rr(stripped_list, cur_rr);
			} else {
				ldns_rr_free(cur_rr);
			}
		}
		ldns_rr_list_free(ldns_zone_rrs(z));
		ldns_zone_set_rrs(z, stripped_list);
	}

	if (s == LDNS_STATUS_OK) {
		if (canonicalize) {
			ldns_rr2canonical(ldns_zone_soa(z));
			for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(z)); i++) {
				ldns_rr2canonical(ldns_rr_list_rr(ldns_zone_rrs(z), i));
			}
		}
		if (sort) {
			ldns_zone_sort(z);
		}

		if (print_soa && ldns_zone_soa(z)) {
			ldns_rr_print(stdout, ldns_zone_soa(z));
		}
		ldns_rr_list_print(stdout, ldns_zone_rrs(z));

		ldns_zone_deep_free(z);
	} else {
		fprintf(stderr, "%s at %d\n", 
				ldns_get_errorstr_by_id(s),
				line_nr);
                exit(EXIT_FAILURE);
	}
	fclose(fp);

        exit(EXIT_SUCCESS);
}
コード例 #19
0
static bool 
retract_dnskey_by_id(int sockfd,
					const char *ds_retract_command,
					const char *id,
					::ods::keystate::keyrole role,
					const char *zone,
					int algorithm,
					bool force)
{
	struct stat stat_ret;
	/* Code to output the DNSKEY record  (stolen from hsmutil) */
	hsm_ctx_t *hsm_ctx = hsm_create_context();
	if (!hsm_ctx) {
		ods_log_error_and_printf(sockfd,
								 module_str,
								 "could not connect to HSM");
		return false;
	}
	hsm_key_t *key = hsm_find_key_by_id(hsm_ctx, id);
	
	if (!key) {
		ods_log_error_and_printf(sockfd,
								 module_str,
								 "key %s not found in any HSM",
								 id);
		hsm_destroy_context(hsm_ctx);
		return false;
	}
	
	bool bOK = false;
	char *dnskey_rr_str;
	
	hsm_sign_params_t *sign_params = hsm_sign_params_new();
	sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone);
	sign_params->algorithm = (ldns_algorithm)algorithm;
	sign_params->flags = LDNS_KEY_ZONE_KEY;
	sign_params->flags += LDNS_KEY_SEP_KEY; /*KSK=>SEP*/
	
	ldns_rr *dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params);
#if 0
	ldns_rr_print(stdout, dnskey_rr);
#endif        
	dnskey_rr_str = ldns_rr2str(dnskey_rr);
	
	hsm_sign_params_free(sign_params);
	ldns_rr_free(dnskey_rr);
	hsm_key_free(key);
	
	/* Replace tab with white-space */
	for (int i = 0; dnskey_rr_str[i]; ++i) {
		if (dnskey_rr_str[i] == '\t') {
			dnskey_rr_str[i] = ' ';
		}
	}
	
	/* We need to strip off trailing comments before we send
	 to any clients that might be listening */
	for (int i = 0; dnskey_rr_str[i]; ++i) {
		if (dnskey_rr_str[i] == ';') {
			dnskey_rr_str[i] = '\n';
			dnskey_rr_str[i+1] = '\0';
			break;
		}
	}
	// pass the dnskey rr string to a configured
	// delegation signer retract program.
	if (!ds_retract_command || ds_retract_command[0] == '\0') {
		if (!force) {
			ods_log_error_and_printf(sockfd, module_str, 
				"No \"DelegationSignerRetractCommand\" "
				"configured. No state changes made. "
				"Use --force to override.");
			bOK = false;
		}
		/* else: Do nothing, return keytag. */
	} else if (stat(ds_retract_command, &stat_ret) != 0) {
		/* First check that the command exists */
		ods_log_error_and_printf(sockfd, module_str,
			"Cannot stat file %s: %s", ds_retract_command,
			strerror(errno));
	} else if (S_ISREG(stat_ret.st_mode) && 
			!(stat_ret.st_mode & S_IXUSR || 
			  stat_ret.st_mode & S_IXGRP || 
			  stat_ret.st_mode & S_IXOTH)) {
		/* Then see if it is a regular file, then if usr, grp or 
		 * all have execute set */
		ods_log_error_and_printf(sockfd, module_str,
			"File %s is not executable", ds_retract_command);
	} else {
		/* send records to the configured command */
		FILE *fp = popen(ds_retract_command, "w");
		if (fp == NULL) {
			ods_log_error_and_printf(sockfd, module_str,
				"failed to run command: %s: %s", ds_retract_command,
				strerror(errno));
		} else {
			int bytes_written = fprintf(fp, "%s", dnskey_rr_str);
			if (bytes_written < 0) {
				ods_log_error_and_printf(sockfd, module_str,
					"[%s] Failed to write to %s: %s", ds_retract_command,
					strerror(errno));
			} else if (pclose(fp) == -1) {
				ods_log_error_and_printf(sockfd, module_str,
					"failed to close %s: %s", ds_retract_command,
					strerror(errno));
			} else {
				bOK = true;
				ods_printf(sockfd, "key %s retracted by %s\n", id,
					ds_retract_command);
			}
		}
	}
	
	LDNS_FREE(dnskey_rr_str);
	hsm_destroy_context(hsm_ctx);
	return bOK;
}