Add 'tls-padding' test.

This commit is contained in:
Jim Hague 2018-01-16 12:56:50 +00:00
parent fdafb458ef
commit a4ff6de985
1 changed files with 146 additions and 6 deletions

View File

@ -52,6 +52,8 @@
#define DEFAULT_LOOKUP_NAME "getdnsapi.net"
#define DEFAULT_LOOKUP_TYPE GETDNS_RRTYPE_AAAA
#define EDNS0_PADDING_CODE 12
#define EXAMPLE_PIN "pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\""
/* Plugin exit values */
@ -193,6 +195,10 @@ static void usage()
" Check server certificate validity, report\n"
" warning or critical if days to expiry at\n"
" or below thresholds (default 14,7).\n"
" tls-padding <blocksize> [<name> [<type>]]\n"
" Check server support for EDNS0 padding in TLS\n"
" Special blocksize values are 0 = off,\n"
" 1 = sensible default.\n"
"\n"
"Enabling monitoring mode ensures output messages and exit statuses conform\n"
"to the requirements of monitoring plugins (www.monitoring-plugins.org).\n",
@ -471,14 +477,19 @@ static exit_value_t get_report_info(const struct test_info_s *test_info,
static exit_value_t get_answers(const struct test_info_s *test_info,
const getdns_dict *response,
const char *section,
getdns_list **answers,
size_t *no_answers)
{
getdns_return_t ret;
char buf[40];
if ((ret = getdns_dict_get_list(response, "/replies_tree/0/answer", answers)) != GETDNS_RETURN_GOOD) {
snprintf(buf, sizeof(buf), "/replies_tree/0/%s", section);
if ((ret = getdns_dict_get_list(response, buf, answers)) != GETDNS_RETURN_GOOD) {
fprintf(test_info->errout,
"Cannot get answers: %s (%d)",
"Cannot get section '%s': %s (%d)",
section,
getdns_get_errorstr_by_id(ret),
ret);
return EXIT_UNKNOWN;
@ -486,13 +497,16 @@ static exit_value_t get_answers(const struct test_info_s *test_info,
if ((ret = getdns_list_get_length(*answers, no_answers)) != GETDNS_RETURN_GOOD) {
fprintf(test_info->errout,
"Cannot get number of answers: %s (%d)",
"Cannot get number of items in '%s': %s (%d)",
section,
getdns_get_errorstr_by_id(ret),
ret);
return EXIT_UNKNOWN;
}
if (*no_answers <= 0) {
fputs("Got zero answers", test_info->errout);
fprintf(test_info->errout,
"Zero entries in '%s'",
section);
return EXIT_WARNING;
}
@ -507,7 +521,7 @@ static exit_value_t check_answer_type(const struct test_info_s *test_info,
size_t no_answers;
exit_value_t xit;
if ((xit = get_answers(test_info, response, &answers, &no_answers)) != EXIT_OK)
if ((xit = get_answers(test_info, response, "answer", &answers, &no_answers)) != EXIT_OK)
return xit;
for (size_t i = 0; i < no_answers; ++i) {
@ -744,7 +758,7 @@ static exit_value_t test_qname_minimisation(const struct test_info_s *test_info,
getdns_list *answers;
size_t no_answers;
if ((xit = get_answers(test_info, response, &answers, &no_answers)) != EXIT_OK)
if ((xit = get_answers(test_info, response, "answer", &answers, &no_answers)) != EXIT_OK)
return xit;
for (size_t i = 0; i < no_answers; ++i) {
@ -773,6 +787,7 @@ static exit_value_t test_qname_minimisation(const struct test_info_s *test_info,
continue;
getdns_bindata *rtxt;
if ((ret = getdns_dict_get_bindata(answer, "/rdata/txt_strings/0", &rtxt)) != GETDNS_RETURN_GOOD) {
fputs("No answer text", test_info->errout);
return EXIT_WARNING;
@ -799,6 +814,130 @@ static exit_value_t test_qname_minimisation(const struct test_info_s *test_info,
return EXIT_UNKNOWN;
}
static exit_value_t test_padding(const struct test_info_s *test_info,
char ** av)
{
getdns_dict *response;
exit_value_t xit;
long blocksize;
char *endptr;
const char USAGE[] = "padding takes arguments <blocksize> [<name> [<type>]]";
if (!*av || (blocksize = strtol(*av, &endptr, 10), *endptr != '\0' || blocksize < 0)) {
fputs(USAGE, test_info->errout);
return EXIT_USAGE;
}
++av;
getdns_return_t ret;
if ((ret = getdns_context_set_tls_query_padding_blocksize(test_info->context, (uint16_t) blocksize)) != GETDNS_RETURN_GOOD) {
fprintf(test_info->errout,
"Cannot set padding blocksize: %s (%d)",
getdns_get_errorstr_by_id(ret),
ret);
return EXIT_UNKNOWN;
}
if ((xit = parse_search_check(test_info,
av,
USAGE,
&response,
NULL,
NULL,
NULL)) != EXIT_OK)
return xit;
getdns_list *answers;
size_t no_answers;
if ((xit = get_answers(test_info, response, "additional", &answers, &no_answers)) != EXIT_OK)
return xit;
for (size_t i = 0; i < no_answers; ++i) {
getdns_dict *answer;
getdns_return_t ret;
if ((ret = getdns_list_get_dict(answers, i, &answer)) != GETDNS_RETURN_GOOD) {
fprintf(test_info->errout,
"Cannot get answer number %zu: %s (%d)",
i,
getdns_get_errorstr_by_id(ret),
ret);
return EXIT_UNKNOWN;
}
uint32_t rtype;
if ((ret = getdns_dict_get_int(answer, "type", &rtype)) != GETDNS_RETURN_GOOD) {
fprintf(test_info->errout,
"Cannot get answer type: %s (%d)",
getdns_get_errorstr_by_id(ret),
ret);
return EXIT_UNKNOWN;
}
if (rtype != GETDNS_RRTYPE_OPT)
continue;
getdns_list *options;
size_t no_options;
if ((ret = getdns_dict_get_list(answer, "/rdata/options", &options)) != GETDNS_RETURN_GOOD) {
goto no_padding;
}
if ((ret = getdns_list_get_length(options, &no_options)) != GETDNS_RETURN_GOOD) {
fprintf(test_info->errout,
"Cannot get number of options: %s (%d)",
getdns_get_errorstr_by_id(ret),
ret);
return EXIT_UNKNOWN;
}
for (size_t j = 0; j < no_options; ++j) {
getdns_dict *option;
uint32_t code;
if ((ret = getdns_list_get_dict(options, j, &option)) != GETDNS_RETURN_GOOD) {
fprintf(test_info->errout,
"Cannot get option number %zu: %s (%d)",
j,
getdns_get_errorstr_by_id(ret),
ret);
return EXIT_UNKNOWN;
}
if ((ret = getdns_dict_get_int(option, "option_code", &code)) != GETDNS_RETURN_GOOD) {
fprintf(test_info->errout,
"Cannot get option code: %s (%d)",
getdns_get_errorstr_by_id(ret),
ret);
return EXIT_UNKNOWN;
}
if (code != EDNS0_PADDING_CODE)
continue;
/* Yes, we have padding! */
getdns_bindata *data;
if ((ret = getdns_dict_get_bindata(option, "option_data", &data)) != GETDNS_RETURN_GOOD) {
fprintf(test_info->errout,
"Cannot get option code: %s (%d)",
getdns_get_errorstr_by_id(ret),
ret);
return EXIT_UNKNOWN;
}
fprintf(test_info->errout,
"Padding found, length %zu",
data->size);
return EXIT_OK;
}
}
no_padding:
fputs("No padding found", test_info->errout);
return EXIT_CRITICAL;
}
static struct test_funcs_s
{
const char *name;
@ -811,6 +950,7 @@ static struct test_funcs_s
{ "qname-min", false, test_qname_minimisation },
{ "tls-auth", true, test_authenticate },
{ "tls-cert-valid", true, test_certificate_valid },
{ "tls-padding", true, test_padding },
{ NULL, false, NULL }
};