/* key-chain for authentication.
   Copyright (C) 2000 Kunihiro Ishiguro

This file is part of GNU Zebra.

GNU Zebra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your
option) any later version.

GNU Zebra is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Zebra; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

#include <zebra.h>

#include "command.h"
#include "memory.h"
#include "linklist.h"
#include "keychain.h"

/* Master list of key chain. */
struct list *keychain_list;

static struct keychain *
keychain_new (void)
{
  return XCALLOC (MTYPE_KEYCHAIN, sizeof (struct keychain));
}

static void
keychain_free (struct keychain *keychain)
{
  XFREE (MTYPE_KEYCHAIN, keychain);
}

static struct key *
key_new (void)
{
  return XCALLOC (MTYPE_KEY, sizeof (struct key));
}

static void
key_free (struct key *key)
{
  XFREE (MTYPE_KEY, key);
}

struct keychain *
keychain_lookup (const char *name)
{
  struct listnode *node;
  struct keychain *keychain;

  if (name == NULL)
    return NULL;

  for (ALL_LIST_ELEMENTS_RO (keychain_list, node, keychain))
    {
      if (strcmp (keychain->name, name) == 0)
	return keychain;
    }
  return NULL;
}

static int
key_cmp_func (void *arg1, void *arg2)
{
  const struct key *k1 = arg1;
  const struct key *k2 = arg2;
  
  if (k1->index > k2->index)
    return 1;
  if (k1->index < k2->index)
    return -1;
  return 0;
}

static void
key_delete_func (struct key *key)
{
  if (key->string)
    free (key->string);
  key_free (key);
}

static struct keychain *
keychain_get (const char *name)
{
  struct keychain *keychain;

  keychain = keychain_lookup (name);

  if (keychain)
    return keychain;

  keychain = keychain_new ();
  keychain->name = strdup (name);
  keychain->key = list_new ();
  keychain->key->cmp = (int (*)(void *, void *)) key_cmp_func;
  keychain->key->del = (void (*)(void *)) key_delete_func;
  listnode_add (keychain_list, keychain);

  return keychain;
}

static void
keychain_delete (struct keychain *keychain)
{
  if (keychain->name)
    free (keychain->name);

  list_delete (keychain->key);
  listnode_delete (keychain_list, keychain);
  keychain_free (keychain);
}

static struct key *
key_lookup (const struct keychain *keychain, u_int32_t index)
{
  struct listnode *node;
  struct key *key;

  for (ALL_LIST_ELEMENTS_RO (keychain->key, node, key))
    {
      if (key->index == index)
	return key;
    }
  return NULL;
}

struct key *
key_lookup_for_accept (const struct keychain *keychain, u_int32_t index)
{
  struct listnode *node;
  struct key *key;
  time_t now;

  now = time (NULL);

  for (ALL_LIST_ELEMENTS_RO (keychain->key, node, key))
    {
      if (key->index >= index)
	{
	  if (key->accept.start == 0)
	    return key;

	  if (key->accept.start <= now)
	    if (key->accept.end >= now || key->accept.end == -1)
	      return key;
	}
    }
  return NULL;
}

struct key *
key_match_for_accept (const struct keychain *keychain, const char *auth_str)
{
  struct listnode *node;
  struct key *key;
  time_t now;

  now = time (NULL);

  for (ALL_LIST_ELEMENTS_RO (keychain->key, node, key))
    {
      if (key->accept.start == 0 ||
	  (key->accept.start <= now &&
	   (key->accept.end >= now || key->accept.end == -1)))
	if (strncmp (key->string, auth_str, 16) == 0)
	  return key;
    }
  return NULL;
}

struct key *
key_lookup_for_send (const struct keychain *keychain)
{
  struct listnode *node;
  struct key *key;
  time_t now;

  now = time (NULL);

  for (ALL_LIST_ELEMENTS_RO (keychain->key, node, key))
    {
      if (key->send.start == 0)
	return key;

      if (key->send.start <= now)
	if (key->send.end >= now || key->send.end == -1)
	  return key;
    }
  return NULL;
}

static struct key *
key_get (const struct keychain *keychain, u_int32_t index)
{
  struct key *key;

  key = key_lookup (keychain, index);

  if (key)
    return key;

  key = key_new ();
  key->index = index;
  listnode_add_sort (keychain->key, key);

  return key;
}

static void
key_delete (struct keychain *keychain, struct key *key)
{
  listnode_delete (keychain->key, key);

  if (key->string)
    free (key->string);
  key_free (key);
}

DEFUN (key_chain,
       key_chain_cmd,
       "key chain WORD",
       "Authentication key management\n"
       "Key-chain management\n"
       "Key-chain name\n")
{
  struct keychain *keychain;

  keychain = keychain_get (argv[0]);
  vty->index = keychain;
  vty->node = KEYCHAIN_NODE;

  return CMD_SUCCESS;
}

DEFUN (no_key_chain,
       no_key_chain_cmd,
       "no key chain WORD",
       NO_STR
       "Authentication key management\n"
       "Key-chain management\n"
       "Key-chain name\n")
{
  struct keychain *keychain;

  keychain = keychain_lookup (argv[0]);

  if (! keychain)
    {
      vty_out (vty, "Can't find keychain %s%s", argv[0], VTY_NEWLINE);
      return CMD_WARNING;
    }

  keychain_delete (keychain);

  return CMD_SUCCESS;
}

DEFUN (key,
       key_cmd,
       "key <0-2147483647>",
       "Configure a key\n"
       "Key identifier number\n")
{
  struct keychain *keychain;
  struct key *key;
  u_int32_t index;

  keychain = vty->index;

  VTY_GET_INTEGER ("key identifier", index, argv[0]);
  key = key_get (keychain, index);
  vty->index_sub = key;
  vty->node = KEYCHAIN_KEY_NODE;
  
  return CMD_SUCCESS;
}

DEFUN (no_key,
       no_key_cmd,
       "no key <0-2147483647>",
       NO_STR
       "Delete a key\n"
       "Key identifier number\n")
{
  struct keychain *keychain;
  struct key *key;
  u_int32_t index;
  
  keychain = vty->index;

  VTY_GET_INTEGER ("key identifier", index, argv[0]);
  key = key_lookup (keychain, index);
  if (! key)
    {
      vty_out (vty, "Can't find key %d%s", index, VTY_NEWLINE);
      return CMD_WARNING;
    }

  key_delete (keychain, key);

  vty->node = KEYCHAIN_NODE;

  return CMD_SUCCESS;
}

DEFUN (key_string,
       key_string_cmd,
       "key-string LINE",
       "Set key string\n"
       "The key\n")
{
  struct key *key;

  key = vty->index_sub;

  if (key->string)
    free (key->string);
  key->string = strdup (argv[0]);

  return CMD_SUCCESS;
}

DEFUN (no_key_string,
       no_key_string_cmd,
       "no key-string [LINE]",
       NO_STR
       "Unset key string\n"
       "The key\n")
{
  struct key *key;

  key = vty->index_sub;

  if (key->string)
    {
      free (key->string);
      key->string = NULL;
    }

  return CMD_SUCCESS;
}

/* Convert HH:MM:SS MON DAY YEAR to time_t value.  -1 is returned when
   given string is malformed. */
static time_t 
key_str2time (const char *time_str, const char *day_str, const char *month_str,
	      const char *year_str)
{
  int i = 0;
  char *colon;
  struct tm tm;
  time_t time;
  unsigned int sec, min, hour;
  unsigned int day, month, year;

  const char *month_name[] = 
  {
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
    NULL
  };

#define _GET_LONG_RANGE(V,STR,MMCOND) \
{ \
  unsigned long tmpl; \
  char *endptr = NULL; \
  tmpl = strtoul ((STR), &endptr, 10); \
  if (*endptr != '\0' || tmpl == ULONG_MAX) \
    return -1; \
  if (MMCOND) \
    return -1; \
  (V) = tmpl; \
}
#define GET_LONG_RANGE(V,STR,MIN,MAX) \
        _GET_LONG_RANGE(V,STR,tmpl < (MIN) || tmpl > (MAX))
#define GET_LONG_RANGE0(V,STR,MAX) \
        _GET_LONG_RANGE(V,STR,tmpl > (MAX))

  /* Check hour field of time_str. */
  colon = strchr (time_str, ':');
  if (colon == NULL)
    return -1;
  *colon = '\0';

  /* Hour must be between 0 and 23. */
  GET_LONG_RANGE0 (hour, time_str, 23);

  /* Check min field of time_str. */
  time_str = colon + 1;
  colon = strchr (time_str, ':');
  if (*time_str == '\0' || colon == NULL)
    return -1;
  *colon = '\0';

  /* Min must be between 0 and 59. */
  GET_LONG_RANGE0 (min, time_str, 59);

  /* Check sec field of time_str. */
  time_str = colon + 1;
  if (*time_str == '\0')
    return -1;
  
  /* Sec must be between 0 and 59. */
  GET_LONG_RANGE0 (sec, time_str, 59);
  
  /* Check day_str.  Day must be <1-31>. */
  GET_LONG_RANGE (day, day_str, 1, 31);

  /* Check month_str.  Month must match month_name. */
  month = 0;
  if (strlen (month_str) >= 3)
    for (i = 0; month_name[i]; i++)
      if (strncmp (month_str, month_name[i], strlen (month_str)) == 0)
	{
	  month = i;
	  break;
	}
  if (! month_name[i])
    return -1;

  /* Check year_str.  Year must be <1993-2035>. */
  GET_LONG_RANGE (year, year_str, 1993, 2035);
  
  memset (&tm, 0, sizeof (struct tm));
  tm.tm_sec = sec;
  tm.tm_min = min;
  tm.tm_hour = hour;
  tm.tm_mon = month;
  tm.tm_mday = day;
  tm.tm_year = year - 1900;
    
  time = mktime (&tm);
  
  return time;
#undef GET_LONG_RANGE
}

static int
key_lifetime_set (struct vty *vty, struct key_range *krange,
		  const char *stime_str, const char *sday_str,
		  const char *smonth_str, const char *syear_str,
		  const char *etime_str, const char *eday_str,
		  const char *emonth_str, const char *eyear_str)
{
  time_t time_start;
  time_t time_end;
  
  time_start = key_str2time (stime_str, sday_str, smonth_str, syear_str);
  if (time_start < 0)
    {
      vty_out (vty, "Malformed time value%s", VTY_NEWLINE);
      return CMD_WARNING;
    }
  time_end = key_str2time (etime_str, eday_str, emonth_str, eyear_str);

  if (time_end < 0)
    {
      vty_out (vty, "Malformed time value%s", VTY_NEWLINE);
      return CMD_WARNING;
    }

  if (time_end <= time_start)
    {
      vty_out (vty, "Expire time is not later than start time%s", VTY_NEWLINE);
      return CMD_WARNING;
    }

  krange->start = time_start;
  krange->end = time_end;

  return CMD_SUCCESS;
}

static int
key_lifetime_duration_set (struct vty *vty, struct key_range *krange,
			   const char *stime_str, const char *sday_str,
			   const char *smonth_str, const char *syear_str,
			   const char *duration_str)
{
  time_t time_start;
  u_int32_t duration;
    
  time_start = key_str2time (stime_str, sday_str, smonth_str, syear_str);
  if (time_start < 0)
    {
      vty_out (vty, "Malformed time value%s", VTY_NEWLINE);
      return CMD_WARNING;
    }
  krange->start = time_start;

  VTY_GET_INTEGER ("duration", duration, duration_str);
  krange->duration = 1;
  krange->end = time_start + duration;

  return CMD_SUCCESS;
}

static int
key_lifetime_infinite_set (struct vty *vty, struct key_range *krange,
			   const char *stime_str, const char *sday_str,
			   const char *smonth_str, const char *syear_str)
{
  time_t time_start;
    
  time_start = key_str2time (stime_str, sday_str, smonth_str, syear_str);
  if (time_start < 0)
    {
      vty_out (vty, "Malformed time value%s", VTY_NEWLINE);
      return CMD_WARNING;
    }
  krange->start = time_start;

  krange->end = -1;

  return CMD_SUCCESS;
}

DEFUN (accept_lifetime_day_month_day_month,
       accept_lifetime_day_month_day_month_cmd,
       "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
       "Set accept lifetime of the key\n"
       "Time to start\n"
       "Day of th month to start\n"
       "Month of the year to start\n"
       "Year to start\n"
       "Time to expire\n"
       "Day of th month to expire\n"
       "Month of the year to expire\n"
       "Year to expire\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2],
			   argv[3], argv[4], argv[5], argv[6], argv[7]);
}

DEFUN (accept_lifetime_day_month_month_day,
       accept_lifetime_day_month_month_day_cmd,
       "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
       "Set accept lifetime of the key\n"
       "Time to start\n"
       "Day of th month to start\n"
       "Month of the year to start\n"
       "Year to start\n"
       "Time to expire\n"
       "Month of the year to expire\n"
       "Day of th month to expire\n"
       "Year to expire\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2],
			   argv[3], argv[4], argv[6], argv[5], argv[7]);
}

DEFUN (accept_lifetime_month_day_day_month,
       accept_lifetime_month_day_day_month_cmd,
       "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
       "Set accept lifetime of the key\n"
       "Time to start\n"
       "Month of the year to start\n"
       "Day of th month to start\n"
       "Year to start\n"
       "Time to expire\n"
       "Day of th month to expire\n"
       "Month of the year to expire\n"
       "Year to expire\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1],
			   argv[3], argv[4], argv[5], argv[6], argv[7]);
}

DEFUN (accept_lifetime_month_day_month_day,
       accept_lifetime_month_day_month_day_cmd,
       "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
       "Set accept lifetime of the key\n"
       "Time to start\n"
       "Month of the year to start\n"
       "Day of th month to start\n"
       "Year to start\n"
       "Time to expire\n"
       "Month of the year to expire\n"
       "Day of th month to expire\n"
       "Year to expire\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1],
			   argv[3], argv[4], argv[6], argv[5], argv[7]);
}

DEFUN (accept_lifetime_infinite_day_month,
       accept_lifetime_infinite_day_month_cmd,
       "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> infinite",
       "Set accept lifetime of the key\n"
       "Time to start\n"
       "Day of th month to start\n"
       "Month of the year to start\n"
       "Year to start\n"
       "Never expires")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[1],
				    argv[2], argv[3]);
}

DEFUN (accept_lifetime_infinite_month_day,
       accept_lifetime_infinite_month_day_cmd,
       "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> infinite",
       "Set accept lifetime of the key\n"
       "Time to start\n"
       "Month of the year to start\n"
       "Day of th month to start\n"
       "Year to start\n"
       "Never expires")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[2],
				    argv[1], argv[3]);
}

DEFUN (accept_lifetime_duration_day_month,
       accept_lifetime_duration_day_month_cmd,
       "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> duration <1-2147483646>",
       "Set accept lifetime of the key\n"
       "Time to start\n"
       "Day of th month to start\n"
       "Month of the year to start\n"
       "Year to start\n"
       "Duration of the key\n"
       "Duration seconds\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[1],
				    argv[2], argv[3], argv[4]);
}

DEFUN (accept_lifetime_duration_month_day,
       accept_lifetime_duration_month_day_cmd,
       "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> duration <1-2147483646>",
       "Set accept lifetime of the key\n"
       "Time to start\n"
       "Month of the year to start\n"
       "Day of th month to start\n"
       "Year to start\n"
       "Duration of the key\n"
       "Duration seconds\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[2],
				    argv[1], argv[3], argv[4]);
}

DEFUN (send_lifetime_day_month_day_month,
       send_lifetime_day_month_day_month_cmd,
       "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
       "Set send lifetime of the key\n"
       "Time to start\n"
       "Day of th month to start\n"
       "Month of the year to start\n"
       "Year to start\n"
       "Time to expire\n"
       "Day of th month to expire\n"
       "Month of the year to expire\n"
       "Year to expire\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3],
			   argv[4], argv[5], argv[6], argv[7]);
}

DEFUN (send_lifetime_day_month_month_day,
       send_lifetime_day_month_month_day_cmd,
       "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
       "Set send lifetime of the key\n"
       "Time to start\n"
       "Day of th month to start\n"
       "Month of the year to start\n"
       "Year to start\n"
       "Time to expire\n"
       "Month of the year to expire\n"
       "Day of th month to expire\n"
       "Year to expire\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3],
			   argv[4], argv[6], argv[5], argv[7]);
}

DEFUN (send_lifetime_month_day_day_month,
       send_lifetime_month_day_day_month_cmd,
       "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
       "Set send lifetime of the key\n"
       "Time to start\n"
       "Month of the year to start\n"
       "Day of th month to start\n"
       "Year to start\n"
       "Time to expire\n"
       "Day of th month to expire\n"
       "Month of the year to expire\n"
       "Year to expire\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3],
			   argv[4], argv[5], argv[6], argv[7]);
}

DEFUN (send_lifetime_month_day_month_day,
       send_lifetime_month_day_month_day_cmd,
       "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
       "Set send lifetime of the key\n"
       "Time to start\n"
       "Month of the year to start\n"
       "Day of th month to start\n"
       "Year to start\n"
       "Time to expire\n"
       "Month of the year to expire\n"
       "Day of th month to expire\n"
       "Year to expire\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3],
			   argv[4], argv[6], argv[5], argv[7]);
}

DEFUN (send_lifetime_infinite_day_month,
       send_lifetime_infinite_day_month_cmd,
       "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> infinite",
       "Set send lifetime of the key\n"
       "Time to start\n"
       "Day of th month to start\n"
       "Month of the year to start\n"
       "Year to start\n"
       "Never expires")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[1], argv[2],
				    argv[3]);
}

DEFUN (send_lifetime_infinite_month_day,
       send_lifetime_infinite_month_day_cmd,
       "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> infinite",
       "Set send lifetime of the key\n"
       "Time to start\n"
       "Month of the year to start\n"
       "Day of th month to start\n"
       "Year to start\n"
       "Never expires")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[2], argv[1],
				    argv[3]);
}

DEFUN (send_lifetime_duration_day_month,
       send_lifetime_duration_day_month_cmd,
       "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> duration <1-2147483646>",
       "Set send lifetime of the key\n"
       "Time to start\n"
       "Day of th month to start\n"
       "Month of the year to start\n"
       "Year to start\n"
       "Duration of the key\n"
       "Duration seconds\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_duration_set (vty, &key->send, argv[0], argv[1], argv[2],
				    argv[3], argv[4]);
}

DEFUN (send_lifetime_duration_month_day,
       send_lifetime_duration_month_day_cmd,
       "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> duration <1-2147483646>",
       "Set send lifetime of the key\n"
       "Time to start\n"
       "Month of the year to start\n"
       "Day of th month to start\n"
       "Year to start\n"
       "Duration of the key\n"
       "Duration seconds\n")
{
  struct key *key;

  key = vty->index_sub;

  return key_lifetime_duration_set (vty, &key->send, argv[0], argv[2], argv[1],
				    argv[3], argv[4]);
}

static struct cmd_node keychain_node =
{
  KEYCHAIN_NODE,
  "%s(config-keychain)# ",
  1
};

static struct cmd_node keychain_key_node =
{
  KEYCHAIN_KEY_NODE,
  "%s(config-keychain-key)# ",
  1
};

static int
keychain_strftime (char *buf, int bufsiz, time_t *time)
{
  struct tm *tm;
  size_t len;

  tm = localtime (time);

  len = strftime (buf, bufsiz, "%T %b %d %Y", tm);

  return len;
}

static int
keychain_config_write (struct vty *vty)
{
  struct keychain *keychain;
  struct key *key;
  struct listnode *node;
  struct listnode *knode;
  char buf[BUFSIZ];

  for (ALL_LIST_ELEMENTS_RO (keychain_list, node, keychain))
    {
      vty_out (vty, "key chain %s%s", keychain->name, VTY_NEWLINE);
      
      for (ALL_LIST_ELEMENTS_RO (keychain->key, knode, key))
	{
	  vty_out (vty, " key %d%s", key->index, VTY_NEWLINE);

	  if (key->string)
	    vty_out (vty, "  key-string %s%s", key->string, VTY_NEWLINE);

	  if (key->accept.start)
	    {
	      keychain_strftime (buf, BUFSIZ, &key->accept.start);
	      vty_out (vty, "  accept-lifetime %s", buf);

	      if (key->accept.end == -1)
		vty_out (vty, " infinite");
	      else if (key->accept.duration)
		vty_out (vty, " duration %ld",
			 (long)(key->accept.end - key->accept.start));
	      else
		{
		  keychain_strftime (buf, BUFSIZ, &key->accept.end);
		  vty_out (vty, " %s", buf);
		}
	      vty_out (vty, "%s", VTY_NEWLINE);
	    }

	  if (key->send.start)
	    {
	      keychain_strftime (buf, BUFSIZ, &key->send.start);
	      vty_out (vty, "  send-lifetime %s", buf);

	      if (key->send.end == -1)
		vty_out (vty, " infinite");
	      else if (key->send.duration)
		vty_out (vty, " duration %ld", (long)(key->send.end - key->send.start));
	      else
		{
		  keychain_strftime (buf, BUFSIZ, &key->send.end);
		  vty_out (vty, " %s", buf);
		}
	      vty_out (vty, "%s", VTY_NEWLINE);
	    }
	}
      vty_out (vty, "!%s", VTY_NEWLINE);
    }

  return 0;
}

void
keychain_init ()
{
  keychain_list = list_new ();

  install_node (&keychain_node, keychain_config_write);
  install_node (&keychain_key_node, NULL);

  install_default (KEYCHAIN_NODE);
  install_default (KEYCHAIN_KEY_NODE);

  install_element (CONFIG_NODE, &key_chain_cmd);
  install_element (CONFIG_NODE, &no_key_chain_cmd);
  install_element (KEYCHAIN_NODE, &key_cmd);
  install_element (KEYCHAIN_NODE, &no_key_cmd);

  install_element (KEYCHAIN_NODE, &key_chain_cmd);
  install_element (KEYCHAIN_NODE, &no_key_chain_cmd);

  install_element (KEYCHAIN_KEY_NODE, &key_string_cmd);
  install_element (KEYCHAIN_KEY_NODE, &no_key_string_cmd);

  install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
  install_element (KEYCHAIN_KEY_NODE, &no_key_chain_cmd);

  install_element (KEYCHAIN_KEY_NODE, &key_cmd);
  install_element (KEYCHAIN_KEY_NODE, &no_key_cmd);

  install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_day_month_day_month_cmd);
  install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_day_month_month_day_cmd);
  install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_month_day_day_month_cmd);
  install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_month_day_month_day_cmd);
  install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_infinite_day_month_cmd);
  install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_infinite_month_day_cmd);
  install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_duration_day_month_cmd);
  install_element (KEYCHAIN_KEY_NODE, &accept_lifetime_duration_month_day_cmd);

  install_element (KEYCHAIN_KEY_NODE, &send_lifetime_day_month_day_month_cmd);
  install_element (KEYCHAIN_KEY_NODE, &send_lifetime_day_month_month_day_cmd);
  install_element (KEYCHAIN_KEY_NODE, &send_lifetime_month_day_day_month_cmd);
  install_element (KEYCHAIN_KEY_NODE, &send_lifetime_month_day_month_day_cmd);
  install_element (KEYCHAIN_KEY_NODE, &send_lifetime_infinite_day_month_cmd);
  install_element (KEYCHAIN_KEY_NODE, &send_lifetime_infinite_month_day_cmd);
  install_element (KEYCHAIN_KEY_NODE, &send_lifetime_duration_day_month_cmd);
  install_element (KEYCHAIN_KEY_NODE, &send_lifetime_duration_month_day_cmd);
}
