]> git.proxmox.com Git - mirror_frr.git/blob - lib/keychain.c
*: Properly use memset() when zeroing
[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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22 #include <zebra.h>
23
24 #include "command.h"
25 #include "memory.h"
26 #include "linklist.h"
27 #include "keychain.h"
28
29 DEFINE_MTYPE_STATIC(LIB, KEY, "Key");
30 DEFINE_MTYPE_STATIC(LIB, KEYCHAIN, "Key chain");
31
32 DEFINE_QOBJ_TYPE(keychain);
33 DEFINE_QOBJ_TYPE(key);
34
35 /* Master list of key chain. */
36 static struct list *keychain_list;
37
38 static struct keychain *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 keychain_free(struct keychain *keychain)
47 {
48 QOBJ_UNREG(keychain);
49 XFREE(MTYPE_KEYCHAIN, keychain);
50 }
51
52 static struct key *key_new(void)
53 {
54 struct key *key = XCALLOC(MTYPE_KEY, sizeof(struct key));
55 QOBJ_REG(key, key);
56 return key;
57 }
58
59 static void key_free(struct key *key)
60 {
61 QOBJ_UNREG(key);
62 XFREE(MTYPE_KEY, key);
63 }
64
65 struct keychain *keychain_lookup(const char *name)
66 {
67 struct listnode *node;
68 struct keychain *keychain;
69
70 if (name == NULL)
71 return NULL;
72
73 for (ALL_LIST_ELEMENTS_RO(keychain_list, node, keychain)) {
74 if (strcmp(keychain->name, name) == 0)
75 return keychain;
76 }
77 return NULL;
78 }
79
80 static int key_cmp_func(void *arg1, void *arg2)
81 {
82 const struct key *k1 = arg1;
83 const struct key *k2 = arg2;
84
85 if (k1->index > k2->index)
86 return 1;
87 if (k1->index < k2->index)
88 return -1;
89 return 0;
90 }
91
92 static void key_delete_func(struct key *key)
93 {
94 if (key->string)
95 free(key->string);
96 key_free(key);
97 }
98
99 static struct keychain *keychain_get(const char *name)
100 {
101 struct keychain *keychain;
102
103 keychain = keychain_lookup(name);
104
105 if (keychain)
106 return keychain;
107
108 keychain = keychain_new();
109 keychain->name = XSTRDUP(MTYPE_KEYCHAIN, name);
110 keychain->key = list_new();
111 keychain->key->cmp = (int (*)(void *, void *))key_cmp_func;
112 keychain->key->del = (void (*)(void *))key_delete_func;
113 listnode_add(keychain_list, keychain);
114
115 return keychain;
116 }
117
118 static void keychain_delete(struct keychain *keychain)
119 {
120 XFREE(MTYPE_KEYCHAIN, keychain->name);
121
122 list_delete(&keychain->key);
123 listnode_delete(keychain_list, keychain);
124 keychain_free(keychain);
125 }
126
127 static struct key *key_lookup(const struct keychain *keychain, uint32_t index)
128 {
129 struct listnode *node;
130 struct key *key;
131
132 for (ALL_LIST_ELEMENTS_RO(keychain->key, node, key)) {
133 if (key->index == index)
134 return key;
135 }
136 return NULL;
137 }
138
139 struct key *key_lookup_for_accept(const struct keychain *keychain,
140 uint32_t index)
141 {
142 struct listnode *node;
143 struct key *key;
144 time_t now;
145
146 now = time(NULL);
147
148 for (ALL_LIST_ELEMENTS_RO(keychain->key, node, key)) {
149 if (key->index >= index) {
150 if (key->accept.start == 0)
151 return key;
152
153 if (key->accept.start <= now)
154 if (key->accept.end >= now
155 || key->accept.end == -1)
156 return key;
157 }
158 }
159 return NULL;
160 }
161
162 struct key *key_match_for_accept(const struct keychain *keychain,
163 const char *auth_str)
164 {
165 struct listnode *node;
166 struct key *key;
167 time_t now;
168
169 now = time(NULL);
170
171 for (ALL_LIST_ELEMENTS_RO(keychain->key, node, key)) {
172 if (key->accept.start == 0
173 || (key->accept.start <= now
174 && (key->accept.end >= now || key->accept.end == -1)))
175 if (key->string && (strncmp(key->string, auth_str, 16) == 0))
176 return key;
177 }
178 return NULL;
179 }
180
181 struct key *key_lookup_for_send(const struct keychain *keychain)
182 {
183 struct listnode *node;
184 struct key *key;
185 time_t now;
186
187 now = time(NULL);
188
189 for (ALL_LIST_ELEMENTS_RO(keychain->key, node, key)) {
190 if (key->send.start == 0)
191 return key;
192
193 if (key->send.start <= now)
194 if (key->send.end >= now || key->send.end == -1)
195 return key;
196 }
197 return NULL;
198 }
199
200 static struct key *key_get(const struct keychain *keychain, uint32_t index)
201 {
202 struct key *key;
203
204 key = key_lookup(keychain, index);
205
206 if (key)
207 return key;
208
209 key = key_new();
210 key->index = index;
211 key->hash_algo = KEYCHAIN_ALGO_NULL;
212 listnode_add_sort(keychain->key, key);
213
214 return key;
215 }
216
217 static void key_delete(struct keychain *keychain, struct key *key)
218 {
219 listnode_delete(keychain->key, key);
220
221 XFREE(MTYPE_KEY, key->string);
222 key_free(key);
223 }
224
225 DEFUN_NOSH (key_chain,
226 key_chain_cmd,
227 "key chain WORD",
228 "Authentication key management\n"
229 "Key-chain management\n"
230 "Key-chain name\n")
231 {
232 int idx_word = 2;
233 struct keychain *keychain;
234
235 keychain = keychain_get(argv[idx_word]->arg);
236 VTY_PUSH_CONTEXT(KEYCHAIN_NODE, keychain);
237
238 return CMD_SUCCESS;
239 }
240
241 DEFUN (no_key_chain,
242 no_key_chain_cmd,
243 "no key chain WORD",
244 NO_STR
245 "Authentication key management\n"
246 "Key-chain management\n"
247 "Key-chain name\n")
248 {
249 int idx_word = 3;
250 struct keychain *keychain;
251
252 keychain = keychain_lookup(argv[idx_word]->arg);
253
254 if (!keychain) {
255 vty_out(vty, "Can't find keychain %s\n", argv[idx_word]->arg);
256 return CMD_WARNING_CONFIG_FAILED;
257 }
258
259 keychain_delete(keychain);
260
261 return CMD_SUCCESS;
262 }
263
264 DEFUN_NOSH (key,
265 key_cmd,
266 "key (0-2147483647)",
267 "Configure a key\n"
268 "Key identifier number\n")
269 {
270 int idx_number = 1;
271 VTY_DECLVAR_CONTEXT(keychain, keychain);
272 struct key *key;
273 uint32_t index;
274
275 index = strtoul(argv[idx_number]->arg, NULL, 10);
276 key = key_get(keychain, index);
277 VTY_PUSH_CONTEXT_SUB(KEYCHAIN_KEY_NODE, key);
278
279 return CMD_SUCCESS;
280 }
281
282 DEFUN (no_key,
283 no_key_cmd,
284 "no key (0-2147483647)",
285 NO_STR
286 "Delete a key\n"
287 "Key identifier number\n")
288 {
289 int idx_number = 2;
290 VTY_DECLVAR_CONTEXT(keychain, keychain);
291 struct key *key;
292 uint32_t index;
293
294 index = strtoul(argv[idx_number]->arg, NULL, 10);
295 key = key_lookup(keychain, index);
296 if (!key) {
297 vty_out(vty, "Can't find key %d\n", index);
298 return CMD_WARNING_CONFIG_FAILED;
299 }
300
301 key_delete(keychain, key);
302
303 vty->node = KEYCHAIN_NODE;
304
305 return CMD_SUCCESS;
306 }
307
308 DEFUN (key_string,
309 key_string_cmd,
310 "key-string LINE",
311 "Set key string\n"
312 "The key\n")
313 {
314 int idx_line = 1;
315 VTY_DECLVAR_CONTEXT_SUB(key, key);
316
317 if (key->string)
318 XFREE(MTYPE_KEY, key->string);
319 key->string = XSTRDUP(MTYPE_KEY, argv[idx_line]->arg);
320
321 return CMD_SUCCESS;
322 }
323
324 DEFUN (no_key_string,
325 no_key_string_cmd,
326 "no key-string [LINE]",
327 NO_STR
328 "Unset key string\n"
329 "The key\n")
330 {
331 VTY_DECLVAR_CONTEXT_SUB(key, key);
332
333 if (key->string) {
334 XFREE(MTYPE_KEY, key->string);
335 key->string = NULL;
336 }
337
338 return CMD_SUCCESS;
339 }
340
341 const struct keychain_algo_info algo_info[] = {
342 {KEYCHAIN_ALGO_NULL, "null", 0, 0, "NULL"},
343 {KEYCHAIN_ALGO_MD5, "md5", KEYCHAIN_MD5_HASH_SIZE,
344 KEYCHAIN_ALGO_MD5_INTERNAL_BLK_SIZE, "MD5"},
345 {KEYCHAIN_ALGO_HMAC_SHA1, "hmac-sha-1", KEYCHAIN_HMAC_SHA1_HASH_SIZE,
346 KEYCHAIN_ALGO_SHA1_INTERNAL_BLK_SIZE, "HMAC-SHA-1"},
347 {KEYCHAIN_ALGO_HMAC_SHA256, "hmac-sha-256",
348 KEYCHAIN_HMAC_SHA256_HASH_SIZE, KEYCHAIN_ALGO_SHA256_INTERNAL_BLK_SIZE,
349 "HMAC-SHA-256"},
350 {KEYCHAIN_ALGO_HMAC_SHA384, "hmac-sha-384",
351 KEYCHAIN_HMAC_SHA384_HASH_SIZE, KEYCHAIN_ALGO_SHA384_INTERNAL_BLK_SIZE,
352 "HMAC-SHA-384"},
353 {KEYCHAIN_ALGO_HMAC_SHA512, "hmac-sha-512",
354 KEYCHAIN_HMAC_SHA512_HASH_SIZE, KEYCHAIN_ALGO_SHA512_INTERNAL_BLK_SIZE,
355 "HMAC-SHA-512"},
356 {KEYCHAIN_ALGO_MAX, "max", KEYCHAIN_MAX_HASH_SIZE,
357 KEYCHAIN_ALGO_MAX_INTERNAL_BLK_SIZE, "Not defined"}
358 };
359
360 uint16_t keychain_get_block_size(enum keychain_hash_algo key)
361 {
362 return algo_info[key].block;
363 }
364
365 uint16_t keychain_get_hash_len(enum keychain_hash_algo key)
366 {
367 return algo_info[key].length;
368 }
369
370 const char *keychain_get_description(enum keychain_hash_algo key)
371 {
372 return algo_info[key].desc;
373 }
374
375 struct keychain_algo_info
376 keychain_get_hash_algo_info(enum keychain_hash_algo key)
377 {
378 return algo_info[key];
379 }
380
381 enum keychain_hash_algo keychain_get_algo_id_by_name(const char *name)
382 {
383 #ifdef CRYPTO_INTERNAL
384 if (!strncmp(name, "hmac-sha-2", 10))
385 return KEYCHAIN_ALGO_HMAC_SHA256;
386 else if (!strncmp(name, "m", 1))
387 return KEYCHAIN_ALGO_MD5;
388 else
389 return KEYCHAIN_ALGO_NULL;
390 #else
391 if (!strncmp(name, "m", 1))
392 return KEYCHAIN_ALGO_MD5;
393 else if (!strncmp(name, "hmac-sha-1", 10))
394 return KEYCHAIN_ALGO_HMAC_SHA1;
395 else if (!strncmp(name, "hmac-sha-2", 10))
396 return KEYCHAIN_ALGO_HMAC_SHA256;
397 else if (!strncmp(name, "hmac-sha-3", 10))
398 return KEYCHAIN_ALGO_HMAC_SHA384;
399 else if (!strncmp(name, "hmac-sha-5", 10))
400 return KEYCHAIN_ALGO_HMAC_SHA512;
401 else
402 return KEYCHAIN_ALGO_NULL;
403 #endif
404 }
405
406 const char *keychain_get_algo_name_by_id(enum keychain_hash_algo key)
407 {
408 return algo_info[key].name;
409 }
410
411 DEFUN(cryptographic_algorithm, cryptographic_algorithm_cmd,
412 "cryptographic-algorithm "
413 "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512>",
414 "Cryptographic-algorithm\n"
415 "Use MD5 algorithm\n"
416 "Use HMAC-SHA-1 algorithm\n"
417 "Use HMAC-SHA-256 algorithm\n"
418 "Use HMAC-SHA-384 algorithm\n"
419 "Use HMAC-SHA-512 algorithm\n")
420 {
421 int algo_idx = 1;
422 uint8_t hash_algo = KEYCHAIN_ALGO_NULL;
423
424 VTY_DECLVAR_CONTEXT_SUB(key, key);
425 hash_algo = keychain_get_algo_id_by_name(argv[algo_idx]->arg);
426 #ifndef CRYPTO_OPENSSL
427 if (hash_algo == KEYCHAIN_ALGO_NULL) {
428 vty_out(vty,
429 "Hash algorithm not supported, compile with --with-crypto=openssl\n");
430 return CMD_WARNING_CONFIG_FAILED;
431 }
432 #endif /* CRYPTO_OPENSSL */
433 key->hash_algo = hash_algo;
434 return CMD_SUCCESS;
435 }
436
437 DEFUN(no_cryptographic_algorithm, no_cryptographic_algorithm_cmd,
438 "no cryptographic-algorithm "
439 "[<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512>]",
440 NO_STR
441 "Cryptographic-algorithm\n"
442 "Use MD5 algorithm\n"
443 "Use HMAC-SHA-1 algorithm\n"
444 "Use HMAC-SHA-256 algorithm\n"
445 "Use HMAC-SHA-384 algorithm\n"
446 "Use HMAC-SHA-512 algorithm\n")
447 {
448 int algo_idx = 2;
449 uint8_t hash_algo = KEYCHAIN_ALGO_NULL;
450
451 VTY_DECLVAR_CONTEXT_SUB(key, key);
452 if (argc > algo_idx) {
453 hash_algo = keychain_get_algo_id_by_name(argv[algo_idx]->arg);
454 if (hash_algo == KEYCHAIN_ALGO_NULL) {
455 vty_out(vty,
456 "Hash algorithm not supported, try compiling with --with-crypto=openssl\n");
457 return CMD_WARNING_CONFIG_FAILED;
458 }
459 }
460
461 if ((hash_algo != KEYCHAIN_ALGO_NULL) && (hash_algo != key->hash_algo))
462 return CMD_SUCCESS;
463
464 key->hash_algo = KEYCHAIN_ALGO_NULL;
465 return CMD_SUCCESS;
466 }
467
468 /* Convert HH:MM:SS MON DAY YEAR to time_t value. -1 is returned when
469 given string is malformed. */
470 static time_t key_str2time(const char *time_str, const char *day_str,
471 const char *month_str, const char *year_str)
472 {
473 int i = 0;
474 char *colon;
475 struct tm tm;
476 time_t time;
477 unsigned int sec, min, hour;
478 unsigned int day, month, year;
479
480 const char *month_name[] = {
481 "January", "February", "March", "April", "May",
482 "June", "July", "August", "September", "October",
483 "November", "December", NULL};
484
485 #define _GET_LONG_RANGE(V, STR, MMCOND) \
486 { \
487 unsigned long tmpl; \
488 char *endptr = NULL; \
489 tmpl = strtoul((STR), &endptr, 10); \
490 if (*endptr != '\0' || tmpl == ULONG_MAX) \
491 return -1; \
492 if (MMCOND) \
493 return -1; \
494 (V) = tmpl; \
495 }
496 #define GET_LONG_RANGE(V, STR, MIN, MAX) \
497 _GET_LONG_RANGE(V, STR, tmpl<(MIN) || tmpl>(MAX))
498 #define GET_LONG_RANGE0(V, STR, MAX) _GET_LONG_RANGE(V, STR, tmpl > (MAX))
499
500 /* Check hour field of time_str. */
501 colon = strchr(time_str, ':');
502 if (colon == NULL)
503 return -1;
504 *colon = '\0';
505
506 /* Hour must be between 0 and 23. */
507 GET_LONG_RANGE0(hour, time_str, 23);
508
509 /* Check min field of time_str. */
510 time_str = colon + 1;
511 colon = strchr(time_str, ':');
512 if (*time_str == '\0' || colon == NULL)
513 return -1;
514 *colon = '\0';
515
516 /* Min must be between 0 and 59. */
517 GET_LONG_RANGE0(min, time_str, 59);
518
519 /* Check sec field of time_str. */
520 time_str = colon + 1;
521 if (*time_str == '\0')
522 return -1;
523
524 /* Sec must be between 0 and 59. */
525 GET_LONG_RANGE0(sec, time_str, 59);
526
527 /* Check day_str. Day must be <1-31>. */
528 GET_LONG_RANGE(day, day_str, 1, 31);
529
530 /* Check month_str. Month must match month_name. */
531 month = 0;
532 if (strlen(month_str) >= 3)
533 for (i = 0; month_name[i]; i++)
534 if (strncmp(month_str, month_name[i], strlen(month_str))
535 == 0) {
536 month = i;
537 break;
538 }
539 if (!month_name[i])
540 return -1;
541
542 /* Check year_str. Year must be <1993-2035>. */
543 GET_LONG_RANGE(year, year_str, 1993, 2035);
544
545 memset(&tm, 0, sizeof(tm));
546 tm.tm_sec = sec;
547 tm.tm_min = min;
548 tm.tm_hour = hour;
549 tm.tm_mon = month;
550 tm.tm_mday = day;
551 tm.tm_year = year - 1900;
552
553 time = mktime(&tm);
554
555 return time;
556 #undef GET_LONG_RANGE
557 }
558
559 static int key_lifetime_set(struct vty *vty, struct key_range *krange,
560 const char *stime_str, const char *sday_str,
561 const char *smonth_str, const char *syear_str,
562 const char *etime_str, const char *eday_str,
563 const char *emonth_str, const char *eyear_str)
564 {
565 time_t time_start;
566 time_t time_end;
567
568 time_start = key_str2time(stime_str, sday_str, smonth_str, syear_str);
569 if (time_start < 0) {
570 vty_out(vty, "Malformed time value\n");
571 return CMD_WARNING_CONFIG_FAILED;
572 }
573 time_end = key_str2time(etime_str, eday_str, emonth_str, eyear_str);
574
575 if (time_end < 0) {
576 vty_out(vty, "Malformed time value\n");
577 return CMD_WARNING_CONFIG_FAILED;
578 }
579
580 if (time_end <= time_start) {
581 vty_out(vty, "Expire time is not later than start time\n");
582 return CMD_WARNING_CONFIG_FAILED;
583 }
584
585 krange->start = time_start;
586 krange->end = time_end;
587
588 return CMD_SUCCESS;
589 }
590
591 static int key_lifetime_duration_set(struct vty *vty, struct key_range *krange,
592 const char *stime_str,
593 const char *sday_str,
594 const char *smonth_str,
595 const char *syear_str,
596 const char *duration_str)
597 {
598 time_t time_start;
599 uint32_t duration;
600
601 time_start = key_str2time(stime_str, sday_str, smonth_str, syear_str);
602 if (time_start < 0) {
603 vty_out(vty, "Malformed time value\n");
604 return CMD_WARNING_CONFIG_FAILED;
605 }
606 krange->start = time_start;
607
608 duration = strtoul(duration_str, NULL, 10);
609 krange->duration = 1;
610 krange->end = time_start + duration;
611
612 return CMD_SUCCESS;
613 }
614
615 static int key_lifetime_infinite_set(struct vty *vty, struct key_range *krange,
616 const char *stime_str,
617 const char *sday_str,
618 const char *smonth_str,
619 const char *syear_str)
620 {
621 time_t time_start;
622
623 time_start = key_str2time(stime_str, sday_str, smonth_str, syear_str);
624 if (time_start < 0) {
625 vty_out(vty, "Malformed time value\n");
626 return CMD_WARNING_CONFIG_FAILED;
627 }
628 krange->start = time_start;
629
630 krange->end = -1;
631
632 return CMD_SUCCESS;
633 }
634
635 DEFUN (accept_lifetime_day_month_day_month,
636 accept_lifetime_day_month_day_month_cmd,
637 "accept-lifetime HH:MM:SS (1-31) MONTH (1993-2035) HH:MM:SS (1-31) MONTH (1993-2035)",
638 "Set accept lifetime of the key\n"
639 "Time to start\n"
640 "Day of th month to start\n"
641 "Month of the year to start\n"
642 "Year to start\n"
643 "Time to expire\n"
644 "Day of th month to expire\n"
645 "Month of the year to expire\n"
646 "Year to expire\n")
647 {
648 int idx_hhmmss = 1;
649 int idx_number = 2;
650 int idx_month = 3;
651 int idx_number_2 = 4;
652 int idx_hhmmss_2 = 5;
653 int idx_number_3 = 6;
654 int idx_month_2 = 7;
655 int idx_number_4 = 8;
656 VTY_DECLVAR_CONTEXT_SUB(key, key);
657
658 return key_lifetime_set(
659 vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
660 argv[idx_month]->arg, argv[idx_number_2]->arg,
661 argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg,
662 argv[idx_month_2]->arg, argv[idx_number_4]->arg);
663 }
664
665 DEFUN (accept_lifetime_day_month_month_day,
666 accept_lifetime_day_month_month_day_cmd,
667 "accept-lifetime HH:MM:SS (1-31) MONTH (1993-2035) HH:MM:SS MONTH (1-31) (1993-2035)",
668 "Set accept lifetime of the key\n"
669 "Time to start\n"
670 "Day of th month to start\n"
671 "Month of the year to start\n"
672 "Year to start\n"
673 "Time to expire\n"
674 "Month of the year to expire\n"
675 "Day of th month to expire\n"
676 "Year to expire\n")
677 {
678 int idx_hhmmss = 1;
679 int idx_number = 2;
680 int idx_month = 3;
681 int idx_number_2 = 4;
682 int idx_hhmmss_2 = 5;
683 int idx_month_2 = 6;
684 int idx_number_3 = 7;
685 int idx_number_4 = 8;
686 VTY_DECLVAR_CONTEXT_SUB(key, key);
687
688 return key_lifetime_set(
689 vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
690 argv[idx_month]->arg, argv[idx_number_2]->arg,
691 argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg,
692 argv[idx_month_2]->arg, argv[idx_number_4]->arg);
693 }
694
695 DEFUN (accept_lifetime_month_day_day_month,
696 accept_lifetime_month_day_day_month_cmd,
697 "accept-lifetime HH:MM:SS MONTH (1-31) (1993-2035) HH:MM:SS (1-31) MONTH (1993-2035)",
698 "Set accept lifetime of the key\n"
699 "Time to start\n"
700 "Month of the year to start\n"
701 "Day of th month to start\n"
702 "Year to start\n"
703 "Time to expire\n"
704 "Day of th month to expire\n"
705 "Month of the year to expire\n"
706 "Year to expire\n")
707 {
708 int idx_hhmmss = 1;
709 int idx_month = 2;
710 int idx_number = 3;
711 int idx_number_2 = 4;
712 int idx_hhmmss_2 = 5;
713 int idx_number_3 = 6;
714 int idx_month_2 = 7;
715 int idx_number_4 = 8;
716 VTY_DECLVAR_CONTEXT_SUB(key, key);
717
718 return key_lifetime_set(
719 vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
720 argv[idx_month]->arg, argv[idx_number_2]->arg,
721 argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg,
722 argv[idx_month_2]->arg, argv[idx_number_4]->arg);
723 }
724
725 DEFUN (accept_lifetime_month_day_month_day,
726 accept_lifetime_month_day_month_day_cmd,
727 "accept-lifetime HH:MM:SS MONTH (1-31) (1993-2035) HH:MM:SS MONTH (1-31) (1993-2035)",
728 "Set accept lifetime of the key\n"
729 "Time to start\n"
730 "Month of the year to start\n"
731 "Day of th month to start\n"
732 "Year to start\n"
733 "Time to expire\n"
734 "Month of the year to expire\n"
735 "Day of th month to expire\n"
736 "Year to expire\n")
737 {
738 int idx_hhmmss = 1;
739 int idx_month = 2;
740 int idx_number = 3;
741 int idx_number_2 = 4;
742 int idx_hhmmss_2 = 5;
743 int idx_month_2 = 6;
744 int idx_number_3 = 7;
745 int idx_number_4 = 8;
746 VTY_DECLVAR_CONTEXT_SUB(key, key);
747
748 return key_lifetime_set(
749 vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
750 argv[idx_month]->arg, argv[idx_number_2]->arg,
751 argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg,
752 argv[idx_month_2]->arg, argv[idx_number_4]->arg);
753 }
754
755 DEFUN (accept_lifetime_infinite_day_month,
756 accept_lifetime_infinite_day_month_cmd,
757 "accept-lifetime HH:MM:SS (1-31) MONTH (1993-2035) infinite",
758 "Set accept lifetime of the key\n"
759 "Time to start\n"
760 "Day of th month to start\n"
761 "Month of the year to start\n"
762 "Year to start\n"
763 "Never expires\n")
764 {
765 int idx_hhmmss = 1;
766 int idx_number = 2;
767 int idx_month = 3;
768 int idx_number_2 = 4;
769 VTY_DECLVAR_CONTEXT_SUB(key, key);
770
771 return key_lifetime_infinite_set(
772 vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
773 argv[idx_month]->arg, argv[idx_number_2]->arg);
774 }
775
776 DEFUN (accept_lifetime_infinite_month_day,
777 accept_lifetime_infinite_month_day_cmd,
778 "accept-lifetime HH:MM:SS MONTH (1-31) (1993-2035) infinite",
779 "Set accept 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\n")
785 {
786 int idx_hhmmss = 1;
787 int idx_month = 2;
788 int idx_number = 3;
789 int idx_number_2 = 4;
790 VTY_DECLVAR_CONTEXT_SUB(key, key);
791
792 return key_lifetime_infinite_set(
793 vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
794 argv[idx_month]->arg, argv[idx_number_2]->arg);
795 }
796
797 DEFUN (accept_lifetime_duration_day_month,
798 accept_lifetime_duration_day_month_cmd,
799 "accept-lifetime HH:MM:SS (1-31) MONTH (1993-2035) duration (1-2147483646)",
800 "Set accept lifetime of the key\n"
801 "Time to start\n"
802 "Day of th month to start\n"
803 "Month of the year to start\n"
804 "Year to start\n"
805 "Duration of the key\n"
806 "Duration seconds\n")
807 {
808 int idx_hhmmss = 1;
809 int idx_number = 2;
810 int idx_month = 3;
811 int idx_number_2 = 4;
812 int idx_number_3 = 6;
813 VTY_DECLVAR_CONTEXT_SUB(key, key);
814
815 return key_lifetime_duration_set(
816 vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
817 argv[idx_month]->arg, argv[idx_number_2]->arg,
818 argv[idx_number_3]->arg);
819 }
820
821 DEFUN (accept_lifetime_duration_month_day,
822 accept_lifetime_duration_month_day_cmd,
823 "accept-lifetime HH:MM:SS MONTH (1-31) (1993-2035) duration (1-2147483646)",
824 "Set accept lifetime of the key\n"
825 "Time to start\n"
826 "Month of the year to start\n"
827 "Day of th month to start\n"
828 "Year to start\n"
829 "Duration of the key\n"
830 "Duration seconds\n")
831 {
832 int idx_hhmmss = 1;
833 int idx_month = 2;
834 int idx_number = 3;
835 int idx_number_2 = 4;
836 int idx_number_3 = 6;
837 VTY_DECLVAR_CONTEXT_SUB(key, key);
838
839 return key_lifetime_duration_set(
840 vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
841 argv[idx_month]->arg, argv[idx_number_2]->arg,
842 argv[idx_number_3]->arg);
843 }
844
845 DEFUN (no_accept_lifetime,
846 no_accept_lifetime_cmd,
847 "no accept-lifetime",
848 NO_STR
849 "Unset accept-lifetime\n")
850 {
851 VTY_DECLVAR_CONTEXT_SUB(key, key);
852
853 if (key->accept.start)
854 key->accept.start = 0;
855 if (key->accept.end)
856 key->accept.end = 0;
857 if (key->accept.duration)
858 key->accept.duration = 0;
859
860 return CMD_SUCCESS;
861 }
862
863 DEFUN (send_lifetime_day_month_day_month,
864 send_lifetime_day_month_day_month_cmd,
865 "send-lifetime HH:MM:SS (1-31) MONTH (1993-2035) HH:MM:SS (1-31) MONTH (1993-2035)",
866 "Set send lifetime of the key\n"
867 "Time to start\n"
868 "Day of th month to start\n"
869 "Month of the year to start\n"
870 "Year to start\n"
871 "Time to expire\n"
872 "Day of th month to expire\n"
873 "Month of the year to expire\n"
874 "Year to expire\n")
875 {
876 int idx_hhmmss = 1;
877 int idx_number = 2;
878 int idx_month = 3;
879 int idx_number_2 = 4;
880 int idx_hhmmss_2 = 5;
881 int idx_number_3 = 6;
882 int idx_month_2 = 7;
883 int idx_number_4 = 8;
884 VTY_DECLVAR_CONTEXT_SUB(key, key);
885
886 return key_lifetime_set(
887 vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
888 argv[idx_month]->arg, argv[idx_number_2]->arg,
889 argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg,
890 argv[idx_month_2]->arg, argv[idx_number_4]->arg);
891 }
892
893 DEFUN (send_lifetime_day_month_month_day,
894 send_lifetime_day_month_month_day_cmd,
895 "send-lifetime HH:MM:SS (1-31) MONTH (1993-2035) HH:MM:SS MONTH (1-31) (1993-2035)",
896 "Set send lifetime of the key\n"
897 "Time to start\n"
898 "Day of th month to start\n"
899 "Month of the year to start\n"
900 "Year to start\n"
901 "Time to expire\n"
902 "Month of the year to expire\n"
903 "Day of th month to expire\n"
904 "Year to expire\n")
905 {
906 int idx_hhmmss = 1;
907 int idx_number = 2;
908 int idx_month = 3;
909 int idx_number_2 = 4;
910 int idx_hhmmss_2 = 5;
911 int idx_month_2 = 6;
912 int idx_number_3 = 7;
913 int idx_number_4 = 8;
914 VTY_DECLVAR_CONTEXT_SUB(key, key);
915
916 return key_lifetime_set(
917 vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
918 argv[idx_month]->arg, argv[idx_number_2]->arg,
919 argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg,
920 argv[idx_month_2]->arg, argv[idx_number_4]->arg);
921 }
922
923 DEFUN (send_lifetime_month_day_day_month,
924 send_lifetime_month_day_day_month_cmd,
925 "send-lifetime HH:MM:SS MONTH (1-31) (1993-2035) HH:MM:SS (1-31) MONTH (1993-2035)",
926 "Set send lifetime of the key\n"
927 "Time to start\n"
928 "Month of the year to start\n"
929 "Day of th month to start\n"
930 "Year to start\n"
931 "Time to expire\n"
932 "Day of th month to expire\n"
933 "Month of the year to expire\n"
934 "Year to expire\n")
935 {
936 int idx_hhmmss = 1;
937 int idx_month = 2;
938 int idx_number = 3;
939 int idx_number_2 = 4;
940 int idx_hhmmss_2 = 5;
941 int idx_number_3 = 6;
942 int idx_month_2 = 7;
943 int idx_number_4 = 8;
944 VTY_DECLVAR_CONTEXT_SUB(key, key);
945
946 return key_lifetime_set(
947 vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
948 argv[idx_month]->arg, argv[idx_number_2]->arg,
949 argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg,
950 argv[idx_month_2]->arg, argv[idx_number_4]->arg);
951 }
952
953 DEFUN (send_lifetime_month_day_month_day,
954 send_lifetime_month_day_month_day_cmd,
955 "send-lifetime HH:MM:SS MONTH (1-31) (1993-2035) HH:MM:SS MONTH (1-31) (1993-2035)",
956 "Set send lifetime of the key\n"
957 "Time to start\n"
958 "Month of the year to start\n"
959 "Day of th month to start\n"
960 "Year to start\n"
961 "Time to expire\n"
962 "Month of the year to expire\n"
963 "Day of th month to expire\n"
964 "Year to expire\n")
965 {
966 int idx_hhmmss = 1;
967 int idx_month = 2;
968 int idx_number = 3;
969 int idx_number_2 = 4;
970 int idx_hhmmss_2 = 5;
971 int idx_month_2 = 6;
972 int idx_number_3 = 7;
973 int idx_number_4 = 8;
974 VTY_DECLVAR_CONTEXT_SUB(key, key);
975
976 return key_lifetime_set(
977 vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
978 argv[idx_month]->arg, argv[idx_number_2]->arg,
979 argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg,
980 argv[idx_month_2]->arg, argv[idx_number_4]->arg);
981 }
982
983 DEFUN (send_lifetime_infinite_day_month,
984 send_lifetime_infinite_day_month_cmd,
985 "send-lifetime HH:MM:SS (1-31) MONTH (1993-2035) infinite",
986 "Set send lifetime of the key\n"
987 "Time to start\n"
988 "Day of th month to start\n"
989 "Month of the year to start\n"
990 "Year to start\n"
991 "Never expires\n")
992 {
993 int idx_hhmmss = 1;
994 int idx_number = 2;
995 int idx_month = 3;
996 int idx_number_2 = 4;
997 VTY_DECLVAR_CONTEXT_SUB(key, key);
998
999 return key_lifetime_infinite_set(
1000 vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
1001 argv[idx_month]->arg, argv[idx_number_2]->arg);
1002 }
1003
1004 DEFUN (send_lifetime_infinite_month_day,
1005 send_lifetime_infinite_month_day_cmd,
1006 "send-lifetime HH:MM:SS MONTH (1-31) (1993-2035) infinite",
1007 "Set send lifetime of the key\n"
1008 "Time to start\n"
1009 "Month of the year to start\n"
1010 "Day of th month to start\n"
1011 "Year to start\n"
1012 "Never expires\n")
1013 {
1014 int idx_hhmmss = 1;
1015 int idx_month = 2;
1016 int idx_number = 3;
1017 int idx_number_2 = 4;
1018 VTY_DECLVAR_CONTEXT_SUB(key, key);
1019
1020 return key_lifetime_infinite_set(
1021 vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
1022 argv[idx_month]->arg, argv[idx_number_2]->arg);
1023 }
1024
1025 DEFUN (send_lifetime_duration_day_month,
1026 send_lifetime_duration_day_month_cmd,
1027 "send-lifetime HH:MM:SS (1-31) MONTH (1993-2035) duration (1-2147483646)",
1028 "Set send lifetime of the key\n"
1029 "Time to start\n"
1030 "Day of th month to start\n"
1031 "Month of the year to start\n"
1032 "Year to start\n"
1033 "Duration of the key\n"
1034 "Duration seconds\n")
1035 {
1036 int idx_hhmmss = 1;
1037 int idx_number = 2;
1038 int idx_month = 3;
1039 int idx_number_2 = 4;
1040 int idx_number_3 = 6;
1041 VTY_DECLVAR_CONTEXT_SUB(key, key);
1042
1043 return key_lifetime_duration_set(
1044 vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
1045 argv[idx_month]->arg, argv[idx_number_2]->arg,
1046 argv[idx_number_3]->arg);
1047 }
1048
1049 DEFUN (send_lifetime_duration_month_day,
1050 send_lifetime_duration_month_day_cmd,
1051 "send-lifetime HH:MM:SS MONTH (1-31) (1993-2035) duration (1-2147483646)",
1052 "Set send lifetime of the key\n"
1053 "Time to start\n"
1054 "Month of the year to start\n"
1055 "Day of th month to start\n"
1056 "Year to start\n"
1057 "Duration of the key\n"
1058 "Duration seconds\n")
1059 {
1060 int idx_hhmmss = 1;
1061 int idx_month = 2;
1062 int idx_number = 3;
1063 int idx_number_2 = 4;
1064 int idx_number_3 = 6;
1065 VTY_DECLVAR_CONTEXT_SUB(key, key);
1066
1067 return key_lifetime_duration_set(
1068 vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
1069 argv[idx_month]->arg, argv[idx_number_2]->arg,
1070 argv[idx_number_3]->arg);
1071 }
1072
1073 DEFUN (no_send_lifetime,
1074 no_send_lifetime_cmd,
1075 "no send-lifetime",
1076 NO_STR
1077 "Unset send-lifetime\n")
1078 {
1079 VTY_DECLVAR_CONTEXT_SUB(key, key);
1080
1081 if (key->send.start)
1082 key->send.start = 0;
1083 if (key->send.end)
1084 key->send.end = 0;
1085 if (key->send.duration)
1086 key->send.duration = 0;
1087
1088 return CMD_SUCCESS;
1089 }
1090
1091 static int keychain_config_write(struct vty *vty);
1092 static struct cmd_node keychain_node = {
1093 .name = "keychain",
1094 .node = KEYCHAIN_NODE,
1095 .parent_node = CONFIG_NODE,
1096 .prompt = "%s(config-keychain)# ",
1097 .config_write = keychain_config_write,
1098 };
1099
1100 static struct cmd_node keychain_key_node = {
1101 .name = "keychain key",
1102 .node = KEYCHAIN_KEY_NODE,
1103 .parent_node = KEYCHAIN_NODE,
1104 .prompt = "%s(config-keychain-key)# ",
1105 };
1106
1107 static int keychain_strftime(char *buf, int bufsiz, time_t *time)
1108 {
1109 struct tm tm;
1110 size_t len;
1111
1112 localtime_r(time, &tm);
1113
1114 len = strftime(buf, bufsiz, "%T %b %d %Y", &tm);
1115
1116 return len;
1117 }
1118
1119 static int keychain_config_write(struct vty *vty)
1120 {
1121 struct keychain *keychain;
1122 struct key *key;
1123 struct listnode *node;
1124 struct listnode *knode;
1125 char buf[BUFSIZ];
1126
1127 for (ALL_LIST_ELEMENTS_RO(keychain_list, node, keychain)) {
1128 vty_out(vty, "key chain %s\n", keychain->name);
1129
1130 for (ALL_LIST_ELEMENTS_RO(keychain->key, knode, key)) {
1131 vty_out(vty, " key %d\n", key->index);
1132
1133 if (key->string)
1134 vty_out(vty, " key-string %s\n", key->string);
1135
1136 if (key->hash_algo != KEYCHAIN_ALGO_NULL)
1137 vty_out(vty, " cryptographic-algorithm %s\n",
1138 keychain_get_algo_name_by_id(
1139 key->hash_algo));
1140
1141 if (key->accept.start) {
1142 keychain_strftime(buf, BUFSIZ,
1143 &key->accept.start);
1144 vty_out(vty, " accept-lifetime %s", buf);
1145
1146 if (key->accept.end == -1)
1147 vty_out(vty, " infinite");
1148 else if (key->accept.duration)
1149 vty_out(vty, " duration %ld",
1150 (long)(key->accept.end
1151 - key->accept.start));
1152 else {
1153 keychain_strftime(buf, BUFSIZ,
1154 &key->accept.end);
1155 vty_out(vty, " %s", buf);
1156 }
1157 vty_out(vty, "\n");
1158 }
1159
1160 if (key->send.start) {
1161 keychain_strftime(buf, BUFSIZ,
1162 &key->send.start);
1163 vty_out(vty, " send-lifetime %s", buf);
1164
1165 if (key->send.end == -1)
1166 vty_out(vty, " infinite");
1167 else if (key->send.duration)
1168 vty_out(vty, " duration %ld",
1169 (long)(key->send.end
1170 - key->send.start));
1171 else {
1172 keychain_strftime(buf, BUFSIZ,
1173 &key->send.end);
1174 vty_out(vty, " %s", buf);
1175 }
1176 vty_out(vty, "\n");
1177 }
1178
1179 vty_out(vty, " exit\n");
1180 }
1181 vty_out(vty, "exit\n");
1182 vty_out(vty, "!\n");
1183 }
1184
1185 return 0;
1186 }
1187
1188
1189 static void keychain_active_config(vector comps, struct cmd_token *token)
1190 {
1191 struct keychain *keychain;
1192 struct listnode *node;
1193
1194 for (ALL_LIST_ELEMENTS_RO(keychain_list, node, keychain))
1195 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, keychain->name));
1196 }
1197
1198 static const struct cmd_variable_handler keychain_var_handlers[] = {
1199 {.varname = "key_chain", .completions = keychain_active_config},
1200 {.tokenname = "KEYCHAIN_NAME", .completions = keychain_active_config},
1201 {.tokenname = "KCHAIN_NAME", .completions = keychain_active_config},
1202 {.completions = NULL}
1203 };
1204
1205 void keychain_init(void)
1206 {
1207 keychain_list = list_new();
1208
1209 /* Register handler for keychain auto config support */
1210 cmd_variable_handler_register(keychain_var_handlers);
1211 install_node(&keychain_node);
1212 install_node(&keychain_key_node);
1213
1214 install_default(KEYCHAIN_NODE);
1215 install_default(KEYCHAIN_KEY_NODE);
1216
1217 install_element(CONFIG_NODE, &key_chain_cmd);
1218 install_element(CONFIG_NODE, &no_key_chain_cmd);
1219 install_element(KEYCHAIN_NODE, &key_cmd);
1220 install_element(KEYCHAIN_NODE, &no_key_cmd);
1221
1222 install_element(KEYCHAIN_NODE, &key_chain_cmd);
1223 install_element(KEYCHAIN_NODE, &no_key_chain_cmd);
1224
1225 install_element(KEYCHAIN_KEY_NODE, &key_string_cmd);
1226 install_element(KEYCHAIN_KEY_NODE, &no_key_string_cmd);
1227
1228 install_element(KEYCHAIN_KEY_NODE, &key_chain_cmd);
1229 install_element(KEYCHAIN_KEY_NODE, &no_key_chain_cmd);
1230
1231 install_element(KEYCHAIN_KEY_NODE, &key_cmd);
1232 install_element(KEYCHAIN_KEY_NODE, &no_key_cmd);
1233
1234 install_element(KEYCHAIN_KEY_NODE,
1235 &accept_lifetime_day_month_day_month_cmd);
1236 install_element(KEYCHAIN_KEY_NODE,
1237 &accept_lifetime_day_month_month_day_cmd);
1238 install_element(KEYCHAIN_KEY_NODE,
1239 &accept_lifetime_month_day_day_month_cmd);
1240 install_element(KEYCHAIN_KEY_NODE,
1241 &accept_lifetime_month_day_month_day_cmd);
1242 install_element(KEYCHAIN_KEY_NODE,
1243 &accept_lifetime_infinite_day_month_cmd);
1244 install_element(KEYCHAIN_KEY_NODE,
1245 &accept_lifetime_infinite_month_day_cmd);
1246 install_element(KEYCHAIN_KEY_NODE,
1247 &accept_lifetime_duration_day_month_cmd);
1248 install_element(KEYCHAIN_KEY_NODE,
1249 &accept_lifetime_duration_month_day_cmd);
1250 install_element(KEYCHAIN_KEY_NODE, &no_accept_lifetime_cmd);
1251
1252 install_element(KEYCHAIN_KEY_NODE,
1253 &send_lifetime_day_month_day_month_cmd);
1254 install_element(KEYCHAIN_KEY_NODE,
1255 &send_lifetime_day_month_month_day_cmd);
1256 install_element(KEYCHAIN_KEY_NODE,
1257 &send_lifetime_month_day_day_month_cmd);
1258 install_element(KEYCHAIN_KEY_NODE,
1259 &send_lifetime_month_day_month_day_cmd);
1260 install_element(KEYCHAIN_KEY_NODE,
1261 &send_lifetime_infinite_day_month_cmd);
1262 install_element(KEYCHAIN_KEY_NODE,
1263 &send_lifetime_infinite_month_day_cmd);
1264 install_element(KEYCHAIN_KEY_NODE,
1265 &send_lifetime_duration_day_month_cmd);
1266 install_element(KEYCHAIN_KEY_NODE,
1267 &send_lifetime_duration_month_day_cmd);
1268 install_element(KEYCHAIN_KEY_NODE, &no_send_lifetime_cmd);
1269 install_element(KEYCHAIN_KEY_NODE, &cryptographic_algorithm_cmd);
1270 install_element(KEYCHAIN_KEY_NODE, &no_cryptographic_algorithm_cmd);
1271 }