OpenDNSSEC-enforcer  2.0.4
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 
99 time_t
100 perform_policy_resalt(int sockfd, engine_type* engine,
101  db_connection_t *dbconn)
102 {
103  policy_list_t *pol_list;
104  policy_t *policy;
105  time_t schedule_time = TIME_INF, now = time_now(), resalt_time;
106  char salt[255], salthex[511];
107  int saltlength;
108  db_clause_list_t* clause_list;
109  (void) engine; (void) sockfd;
110 
111 #ifndef HAVE_ARC4RANDOM
112  srand(now);
113 #endif
114 
115  if (!(clause_list = db_clause_list_new())
117  || !(pol_list = policy_list_new_get_by_clauses(dbconn, clause_list)))
118  {
119  db_clause_list_free(clause_list);
120  ods_log_error("[%s] retrying in 60 seconds", module_str);
121  return now + 60;
122  }
123  db_clause_list_free(clause_list);
124 
125  while ((policy = policy_list_get_next(pol_list))) {
127  || policy_passthrough(policy))
128  {
129  policy_free(policy);
130  continue;
131  }
132  resalt_time = policy_denial_salt_last_change(policy) +
133  policy_denial_resalt(policy);
134  if (now >= resalt_time) {
135  saltlength = policy_denial_salt_length(policy);
136  if (saltlength <= 0 || saltlength > 255) {
137  ods_log_error("[%s] policy %s has an invalid salt length. "
138  "Must be in range [0..255]", module_str, policy_name(policy));
139  policy_free(policy);
140  continue; /* no need to schedule for this policy */
141  }
142  /* Yes, we need to resalt this policy */
143  generate_salt(salt, saltlength);
144  to_hex(salt, saltlength, salthex);
145 
146  if(policy_set_denial_salt(policy, salthex) ||
147  policy_set_denial_salt_last_change(policy, now) ||
148  policy_update(policy))
149  {
150  ods_log_error("[%s] db error", module_str);
151  policy_free(policy);
152  break;
153  }
154  resalt_time = now + policy_denial_resalt(policy);
155  ods_log_debug("[%s] policy %s resalted successfully", module_str, policy_name(policy));
156  if (perform_signconf(sockfd, dbconn, 1))
157  ods_log_error("[%s] signconf not updated: new salt cannot be written in signconf", module_str);
158  }
159  if ((resalt_time < schedule_time || schedule_time == TIME_INF) && policy_denial_resalt(policy) > 0)
160  schedule_time = resalt_time;
161  policy_free(policy);
162  }
163  policy_list_free(pol_list);
164  ods_log_debug("[%s] policies have been updated", module_str);
165  return schedule_time;
166 }
167 
168 static task_type *
169 policy_resalt_task_perform(task_type *task)
170 {
171  task->backoff = 0;
172  task->when = perform_policy_resalt(-1,(engine_type *)task->context,
173  task->dbconn);
174  if (task->when == -1) {
175  task_cleanup(task);
176  return NULL;
177  }
178  return task;
179 }
180 
181 task_type *
183 {
184  task_id what_id = task_register("resalt",
185  "policy_resalt_task_perform", policy_resalt_task_perform);
186  return task_create(what_id, time_now(), "policies", "resalt", engine, NULL);
187 }
188 
189 int
191 {
192  int status;
193  task_id what_id;
194  /* flush (force to run) the enforcer task when it is waiting in the
195  task list. */
196  if (!task_id_from_long_name("policy_resalt_task_perform", &what_id)) {
197  /* no such task */
198  return 1;
199  }
200  if (!schedule_flush_type(engine->taskq, what_id)) {
201  status = schedule_task(engine->taskq, policy_resalt_task(engine));
202  if (status != ODS_STATUS_OK) {
203  ods_fatal_exit("[%s] failed to create resalt task", module_str);
204  return 0;
205  }
206  }
207  return 1;
208 }
void policy_list_free(policy_list_t *policy_list)
Definition: policy.c:2664
void ods_log_debug(const char *format,...)
Definition: log.c:41
unsigned int policy_denial_resalt(const policy_t *policy)
Definition: policy.c:917
time_t when
Definition: task.h:63
db_clause_list_t * db_clause_list_new(void)
Definition: db_clause.c:202
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
void ods_fatal_exit(const char *format,...)
Definition: log.c:94
unsigned int policy_denial_salt_last_change(const policy_t *policy)
Definition: policy.c:957
int perform_signconf(int sockfd, const db_connection_t *dbconn, int force)
Definition: signconf_task.c:39
time_t backoff
Definition: task.h:64
void * context
Definition: task.h:68
ods_status schedule_task(schedule_type *schedule, task_type *task)
Definition: schedule.c:401
void ods_log_error(const char *format,...)
Definition: log.c:69
bool task_id_from_long_name(const char *long_name, task_id *pwhat)
Definition: task.c:53
unsigned int policy_passthrough(const policy_t *policy)
Definition: policy.c:1085
policy_denial_type
Definition: policy.h:40
enum task_id_enum task_id
Definition: task.h:53
void db_clause_list_free(db_clause_list_t *clause_list)
Definition: db_clause.c:209
policy_t * policy_list_get_next(policy_list_t *policy_list)
Definition: policy.c:3277
void policy_free(policy_t *policy)
Definition: policy.c:518
task_type * policy_resalt_task(engine_type *engine)
int flush_resalt_task(engine_type *engine)
void task_cleanup(task_type *task)
Definition: task.c:147
db_connection_t * dbconn
Definition: task.h:71
int policy_update(policy_t *policy)
Definition: policy.c:2110
int schedule_flush_type(schedule_type *schedule, task_id id)
Definition: schedule.c:298
int policy_set_denial_salt(policy_t *policy, const char *denial_salt_text)
Definition: policy.c:1351
time_t perform_policy_resalt(int sockfd, engine_type *engine, db_connection_t *dbconn)
schedule_type * taskq
Definition: engine.h:55
task_id task_register(const char *short_name, const char *long_name, how_type how)
Definition: task.c:82
db_clause_t * policy_denial_type_clause(db_clause_list_t *clause_list, policy_denial_type_t denial_type)
Definition: policy.c:1540
task_type * task_create(task_id what_id, time_t when, const char *who, const char *what, void *context, how_type clean_context)
Definition: task.c:110
Definition: policy.h:60
unsigned int policy_denial_salt_length(const policy_t *policy)
Definition: policy.c:941
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_get_by_clauses(const db_connection_t *connection, const db_clause_list_t *clause_list)
Definition: policy.c:3135