/**
 * 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;
}
Пример #2
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;
}
Пример #3
0
/* Reads one entry from file. Returns entry or NULL on error. */
struct entry*
read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl, 
	ldns_rdf** origin, ldns_rdf** prev_rr)
{
	struct entry* current = NULL;
	char line[MAX_LINE];
	char* parse;
	ldns_pkt_section add_section = LDNS_SECTION_QUESTION;
	struct reply_packet *cur_reply = NULL;
	bool reading_hex = false;
	ldns_buffer* hex_data_buffer = NULL;

	while(fgets(line, (int)sizeof(line), in) != NULL) {
		line[MAX_LINE-1] = 0;
		parse = line;
		(*lineno) ++;
		
		while(isspace((int)*parse))
			parse++;
		/* test for keywords */
		if(isendline(*parse))
			continue; /* skip comment and empty lines */
		if(str_keyword(&parse, "ENTRY_BEGIN")) {
			if(current) {
				error("%s line %d: previous entry does not ENTRY_END", 
					name, *lineno);
			}
			current = new_entry();
			current->lineno = *lineno;
			cur_reply = entry_add_reply(current);
			continue;
		} else if(str_keyword(&parse, "$ORIGIN")) {
			get_origin(name, *lineno, origin, parse);
			continue;
		} else if(str_keyword(&parse, "$TTL")) {
			*default_ttl = (uint32_t)atoi(parse);
			continue;
		}

		/* working inside an entry */
		if(!current) {
			error("%s line %d: expected ENTRY_BEGIN but got %s", 
				name, *lineno, line);
		}
		if(str_keyword(&parse, "MATCH")) {
			matchline(parse, current);
		} else if(str_keyword(&parse, "REPLY")) {
			replyline(parse, cur_reply->reply);
		} else if(str_keyword(&parse, "ADJUST")) {
			adjustline(parse, current, cur_reply);
		} else if(str_keyword(&parse, "EXTRA_PACKET")) {
			cur_reply = entry_add_reply(current);
		} else if(str_keyword(&parse, "SECTION")) {
			if(str_keyword(&parse, "QUESTION"))
				add_section = LDNS_SECTION_QUESTION;
			else if(str_keyword(&parse, "ANSWER"))
				add_section = LDNS_SECTION_ANSWER;
			else if(str_keyword(&parse, "AUTHORITY"))
				add_section = LDNS_SECTION_AUTHORITY;
			else if(str_keyword(&parse, "ADDITIONAL"))
				add_section = LDNS_SECTION_ADDITIONAL;
			else error("%s line %d: bad section %s", name, *lineno, parse);
		} else if(str_keyword(&parse, "HEX_ANSWER_BEGIN")) {
			hex_data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
			reading_hex = true;
		} else if(str_keyword(&parse, "HEX_ANSWER_END")) {
			if (!reading_hex) {
				error("%s line %d: HEX_ANSWER_END read but no HEX_ANSWER_BEGIN keyword seen", name, *lineno);
			}
			reading_hex = false;
			cur_reply->reply_from_hex = data_buffer2wire(hex_data_buffer);
			ldns_buffer_free(hex_data_buffer);
		} else if(str_keyword(&parse, "ENTRY_END")) {
			return current;
		} else if(reading_hex) {
			ldns_buffer_printf(hex_data_buffer, line);
		} else {
			/* it must be a RR, parse and add to packet. */
			ldns_rr* n = NULL;
			ldns_status status;
			if(add_section == LDNS_SECTION_QUESTION)
				status = ldns_rr_new_question_frm_str(
					&n, parse, *origin, prev_rr);
			else status = ldns_rr_new_frm_str(&n, parse, 
				*default_ttl, *origin, prev_rr);
			if(status != LDNS_STATUS_OK)
				error("%s line %d:\n\t%s: %s", name, *lineno,
					ldns_get_errorstr_by_id(status), parse);
			ldns_pkt_push_rr(cur_reply->reply, add_section, n);
		}

	}
	if (reading_hex) {
		error("%s: End of file reached while still reading hex, "
			"missing HEX_ANSWER_END\n", name);
	}
	if(current) {
		error("%s: End of file reached while reading entry. "
			"missing ENTRY_END\n", name);
	}
	return 0;
}
Пример #4
0
ldns_status output_packet(ldns_buffer *output, const ldns_pkt *pkt, struct sockaddr_storage sa, lookup_context_t* context)
{
    const ldns_output_format *fmt = ldns_output_format_nocomments;
    uint16_t i;
    ldns_status status = LDNS_STATUS_OK;

    time_t now = time(NULL);
    char nsbuffer[INET6_ADDRSTRLEN];
    char* ip_prefix = "";
    char* ip_suffix = "";
    switch (((struct sockaddr *) &sa)->sa_family)
    {
        case AF_INET:
            inet_ntop(AF_INET, &(((struct sockaddr_in *) &sa)->sin_addr), nsbuffer, INET_ADDRSTRLEN);
            break;
        case AF_INET6:
            inet_ntop(AF_INET6, &(((struct sockaddr_in6 *) &sa)->sin6_addr), nsbuffer, INET6_ADDRSTRLEN);
            ip_prefix = "[";
            ip_suffix = "]";
            break;
        default:
            exit(1);
    }

    if (!pkt)
    {
        if(0 > ldns_buffer_printf(output, ""))
        {
            abort();
        }
        return LDNS_STATUS_OK;
    }

    if(!context->cmd_args.only_responses)
    {
        if(0 > ldns_buffer_printf(output, "%s%s%s:%u %ld ", ip_prefix, ip_suffix, nsbuffer, ntohs(((struct sockaddr_in *) &sa)->sin_port), now))
        {
            abort();
        }
        for (i = 0; i < ldns_pkt_qdcount(pkt); i++)
        {
            status = ldns_rr2buffer_str_fmt(output, fmt, ldns_rr_list_rr(ldns_pkt_question(pkt), i));
            if (status != LDNS_STATUS_OK)
            {
                return status;
            }
        }
    }

    if (ldns_buffer_status_ok(output))
    {
        for (i = 0; i < ldns_pkt_ancount(pkt); i++)
        {
            if(!context->cmd_args.only_responses)
            {
                if(0 > ldns_buffer_printf(output, "\t"))
                {
                    abort();
                }
            }
            status = ldns_rr2buffer_str_fmt(output, fmt, ldns_rr_list_rr(ldns_pkt_answer(pkt), i));
            if (status != LDNS_STATUS_OK)
            {
                return status;
            }

        }
        if(!context->cmd_args.no_authority)
        {
            if(0 > ldns_buffer_printf(output, "\n"))
            {
                abort();
            }
            for (i = 0; i < ldns_pkt_nscount(pkt); i++)
            {
                if(!context->cmd_args.only_responses)
                {
                    ldns_buffer_printf(output, "\t");
                }
                status = ldns_rr2buffer_str_fmt(output, fmt, ldns_rr_list_rr(ldns_pkt_authority(pkt), i));
                if (status != LDNS_STATUS_OK)
                {
                    return status;
                }
            }
        }
        if(context->cmd_args.additional)
        {
            for (i = 0; i < ldns_pkt_arcount(pkt); i++)
            {
                if(!context->cmd_args.only_responses)
                {
                    ldns_buffer_printf(output, "\t");
                }
                status = ldns_rr2buffer_str_fmt(output, fmt, ldns_rr_list_rr(ldns_pkt_additional(pkt), i));
                if (status != LDNS_STATUS_OK)
                {
                    return status;
                }

            }
        }
    }
    else
    {
        return ldns_buffer_status(output);
    }
    return status;
}