Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated cookie secrets management #378

Merged
merged 11 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ logfile = @logfile@
xfrdir = @xfrdir@
xfrdfile = @xfrdfile@
zonelistfile = @zonelistfile@
cookiesecretsfile = @cookiesecretsfile@
nsdconfigfile = @nsd_conf_file@
zonesdir = @zonesdir@
chrootdir= @chrootdir@
Expand Down Expand Up @@ -73,6 +74,7 @@ EDIT = $(SED) \
-e 's,@xfrdir\@,$(xfrdir),g' \
-e 's,@xfrdfile\@,$(xfrdfile),g' \
-e 's,@zonelistfile\@,$(zonelistfile),g' \
-e 's,@cookiesecretsfile\@,$(cookiesecretsfile),g' \
-e 's,@nsdconfigfile\@,$(nsdconfigfile),g' \
-e 's,@shell\@,$(SHELL),g' \
-e 's,@ratelimit_default\@,@ratelimit_default@,g' \
Expand Down Expand Up @@ -167,6 +169,7 @@ install: all
$(INSTALL) -d $(DESTDIR)$(xfrdir)
$(INSTALL) -d `dirname $(DESTDIR)$(xfrdfile)`
$(INSTALL) -d `dirname $(DESTDIR)$(zonelistfile)`
$(INSTALL) -d `dirname $(DESTDIR)$(cookiesecretsfile)`
$(INSTALL) -d $(DESTDIR)$(mandir)
$(INSTALL) -d $(DESTDIR)$(mandir)/man8
$(INSTALL) -d $(DESTDIR)$(mandir)/man5
Expand All @@ -189,7 +192,7 @@ uninstall:
rm -f -- $(DESTDIR)$(mandir)/man8/nsd-checkconf.8 $(DESTDIR)$(mandir)/man8/nsd-checkzone.8 $(DESTDIR)$(mandir)/man8/nsd-control.8
rm -f -- $(DESTDIR)$(pidfile)
@echo
@echo "You still need to remove $(DESTDIR)$(configdir), $(DESTDIR)$(piddir), $(DESTDIR)$(xfrdfile), $(DESTDIR)$(zonelistfile) directory by hand."
@echo "You still need to remove $(DESTDIR)$(configdir), $(DESTDIR)$(piddir), $(DESTDIR)$(xfrdfile), $(DESTDIR)$(zonelistfile) $(DESTDIR)$(cookiesecretsfile) directory by hand."

test:

Expand Down
1 change: 1 addition & 0 deletions configlexer.lex
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ proxy-protocol-port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PROXY_PROTOC
answer-cookie{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ANSWER_COOKIE;}
cookie-secret{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_COOKIE_SECRET;}
cookie-secret-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_COOKIE_SECRET_FILE;}
cookie-staging-secret{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_COOKIE_STAGING_SECRET;}
xfrd-tcp-max{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XFRD_TCP_MAX;}
xfrd-tcp-pipeline{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XFRD_TCP_PIPELINE;}
verify{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERIFY; }
Expand Down
23 changes: 22 additions & 1 deletion configparser.y
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ struct component {
%token VAR_ANSWER_COOKIE
%token VAR_COOKIE_SECRET
%token VAR_COOKIE_SECRET_FILE
%token VAR_COOKIE_STAGING_SECRET
%token VAR_MAX_REFRESH_TIME
%token VAR_MIN_REFRESH_TIME
%token VAR_MAX_RETRY_TIME
Expand Down Expand Up @@ -512,7 +513,27 @@ server_option:
| VAR_ANSWER_COOKIE boolean
{ cfg_parser->opt->answer_cookie = $2; }
| VAR_COOKIE_SECRET STRING
{ cfg_parser->opt->cookie_secret = region_strdup(cfg_parser->opt->region, $2); }
{
uint8_t secret[32];
ssize_t len = hex_pton($2, secret, NSD_COOKIE_SECRET_SIZE);

if(len != NSD_COOKIE_SECRET_SIZE) {
yyerror("expected a 128 bit hex string");
} else {
cfg_parser->opt->cookie_secret = region_strdup(cfg_parser->opt->region, $2);
}
}
| VAR_COOKIE_STAGING_SECRET STRING
{
uint8_t secret[32];
ssize_t len = hex_pton($2, secret, NSD_COOKIE_SECRET_SIZE);

if(len != NSD_COOKIE_SECRET_SIZE) {
yyerror("expected a 128 bit hex string");
} else {
cfg_parser->opt->cookie_staging_secret = region_strdup(cfg_parser->opt->region, $2);
}
}
| VAR_COOKIE_SECRET_FILE STRING
{ cfg_parser->opt->cookie_secret_file = region_strdup(cfg_parser->opt->region, $2); }
| VAR_XFRD_TCP_MAX number
Expand Down
6 changes: 6 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ AC_ARG_WITH([zonelistfile], AS_HELP_STRING([--with-zonelistfile=path],[Pathname
AC_DEFINE_UNQUOTED(ZONELISTFILE, ["`eval echo $zonelistfile`"], [Pathname to the NSD zone list file.])
AC_SUBST(zonelistfile)

# default cookiesecrets file location.
cookiesecretsfile=${dbdir}/cookiesecrets.txt
AC_ARG_WITH([cookiesecretsfile], AS_HELP_STRING([--with-cookiesecretsfile=path],[Pathname to the NSD cookie secrets file]), [cookiesecretsfile=$withval])
AC_DEFINE_UNQUOTED(COOKIESECRETSFILE, ["`eval echo $cookiesecretsfile`"], [Pathname to the NSD cookies secrets file.])
AC_SUBST(cookiesecretsfile)

# default xfr dir location.
xfrdir="/tmp"
AC_ARG_WITH([xfrdir], AS_HELP_STRING([--with-xfrdir=path],[Pathname to where the NSD transfer dir is created]), [xfrdir=$withval])
Expand Down
103 changes: 19 additions & 84 deletions difffile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1714,44 +1714,25 @@ void task_new_del_key(udb_base* udb, udb_ptr* last, const char* name)
udb_ptr_unlink(&e, udb);
}

void task_new_add_cookie_secret(udb_base* udb, udb_ptr* last,
const char* secret) {
void task_new_cookies(udb_base* udb, udb_ptr* last, int answer_cookie,
size_t cookie_count, void* cookie_secrets) {
udb_ptr e;
char* p;
size_t const secret_size = strlen(secret) + 1;
size_t const secrets_size = sizeof(cookie_secrets_type);

DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task add_cookie_secret"));
DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task cookies"));

if(!task_create_new_elem(udb, last, &e,
sizeof(struct task_list_d) + secret_size, NULL)) {
log_msg(LOG_ERR, "tasklist: out of space, cannot add add_cookie_secret");
sizeof(struct task_list_d) + secrets_size, NULL)) {
log_msg(LOG_ERR, "tasklist: out of space, cannot add cookies");
return;
}
TASKLIST(&e)->task_type = task_add_cookie_secret;
TASKLIST(&e)->task_type = task_cookies;
TASKLIST(&e)->newserial = (uint32_t) answer_cookie;
TASKLIST(&e)->yesno = (uint64_t) cookie_count;
p = (char*)TASKLIST(&e)->zname;
memmove(p, secret, secret_size);
udb_ptr_unlink(&e, udb);
}

void task_new_drop_cookie_secret(udb_base* udb, udb_ptr* last) {
udb_ptr e;
DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task drop_cookie_secret"));
if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), NULL)) {
log_msg(LOG_ERR, "tasklist: out of space, cannot add drop_cookie_secret");
return;
}
TASKLIST(&e)->task_type = task_drop_cookie_secret;
udb_ptr_unlink(&e, udb);
}
memmove(p, cookie_secrets, secrets_size);

void task_new_activate_cookie_secret(udb_base* udb, udb_ptr* last) {
udb_ptr e;
DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task activate_cookie_secret"));
if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), NULL)) {
log_msg(LOG_ERR, "tasklist: out of space, cannot add activate_cookie_secret");
return;
}
TASKLIST(&e)->task_type = task_activate_cookie_secret;
udb_ptr_unlink(&e, udb);
}

Expand Down Expand Up @@ -1988,53 +1969,13 @@ task_process_del_key(struct nsd* nsd, struct task_list_d* task)
}

static void
task_process_add_cookie_secret(struct nsd* nsd, struct task_list_d* task) {
uint8_t secret_tmp[NSD_COOKIE_SECRET_SIZE];
ssize_t decoded_len;
char* secret = (char*)task->zname;

DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add_cookie_secret task %s", secret));

if( strlen(secret) != 32 ) {
log_msg(LOG_ERR, "invalid cookie secret: %s", secret);
explicit_bzero(secret, strlen(secret));
return;
}

decoded_len = hex_pton(secret, secret_tmp, NSD_COOKIE_SECRET_SIZE);
if( decoded_len != 16 ) {
explicit_bzero(secret_tmp, NSD_COOKIE_SECRET_SIZE);
log_msg(LOG_ERR, "unable to parse cookie secret: %s", secret);
explicit_bzero(secret, strlen(secret));
return;
}
explicit_bzero(secret, strlen(secret));
add_cookie_secret(nsd, secret_tmp);
explicit_bzero(secret_tmp, NSD_COOKIE_SECRET_SIZE);
}

static void
task_process_drop_cookie_secret(struct nsd* nsd, struct task_list_d* task)
{
(void)task;
DEBUG(DEBUG_IPC, 1, (LOG_INFO, "drop_cookie_secret task"));
if( nsd->cookie_count <= 1 ) {
log_msg(LOG_ERR, "can not drop the only active cookie secret");
return;
}
drop_cookie_secret(nsd);
}

static void
task_process_activate_cookie_secret(struct nsd* nsd, struct task_list_d* task)
{
(void)task;
DEBUG(DEBUG_IPC, 1, (LOG_INFO, "activate_cookie_secret task"));
if( nsd->cookie_count <= 1 ) {
log_msg(LOG_ERR, "can not activate the only active cookie secret");
return;
}
activate_cookie_secret(nsd);
task_process_cookies(struct nsd* nsd, struct task_list_d* task) {
DEBUG(DEBUG_IPC, 1, (LOG_INFO, "cookies task answer: %s, count: %d",
task->newserial ? "yes" : "no", (int)task->yesno));

nsd->do_answer_cookie = (int) task->newserial;
nsd->cookie_count = (size_t) task->yesno;
memmove(nsd->cookie_secrets, task->zname, sizeof(nsd->cookie_secrets));
wtoorop marked this conversation as resolved.
Show resolved Hide resolved
}

static void
Expand Down Expand Up @@ -2179,14 +2120,8 @@ void task_process_in_reload(struct nsd* nsd, udb_base* udb, udb_ptr *last_task,
case task_apply_xfr:
task_process_apply_xfr(nsd, udb, last_task, task);
break;
case task_add_cookie_secret:
task_process_add_cookie_secret(nsd, TASKLIST(task));
break;
case task_drop_cookie_secret:
task_process_drop_cookie_secret(nsd, TASKLIST(task));
break;
case task_activate_cookie_secret:
task_process_activate_cookie_secret(nsd, TASKLIST(task));
case task_cookies:
task_process_cookies(nsd, TASKLIST(task));
break;
default:
log_msg(LOG_WARNING, "unhandled task in reload type %d",
Expand Down
13 changes: 4 additions & 9 deletions difffile.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,8 @@ struct task_list_d {
task_opt_change,
/** zonestat increment */
task_zonestat_inc,
/** add a new cookie secret */
task_add_cookie_secret,
/** drop the oldest cookie secret */
task_drop_cookie_secret,
/** make staging cookie secret active */
task_activate_cookie_secret,
/** cookies */
task_cookies,
} task_type;
uint32_t size; /* size of this struct */

Expand Down Expand Up @@ -152,9 +148,8 @@ void task_new_add_pattern(udb_base* udb, udb_ptr* last,
void task_new_del_pattern(udb_base* udb, udb_ptr* last, const char* name);
void task_new_opt_change(udb_base* udb, udb_ptr* last, struct nsd_options* opt);
void task_new_zonestat_inc(udb_base* udb, udb_ptr* last, unsigned sz);
void task_new_add_cookie_secret(udb_base* udb, udb_ptr* last, const char* secret);
void task_new_drop_cookie_secret(udb_base* udb, udb_ptr* last);
void task_new_activate_cookie_secret(udb_base* udb, udb_ptr* last);
void task_new_cookies(udb_base* udb, udb_ptr* last, int answer_cookie,
size_t cookie_count, void* cookie_secrets);
int task_new_apply_xfr(udb_base* udb, udb_ptr* last, const dname_type* zone,
uint32_t old_serial, uint32_t new_serial, uint64_t filenumber);
void task_process_in_reload(struct nsd* nsd, udb_base* udb, udb_ptr *last_task,
Expand Down
26 changes: 18 additions & 8 deletions nsd-checkconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,23 @@ usage(void)
}

static void
print_string_var(const char* varname, const char* value)
print_string_var_default(const char* varname, const char* value,
const char* default_value)
{
if (!value) {
printf("\t#%s\n", varname);
} else {
if (value) {
printf("\t%s \"%s\"\n", varname, value);
} else if (default_value) {
printf("\t#%s \"%s\"\n", varname, default_value);
} else {
printf("\t#%s\n", varname);
}

}

static void
print_string_var(const char* varname, const char* value)
{
print_string_var_default(varname, value, NULL);
}

static void
Expand Down Expand Up @@ -439,6 +449,7 @@ config_print_zone(nsd_options_type* opt, const char* k, int s, const char *o,
SERV_GET_STR(tls_port, o);
SERV_GET_STR(tls_cert_bundle, o);
SERV_GET_STR(cookie_secret, o);
SERV_GET_STR(cookie_staging_secret, o);
SERV_GET_STR(cookie_secret_file, o);
SERV_GET_BIN(answer_cookie, o);
/* int */
Expand Down Expand Up @@ -716,10 +727,9 @@ config_test_print_server(nsd_options_type* opt)
print_string_var("tls-port:", opt->tls_port);
print_string_var("tls-cert-bundle:", opt->tls_cert_bundle);
printf("\tanswer-cookie: %s\n", opt->answer_cookie?"yes":"no");
if (opt->cookie_secret)
print_string_var("cookie-secret:", opt->cookie_secret);
if (opt->cookie_secret_file)
print_string_var("cookie-secret-file:", opt->cookie_secret_file);
print_string_var("cookie-secret:", opt->cookie_secret);
print_string_var("cookie-staging-secret:", opt->cookie_staging_secret);
print_string_var_default("cookie-secret-file:", opt->cookie_secret_file, COOKIESECRETSFILE);
if(opt->proxy_protocol_port) {
struct proxy_protocol_port_list* p;
for(p = opt->proxy_protocol_port; p; p = p->next)
Expand Down
2 changes: 1 addition & 1 deletion nsd-control.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ be dropped with the \fBdrop_cookie_secret\fR command.
.sp
Persistence is accomplished by writing to a file which if configured with the
\fBcookie\-secret\-file\fR option in the server section of the config file.
The default value for that is: @configdir@/nsd_cookiesecrets.txt .
The default value for that is: @cookiesecretsfile@ .
.TP
.B drop_cookie_secret
Drop the \fIstaging\fR cookie secret.
Expand Down
Loading
Loading