OpenDNSSEC-enforcer  2.1.6
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 
55 #include "signconf/signconf_task.h"
56 
57 static const char *module_str = "policy_resalt_task";
58 static const time_t TIME_INF = ((time_t)-1);
59 
66 static void
67 generate_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 
86 static void
87 to_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 
103 static time_t
104 perform_policy_resalt(task_type* task, char const *policyname, void *userdata,
105  void *context)
106 {
107  policy_t *policy;
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  }
129  resalt_time = policy_denial_salt_last_change(policy) +
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 
166 static task_type *
167 policy_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  * */
176 int
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 }
policy.h
flush_resalt_task_all
int flush_resalt_task_all(engine_type *engine, db_connection_t *dbconn)
Definition: policy_resalt_task.c:177
policy_resalt_task.h
policy_list_free
void policy_list_free(policy_list_t *policy_list)
Definition: policy.c:2664
policy_name
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
policy_denial_resalt
unsigned int policy_denial_resalt(const policy_t *policy)
Definition: policy.c:917
policy_list_next
const policy_t * policy_list_next(policy_list_t *policy_list)
Definition: policy.c:3214
policy_denial_type
policy_denial_type
Definition: policy.h:40
policy_free
void policy_free(policy_t *policy)
Definition: policy.c:518
engine_struct::taskq
schedule_type * taskq
Definition: engine.h:60
policy_denial_salt_last_change
unsigned int policy_denial_salt_last_change(const policy_t *policy)
Definition: policy.c:957
signconf_task.h
policy_list_new
policy_list_t * policy_list_new(const db_connection_t *connection)
Definition: policy.c:2621
signconf_task_flush_policy
void signconf_task_flush_policy(engine_type *engine, db_connection_t *dbconn, policy_t const *policy)
Definition: signconf_task.c:85
policy_passthrough
unsigned int policy_passthrough(const policy_t *policy)
Definition: policy.c:1085
policy_denial_salt_length
unsigned int policy_denial_salt_length(const policy_t *policy)
Definition: policy.c:941
engine_struct
Definition: engine.h:47
policy
Definition: policy.h:60
policy_update
int policy_update(policy_t *policy)
Definition: policy.c:2110
policy_list
Definition: policy.h:733
policy_set_denial_salt
int policy_set_denial_salt(policy_t *policy, const char *denial_salt_text)
Definition: policy.c:1351
engine.h
policy_list_get
int policy_list_get(policy_list_t *policy_list)
Definition: policy.c:3040
policy_new_get_by_name
policy_t * policy_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: policy.c:2090
db_connection
Definition: db_connection.h:46
policy_set_denial_salt_last_change
int policy_set_denial_salt_last_change(policy_t *policy, unsigned int denial_salt_last_change)
Definition: policy.c:1373
POLICY_DENIAL_TYPE_NSEC3
@ POLICY_DENIAL_TYPE_NSEC3
Definition: policy.h:43