OpenDNSSEC-enforcer  1.4.3
ksm_request.c
Go to the documentation of this file.
1 /*
2  * $Id: ksm_request.c 7028 2013-02-13 11:41:17Z sion $
3  *
4  * Copyright (c) 2008-2009 Nominet UK. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
29 /*+
30  * ksm_request.c - Handle Request Keys Processing
31  *
32  * Description:
33  * The REQUEST command asks KSM to list the keys to be included in the
34  * zone when it is next signed. It can optionally force a rollover by
35  * marking the active key as retired.
36 -*/
37 
38 #include <assert.h>
39 #include <stdio.h>
40 #include <string.h>
41 
42 #include "ksm/database.h"
43 #include "ksm/database_statement.h"
44 #include "ksm/db_fields.h"
45 #include "ksm/debug.h"
46 #include "ksm/ksm.h"
47 #include "ksm/kmedef.h"
48 #include "ksm/ksmdef.h"
49 #include "ksm/message.h"
50 #include "ksm/memory.h"
51 #include "ksm/string_util.h"
52 #include "ksm/string_util2.h"
53 
54 /* TODO The nomenclature needs to be updated to agree with that in the timing draft */
55 
56 /*+
57  * KsmRequestKeys - Request Keys for Output
58  *
59  * Description:
60  * Updates the key times and then calls KsmRequestKeysByType to process
61  * keys of the type chosen by the keytype argument.
62  *
63  * Arguments:
64  * int keytype
65  * Key type for which the request should happen.
66  *
67  * KSM_TYPE_KSK KSKs
68  * KSM_TYPE_ZSK ZSKs
69  * Other Both KSK and ZSK
70  *
71  * int rollover
72  * 1 to force a rollover, 0 to ignore
73  *
74  * const char* datetime
75  * Time at which the request is issued. Comparisons for key
76  * expirations etc. will be against this time.
77  *
78  * KSM_REQUEST_CALLBACK callback
79  * Callback function called for every key that will be issued.
80  *
81  * void* context
82  * Context argument passed uninterpreted to the callback function.
83  *
84  * int policy_id
85  * ID of policy that we are looking at
86  *
87  * int zone_id
88  * ID of zone that we are looking at (-1 == all zones)
89  *
90  * int run_interval
91  * how frequently do we run?
92  *
93  * int* NewDS
94  * were new DS records needed?
95 -*/
96 
97 int KsmRequestKeys(int keytype, int rollover, const char* datetime,
98  KSM_REQUEST_CALLBACK callback, void* context, int policy_id, int zone_id,
99  int run_interval, int* NewDS)
100 {
101  int status; /* Status return */
102 
103  /* Start the transaction */
104  status = DbBeginTransaction();
105  if (status != 0) {
106  /* Something went wrong */
107 
109  return status;
110  }
111 
112  /* Update the estimated times of state change */
113  status = KsmUpdate(policy_id, zone_id);
114  if (status == 0) {
115 
116  /* Process all key types */
117 
118  if ((keytype == KSM_TYPE_KSK) || (keytype == KSM_TYPE_ZSK)) {
119  status = KsmRequestKeysByType(keytype, rollover, datetime,
120  callback, context, policy_id, zone_id, run_interval, NewDS);
121 
122  if (status != 0) {
123  DbRollback();
124  return status;
125  }
126  }
127  else {
128  status = KsmRequestKeysByType(KSM_TYPE_KSK, rollover, datetime,
129  callback, context, policy_id, zone_id, run_interval, NewDS);
130  if (status != 0) {
131  DbRollback();
132  return status;
133  }
134 
135  status = KsmRequestKeysByType(KSM_TYPE_ZSK, rollover, datetime,
136  callback, context, policy_id, zone_id, run_interval, NewDS);
137  if (status != 0) {
138  DbRollback();
139  return status;
140  }
141  }
142 
143  /*
144  * Finally, update the key times again, in case any keys were
145  * moved between states.
146  */
147 
148  status = KsmUpdate(policy_id, zone_id);
149  if (status != 0) {
150  DbRollback();
151  return status;
152  }
153  else
154  {
155  /* Everything worked by the looks of it */
156  DbCommit();
157  }
158  }
159  else
160  {
161  /* Whatever happened, it was not good */
162  DbRollback();
163  }
164 
165  return status;
166 }
167 
168 
169 /*+
170  * KsmRequestKeysByType - Request Keys for Output
171  *
172  * Description:
173  * Does REQUEST KEYS processing for keys of a given type.
174  *
175  * Arguments:
176  * int keytype
177  * Key type for which the request should happen.
178  *
179  * KSM_TYPE_KSK KSKs
180  * KSM_TYPE_ZSK ZSKs
181  *
182  * int rollover
183  * 1 to force a rollover, 0 to ignore
184  *
185  * const char* datetime
186  * Time to insert into database.
187  *
188  * KSM_REQUEST_CALLBACK callback
189  * Callback function called for every key that will be issued.
190  *
191  * void* context
192  * Context argument passed uninterpreted to the callback function.
193  *
194  * int policy_id
195  * ID of policy that we are looking at
196  *
197  * int zone_id
198  * ID of zone that we are looking at
199  *
200  * int run_interval
201  * how frequently do we run?
202  *
203  * int* NewDS
204  * were new DS records needed?
205  *
206  * Returns:
207  * int
208  * Status return. 0 = Success, other = error (in which case a message
209  * will have been output).
210 -*/
211 
212 int KsmRequestKeysByType(int keytype, int rollover, const char* datetime,
213  KSM_REQUEST_CALLBACK callback, void* context, int policy_id, int zone_id,
214  int run_interval, int* NewDS)
215 {
216  int active; /* Number of active keys to be retired */
217  KSM_PARCOLL collection; /* Parameters collection */
218  int ready; /* Number of keys in the "ready" state */
219  int first_pass = 0; /* Indicates if this zone has been published before */
220  int status; /* Status return */
221  char* zone_name = NULL; /* For rollover message, if needed */
222  int manual_rollover = 0; /* Flag specific to keytype */
223 
224  /* Check that we have a valid key type */
225 
226  if ((keytype != KSM_TYPE_KSK) && (keytype != KSM_TYPE_ZSK)) {
227  status = MsgLog(KME_UNKEYTYPE, keytype);
228  return status;
229  }
230 
232  (keytype == KSM_TYPE_KSK) ? "key" : "zone");
233 
234  /* Get list of parameters */
235 
236  status = KsmParameterCollection(&collection, policy_id);
237  if (status != 0) {
238  return status;
239  }
240 
241  if (keytype == KSM_TYPE_KSK) {
242  manual_rollover = collection.kskmanroll;
243  }
244  else if (keytype == KSM_TYPE_ZSK) {
245  manual_rollover = collection.zskmanroll;
246  }
247 
248  /* Check to see if this zone has been published before */
249  status = KsmRequestCheckFirstPass(keytype, &first_pass, zone_id);
250  if (status != 0) {
251  return status;
252  }
253 
254  /*
255  * Step 0: If rolling over the key, set the expected retirement date of
256  * active keys to the given date/time.
257  */
258 
259  if (rollover) {
260  status = KsmRequestSetActiveExpectedRetire(keytype, datetime, zone_id);
261  if (status != 0) {
262  return status;
263  }
264  } else {
265  /* Check for the compromised flag on the currently active key;
266  if set then force rollover to 1 (could set manual_rollover to 0)
267  NOTE: because of where this is called from we can not overwrite
268  the incoming rollover flag if set */
269  status = KsmRequestCheckCompromisedFlag(keytype, zone_id, &rollover);
270  if (status != 0) {
271  return status;
272  }
273  }
274  /*
275  * Step 0a: Complete Key rollover of standbykeys in KEYPUBLISH state
276  * if we are after their active time, move them into the active state
277  */
278  if (keytype == KSM_TYPE_KSK) {
279  status = KsmRequestChangeStateKeyPublishActive(datetime, zone_id, policy_id, NewDS);
280  if (status != 0) {
281  return status;
282  }
283 
284  if (*NewDS == 1) {
285  /* Standby Key has become active, retire the old key */
286  status = KsmRequestChangeStateActiveRetire(keytype, datetime, zone_id, policy_id);
287  if (status != 0) {
288  StrFree(zone_name);
289  return status;
290  }
291  *NewDS = 0; /* We were naughty when we used this flag, clean up */
292  /* DS set won't change until the old active key moves to dead */
293  }
294  }
295 
296 
297  /*
298  * Step 1. For each retired key, mark it as dead if it past the given
299  * time.
300  */
301 
302  status = KsmRequestChangeStateRetireDead(keytype, datetime, zone_id, policy_id, collection.kskroll, NewDS);
303  if (status != 0) {
304  return status;
305  }
306 
307  /*
308  * Step 2. For each key in the published state, set it ready if it has
309  * been in the zone long enough.
310  */
311 
312  if (keytype == KSM_TYPE_ZSK ||
313  collection.kskroll == KSM_ROLL_DNSKEY ||
314  first_pass == 1) {
315  status = KsmRequestChangeStatePublishReady(keytype, datetime, zone_id, policy_id, NewDS);
316  if (status != 0) {
317  return status;
318  }
319  }
320 
321  /*
322  * Step 2a. For each key in the dspublished state, set it dsready if it has
323  * been in the zone long enough.
324  */
325 
326  if (keytype == KSM_TYPE_KSK) {
327  status = KsmRequestChangeStateDSPublishDSReady(keytype, datetime, zone_id, policy_id);
328  if (status != 0) {
329  return status;
330  }
331  }
332 
333  /*
334  * Step 3a. make sure that we have enough standby KSKs
335  * Doing this before 3.
336  */
337 
338  if (keytype == KSM_TYPE_KSK) {
339  status = KsmRequestChangeStateGenerateDSSubConditional(keytype, datetime, &collection, zone_id, NewDS);
340 
341  /* Reset this flag; TODO is this correct? */
342  if (first_pass == 1) {
343  *NewDS = 0;
344  }
345  if (status != 0) {
346  return status;
347  }
348  }
349 
350  /*
351  * Step 3. We are within the appropriate interval of the retirement
352  * of the active key, move keys from the generate state into the
353  * publish state.
354  */
355 
356  status = KsmRequestChangeStateGeneratePublishConditional(keytype, datetime, &collection, zone_id, run_interval);
357  if (status != 0) {
358  return status;
359  }
360 
361  /*
362  * Step 4. If there is an active key and the date on which this procedure
363  * is run is earlier than the retire time of that key, exit the procedure.
364  */
365 
366  status = KsmRequestCheckActiveKey(keytype, datetime, &active, zone_id);
367  if (status != 0) {
368  return status;
369  }
370 
371  /*
372  * Step 5: Unless we are forcing a rollover, if there are some keys that
373  * will be active after the cut-off, end the modification of key states and
374  * times now. Otherwise continue.
375  *
376  * Note that we don't return if keys are active - we still need to issue
377  * the keys.
378  */
379 
380  if ((active <= 0) || (rollover)) {
381 
382  /* Get some info that we need for logging later */
383  status = KsmZoneNameFromId(zone_id, &zone_name);
384  if (status != 0) {
385  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
386  if (zone_name != NULL) {
387  StrFree(zone_name);
388  }
389  return(status);
390  }
391 
392  /*
393  * Step 6. If there are keys to be made active, count the number of keys
394  * in the "READY" state.
395  */
396 
397  status = KsmRequestCountReadyKey(keytype, datetime, &ready, zone_id);
398  if (status != 0) {
399  StrFree(zone_name);
400  return status;
401  }
402 
403  /*
404  * Step 7. We can only promote a key if there is at least one key in the
405  * READY state. Otherwise, just issue what we have.
406  */
407 
408  if (ready <= 0) {
409 
410  /*
411  * If this is the first pass for this zone. Then we can promote a key
412  * to active from published
413  * NB: A consequence of this is that these keys will have no "ready"
414  * time as they are never in the "ready" state.
415  */
416 
417  if (first_pass == 1) {
418  /* We have to wait until the KSK is ready before we can
419  * publish the DS record */
420  if (keytype == KSM_TYPE_KSK) {
421  /* status = KsmRequestChangeStateN(keytype, datetime, 1,
422  KSM_STATE_READY, KSM_STATE_ACTIVE, zone_id);*/
423  } else {
424  (void) MsgLog(KME_PROM_PUB, "ZSK");
425  status = KsmRequestChangeStateN(keytype, datetime, 1,
427  }
428 
429  if (status != 0) {
430  StrFree(zone_name);
431  return status;
432  }
433  }
434  else {
435  /* Move standby key from DSready to KEYPUBLISH if we can */
436  if (keytype == KSM_TYPE_KSK) {
437  status = KsmRequestChangeStateDSReadyKeyPublish(datetime, zone_id, policy_id);
438  if (status != 0) {
439  return status;
440  }
441  }
442 
443  (void) MsgLog(KME_NOREADYKEY, (keytype == KSM_TYPE_KSK ? "KSK" : "ZSK"), zone_name);
444  /* TODO return here? */
445  }
446  }
447  else if (manual_rollover == 1 && rollover == 0) {
448  (void) MsgLog(KME_MAN_ROLL_REQUIRED, (keytype == KSM_TYPE_KSK ? "KSK" : "ZSK"), zone_name);
449  }
450  /* TODO I think that this is no longer true... */
451  /* Check where we need this to happen */
452  else if (keytype == KSM_TYPE_KSK) {
453  /* A rollover should be occuring... For KSKs we just prompt for
454  * the user to submit their DS record
455  * TODO Include the keytag or cka-id in the message
456  * TODO Do we still need this? */
457  (void) MsgLog(KME_DS_SUBMISSION, zone_name);
458  }
459  else {
460 
461  /* Step 8. Make a key active. */
462  status = KsmRequestChangeStateReadyActive(keytype, datetime, 1, zone_id);
463  /*
464  * If we didn't complete due to non-backed up keys then skip the
465  * retire step; otherwise carry on.
466  */
467  if (status != KME_BACK_FATAL) {
468  if (status != 0) {
469  StrFree(zone_name);
470  return status;
471  }
472 
473  /* Step 9. ... and retire old active keys */
474  status = KsmRequestChangeStateActiveRetire(keytype, datetime, zone_id, policy_id);
475  if (status != 0) {
476  StrFree(zone_name);
477  return status;
478  }
479 
480  /* Log that a rollover has happened */
481  (void) MsgLog(KME_ROLL_ZONE, (keytype == KSM_TYPE_KSK ? "KSK" : "ZSK"), zone_name);
482  }
483  }
484  StrFree(zone_name);
485  }
486 
487  /* Step 10. Issue the keys */
488 
489  status = KsmRequestIssueKeys(keytype, callback, context, zone_id);
490 
491  return status;
492 }
493 
494 
495 
496 /*+
497  * KsmRequestSetActiveExpectedRetire - Set Expected Retire Date
498  *
499  * Description:
500  * Sets the expected retire date for active keys to the date specified.
501  * Note that this does change not the state from active - it only changes
502  * the expected retire date.
503  *
504  * Arguments:
505  * int keytype
506  * Type of keys being changed.
507  *
508  * const char* datetime
509  * Date/time for which the calculation is being done. This can be
510  * the string "NOW()".
511  *
512  * int zone_id
513  * Zone we are looking at (-1 == all zones)
514  *
515  * Returns:
516  * int
517  * Status return. 0 => success, Other => failure, in which case an
518  * error message will have been output.
519 -*/
520 
521 int KsmRequestSetActiveExpectedRetire(int keytype, const char* datetime, int zone_id)
522 {
523  int count = 0; /* Count of keys whose date will be set */
524  char* sql = NULL; /* For creating the SQL command */
525  int status = 0; /* Status return */
526  int where = 0; /* For the SQL selection */
527  int i = 0; /* A counter */
528  int j = 0; /* Another counter */
529  char* insql = NULL; /* SQL "IN" clause */
530  int* keyids; /* List of IDs of keys to promote */
531  DB_RESULT result; /* List result set */
532  KSM_KEYDATA data; /* Data for this key */
533  char buffer[32]; /* For integer conversion */
534 
535  /* Count how many keys will have the retire date set */
536 
537  sql = DqsCountInit("KEYDATA_VIEW");
538  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, where++);
539  DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, KSM_STATE_ACTIVE, where++);
540  if (zone_id != -1) {
541  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, where++);
542  }
543  DqsEnd(&sql);
544 
545  status = DbIntQuery(DbHandle(), &count, sql);
546  DqsFree(sql);
547 
548  if (status != 0) {
549  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
550  return status;
551  }
552 
553  if (count == 0) {
554  /* Nothing to do NO ACTIVE KEYS! */
555  return status;
556  }
557 
558  /* Allocate space for the list of key IDs */
559  keyids = MemMalloc(count * sizeof(int));
560 
561  /* Get the list of IDs */
562 
563  where = 0;
564  sql = DqsSpecifyInit("KEYDATA_VIEW", DB_KEYDATA_FIELDS);
565  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, where++);
566  DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, KSM_STATE_ACTIVE, where++);
567  if (zone_id != -1) {
568  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, where++);
569  }
570  DqsEnd(&sql);
571 
572  status = KsmKeyInitSql(&result, sql);
573  DqsFree(sql);
574 
575  if (status == 0) {
576  while (status == 0) {
577  status = KsmKey(result, &data);
578  if (status == 0) {
579  keyids[i] = data.keypair_id;
580  i++;
581  }
582  }
583 
584  /* Convert EOF status to success */
585 
586  if (status == -1) {
587  status = 0;
588  } else {
589  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
590  StrFree(keyids);
591  return status;
592  }
593 
594  KsmKeyEnd(result);
595 
596  } else {
597  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
598  StrFree(keyids);
599  return status;
600  }
601 
602  /*
603  * Now construct the "IN" statement listing the IDs of the keys we
604  * are planning to change the state of.
605  */
606 
607  StrAppend(&insql, "(");
608  for (j = 0; j < i; ++j) {
609  if (j != 0) {
610  StrAppend(&insql, ",");
611  }
612  snprintf(buffer, sizeof(buffer), "%d", keyids[j]);
613  StrAppend(&insql, buffer);
614  }
615  StrAppend(&insql, ")");
616 
617  /*
618  * Update the keys. This is done after a status check, as the debug
619  * code may have hit a database error, in which case we won't query the
620  * database again. ("status" is initialized to success in case the debug
621  * code is not executed.)
622  */
623 
624  sql = DusInit("keypairs");
625  DusSetInt(&sql, "fixedDate", 1, 0);
626  DusSetInt(&sql, "compromisedflag", 1, 1);
627 
628  DusConditionKeyword(&sql, "ID", DQS_COMPARE_IN, insql, 0);
629  DusEnd(&sql);
630 
631  status = DbExecuteSqlNoResult(DbHandle(), sql);
632  DusFree(sql);
633 
634  /* Report any errors */
635  if (status != 0) {
636  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
637  }
638 
639  sql = DusInit("dnsseckeys");
640  DusSetString(&sql, "RETIRE", datetime, 0);
641 
642  DusConditionKeyword(&sql, "KEYPAIR_ID", DQS_COMPARE_IN, insql, 0);
643  /* NO ZONE_ID !!! We want to retire ALL instances of this key */
644  StrFree(insql);
645  DusEnd(&sql);
646 
647  status = DbExecuteSqlNoResult(DbHandle(), sql);
648  DusFree(sql);
649 
650  /* Report any errors */
651  if (status != 0) {
652  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
653  }
654 
655  StrFree(keyids);
656 
657  return status;
658 }
659 
660 
661 
662 /*+
663  * KsmRequestChangeStatePublishReady - Change State from PUBLISH to READY
664  * KsmRequestChangeStateActiveRetire - Change State from ACTIVE to RETIRE
665  * KsmRequestChangeStateRetireDead - Change State from RETIRE to DEAD
666  *
667  * Description:
668  * Changes the state of keys of a particular type in the given zone
669  * between two states.
670  *
671  * Arguments:
672  * int keytype
673  * Type of keys being changed.
674  *
675  * const char* datetime
676  * Date/time for which the calculation is being done. This ancan be
677  * the string "NOW()".
678  *
679  * int zone_id
680  * ID of zone that we are looking at (-1 == all zones)
681  *
682  * Returns:
683  * int
684  * Status return. 0 => success, Other => failure, in which case an
685  * error message will have been output.
686 -*/
687 
688 int KsmRequestChangeStatePublishReady(int keytype, const char* datetime, int zone_id, int policy_id, int* NewDS)
689 {
690  return KsmRequestChangeState(keytype, datetime,
691  KSM_STATE_PUBLISH, KSM_STATE_READY, zone_id, policy_id, -1, NewDS);
692 }
693 
694 int KsmRequestChangeStateDSPublishDSReady(int keytype, const char* datetime, int zone_id, int policy_id)
695 {
696  int* dummy = NULL;
697  return KsmRequestChangeState(keytype, datetime,
698  KSM_STATE_DSPUBLISH, KSM_STATE_DSREADY, zone_id, policy_id, -1, dummy);
699 }
700 
701 int KsmRequestChangeStateDSReadyKeyPublish(const char* datetime, int zone_id, int policy_id)
702 {
703  int* dummy = NULL;
704  return KsmRequestChangeState(KSM_TYPE_KSK, datetime,
705  KSM_STATE_DSREADY, KSM_STATE_KEYPUBLISH, zone_id, policy_id, -1, dummy);
706 }
707 
708 int KsmRequestChangeStateKeyPublishActive(const char* datetime, int zone_id, int policy_id, int* NewDS)
709 {
710  return KsmRequestChangeState(KSM_TYPE_KSK, datetime,
711  KSM_STATE_KEYPUBLISH, KSM_STATE_ACTIVE, zone_id, policy_id, -1, NewDS);
712 }
713 
714 int KsmRequestChangeStateActiveRetire(int keytype, const char* datetime, int zone_id, int policy_id)
715 {
716  int* dummy = NULL;
717  return KsmRequestChangeState(keytype, datetime,
718  KSM_STATE_ACTIVE, KSM_STATE_RETIRE, zone_id, policy_id, -1, dummy);
719 }
720 
721 int KsmRequestChangeStateRetireDead(int keytype, const char* datetime, int zone_id, int policy_id, int rollover_scheme, int* NewDS)
722 {
723  return KsmRequestChangeState(keytype, datetime,
724  KSM_STATE_RETIRE, KSM_STATE_DEAD, zone_id, policy_id, rollover_scheme, NewDS);
725 }
726 
727 
728 
729 /*+
730  * KsmRequestChangeState - Change State of a Key
731  *
732  * Description:
733  * Changes the state of a key between two states if the estimated time of
734  * entering the target state is equal to or earlier than the given time.
735  * The time of entering the state is updated to the given time as well.
736  *
737  * Arguments:
738  * int keytype
739  * Type of keys being changed.
740  *
741  * const char* datetime
742  * Date/time for which the calculation is being done. This can be
743  * the string "NOW()".
744  *
745  * int src_state
746  * ID of the state that the key is moving from.
747  *
748  * int dst_state
749  * ID of the state that the key is moving to.
750  *
751  * int zone_id
752  * ID of zone that we are looking at (-1 == all zones)
753  *
754  * int policy_id
755  * ID of the policy that we are looking at
756  *
757  * int rollover_scheme
758  * what KSK rollover scheme are we using
759  *
760  * Returns:
761  * int
762  * Status return. 0 => success, Other => failure, in which case an
763  * error message will have been output.
764 -*/
765 
766 int KsmRequestChangeState(int keytype, const char* datetime,
767  int src_state, int dst_state, int zone_id, int policy_id,
768  int rollover_scheme, int* NewDS)
769 {
770  int where = 0; /* for the SELECT statement */
771  char* dst_col = NULL; /* Destination column */
772  int set = 0; /* For UPDATE */
773  char* sql = NULL; /* SQL statement (when verifying) */
774  int status = 0; /* Status return */
775  int count = 0; /* How many keys fit our select? */
776  int i = 0; /* A counter */
777  int j = 0; /* Another counter */
778  char* insql = NULL; /* SQL "IN" clause */
779  int* keyids; /* List of IDs of keys to promote */
780  DB_RESULT result; /* List result set */
781  KSM_KEYDATA data; /* Data for this key */
782  char buffer[32]; /* For integer conversion */
783  char* zone_name = NULL; /* For DS removal message, if needed */
784 
785  /* Unused parameter */
786  (void)policy_id;
787 
788  /* Create the destination column name */
789  if (dst_state == KSM_STATE_DSREADY) {
791  } else if (dst_state == KSM_STATE_KEYPUBLISH) {
793  } else {
794  dst_col = StrStrdup(KsmKeywordStateValueToName(dst_state));
795  }
796  (void) StrToUpper(dst_col);
797 
798  /* First up we need to count how many keys will move */
799  sql = DqsCountInit("KEYDATA_VIEW");
800  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, where++);
801  DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, src_state, where++);
802  if (zone_id != -1) {
803  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, where++);
804  }
805  DqsConditionString(&sql, dst_col, DQS_COMPARE_LE, datetime, where++);
806  DqsEnd(&sql);
807 
808  status = DbIntQuery(DbHandle(), &count, sql);
809  DqsFree(sql);
810 
811  if (status != 0) {
812  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
813  StrFree(dst_col);
814  return status;
815  }
816 
817  if (count == 0) {
818  /* Nothing to do */
819  StrFree(dst_col);
820  return status;
821  }
822 
823  /* Allocate space for the list of key IDs */
824  keyids = MemMalloc(count * sizeof(int));
825 
826  /* Get the list of IDs */
827 
828  where = 0;
829  sql = DqsSpecifyInit("KEYDATA_VIEW", DB_KEYDATA_FIELDS);
830  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, where++);
831  DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, src_state, where++);
832  if (zone_id != -1) {
833  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, where++);
834  }
835  DqsConditionString(&sql, dst_col, DQS_COMPARE_LE, datetime, where++);
836  DqsEnd(&sql);
837 
838  status = KsmKeyInitSql(&result, sql);
839  DqsFree(sql);
840 
841  if (status == 0) {
842  while (status == 0) {
843  status = KsmKey(result, &data);
844  if (status == 0) {
845  keyids[i] = data.keypair_id;
846  i++;
847  }
848  }
849 
850  /* Convert EOF status to success */
851 
852  if (status == -1) {
853  status = 0;
854  } else {
855  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
856  StrFree(dst_col);
857  StrFree(keyids);
858  return status;
859  }
860 
861  KsmKeyEnd(result);
862 
863  } else {
864  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
865  StrFree(dst_col);
866  StrFree(keyids);
867  return status;
868  }
869 
870  /* Notify progress if debugging */
871 
873  KsmKeywordStateValueToName(src_state),
874  KsmKeywordStateValueToName(dst_state));
875 
876  /*
877  * Now construct the "IN" statement listing the IDs of the keys we
878  * are planning to change the state of.
879  */
880 
881  StrAppend(&insql, "(");
882  for (j = 0; j < i; ++j) {
883  if (j != 0) {
884  StrAppend(&insql, ",");
885  }
886  snprintf(buffer, sizeof(buffer), "%d", keyids[j]);
887  StrAppend(&insql, buffer);
888  }
889  StrAppend(&insql, ")");
890 
891  StrFree(keyids);
892 
893  /*
894  * Update the keys. This is done after a status check, as the debug
895  * code may have hit a database error, in which case we won't query the
896  * database again. ("status" is initialized to success in case the debug
897  * code is not executed.)
898  */
899 
900  sql = DusInit("dnsseckeys");
901  DusSetInt(&sql, "STATE", dst_state, set++);
902  DusSetString(&sql, dst_col, datetime, set++);
903 
904  DusConditionKeyword(&sql, "KEYPAIR_ID", DQS_COMPARE_IN, insql, 0);
905  DusConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, 1);
906  DusEnd(&sql);
907  StrFree(dst_col);
908 
909  status = DbExecuteSqlNoResult(DbHandle(), sql);
910  DusFree(sql);
911 
912  /* Report any errors */
913  if (status != 0) {
914  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
915  }
916 
917  /* See if we need to log a message about the DS records */
918  if (keytype == KSM_TYPE_KSK && ((dst_state == KSM_STATE_DEAD && rollover_scheme == KSM_ROLL_DS) || dst_state == KSM_STATE_READY))
919  {
920  /* Set our flag */
921  *NewDS = 1;
922 
923  /* Get common info we need for either message */
924  status = KsmZoneNameFromId(zone_id, &zone_name);
925  if (status != 0) {
926  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
927  if (zone_name != NULL) {
928  StrFree(insql);
929  StrFree(zone_name);
930  }
931  return(status);
932  }
933 
934  /* If we moved a KSK from retire to dead then the DS can be removed */
935  if (dst_state == KSM_STATE_DEAD && rollover_scheme == KSM_ROLL_DS) {
936  (void) MsgLog(KME_DS_REM_ZONE, zone_name);
937  }
938  else if (dst_state == KSM_STATE_READY) {
939  (void) MsgLog(KME_NEW_DS, zone_name);
940 
941  }
942  }
943  else if (keytype == KSM_TYPE_KSK && src_state == KSM_STATE_KEYPUBLISH) {
944  /* Set our flag, we are completing an emergency rollover */
945  *NewDS = 1;
946  }
947 
948  StrFree(insql);
949  StrFree(zone_name);
950 
951  return status;
952 }
953 
954 
955 
956 /*+
957  * KsmRequestChangeStateGeneratePublish - Change State from GENERATE to PUBLISH
958  * KsmRequestChangeStateGenerateDSPublish - Change State from GENERATE to DSPUBLISH
959  * KsmRequestChangeStateReadyActive - Change State from READY to ACTIVE
960  *
961  * Description:
962  * Changes the state of a number of keys from one state to another.
963  *
964  * Arguments:
965  * int keytype
966  * Type of keys being changed.
967  *
968  * const char* datetime
969  * Date/time for which this request is being made.
970  *
971  * int count
972  * Number of keys to be promoted to the publish state. There is no
973  * check as to whether that number of keys are available in the
974  * GENERATE state - it is assumed that that check has already been
975  * carried out.
976  *
977  * int zone_id
978  * ID of zone that we are looking at (-1 == all zones)
979  *
980  * Returns:
981  * int
982  * Status return. 0 => success, Other => failure, in which case an
983  * error message will have been output.
984 -*/
985 
986 int KsmRequestChangeStateGeneratePublish(int keytype, const char* datetime,
987  int count, int zone_id)
988 {
989  return KsmRequestChangeStateN(keytype, datetime, count,
991 }
992 
993 int KsmRequestChangeStateGenerateDSSub(int keytype, const char* datetime,
994  int count, int zone_id)
995 {
996  return KsmRequestChangeStateN(keytype, datetime, count,
998 }
999 
1000 int KsmRequestChangeStateReadyActive(int keytype, const char* datetime,
1001  int count, int zone_id)
1002 {
1003  return KsmRequestChangeStateN(keytype, datetime, count,
1004  KSM_STATE_READY, KSM_STATE_ACTIVE, zone_id);
1005 }
1006 
1007 
1008 /*+
1009  * KsmRequestChangeStateN - Change State of N Keys
1010  *
1011  * Description:
1012  * Changes the state of a given number of keys from one state to another.
1013  *
1014  * Arguments:
1015  * int keytype
1016  * Type of keys being changed.
1017  *
1018  * const char* datetime
1019  * Date/time for which this request is being made.
1020  *
1021  * int count
1022  * Number of keys to be promoted to the destination state. There is no
1023  * check as to whether that number of keys are available in the
1024  * state - it is assumed that that check has already been carried out.
1025  *
1026  * int src_state
1027  * State from which keys are being prompted.
1028  *
1029  * int dst_state
1030  * State to which keys are being promoted.
1031  *
1032  * int zone_id
1033  * ID of zone that we are looking at (-1 == all zones)
1034  *
1035  * Returns:
1036  * int
1037  * Status return. 0 => success, Other => failure, in which case an
1038  * error message will have been output.
1039 -*/
1040 
1041 int KsmRequestChangeStateN(int keytype, const char* datetime, int count,
1042  int src_state, int dst_state, int zone_id)
1043 {
1044  char buffer[32]; /* For integer conversion */
1045  DQS_QUERY_CONDITION condition[4]; /* Condition codes */
1046  KSM_KEYDATA data; /* Data for this key */
1047  char* dst_name = NULL; /* Dest state name uppercase */
1048  DB_RESULT result; /* List result set */
1049  int i; /* Loop counter */
1050  char* insql = NULL; /* SQL "IN" clause */
1051  int* keyids; /* List of IDs of keys to promote */
1052  int setclause = 0; /* For the "SET" clauses */
1053  char* sql1 = NULL; /* SQL statement */
1054  char* sql2 = NULL; /* SQL statement */
1055  char* sql3 = NULL; /* SQL statement */
1056  int status; /* Status return */
1057  int whereclause = 0; /* For the "WHERE" clauses */
1058  int count1 = 0; /* No. of non-backed up keys */
1059  int count2 = 0; /* No. of non-backed up keys which should be */
1060 
1061  /* Just checking */
1062  if (count <= 0) {
1063  status = MsgLog(KSM_INVARG, "Asked to move 0 keys");
1064  return status;
1065  }
1066 
1067  /* Notify progress if debugging */
1068 
1070  KsmKeywordStateValueToName(src_state),
1071  KsmKeywordStateValueToName(dst_state));
1072 
1073  /* Allocate space for the list of key IDs */
1074  keyids = MemMalloc(count * sizeof(int));
1075 
1076  /* Get the list of IDs */
1077 
1078  condition[0].code = DB_KEYDATA_KEYTYPE;
1079  condition[0].data.number = keytype;
1080  condition[0].compare = DQS_COMPARE_EQ;
1081 
1082  condition[1].code = DB_KEYDATA_STATE;
1083  condition[1].data.number = src_state;
1084  condition[1].compare = DQS_COMPARE_EQ;
1085 
1086  condition[2].compare = DQS_END_OF_LIST;
1087 
1088  if (zone_id != -1) {
1089  condition[2].code = DB_KEYDATA_ZONE_ID;
1090  condition[2].data.number = zone_id;
1091  condition[2].compare = DQS_COMPARE_EQ;
1092 
1093  condition[3].compare = DQS_END_OF_LIST;
1094  }
1095 
1096 
1097  status = KsmKeyInit(&result, condition);
1098  for (i = 0; ((i < count) && (status == 0)); ++i) {
1099  status = KsmKey(result, &data);
1100  if (status == 0) {
1101  keyids[i] = data.keypair_id;
1102  }
1103  }
1104  KsmKeyEnd(result);
1105 
1106  /* Did we get everything? */
1107 
1108  if (status == 0) {
1109 
1110  /*
1111  * Yes: construct the "IN" statement listing the IDs of the keys we
1112  * are planning to change the state of.
1113  */
1114 
1115  StrAppend(&insql, "(");
1116  for (i = 0; i < count; ++i) {
1117  if (i != 0) {
1118  StrAppend(&insql, ",");
1119  }
1120  snprintf(buffer, sizeof(buffer), "%d", keyids[i]);
1121  StrAppend(&insql, buffer);
1122  }
1123  StrAppend(&insql, ")");
1124 
1125  /* Get upper case names of the states (= names of date columns) */
1126 
1127  if (dst_state == KSM_STATE_DSSUB) {
1128  StrAppend(&dst_name, KSM_STATE_PUBLISH_STRING);
1129  } else {
1130  dst_name = StrStrdup(KsmKeywordStateValueToName(dst_state));
1131  }
1132  (void) StrToUpper(dst_name);
1133 
1134  if (dst_state == KSM_STATE_ACTIVE) {
1135  /*
1136  * We are making the key(s) active so check the backedupness of these keys,
1137  * and compare with the requirebackup flag on their repository
1138  */
1139  /*
1140  * First see if we have any which are not backed up
1141  */
1142  StrAppend(&sql1, "select count(*) from keypairs where id in ");
1143  StrAppend(&sql1, insql);
1144  StrAppend(&sql1, " and backup is null");
1145 
1146  status = DbIntQuery(DbHandle(), &count1, sql1);
1147  DqsFree(sql1);
1148 
1149  if (status != 0)
1150  {
1151  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
1152  StrFree(insql);
1153  MemFree(keyids);
1154  StrFree(dst_name);
1155  return status;
1156  }
1157 
1158  if (count1 != 0) {
1159  /*
1160  * See if any of these are supposed to be backed up
1161  */
1162 
1163  StrAppend(&sql2, "select count(*) from keypairs k, securitymodules s where s.id = k.securitymodule_id and k.id in ");
1164  StrAppend(&sql2, insql);
1165  StrAppend(&sql2, " and k.backup is null and s.requirebackup = 1");
1166 
1167  status = DbIntQuery(DbHandle(), &count2, sql2);
1168  DqsFree(sql2);
1169 
1170  if (status != 0)
1171  {
1172  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
1173  StrFree(insql);
1174  MemFree(keyids);
1175  StrFree(dst_name);
1176  return status;
1177  }
1178 
1179  if (count2 != 0) {
1180  /*
1181  * This is bad; log an error and return
1182  */
1183  status = MsgLog(KME_BACK_FATAL, (keytype == KSM_TYPE_KSK) ? "KSK" : "ZSK");
1184  StrFree(insql);
1185  MemFree(keyids);
1186  StrFree(dst_name);
1187  return status;
1188  }
1189 
1190  /*
1191  * We allow this, but with a strong warning
1192  */
1193  (void) MsgLog(KME_BACK_NON_FATAL, (keytype == KSM_TYPE_KSK) ? "KSK" : "ZSK");
1194  }
1195  }
1196 
1197  /*
1198  * Now construct the "UPDATE" statement and execute it. This relies on
1199  * the fact that the name of the state is the same as the name of
1200  * the column in KEYDATA holding the date at which the key moved to
1201  * that state.
1202  */
1203 
1204  sql3 = DusInit("dnsseckeys");
1205  DusSetInt(&sql3, "STATE", dst_state, setclause++);
1206  DusSetString(&sql3, dst_name, datetime, setclause++);
1207  StrFree(dst_name);
1208 
1209  DusConditionKeyword(&sql3, "KEYPAIR_ID", DQS_COMPARE_IN, insql, whereclause++);
1210  DusConditionInt(&sql3, "ZONE_ID", DQS_COMPARE_EQ, zone_id, whereclause++);
1211  StrFree(insql);
1212  DusEnd(&sql3);
1213 
1214  status = DbExecuteSqlNoResult(DbHandle(), sql3);
1215  DusFree(sql3);
1216 
1217  /* Report any errors */
1218 
1219  if (status != 0) {
1220  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
1221  }
1222  }
1223 
1224  /* Free up resources */
1225 
1226  MemFree(keyids);
1227 
1228  return status;
1229 }
1230 
1231 /*+
1232  * KsmRequestChangeStateGenerateDSSubConditional -
1233  * Change State from Generate to DSSub
1234  *
1235  * Description:
1236  * Make sure that the zone has the correct number of standby keys.
1237  *
1238  * Arguments:
1239  * int keytype
1240  * Key type for which the request should happen.
1241  *
1242  * KSM_TYPE_KSK KSKs
1243  * KSM_TYPE_ZSK ZSKs
1244  *
1245  * const char* datetime
1246  * Date/time for which this request is taking place.
1247  *
1248  * KSM_PARCOLL* collection
1249  * Pointer to parameter collection for this zone.
1250  *
1251  * int zone_id
1252  * ID of zone that we are looking at (-1 == all zones)
1253  *
1254  * Returns:
1255  * int
1256  * Status return. 0 => success, Other => failure, in which case an
1257  * error message will have been output.
1258 -*/
1259 
1261  const char* datetime, KSM_PARCOLL* collection, int zone_id, int* NewDS)
1262 {
1263  int gencnt; /* Number of keys in generate state */
1264  int newkeys; /* New keys required */
1265  int standby; /* Number of standby keys */
1266  int reqkeys; /* Number of keys required */
1267  int status; /* Status return */
1268 
1269  /* How many standby keys we have */
1270  status = KsmRequestStandbyKSKCount(&standby, zone_id);
1271  if (status != 0) {
1272  return status;
1273  }
1274 
1275  reqkeys = KsmParameterStandbyKSKeys(collection);
1276 
1277  /*
1278  * So, if we remove "pendret" keys from the number of "available"
1279  * keys, how many are we short of the required number? This is how many
1280  * we need to promote from "generate" to "publish"
1281  */
1282 
1283  newkeys = reqkeys - standby;
1284 
1285  if (newkeys > 0) {
1286 
1287  /* Are there enough generated keys available */
1288 
1289  status = KsmRequestGenerateCount(keytype, &gencnt, zone_id);
1290  if (status == 0) {
1291  if (gencnt < newkeys) {
1292  status = MsgLog(KME_INSFGENKEY, gencnt,
1293  KsmKeywordTypeValueToName(keytype), newkeys);
1294  }
1296  KsmKeywordTypeValueToName(keytype));
1297 
1298  if (status == 0) {
1299 
1300  /* There are enough keys, so move them to "dssub" state */
1301 
1302  status = KsmRequestChangeStateGenerateDSSub(keytype,
1303  datetime, newkeys, zone_id);
1304 
1305  /* Set our flag */
1306  *NewDS = 1;
1307  }
1308  }
1309  }
1310 
1311  return 0;
1312 }
1313 
1314 /*+
1315  * KsmRequestChangeStateGeneratePublishConditional -
1316  * Change State from Generate to Pubish
1317  *
1318  * Description:
1319  * Unlike the other "Change State" functions, this is conditional. It
1320  * promotes keys in the "Generate" state to the "Publish" state to maintain
1321  * the required number of keys active/standby keys when the active keys
1322  * are retired.
1323  *
1324  * a) For the given time, work out how many "active" keys have a retire
1325  * date within this time + "publication interval". Call this number
1326  * Npr (Number pending retirement).
1327  *
1328  * This should be 1 or 0, as there is an assumption that there is only
1329  * ever one active key.
1330  *
1331  * b) Work out how many keys are in the active, publish and ready states.
1332  * Call this Nt (Number total).
1333  *
1334  * c) Now look at the difference (Nt - Npr). This is the number of keys
1335  * that will be (potentially) usable after the active key retires.
1336  * If this number is less than (1 + Ne) (where Ne is the number of
1337  * standby keys), move the difference from the generated state into
1338  * the published state.
1339  *
1340  * Arguments:
1341  * int keytype
1342  * Key type for which the request should happen.
1343  *
1344  * KSM_TYPE_KSK KSKs
1345  * KSM_TYPE_ZSK ZSKs
1346  *
1347  * const char* datetime
1348  * Date/time for which this request is taking place.
1349  *
1350  * KSM_PARCOLL* collection
1351  * Pointer to parameter collection for this zone.
1352  *
1353  * int zone_id
1354  * ID of zone that we are looking at (-1 == all zones)
1355  *
1356  * int run_interval
1357  * how frequently do we run?
1358  *
1359  * Returns:
1360  * int
1361  * Status return. 0 => success, Other => failure, in which case an
1362  * error message will have been output.
1363 -*/
1364 
1366  const char* datetime, KSM_PARCOLL* collection, int zone_id, int run_interval)
1367 {
1368  int availkeys; /* Number of availkeys keys */
1369  int gencnt; /* Number of keys in generate state */
1370  int newkeys; /* New keys required */
1371  int pendret; /* Number of keys that will be retired */
1372  int reqkeys; /* Number of keys required */
1373  int status; /* Status return */
1374 
1375  /* How many active keys will be retired in the immediate future */
1376  status = KsmRequestPendingRetireCount(keytype, datetime, collection,
1377  &pendret, zone_id, run_interval);
1378  if (status != 0) {
1379  return status;
1380  }
1381  DbgLog(DBG_M_REQUEST, KME_RETIRECNT, pendret);
1382 
1383  /* How many available keys are there */
1384 
1385  status = KsmRequestAvailableCount(keytype, datetime, collection,
1386  &availkeys, zone_id);
1387  if (status != 0) {
1388  return status;
1389  }
1390  DbgLog(DBG_M_REQUEST, KME_AVAILCNT, availkeys);
1391 
1392  /*
1393  * We need at least one active key and "number of standby keys" ready
1394  * keys at any one time.
1395  */
1396 
1397  if (keytype == KSM_TYPE_KSK) {
1398  /* For KSKs we sort out standby keys separately */
1399  reqkeys = 1; /*+ KsmParameterStandbyKSKeys(collection);*/
1400  }
1401  else if (keytype == KSM_TYPE_ZSK) {
1402  reqkeys = 1 + KsmParameterStandbyZSKeys(collection);
1403  }
1404  else {
1405  /* should not get here */
1406  return -1;
1407  }
1408 
1409  /*
1410  * So, if we remove "pendret" keys from the number of "available"
1411  * keys, how many are we short of the required number? This is how many
1412  * we need to promote from "generate" to "publish"
1413  */
1414 
1415  newkeys = reqkeys - (availkeys - pendret);
1416  /* fprintf(stderr, "%s: keytype(%d): newkeys(%d) = reqkeys(%d) - (availkeys(%d) - pendret(%d))\n", datetime, keytype, newkeys, reqkeys, availkeys, pendret); */
1417  DbgLog(DBG_M_REQUEST, KME_KEYCNTSUMM, reqkeys, newkeys);
1418 
1419  if (newkeys > 0) {
1420 
1421  /* Are there enough generated keys available */
1422 
1423  status = KsmRequestGenerateCount(keytype, &gencnt, zone_id);
1424  if (status == 0) {
1425  if (gencnt < newkeys) {
1426  status = MsgLog(KME_INSFGENKEY, gencnt,
1427  KsmKeywordTypeValueToName(keytype), newkeys);
1428  }
1430  KsmKeywordTypeValueToName(keytype));
1431 
1432  if (status == 0) {
1433 
1434  /* There are enough keys, so move them to "publish" state */
1435 
1436  status = KsmRequestChangeStateGeneratePublish(keytype,
1437  datetime, newkeys, zone_id);
1438  }
1439  }
1440  }
1441 
1442  return 0;
1443 }
1444 
1445 
1446 
1447 /*+
1448  * KsmRequestPendingRetireCount - Get Count of Keys Pending Retirement
1449  *
1450  * Description:
1451  * For the given time, works out how many "active" keys have a retire
1452  * date within this time + "publication interval".
1453  *
1454  * This should be 1 or 0, as there is an assumption that there is only
1455  * ever one active key.
1456  *
1457  * Arguments:
1458  * int keytype
1459  * Key type for which the request should happen.
1460  *
1461  * KSM_TYPE_KSK KSKs
1462  * KSM_TYPE_ZSK ZSKs
1463  *
1464  * const char* datetime
1465  * Date/time for which this request is taking place.
1466  *
1467  * KSM_PARCOLL* parameters
1468  * Parameters associated with this zone.
1469  *
1470  * int* count (returned)
1471  * Number of active keys that will retire within that period.
1472  *
1473  * int zone_id
1474  * ID of zone that we are looking at (-1 == all zones)
1475  *
1476  * Returns:
1477  * int
1478  * Status return. 0 => success, <>0 => error, in which case a message
1479  * will have been output.
1480 -*/
1481 
1482 int KsmRequestPendingRetireCount(int keytype, const char* datetime,
1483  KSM_PARCOLL* parameters, int* count, int zone_id, int interval)
1484 {
1485  char buffer[256]; /* For constructing part of the command */
1486  int clause = 0; /* Used in constructing SQL statement */
1487  size_t nchar; /* Number of characters written */
1488  char* sql; /* SQL command to be isssued */
1489  int status; /* Status return */
1490  int total_interval; /* The PublicationInterval + interval (when we will run again) */
1491 
1492  if (keytype == KSM_TYPE_ZSK)
1493  {
1494  total_interval = KsmParameterZskTtl(parameters) +
1495  KsmParameterPropagationDelay(parameters) +
1496  KsmParameterPubSafety(parameters) +
1497  interval;
1498  } else {
1499  total_interval = KsmParameterKskTtl(parameters) +
1500  KsmParameterKskPropagationDelay(parameters) +
1501  KsmParameterPubSafety(parameters) +
1502  interval;
1503  /*
1504  if (DOUBLEDNSKEY) {
1505  total_interval = KsmParameterKskTtl(parameters) +
1506  KsmParameterPropagationDelay(parameters) +
1507  KsmParameterDSTtl(parameters) +
1508  KsmParameterKskPropagationDelay(parameters) +
1509  KsmParameterPubSafety(parameters) +
1510  interval;
1511  }
1512  if (DOUBLEDS) {
1513  total_interval = KsmParameterDSTtl(parameters) +
1514  KsmParameterKskPropagationDelay(parameters) +
1515  KsmParameterPubSafety(parameters) +
1516  interval;
1517  }
1518  if (DOUBLERRSET) {
1519  temp = MAX(
1520  (KsmParameterKskTtl(parameters) + KsmParameterPropagationDelay(parameters)),
1521  (KsmParameterDSTtl(parameters) + KsmParameterKskPropagationDelay(parameters)));
1522  if (RFC5011) {
1523  temp = max(temp, 30*24*60*60);
1524  }
1525  total_interval = temp + KsmParameterPubSafety(parameters) +
1526  interval;
1527  }
1528  */
1529  }
1530  /* Create the SQL command to interrogate the database */
1531 
1532  sql = DqsCountInit("KEYDATA_VIEW");
1533  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
1534  DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, KSM_STATE_ACTIVE, clause++);
1535  if (zone_id != -1) {
1536  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
1537  }
1538 
1539  /* Calculate the initial publication interval & add to query */
1540 
1541  /*
1542  * TODO is there an alternative to DATE_ADD which is more generic?
1543  */
1544 #ifdef USE_MYSQL
1545  nchar = snprintf(buffer, sizeof(buffer),
1546  "DATE_ADD('%s', INTERVAL %d SECOND)",
1547  datetime, total_interval);
1548 #else
1549  nchar = snprintf(buffer, sizeof(buffer),
1550  "DATETIME('%s', '+%d SECONDS')",
1551  datetime, total_interval);
1552 #endif /* USE_MYSQL */
1553  if (nchar >= sizeof(buffer)) {
1554  status = MsgLog(KME_BUFFEROVF, "KsmRequestKeys");
1555  DqsFree(sql);
1556  return status;
1557  }
1558 
1559 #ifdef USE_MYSQL
1560  DqsConditionKeyword(&sql, "RETIRE", DQS_COMPARE_LE, buffer, clause++);
1561 #else
1562  DqsConditionKeyword(&sql, "DATETIME(RETIRE)", DQS_COMPARE_LE, buffer, clause++);
1563 #endif /* USE_MYSQL */
1564 
1565  DqsEnd(&sql);
1566 
1567  /* Execute the query and free resources */
1568 
1569  status = DbIntQuery(DbHandle(), count, sql);
1570  DqsFree(sql);
1571 
1572  /* Report any errors */
1573 
1574  if (status != 0) {
1575  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
1576  }
1577 
1578  return status;
1579 }
1580 
1581 
1582 
1583 /*+
1584  * KsmRequestAvailableCount - Get Count of Available Keys
1585  *
1586  * Description:
1587  * By "available", is the number of keys in the "published", "ready"
1588  * and "active" state.
1589  *
1590  * Arguments:
1591  * int keytype
1592  * Key type for which the request should happen.
1593  *
1594  * KSM_TYPE_KSK KSKs
1595  * KSM_TYPE_ZSK ZSKs
1596  *
1597  * const char* datetime
1598  * Date/time for which this request is taking place.
1599  *
1600  * KSM_PARCOLL* parameters
1601  * Parameters associated with this zone.
1602  *
1603  * int* count (returned)
1604  * Number of available keys.
1605  *
1606  * int zone_id
1607  * ID of zone that we are looking at (-1 == all zones)
1608  *
1609  * Returns:
1610  * int
1611  * Status return. 0 => success, <>0 => error, in which case a message
1612  * will have been output.
1613 -*/
1614 
1615 int KsmRequestAvailableCount(int keytype, const char* datetime, KSM_PARCOLL* parameters, int* count, int zone_id)
1616 {
1617  char buffer[256]; /* For constructing part of the command */
1618  int clause = 0; /* Used in constructing SQL statement */
1619  size_t nchar; /* Number of characters written */
1620  char* sql; /* SQL command to be isssued */
1621  int status; /* Status return */
1622 
1623  /* Unused parameters */
1624  (void)datetime;
1625  (void)parameters;
1626 
1627  /* Create the SQL command to interrogate the database */
1628 
1629  sql = DqsCountInit("KEYDATA_VIEW");
1630  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
1631 
1632  /* Calculate the initial publication interval & add to query */
1633 
1634  nchar = snprintf(buffer, sizeof(buffer), "(%d, %d, %d, %d)",
1636  if (nchar >= sizeof(buffer)) {
1637  status = MsgLog(KME_BUFFEROVF, "KsmRequestKeys");
1638  DqsFree(sql);
1639  return status;
1640  }
1641  DqsConditionKeyword(&sql, "STATE", DQS_COMPARE_IN, buffer, clause++);
1642  if (zone_id != -1) {
1643  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
1644  }
1645  DqsEnd(&sql);
1646 
1647  /* Execute the query and free resources */
1648 
1649  status = DbIntQuery(DbHandle(), count, sql);
1650  DqsFree(sql);
1651 
1652  /* Report any errors */
1653 
1654  if (status != 0) {
1655  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
1656  }
1657 
1658  return status;
1659 }
1660 
1661 
1662 /*+
1663  * KsmRequestGenerateCount - Return Number of Keys in Generate State
1664  *
1665  * Description:
1666  * Returns the retire time of the currently active key. If there are
1667  * multiple active keys, returns the earliest time.
1668  *
1669  * Arguments:
1670  * int keytype
1671  * Time of key to search for.
1672  *
1673  * int* count (returned)
1674  * Number of available keys.
1675  *
1676  * int zone_id
1677  * ID of zone that we are looking at (-1 == all zones)
1678  *
1679  * Returns:
1680  * int
1681  * Status return. 0 => success, Other implies error, in which case a
1682  * message will have been output.
1683 -*/
1684 
1685 int KsmRequestGenerateCount(int keytype, int* count, int zone_id)
1686 {
1687  int clause = 0; /* Clause count */
1688  char* sql = NULL; /* SQL to interrogate database */
1689  int status = 0; /* Status return */
1690 
1691  /* Create the SQL */
1692 
1693  sql = DqsCountInit("KEYDATA_VIEW");
1694  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
1695  DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, KSM_STATE_GENERATE, clause++);
1696  if (zone_id != -1) {
1697  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
1698  }
1699  DqsEnd(&sql);
1700 
1701  /* Execute the query and free resources */
1702 
1703  status = DbIntQuery(DbHandle(), count, sql);
1704  DqsFree(sql);
1705 
1706  /* Report any errors */
1707 
1708  if (status != 0) {
1709  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
1710  }
1711 
1712  return status;
1713 }
1714 
1715 /*+
1716  * KsmRequestStandbyKSKCount - Get Count of Standby Keys
1717  *
1718  * Description:
1719  * The number of keys in the "dspublished" and "dsready" states.
1720  *
1721  * Arguments:
1722  *
1723  * int* count (returned)
1724  * Number of standby keys.
1725  *
1726  * int zone_id
1727  * ID of zone that we are looking at (-1 == all zones)
1728  *
1729  * Returns:
1730  * int
1731  * Status return. 0 => success, <>0 => error, in which case a message
1732  * will have been output.
1733 -*/
1734 
1735 int KsmRequestStandbyKSKCount(int* count, int zone_id)
1736 {
1737  char buffer[256]; /* For constructing part of the command */
1738  int clause = 0; /* Used in constructing SQL statement */
1739  size_t nchar; /* Number of characters written */
1740  char* sql; /* SQL command to be isssued */
1741  int status; /* Status return */
1742 
1743  /* Create the SQL command to interrogate the database */
1744 
1745  sql = DqsCountInit("KEYDATA_VIEW");
1746  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, KSM_TYPE_KSK, clause++);
1747 
1748  /* Calculate the initial publication interval & add to query */
1749 
1750  nchar = snprintf(buffer, sizeof(buffer), "(%d, %d, %d)",
1752  if (nchar >= sizeof(buffer)) {
1753  status = MsgLog(KME_BUFFEROVF, "KsmRequestKeys");
1754  DqsFree(sql);
1755  return status;
1756  }
1757  DqsConditionKeyword(&sql, "STATE", DQS_COMPARE_IN, buffer, clause++);
1758  if (zone_id != -1) {
1759  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
1760  }
1761  DqsEnd(&sql);
1762 
1763  /* Execute the query and free resources */
1764 
1765  status = DbIntQuery(DbHandle(), count, sql);
1766  DqsFree(sql);
1767 
1768  /* Report any errors */
1769 
1770  if (status != 0) {
1771  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
1772  }
1773 
1774  return status;
1775 }
1776 
1777 /*
1778  * KsmRequestCheckActiveKey - Check Active Key
1779  *
1780  * Description:
1781  * Checks:
1782  *
1783  * a) If there is an active key.
1784  * b) If a key is present, what the retire time of it is. This is compared
1785  * against the specified date/time.
1786  *
1787  * A flag is returned indicating whether the key (if active) should be
1788  * replaced.
1789  *
1790  * Arguments:
1791  * int keytype
1792  * Either KSK or ZSK, depending on the key type
1793  *
1794  * const char* datetime
1795  * Date/time at which the check is being carried out.
1796  *
1797  * int* count
1798  * Number of active keys of the appropriate type and in the zone
1799  * that will be active AFTER the given date and time.
1800  *
1801  * int zone_id
1802  * ID of zone that we are looking at (-1 == all zones)
1803  *
1804  * This negative form (i.e. keys not meeting the specified condition)
1805  * is used to ensure that if there are no active keys, this fact is
1806  * reported.
1807  *
1808  * Returns:
1809  * int
1810  * Status return. 0 => success, Other => error, in which case a message
1811  * will have been output.
1812 -*/
1813 
1814 int KsmRequestCheckActiveKey(int keytype, const char* datetime, int* count, int zone_id)
1815 {
1816  int clause = 0; /* Clause counter */
1817  char* sql = NULL; /* SQL command */
1818  int status; /* Status return */
1819 #ifdef USE_MYSQL
1820 #else
1821  char buf[256]; /* For constructing part of the command */
1822 #endif /* USE_MYSQL */
1823  sql = DqsCountInit("KEYDATA_VIEW");
1824  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
1825  DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, KSM_STATE_ACTIVE, clause++);
1826  if (zone_id != -1) {
1827  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
1828  }
1829 
1830 #ifdef USE_MYSQL
1831  DqsConditionString(&sql, "RETIRE", DQS_COMPARE_GT, datetime, clause++);
1832 #else
1833  snprintf(buf, sizeof(buf), "DATETIME('%s')", datetime);
1834  DqsConditionKeyword(&sql, "DATETIME(RETIRE)", DQS_COMPARE_GT, buf, clause++);
1835 #endif /* USE_MYSQL */
1836 
1837  DqsEnd(&sql);
1838 
1839  status = DbIntQuery(DbHandle(), count, sql);
1840  DqsFree(sql);
1841 
1842  if (status != 0) {
1843  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
1844  }
1846  KsmKeywordTypeValueToName(keytype));
1847 
1848  return status;
1849 }
1850 
1851 
1852 
1853 /*
1854  * KsmRequestCountReadyKey - Count Keys in READY state
1855  *
1856  * Description:
1857  * Counts the number of keys in the "READY" state.
1858  *
1859  * Arguments:
1860  * int keytype
1861  * Either KSK or ZSK, depending on the key type
1862  *
1863  * const char* datetime
1864  * Date/time at which the check is being carried out.
1865  *
1866  * int* count
1867  * Number of keys meeting the condition.
1868  *
1869  * int zone_id
1870  * ID of zone that we are looking at (-1 == all zones)
1871  *
1872  * Returns:
1873  * int
1874  * Status return. 0 => success, Other => error, in which case a message
1875  * will have been output.
1876 -*/
1877 
1878 int KsmRequestCountReadyKey(int keytype, const char* datetime, int* count, int zone_id)
1879 {
1880  int clause = 0; /* Clause counter */
1881  char* sql = NULL; /* SQL command */
1882  int status; /* Status return */
1883 
1884  /* Unused parameter */
1885  (void)datetime;
1886 
1887  sql = DqsCountInit("KEYDATA_VIEW");
1888  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
1889  DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, KSM_STATE_READY, clause++);
1890  if (zone_id != -1) {
1891  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
1892  }
1893  DqsEnd(&sql);
1894 
1895  status = DbIntQuery(DbHandle(), count, sql);
1896  DqsFree(sql);
1897 
1898  if (status != 0) {
1899  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
1900  }
1902  KsmKeywordTypeValueToName(keytype));
1903 
1904  return status;
1905 }
1906 
1907 /*
1908  * KsmRequestCheckFirstPass - Work out if this zone has been processed before
1909  *
1910  * Description:
1911  * Counts the number of keys above the PUBLISH state; if this is 0 then this is
1912  * a new zone.
1913  *
1914  * Arguments:
1915  * int keytype
1916  * Either KSK or ZSK, depending on the key type
1917  *
1918  * int* first_pass_flag
1919  * Indicator as to the result
1920  *
1921  * int zone_id
1922  * ID of zone that we are looking at (-1 == all zones)
1923  *
1924  * Returns:
1925  * int
1926  * Status return. 0 => success, Other => error, in which case a message
1927  * will have been output.
1928 -*/
1929 
1930 int KsmRequestCheckFirstPass(int keytype, int* first_pass_flag, int zone_id)
1931 {
1932  int clause = 0; /* Clause counter */
1933  char* sql = NULL; /* SQL command */
1934  int status; /* Status return */
1935  int count = 0; /* Number of matching keys */
1936 
1937  sql = DqsCountInit("KEYDATA_VIEW");
1938  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
1939  DqsConditionInt(&sql, "STATE", DQS_COMPARE_GE, KSM_STATE_PUBLISH, clause++);
1940  if (zone_id != -1) {
1941  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
1942  }
1943  DqsEnd(&sql);
1944 
1945  status = DbIntQuery(DbHandle(), &count, sql);
1946  DqsFree(sql);
1947 
1948  if (status != 0) {
1949  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
1950  }
1951 
1952  if (count == 0) {
1953  /* No "ready, active, retired or dead" keys */
1954  *first_pass_flag = 1;
1955  }
1956  else {
1957  *first_pass_flag = 0;
1958  }
1959 
1960  return status;
1961 }
1962 
1963 /*
1964  * KsmRequestCheckCompromisedFlag - Work out if this zone is rolling
1965  *
1966  * Description:
1967  * Counts the number of "compromised" active keys, if > 0 then force
1968  * the zone to roll if we can.
1969  *
1970  * Arguments:
1971  * int keytype
1972  * Either KSK or ZSK, depending on the key type
1973  *
1974  * int zone_id
1975  * ID of zone that we are looking at (-1 == all zones)
1976  *
1977  * int* comp_flag
1978  * Force rollover behaviour if the active key is marked as compromised
1979  *
1980  * Returns:
1981  * int
1982  * Status return. 0 => success, Other => error, in which case a message
1983  * will have been output.
1984 -*/
1985 
1986 int KsmRequestCheckCompromisedFlag(int keytype, int zone_id, int* comp_flag)
1987 {
1988  int clause = 0; /* Clause counter */
1989  char* sql = NULL; /* SQL command */
1990  int status; /* Status return */
1991  int count = 0; /* Number of matching keys */
1992 
1993  sql = DqsCountInit("KEYDATA_VIEW");
1994  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
1995  DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, KSM_STATE_ACTIVE, clause++);
1996  if (zone_id != -1) {
1997  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
1998  }
1999  DqsConditionInt(&sql, "compromisedflag", DQS_COMPARE_EQ, 1, clause++);
2000  DqsEnd(&sql);
2001 
2002  status = DbIntQuery(DbHandle(), &count, sql);
2003  DqsFree(sql);
2004 
2005  if (status != 0) {
2006  status = MsgLog(KME_SQLFAIL, DbErrmsg(DbHandle()));
2007  }
2008 
2009  if (count == 0) {
2010  /* No "compromised" keys; i.e. keys waiting to roll */
2011  /* We actually don't need to do this as it can only be 0 already */
2012  *comp_flag = 0;
2013  }
2014  else {
2015  *comp_flag = 1;
2016  }
2017 
2018  return status;
2019 }
2020 
2021 /*+
2022  * KsmRequestIssueKeys - Issue Keys
2023  *
2024  * Description:
2025  * Done as the last step in the "REQUEST KEYS" operation, this actually
2026  * issues the keys that should be in the current zone file. All keys in
2027  * the "publish", "ready", "active" and "retire" states are included.
2028  *
2029  * Arguments:
2030  * int keytype
2031  * Type of keys required.
2032  *
2033  * KSM_REQUEST_CALLBACK callback
2034  * Callback function called for every key that will be issued.
2035  *
2036  * void* context
2037  * Context argument passed uninterpreted to the callback function.
2038  *
2039  * int zone_id
2040  * ID of zone that we are looking at (-1 == all zones)
2041  *
2042  * Returns:
2043  * int
2044  * Status return. 0 => success, <>0 => error (in which case a message
2045  * will have been output).
2046 -*/
2047 
2048 int KsmRequestIssueKeys(int keytype, KSM_REQUEST_CALLBACK callback,
2049  void* context, int zone_id)
2050 {
2051  int clause = 0; /* For the WHERE clause */
2052  KSM_KEYDATA data; /* Data for this key */
2053  DB_RESULT result; /* Result set from query */
2054  char in[128]; /* Easily large enought for four keys */
2055  size_t nchar; /* Number of output characters */
2056  char* sql = NULL; /* SQL statement to get listing */
2057  int status; /* Status return */
2058 
2059  /*
2060  * Construct the "IN" statement listing the states of the keys that
2061  * are included in the output.
2062  */
2063 
2064  nchar = snprintf(in, sizeof(in), "(%d, %d, %d, %d, %d)",
2066  if (nchar >= sizeof(in)) {
2067  status = MsgLog(KME_BUFFEROVF, "KsmRequestIssueKeys");
2068  return status;
2069  }
2070 
2071  /* Create the SQL command to interrogate the database */
2072 
2073  sql = DqsSpecifyInit("KEYDATA_VIEW", DB_KEYDATA_FIELDS);
2074  DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, clause++);
2075  DqsConditionKeyword(&sql, "STATE", DQS_COMPARE_IN, in, clause++);
2076  if (zone_id != -1) {
2077  DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, clause++);
2078  }
2079  DqsEnd(&sql);
2080 
2081  /* Now iterate round the keys meeting the condition and print them */
2082 
2083  status = KsmKeyInitSql(&result, sql);
2084  if (status == 0) {
2085  status = KsmKey(result, &data);
2086  while (status == 0) {
2087  status = (*callback)(context, &data);
2088  if (status == 0) {
2089  status = KsmKey(result, &data);
2090  }
2091  }
2092 
2093  /* Convert EOF status to success */
2094 
2095  if (status == -1) {
2096  status = 0;
2097  }
2098 
2099  KsmKeyEnd(result);
2100  }
2101 
2102  DqsFree(sql);
2103  return status;
2104 }
2105 
2106 
2107 
2108 /*+
2109  * KsmRequestPrintKey - Print Key Data
2110  *
2111  * Description:
2112  * Suitable callback function for KsmRequest, this prints a summary of the
2113  * key information to stdout.
2114  *
2115  * Arguments:
2116  * void* context
2117  * Context passed to KsmUpdate. This is unused.
2118  *
2119  * KSM_KEYDATA* data
2120  * Data about the key to be isssued.
2121  *
2122  * Returns:
2123  * int
2124  * Always 0.
2125 -*/
2126 
2127 int KsmRequestPrintKey(void* context, KSM_KEYDATA* data)
2128 {
2129  /* Unused parameter */
2130  (void)context;
2131 
2132  printf("%s %lu %d %d %s\n", KsmKeywordStateValueToName(data->state),
2133  data->keypair_id, data->keytype, data->algorithm, data->location);
2134 
2135  return 0;
2136 }
int KsmRequestChangeStateKeyPublishActive(const char *datetime, int zone_id, int policy_id, int *NewDS)
Definition: ksm_request.c:708
int KsmRequestKeys(int keytype, int rollover, const char *datetime, KSM_REQUEST_CALLBACK callback, void *context, int policy_id, int zone_id, int run_interval, int *NewDS)
Definition: ksm_request.c:97
#define KME_READYCNT
Definition: kmedef.h:65
int KsmRequestCountReadyKey(int keytype, const char *datetime, int *count, int zone_id)
Definition: ksm_request.c:1878
#define KSM_TYPE_ZSK
Definition: ksm.h:359
#define StrFree(x)
Definition: string_util.h:68
void DusConditionKeyword(char **query, const char *field, DQS_COMPARISON compare, const char *value, int clause)
Definition: du_string.c:184
int DbRollback(void)
#define KSM_INVARG
Definition: ksmdef.h:68
int KsmRequestCheckActiveKey(int keytype, const char *datetime, int *count, int zone_id)
Definition: ksm_request.c:1814
#define KSM_SQLFAIL
Definition: ksmdef.h:69
int KsmRequestPendingRetireCount(int keytype, const char *datetime, KSM_PARCOLL *parameters, int *count, int zone_id, int interval)
Definition: ksm_request.c:1482
#define KSM_STATE_DEAD
Definition: ksm.h:372
int KsmRequestCheckFirstPass(int keytype, int *first_pass_flag, int zone_id)
Definition: ksm_request.c:1930
union DQS_QUERY_CONDITION::@0 data
char * DqsSpecifyInit(const char *table, const char *fields)
Definition: dq_string.c:119
#define KSM_STATE_ACTIVE
Definition: ksm.h:368
char location[KSM_NAME_LENGTH]
Definition: ksm.h:111
int KsmUpdate(int policy_id, int zone_id)
Definition: ksm_update.c:72
int(* KSM_REQUEST_CALLBACK)(void *context, KSM_KEYDATA *key)
Definition: ksm.h:547
int KsmRequestChangeStateGeneratePublishConditional(int keytype, const char *datetime, KSM_PARCOLL *collection, int zone_id, int run_interval)
Definition: ksm_request.c:1365
#define KSM_STATE_READY
Definition: ksm.h:366
int KsmParameterZskTtl(KSM_PARCOLL *collection)
#define KME_AVAILCNT
Definition: kmedef.h:49
int KsmRequestGenerateCount(int keytype, int *count, int zone_id)
Definition: ksm_request.c:1685
#define KSM_ROLL_DS
Definition: ksm.h:399
int state
Definition: ksm.h:101
int KsmParameterCollection(KSM_PARCOLL *data, int policy_id)
void DusFree(char *sql)
Definition: du_string.c:225
int KsmRequestChangeState(int keytype, const char *datetime, int src_state, int dst_state, int zone_id, int policy_id, int rollover_scheme, int *NewDS)
Definition: ksm_request.c:766
DQS_COMPARISON compare
#define KME_GENERATECNT
Definition: kmedef.h:55
#define KME_PROM_PUB
Definition: kmedef.h:73
void DqsConditionKeyword(char **query, const char *field, DQS_COMPARISON compare, const char *value, int index)
Definition: dq_string.c:253
int KsmRequestCheckCompromisedFlag(int keytype, int zone_id, int *comp_flag)
Definition: ksm_request.c:1986
#define KSM_STATE_READY_STRING
Definition: ksm.h:367
int KsmRequestPrintKey(void *context, KSM_KEYDATA *data)
Definition: ksm_request.c:2127
int KsmRequestChangeStateDSPublishDSReady(int keytype, const char *datetime, int zone_id, int policy_id)
Definition: ksm_request.c:694
#define DB_KEYDATA_ZONE_ID
Definition: db_fields.h:70
#define KME_DS_SUBMISSION
Definition: kmedef.h:84
int MsgLog(int status,...)
Definition: message.c:337
void DbgLog(unsigned int mask, int status,...)
Definition: debug.c:172
void DusSetInt(char **sql, const char *field, int data, int clause)
Definition: du_string.c:99
void DqsFree(char *query)
Definition: dq_string.c:322
#define KSM_ROLL_DNSKEY
Definition: ksm.h:397
#define KME_DS_REM_ZONE
Definition: kmedef.h:76
#define KSM_STATE_KEYPUBLISH
Definition: ksm.h:380
#define KME_INSFGENKEY
Definition: kmedef.h:56
int KsmParameterKskTtl(KSM_PARCOLL *collection)
void DusConditionInt(char **query, const char *field, DQS_COMPARISON compare, int value, int clause)
Definition: du_string.c:172
#define MemFree(ptr)
Definition: memory.h:50
const char * KsmKeywordStateValueToName(int value)
Definition: ksm_keyword.c:244
char * DqsCountInit(const char *table)
Definition: dq_string.c:92
DB_HANDLE DbHandle(void)
int KsmParameterKskPropagationDelay(KSM_PARCOLL *collection)
char * StrStrdup(const char *string)
Definition: string_util.c:126
void DqsConditionInt(char **query, const char *field, DQS_COMPARISON compare, int value, int index)
Definition: dq_string.c:226
int KsmRequestChangeStateReadyActive(int keytype, const char *datetime, int count, int zone_id)
Definition: ksm_request.c:1000
#define KME_KEYCHSTATE
Definition: kmedef.h:57
int DbCommit(void)
int kskmanroll
Definition: ksm.h:486
int KsmRequestStandbyKSKCount(int *count, int zone_id)
Definition: ksm_request.c:1735
int KsmRequestChangeStateGenerateDSSub(int keytype, const char *datetime, int count, int zone_id)
Definition: ksm_request.c:993
#define KSM_STATE_DSPUBLISH
Definition: ksm.h:376
#define DB_KEYDATA_STATE
Definition: db_fields.h:60
int KsmParameterStandbyZSKeys(KSM_PARCOLL *collection)
int KsmRequestChangeStatePublishReady(int keytype, const char *datetime, int zone_id, int policy_id, int *NewDS)
Definition: ksm_request.c:688
int KsmKeyInitSql(DB_RESULT *result, const char *sql)
Definition: ksm_key.c:219
#define DB_KEYDATA_FIELDS
Definition: db_fields.h:58
const char * DbErrmsg(DB_HANDLE handle)
int KsmKey(DB_RESULT result, KSM_KEYDATA *data)
Definition: ksm_key.c:368
#define KME_NOREADYKEY
Definition: kmedef.h:59
int KsmParameterPropagationDelay(KSM_PARCOLL *collection)
int KsmRequestAvailableCount(int keytype, const char *datetime, KSM_PARCOLL *parameters, int *count, int zone_id)
Definition: ksm_request.c:1615
int KsmRequestChangeStateGeneratePublish(int keytype, const char *datetime, int count, int zone_id)
Definition: ksm_request.c:986
int keytype
Definition: ksm.h:102
int KsmKeyInit(DB_RESULT *result, DQS_QUERY_CONDITION *condition)
Definition: ksm_key.c:251
#define KME_SQLFAIL
Definition: kmedef.h:69
void StrAppend(char **str1, const char *str2)
Definition: string_util2.c:78
#define KSM_STATE_PUBLISH_STRING
Definition: ksm.h:365
int KsmRequestChangeStateRetireDead(int keytype, const char *datetime, int zone_id, int policy_id, int rollover_scheme, int *NewDS)
Definition: ksm_request.c:721
int algorithm
Definition: ksm.h:103
void DusEnd(char **sql)
Definition: du_string.c:204
int DbIntQuery(DB_HANDLE handle, int *value, const char *query)
int KsmRequestChangeStateN(int keytype, const char *datetime, int count, int src_state, int dst_state, int zone_id)
Definition: ksm_request.c:1041
#define KSM_STATE_RETIRE
Definition: ksm.h:370
#define KSM_STATE_PUBLISH
Definition: ksm.h:364
int KsmZoneNameFromId(int zone_id, char **zone_name)
Definition: ksm_zone.c:414
char * DusInit(const char *table)
Definition: du_string.c:62
#define KME_NEW_DS
Definition: kmedef.h:86
int KsmParameterPubSafety(KSM_PARCOLL *collection)
int KsmRequestKeysByType(int keytype, int rollover, const char *datetime, KSM_REQUEST_CALLBACK callback, void *context, int policy_id, int zone_id, int run_interval, int *NewDS)
Definition: ksm_request.c:212
DB_ID keypair_id
Definition: ksm.h:100
#define KME_ROLL_ZONE
Definition: kmedef.h:78
const char * KsmKeywordTypeValueToName(int value)
Definition: ksm_keyword.c:249
#define KME_MAN_ROLL_REQUIRED
Definition: kmedef.h:81
#define KME_BACK_NON_FATAL
Definition: kmedef.h:75
#define KME_BUFFEROVF
Definition: kmedef.h:50
#define KME_BACK_FATAL
Definition: kmedef.h:74
#define DB_KEYDATA_KEYTYPE
Definition: db_fields.h:67
int KsmRequestChangeStateDSReadyKeyPublish(const char *datetime, int zone_id, int policy_id)
Definition: ksm_request.c:701
#define KSM_STATE_DSSUB
Definition: ksm.h:374
#define KSM_TYPE_KSK
Definition: ksm.h:357
int KsmParameterStandbyKSKeys(KSM_PARCOLL *collection)
#define DBG_M_REQUEST
Definition: debug.h:47
#define KME_KEYCNTSUMM
Definition: kmedef.h:58
void * MemMalloc(size_t size)
Definition: memory.c:59
int KsmRequestChangeStateGenerateDSSubConditional(int keytype, const char *datetime, KSM_PARCOLL *collection, int zone_id, int *NewDS)
Definition: ksm_request.c:1260
#define KSM_STATE_DSREADY
Definition: ksm.h:378
size_t StrToUpper(char *text)
Definition: string_util.c:355
void KsmKeyEnd(DB_RESULT result)
Definition: ksm_key.c:471
#define KME_UNKEYTYPE
Definition: kmedef.h:70
#define KSM_STATE_GENERATE
Definition: ksm.h:362
void DusSetString(char **sql, const char *field, const char *data, int clause)
Definition: du_string.c:115
int KsmRequestIssueKeys(int keytype, KSM_REQUEST_CALLBACK callback, void *context, int zone_id)
Definition: ksm_request.c:2048
void DqsEnd(char **query)
Definition: dq_string.c:301
#define KME_REQKEYTYPE
Definition: kmedef.h:67
int DbBeginTransaction(void)
int DbExecuteSqlNoResult(DB_HANDLE handle, const char *stmt_str)
int KsmRequestSetActiveExpectedRetire(int keytype, const char *datetime, int zone_id)
Definition: ksm_request.c:521
int zskmanroll
Definition: ksm.h:487
void DqsConditionString(char **query, const char *field, DQS_COMPARISON compare, const char *value, int index)
Definition: dq_string.c:240
#define KME_RETIRECNT
Definition: kmedef.h:68
int KsmRequestChangeStateActiveRetire(int keytype, const char *datetime, int zone_id, int policy_id)
Definition: ksm_request.c:714
int kskroll
Definition: ksm.h:489
#define KME_REMAINACT
Definition: kmedef.h:66