]> git.proxmox.com Git - mirror_frr.git/blob - lib/keychain.c
ldpd: use red-black trees to store 'tnbr' elements
[mirror_frr.git] / lib / keychain.c
1 /* key-chain for authentication.
2 Copyright (C) 2000 Kunihiro Ishiguro
3
4 This file is part of GNU Zebra.
5
6 GNU Zebra is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2, or (at your
9 option) any later version.
10
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #include <zebra.h>
22
23 #include "command.h"
24 #include "memory.h"
25 #include "linklist.h"
26 #include "keychain.h"
27
28 DEFINE_MTYPE_STATIC(LIB, KEY, "Key")
29 DEFINE_MTYPE_STATIC(LIB, KEYCHAIN, "Key chain")
30
31 DEFINE_QOBJ_TYPE(keychain)
32 DEFINE_QOBJ_TYPE(key)
33
34 /* Master list of key chain. */
35 struct list *keychain_list;
36
37 static struct keychain *
38 keychain_new (void)
39 {
40 struct keychain *keychain;
41 keychain = XCALLOC (MTYPE_KEYCHAIN, sizeof (struct keychain));
42 QOBJ_REG (keychain, keychain);
43 return keychain;
44 }
45
46 static void
47 keychain_free (struct keychain *keychain)
48 {
49 QOBJ_UNREG (keychain);
50 XFREE (MTYPE_KEYCHAIN, keychain);
51 }
52
53 static struct key *
54 key_new (void)
55 {
56 struct key *key = XCALLOC (MTYPE_KEY, sizeof (struct key));
57 QOBJ_REG (key, key);
58 return key;
59 }
60
61 static void
62 key_free (struct key *key)
63 {
64 QOBJ_UNREG (key);
65 XFREE (MTYPE_KEY, key);
66 }
67
68 struct keychain *
69 keychain_lookup (const char *name)
70 {
71 struct listnode *node;
72 struct keychain *keychain;
73
74 if (name == NULL)
75 return NULL;
76
77 for (ALL_LIST_ELEMENTS_RO (keychain_list, node, keychain))
78 {
79 if (strcmp (keychain->name, name) == 0)
80 return keychain;
81 }
82 return NULL;
83 }
84
85 static int
86 key_cmp_func (void *arg1, void *arg2)
87 {
88 const struct key *k1 = arg1;
89 const struct key *k2 = arg2;
90
91 if (k1->index > k2->index)
92 return 1;
93 if (k1->index < k2->index)
94 return -1;
95 return 0;
96 }
97
98 static void
99 key_delete_func (struct key *key)
100 {
101 if (key->string)
102 free (key->string);
103 key_free (key);
104 }
105
106 static struct keychain *
107 keychain_get (const char *name)
108 {
109 struct keychain *keychain;
110
111 keychain = keychain_lookup (name);
112
113 if (keychain)
114 return keychain;
115
116 keychain = keychain_new ();
117 keychain->name = XSTRDUP(MTYPE_KEYCHAIN, name);
118 keychain->key = list_new ();
119 keychain->key->cmp = (int (*)(void *, void *)) key_cmp_func;
120 keychain->key->del = (void (*)(void *)) key_delete_func;
121 listnode_add (keychain_list, keychain);
122
123 return keychain;
124 }
125
126 static void
127 keychain_delete (struct keychain *keychain)
128 {
129 if (keychain->name)
130 XFREE(MTYPE_KEYCHAIN, keychain->name);
131
132 list_delete (keychain->key);
133 listnode_delete (keychain_list, keychain);
134 keychain_free (keychain);
135 }
136
137 static struct key *
138 key_lookup (const struct keychain *keychain, u_int32_t index)
139 {
140 struct listnode *node;
141 struct key *key;
142
143 for (ALL_LIST_ELEMENTS_RO (keychain->key, node, key))
144 {
145 if (key->index == index)
146 return key;
147 }
148 return NULL;
149 }
150
151 struct key *
152 key_lookup_for_accept (const struct keychain *keychain, u_int32_t index)
153 {
154 struct listnode *node;
155 struct key *key;
156 time_t now;
157
158 now = time (NULL);
159
160 for (ALL_LIST_ELEMENTS_RO (keychain->key, node, key))
161 {
162 if (key->index >= index)
163 {
164 if (key->accept.start == 0)
165 return key;
166
167 if (key->accept.start <= now)
168 if (key->accept.end >= now || key->accept.end == -1)
169 return key;
170 }
171 }
172 return NULL;
173 }
174
175 struct key *
176 key_match_for_accept (const struct keychain *keychain, const char *auth_str)
177 {
178 struct listnode *node;
179 struct key *key;
180 time_t now;
181
182 now = time (NULL);
183
184 for (ALL_LIST_ELEMENTS_RO (keychain->key, node, key))
185 {
186 if (key->accept.start == 0 ||
187 (key->accept.start <= now &&
188 (key->accept.end >= now || key->accept.end == -1)))
189 if (strncmp (key->string, auth_str, 16) == 0)
190 return key;
191 }
192 return NULL;
193 }
194
195 struct key *
196 key_lookup_for_send (const struct keychain *keychain)
197 {
198 struct listnode *node;
199 struct key *key;
200 time_t now;
201
202 now = time (NULL);
203
204 for (ALL_LIST_ELEMENTS_RO (keychain->key, node, key))
205 {
206 if (key->send.start == 0)
207 return key;
208
209 if (key->send.start <= now)
210 if (key->send.end >= now || key->send.end == -1)
211 return key;
212 }
213 return NULL;
214 }
215
216 static struct key *
217 key_get (const struct keychain *keychain, u_int32_t index)
218 {
219 struct key *key;
220
221 key = key_lookup (keychain, index);
222
223 if (key)
224 return key;
225
226 key = key_new ();
227 key->index = index;
228 listnode_add_sort (keychain->key, key);
229
230 return key;
231 }
232
233 static void
234 key_delete (struct keychain *keychain, struct key *key)
235 {
236 listnode_delete (keychain->key, key);
237
238 if (key->string)
239 XFREE(MTYPE_KEY, key->string);
240 key_free (key);
241 }
242
243 DEFUN (key_chain,
244 key_chain_cmd,
245 "key chain WORD",
246 "Authentication key management\n"
247 "Key-chain management\n"
248 "Key-chain name\n")
249 {
250 struct keychain *keychain;
251
252 keychain = keychain_get (argv[0]);
253 VTY_PUSH_CONTEXT_COMPAT (KEYCHAIN_NODE, keychain);
254
255 return CMD_SUCCESS;
256 }
257
258 DEFUN (no_key_chain,
259 no_key_chain_cmd,
260 "no key chain WORD",
261 NO_STR
262 "Authentication key management\n"
263 "Key-chain management\n"
264 "Key-chain name\n")
265 {
266 struct keychain *keychain;
267
268 keychain = keychain_lookup (argv[0]);
269
270 if (! keychain)
271 {
272 vty_out (vty, "Can't find keychain %s%s", argv[0], VTY_NEWLINE);
273 return CMD_WARNING;
274 }
275
276 keychain_delete (keychain);
277
278 return CMD_SUCCESS;
279 }
280
281 DEFUN (key,
282 key_cmd,
283 "key <0-2147483647>",
284 "Configure a key\n"
285 "Key identifier number\n")
286 {
287 VTY_DECLVAR_CONTEXT (keychain, keychain);
288 struct key *key;
289 u_int32_t index;
290
291 VTY_GET_INTEGER ("key identifier", index, argv[0]);
292 key = key_get (keychain, index);
293 VTY_PUSH_CONTEXT_SUB (KEYCHAIN_KEY_NODE, key);
294
295 return CMD_SUCCESS;
296 }
297
298 DEFUN (no_key,
299 no_key_cmd,
300 "no key <0-2147483647>",
301 NO_STR
302 "Delete a key\n"
303 "Key identifier number\n")
304 {
305 VTY_DECLVAR_CONTEXT (keychain, keychain);
306 struct key *key;
307 u_int32_t index;
308
309 VTY_GET_INTEGER ("key identifier", index, argv[0]);
310 key = key_lookup (keychain, index);
311 if (! key)
312 {
313 vty_out (vty, "Can't find key %d%s", index, VTY_NEWLINE);
314 return CMD_WARNING;
315 }
316
317 key_delete (keychain, key);
318
319 vty->node = KEYCHAIN_NODE;
320
321 return CMD_SUCCESS;
322 }
323
324 DEFUN (key_string,
325 key_string_cmd,
326 "key-string LINE",
327 "Set key string\n"
328 "The key\n")
329 {
330 VTY_DECLVAR_CONTEXT_SUB (key, key);
331
332 if (key->string)
333 XFREE(MTYPE_KEY, key->string);
334 key->string = XSTRDUP(MTYPE_KEY, argv[0]);
335
336 return CMD_SUCCESS;
337 }
338
339 DEFUN (no_key_string,
340 no_key_string_cmd,
341 "no key-string [LINE]",
342 NO_STR
343 "Unset key string\n"
344 "The key\n")
345 {
346 VTY_DECLVAR_CONTEXT_SUB (key, key);
347
348 if (key->string)
349 {
350 XFREE(MTYPE_KEY, key->string);
351 key->string = NULL;
352 }
353
354 return CMD_SUCCESS;
355 }
356
357 /* Convert HH:MM:SS MON DAY YEAR to time_t value. -1 is returned when
358 given string is malformed. */
359 static time_t
360 key_str2time (const char *time_str, const char *day_str, const char *month_str,
361 const char *year_str)
362 {
363 int i = 0;
364 char *colon;
365 struct tm tm;
366 time_t time;
367 unsigned int sec, min, hour;
368 unsigned int day, month, year;
369
370 const char *month_name[] =
371 {
372 "January",
373 "February",
374 "March",
375 "April",
376 "May",
377 "June",
378 "July",
379 "August",
380 "September",
381 "October",
382 "November",
383 "December",
384 NULL
385 };
386
387 #define _GET_LONG_RANGE(V,STR,MMCOND) \
388 { \
389 unsigned long tmpl; \
390 char *endptr = NULL; \
391 tmpl = strtoul ((STR), &endptr, 10); \
392 if (*endptr != '\0' || tmpl == ULONG_MAX) \
393 return -1; \
394 if (MMCOND) \
395 return -1; \
396 (V) = tmpl; \
397 }
398 #define GET_LONG_RANGE(V,STR,MIN,MAX) \
399 _GET_LONG_RANGE(V,STR,tmpl < (MIN) || tmpl > (MAX))
400 #define GET_LONG_RANGE0(V,STR,MAX) \
401 _GET_LONG_RANGE(V,STR,tmpl > (MAX))
402
403 /* Check hour field of time_str. */
404 colon = strchr (time_str, ':');
405 if (colon == NULL)
406 return -1;
407 *colon = '\0';
408
409 /* Hour must be between 0 and 23. */
410 GET_LONG_RANGE0 (hour, time_str, 23);
411
412 /* Check min field of time_str. */
413 time_str = colon + 1;
414 colon = strchr (time_str, ':');
415 if (*time_str == '\0' || colon == NULL)
416 return -1;
417 *colon = '\0';
418
419 /* Min must be between 0 and 59. */
420 GET_LONG_RANGE0 (min, time_str, 59);
421
422 /* Check sec field of time_str. */
423 time_str = colon + 1;
424 if (*time_str == '\0')
425 return -1;
426
427 /* Sec must be between 0 and 59. */
428 GET_LONG_RANGE0 (sec, time_str, 59);
429
430 /* Check day_str. Day must be <1-31>. */
431 GET_LONG_RANGE (day, day_str, 1, 31);
432
433 /* Check month_str. Month must match month_name. */
434 month = 0;
435 if (strlen (month_str) >= 3)
436 for (i = 0; month_name[i]; i++)
437 if (strncmp (month_str, month_name[i], strlen (month_str)) == 0)
438 {
439 month = i;
440 break;
441 }
442 if (! month_name[i])
443 return -1;
444
445 /* Check year_str. Year must be <1993-2035>. */
446 GET_LONG_RANGE (year, year_str, 1993, 2035);
447
448 memset (&tm, 0, sizeof (struct tm));
449 tm.tm_sec = sec;
450 tm.tm_min = min;
451 tm.tm_hour = hour;
452 tm.tm_mon = month;
453 tm.tm_mday = day;
454 tm.tm_year = year - 1900;
455
456 time = mktime (&tm);
457
458 return time;
459 #undef GET_LONG_RANGE
460 }
461
462 static int
463 key_lifetime_set (struct vty *vty, struct key_range *krange,
464 const char *stime_str, const char *sday_str,
465 const char *smonth_str, const char *syear_str,
466 const char *etime_str, const char *eday_str,
467 const char *emonth_str, const char *eyear_str)
468 {
469 time_t time_start;
470 time_t time_end;
471
472 time_start = key_str2time (stime_str, sday_str, smonth_str, syear_str);
473 if (time_start < 0)
474 {
475 vty_out (vty, "Malformed time value%s", VTY_NEWLINE);
476 return CMD_WARNING;
477 }
478 time_end = key_str2time (etime_str, eday_str, emonth_str, eyear_str);
479
480 if (time_end < 0)
481 {
482 vty_out (vty, "Malformed time value%s", VTY_NEWLINE);
483 return CMD_WARNING;
484 }
485
486 if (time_end <= time_start)
487 {
488 vty_out (vty, "Expire time is not later than start time%s", VTY_NEWLINE);
489 return CMD_WARNING;
490 }
491
492 krange->start = time_start;
493 krange->end = time_end;
494
495 return CMD_SUCCESS;
496 }
497
498 static int
499 key_lifetime_duration_set (struct vty *vty, struct key_range *krange,
500 const char *stime_str, const char *sday_str,
501 const char *smonth_str, const char *syear_str,
502 const char *duration_str)
503 {
504 time_t time_start;
505 u_int32_t duration;
506
507 time_start = key_str2time (stime_str, sday_str, smonth_str, syear_str);
508 if (time_start < 0)
509 {
510 vty_out (vty, "Malformed time value%s", VTY_NEWLINE);
511 return CMD_WARNING;
512 }
513 krange->start = time_start;
514
515 VTY_GET_INTEGER ("duration", duration, duration_str);
516 krange->duration = 1;
517 krange->end = time_start + duration;
518
519 return CMD_SUCCESS;
520 }
521
522 static int
523 key_lifetime_infinite_set (struct vty *vty, struct key_range *krange,
524 const char *stime_str, const char *sday_str,
525 const char *smonth_str, const char *syear_str)
526 {
527 time_t time_start;
528
529 time_start = key_str2time (stime_str, sday_str, smonth_str, syear_str);
530 if (time_start < 0)
531 {
532 vty_out (vty, "Malformed time value%s", VTY_NEWLINE);
533 return CMD_WARNING;
534 }
535 krange->start = time_start;
536
537 krange->end = -1;
538
539 return CMD_SUCCESS;
540 }
541
542 DEFUN (accept_lifetime_day_month_day_month,
543 accept_lifetime_day_month_day_month_cmd,
544 "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
545 "Set accept lifetime of the key\n"
546 "Time to start\n"
547 "Day of th month to start\n"
548 "Month of the year to start\n"
549 "Year to start\n"
550 "Time to expire\n"
551 "Day of th month to expire\n"
552 "Month of the year to expire\n"
553 "Year to expire\n")
554 {
555 VTY_DECLVAR_CONTEXT_SUB (key, key);
556
557 return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2],
558 argv[3], argv[4], argv[5], argv[6], argv[7]);
559 }
560
561 DEFUN (accept_lifetime_day_month_month_day,
562 accept_lifetime_day_month_month_day_cmd,
563 "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
564 "Set accept lifetime of the key\n"
565 "Time to start\n"
566 "Day of th month to start\n"
567 "Month of the year to start\n"
568 "Year to start\n"
569 "Time to expire\n"
570 "Month of the year to expire\n"
571 "Day of th month to expire\n"
572 "Year to expire\n")
573 {
574 VTY_DECLVAR_CONTEXT_SUB (key, key);
575
576 return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2],
577 argv[3], argv[4], argv[6], argv[5], argv[7]);
578 }
579
580 DEFUN (accept_lifetime_month_day_day_month,
581 accept_lifetime_month_day_day_month_cmd,
582 "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
583 "Set accept lifetime of the key\n"
584 "Time to start\n"
585 "Month of the year to start\n"
586 "Day of th month to start\n"
587 "Year to start\n"
588 "Time to expire\n"
589 "Day of th month to expire\n"
590 "Month of the year to expire\n"
591 "Year to expire\n")
592 {
593 VTY_DECLVAR_CONTEXT_SUB (key, key);
594
595 return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1],
596 argv[3], argv[4], argv[5], argv[6], argv[7]);
597 }
598
599 DEFUN (accept_lifetime_month_day_month_day,
600 accept_lifetime_month_day_month_day_cmd,
601 "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
602 "Set accept lifetime of the key\n"
603 "Time to start\n"
604 "Month of the year to start\n"
605 "Day of th month to start\n"
606 "Year to start\n"
607 "Time to expire\n"
608 "Month of the year to expire\n"
609 "Day of th month to expire\n"
610 "Year to expire\n")
611 {
612 VTY_DECLVAR_CONTEXT_SUB (key, key);
613
614 return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1],
615 argv[3], argv[4], argv[6], argv[5], argv[7]);
616 }
617
618 DEFUN (accept_lifetime_infinite_day_month,
619 accept_lifetime_infinite_day_month_cmd,
620 "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> infinite",
621 "Set accept lifetime of the key\n"
622 "Time to start\n"
623 "Day of th month to start\n"
624 "Month of the year to start\n"
625 "Year to start\n"
626 "Never expires")
627 {
628 VTY_DECLVAR_CONTEXT_SUB (key, key);
629
630 return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[1],
631 argv[2], argv[3]);
632 }
633
634 DEFUN (accept_lifetime_infinite_month_day,
635 accept_lifetime_infinite_month_day_cmd,
636 "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> infinite",
637 "Set accept lifetime of the key\n"
638 "Time to start\n"
639 "Month of the year to start\n"
640 "Day of th month to start\n"
641 "Year to start\n"
642 "Never expires")
643 {
644 VTY_DECLVAR_CONTEXT_SUB (key, key);
645
646 return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[2],
647 argv[1], argv[3]);
648 }
649
650 DEFUN (accept_lifetime_duration_day_month,
651 accept_lifetime_duration_day_month_cmd,
652 "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> duration <1-2147483646>",
653 "Set accept lifetime of the key\n"
654 "Time to start\n"
655 "Day of th month to start\n"
656 "Month of the year to start\n"
657 "Year to start\n"
658 "Duration of the key\n"
659 "Duration seconds\n")
660 {
661 VTY_DECLVAR_CONTEXT_SUB (key, key);
662
663 return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[1],
664 argv[2], argv[3], argv[4]);
665 }
666
667 DEFUN (accept_lifetime_duration_month_day,
668 accept_lifetime_duration_month_day_cmd,
669 "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> duration <1-2147483646>",
670 "Set accept lifetime of the key\n"
671 "Time to start\n"
672 "Month of the year to start\n"
673 "Day of th month to start\n"
674 "Year to start\n"
675 "Duration of the key\n"
676 "Duration seconds\n")
677 {
678 VTY_DECLVAR_CONTEXT_SUB (key, key);
679
680 return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[2],
681 argv[1], argv[3], argv[4]);
682 }
683
684 DEFUN (send_lifetime_day_month_day_month,
685 send_lifetime_day_month_day_month_cmd,
686 "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
687 "Set send lifetime of the key\n"
688 "Time to start\n"
689 "Day of th month to start\n"
690 "Month of the year to start\n"
691 "Year to start\n"
692 "Time to expire\n"
693 "Day of th month to expire\n"
694 "Month of the year to expire\n"
695 "Year to expire\n")
696 {
697 VTY_DECLVAR_CONTEXT_SUB (key, key);
698
699 return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3],
700 argv[4], argv[5], argv[6], argv[7]);
701 }
702
703 DEFUN (send_lifetime_day_month_month_day,
704 send_lifetime_day_month_month_day_cmd,
705 "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
706 "Set send lifetime of the key\n"
707 "Time to start\n"
708 "Day of th month to start\n"
709 "Month of the year to start\n"
710 "Year to start\n"
711 "Time to expire\n"
712 "Month of the year to expire\n"
713 "Day of th month to expire\n"
714 "Year to expire\n")
715 {
716 VTY_DECLVAR_CONTEXT_SUB (key, key);
717
718 return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3],
719 argv[4], argv[6], argv[5], argv[7]);
720 }
721
722 DEFUN (send_lifetime_month_day_day_month,
723 send_lifetime_month_day_day_month_cmd,
724 "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
725 "Set send lifetime of the key\n"
726 "Time to start\n"
727 "Month of the year to start\n"
728 "Day of th month to start\n"
729 "Year to start\n"
730 "Time to expire\n"
731 "Day of th month to expire\n"
732 "Month of the year to expire\n"
733 "Year to expire\n")
734 {
735 VTY_DECLVAR_CONTEXT_SUB (key, key);
736
737 return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3],
738 argv[4], argv[5], argv[6], argv[7]);
739 }
740
741 DEFUN (send_lifetime_month_day_month_day,
742 send_lifetime_month_day_month_day_cmd,
743 "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
744 "Set send lifetime of the key\n"
745 "Time to start\n"
746 "Month of the year to start\n"
747 "Day of th month to start\n"
748 "Year to start\n"
749 "Time to expire\n"
750 "Month of the year to expire\n"
751 "Day of th month to expire\n"
752 "Year to expire\n")
753 {
754 VTY_DECLVAR_CONTEXT_SUB (key, key);
755
756 return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3],
757 argv[4], argv[6], argv[5], argv[7]);
758 }
759
760 DEFUN (send_lifetime_infinite_day_month,
761 send_lifetime_infinite_day_month_cmd,
762 "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> infinite",
763 "Set send lifetime of the key\n"
764 "Time to start\n"
765 "Day of th month to start\n"
766 "Month of the year to start\n"
767 "Year to start\n"
768 "Never expires")
769 {
770 VTY_DECLVAR_CONTEXT_SUB (key, key);
771
772 return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[1], argv[2],
773 argv[3]);
774 }
775
776 DEFUN (send_lifetime_infinite_month_day,
777 send_lifetime_infinite_month_day_cmd,
778 "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> infinite",
779 "Set send lifetime of the key\n"
780 "Time to start\n"
781 "Month of the year to start\n"
782 "Day of th month to start\n"
783 "Year to start\n"
784 "Never expires")
785 {
786 VTY_DECLVAR_CONTEXT_SUB (key, key);
787
788 return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[2], argv[1],
789 argv[3]);
790 }
791
792 DEFUN (send_lifetime_duration_day_month,
793 send_lifetime_duration_day_month_cmd,
794 "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> duration <1-2147483646>",
795 "Set send lifetime of the key\n"
796 "Time to start\n"
797 "Day of th month to start\n"
798 "Month of the year to start\n"
799 "Year to start\n"
800 "Duration of the key\n"
801 "Duration seconds\n")
802 {
803 VTY_DECLVAR_CONTEXT_SUB (key, key);
804
805 return key_lifetime_duration_set (vty, &key->send, argv[0], argv[1], argv[2],
806 argv[3], argv[4]);
807 }
808
809 DEFUN (send_lifetime_duration_month_day,
810 send_lifetime_duration_month_day_cmd,
811 "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> duration <1-2147483646>",
812 "Set send lifetime of the key\n"
813 "Time to start\n"
814 "Month of the year to start\n"
815 "Day of th month to start\n"
816 "Year to start\n"
817 "Duration of the key\n"
818 "Duration seconds\n")
819 {
820 VTY_DECLVAR_CONTEXT_SUB (key, key);
821
822 return key_lifetime_duration_set (vty, &key->send, argv[0], argv[2], argv[1],
823 argv[3], argv[4]);
824 }
825
826 static struct cmd_node keychain_node =
827 {
828 KEYCHAIN_NODE,
829 "%s(config-keychain)# ",
830 1
831 };
832
833 static struct cmd_node keychain_key_node =
834 {
835 KEYCHAIN_KEY_NODE,
836 "%s(config-keychain-key)# ",
837 1
838 };
839
840 static int
841 keychain_strftime (char *buf, int bufsiz, time_t *time)
842 {
843 struct tm *tm;
844 size_t len;
845
846 tm = localtime (time);
847
848 len = strftime (buf, bufsiz, "%T %b %d %Y", tm);
849
850 return len;
851 }
852
853 static int
854 keychain_config_write (struct vty *vty)
855 {
856 struct keychain *keychain;
857 struct key *key;
858 struct listnode *node;
859 struct listnode *knode;
860 char buf[BUFSIZ];
861
862 for (ALL_LIST_ELEMENTS_RO (keychain_list, node, keychain))
863 {
864 vty_out (vty, "key chain %s%s", keychain->name, VTY_NEWLINE);
865
866 for (ALL_LIST_ELEMENTS_RO (keychain->key, knode, key))
867 {
868 vty_out (vty, " key %d%s", key->index, VTY_NEWLINE);
869
870 if (key->string)
871 vty_out (vty, " key-string %s%s", key->string, VTY_NEWLINE);
872
873 if (key->accept.start)
874 {
875 keychain_strftime (buf, BUFSIZ, &key->accept.start);
876 vty_out (vty, " accept-lifetime %s", buf);
877
878 if (key->accept.end == -1)
879 vty_out (vty, " infinite");
880 else if (key->accept.duration)
881 vty_out (vty, " duration %ld",
882 (long)(key->accept.end - key->accept.start));
883 else
884 {
885 keychain_strftime (buf, BUFSIZ, &key->accept.end);
886 vty_out (vty, " %s", buf);
887 }
888 vty_out (vty, "%s", VTY_NEWLINE);
889 }
890
891 if (key->send.start)
892 {
893 keychain_strftime (buf, BUFSIZ, &key->send.start);
894 vty_out (vty, " send-lifetime %s", buf);
895
896 if (key->send.end == -1)
897 vty_out (vty, " infinite");
898 else if (key->send.duration)
899 vty_out (vty, " duration %ld", (long)(key->send.end - key->send.start));
900 else
901 {
902 keychain_strftime (buf, BUFSIZ, &key->send.end);
903 vty_out (vty, " %s", buf);
904 }
905 vty_out (vty, "%s", VTY_NEWLINE);
906 }
907 }
908 vty_out (vty, "!%s", VTY_NEWLINE);
909 }
910
911 return 0;
912 }
913
914 void
915 keychain_init ()
916 {
917 keychain_list = list_new ();
918
919 install_node (&keychain_node, keychain_config_write);
920 install_node (&keychain_key_node, NULL);
921
922 install_default (KEYCHAIN_NODE);
923 install_default (KEYCHAIN_KEY_NODE);
924
925 install_element (CONFIG_NODE, &key_chain_cmd);
926 install_element (CONFIG_NODE, &no_key_chain_cmd);
927 install_element (KEYCHAIN_NODE, &key_cmd);
928 install_element (KEYCHAIN_NODE, &no_key_cmd);
929
930 install_element (KEYCHAIN_NODE, &key_chain_cmd);
931 install_element (KEYCHAIN_NODE, &no_key_chain_cmd);
932
933 install_element (KEYCHAIN_KEY_NODE, &key_string_cmd);
934 install_element (KEYCHAIN_KEY_NODE, &no_key_string_cmd);
935
936 install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
937 install_element (KEYCHAIN_KEY_NODE, &no_key_chain_cmd);
938
939 install_element (KEYCHAIN_KEY_NODE, &key_cmd);
940 install_element (KEYCHAIN_KEY_NODE, &no_key_cmd);
941
942 install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_day_month_day_month_cmd);
943 install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_day_month_month_day_cmd);
944 install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_month_day_day_month_cmd);
945 install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_month_day_month_day_cmd);
946 install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_infinite_day_month_cmd);
947 install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_infinite_month_day_cmd);
948 install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_duration_day_month_cmd);
949 install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_duration_month_day_cmd);
950
951 install_element (KEYCHAIN_KEY_NODE, &send_lifetime_day_month_day_month_cmd);
952 install_element (KEYCHAIN_KEY_NODE, &send_lifetime_day_month_month_day_cmd);
953 install_element (KEYCHAIN_KEY_NODE, &send_lifetime_month_day_day_month_cmd);
954 install_element (KEYCHAIN_KEY_NODE, &send_lifetime_month_day_month_day_cmd);
955 install_element (KEYCHAIN_KEY_NODE, &send_lifetime_infinite_day_month_cmd);
956 install_element (KEYCHAIN_KEY_NODE, &send_lifetime_infinite_month_day_cmd);
957 install_element (KEYCHAIN_KEY_NODE, &send_lifetime_duration_day_month_cmd);
958 install_element (KEYCHAIN_KEY_NODE, &send_lifetime_duration_month_day_cmd);
959 }