- xfr-tsig, tsig test.

This commit is contained in:
W.C.A. Wijngaards
2025-06-18 16:41:10 +02:00
parent dd4ee42eb6
commit 4bbb74da39
3 changed files with 276 additions and 2 deletions
+243
View File
@@ -39,11 +39,254 @@
*/
#include "config.h"
#include "util/tsig.h"
#include "util/config_file.h"
#include "testcode/unitmain.h"
#include "sldns/sbuffer.h"
#include <ctype.h>
#define xstr(s) str(s)
#define str(s) #s
#define SRCDIRSTR xstr(SRCDIR)
/** verbosity for this file */
static int vtest = 0;
/**
* Content of the TSIG test files.
*
* The tsig test files have this syntax. It is made of lines, lines started
* with # are a comment. empty lines are ignored.
* file_algorithm <name>
* The name is like md5, sha1, sha256 and if the algorithm is not
* supported at the test run time, the file is skipped, silently.
* tsig-key:
* the following lines define name:, algorithm: and secret:
* and it adds a tsig-key that can be used.
* del-key <name>
* The tsig key is deleted, from the in-memory key table.
*
*/
/** Clean up first keyword */
static char*
get_keyword(char* line)
{
char* s = line;
while(isspace(*s))
s++;
if(strlen(s)>0 && s[strlen(s)-1] == '\n')
s[strlen(s)-1] = 0;
return s;
}
/** Get argument from line */
static char*
get_arg_on_line(char* line, char* keyword)
{
char* s = line;
s += strlen(keyword);
while(isspace(*s))
s++;
return s;
}
/** See if algorithm is supported for tsig test */
static int
tsig_algo_test(char* algo)
{
if(strcmp(algo, "md5") == 0)
return 1;
if(strcmp(algo, "sha1") == 0)
return 1;
if(strcmp(algo, "sha224") == 0) {
/* The EVP_sha256 test is also used for sha224. */
#ifdef HAVE_EVP_SHA256
return 1;
#else
return 0;
#endif
}
if(strcmp(algo, "sha256") == 0) {
#ifdef HAVE_EVP_SHA256
return 1;
#else
return 0;
#endif
}
if(strcmp(algo, "sha384") == 0) {
/* The EVP_sha512 test is also used for sha384. */
#ifdef HAVE_EVP_SHA512
return 1;
#else
return 0;
#endif
}
if(strcmp(algo, "sha512") == 0) {
#ifdef HAVE_EVP_SHA512
return 1;
#else
return 0;
#endif
}
if(vtest)
printf("Unknown tsig test algorithm %s\n", algo);
return 0;
}
/** Handle the file_algorithm */
static void
handle_file_algorithm(char* line, int* break_file)
{
char* algo = get_arg_on_line(line, "file_algorithm");
if(!tsig_algo_test(algo)) {
if(vtest)
printf("algorithm not supported\n");
*break_file = 1;
return;
}
if(vtest)
printf("algorithm supported\n");
}
/** Removes quotes if any */
static char*
quote_removal(char* line)
{
if(line[0] == '"') {
char* s = line+1;
if(strlen(s)>0 && s[strlen(s)-1] == '"')
s[strlen(s)-1] = 0;
return s;
}
return line;
}
/** Handle the tsig-key */
static void
handle_tsig_key(struct tsig_key_table* key_table, FILE* in, const char* fname)
{
char line[1024];
char* s;
char* name = NULL, *algorithm = NULL, *secret = NULL;
struct config_tsig_key k;
while(fgets(line, sizeof(line), in)) {
line[sizeof(line)-1]=0;
s = get_keyword(line);
if(strncmp(s, "name:", 5) == 0) {
name = strdup(quote_removal(
get_arg_on_line(s, "name:")));
if(!name)
fatal_exit("out of memory");
} else if(strncmp(s, "algorithm:", 10) == 0) {
algorithm = strdup(quote_removal(
get_arg_on_line(s, "algorithm:")));
if(!algorithm)
fatal_exit("out of memory");
} else if(strncmp(s, "secret:", 7) == 0) {
secret = strdup(quote_removal(
get_arg_on_line(s, "secret:")));
if(!secret)
fatal_exit("out of memory");
} else {
fatal_exit("unknown tsig-key element %s: %s",
fname, s);
}
if(name && algorithm && secret)
break;
}
k.next = NULL;
k.name = name;
k.algorithm = algorithm;
k.secret = secret;
if(!tsig_key_table_add_key(key_table, &k))
fatal_exit("could not tsig_key_table_add_key, out of memory");
if(vtest)
printf("add key %s %s\n", name, algorithm);
free(name);
free(algorithm);
explicit_bzero(secret, strlen(secret));
free(secret);
}
/** Handle the del_key */
static void
handle_del_key(char* line, struct tsig_key_table* key_table)
{
char* name = get_arg_on_line(line, "del_key");
tsig_key_table_del_key_fromstr(key_table, name);
if(vtest)
printf("deleted key %s\n", name);
}
/** Handle one line from the TSIG test file */
static void
handle_line(char* line, struct tsig_key_table* key_table,
struct sldns_buffer* pkt, FILE* in, const char* fname,
int* break_file)
{
char* s = get_keyword(line);
if(vtest)
printf("line: %s\n", s);
if(strncmp(s, "file_algorithm", 14) == 0) {
handle_file_algorithm(s, break_file);
} else if(strcmp(s, "tsig-key:") == 0) {
handle_tsig_key(key_table, in, fname);
} else if(strncmp(s, "delkey", 6) == 0) {
handle_del_key(s, key_table);
} else if(strncmp(s, "#", 1) == 0) {
/* skip comment */
} else if(strcmp(s, "") == 0) {
/* skip empty lines */
} else {
fatal_exit("Unknown tsig line %s: %s", fname, s);
}
(void)pkt;
}
/** test tsig */
static void
tsig_test_one(const char* fname)
{
struct tsig_key_table* key_table;
sldns_buffer* pkt;
FILE* in;
char line[1024];
int break_file = 0;
unit_show_func("tsig", fname);
key_table = tsig_key_table_create();
if(!key_table)
fatal_exit("out of memory");
pkt = sldns_buffer_new(65536);
if(!pkt)
fatal_exit("out of memory");
sldns_buffer_flip(pkt); /* start with empty buffer */
in = fopen(fname, "r");
if(!in)
fatal_exit("could not open %s: %s", fname, strerror(errno));
while(fgets(line, sizeof(line), in)) {
line[sizeof(line)-1]=0;
handle_line(line, key_table, pkt, in, fname, &break_file);
if(break_file)
break;
}
if(ferror(in))
fatal_exit("error read %s: %s", fname, strerror(errno));
tsig_key_table_delete(key_table);
sldns_buffer_free(pkt);
fclose(in);
}
/** test tsig code */
void
tsig_test(void)
{
unit_show_feature("tsig");
tsig_test_one(SRCDIRSTR "/testdata/tsig_test.1");
}