OpenDNSSEC-enforcer 2.1.10
policy_resalt_task.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Surfnet
3 * Copyright (c) 2011 .SE (The Internet Infrastructure Foundation).
4 * Copyright (c) 2011 OpenDNSSEC AB (svb)
5 * Copyright (c) 2014 NLnet Labs
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31#include "config.h"
32
33/* On MacOSX arc4random is only available when we
34 undef _ANSI_SOURCE and define _DARWIN_C_SOURCE. */
35#ifdef __APPLE__
36 #undef _ANSI_SOURCE
37 #define _DARWIN_C_SOURCE 1
38#endif
39/* Make arc4random visible on FreeBSD */
40#ifndef __BSD_VISIBLE
41 #define __BSD_VISIBLE 1
42#endif
43
44#include "duration.h"
45#include "file.h"
46#include "log.h"
47#include "str.h"
48#include "scheduler/task.h"
49#include "daemon/engine.h"
50#include "db/policy.h"
51
52#include <stdlib.h>
53
56
57static const char *module_str = "policy_resalt_task";
58static const time_t TIME_INF = ((time_t)-1);
59
66static void
67generate_salt(char *buf, int len)
68{
69#ifdef HAVE_ARC4RANDOM
70 arc4random_buf(buf, len);
71#else
72 int i;
73 /* Not really sure how many bits we get, but pseudo randomness
74 * is cheap. */
75 for (i = 0; i < len; i++)
76 buf[i] = rand() & 0xFF;
77#endif
78}
79
86static void
87to_hex(const char *buf, int len, char *out)
88{
89 const char *h = "0123456789abcdef";
90 int i;
91
92 for (i = 0; i < len; i++) {
93 out[2*i] = h[(buf[i]>>4) & 0x0F];
94 out[2*i+1] = h[buf[i] & 0x0F];
95 }
96 out[2*len] = 0;
97}
98
103static time_t
104perform_policy_resalt(task_type* task, char const *policyname, void *userdata,
105 void *context)
106{
108 db_connection_t *dbconn = (db_connection_t *) context;
109 time_t resalt_time, now = time_now();
110 char salt[255], salthex[511];
111 int saltlength;
112 engine_type *engine = (engine_type *)userdata;
113
114 policy = policy_new_get_by_name(dbconn, policyname);
115 if (!policy) {
116 ods_log_error("[%s] could not fetch policy %s from database,"
117 " rescheduling", module_str, policyname);
118 /* TODO: figure out if it was a database error. if it is truly
119 * not in database we should just return schedule_SUCCESS */
120 return schedule_DEFER;
121 }
122
125 {
127 return schedule_SUCCESS;
128 }
131
132 if (now >= resalt_time) {
133 saltlength = policy_denial_salt_length(policy);
134 if (saltlength <= 0 || saltlength > 255) {
135 ods_log_error("[%s] policy %s has an invalid salt length. "
136 "Must be in range [0..255]", module_str, policy_name(policy));
138 return schedule_SUCCESS; /* no point in rescheduling */
139 }
140
141#ifndef HAVE_ARC4RANDOM
142 srand(now);
143#endif
144
145 /* Yes, we need to resalt this policy */
146 generate_salt(salt, saltlength);
147 to_hex(salt, saltlength, salthex);
148
149 if(policy_set_denial_salt(policy, salthex) ||
152 {
153 ods_log_error("[%s] db error", module_str);
155 return schedule_DEFER;
156 }
157 resalt_time = now + policy_denial_resalt(policy);
158 ods_log_debug("[%s] policy %s resalted successfully", module_str, policy_name(policy));
159 signconf_task_flush_policy(engine, dbconn, policy);
160 }
161 if (policy_denial_resalt(policy) <= 0) resalt_time = -1;
163 return resalt_time;
164}
165
166static task_type *
167policy_resalt_task(char const *owner, engine_type *engine)
168{
169 return task_create(strdup(owner), TASK_CLASS_ENFORCER, TASK_TYPE_RESALT,
170 perform_policy_resalt, engine, NULL, time_now());
171}
172
173/*
174 * Schedule resalt tasks for all policies.
175 * */
176int
178{
179
180 policy_list_t *policylist;
181 const policy_t *policy;
182 task_type *task;
183 int status = ODS_STATUS_OK;
184
185 policylist = policy_list_new(dbconn);
186 if (policy_list_get(policylist)) {
187 ods_log_error("[%s] Unable to get list of policies from database",
188 module_str);
189 policy_list_free(policylist);
190 return ODS_STATUS_ERR;
191 }
192
193 while ((policy = policy_list_next(policylist))) {
194 task = policy_resalt_task(policy_name(policy), engine);
195 status |= schedule_task(engine->taskq, task, 1, 0);
196 }
197 policy_list_free(policylist);
198 return status;
199}
unsigned int policy_denial_salt_length(const policy_t *policy)
Definition: policy.c:941
void policy_list_free(policy_list_t *policy_list)
Definition: policy.c:2664
const policy_t * policy_list_next(policy_list_t *policy_list)
Definition: policy.c:3214
unsigned int policy_denial_salt_last_change(const policy_t *policy)
Definition: policy.c:957
unsigned int policy_passthrough(const policy_t *policy)
Definition: policy.c:1085
policy_t * policy_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: policy.c:2090
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
int policy_set_denial_salt_last_change(policy_t *policy, unsigned int denial_salt_last_change)
Definition: policy.c:1373
policy_list_t * policy_list_new(const db_connection_t *connection)
Definition: policy.c:2621
int policy_set_denial_salt(policy_t *policy, const char *denial_salt_text)
Definition: policy.c:1351
int policy_list_get(policy_list_t *policy_list)
Definition: policy.c:3040
void policy_free(policy_t *policy)
Definition: policy.c:518
unsigned int policy_denial_resalt(const policy_t *policy)
Definition: policy.c:917
int policy_update(policy_t *policy)
Definition: policy.c:2110
policy_denial_type
Definition: policy.h:40
@ POLICY_DENIAL_TYPE_NSEC3
Definition: policy.h:43
int flush_resalt_task_all(engine_type *engine, db_connection_t *dbconn)
void signconf_task_flush_policy(engine_type *engine, db_connection_t *dbconn, policy_t const *policy)
Definition: signconf_task.c:85
schedule_type * taskq
Definition: engine.h:60
Definition: policy.h:60