]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
ntp-keygen-opts.def:
authorHarlan Stenn <stenn@ntp.org>
Tue, 28 Aug 2007 03:42:20 +0000 (23:42 -0400)
committerHarlan Stenn <stenn@ntp.org>
Tue, 28 Aug 2007 03:42:20 +0000 (23:42 -0400)
  ntp-keygen -i takes an arg
ntpq.c:
  Calysto cleanup for ntpq.
Many files:
  Cleanup from Dave Mills
ChangeLog:
  Cleanup from Dave Mills.
  Coverity fix for ntpq.
  ntp-keygen -i takes an arg.

bk: 46d3999cpEE3t2BhEIGcIeBF3XQyaA

12 files changed:
ChangeLog
include/ntp.h
include/ntp_crypto.h
include/ntpd.h
ntpd/ntp_control.c
ntpd/ntp_crypto.c
ntpd/ntp_parser.c
ntpd/ntp_parser.y
ntpd/ntp_proto.c
ntpq/ntpq.c
util/ntp-keygen-opts.def
util/ntp-keygen.c

index 8487a4d08a608019d3bfc0ec99932f028269225f..9f005b82f7f9741defed2bab083d75eac4df3082 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+* Calysto cleanup for ntpq.
+* ntp-keygen -i takes an arg.
+* Cleanup and fixes from Dave Mills.
 * [Bug 887] Fix error in ntp_types.h (for sizeof int != 4).
 * Bug 880 bug fixes for Windows build
 * Improve Calysto support.
index 13a6a6f40ae485bfa587c3cf0bb15a505a4fe0c5..46e9b3f22f5a0db2dd18c3ccbf133040d3a8a269 100644 (file)
@@ -305,10 +305,9 @@ struct peer {
        char    *issuer;        /* certificate issuer name */
        keyid_t pkeyid;         /* previous key ID */
        keyid_t pcookie;        /* peer cookie */
-       EVP_PKEY *ident_pkey;   /* identity key */
-       tstamp_t fstamp;        /* identity filestamp */
-       BIGNUM  *iffval;        /* IFF/GQ challenge */
-       BIGNUM  *grpkey;        /* GQ group key */
+       struct pkey_info *ident_pkey; /* identity key */
+       BIGNUM  *iffval;        /* identity challenge (IFF, GQ, MV) */
+       BIGNUM  *grpkey;        /* identity challenge key (GQ) */
        struct value cookval;   /* cookie values */
        struct value recval;    /* receive autokey values */
        struct exten *cmmd;     /* extension pointer */
@@ -320,7 +319,6 @@ struct peer {
        int     keynumber;      /* current key number */
        struct value encrypt;   /* send encrypt values */
        struct value sndval;    /* send autokey values */
-       struct value tai_leap;  /* send leapsecond table */
 #else /* OPENSSL */
 #define clear_to_zero status
 #endif /* OPENSSL */
index a6b5e760fc3cd0af6a233ad3e79ade92d01ce48a..7de89a3072516d0f3d0014a9e09030bd72526287 100644 (file)
@@ -1,29 +1,26 @@
 /*
  * ntp_crypto.h - definitions for cryptographic operations
  */
-
 #ifndef NTP_CRYPTO_H
 #define NTP_CRYPTO_H
 
-/* We need the following for the config parser code */
-
 /*
- * Configuration codes
+ * Configuration codes (also needed for parser without OPENSSL)
  */
 #define CRYPTO_CONF_NONE  0    /* nothing doing */
 #define CRYPTO_CONF_PRIV  1    /* host keys file name */
 #define CRYPTO_CONF_SIGN  2    /* signature keys file name */
-#define CRYPTO_CONF_LEAP  3    /* leapseconds table file name */
-#define CRYPTO_CONF_CERT  4    /* certificate file name */
-#define CRYPTO_CONF_RAND  5    /* random seed file name */
-#define CRYPTO_CONF_IFFPAR 6   /* IFF parameters file name */
-#define CRYPTO_CONF_GQPAR 7    /* GQ parameters file name */
-#define        CRYPTO_CONF_MVPAR 8     /* GQ parameters file name */
-#define CRYPTO_CONF_PW   9     /* private key password */
-#define        CRYPTO_CONF_IDENT 10    /* specify identity scheme */
+#define CRYPTO_CONF_CERT  3    /* certificate file name */
+#define CRYPTO_CONF_RAND  4    /* random seed file name */
+#define CRYPTO_CONF_IFFPAR 5   /* IFF parameters file name */
+#define CRYPTO_CONF_GQPAR 6    /* GQ parameters file name */
+#define        CRYPTO_CONF_MVPAR 7     /* MV parameters file name */
+#define CRYPTO_CONF_PW   8     /* private key password */
+#define        CRYPTO_CONF_IDENT 9     /* specify identity scheme */
 
 #ifdef OPENSSL
 #include "openssl/evp.h"
+
 /*
  * The following bits are set by the CRYPTO_ASSOC message from
  * the server and are not modified by the client.
@@ -157,11 +154,20 @@ struct cert_info {
        tstamp_t last;          /* not valid after */
        char    *subject;       /* subject common name */
        char    *issuer;        /* issuer common name */
-       u_char  *grpkey;        /* GQ group key */
-       u_int   grplen;         /* GQ group key length */
+       BIGNUM  *grpkey;        /* GQ group key */
        struct value cert;      /* certificate/value */
 };
 
+/*
+ * The keys info/value structure
+ */
+struct pkey_info {
+       struct pkey_info *link; /* forward link */
+       EVP_PKEY *pkey;         /* generic key */
+       char    *name;          /* file name */
+       tstamp_t fstamp;        /* filestamp */
+};
+
 /*
  * Cryptographic values
  */
index 147d59d9500bc32bcd0da74436fdcfad0fc42dbd..105432d9de215e7b24cde33c13b6147d05ef1188 100644 (file)
@@ -230,7 +230,8 @@ extern      void    timer_clr_stats (void);
 extern  void    timer_interfacetimeout (u_long);
 extern  volatile int interface_interval;
 #ifdef OPENSSL
-extern char    *sys_hostname;
+extern char    *sys_hostname;  /* host name */
+extern char    *group_name;    /* group name */
 extern u_long  sys_revoke;     /* keys revoke timeout */
 extern u_long  sys_automax;    /* session key timeout */
 #endif /* OPENSSL */
index e519a63cd6ff329d402e44c5c25ebab9e46b3ec6..1e9e1ef9ba57434e475b8095d04cba288975109e 100644 (file)
@@ -120,7 +120,7 @@ static struct ctl_var sys_var[] = {
        { CS_LEAPEND,   RO, "expire" },         /* 23 */
 #ifdef OPENSSL
        { CS_FLAGS,     RO, "flags" },          /* 24 */
-       { CS_HOST,      RO, "hostname" },       /* 25 */
+       { CS_HOST,      RO, "host" },   /* 25 */
        { CS_PUBLIC,    RO, "update" },         /* 26 */
        { CS_CERTIF,    RO, "cert" },           /* 27 */
        { CS_DIGEST,    RO, "signature" },      /* 28 */
@@ -161,10 +161,10 @@ static    u_char def_sys_var[] = {
        CS_LEAPEND,
 #ifdef OPENSSL
        CS_HOST,
-       CS_DIGEST,
+       CS_IDENT,
        CS_FLAGS,
+       CS_DIGEST,
        CS_PUBLIC,
-       CS_IDENT,
        CS_CERTIF,
 #endif /* OPENSSL */
        0
@@ -217,13 +217,13 @@ static struct ctl_var peer_var[] = {
        { CP_OUT,       RO, "out" },            /* 39 */
 #ifdef OPENSSL
        { CP_FLAGS,     RO, "flags" },          /* 40 */
-       { CP_HOST,      RO, "hostname" },       /* 41 */
+       { CP_HOST,      RO, "host" },   /* 41 */
        { CP_VALID,     RO, "valid" },          /* 42 */
        { CP_INITSEQ,   RO, "initsequence" },   /* 43 */
        { CP_INITKEY,   RO, "initkey" },        /* 44 */
        { CP_INITTSP,   RO, "timestamp" },      /* 45 */
        { CP_DIGEST,    RO, "signature" },      /* 46 */
-       { CP_IDENT,     RO, "trust" },          /* 47 */
+       { CP_IDENT,     RO, "ident" },          /* 47 */
 #endif /* OPENSSL */
        { 0,            EOV, "" }               /* 40/48 */
 };
@@ -267,10 +267,10 @@ static u_char def_peer_var[] = {
        CP_FILTERROR,
 #ifdef OPENSSL
        CP_HOST,
+       CP_IDENT,
+       CP_FLAGS,
        CP_DIGEST,
        CP_VALID,
-       CP_FLAGS,
-       CP_IDENT,
        CP_INITSEQ,
 #endif /* OPENSSL */
        0
@@ -1384,7 +1384,7 @@ ctl_putsys(
                    *s = '\0';
 
                    ctl_putdata(buf, (unsigned)( s - buf ),
-                               0);
+                       0);
            }
            break;
 
@@ -1396,20 +1396,20 @@ ctl_putsys(
            case CS_LEAPTAB:
                if (leap_sec > 0)
                        ctl_putuint(sys_var[CS_LEAPTAB].text,
-                                   leap_sec);
+                           leap_sec);
                break;
 
            case CS_LEAPEND:
                if (leap_expire > 0)
                        ctl_putfs(sys_var[CS_LEAPEND].text,
-                                 leap_expire);
+                           leap_expire);
                break;
 
 #ifdef OPENSSL
            case CS_FLAGS:
                if (crypto_flags)
                        ctl_puthex(sys_var[CS_FLAGS].text,
-                                  crypto_flags);
+                           crypto_flags);
                break;
 
            case CS_DIGEST:
@@ -1419,22 +1419,22 @@ ctl_putsys(
                        dp = EVP_get_digestbynid(crypto_flags >> 16);
                        strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
                        ctl_putstr(sys_var[CS_DIGEST].text, str,
-                                  strlen(str));
+                           strlen(str));
                }
                break;
 
            case CS_HOST:
                if (sys_hostname != NULL)
                        ctl_putstr(sys_var[CS_HOST].text, sys_hostname,
-                                  strlen(sys_hostname));
+                           strlen(sys_hostname));
                break;
 
            case CS_CERTIF:
                for (cp = cinfo; cp != NULL; cp = cp->link) {
                        sprintf(cbuf, "%s %s 0x%x", cp->subject,
-                               cp->issuer, cp->flags);
+                           cp->issuer, cp->flags);
                        ctl_putstr(sys_var[CS_CERTIF].text, cbuf,
-                                  strlen(cbuf));
+                           strlen(cbuf));
                        ctl_putfs(sys_var[CS_REVTIME].text, cp->last);
                }
                break;
@@ -1442,19 +1442,13 @@ ctl_putsys(
            case CS_PUBLIC:
                if (hostval.fstamp != 0)
                        ctl_putfs(sys_var[CS_PUBLIC].text,
-                                 ntohl(hostval.tstamp));
+                           ntohl(hostval.tstamp));
                break;
 
            case CS_IDENT:
-               if (iffpar_pkey != NULL)
-                       ctl_putstr(sys_var[CS_IDENT].text,
-                                  iffpar_file, strlen(iffpar_file));
-               if (gqpar_pkey != NULL)
+               if (group_name != NULL)
                        ctl_putstr(sys_var[CS_IDENT].text,
-                                  gqpar_file, strlen(gqpar_file));
-               if (mvpar_pkey != NULL)
-                       ctl_putstr(sys_var[CS_IDENT].text,
-                                  mvpar_file, strlen(mvpar_file));
+                           group_name, strlen(group_name));
                break;
 
 #endif /* OPENSSL */
@@ -1723,28 +1717,29 @@ ctl_putpeer(
                        dp = EVP_get_digestbynid(peer->crypto >> 16);
                        strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
                        ctl_putstr(peer_var[CP_DIGEST].text, str,
-                                  strlen(str));
+                           strlen(str));
                }
                break;
 
            case CP_HOST:
                if (peer->subject != NULL)
                        ctl_putstr(peer_var[CP_HOST].text,
-                                  peer->subject, strlen(peer->subject));
+                           peer->subject, strlen(peer->subject));
                break;
 
            case CP_VALID:              /* not used */
                break;
 
            case CP_IDENT:
-               if (peer->issuer != NULL)
+               if (peer->issuer != NULL && peer->ident_pkey != NULL)
                        ctl_putstr(peer_var[CP_IDENT].text,
-                                  peer->issuer, strlen(peer->issuer));
+                           peer->issuer, strlen(peer->issuer));
                break;
 
            case CP_INITSEQ:
                if ((ap = (struct autokey *)peer->recval.ptr) == NULL)
                        break;
+
                ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
                ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
                ctl_putfs(peer_var[CP_INITTSP].text,
index e3e0f30fe63444d4b1533a7d802703b656272326..1a5e7eca92dbd2cb85f71201dcb68180ed971a2e 100644 (file)
@@ -119,14 +119,16 @@ u_int32   crypto_flags = 0x0;     /* status word */
 /*
  * Global cryptodata in network byte order
  */
-struct cert_info *cinfo = NULL;        /* certificate info/value */
+struct cert_info *cinfo = NULL;        /* certificate info/value cache */
+struct pkey_info *pkinfo = NULL; /* key info/value cache */
 struct value hostval;          /* host value */
 struct value pubkey;           /* public key */
 struct value tai_leap;         /* leapseconds table */
-EVP_PKEY *iffpar_pkey = NULL;  /* IFF parameters */
-EVP_PKEY *gqpar_pkey = NULL;   /* GQ parameters */
-EVP_PKEY *mvpar_pkey = NULL;   /* MV parameters */
-char   *iffpar_file = NULL; /* IFF parameters file */
+struct pkey_info *iffpar_info = NULL; /* IFF parameters */
+struct pkey_info *gqpar_info = NULL; /* GQ parameters */
+struct pkey_info *mvpar_info = NULL; /* MV parameters */
+char   *group_name = NULL;     /* group name */
+char   *iffpar_file = NULL;    /* IFF parameters file */
 char   *gqpar_file = NULL;     /* GQ parameters file */
 char   *mvpar_file = NULL;     /* MV parameters file */
 
@@ -142,9 +144,6 @@ static char *rand_file = NULL;      /* random seed file */
 static char *host_file = NULL; /* host key file */
 static char *sign_file = NULL; /* sign key file */
 static char *cert_file = NULL; /* certificate file */
-static tstamp_t if_fstamp = 0; /* IFF filestamp */
-static tstamp_t gq_fstamp = 0; /* GQ file stamp */
-static tstamp_t mv_fstamp = 0; /* MV filestamp */
 static u_int ident_scheme = 0; /* server identity scheme */
 
 /*
@@ -163,15 +162,16 @@ static    int     crypto_bob3     (struct exten *, struct value *);
 static int     crypto_iff      (struct exten *, struct peer *);
 static int     crypto_gq       (struct exten *, struct peer *);
 static int     crypto_mv       (struct exten *, struct peer *);
-static u_int   crypto_send     (struct exten *, struct value *, int *);
+static u_int   crypto_send     (struct exten *, struct value *,
+                                   u_int *);
 static tstamp_t crypto_time    (void);
 static u_long  asn2ntp         (ASN1_TIME *);
-static struct cert_info *cert_parse (u_char *, u_int, tstamp_t, int);
+static struct cert_info *cert_parse (u_char *, u_int, tstamp_t);
 static int     cert_sign       (struct exten *, struct value *);
 static int     cert_valid      (struct cert_info *, EVP_PKEY *);
 static int     cert_install    (struct exten *, struct peer *);
 static void    cert_free       (struct cert_info *);
-static EVP_PKEY *crypto_key    (char *, tstamp_t *);
+static struct pkey_info *crypto_key (char *);
 static void    bighash         (BIGNUM *, BIGNUM *);
 static struct cert_info *crypto_cert (char *);
 
@@ -363,7 +363,7 @@ make_keylist(
                if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
                        vp->siglen = htonl(len);
                else
-                       msyslog(LOG_ERR, "make_keys %s\n",
+                       msyslog(LOG_ERR, "make_keys: %s",
                            ERR_error_string(ERR_get_error(), NULL));
                peer->flags |= FLAG_ASSOC;
        }
@@ -710,7 +710,7 @@ crypto_recv(
                        peer->crypto |= CRYPTO_FLAG_VRFY |
                            CRYPTO_FLAG_PROV;
                        peer->flash &= ~TEST8;
-                       sprintf(statstr, "iff fs %u",
+                       sprintf(statstr, "iff %s fs %u", group_name,
                            ntohl(ep->fstamp));
                        record_crypto_stats(&peer->srcadr, statstr);
 #ifdef DEBUG
@@ -1081,22 +1081,15 @@ crypto_recv(
                         * leapsecond table values.
                         */
                        if (peer->cmmd == NULL) {
-                               if ((rval = crypto_verify(ep,
-                                   &peer->tai_leap, peer)) != XEVNT_OK)
+                               if ((rval = crypto_verify(ep, NULL,
+                                   peer)) != XEVNT_OK)
                                        break;
                        }
 
-                       /*
-                        * Initialize peer variables with latest update.
-                        */
-                       peer->tai_leap.tstamp = ep->tstamp;
-                       peer->tai_leap.fstamp = ep->fstamp;
-                       peer->tai_leap.vallen = ep->vallen;
-
                        /*
                         * If the packet leap values are more recent
-                        * that the stored ones, install the new leap
-                        * values and changed, recompute the signatures.
+                        * than the stored ones, install the new leap
+                        * values and recompute the signatures.
                         */
                        if (ntohl(ep->pkt[2]) > leap_expire) {
                                tai_leap.tstamp = ep->tstamp;
@@ -1276,6 +1269,10 @@ crypto_xmit(
         * from the certificate cache. If the request contains no
         * subject name, assume the name of this host. This is for
         * backwards compatibility. Private certificates are never sent.
+        *
+        * If a sign request, send the host certificate, which is self-
+        * signed and may or may not be trusted. If a certificate
+        * response, do not send the host certificate.
         */
        case CRYPTO_SIGN:
        case CRYPTO_CERT | CRYPTO_RESP:
@@ -1294,31 +1291,40 @@ crypto_xmit(
                /*
                 * Find all certificates with matching subject. If a
                 * self-signed, trusted certificate is found, use that.
-                * If not, use the first one with matching subject. A
-                * private certificate is never divulged or signed.
+                * If not, use the first non self-signed one with
+                * matching subject. A private certificate is never
+                * divulged or signed.
                 */
                xp = NULL;
                for (cp = cinfo; cp != NULL; cp = cp->link) {
                        if (cp->flags & CERT_PRIV)
                                continue;
 
-                       if (strcmp(certname, cp->subject) == 0) {
-                               if (xp == NULL)
-                                       xp = cp;
-                               if (strcmp(certname, cp->issuer) ==
-                                   0 && cp->flags & CERT_TRUST) {
-                                       xp = cp;
-                                       break;
-                               }
+                       if (strcmp(certname, cp->subject) != 0)
+                               continue;
+
+                       if (xp == NULL)
+                               xp = cp;
+                       if (strcmp(certname, cp->issuer) != 0) {
+                               xp = cp;
+                               continue;
                        }
+
+                       /*
+                        * Use the self-signed certificate only if
+                        * trusted.
+                        */
+                       if (cp->flags & CERT_TRUST)
+                               xp = cp;
+                               break;
                }
 
                /*
-                * Be careful who you trust. If not yet synchronized,
-                * give back an empty response. If certificate not found
-                * or beyond the lifetime, return an error. This is to
-                * avoid a bad dude trying to get an expired certificate
-                * re-signed. Otherwise, send it.
+                * Be careful who you trust. If not yet synchronized or
+                * certificate not found, give back an empty response.
+                * If certificate is beyond the lifetime, return an
+                * error. This is to avoid a bad dude trying to get an
+                * expired certificate re-signed. Otherwise, send it.
                 *
                 * Note the timestamp and filestamp are taken from the
                 * certificate value structure. For all certificates the
@@ -1329,11 +1335,9 @@ crypto_xmit(
                 * the base of the certificate trail. In principle, this
                 * allows strong checking for signature masquerade.
                 */
-               if (tstamp == 0)
+               if (tstamp == 0 || xp == NULL)
                        break;
 
-               if (xp == NULL)
-                       rval = XEVNT_CRT;
                else if (tstamp < xp->first || tstamp > xp->last)
                        rval = XEVNT_SRV;
                else
@@ -1692,7 +1696,7 @@ crypto_encrypt(
        ptr = (u_char *)ep->pkt;
        pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &ptr, len);
        if (pkey == NULL) {
-               msyslog(LOG_ERR, "crypto_encrypt %s\n",
+               msyslog(LOG_ERR, "crypto_encrypt: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (XEVNT_PUB);
        }
@@ -1710,7 +1714,7 @@ crypto_encrypt(
        temp32 = htonl(*cookie);
        if (!RSA_public_encrypt(4, (u_char *)&temp32, vp->ptr,
            pkey->pkey.rsa, RSA_PKCS1_OAEP_PADDING)) {
-               msyslog(LOG_ERR, "crypto_encrypt %s\n",
+               msyslog(LOG_ERR, "crypto_encrypt: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                EVP_PKEY_free(pkey);
                return (XEVNT_CKY);
@@ -1753,61 +1757,31 @@ crypto_ident(
        char    filename[MAXFILENAME + 1];
 
        /*
-        * If the server identity has already been verified, no further
-        * action is necessary. Otherwise, try to load the identity file
-        * of the certificate issuer. If the issuer file is not found,
-        * try the host file. If nothing found, declare a cryptobust.
-        * Note we can't get here unless the trusted certificate has
-        * been found and the CRYPTO_FLAG_VALID bit is set, so the
-        * certificate issuer is valid.
+        * We come here after the group trusted host has been found; its
+        * name defines the group name. If we are in the same group,
+        * just return the identity parameters. If not, try to load the
+        * identity parameters from files. If not found, declare a
+        * cryptobust.
         */
+       snprintf(filename, MAXFILENAME, "ntpkey_iffkey_%s",
+           peer->issuer);
+       peer->ident_pkey = crypto_key(filename);
        if (peer->ident_pkey != NULL)
-               EVP_PKEY_free(peer->ident_pkey);
-       if (peer->crypto & CRYPTO_FLAG_GQ) {
-               snprintf(filename, MAXFILENAME, "ntpkey_gq_%s",
-                   peer->issuer);
-               peer->ident_pkey = crypto_key(filename, &peer->fstamp);
-               if (peer->ident_pkey != NULL)
-                       return (CRYPTO_GQ);
-
-               snprintf(filename, MAXFILENAME, "ntpkey_gq_%s",
-                   sys_hostname);
-               peer->ident_pkey = crypto_key(filename, &peer->fstamp);
-               if (peer->ident_pkey != NULL)
-                       return (CRYPTO_GQ);
-       }
-       if (peer->crypto & CRYPTO_FLAG_IFF) {
-               snprintf(filename, MAXFILENAME, "ntpkey_iff_%s",
-                   peer->issuer);
-               peer->ident_pkey = crypto_key(filename, &peer->fstamp);
-               if (peer->ident_pkey != NULL)
-                       return (CRYPTO_IFF);
-
-               snprintf(filename, MAXFILENAME, "ntpkey_iff_%s",
-                   sys_hostname);
-               peer->ident_pkey = crypto_key(filename, &peer->fstamp);
-               if (peer->ident_pkey != NULL)
-                       return (CRYPTO_IFF);
-       }
-       if (peer->crypto & CRYPTO_FLAG_MV) {
-               snprintf(filename, MAXFILENAME, "ntpkey_mv_%s",
-                   peer->issuer);
-               peer->ident_pkey = crypto_key(filename, &peer->fstamp);
-               if (peer->ident_pkey != NULL)
-                       return (CRYPTO_MV);
-
-               snprintf(filename, MAXFILENAME, "ntpkey_mv_%s",
-                   sys_hostname);
-               peer->ident_pkey = crypto_key(filename, &peer->fstamp);
-               if (peer->ident_pkey != NULL)
-                       return (CRYPTO_MV);
-       }
+               return (CRYPTO_IFF);
+
+       snprintf(filename, MAXFILENAME, "ntpkey_gq_%s", peer->issuer);
+       peer->ident_pkey = crypto_key(filename);
+       if (peer->ident_pkey != NULL)
+               return (CRYPTO_GQ);
+
+       snprintf(filename, MAXFILENAME, "ntpkey_mv_%s", peer->issuer);
+       peer->ident_pkey = crypto_key(filename);
+       if (peer->ident_pkey != NULL)
+               return (CRYPTO_MV);
 
-       /*
-        * No compatible identity scheme is available. Life is hard.
-        */
        msyslog(LOG_INFO,
-           "crypto_ident: no compatible identity scheme found");
+           "crypto_ident: no identity parameters found for group %s",
+           peer->issuer);
        return (CRYPTO_NULL);
 }
 
@@ -1879,7 +1853,7 @@ u_int
 crypto_send(
        struct exten *ep,       /* extension field pointer */
        struct value *vp,       /* value pointer */
-       int     *start          /* buffer offset */
+       u_int   *start          /* buffer offset */
        )
 {
        u_int   len, vallen, siglen;
@@ -2010,7 +1984,7 @@ crypto_update(void)
         * error to return null values.
         */
        tai_leap.tstamp = hostval.tstamp;
-       tai_leap.fstamp = hostval.tstamp;
+       tai_leap.fstamp = hostval.fstamp;
        len = 3 * sizeof(u_int32);
        if (tai_leap.ptr == NULL)
                tai_leap.ptr = emalloc(len);
@@ -2205,21 +2179,20 @@ crypto_alice(
        if (peer->ident_pkey == NULL)
                return (XEVNT_ID);
 
-       if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) {
+       if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) {
                msyslog(LOG_INFO, "crypto_alice: defective key");
                return (XEVNT_PUB);
        }
 
        /*
-        * Roll new random r (0 < r < q). The OpenSSL library has a bug
-        * omitting BN_rand_range, so we have to do it the hard way.
+        * Roll new random r (0 < r < q).
         */
-       bctx = BN_CTX_new();
-       len = BN_num_bytes(dsa->q);
        if (peer->iffval != NULL)
                BN_free(peer->iffval);
        peer->iffval = BN_new();
-       BN_rand(peer->iffval, len * 8, -1, 1);  /* r */
+       len = BN_num_bytes(dsa->q);
+       BN_rand(peer->iffval, len * 8, -1, 1);  /* r mod q*/
+       bctx = BN_CTX_new();
        BN_mod(peer->iffval, peer->iffval, dsa->q, bctx);
        BN_CTX_free(bctx);
 
@@ -2229,7 +2202,7 @@ crypto_alice(
        tstamp = crypto_time();
        memset(vp, 0, sizeof(struct value));
        vp->tstamp = htonl(tstamp);
-       vp->fstamp = htonl(peer->fstamp);
+       vp->fstamp = htonl(peer->ident_pkey->fstamp);
        vp->vallen = htonl(len);
        vp->ptr = emalloc(len);
        BN_bn2bin(peer->iffval, vp->ptr);
@@ -2278,18 +2251,18 @@ crypto_bob(
         * If the IFF parameters are not valid, something awful
         * happened or we are being tormented.
         */
-       if (iffpar_pkey == NULL) {
+       if (iffpar_info == NULL) {
                msyslog(LOG_INFO, "crypto_bob: scheme unavailable");
                return (XEVNT_ID);
        }
-       dsa = iffpar_pkey->pkey.dsa;
+       dsa = iffpar_info->pkey->pkey.dsa;
 
        /*
         * Extract r from the challenge.
         */
        len = ntohl(ep->vallen);
        if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
-               msyslog(LOG_ERR, "crypto_bob %s\n",
+               msyslog(LOG_ERR, "crypto_bob: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (XEVNT_ERR);
        }
@@ -2312,15 +2285,16 @@ crypto_bob(
        BN_free(r); BN_free(bn); BN_free(bk);
 
        /*
-        * Encode the values in ASN.1 and sign.
+        * Encode the values in ASN.1 and sign. The filestamp is from
+        * the local file.
         */
        tstamp = crypto_time();
        memset(vp, 0, sizeof(struct value));
        vp->tstamp = htonl(tstamp);
-       vp->fstamp = htonl(if_fstamp);
+       vp->fstamp = htonl(iffpar_info->fstamp);
        len = i2d_DSA_SIG(sdsa, NULL);
        if (len <= 0) {
-               msyslog(LOG_ERR, "crypto_bob %s\n",
+               msyslog(LOG_ERR, "crypto_bob: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                DSA_SIG_free(sdsa);
                return (XEVNT_ERR);
@@ -2367,7 +2341,7 @@ crypto_iff(
        DSA_SIG *sdsa;          /* DSA parameters */
        BIGNUM  *bn, *bk;
        u_int   len;
-       const u_char    *ptr;
+       const u_char *ptr;
        int     temp;
 
        /*
@@ -2378,12 +2352,12 @@ crypto_iff(
                msyslog(LOG_INFO, "crypto_iff: scheme unavailable");
                return (XEVNT_ID);
        }
-       if (ntohl(ep->fstamp) != peer->fstamp) {
+       if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) {
                msyslog(LOG_INFO, "crypto_iff: invalid filestamp %u",
                    ntohl(ep->fstamp));
                return (XEVNT_FSP);
        }
-       if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) {
+       if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) {
                msyslog(LOG_INFO, "crypto_iff: defective key");
                return (XEVNT_PUB);
        }
@@ -2397,9 +2371,9 @@ crypto_iff(
         */
        bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new();
        len = ntohl(ep->vallen);
-       ptr = (const u_char *)ep->pkt;
+       ptr = (u_char *)ep->pkt;
        if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) {
-               msyslog(LOG_ERR, "crypto_iff %s\n",
+               msyslog(LOG_ERR, "crypto_iff %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (XEVNT_ERR);
        }
@@ -2423,8 +2397,8 @@ crypto_iff(
        if (temp == 0)
                return (XEVNT_OK);
 
-       else
-               return (XEVNT_ID);
+       msyslog(LOG_INFO, "crypto_iff: identity not verified");
+       return (XEVNT_ID);
 }
 
 
@@ -2507,21 +2481,20 @@ crypto_alice2(
        if (peer->ident_pkey == NULL)
                return (XEVNT_ID);
 
-       if ((rsa = peer->ident_pkey->pkey.rsa) == NULL) {
+       if ((rsa = peer->ident_pkey->pkey->pkey.rsa) == NULL) {
                msyslog(LOG_INFO, "crypto_alice2: defective key");
                return (XEVNT_PUB);
        }
 
        /*
-        * Roll new random r (0 < r < n). The OpenSSL library has a bug
-        * omitting BN_rand_range, so we have to do it the hard way.
+        * Roll new random r (0 < r < n).
         */
-       bctx = BN_CTX_new();
-       len = BN_num_bytes(rsa->n);
        if (peer->iffval != NULL)
                BN_free(peer->iffval);
        peer->iffval = BN_new();
+       len = BN_num_bytes(rsa->n);
        BN_rand(peer->iffval, len * 8, -1, 1);  /* r mod n */
+       bctx = BN_CTX_new();
        BN_mod(peer->iffval, peer->iffval, rsa->n, bctx);
        BN_CTX_free(bctx);
 
@@ -2531,7 +2504,7 @@ crypto_alice2(
        tstamp = crypto_time();
        memset(vp, 0, sizeof(struct value));
        vp->tstamp = htonl(tstamp);
-       vp->fstamp = htonl(peer->fstamp);
+       vp->fstamp = htonl(peer->ident_pkey->fstamp);
        vp->vallen = htonl(len);
        vp->ptr = emalloc(len);
        BN_bn2bin(peer->iffval, vp->ptr);
@@ -2580,18 +2553,18 @@ crypto_bob2(
         * If the GQ parameters are not valid, something awful
         * happened or we are being tormented.
         */
-       if (gqpar_pkey == NULL) {
+       if (gqpar_info == NULL) {
                msyslog(LOG_INFO, "crypto_bob2: scheme unavailable");
                return (XEVNT_ID);
        }
-       rsa = gqpar_pkey->pkey.rsa;
+       rsa = gqpar_info->pkey->pkey.rsa;
 
        /*
         * Extract r from the challenge.
         */
        len = ntohl(ep->vallen);
        if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
-               msyslog(LOG_ERR, "crypto_bob2 %s\n",
+               msyslog(LOG_ERR, "crypto_bob2: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (XEVNT_ERR);
        }
@@ -2614,15 +2587,16 @@ crypto_bob2(
        BN_free(r); BN_free(k); BN_free(g); BN_free(y);
  
        /*
-        * Encode the values in ASN.1 and sign.
+        * Encode the values in ASN.1 and sign. The filestamp is from
+        * the local file.
         */
        tstamp = crypto_time();
        memset(vp, 0, sizeof(struct value));
        vp->tstamp = htonl(tstamp);
-       vp->fstamp = htonl(gq_fstamp);
+       vp->fstamp = htonl(gqpar_info->fstamp);
        len = i2d_DSA_SIG(sdsa, NULL);
        if (len <= 0) {
-               msyslog(LOG_ERR, "crypto_bob2 %s\n",
+               msyslog(LOG_ERR, "crypto_bob2: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                DSA_SIG_free(sdsa);
                return (XEVNT_ERR);
@@ -2669,7 +2643,7 @@ crypto_gq(
        BN_CTX  *bctx;          /* BIGNUM context */
        DSA_SIG *sdsa;          /* RSA signature context fake */
        BIGNUM  *y, *v;
-       const u_char    *ptr;
+       const u_char *ptr;
        u_int   len;
        int     temp;
 
@@ -2681,12 +2655,12 @@ crypto_gq(
                msyslog(LOG_INFO, "crypto_gq: scheme unavailable");
                return (XEVNT_ID);
        }
-       if (ntohl(ep->fstamp) != peer->fstamp) {
+       if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) {
                msyslog(LOG_INFO, "crypto_gq: invalid filestamp %u",
                    ntohl(ep->fstamp));
                return (XEVNT_FSP);
        }
-       if ((rsa = peer->ident_pkey->pkey.rsa) == NULL) {
+       if ((rsa = peer->ident_pkey->pkey->pkey.rsa) == NULL) {
                msyslog(LOG_INFO, "crypto_gq: defective key");
                return (XEVNT_PUB);
        }
@@ -2701,9 +2675,9 @@ crypto_gq(
         */
        bctx = BN_CTX_new(); y = BN_new(); v = BN_new();
        len = ntohl(ep->vallen);
-       ptr = (const u_char *)ep->pkt;
+       ptr = (u_char *)ep->pkt;
        if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) {
-               msyslog(LOG_ERR, "crypto_gq %s\n",
+               msyslog(LOG_ERR, "crypto_gq %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (XEVNT_ERR);
        }
@@ -2728,8 +2702,8 @@ crypto_gq(
        if (temp == 0)
                return (XEVNT_OK);
 
-       else
-               return (XEVNT_ID);
+       msyslog(LOG_INFO, "crypto_gq: identity not verified");
+       return (XEVNT_ID);
 }
 
 
@@ -2833,21 +2807,20 @@ crypto_alice3(
        if (peer->ident_pkey == NULL)
                return (XEVNT_ID);
 
-       if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) {
+       if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) {
                msyslog(LOG_INFO, "crypto_alice3: defective key");
                return (XEVNT_PUB);
        }
 
        /*
-        * Roll new random r (0 < r < q). The OpenSSL library has a bug
-        * omitting BN_rand_range, so we have to do it the hard way.
+        * Roll new random r (0 < r < q).
         */
-       bctx = BN_CTX_new();
-       len = BN_num_bytes(dsa->p);
        if (peer->iffval != NULL)
                BN_free(peer->iffval);
        peer->iffval = BN_new();
-       BN_rand(peer->iffval, len * 8, -1, 1);  /* r */
+       len = BN_num_bytes(dsa->p);
+       BN_rand(peer->iffval, len * 8, -1, 1);  /* r mod p */
+       bctx = BN_CTX_new();
        BN_mod(peer->iffval, peer->iffval, dsa->p, bctx);
        BN_CTX_free(bctx);
 
@@ -2857,7 +2830,7 @@ crypto_alice3(
        tstamp = crypto_time();
        memset(vp, 0, sizeof(struct value));
        vp->tstamp = htonl(tstamp);
-       vp->fstamp = htonl(peer->fstamp);
+       vp->fstamp = htonl(peer->ident_pkey->fstamp);
        vp->vallen = htonl(len);
        vp->ptr = emalloc(len);
        BN_bn2bin(peer->iffval, vp->ptr);
@@ -2905,18 +2878,18 @@ crypto_bob3(
         * If the MV parameters are not valid, something awful
         * happened or we are being tormented.
         */
-       if (mvpar_pkey == NULL) {
+       if (mvpar_info == NULL) {
                msyslog(LOG_INFO, "crypto_bob3: scheme unavailable");
                return (XEVNT_ID);
        }
-       dsa = mvpar_pkey->pkey.dsa;
+       dsa = mvpar_info->pkey->pkey.dsa;
 
        /*
         * Extract r from the challenge.
         */
        len = ntohl(ep->vallen);
        if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
-               msyslog(LOG_ERR, "crypto_bob3 %s\n",
+               msyslog(LOG_ERR, "crypto_bob3 %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (XEVNT_ERR);
        }
@@ -2944,15 +2917,16 @@ crypto_bob3(
        BN_CTX_free(bctx); BN_free(k); BN_free(r); BN_free(u);
 
        /*
-        * Encode the values in ASN.1 and sign.
+        * Encode the values in ASN.1 and sign. The filestamp is from
+        * the local file.
         */
        tstamp = crypto_time();
        memset(vp, 0, sizeof(struct value));
        vp->tstamp = htonl(tstamp);
-       vp->fstamp = htonl(mv_fstamp);
+       vp->fstamp = htonl(mvpar_info->fstamp);
        len = i2d_DSAparams(sdsa, NULL);
        if (len <= 0) {
-               msyslog(LOG_ERR, "crypto_bob3 %s\n",
+               msyslog(LOG_ERR, "crypto_bob3 %s",
                    ERR_error_string(ERR_get_error(), NULL));
                DSA_free(sdsa);
                return (XEVNT_ERR);
@@ -3000,7 +2974,7 @@ crypto_mv(
        BN_CTX  *bctx;          /* BIGNUM context */
        BIGNUM  *k, *u, *v;
        u_int   len;
-       const u_char    *ptr;
+       const u_char *ptr;
        int     temp;
 
        /*
@@ -3011,12 +2985,12 @@ crypto_mv(
                msyslog(LOG_INFO, "crypto_mv: scheme unavailable");
                return (XEVNT_ID);
        }
-       if (ntohl(ep->fstamp) != peer->fstamp) {
+       if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) {
                msyslog(LOG_INFO, "crypto_mv: invalid filestamp %u",
                    ntohl(ep->fstamp));
                return (XEVNT_FSP);
        }
-       if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) {
+       if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) {
                msyslog(LOG_INFO, "crypto_mv: defective key");
                return (XEVNT_PUB);
        }
@@ -3030,9 +3004,9 @@ crypto_mv(
         */
        bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); v = BN_new();
        len = ntohl(ep->vallen);
-       ptr = (const u_char *)ep->pkt;
+       ptr = (u_char *)ep->pkt;
        if ((sdsa = d2i_DSAparams(NULL, &ptr, len)) == NULL) {
-               msyslog(LOG_ERR, "crypto_mv %s\n",
+               msyslog(LOG_ERR, "crypto_mv: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (XEVNT_ERR);
        }
@@ -3058,8 +3032,8 @@ crypto_mv(
        if (temp == 0)
                return (XEVNT_OK);
 
-       else
-               return (XEVNT_ID);
+       msyslog(LOG_INFO, "crypto_mv: identity not verified");
+       return (XEVNT_ID);
 }
 
 
@@ -3087,8 +3061,7 @@ struct cert_info *                /* certificate information structure */
 cert_parse(
        u_char  *asn1cert,      /* X509 certificate */
        u_int   len,            /* certificate length */
-       tstamp_t fstamp,        /* filestamp */
-       int     ssflag          /* check self-signed certificate */
+       tstamp_t fstamp         /* filestamp */
        )
 {
        X509    *cert;          /* X509 certificate */
@@ -3098,7 +3071,7 @@ cert_parse(
        X509V3_EXT_METHOD *method;
        char    pathbuf[MAXFILENAME];
        u_char  *uptr;
-       char    *ptr;
+       const char *ptr;
        int     temp, cnt, i;
 
        /*
@@ -3106,7 +3079,7 @@ cert_parse(
         */
        uptr = asn1cert;
        if ((cert = d2i_X509(NULL, &uptr, len)) == NULL) {
-               msyslog(LOG_ERR, "cert_parse %s\n",
+               msyslog(LOG_ERR, "cert_parse: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (NULL);
        }
@@ -3117,7 +3090,7 @@ cert_parse(
        ret = emalloc(sizeof(struct cert_info));
        memset(ret, 0, sizeof(struct cert_info));
        if ((ret->pkey = X509_get_pubkey(cert)) == NULL) {
-               msyslog(LOG_ERR, "cert_parse %s\n",
+               msyslog(LOG_ERR, "cert_parse: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                cert_free(ret);
                X509_free(cert);
@@ -3144,8 +3117,6 @@ cert_parse(
         * objects at this time, since the real crunch can happen only
         * when the time is valid but not yet certificated.
         */
-       NTP_INSIST(cert->cert_info != NULL);
-       NTP_INSIST(cert->cert_info->signature != NULL);
        ret->nid = OBJ_obj2nid(cert->cert_info->signature->algorithm);
        ret->digest = (const EVP_MD *)EVP_get_digestbynid(ret->nid);
        ret->serial =
@@ -3187,15 +3158,15 @@ cert_parse(
                        X509V3_EXT_print(bp, ext, 0, 0);
                        BIO_gets(bp, pathbuf, MAXFILENAME);
                        BIO_free(bp);
+                       if (strcmp(pathbuf, "Trust Root") == 0)
+                               ret->flags |= CERT_TRUST;
+                       else if (strcmp(pathbuf, "Private") == 0)
+                               ret->flags |= CERT_PRIV;
 #if DEBUG
                        if (debug)
                                printf("cert_parse: %s: %s\n",
                                    OBJ_nid2ln(temp), pathbuf);
 #endif
-                       if (strcmp(pathbuf, "Trust Root") == 0)
-                               ret->flags |= CERT_TRUST;
-                       else if (strcmp(pathbuf, "Private") == 0)
-                               ret->flags |= CERT_PRIV;
                        break;
 
                /*
@@ -3203,42 +3174,39 @@ cert_parse(
                 * contains the GQ public key.
                 */
                case NID_subject_key_identifier:
-                       ret->grplen = ext->value->length - 2;
-                       ret->grpkey = emalloc(ret->grplen);
-                       memcpy(ret->grpkey, &ext->value->data[2],
-                           ret->grplen);
-                       break;
+                       ret->grpkey = BN_bin2bn(&ext->value->data[2],
+                           ext->value->length - 2, NULL);
+                       /* fall through */
+               default:
+#if DEBUG
+                       if (debug)
+                               printf("cert_parse: %s\n",
+                                   OBJ_nid2ln(temp));
+#endif
                }
        }
+       if (strcmp(ret->subject, ret->issuer) == 0) {
 
-       /*
-        * Check for a certificate loop.
-        */
-       if (strcmp(sys_hostname, ret->issuer) == 0 && ssflag) {
-               msyslog(LOG_INFO,
-                   "cert_parse: certificate trail loop %s",
-                   pathbuf);
-               cert_free(ret);
-               X509_free(cert);
-               return (NULL);
-       }
-       
-       /*
-        * If certificate is self signed, verify signature.
-        */
-       if (strcmp(ret->subject, ret->issuer) == 0 && ssflag) {
-               if (!(ret->flags & CERT_TRUST)) {
+               /*
+                * If certificate is self signed, verify signature.
+                */
+               if (!X509_verify(cert, ret->pkey)) {
                        msyslog(LOG_INFO,
-                           "cert_parse: self-signed but not trusted %s",
-                           pathbuf);
+                           "cert_parse: signature not verified %s",
+                           ret->subject);
                        cert_free(ret);
                        X509_free(cert);
                        return (NULL);
                }
-               if (!X509_verify(cert, ret->pkey)) {
+       } else {
+
+               /*
+                * Check for a certificate loop.
+                */
+               if (strcmp(sys_hostname, ret->issuer) == 0) {
                        msyslog(LOG_INFO,
-                           "cert_parse: signature not verified %s",
-                           pathbuf);
+                           "cert_parse: certificate trail loop %s",
+                           ret->subject);
                        cert_free(ret);
                        X509_free(cert);
                        return (NULL);
@@ -3339,8 +3307,9 @@ cert_sign(
                return (XEVNT_PER);
 
        ptr = (u_char *)ep->pkt;
-       if ((req = d2i_X509(NULL, &ptr, ntohl(ep->vallen))) == NULL) {
-               msyslog(LOG_ERR, "cert_sign %s\n",
+       if ((req = d2i_X509(NULL, (u_char **)&ptr,
+           ntohl(ep->vallen))) == NULL) {
+               msyslog(LOG_ERR, "cert_sign %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (XEVNT_CRT);
        }
@@ -3348,7 +3317,7 @@ cert_sign(
         * Extract public key and check for errors.
         */
        if ((pkey = X509_get_pubkey(req)) == NULL) {
-               msyslog(LOG_ERR, "cert_sign %s\n",
+               msyslog(LOG_ERR, "cert_sign %s",
                    ERR_error_string(ERR_get_error(), NULL));
                X509_free(req);
                return (XEVNT_PUB);
@@ -3403,7 +3372,7 @@ cert_sign(
        vp->vallen = htonl(len);
        vp->ptr = emalloc(len);
        ptr = vp->ptr;
-       i2d_X509(cert, &ptr);
+       i2d_X509(cert, (u_char **)&ptr);
        vp->siglen = 0;
        vp->sig = emalloc(sign_siglen);
        EVP_SignInit(&ctx, sign_digest);
@@ -3454,7 +3423,7 @@ cert_valid(
 
 
 /*
- * cert - install certificate in certificate list
+ * cert_install - install certificate in certificate cache
  *
  * This routine encodes an extension field into a certificate info/value
  * structure. It searches the certificate list for duplicates and
@@ -3480,7 +3449,7 @@ cert_install(
         * construct the info/value structure; otherwise, scamper home.
         */
        if ((cp = cert_parse((u_char *)ep->pkt, ntohl(ep->vallen),
-           ntohl(ep->fstamp), 1)) == NULL)
+           ntohl(ep->fstamp))) == NULL)
                return (XEVNT_CRT);
 
        /*
@@ -3574,12 +3543,7 @@ cert_install(
                        if (strcmp(yp->subject, peer->subject) != 0)
                                continue;
 
-                       if (yp->grpkey != NULL) {
-                               if (peer->grpkey != NULL)
-                                       BN_free(peer->grpkey);
-                               peer->grpkey = BN_bin2bn(yp->grpkey,
-                                    yp->grplen, NULL);
-                       }
+                       peer->grpkey = yp->grpkey;
                        peer->crypto |= CRYPTO_FLAG_VALID;
 
                        /*
@@ -3593,6 +3557,9 @@ cert_install(
                            CRYPTO_FLAG_IFF | CRYPTO_FLAG_MV))
                                continue;
 
+                       if (group_name != NULL)
+                               continue;
+
                        peer->crypto |= CRYPTO_FLAG_VRFY;
                }
        }
@@ -3620,41 +3587,43 @@ cert_free(
        if (cinf->issuer != NULL)
                free(cinf->issuer);
        if (cinf->grpkey != NULL)
-               free(cinf->grpkey);
+               BN_free(cinf->grpkey);
        value_free(&cinf->cert);
        free(cinf);
 }
 
 
 /*
- ***********************************************************************
- *                                                                    *
- * The following routines are used only at initialization time         *
- *                                                                    *
- ***********************************************************************
- */
-/*
- * crypto_key - load cryptographic parameters and keys from files
+ * crypto_key - load cryptographic parameters and keys
  *
- * This routine loads a PEM-encoded public/private key pair and extracts
- * the filestamp from the file name.
- *
- * Returns public key pointer if valid, NULL if not. Side effect updates
- * the filestamp if valid.
+ * This routine searches the key cache for matching name in the form
+ * ntpkey_<key>_<name>, where <key> is one of host, sign, iff, gq, mv,
+ * and <name> is the host/group name. If not found, it tries to load a
+ * PEM-encoded file of the same name and extracts the filestamp from
+ * the file name. It returns the key pointer if valid, NULL if not.
  */
-static EVP_PKEY *
+static struct pkey_info *
 crypto_key(
-       char    *cp,            /* file name */
-       tstamp_t *fstamp        /* filestamp */
+       char    *cp             /* file name */
        )
 {
        FILE    *str;           /* file handle */
+       struct pkey_info *pkp;  /* generic key */
        EVP_PKEY *pkey = NULL;  /* public/private key */
+       tstamp_t fstamp;
        char    filename[MAXFILENAME]; /* name of key file */
        char    linkname[MAXFILENAME]; /* filestamp buffer) */
        char    statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
        char    *ptr;
 
+       /*
+        * Search the key cache for matching key and name.
+        */
+       for (pkp = pkinfo; pkp != NULL; pkp = pkp->link) {
+               if (strcmp(cp, pkp->name) == 0)
+                       return (pkp);
+       }  
+
        /*
         * Open the key file. If the first character of the file name is
         * not '/', prepend the keys directory string. If something goes
@@ -3672,21 +3641,21 @@ crypto_key(
         * Read the filestamp, which is contained in the first line.
         */
        if ((ptr = fgets(linkname, MAXFILENAME, str)) == NULL) {
-               msyslog(LOG_ERR, "crypto_key: no data %s\n",
+               msyslog(LOG_ERR, "crypto_key: empty file %s",
                    filename);
-               (void)fclose(str);
+               fclose(str);
                return (NULL);
        }
        if ((ptr = strrchr(ptr, '.')) == NULL) {
-               msyslog(LOG_ERR, "crypto_key: no filestamp %s\n",
+               msyslog(LOG_ERR, "crypto_key: no filestamp %s",
                    filename);
-               (void)fclose(str);
+               fclose(str);
                return (NULL);
        }
-       if (sscanf(++ptr, "%u", fstamp) != 1) {
-               msyslog(LOG_ERR, "crypto_key: invalid timestamp %s\n",
+       if (sscanf(++ptr, "%u", &fstamp) != 1) {
+               msyslog(LOG_ERR, "crypto_key: invalid filestamp %s",
                    filename);
-               (void)fclose(str);
+               fclose(str);
                return (NULL);
        }
 
@@ -3696,11 +3665,23 @@ crypto_key(
        pkey = PEM_read_PrivateKey(str, NULL, NULL, passwd);
        fclose(str);
        if (pkey == NULL) {
-               msyslog(LOG_ERR, "crypto_key %s\n",
+               msyslog(LOG_ERR, "crypto_key: %s",
                    ERR_error_string(ERR_get_error(), NULL));
+               fclose(str);
                return (NULL);
        }
 
+       /*
+        * Make a new entry in the key cache.
+        */
+       pkp = emalloc(sizeof(struct pkey_info));
+       pkp->link = pkinfo;
+       pkinfo = pkp;
+       pkp->pkey = pkey;
+       pkp->name = emalloc(sizeof(cp) + 1);
+       pkp->fstamp = fstamp;
+       strcpy(pkp->name, cp);
+
        /*
         * Leave tracks in the cryptostats.
         */
@@ -3708,28 +3689,34 @@ crypto_key(
                *ptr = '\0'; 
        sprintf(statstr, "%s mod %d", &linkname[2],
            EVP_PKEY_size(pkey) * 8);
-       record_crypto_stats(NULL, statstr);
 #ifdef DEBUG
        if (debug)
                printf("crypto_key: %s\n", statstr);
        if (debug > 1) {
-               if (EVP_MD_type(pkey) == EVP_PKEY_DSA)
+               if (pkey->type == EVP_PKEY_DSA)
                        DSA_print_fp(stdout, pkey->pkey.dsa, 0);
                else
                        RSA_print_fp(stdout, pkey->pkey.rsa, 0);
        }
 #endif
-       return (pkey);
+       return (pkp);
 }
 
 
+/*
+ ***********************************************************************
+ *                                                                    *
+ * The following routines are used only at initialization time         *
+ *                                                                    *
+ ***********************************************************************
+ */
 /*
  * crypto_cert - load certificate from file
  *
- * This routine loads a X.509 RSA or DSA certificate from a file and
+ * This routine loads an X.509 RSA or DSA certificate from a file and
  * constructs a info/cert value structure for this machine. The
  * structure includes a filestamp extracted from the file name. Later
- * the certificate can be sent to another machine by request.
+ * the certificate can be sent to another machine on request.
  *
  * Returns certificate info/value pointer if valid, NULL if not.
  */
@@ -3766,21 +3753,21 @@ crypto_cert(
         * Read the filestamp, which is contained in the first line.
         */
        if ((ptr = fgets(linkname, MAXFILENAME, str)) == NULL) {
-               msyslog(LOG_ERR, "crypto_cert: no data %s\n",
+               msyslog(LOG_ERR, "crypto_cert: empty file %s",
                    filename);
-               (void)fclose(str);
+               fclose(str);
                return (NULL);
        }
        if ((ptr = strrchr(ptr, '.')) == NULL) {
                msyslog(LOG_ERR, "crypto_cert: no filestamp %s\n",
                    filename);
-               (void)fclose(str);
+               fclose(str);
                return (NULL);
        }
        if (sscanf(++ptr, "%u", &fstamp) != 1) {
                msyslog(LOG_ERR, "crypto_cert: invalid filestamp %s\n",
                    filename);
-               (void)fclose(str);
+               fclose(str);
                return (NULL);
        }
 
@@ -3790,7 +3777,7 @@ crypto_cert(
        if (!PEM_read(str, &name, &header, &data, &len)) {
                msyslog(LOG_ERR, "crypto_cert %s\n",
                    ERR_error_string(ERR_get_error(), NULL));
-               (void)fclose(str);
+               fclose(str);
                return (NULL);
        }
        free(header);
@@ -3799,7 +3786,7 @@ crypto_cert(
                    name);
                free(name);
                free(data);
-               (void)fclose(str);
+               fclose(str);
                return (NULL);
        }
        free(name);
@@ -3807,9 +3794,9 @@ crypto_cert(
        /*
         * Parse certificate and generate info/value structure.
         */
-       ret = cert_parse(data, len, fstamp, 0);
+       ret = cert_parse(data, len, fstamp);
        free(data);
-       (void)fclose(str);
+       fclose(str);
        if (ret == NULL)
                return (NULL);
 
@@ -3827,13 +3814,14 @@ crypto_cert(
 
 
 /*
- * crypto_setup - load keys, certificate and leapseconds table
+ * crypto_setup - load keys, certificate and identity parameters
  *
  * This routine loads the public/private host key and certificate. If
  * available, it loads the public/private sign key, which defaults to
- * the host key, and leapseconds table. The host key must be RSA, but
- * the sign key can be either RSA or DSA. In either case, the public key
- * on the certificate must agree with the sign key.
+ * the host key. The host key must be RSA, but the sign key can be
+ * either RSA or DSA. If a trusted certificate, it loads the identity
+ * parameters. In either case, the public key on the certificate must
+ * agree with the sign key.
  *
  * Required but missing files and inconsistent data and errors are
  * fatal. Allowing configuration to continue would be hazardous and
@@ -3842,11 +3830,9 @@ crypto_cert(
 void
 crypto_setup(void)
 {
-       EVP_PKEY *pkey;         /* private/public key pair */
+       struct pkey_info *pinfo; /* private/public key */
        char    filename[MAXFILENAME]; /* file name buffer */
        l_fp    seed;           /* crypto PRNG seed as NTP timestamp */
-       tstamp_t fstamp;        /* filestamp */
-       tstamp_t sstamp;        /* sign filestamp */
        u_int   len, bytes;
        u_char  *ptr;
 
@@ -3870,9 +3856,8 @@ crypto_setup(void)
         * Initialize structures.
         */
        gethostname(filename, MAXFILENAME);
-       bytes = strlen(filename) + 1;
-       sys_hostname = emalloc(bytes);
-       memcpy(sys_hostname, filename, bytes);
+       sys_hostname = emalloc(strlen(filename) + 1);
+       strcpy(sys_hostname, filename);
        if (passwd == NULL)
                passwd = sys_hostname;
        memset(&hostval, 0, sizeof(hostval));
@@ -3901,12 +3886,12 @@ crypto_setup(void)
        }
        if (rand_file == NULL) {
                msyslog(LOG_ERR,
-                   "crypto_setup: random seed file not specified");
+                   "crypto_setup: random seed file unknown name");
                exit (-1);
        }
        if ((bytes = RAND_load_file(rand_file, -1)) == 0) {
                msyslog(LOG_ERR,
-                   "crypto_setup: random seed file %s not found\n",
+                   "crypto_setup: random seed file %s missing",
                    rand_file);
                exit (-1);
        }
@@ -3922,27 +3907,36 @@ crypto_setup(void)
 #endif
 
        /*
-        * Load required host key from file "ntpkey_host_<hostname>". It
-        * also becomes the default sign key.
+        * Load required host key from file "ntpkey_host_<name>" using
+        * the group name. If the file is unavailable, try using the
+        * host name. The host key also becomes the default sign
+        * key. 
         */
-       if (host_file == NULL) {
+       if (group_name != NULL) 
                snprintf(filename, MAXFILENAME, "ntpkey_host_%s",
-                   sys_hostname);
-               host_file = emalloc(strlen(filename) + 1);
-               strcpy(host_file, filename);
+                   group_name);
+               pinfo = crypto_key(filename);
+               if (pinfo != NULL) {
+                       sys_hostname = group_name;
+       } else {
+               if (host_file != NULL)
+                       snprintf(filename, MAXFILENAME,
+                           "ntpkey_host_%s", host_file);
+               else
+                       snprintf(filename, MAXFILENAME,
+                           "ntpkey_host_%s", sys_hostname);
+               pinfo = crypto_key(filename);
        }
-       pkey = crypto_key(host_file, &fstamp);
-       if (pkey == NULL) {
+       if (pinfo == NULL) {
                msyslog(LOG_ERR,
                    "crypto_setup: host key file %s not found or corrupt",
-                   host_file);
+                   filename);
                exit (-1);
        }
-       host_pkey = pkey;
-       sign_pkey = pkey;
-       sstamp = fstamp;
-       hostval.fstamp = htonl(fstamp);
-       if (EVP_MD_type(host_pkey) != EVP_PKEY_RSA) {
+       host_pkey = pinfo->pkey;
+       sign_pkey = host_pkey;
+       hostval.fstamp = htonl(pinfo->fstamp);
+       if (host_pkey->type != EVP_PKEY_RSA) {
                msyslog(LOG_ERR,
                    "crypto_setup: host key is not RSA key type");
                exit (-1);
@@ -3962,114 +3956,116 @@ crypto_setup(void)
 
        /*
         * Load optional sign key from file "ntpkey_sign_<hostname>". If
-        * loaded, it becomes the sign key.
+        * available, it becomes the sign key.
         */
        if (sign_file == NULL) {
                snprintf(filename, MAXFILENAME, "ntpkey_sign_%s",
                    sys_hostname);
-               sign_file = emalloc(strlen(filename) + 1);
-               strcpy(sign_file, filename);
-       }
-       pkey = crypto_key(sign_file, &fstamp);
-       if (pkey != NULL) {
-               sign_pkey = pkey;
-               sstamp = fstamp;
        }
+       pinfo = crypto_key(filename);
+       if (pinfo != NULL)
+               sign_pkey = pinfo->pkey;
        sign_siglen = EVP_PKEY_size(sign_pkey);
 
-       /*
-        * Load optional IFF parameters from file
-        * "ntpkey_iff_<hostname>".
-        */
-       if (iffpar_file == NULL) {
-               snprintf(filename, MAXFILENAME, "ntpkey_iff_%s",
-                   sys_hostname);
-               iffpar_file = emalloc(strlen(filename) + 1);
-               strcpy(iffpar_file, filename);
-       }
-       iffpar_pkey = crypto_key(iffpar_file, &if_fstamp);
-       if (iffpar_pkey != NULL)
-               crypto_flags |= CRYPTO_FLAG_IFF;
-
-       /*
-        * Load optional GQ parameters from file "ntpkey_gq_<hostname>".
-        */
-       if (gqpar_file == NULL) {
-               snprintf(filename, MAXFILENAME, "ntpkey_gq_%s",
-                   sys_hostname);
-               gqpar_file = emalloc(strlen(filename) + 1);
-               strcpy(gqpar_file, filename);
-       }
-       gqpar_pkey = crypto_key(gqpar_file, &gq_fstamp);
-       if (gqpar_pkey != NULL)
-               crypto_flags |= CRYPTO_FLAG_GQ;
-
-       /*
-        * Load optional MV parameters from file "ntpkey_mv_<hostname>".
-        */
-       if (mvpar_file == NULL) {
-               snprintf(filename, MAXFILENAME, "ntpkey_mv_%s",
-                   sys_hostname);
-               mvpar_file = emalloc(strlen(filename) + 1);
-               strcpy(mvpar_file, filename);
-       }
-       mvpar_pkey = crypto_key(mvpar_file, &mv_fstamp);
-       if (mvpar_pkey != NULL)
-               crypto_flags |= CRYPTO_FLAG_MV;
-
        /*
         * Load required certificate from file "ntpkey_cert_<hostname>".
         */
-       if (cert_file == NULL) {
+       if (cert_file == NULL)
                snprintf(filename, MAXFILENAME, "ntpkey_cert_%s",
                    sys_hostname);
-               cert_file = emalloc(strlen(filename) + 1);
-               strcpy(cert_file, filename);
-       }
-       if ((cinfo = crypto_cert(cert_file)) == NULL) {
+       cinfo = crypto_cert(filename);
+       if (cinfo == NULL) {
                msyslog(LOG_ERR,
-                   "certificate file %s not found or corrupt",
-                   cert_file);
+           "crypto_setup: certificate file %s not found or corrupt",
+                   filename);
                exit (-1);
        }
 
        /*
         * The subject name must be the same as the host name, unless
-        * the certificate is private, in which case it may have come
-        * from another host.
+        * the certificate is private. In that case case it may have
+        * come from anywhere.
         */
        if (!(cinfo->flags & CERT_PRIV) && strcmp(cinfo->subject,
            sys_hostname) != 0) {
                msyslog(LOG_ERR,
                    "crypto_setup: certificate %s not for this host",
-                   cert_file);
+                   filename);
                cert_free(cinfo);
                exit (-1);
        }
+       sign_digest = cinfo->digest;
+       if (cinfo->flags & CERT_PRIV)
+               crypto_flags |= CRYPTO_FLAG_PRIV;
 
        /*
-        * It the certificate is trusted, the subject must be the same
-        * as the issuer, in other words it must be self-signed.
+        * if the certificate is trusted, it must be self-signed.
+        * In that case, scan for identity keys.
         */
-       if (cinfo->flags & CERT_TRUST && strcmp(cinfo->subject,
-           cinfo->issuer) != 0) {
-               if (cert_valid(cinfo, sign_pkey) != XEVNT_OK) {
+       if (cinfo->flags & CERT_TRUST) {
+               if (strcmp(cinfo->subject, cinfo->issuer) != 0) {
                        msyslog(LOG_ERR,
-                           "crypto_setup: certificate %s is trusted, but not self signed.",
-                           cert_file);
+                           "crypto_setup: trusted certificate %s is not self-signed",
+                           filename);
                        cert_free(cinfo);
                        exit (-1);
                }
        }
-       sign_digest = cinfo->digest;
-       if (cinfo->flags & CERT_PRIV)
-               crypto_flags |= CRYPTO_FLAG_PRIV;
+       if (group_name != NULL) {
+
+               /*
+                * Load optional IFF parameters from file
+                * "ntpkey_iff_<group_name>".
+                */
+               if (iffpar_file != NULL)
+                       snprintf(filename, MAXFILENAME, "ntpkey_iff_%s",
+                           iffpar_file);
+               else
+                       snprintf(filename, MAXFILENAME, "ntpkey_iff_%s",
+                           group_name);
+               iffpar_info = crypto_key(filename);
+               if (iffpar_info != NULL)
+                       crypto_flags |= CRYPTO_FLAG_IFF;
+
+               /*
+                * Load optional GQ parameters from file
+                * "ntpkey_gq_<group_name>".
+                */
+               if (gqpar_file != NULL)
+                       snprintf(filename, MAXFILENAME, "ntpkey_gq_%s",
+                           gqpar_file);
+               else
+                       snprintf(filename, MAXFILENAME, "ntpkey_gq_%s",
+                           group_name);
+               gqpar_info = crypto_key(filename);
+               if (gqpar_info != NULL)
+                       crypto_flags |= CRYPTO_FLAG_GQ;
+
+               /*
+                * Load optional MV parameters from file
+                * "ntpkey_mv_<groupname>".
+                */
+               if (mvpar_file != NULL)
+                       snprintf(filename, MAXFILENAME, "ntpkey_mv_%s",
+                           mvpar_file);
+               else
+                       snprintf(filename, MAXFILENAME, "ntpkey_mv_%s",
+                           group_name);
+               mvpar_info = crypto_key(filename);
+               if (mvpar_info != NULL)
+                       crypto_flags |= CRYPTO_FLAG_MV;
+       }
+
+       /*
+        * We have survived tedious and careful checking; now strike up
+        * the dance.
+        */
        crypto_flags |= CRYPTO_FLAG_ENAB | (cinfo->nid << 16);
 #ifdef DEBUG
        if (debug)
                printf(
                    "crypto_setup: flags 0x%x host %s signature %s\n",
-                   crypto_flags, sys_hostname, OBJ_nid2ln(cinfo->nid));
+                   crypto_flags, group_name, OBJ_nid2ln(cinfo->nid));
 #endif
 }
 
@@ -4086,7 +4082,7 @@ crypto_config(
 
 #ifdef DEBUG
        if (debug > 1)
-               printf("crypto_setup: item %d %s\n", item, cp);
+               printf("crypto_config: item %d %s\n", item, cp);
 #endif
        switch (item) {
 
@@ -4118,12 +4114,8 @@ crypto_config(
         * Set identity scheme (ident).
         */
        case CRYPTO_CONF_IDENT:
-               if (!strcasecmp(cp, "iff"))
-                       ident_scheme |= CRYPTO_FLAG_IFF;
-               else if (!strcasecmp(cp, "gq"))
-                       ident_scheme |= CRYPTO_FLAG_GQ;
-               else if (!strcasecmp(cp, "mv"))
-                       ident_scheme |= CRYPTO_FLAG_MV;
+               group_name = emalloc(strlen(cp) + 1);
+               strcpy(group_name, cp);
                break;
 
        /*
index 57547a171765331e1befb215462821cf126b561f..757ada7db381d9d46e1216330e59251896cbaa99 100644 (file)
@@ -1,4 +1,4 @@
-/* A Bison parser, made from /backroom/ntp-dev/A.whimsy-noopenssl/ntpd/../../ntpd/ntp_parser.y
+/* A Bison parser, made from /deacon/backroom/ntp-dev/A.deacon/ntpd/../../ntpd/ntp_parser.y
    by GNU bison 1.35.  */
 
 #define YYBISON 1  /* Identify Bison output.  */
@@ -217,7 +217,7 @@ typedef union {
 
 
 
-#define        YYFINAL         363
+#define        YYFINAL         361
 #define        YYFLAG          -32768
 #define        YYNTBASE        159
 
@@ -280,22 +280,22 @@ static const short yyprhs[] =
       89,    91,    94,    97,   100,   102,   105,   108,   111,   114,
      117,   120,   123,   126,   129,   132,   135,   137,   140,   143,
      146,   149,   152,   155,   158,   161,   164,   167,   170,   173,
-     176,   178,   181,   184,   187,   190,   193,   196,   199,   202,
-     205,   208,   211,   214,   217,   221,   224,   226,   228,   230,
-     232,   234,   236,   238,   241,   243,   246,   249,   251,   253,
-     255,   257,   259,   261,   263,   265,   267,   269,   271,   274,
-     278,   282,   288,   289,   292,   294,   296,   298,   300,   302,
-     304,   306,   308,   310,   312,   314,   316,   319,   321,   324,
-     327,   330,   334,   337,   339,   342,   345,   348,   351,   354,
-     357,   360,   363,   366,   369,   372,   374,   376,   378,   380,
-     382,   384,   386,   388,   391,   394,   396,   399,   402,   405,
-     408,   411,   414,   417,   421,   423,   426,   429,   432,   435,
-     438,   441,   444,   447,   450,   453,   456,   460,   463,   465,
-     468,   469,   474,   478,   481,   483,   486,   489,   492,   494,
-     497,   499,   501,   503,   505,   508,   510,   513,   515,   518,
-     520,   522,   524,   526,   528,   530,   536,   538,   542,   545,
-     549,   553,   556,   558,   564,   569,   573,   575,   577,   580,
-     582,   589,   593,   596,   600,   604,   608,   612
+     175,   178,   181,   184,   187,   190,   193,   196,   199,   202,
+     205,   208,   211,   214,   218,   221,   223,   225,   227,   229,
+     231,   233,   235,   238,   240,   243,   246,   248,   250,   252,
+     254,   256,   258,   260,   262,   264,   266,   268,   271,   275,
+     279,   285,   286,   289,   291,   293,   295,   297,   299,   301,
+     303,   305,   307,   309,   311,   313,   316,   318,   321,   324,
+     327,   331,   334,   336,   339,   342,   345,   348,   351,   354,
+     357,   360,   363,   366,   369,   371,   373,   375,   377,   379,
+     381,   383,   385,   388,   391,   393,   396,   399,   402,   405,
+     408,   411,   414,   418,   420,   423,   426,   429,   432,   435,
+     438,   441,   444,   447,   450,   453,   457,   460,   462,   465,
+     466,   471,   475,   478,   480,   483,   486,   489,   491,   494,
+     496,   498,   500,   502,   505,   507,   510,   512,   515,   517,
+     519,   521,   523,   525,   527,   533,   535,   539,   542,   546,
+     550,   553,   555,   561,   566,   570,   572,   574,   577,   579,
+     586,   590,   593,   597,   601,   605,   609
 };
 static const short yyrhs[] =
 {
@@ -314,53 +314,53 @@ static const short yyrhs[] =
       58,   126,     0,    59,   126,     0,   114,    54,     0,   135,
      203,     0,   170,   171,     0,   171,     0,    18,   126,     0,
       44,   126,     0,    45,   126,     0,    50,   126,     0,    51,
-     126,     0,    61,   126,     0,    85,   126,     0,   110,   126,
-       0,   111,   126,     0,   116,    54,     0,   119,   126,     0,
-     132,   173,     0,   173,   174,     0,   174,     0,    17,    54,
-       0,    41,    54,     0,    20,   206,     0,    98,    54,     0,
-      77,   207,     0,    73,   207,     0,    76,   207,     0,    72,
-     207,     0,    80,    54,     0,    10,    54,     0,    74,    54,
-       0,   120,   176,     0,   122,   126,     0,    36,   177,   178,
-       0,   176,   177,     0,   177,     0,    19,     0,    23,     0,
-      67,     0,   101,     0,   112,     0,   127,     0,   178,   179,
-       0,   179,     0,    35,   126,     0,   137,   180,     0,    64,
-       0,    86,     0,    32,     0,    26,     0,    88,     0,   103,
-       0,    24,     0,   139,     0,    83,     0,   140,     0,     3,
-       0,    27,   184,     0,   115,   164,   182,     0,   115,    25,
-     182,     0,   115,   165,    71,   165,   182,     0,     0,   182,
-     183,     0,    52,     0,    60,     0,    63,     0,    68,     0,
-      87,     0,    89,     0,    90,     0,    92,     0,    93,     0,
-      94,     0,    97,     0,   138,     0,   184,   185,     0,   185,
-       0,     8,    54,     0,    78,    54,     0,    82,    54,     0,
-      43,   164,   187,     0,   187,   188,     0,   188,     0,   129,
-     207,     0,   130,   207,     0,   125,    54,     0,   113,   126,
-       0,    37,   206,     0,    38,   206,     0,    39,   206,     0,
-      40,   206,     0,    32,   190,     0,    26,   190,     0,   190,
-     191,     0,   191,     0,     5,     0,     9,     0,    15,     0,
-      56,     0,    82,     0,    96,     0,   121,     0,   131,   193,
-       0,   193,   194,     0,   194,     0,     4,   207,     0,    28,
-     207,     0,    42,   207,     0,    46,   207,     0,    99,   207,
-       0,   123,   207,     0,   124,   207,     0,    53,   126,   161,
-       0,    33,     0,    13,   207,     0,    16,    54,     0,   128,
-     207,     0,    30,   196,     0,    62,   126,     0,   104,   126,
-       0,    66,   126,     0,     7,    54,     0,    65,   200,     0,
-     102,   204,     0,   118,   197,     0,   133,   165,   198,     0,
-     136,   203,     0,   126,     0,   126,    29,     0,     0,   126,
-     154,   126,    25,     0,   126,   154,   126,     0,   198,   199,
-       0,   199,     0,   106,    54,     0,    55,   165,     0,   200,
-     201,     0,   201,     0,   202,   126,     0,   126,     0,   155,
-       0,   156,     0,   154,     0,   203,    54,     0,    54,     0,
-     204,   126,     0,   126,     0,   205,   164,     0,   164,     0,
-      54,     0,   134,     0,    34,     0,    54,     0,    29,     0,
-     209,   157,   210,   212,   158,     0,   144,     0,   210,   211,
-     143,     0,   211,   143,     0,   145,   154,   207,     0,   146,
-     154,   207,     0,   212,   213,     0,   213,     0,   215,   157,
-     214,   217,   158,     0,   147,   154,   207,   143,     0,   117,
-     154,   216,     0,   165,     0,   126,     0,   217,   218,     0,
-     218,     0,   148,   154,   207,   157,   219,   158,     0,   219,
-     220,   143,     0,   220,   143,     0,   149,   154,   207,     0,
-     150,   154,   207,     0,   151,   154,   207,     0,   152,   154,
-     207,     0,   153,   154,   207,     0
+     126,     0,    85,   126,     0,   110,   126,     0,   111,   126,
+       0,   116,    54,     0,   119,   126,     0,   132,   173,     0,
+     173,   174,     0,   174,     0,    17,    54,     0,    41,    54,
+       0,    20,   206,     0,    98,    54,     0,    77,   207,     0,
+      73,   207,     0,    76,   207,     0,    72,   207,     0,    80,
+      54,     0,    10,    54,     0,    74,    54,     0,   120,   176,
+       0,   122,   126,     0,    36,   177,   178,     0,   176,   177,
+       0,   177,     0,    19,     0,    23,     0,    67,     0,   101,
+       0,   112,     0,   127,     0,   178,   179,     0,   179,     0,
+      35,   126,     0,   137,   180,     0,    64,     0,    86,     0,
+      32,     0,    26,     0,    88,     0,   103,     0,    24,     0,
+     139,     0,    83,     0,   140,     0,     3,     0,    27,   184,
+       0,   115,   164,   182,     0,   115,    25,   182,     0,   115,
+     165,    71,   165,   182,     0,     0,   182,   183,     0,    52,
+       0,    60,     0,    63,     0,    68,     0,    87,     0,    89,
+       0,    90,     0,    92,     0,    93,     0,    94,     0,    97,
+       0,   138,     0,   184,   185,     0,   185,     0,     8,    54,
+       0,    78,    54,     0,    82,    54,     0,    43,   164,   187,
+       0,   187,   188,     0,   188,     0,   129,   207,     0,   130,
+     207,     0,   125,    54,     0,   113,   126,     0,    37,   206,
+       0,    38,   206,     0,    39,   206,     0,    40,   206,     0,
+      32,   190,     0,    26,   190,     0,   190,   191,     0,   191,
+       0,     5,     0,     9,     0,    15,     0,    56,     0,    82,
+       0,    96,     0,   121,     0,   131,   193,     0,   193,   194,
+       0,   194,     0,     4,   207,     0,    28,   207,     0,    42,
+     207,     0,    46,   207,     0,    99,   207,     0,   123,   207,
+       0,   124,   207,     0,    53,   126,   161,     0,    33,     0,
+      13,   207,     0,    16,    54,     0,   128,   207,     0,    30,
+     196,     0,    62,   126,     0,   104,   126,     0,    66,   126,
+       0,     7,    54,     0,    65,   200,     0,   102,   204,     0,
+     118,   197,     0,   133,   165,   198,     0,   136,   203,     0,
+     126,     0,   126,    29,     0,     0,   126,   154,   126,    25,
+       0,   126,   154,   126,     0,   198,   199,     0,   199,     0,
+     106,    54,     0,    55,   165,     0,   200,   201,     0,   201,
+       0,   202,   126,     0,   126,     0,   155,     0,   156,     0,
+     154,     0,   203,    54,     0,    54,     0,   204,   126,     0,
+     126,     0,   205,   164,     0,   164,     0,    54,     0,   134,
+       0,    34,     0,    54,     0,    29,     0,   209,   157,   210,
+     212,   158,     0,   144,     0,   210,   211,   143,     0,   211,
+     143,     0,   145,   154,   207,     0,   146,   154,   207,     0,
+     212,   213,     0,   213,     0,   215,   157,   214,   217,   158,
+       0,   147,   154,   207,   143,     0,   117,   154,   216,     0,
+     165,     0,   126,     0,   217,   218,     0,   218,     0,   148,
+     154,   207,   157,   219,   158,     0,   219,   220,   143,     0,
+     220,   143,     0,   149,   154,   207,     0,   150,   154,   207,
+       0,   151,   154,   207,     0,   152,   154,   207,     0,   153,
+     154,   207,     0
 };
 
 #endif
@@ -375,23 +375,23 @@ static const short yyrline[] =
      367,   372,   373,   374,   375,   376,   377,   378,   379,   380,
      381,   382,   383,   384,   394,   396,   398,   400,   411,   413,
      415,   421,   423,   425,   427,   432,   433,   437,   439,   441,
-     443,   445,   447,   449,   451,   453,   455,   457,   467,   472,
-     473,   477,   479,   481,   483,   485,   487,   489,   491,   493,
-     495,   497,   507,   509,   511,   519,   520,   524,   526,   528,
-     530,   532,   534,   539,   540,   544,   545,   546,   547,   548,
-     549,   553,   554,   555,   556,   557,   558,   559,   568,   570,
-     575,   580,   588,   589,   593,   594,   595,   596,   597,   598,
-     599,   600,   601,   602,   603,   604,   608,   609,   613,   614,
-     615,   623,   628,   629,   633,   635,   637,   639,   641,   643,
-     645,   647,   656,   658,   663,   664,   668,   669,   670,   671,
-     672,   673,   675,   683,   687,   688,   692,   693,   694,   695,
-     696,   697,   698,   706,   722,   728,   730,   732,   734,   736,
-     739,   741,   743,   746,   748,   750,   752,   754,   758,   760,
-     763,   768,   770,   776,   777,   781,   782,   787,   788,   792,
-     793,   810,   811,   812,   821,   822,   826,   827,   831,   832,
-     836,   845,   846,   850,   851,   859,   874,   878,   879,   883,
-     884,   888,   889,   893,   898,   902,   906,   907,   911,   912,
-     916,   921,   922,   926,   928,   930,   932,   934
+     443,   445,   447,   449,   451,   453,   455,   465,   470,   471,
+     475,   477,   479,   481,   483,   485,   487,   489,   491,   493,
+     495,   505,   507,   509,   517,   518,   522,   524,   526,   528,
+     530,   532,   537,   538,   542,   543,   544,   545,   546,   547,
+     551,   552,   553,   554,   555,   556,   557,   566,   568,   573,
+     578,   586,   587,   591,   592,   593,   594,   595,   596,   597,
+     598,   599,   600,   601,   602,   606,   607,   611,   612,   613,
+     621,   626,   627,   631,   633,   635,   637,   639,   641,   643,
+     645,   654,   656,   661,   662,   666,   667,   668,   669,   670,
+     671,   673,   681,   685,   686,   690,   691,   692,   693,   694,
+     695,   696,   704,   720,   726,   728,   730,   732,   734,   737,
+     739,   741,   744,   746,   748,   750,   752,   756,   758,   761,
+     766,   768,   774,   775,   779,   780,   785,   786,   790,   791,
+     808,   809,   810,   819,   820,   824,   825,   829,   830,   834,
+     843,   844,   848,   849,   857,   872,   876,   877,   881,   882,
+     886,   887,   891,   896,   900,   904,   905,   909,   910,   914,
+     919,   920,   924,   926,   928,   930,   932
 };
 #endif
 
@@ -461,23 +461,23 @@ static const short yyr1[] =
      166,   167,   167,   167,   167,   167,   167,   167,   167,   167,
      167,   167,   167,   167,   168,   168,   168,   168,   169,   169,
      169,   169,   169,   169,   169,   170,   170,   171,   171,   171,
-     171,   171,   171,   171,   171,   171,   171,   171,   172,   173,
-     173,   174,   174,   174,   174,   174,   174,   174,   174,   174,
-     174,   174,   175,   175,   175,   176,   176,   177,   177,   177,
-     177,   177,   177,   178,   178,   179,   179,   179,   179,   179,
-     179,   180,   180,   180,   180,   180,   180,   180,   181,   181,
-     181,   181,   182,   182,   183,   183,   183,   183,   183,   183,
-     183,   183,   183,   183,   183,   183,   184,   184,   185,   185,
-     185,   186,   187,   187,   188,   188,   188,   188,   188,   188,
-     188,   188,   189,   189,   190,   190,   191,   191,   191,   191,
-     191,   191,   191,   192,   193,   193,   194,   194,   194,   194,
-     194,   194,   194,   195,   195,   195,   195,   195,   195,   195,
-     195,   195,   195,   195,   195,   195,   195,   195,   196,   196,
-     196,   197,   197,   198,   198,   199,   199,   200,   200,   201,
-     201,   202,   202,   202,   203,   203,   204,   204,   205,   205,
-     206,   206,   206,   207,   207,   208,   209,   210,   210,   211,
-     211,   212,   212,   213,   214,   215,   216,   216,   217,   217,
-     218,   219,   219,   220,   220,   220,   220,   220
+     171,   171,   171,   171,   171,   171,   171,   172,   173,   173,
+     174,   174,   174,   174,   174,   174,   174,   174,   174,   174,
+     174,   175,   175,   175,   176,   176,   177,   177,   177,   177,
+     177,   177,   178,   178,   179,   179,   179,   179,   179,   179,
+     180,   180,   180,   180,   180,   180,   180,   181,   181,   181,
+     181,   182,   182,   183,   183,   183,   183,   183,   183,   183,
+     183,   183,   183,   183,   183,   184,   184,   185,   185,   185,
+     186,   187,   187,   188,   188,   188,   188,   188,   188,   188,
+     188,   189,   189,   190,   190,   191,   191,   191,   191,   191,
+     191,   191,   192,   193,   193,   194,   194,   194,   194,   194,
+     194,   194,   195,   195,   195,   195,   195,   195,   195,   195,
+     195,   195,   195,   195,   195,   195,   195,   196,   196,   196,
+     197,   197,   198,   198,   199,   199,   200,   200,   201,   201,
+     202,   202,   202,   203,   203,   204,   204,   205,   205,   206,
+     206,   206,   207,   207,   208,   209,   210,   210,   211,   211,
+     212,   212,   213,   214,   215,   216,   216,   217,   217,   218,
+     219,   219,   220,   220,   220,   220,   220
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
@@ -489,23 +489,23 @@ static const short yyr2[] =
        1,     1,     1,     1,     2,     2,     2,     1,     1,     1,
        1,     2,     2,     2,     1,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     1,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       1,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     3,     2,     1,     1,     1,     1,
-       1,     1,     1,     2,     1,     2,     2,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     1,     2,     3,
-       3,     5,     0,     2,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     2,     1,     2,     2,
-       2,     3,     2,     1,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     1,     1,     1,     1,     1,
-       1,     1,     1,     2,     2,     1,     2,     2,     2,     2,
-       2,     2,     2,     3,     1,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     3,     2,     1,     2,
-       0,     4,     3,     2,     1,     2,     2,     2,     1,     2,
-       1,     1,     1,     1,     2,     1,     2,     1,     2,     1,
-       1,     1,     1,     1,     1,     5,     1,     3,     2,     3,
-       3,     2,     1,     5,     4,     3,     1,     1,     2,     1,
-       6,     3,     2,     3,     3,     3,     3,     3
+       2,     2,     2,     3,     2,     1,     1,     1,     1,     1,
+       1,     1,     2,     1,     2,     2,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     2,     3,     3,
+       5,     0,     2,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     2,     1,     2,     2,     2,
+       3,     2,     1,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     2,     2,     1,     2,     2,     2,     2,     2,
+       2,     2,     3,     1,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     3,     2,     1,     2,     0,
+       4,     3,     2,     1,     2,     2,     2,     1,     2,     1,
+       1,     1,     1,     2,     1,     2,     1,     2,     1,     1,
+       1,     1,     1,     1,     5,     1,     3,     2,     3,     3,
+       2,     1,     5,     4,     3,     1,     1,     2,     1,     6,
+       3,     2,     3,     3,     3,     3,     3
 };
 
 /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
@@ -514,219 +514,215 @@ static const short yyr2[] =
 static const short yydefact[] =
 {
        0,     0,     0,     0,    22,    44,     0,     0,     0,     0,
-       0,     0,   180,     0,   164,     0,     0,     0,     0,     0,
+       0,     0,   179,     0,   163,     0,     0,     0,     0,     0,
        0,     0,     0,    23,     0,     0,    21,     0,     0,    20,
        0,     0,    19,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   206,     1,     0,     6,     0,     7,     8,    11,
+       0,     0,   205,     1,     0,     6,     0,     7,     8,    11,
        9,    10,    12,    13,    14,    15,    16,     0,     4,    48,
-     172,    45,   204,   203,   165,   166,    49,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    50,    56,
-     146,   147,   148,   149,   150,   151,   152,   143,   145,     0,
-       0,     0,   108,   127,   178,   168,   142,    87,    88,    89,
-      90,    91,    92,     0,    27,    28,     0,    25,     0,    24,
-       5,    51,    52,   169,   190,   193,   191,   192,   173,   188,
-       0,   171,   199,    46,    47,   197,   174,   170,    53,   112,
-     112,    24,     0,   175,    82,    86,    83,   167,     0,     0,
-       0,     0,     0,     0,     0,   153,   155,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    68,    70,
-       0,   195,    54,   177,     0,     3,    18,     0,    57,    58,
-      59,    60,    61,    62,    63,    64,    65,    66,    67,    55,
-     144,   128,   129,   130,   126,   179,   100,    99,     0,    97,
-      98,     0,    84,    94,    26,     0,     0,     0,     0,     0,
-       0,     0,     0,   131,   133,   163,   187,   189,   198,   196,
-     110,   109,     0,     0,    85,   156,   157,   158,   159,   160,
-     161,   162,   154,    80,    71,   202,   200,   201,    73,    72,
-      78,    76,    81,    77,    75,    79,    74,    69,     0,     0,
-     176,   184,   194,     2,    31,    32,    33,     0,     0,     0,
-       0,    37,    38,    39,    40,     0,     0,    17,    30,     0,
-       0,     0,     0,    95,   107,   103,   105,   101,   102,   104,
-     106,    96,    93,   138,   139,   140,   141,   137,   136,   134,
-     135,   132,   114,   115,   116,   117,   118,   119,   120,   121,
-     122,   123,   124,   125,   113,   112,   182,   186,   185,   183,
-      34,    36,    35,    42,    41,    43,    29,     0,     0,     0,
-       0,     0,   212,     0,   208,   111,   181,   209,   210,     0,
-     207,   205,   211,     0,   217,   216,   215,     0,     0,     0,
-       0,     0,   219,     0,     0,   213,   218,   214,     0,     0,
+     171,    45,   203,   202,   164,   165,    49,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    50,    56,   145,
+     146,   147,   148,   149,   150,   151,   142,   144,     0,     0,
+       0,   107,   126,   177,   167,   141,    86,    87,    88,    89,
+      90,    91,     0,    27,    28,     0,    25,     0,    24,     5,
+      51,    52,   168,   189,   192,   190,   191,   172,   187,     0,
+     170,   198,    46,    47,   196,   173,   169,    53,   111,   111,
+      24,     0,   174,    81,    85,    82,   166,     0,     0,     0,
+       0,     0,     0,     0,   152,   154,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    67,    69,     0,
+     194,    54,   176,     0,     3,    18,     0,    57,    58,    59,
+      60,    61,    62,    63,    64,    65,    66,    55,   143,   127,
+     128,   129,   125,   178,    99,    98,     0,    96,    97,     0,
+      83,    93,    26,     0,     0,     0,     0,     0,     0,     0,
+       0,   130,   132,   162,   186,   188,   197,   195,   109,   108,
+       0,     0,    84,   155,   156,   157,   158,   159,   160,   161,
+     153,    79,    70,   201,   199,   200,    72,    71,    77,    75,
+      80,    76,    74,    78,    73,    68,     0,     0,   175,   183,
+     193,     2,    31,    32,    33,     0,     0,     0,     0,    37,
+      38,    39,    40,     0,     0,    17,    30,     0,     0,     0,
+       0,    94,   106,   102,   104,   100,   101,   103,   105,    95,
+      92,   137,   138,   139,   140,   136,   135,   133,   134,   131,
+     113,   114,   115,   116,   117,   118,   119,   120,   121,   122,
+     123,   124,   112,   111,   181,   185,   184,   182,    34,    36,
+      35,    42,    41,    43,    29,     0,     0,     0,     0,     0,
+     211,     0,   207,   110,   180,   208,   209,     0,   206,   204,
+     210,     0,   216,   215,   214,     0,     0,     0,     0,     0,
+     218,     0,     0,   212,   217,   213,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   220,     0,   222,   223,   224,   225,   226,   227,
-     221,     0,     0,     0
+     219,     0,   221,   222,   223,   224,   225,   226,   220,     0,
+       0,     0
 };
 
 static const short yydefgoto[] =
 {
-     361,    43,    44,    45,    46,   122,   109,   257,   258,    47,
-      48,    78,    79,    49,   158,   159,    50,   134,   103,   192,
-     193,   271,    51,   210,   294,    92,    93,    52,   203,   204,
-      53,    87,    88,    54,   145,   146,    55,    95,   133,   240,
-     241,   118,   119,   120,   162,   126,   123,   228,    64,    56,
-      57,   261,   262,   311,   312,   328,   313,   326,   331,   332,
-     345,   346
+     359,    43,    44,    45,    46,   121,   108,   255,   256,    47,
+      48,    77,    78,    49,   157,   158,    50,   133,   102,   190,
+     191,   269,    51,   208,   292,    91,    92,    52,   201,   202,
+      53,    86,    87,    54,   144,   145,    55,    94,   132,   238,
+     239,   117,   118,   119,   161,   125,   122,   226,    64,    56,
+      57,   259,   260,   309,   310,   326,   311,   324,   329,   330,
+     343,   344
 };
 
 static const short yypact[] =
 {
-       9,  -125,   -28,   -21,-32768,   -57,   -10,    -4,     2,   184,
-      -1,    -5,   -62,    -1,-32768,    24,   -41,   -50,   -46,   -40,
-     -37,    31,   -34,-32768,   -41,   -41,-32768,   -32,   -16,-32768,
-      34,    12,-32768,     4,    24,     7,   -10,    23,   324,    10,
-      36,    36,-32768,   148,    -8,-32768,   -41,-32768,-32768,-32768,
-  -32768,-32768,-32768,-32768,-32768,-32768,-32768,   -61,-32768,-32768,
-  -32768,-32768,-32768,-32768,-32768,-32768,-32768,    13,    30,    32,
-      45,    46,    47,    50,    53,    57,    95,    62,   184,-32768,
-  -32768,-32768,-32768,-32768,-32768,-32768,-32768,    -1,-32768,    96,
-     108,   123,    -5,-32768,   163,-32768,    -1,-32768,-32768,-32768,
-  -32768,-32768,-32768,    -3,-32768,-32768,    67,-32768,   220,-32768,
-     310,-32768,-32768,-32768,-32768,-32768,-32768,-32768,    31,-32768,
-      68,-32768,-32768,   -41,   -41,-32768,    69,-32768,-32768,-32768,
-  -32768,   127,    49,-32768,    24,-32768,-32768,-32768,   -10,   -10,
-     -10,   -10,   -10,   -10,   -10,    23,-32768,   150,   151,    -6,
-     155,   -10,   -10,   157,   -10,   -10,   158,   161,   324,-32768,
-      15,-32768,   162,   162,    76,-32768,   342,  -134,-32768,-32768,
+      24,  -136,   -39,   -34,-32768,   -61,   -25,   -15,    -7,   333,
+      53,    10,   -65,    53,-32768,   153,   -42,   -63,   -60,   -54,
+     -52,    27,   -48,-32768,   -42,   -42,-32768,   -47,   -45,-32768,
+      31,    17,-32768,   -10,   153,    -3,   -25,    13,   350,    28,
+      33,    33,-32768,   202,   -18,-32768,   -42,-32768,-32768,-32768,
+  -32768,-32768,-32768,-32768,-32768,-32768,-32768,   -17,-32768,-32768,
+  -32768,-32768,-32768,-32768,-32768,-32768,-32768,    19,    25,    32,
+      35,    39,    43,    45,    49,    96,    51,   333,-32768,-32768,
+  -32768,-32768,-32768,-32768,-32768,-32768,    53,-32768,   100,   124,
+     125,    10,-32768,   155,-32768,    53,-32768,-32768,-32768,-32768,
+  -32768,-32768,   -16,-32768,-32768,    65,-32768,    60,-32768,   336,
+  -32768,-32768,-32768,-32768,-32768,-32768,-32768,    27,-32768,    67,
+  -32768,-32768,   -42,   -42,-32768,    69,-32768,-32768,-32768,-32768,
+     130,    48,-32768,   153,-32768,-32768,-32768,   -25,   -25,   -25,
+     -25,   -25,   -25,   -25,    13,-32768,   149,   156,   -21,   157,
+     -25,   -25,   158,   -25,   -25,   162,   163,   350,-32768,   -33,
+  -32768,   165,   165,    82,-32768,   113,  -119,-32768,-32768,-32768,
   -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
-  -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,    94,-32768,
-  -32768,    60,    -3,-32768,-32768,    -6,    -6,    -6,    -6,   100,
-     173,   -10,   -10,   220,-32768,-32768,-32768,-32768,-32768,-32768,
-     366,   366,    10,   105,-32768,-32768,-32768,-32768,-32768,-32768,
+  -32768,-32768,-32768,-32768,-32768,-32768,    81,-32768,-32768,     8,
+     -16,-32768,-32768,   -21,   -21,   -21,   -21,   101,   172,   -25,
+     -25,    60,-32768,-32768,-32768,-32768,-32768,-32768,   322,   322,
+      28,   104,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
   -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
-  -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,    10,   179,
-      15,-32768,-32768,-32768,-32768,-32768,-32768,   187,   188,   189,
-     190,-32768,-32768,-32768,-32768,   192,   193,   342,-32768,    97,
-     101,    51,   106,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+  -32768,-32768,-32768,-32768,-32768,-32768,    28,   177,   -33,-32768,
+  -32768,-32768,-32768,-32768,-32768,   179,   182,   183,   189,-32768,
+  -32768,-32768,-32768,   190,   192,   113,-32768,    94,    98,   -93,
+     107,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
   -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
   -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
-  -32768,-32768,-32768,-32768,-32768,-32768,   229,-32768,-32768,-32768,
-  -32768,-32768,-32768,-32768,-32768,-32768,-32768,   -10,   -10,   102,
-     118,   -71,-32768,   107,-32768,   366,-32768,-32768,-32768,     6,
-  -32768,-32768,-32768,   120,-32768,-32768,-32768,   119,   126,   -10,
-     121,  -124,-32768,   134,   -10,-32768,-32768,-32768,   125,    87,
-     124,   131,   132,   133,   136,    72,   145,   -10,   -10,   -10,
-     -10,   -10,-32768,   153,-32768,-32768,-32768,-32768,-32768,-32768,
-  -32768,   297,   299,-32768
+  -32768,-32768,-32768,-32768,   228,-32768,-32768,-32768,-32768,-32768,
+  -32768,-32768,-32768,-32768,-32768,   -25,   -25,   102,   114,  -109,
+  -32768,   105,-32768,   322,-32768,-32768,-32768,    -4,-32768,-32768,
+  -32768,   111,-32768,-32768,-32768,   109,   118,   -25,   119,  -120,
+  -32768,   116,   -25,-32768,-32768,-32768,   117,   -19,   121,   122,
+     123,   127,   128,    47,   135,   -25,   -25,   -25,   -25,   -25,
+  -32768,   136,-32768,-32768,-32768,-32768,-32768,-32768,-32768,   283,
+     284,-32768
 };
 
 static const short yypgoto[] =
 {
-  -32768,-32768,   -38,-32768,-32768,    66,   -30,-32768,    44,-32768,
-  -32768,-32768,   224,-32768,-32768,   146,-32768,-32768,   -17,-32768,
-     113,-32768,-32768,  -128,-32768,-32768,   214,-32768,-32768,   104,
-  -32768,   295,   -47,-32768,-32768,   164,-32768,-32768,-32768,-32768,
-      70,-32768,   200,-32768,   278,-32768,   300,   -97,   -36,-32768,
-  -32768,-32768,    59,-32768,    16,-32768,-32768,-32768,-32768,    -7,
-  -32768,   -15
+  -32768,-32768,   -40,-32768,-32768,    64,   -30,-32768,    30,-32768,
+  -32768,-32768,   211,-32768,-32768,   132,-32768,-32768,   -13,-32768,
+     103,-32768,-32768,  -127,-32768,-32768,   199,-32768,-32768,    91,
+  -32768,   281,   -72,-32768,-32768,   151,-32768,-32768,-32768,-32768,
+      59,-32768,   181,-32768,   258,-32768,   275,    46,   -36,-32768,
+  -32768,-32768,    42,-32768,    -6,-32768,-32768,-32768,-32768,   -24,
+  -32768,   -35
 };
 
 
-#define        YYLAST          504
+#define        YYLAST          480
 
 
 static const short yytable[] =
 {
-     137,   131,   211,    89,    80,   164,   104,   105,    81,   160,
-       1,   259,   260,   106,    82,     2,     3,   135,    58,    62,
-       4,     5,     6,   186,   330,     7,    59,   138,   225,   187,
-       8,     9,   188,    60,   335,    10,    11,   129,    61,    12,
-     180,    13,    14,    97,    63,    15,   309,    98,   226,   180,
-      65,   139,    16,   104,   105,    83,    66,   104,   105,   104,
-     105,   189,    17,   264,    94,   140,   106,    18,    19,   141,
-     238,    20,   205,    90,    21,    22,   110,    91,    23,    24,
-     111,    84,   108,   190,   265,   107,   112,   321,   128,   113,
-     161,    99,   121,    25,   125,    85,   167,   130,   273,   274,
-     275,   276,   215,   216,   217,   218,   219,   220,   221,    26,
-     127,    27,   166,    28,    29,   230,   231,   214,   233,   234,
-      86,   239,   142,    30,    31,   100,    32,    33,   227,    34,
-     132,    35,   324,   136,   191,   165,   101,    36,   107,   168,
-      37,    38,    39,   266,    40,    41,   143,   144,   267,   177,
-     181,   102,    -5,    42,     2,     3,   169,   114,   170,     4,
-       5,     6,   182,   268,     7,   279,   280,   315,   309,     8,
-       9,   171,   172,   173,    10,    11,   174,   183,    12,   175,
-      13,    14,   295,   176,    15,   115,   116,   117,   178,   208,
-     208,    16,   185,   194,   207,   209,   259,   260,   212,   269,
-     270,    17,    67,   213,   223,   224,    18,    19,   297,   229,
-      20,   232,   235,    21,    22,   236,   242,    23,    24,   243,
-     263,   340,   341,   342,   343,   344,   277,   278,    68,    69,
-     352,   296,    25,   298,    70,    71,   340,   341,   342,   343,
-     344,   300,   301,   302,   303,    72,   304,   305,    26,   314,
-      27,   307,    28,    29,   316,   308,   319,   195,   196,   197,
-     198,   320,    30,    31,   323,    32,    33,   327,    34,    73,
-      35,   317,   318,   329,   330,   334,    36,   337,   347,    37,
-      38,    39,   339,    40,    41,   348,   349,   350,   354,   325,
-     351,    -5,    42,   333,    74,    75,   360,   362,   338,   363,
-      76,   306,   179,    77,   237,   272,   184,   281,    96,   222,
-     299,   355,   356,   357,   358,   359,     2,     3,   206,   163,
-     310,     4,     5,     6,   336,   124,     7,   322,     0,     0,
-     353,     8,     9,   199,   147,     0,    10,    11,     0,     0,
-      12,   148,    13,    14,   149,   200,    15,     0,   244,   201,
-     202,     0,     0,    16,     0,     0,   245,     0,     0,     0,
-       0,     0,     0,    17,     0,   150,     0,     0,    18,    19,
-       0,     0,    20,     0,     0,    21,    22,     0,     0,    23,
-      24,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   246,     0,     0,    25,     0,   151,   152,   153,   247,
-     154,   155,     0,     0,   156,     0,     0,     0,     0,     0,
-      26,     0,    27,     0,    28,    29,     0,   248,   282,     0,
-       0,   249,   157,   250,    30,    31,   283,    32,    33,   284,
-      34,     0,    35,   251,   285,     0,     0,     0,    36,     0,
-       0,    37,    38,    39,     0,    40,    41,     0,     0,     0,
-     252,   253,     0,   286,    42,   287,   288,     0,   289,   290,
-     291,     0,     0,   292,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,   254,     0,   255,     0,
-     256,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,   293
+     136,   130,   209,   163,    62,   103,   104,    58,   307,   159,
+     184,   262,   105,   223,   178,    59,   185,   137,    88,   186,
+      60,   134,   236,   178,   307,     1,   257,   258,   328,    63,
+       2,     3,   263,   224,    61,     4,     5,     6,   333,    65,
+       7,   138,   128,   103,   104,     8,     9,    66,   187,   319,
+      10,    11,   257,   258,    12,   139,    13,    14,    79,   140,
+      15,    93,    80,   109,   103,   104,   110,    16,    81,   203,
+     188,   105,   111,   237,   112,   103,   104,    17,   120,   124,
+     107,   126,    18,    19,   106,   127,    20,   160,    89,    21,
+      22,   264,    90,    23,    24,   129,   265,   193,   194,   195,
+     196,   213,   214,   215,   216,   217,   218,   219,    25,    82,
+     165,   266,   141,   225,   228,   229,   131,   231,   232,   242,
+     212,   189,   322,   135,    26,   164,    27,   243,    28,    29,
+     338,   339,   340,   341,   342,    83,   142,   143,    30,    31,
+     166,    32,    33,   106,    34,   167,    35,   267,   268,    84,
+     175,   168,    36,   113,   179,    37,    38,    39,   169,    40,
+      41,   170,   244,   277,   278,   171,   313,    -5,    42,   172,
+     245,   173,    96,   197,    85,   174,    97,   176,   180,   181,
+     293,   114,   115,   116,   183,   198,   206,   206,   246,   199,
+     200,   192,   247,   205,   248,   207,   338,   339,   340,   341,
+     342,   210,   211,   221,   249,   350,   295,   261,     2,     3,
+     222,   227,   230,     4,     5,     6,   233,   234,     7,   240,
+      98,   250,   251,     8,     9,   241,   276,   275,    10,    11,
+     294,   296,    12,   298,    13,    14,   299,   300,    15,   271,
+     272,   273,   274,   301,   302,    16,   303,   252,   305,   253,
+     312,   254,   306,   314,    99,    17,   317,   318,   325,   335,
+      18,    19,   321,   327,    20,   100,   328,    21,    22,   315,
+     316,    23,    24,   332,   337,   345,   346,   347,   352,   358,
+     101,   348,   349,   360,   361,   304,    25,   323,   177,   235,
+     182,   331,   279,   270,    95,   220,   336,   297,   204,   162,
+     123,   308,    26,   320,    27,   334,    28,    29,   351,   353,
+     354,   355,   356,   357,     0,     0,    30,    31,     0,    32,
+      33,     0,    34,     0,    35,     0,     0,     0,     0,     0,
+      36,     0,     0,    37,    38,    39,     0,    40,    41,     0,
+       0,     0,     2,     3,     0,    -5,    42,     4,     5,     6,
+       0,    67,     7,     0,     0,     0,     0,     8,     9,     0,
+     146,     0,    10,    11,     0,     0,    12,   147,    13,    14,
+     148,     0,    15,     0,   280,     0,     0,    68,    69,    16,
+       0,     0,   281,    70,    71,   282,     0,     0,     0,    17,
+     283,   149,     0,     0,    18,    19,     0,     0,    20,     0,
+       0,    21,    22,     0,     0,    23,    24,     0,     0,   284,
+       0,   285,   286,     0,   287,   288,   289,     0,    72,   290,
+      25,     0,   150,   151,   152,     0,   153,   154,     0,     0,
+     155,     0,     0,     0,     0,     0,    26,     0,    27,     0,
+      28,    29,     0,    73,    74,     0,     0,     0,   156,    75,
+      30,    31,    76,    32,    33,     0,    34,     0,    35,     0,
+     291,     0,     0,     0,    36,     0,     0,    37,    38,    39,
+       0,    40,    41,     0,     0,     0,     0,     0,     0,     0,
+      42
 };
 
 static const short yycheck[] =
 {
-      36,    31,   130,     8,     5,    43,    47,    48,     9,    39,
-       1,   145,   146,    54,    15,     6,     7,    34,   143,    29,
-      11,    12,    13,    26,   148,    16,    54,     4,    34,    32,
-      21,    22,    35,    54,   158,    26,    27,    25,    95,    30,
-      87,    32,    33,    19,    54,    36,   117,    23,    54,    96,
-      54,    28,    43,    47,    48,    56,    54,    47,    48,    47,
-      48,    64,    53,     3,   126,    42,    54,    58,    59,    46,
-      55,    62,   110,    78,    65,    66,   126,    82,    69,    70,
-     126,    82,    16,    86,    24,   126,   126,   158,    54,   126,
-      54,    67,   126,    84,   126,    96,   157,    31,   195,   196,
-     197,   198,   138,   139,   140,   141,   142,   143,   144,   100,
-     126,   102,    46,   104,   105,   151,   152,   134,   154,   155,
-     121,   106,    99,   114,   115,   101,   117,   118,   134,   120,
-     126,   122,   126,   126,   137,   143,   112,   128,   126,   126,
-     131,   132,   133,    83,   135,   136,   123,   124,    88,    54,
-      54,   127,   143,   144,     6,     7,   126,   126,   126,    11,
-      12,    13,    54,   103,    16,   201,   202,   295,   117,    21,
-      22,   126,   126,   126,    26,    27,   126,    54,    30,   126,
-      32,    33,   212,   126,    36,   154,   155,   156,   126,   123,
-     124,    43,    29,   126,   126,   126,   145,   146,    71,   139,
-     140,    53,    18,   154,    54,    54,    58,    59,   238,    54,
-      62,    54,    54,    65,    66,    54,    54,    69,    70,   143,
-     126,   149,   150,   151,   152,   153,   126,    54,    44,    45,
-     158,   126,    84,    54,    50,    51,   149,   150,   151,   152,
-     153,    54,    54,    54,    54,    61,    54,    54,   100,   143,
-     102,   154,   104,   105,    25,   154,   154,    37,    38,    39,
-      40,   143,   114,   115,   157,   117,   118,   147,   120,    85,
-     122,   307,   308,   154,   148,   154,   128,   143,   154,   131,
-     132,   133,   157,   135,   136,   154,   154,   154,   143,   319,
-     154,   143,   144,   329,   110,   111,   143,     0,   334,     0,
-     116,   257,    78,   119,   158,   192,    92,   203,    13,   145,
-     240,   347,   348,   349,   350,   351,     6,     7,   118,    41,
-     261,    11,    12,    13,   331,    25,    16,   311,    -1,    -1,
-     345,    21,    22,   113,    10,    -1,    26,    27,    -1,    -1,
-      30,    17,    32,    33,    20,   125,    36,    -1,     6,   129,
-     130,    -1,    -1,    43,    -1,    -1,    14,    -1,    -1,    -1,
-      -1,    -1,    -1,    53,    -1,    41,    -1,    -1,    58,    59,
-      -1,    -1,    62,    -1,    -1,    65,    66,    -1,    -1,    69,
-      70,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    49,    -1,    -1,    84,    -1,    72,    73,    74,    57,
-      76,    77,    -1,    -1,    80,    -1,    -1,    -1,    -1,    -1,
-     100,    -1,   102,    -1,   104,   105,    -1,    75,    52,    -1,
-      -1,    79,    98,    81,   114,   115,    60,   117,   118,    63,
-     120,    -1,   122,    91,    68,    -1,    -1,    -1,   128,    -1,
-      -1,   131,   132,   133,    -1,   135,   136,    -1,    -1,    -1,
-     108,   109,    -1,    87,   144,    89,    90,    -1,    92,    93,
-      94,    -1,    -1,    97,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,   134,    -1,   136,    -1,
-     138,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,   138
+      36,    31,   129,    43,    29,    47,    48,   143,   117,    39,
+      26,     3,    54,    34,    86,    54,    32,     4,     8,    35,
+      54,    34,    55,    95,   117,     1,   145,   146,   148,    54,
+       6,     7,    24,    54,    95,    11,    12,    13,   158,    54,
+      16,    28,    25,    47,    48,    21,    22,    54,    64,   158,
+      26,    27,   145,   146,    30,    42,    32,    33,     5,    46,
+      36,   126,     9,   126,    47,    48,   126,    43,    15,   109,
+      86,    54,   126,   106,   126,    47,    48,    53,   126,   126,
+      16,   126,    58,    59,   126,    54,    62,    54,    78,    65,
+      66,    83,    82,    69,    70,    31,    88,    37,    38,    39,
+      40,   137,   138,   139,   140,   141,   142,   143,    84,    56,
+      46,   103,    99,   134,   150,   151,   126,   153,   154,     6,
+     133,   137,   126,   126,   100,   143,   102,    14,   104,   105,
+     149,   150,   151,   152,   153,    82,   123,   124,   114,   115,
+     157,   117,   118,   126,   120,   126,   122,   139,   140,    96,
+      54,   126,   128,   126,    54,   131,   132,   133,   126,   135,
+     136,   126,    49,   199,   200,   126,   293,   143,   144,   126,
+      57,   126,    19,   113,   121,   126,    23,   126,    54,    54,
+     210,   154,   155,   156,    29,   125,   122,   123,    75,   129,
+     130,   126,    79,   126,    81,   126,   149,   150,   151,   152,
+     153,    71,   154,    54,    91,   158,   236,   126,     6,     7,
+      54,    54,    54,    11,    12,    13,    54,    54,    16,    54,
+      67,   108,   109,    21,    22,   143,    54,   126,    26,    27,
+     126,    54,    30,    54,    32,    33,    54,    54,    36,   193,
+     194,   195,   196,    54,    54,    43,    54,   134,   154,   136,
+     143,   138,   154,    25,   101,    53,   154,   143,   147,   143,
+      58,    59,   157,   154,    62,   112,   148,    65,    66,   305,
+     306,    69,    70,   154,   157,   154,   154,   154,   143,   143,
+     127,   154,   154,     0,     0,   255,    84,   317,    77,   157,
+      91,   327,   201,   190,    13,   144,   332,   238,   117,    41,
+      25,   259,   100,   309,   102,   329,   104,   105,   343,   345,
+     346,   347,   348,   349,    -1,    -1,   114,   115,    -1,   117,
+     118,    -1,   120,    -1,   122,    -1,    -1,    -1,    -1,    -1,
+     128,    -1,    -1,   131,   132,   133,    -1,   135,   136,    -1,
+      -1,    -1,     6,     7,    -1,   143,   144,    11,    12,    13,
+      -1,    18,    16,    -1,    -1,    -1,    -1,    21,    22,    -1,
+      10,    -1,    26,    27,    -1,    -1,    30,    17,    32,    33,
+      20,    -1,    36,    -1,    52,    -1,    -1,    44,    45,    43,
+      -1,    -1,    60,    50,    51,    63,    -1,    -1,    -1,    53,
+      68,    41,    -1,    -1,    58,    59,    -1,    -1,    62,    -1,
+      -1,    65,    66,    -1,    -1,    69,    70,    -1,    -1,    87,
+      -1,    89,    90,    -1,    92,    93,    94,    -1,    85,    97,
+      84,    -1,    72,    73,    74,    -1,    76,    77,    -1,    -1,
+      80,    -1,    -1,    -1,    -1,    -1,   100,    -1,   102,    -1,
+     104,   105,    -1,   110,   111,    -1,    -1,    -1,    98,   116,
+     114,   115,   119,   117,   118,    -1,   120,    -1,   122,    -1,
+     138,    -1,    -1,    -1,   128,    -1,    -1,   131,   132,   133,
+      -1,   135,   136,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     144
 };
 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
 #line 3 "/usr/local/gnu/share/bison/bison.simple"
@@ -1649,422 +1645,418 @@ case 61:
     break;
 case 62:
 #line 448 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_sval(CRYPTO_CONF_LEAP, yyvsp[0].String); }
+{ yyval.Attr_val = create_attr_sval(CRYPTO_CONF_MVPAR, yyvsp[0].String); }
     break;
 case 63:
 #line 450 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_sval(CRYPTO_CONF_MVPAR, yyvsp[0].String); }
+{ yyval.Attr_val = create_attr_sval(CRYPTO_CONF_PW, yyvsp[0].String); }
     break;
 case 64:
 #line 452 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_sval(CRYPTO_CONF_PW, yyvsp[0].String); }
+{ yyval.Attr_val = create_attr_sval(CRYPTO_CONF_RAND, yyvsp[0].String); }
     break;
 case 65:
 #line 454 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_sval(CRYPTO_CONF_RAND, yyvsp[0].String); }
+{ my_config.auth.revoke = yyvsp[0].Integer;  }
     break;
 case 66:
 #line 456 "ntp_parser.y"
-{ my_config.auth.revoke = yyvsp[0].Integer;  }
+{ yyval.Attr_val = create_attr_sval(CRYPTO_CONF_SIGN, yyvsp[0].String); }
     break;
 case 67:
-#line 458 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_sval(CRYPTO_CONF_SIGN, yyvsp[0].String); }
+#line 466 "ntp_parser.y"
+{ append_queue(my_config.orphan_cmds,yyvsp[0].Queue);  }
     break;
 case 68:
-#line 468 "ntp_parser.y"
-{ append_queue(my_config.orphan_cmds,yyvsp[0].Queue);  }
+#line 470 "ntp_parser.y"
+{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
     break;
 case 69:
-#line 472 "ntp_parser.y"
-{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
+#line 471 "ntp_parser.y"
+{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
     break;
 case 70:
-#line 473 "ntp_parser.y"
-{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
+#line 476 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_dval(PROTO_CEILING, (double)yyvsp[0].Integer); }
     break;
 case 71:
 #line 478 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_CEILING, (double)yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_dval(PROTO_FLOOR, (double)yyvsp[0].Integer); }
     break;
 case 72:
 #line 480 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_FLOOR, (double)yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_dval(PROTO_COHORT, (double)yyvsp[0].Integer); }
     break;
 case 73:
 #line 482 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_COHORT, (double)yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_dval(PROTO_ORPHAN, (double)yyvsp[0].Integer); }
     break;
 case 74:
 #line 484 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_ORPHAN, (double)yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_dval(PROTO_MINDISP, yyvsp[0].Double); }
     break;
 case 75:
 #line 486 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_MINDISP, yyvsp[0].Double); }
+{ yyval.Attr_val = create_attr_dval(PROTO_MAXDIST, yyvsp[0].Double); }
     break;
 case 76:
 #line 488 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_MAXDIST, yyvsp[0].Double); }
+{ yyval.Attr_val = create_attr_dval(PROTO_MINCLOCK, yyvsp[0].Double); }
     break;
 case 77:
 #line 490 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_MINCLOCK, yyvsp[0].Double); }
+{ yyval.Attr_val = create_attr_dval(PROTO_MAXCLOCK, yyvsp[0].Double); }
     break;
 case 78:
 #line 492 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_MAXCLOCK, yyvsp[0].Double); }
+{ yyval.Attr_val = create_attr_dval(PROTO_MINSANE, (double)yyvsp[0].Integer); }
     break;
 case 79:
 #line 494 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_MINSANE, (double)yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_dval(PROTO_BEACON, (double)yyvsp[0].Integer); }
     break;
 case 80:
 #line 496 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_BEACON, (double)yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_dval(PROTO_MAXHOP, (double)yyvsp[0].Integer); }
     break;
 case 81:
-#line 498 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(PROTO_MAXHOP, (double)yyvsp[0].Integer); }
+#line 506 "ntp_parser.y"
+{ append_queue(my_config.stats_list, yyvsp[0].Queue);  }
     break;
 case 82:
 #line 508 "ntp_parser.y"
-{ append_queue(my_config.stats_list, yyvsp[0].Queue);  }
+{ my_config.stats_dir = yyvsp[0].String;  }
     break;
 case 83:
 #line 510 "ntp_parser.y"
-{ my_config.stats_dir = yyvsp[0].String;  }
-    break;
-case 84:
-#line 512 "ntp_parser.y"
 {
                         enqueue(my_config.filegen_opts,
                                 create_filegen_node(yyvsp[-1].VoidPtr, yyvsp[0].Queue));
                     }
     break;
-case 85:
-#line 519 "ntp_parser.y"
+case 84:
+#line 517 "ntp_parser.y"
 { yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].VoidPtr); }
     break;
-case 86:
-#line 520 "ntp_parser.y"
+case 85:
+#line 518 "ntp_parser.y"
 { yyval.Queue = enqueue_in_new_queue(yyvsp[0].VoidPtr); }
     break;
+case 86:
+#line 523 "ntp_parser.y"
+{ yyval.VoidPtr = create_pval("clockstats"); }
+    break;
 case 87:
 #line 525 "ntp_parser.y"
-{ yyval.VoidPtr = create_pval("clockstats"); }
+{ yyval.VoidPtr = create_pval("cryptostats"); }
     break;
 case 88:
 #line 527 "ntp_parser.y"
-{ yyval.VoidPtr = create_pval("cryptostats"); }
+{ yyval.VoidPtr = create_pval("loopstats"); }
     break;
 case 89:
 #line 529 "ntp_parser.y"
-{ yyval.VoidPtr = create_pval("loopstats"); }
+{ yyval.VoidPtr = create_pval("peerstats"); }
     break;
 case 90:
 #line 531 "ntp_parser.y"
-{ yyval.VoidPtr = create_pval("peerstats"); }
+{ yyval.VoidPtr = create_pval("rawstats"); }
     break;
 case 91:
 #line 533 "ntp_parser.y"
-{ yyval.VoidPtr = create_pval("rawstats"); }
+{ yyval.VoidPtr = create_pval("sysstats"); }
     break;
 case 92:
-#line 535 "ntp_parser.y"
-{ yyval.VoidPtr = create_pval("sysstats"); }
+#line 537 "ntp_parser.y"
+{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
     break;
 case 93:
-#line 539 "ntp_parser.y"
-{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
+#line 538 "ntp_parser.y"
+{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
     break;
 case 94:
-#line 540 "ntp_parser.y"
-{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
+#line 542 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_sval(T_File, yyvsp[0].String); }
     break;
 case 95:
-#line 544 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_sval(T_File, yyvsp[0].String); }
+#line 543 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Type, yyvsp[0].Integer); }
     break;
 case 96:
-#line 545 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Type, yyvsp[0].Integer); }
+#line 544 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, T_Link); }
     break;
 case 97:
-#line 546 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, T_Link); }
+#line 545 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, T_Nolink); }
     break;
 case 98:
-#line 547 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, T_Nolink); }
+#line 546 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, T_Enable); }
     break;
 case 99:
-#line 548 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, T_Enable); }
+#line 547 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, T_Disable); }
     break;
 case 100:
-#line 549 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, T_Disable); }
+#line 551 "ntp_parser.y"
+{ yyval.Integer = FILEGEN_NONE; }
     break;
 case 101:
-#line 553 "ntp_parser.y"
-{ yyval.Integer = FILEGEN_NONE; }
+#line 552 "ntp_parser.y"
+{ yyval.Integer = FILEGEN_PID; }
     break;
 case 102:
-#line 554 "ntp_parser.y"
-{ yyval.Integer = FILEGEN_PID; }
+#line 553 "ntp_parser.y"
+{ yyval.Integer = FILEGEN_DAY; }
     break;
 case 103:
-#line 555 "ntp_parser.y"
-{ yyval.Integer = FILEGEN_DAY; }
+#line 554 "ntp_parser.y"
+{ yyval.Integer = FILEGEN_WEEK; }
     break;
 case 104:
-#line 556 "ntp_parser.y"
-{ yyval.Integer = FILEGEN_WEEK; }
+#line 555 "ntp_parser.y"
+{ yyval.Integer = FILEGEN_MONTH; }
     break;
 case 105:
-#line 557 "ntp_parser.y"
-{ yyval.Integer = FILEGEN_MONTH; }
+#line 556 "ntp_parser.y"
+{ yyval.Integer = FILEGEN_YEAR; }
     break;
 case 106:
-#line 558 "ntp_parser.y"
-{ yyval.Integer = FILEGEN_YEAR; }
+#line 557 "ntp_parser.y"
+{ yyval.Integer = FILEGEN_AGE; }
     break;
 case 107:
-#line 559 "ntp_parser.y"
-{ yyval.Integer = FILEGEN_AGE; }
+#line 567 "ntp_parser.y"
+{   append_queue(my_config.discard_opts, yyvsp[0].Queue); }
     break;
 case 108:
 #line 569 "ntp_parser.y"
-{   append_queue(my_config.discard_opts, yyvsp[0].Queue); }
-    break;
-case 109:
-#line 571 "ntp_parser.y"
 {
                         enqueue(my_config.restrict_opts,
                                 create_restrict_node(yyvsp[-1].Address_node, NULL, yyvsp[0].Queue, ip_file->line_no));
                     }
     break;
-case 110:
-#line 576 "ntp_parser.y"
+case 109:
+#line 574 "ntp_parser.y"
 {
                         enqueue(my_config.restrict_opts,
                                 create_restrict_node(NULL, NULL, yyvsp[0].Queue, ip_file->line_no));
                     }
     break;
-case 111:
-#line 581 "ntp_parser.y"
+case 110:
+#line 579 "ntp_parser.y"
 {
                         enqueue(my_config.restrict_opts,
                                 create_restrict_node(yyvsp[-3].Address_node, yyvsp[-1].Address_node, yyvsp[0].Queue, ip_file->line_no));
                     }
     break;
-case 112:
-#line 588 "ntp_parser.y"
+case 111:
+#line 586 "ntp_parser.y"
 { yyval.Queue = create_queue(); }
     break;
-case 113:
-#line 589 "ntp_parser.y"
+case 112:
+#line 587 "ntp_parser.y"
 { yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].VoidPtr); }
     break;
-case 114:
-#line 593 "ntp_parser.y"
+case 113:
+#line 591 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_IGNORE); }
     break;
-case 115:
-#line 594 "ntp_parser.y"
+case 114:
+#line 592 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_DEMOBILIZE); }
     break;
-case 116:
-#line 595 "ntp_parser.y"
+case 115:
+#line 593 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_LIMITED); }
     break;
-case 117:
-#line 596 "ntp_parser.y"
+case 116:
+#line 594 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_LPTRAP); }
     break;
-case 118:
-#line 597 "ntp_parser.y"
+case 117:
+#line 595 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_NOMODIFY); }
     break;
-case 119:
-#line 598 "ntp_parser.y"
+case 118:
+#line 596 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_NOPEER); }
     break;
-case 120:
-#line 599 "ntp_parser.y"
+case 119:
+#line 597 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_NOQUERY); }
     break;
-case 121:
-#line 600 "ntp_parser.y"
+case 120:
+#line 598 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_DONTSERVE); }
     break;
-case 122:
-#line 601 "ntp_parser.y"
+case 121:
+#line 599 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_NOTRAP); }
     break;
-case 123:
-#line 602 "ntp_parser.y"
+case 122:
+#line 600 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_DONTTRUST); }
     break;
-case 124:
-#line 603 "ntp_parser.y"
+case 123:
+#line 601 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RESM_NTPONLY); }
     break;
-case 125:
-#line 604 "ntp_parser.y"
+case 124:
+#line 602 "ntp_parser.y"
 { yyval.VoidPtr = create_ival(RES_VERSION); }
     break;
-case 126:
-#line 608 "ntp_parser.y"
+case 125:
+#line 606 "ntp_parser.y"
 { yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
     break;
-case 127:
-#line 609 "ntp_parser.y"
+case 126:
+#line 607 "ntp_parser.y"
 { yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
     break;
-case 128:
-#line 613 "ntp_parser.y"
+case 127:
+#line 611 "ntp_parser.y"
 { yyval.Attr_val = create_attr_ival(T_Average, yyvsp[0].Integer); }
     break;
-case 129:
-#line 614 "ntp_parser.y"
+case 128:
+#line 612 "ntp_parser.y"
 { yyval.Attr_val = create_attr_ival(T_Minimum, yyvsp[0].Integer); }
     break;
-case 130:
-#line 615 "ntp_parser.y"
+case 129:
+#line 613 "ntp_parser.y"
 { yyval.Attr_val = create_attr_ival(T_Monitor, yyvsp[0].Integer); }
     break;
-case 131:
-#line 624 "ntp_parser.y"
+case 130:
+#line 622 "ntp_parser.y"
 { enqueue(my_config.fudge, create_addr_opts_node(yyvsp[-1].Address_node, yyvsp[0].Queue));  }
     break;
-case 132:
-#line 628 "ntp_parser.y"
+case 131:
+#line 626 "ntp_parser.y"
 { enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
     break;
-case 133:
-#line 629 "ntp_parser.y"
+case 132:
+#line 627 "ntp_parser.y"
 { yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
     break;
+case 133:
+#line 632 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_dval(CLK_HAVETIME1, yyvsp[0].Double); }
+    break;
 case 134:
 #line 634 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(CLK_HAVETIME1, yyvsp[0].Double); }
+{ yyval.Attr_val = create_attr_dval(CLK_HAVETIME2, yyvsp[0].Double); }
     break;
 case 135:
 #line 636 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(CLK_HAVETIME2, yyvsp[0].Double); }
+{ yyval.Attr_val = create_attr_ival(CLK_HAVEVAL1,  yyvsp[0].Integer); }
     break;
 case 136:
 #line 638 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(CLK_HAVEVAL1,  yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_sval(CLK_HAVEVAL2,  yyvsp[0].String); }
     break;
 case 137:
 #line 640 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_sval(CLK_HAVEVAL2,  yyvsp[0].String); }
+{ yyval.Attr_val = create_attr_ival(CLK_HAVEFLAG1, yyvsp[0].Integer); }
     break;
 case 138:
 #line 642 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(CLK_HAVEFLAG1, yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_ival(CLK_HAVEFLAG2, yyvsp[0].Integer); }
     break;
 case 139:
 #line 644 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(CLK_HAVEFLAG2, yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_ival(CLK_HAVEFLAG3, yyvsp[0].Integer); }
     break;
 case 140:
 #line 646 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(CLK_HAVEFLAG3, yyvsp[0].Integer); }
+{ yyval.Attr_val = create_attr_ival(CLK_HAVEFLAG4, yyvsp[0].Integer); }
     break;
 case 141:
-#line 648 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(CLK_HAVEFLAG4, yyvsp[0].Integer); }
+#line 655 "ntp_parser.y"
+{ append_queue(my_config.enable_opts,yyvsp[0].Queue);  }
     break;
 case 142:
 #line 657 "ntp_parser.y"
-{ append_queue(my_config.enable_opts,yyvsp[0].Queue);  }
+{ append_queue(my_config.disable_opts,yyvsp[0].Queue);  }
     break;
 case 143:
-#line 659 "ntp_parser.y"
-{ append_queue(my_config.disable_opts,yyvsp[0].Queue);  }
+#line 661 "ntp_parser.y"
+{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
     break;
 case 144:
-#line 663 "ntp_parser.y"
-{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
+#line 662 "ntp_parser.y"
+{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
     break;
 case 145:
-#line 664 "ntp_parser.y"
-{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
+#line 666 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_AUTHENTICATE); }
     break;
 case 146:
-#line 668 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_AUTHENTICATE); }
+#line 667 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_BROADCLIENT); }
     break;
 case 147:
-#line 669 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_BROADCLIENT); }
+#line 668 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_CAL); }
     break;
 case 148:
-#line 670 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_CAL); }
+#line 669 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_KERNEL); }
     break;
 case 149:
-#line 671 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_KERNEL); }
+#line 670 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_MONITOR); }
     break;
 case 150:
-#line 672 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_MONITOR); }
+#line 671 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_NTP); }
     break;
 case 151:
 #line 673 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Flag, PROTO_NTP); }
-    break;
-case 152:
-#line 675 "ntp_parser.y"
 { yyval.Attr_val = create_attr_ival(T_Flag, PROTO_FILEGEN); }
     break;
-case 153:
-#line 683 "ntp_parser.y"
+case 152:
+#line 681 "ntp_parser.y"
 { append_queue(my_config.tinker, yyvsp[0].Queue);  }
     break;
-case 154:
-#line 687 "ntp_parser.y"
+case 153:
+#line 685 "ntp_parser.y"
 { yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
     break;
-case 155:
-#line 688 "ntp_parser.y"
+case 154:
+#line 686 "ntp_parser.y"
 { yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
     break;
-case 156:
-#line 692 "ntp_parser.y"
+case 155:
+#line 690 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(LOOP_ALLAN, yyvsp[0].Double); }
     break;
-case 157:
-#line 693 "ntp_parser.y"
+case 156:
+#line 691 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(LOOP_PHI, yyvsp[0].Double); }
     break;
-case 158:
-#line 694 "ntp_parser.y"
+case 157:
+#line 692 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(LOOP_FREQ, yyvsp[0].Double); }
     break;
-case 159:
-#line 695 "ntp_parser.y"
+case 158:
+#line 693 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(LOOP_HUFFPUFF, yyvsp[0].Double); }
     break;
-case 160:
-#line 696 "ntp_parser.y"
+case 159:
+#line 694 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(LOOP_PANIC, yyvsp[0].Double); }
     break;
-case 161:
-#line 697 "ntp_parser.y"
+case 160:
+#line 695 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(LOOP_MAX, yyvsp[0].Double); }
     break;
-case 162:
-#line 698 "ntp_parser.y"
+case 161:
+#line 696 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(LOOP_MINSTEP, yyvsp[0].Double); }
     break;
-case 163:
-#line 707 "ntp_parser.y"
+case 162:
+#line 705 "ntp_parser.y"
 {
                     if (curr_include_level >= MAXINCLUDELEVEL) {
                         fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
@@ -2081,117 +2073,117 @@ case 163:
                     }
                 }
     break;
-case 164:
-#line 723 "ntp_parser.y"
+case 163:
+#line 721 "ntp_parser.y"
 {
                     while (curr_include_level != -1)
                         FCLOSE(fp[curr_include_level--]);
                 }
     break;
+case 164:
+#line 727 "ntp_parser.y"
+{ enqueue(my_config.vars, create_attr_dval(T_Broadcastdelay, yyvsp[0].Double));  }
+    break;
 case 165:
 #line 729 "ntp_parser.y"
-{ enqueue(my_config.vars, create_attr_dval(T_Broadcastdelay, yyvsp[0].Double));  }
+{ enqueue(my_config.vars, create_attr_ival(T_Calldelay, yyvsp[0].Integer));  }
     break;
 case 166:
 #line 731 "ntp_parser.y"
-{ enqueue(my_config.vars, create_attr_ival(T_Calldelay, yyvsp[0].Integer));  }
+{ enqueue(my_config.vars, create_attr_dval(T_Tick, yyvsp[0].Double));  }
     break;
 case 167:
 #line 733 "ntp_parser.y"
-{ enqueue(my_config.vars, create_attr_dval(T_Tick, yyvsp[0].Double));  }
+{ /* Null action, possibly all null parms */ }
     break;
 case 168:
 #line 735 "ntp_parser.y"
-{ /* Null action, possibly all null parms */ }
+{ enqueue(my_config.vars, create_attr_sval(T_Leapfile, yyvsp[0].String)); }
     break;
 case 169:
-#line 737 "ntp_parser.y"
-{ enqueue(my_config.vars, create_attr_sval(T_Leapfile, yyvsp[0].String)); }
+#line 738 "ntp_parser.y"
+{ enqueue(my_config.vars, create_attr_sval(T_Pidfile, yyvsp[0].String));  }
     break;
 case 170:
 #line 740 "ntp_parser.y"
-{ enqueue(my_config.vars, create_attr_sval(T_Pidfile, yyvsp[0].String));  }
+{ enqueue(my_config.vars, create_attr_sval(T_Logfile, yyvsp[0].String));  }
     break;
 case 171:
 #line 742 "ntp_parser.y"
-{ enqueue(my_config.vars, create_attr_sval(T_Logfile, yyvsp[0].String));  }
+{ enqueue(my_config.vars, create_attr_ival(T_Automax, yyvsp[0].Integer));  }
     break;
 case 172:
-#line 744 "ntp_parser.y"
-{ enqueue(my_config.vars, create_attr_ival(T_Automax, yyvsp[0].Integer));  }
+#line 745 "ntp_parser.y"
+{ append_queue(my_config.logconfig, yyvsp[0].Queue);  }
     break;
 case 173:
 #line 747 "ntp_parser.y"
-{ append_queue(my_config.logconfig, yyvsp[0].Queue);  }
+{ append_queue(my_config.phone, yyvsp[0].Queue);  }
     break;
 case 174:
 #line 749 "ntp_parser.y"
-{ append_queue(my_config.phone, yyvsp[0].Queue);  }
+{ enqueue(my_config.setvar, yyvsp[0].Set_var);  }
     break;
 case 175:
 #line 751 "ntp_parser.y"
-{ enqueue(my_config.setvar, yyvsp[0].Set_var);  }
+{ enqueue(my_config.trap, create_addr_opts_node(yyvsp[-1].Address_node, yyvsp[0].Queue));  }
     break;
 case 176:
 #line 753 "ntp_parser.y"
-{ enqueue(my_config.trap, create_addr_opts_node(yyvsp[-1].Address_node, yyvsp[0].Queue));  }
+{ append_queue(my_config.ttl, yyvsp[0].Queue); }
     break;
 case 177:
-#line 755 "ntp_parser.y"
-{ append_queue(my_config.ttl, yyvsp[0].Queue); }
+#line 757 "ntp_parser.y"
+{ enqueue(my_config.vars, create_attr_sval(T_Driftfile, yyvsp[0].String)); }
     break;
 case 178:
 #line 759 "ntp_parser.y"
-{ enqueue(my_config.vars, create_attr_sval(T_Driftfile, yyvsp[0].String)); }
-    break;
-case 179:
-#line 761 "ntp_parser.y"
 { enqueue(my_config.vars, create_attr_dval(T_WanderThreshold, yyvsp[0].Double));
                  enqueue(my_config.vars, create_attr_sval(T_Driftfile, yyvsp[-1].String)); }
     break;
-case 180:
-#line 763 "ntp_parser.y"
+case 179:
+#line 761 "ntp_parser.y"
 { /* Null driftfile,  indicated by null string "\0" */
                  enqueue(my_config.vars, create_attr_sval(T_Driftfile, "\0")); }
     break;
+case 180:
+#line 767 "ntp_parser.y"
+{ yyval.Set_var = create_setvar_node(yyvsp[-3].String, yyvsp[-1].String, DEF); }
+    break;
 case 181:
 #line 769 "ntp_parser.y"
-{ yyval.Set_var = create_setvar_node(yyvsp[-3].String, yyvsp[-1].String, DEF); }
+{ yyval.Set_var = create_setvar_node(yyvsp[-2].String, yyvsp[0].String, 0); }
     break;
 case 182:
-#line 771 "ntp_parser.y"
-{ yyval.Set_var = create_setvar_node(yyvsp[-2].String, yyvsp[0].String, 0); }
+#line 774 "ntp_parser.y"
+{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
     break;
 case 183:
-#line 776 "ntp_parser.y"
-{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
+#line 775 "ntp_parser.y"
+{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
     break;
 case 184:
-#line 777 "ntp_parser.y"
-{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
+#line 779 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_ival(T_Port, yyvsp[0].Integer); }
     break;
 case 185:
-#line 781 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_ival(T_Port, yyvsp[0].Integer); }
+#line 780 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_pval(T_Interface, yyvsp[0].Address_node); }
     break;
 case 186:
-#line 782 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_pval(T_Interface, yyvsp[0].Address_node); }
+#line 785 "ntp_parser.y"
+{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
     break;
 case 187:
-#line 787 "ntp_parser.y"
-{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Attr_val); }
+#line 786 "ntp_parser.y"
+{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
     break;
 case 188:
-#line 788 "ntp_parser.y"
-{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Attr_val); }
+#line 790 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_sval(yyvsp[-1].Integer, yyvsp[0].String); }
     break;
 case 189:
 #line 792 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_sval(yyvsp[-1].Integer, yyvsp[0].String); }
-    break;
-case 190:
-#line 794 "ntp_parser.y"
 {
                     /* YUCK!! This is needed because '+' and '-' are not special characters
                      * while '=' is.
@@ -2206,44 +2198,44 @@ case 190:
                         yyval.Attr_val = create_attr_sval(prefix, type);
                 }
     break;
-case 191:
-#line 810 "ntp_parser.y"
+case 190:
+#line 808 "ntp_parser.y"
 { yyval.Integer = '+'; }
     break;
-case 192:
-#line 811 "ntp_parser.y"
+case 191:
+#line 809 "ntp_parser.y"
 { yyval.Integer = '-'; }
     break;
-case 193:
-#line 812 "ntp_parser.y"
+case 192:
+#line 810 "ntp_parser.y"
 { yyval.Integer = '='; }
     break;
-case 194:
-#line 821 "ntp_parser.y"
+case 193:
+#line 819 "ntp_parser.y"
 { yyval.Queue = enqueue(yyvsp[-1].Queue, create_ival(yyvsp[0].Integer)); }
     break;
-case 195:
-#line 822 "ntp_parser.y"
+case 194:
+#line 820 "ntp_parser.y"
 { yyval.Queue = enqueue_in_new_queue(create_ival(yyvsp[0].Integer)); }
     break;
-case 196:
-#line 826 "ntp_parser.y"
+case 195:
+#line 824 "ntp_parser.y"
 { yyval.Queue = enqueue(yyvsp[-1].Queue, create_pval(yyvsp[0].String)); }
     break;
-case 197:
-#line 827 "ntp_parser.y"
+case 196:
+#line 825 "ntp_parser.y"
 { yyval.Queue = enqueue_in_new_queue(create_pval(yyvsp[0].String)); }
     break;
-case 198:
-#line 831 "ntp_parser.y"
+case 197:
+#line 829 "ntp_parser.y"
 { yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Address_node); }
     break;
-case 199:
-#line 832 "ntp_parser.y"
+case 198:
+#line 830 "ntp_parser.y"
 { yyval.Queue = enqueue_in_new_queue(yyvsp[0].Address_node); }
     break;
-case 200:
-#line 837 "ntp_parser.y"
+case 199:
+#line 835 "ntp_parser.y"
 {
                     if (yyvsp[0].Integer != 0 && yyvsp[0].Integer != 1) {
                         yyerror("Integer value is not boolean (0 or 1). Assuming 1");
@@ -2253,24 +2245,24 @@ case 200:
                         yyval.Integer = yyvsp[0].Integer;
                 }
     break;
-case 201:
-#line 845 "ntp_parser.y"
+case 200:
+#line 843 "ntp_parser.y"
 { yyval.Integer = 1; }
     break;
-case 202:
-#line 846 "ntp_parser.y"
+case 201:
+#line 844 "ntp_parser.y"
 { yyval.Integer = 0; }
     break;
-case 203:
-#line 850 "ntp_parser.y"
+case 202:
+#line 848 "ntp_parser.y"
 { yyval.Double = (double)yyvsp[0].Integer; }
     break;
-case 204:
-#line 851 "ntp_parser.y"
+case 203:
+#line 849 "ntp_parser.y"
 { yyval.Double = yyvsp[0].Double; }
     break;
-case 205:
-#line 860 "ntp_parser.y"
+case 204:
+#line 858 "ntp_parser.y"
 {
                  my_config.sim_details = create_sim_node(yyvsp[-2].Queue, yyvsp[-1].Queue);
 
@@ -2278,92 +2270,92 @@ case 205:
                  old_config_style = 1;
              }
     break;
-case 206:
-#line 874 "ntp_parser.y"
+case 205:
+#line 872 "ntp_parser.y"
 { old_config_style = 0; }
     break;
-case 207:
-#line 878 "ntp_parser.y"
+case 206:
+#line 876 "ntp_parser.y"
 { yyval.Queue = enqueue(yyvsp[-2].Queue, yyvsp[-1].Attr_val); }
     break;
-case 208:
-#line 879 "ntp_parser.y"
+case 207:
+#line 877 "ntp_parser.y"
 { yyval.Queue = enqueue_in_new_queue(yyvsp[-1].Attr_val); }
     break;
-case 209:
-#line 883 "ntp_parser.y"
+case 208:
+#line 881 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(T_Beep_Delay, yyvsp[0].Double); }
     break;
-case 210:
-#line 884 "ntp_parser.y"
+case 209:
+#line 882 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(T_Sim_Duration, yyvsp[0].Double); }
     break;
-case 211:
-#line 888 "ntp_parser.y"
+case 210:
+#line 886 "ntp_parser.y"
 { yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Sim_server); }
     break;
-case 212:
-#line 889 "ntp_parser.y"
+case 211:
+#line 887 "ntp_parser.y"
 { yyval.Queue = enqueue_in_new_queue(yyvsp[0].Sim_server); }
     break;
-case 213:
-#line 894 "ntp_parser.y"
+case 212:
+#line 892 "ntp_parser.y"
 { yyval.Sim_server = create_sim_server(yyvsp[-4].Address_node, yyvsp[-2].Double, yyvsp[-1].Queue); }
     break;
-case 214:
-#line 898 "ntp_parser.y"
+case 213:
+#line 896 "ntp_parser.y"
 { yyval.Double = yyvsp[-1].Double; }
     break;
+case 214:
+#line 900 "ntp_parser.y"
+{ yyval.Address_node = yyvsp[0].Address_node; }
+    break;
 case 215:
-#line 902 "ntp_parser.y"
+#line 904 "ntp_parser.y"
 { yyval.Address_node = yyvsp[0].Address_node; }
     break;
 case 216:
-#line 906 "ntp_parser.y"
-{ yyval.Address_node = yyvsp[0].Address_node; }
+#line 905 "ntp_parser.y"
+{ yyval.Address_node = create_address_node(yyvsp[0].String, T_String); }
     break;
 case 217:
-#line 907 "ntp_parser.y"
-{ yyval.Address_node = create_address_node(yyvsp[0].String, T_String); }
+#line 909 "ntp_parser.y"
+{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Sim_script); }
     break;
 case 218:
-#line 911 "ntp_parser.y"
-{ yyval.Queue = enqueue(yyvsp[-1].Queue, yyvsp[0].Sim_script); }
+#line 910 "ntp_parser.y"
+{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Sim_script); }
     break;
 case 219:
-#line 912 "ntp_parser.y"
-{ yyval.Queue = enqueue_in_new_queue(yyvsp[0].Sim_script); }
+#line 915 "ntp_parser.y"
+{ yyval.Sim_script = create_sim_script_info(yyvsp[-3].Double, yyvsp[-1].Queue); }
     break;
 case 220:
-#line 917 "ntp_parser.y"
-{ yyval.Sim_script = create_sim_script_info(yyvsp[-3].Double, yyvsp[-1].Queue); }
+#line 919 "ntp_parser.y"
+{ yyval.Queue = enqueue(yyvsp[-2].Queue, yyvsp[-1].Attr_val); }
     break;
 case 221:
-#line 921 "ntp_parser.y"
-{ yyval.Queue = enqueue(yyvsp[-2].Queue, yyvsp[-1].Attr_val); }
+#line 920 "ntp_parser.y"
+{ yyval.Queue = enqueue_in_new_queue(yyvsp[-1].Attr_val); }
     break;
 case 222:
-#line 922 "ntp_parser.y"
-{ yyval.Queue = enqueue_in_new_queue(yyvsp[-1].Attr_val); }
+#line 925 "ntp_parser.y"
+{ yyval.Attr_val = create_attr_dval(T_Freq_Offset, yyvsp[0].Double); }
     break;
 case 223:
 #line 927 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(T_Freq_Offset, yyvsp[0].Double); }
+{ yyval.Attr_val = create_attr_dval(T_Wander, yyvsp[0].Double); }
     break;
 case 224:
 #line 929 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(T_Wander, yyvsp[0].Double); }
+{ yyval.Attr_val = create_attr_dval(T_Jitter, yyvsp[0].Double); }
     break;
 case 225:
 #line 931 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(T_Jitter, yyvsp[0].Double); }
+{ yyval.Attr_val = create_attr_dval(T_Prop_Delay, yyvsp[0].Double); }
     break;
 case 226:
 #line 933 "ntp_parser.y"
-{ yyval.Attr_val = create_attr_dval(T_Prop_Delay, yyvsp[0].Double); }
-    break;
-case 227:
-#line 935 "ntp_parser.y"
 { yyval.Attr_val = create_attr_dval(T_Proc_Delay, yyvsp[0].Double); }
     break;
 }
@@ -2599,7 +2591,7 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 939 "ntp_parser.y"
+#line 937 "ntp_parser.y"
 
 
 /* KEYWORDS
index 50142b72c3f8a6f2b83bab3c46c60801c5b354a1..e839415ab575b53a850dd545798f0b5e69aef984 100644 (file)
@@ -444,8 +444,6 @@ crypto_command
                     { $$ = create_attr_sval(CRYPTO_CONF_IDENT, $2); }
        |       T_Iffpar T_String
                     { $$ = create_attr_sval(CRYPTO_CONF_IFFPAR, $2); }
-       |       T_Leap T_String
-                    { $$ = create_attr_sval(CRYPTO_CONF_LEAP, $2); }
        |       T_Mvpar T_String
                     { $$ = create_attr_sval(CRYPTO_CONF_MVPAR, $2); }
        |       T_Pw T_String
index 6648062905168045737ee5a7533a4b4c383a980b..141f399973d5e41b88a23ac3557795bb063c0247 100644 (file)
@@ -879,8 +879,11 @@ receive(
         */
        case AM_NEWPASS:
                if (!AUTH(sys_authenticate | (restrict_mask &
-                   (RES_NOPEER | RES_DONTTRUST)), is_authentic))
+                   (RES_NOPEER | RES_DONTTRUST)), is_authentic)) {
+                       fast_xmit(rbufp, MODE_PASSIVE, 0,
+                           restrict_mask);
                        return;                 /* bad auth */
+               }
 
                /*
                 * Do not respond if unsynchronized or stratum is below
@@ -1446,6 +1449,19 @@ clock_update(
                        report_event(EVNT_SYNCCHG, NULL);
                }
                sys_stratum = min(peer->stratum + 1, STRATUM_UNSPEC);
+
+               /*
+                * In orphan mode the stratum is clamped to the orphan
+                * stratum and the root delay is set to a random value
+                * generated at startup. Otherwise, the root delay is
+                * set to the peer delay plus the peer root delay.
+                */
+               if (sys_stratum >= sys_orphan) {
+                       sys_stratum = sys_orphan;
+                       sys_rootdelay = sys_orphandelay;
+               } else {
+                       sys_rootdelay = peer->delay + peer->rootdelay;
+               }
                sys_reftime = peer->rec;
 
                /*
@@ -1509,20 +1525,6 @@ clock_update(
 #endif /* KERNEL_PLL */
                        }
                }
-
-               /*
-                * In orphan mode the stratum defaults to the orphan
-                * stratum. The root delay is set to a random value
-                * generated at startup. The root dispersion is set from
-                * the peer dispersion; the peer root dispersion is
-                * ignored.
-                */
-               if (sys_stratum >= sys_orphan) {
-                       sys_stratum = sys_orphan;
-                       sys_rootdelay = sys_orphandelay;
-               } else {
-                       sys_rootdelay = peer->delay + peer->rootdelay;
-               }
                break;
        /*
         * Popcorn spike or step threshold exceeded. Pretend it never
@@ -1671,11 +1673,6 @@ peer_clear(
        if (peer == sys_peer)
                sys_peer = NULL;
 
-       /*
-        * Wipe the association clean and initialize the nonzero values.
-        */
-       memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO);
-
 #ifdef OPENSSL
        /*
         * If cryptographic credentials have been acquired, toss them to
@@ -1686,37 +1683,27 @@ peer_clear(
         * purged, too. This makes it much harder to sneak in some
         * unauthenticated data in the clock filter.
         */
-       if (peer->pkey != NULL)
-               EVP_PKEY_free(peer->pkey);
-       peer->pkey = NULL;
-       peer->digest = NULL;            /* digest * is a constant */
-       if (peer->subject != NULL)
-               free(peer->subject);
-       peer->subject = NULL;
-       if (peer->issuer != NULL)
-               free(peer->issuer);
-       peer->issuer = NULL;
-       peer->pkeyid = 0;
-       peer->pcookie = 0;
-       if (peer->ident_pkey != NULL)
-               EVP_PKEY_free(peer->ident_pkey);
-       peer->ident_pkey = NULL;
-       memset(&peer->fstamp, 0, sizeof(peer->fstamp));
+       key_expire(peer);
        if (peer->iffval != NULL)
                BN_free(peer->iffval);
-       peer->iffval = NULL;
        if (peer->grpkey != NULL)
                BN_free(peer->grpkey);
-       peer->grpkey = NULL;
        value_free(&peer->cookval);
        value_free(&peer->recval);
-       if (peer->cmmd != NULL) {
-               free(peer->cmmd);
-               peer->cmmd = NULL;
-       }
-       key_expire(peer);
        value_free(&peer->encrypt);
+       value_free(&peer->sndval);
+       if (peer->cmmd != NULL)
+               free(peer->cmmd);
+       if (peer->subject != NULL)
+               free(peer->subject);
+       if (peer->issuer != NULL)
+               free(peer->issuer);
 #endif /* OPENSSL */
+
+       /*
+        * Clear all values, including the optional crypto values above.
+        */
+       memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO);
        peer->estbdelay = sys_bdelay;
        peer->ppoll = peer->maxpoll;
        peer->hpoll = peer->minpoll;
index 51fb3927a9e8dfe52631ef7abd74e4384da2989c..9ce79e23f128392bb85be3821d11c19e0a002d0b 100644 (file)
@@ -16,6 +16,7 @@
 #include "ntp_io.h"
 #include "ntp_select.h"
 #include "ntp_stdlib.h"
+#include "ntp_assert.h"
 /* Don't include ISC's version of IPv6 variables and structures */
 #define ISC_IPV6_H 1
 #include "isc/net.h"
@@ -604,6 +605,7 @@ ntpqmain(
                exit(2);
        }
 #endif
+       NTP_INSIST(ntp_optind <= argc);
        if (ntp_optind == argc) {
                ADDHOST(DEFHOST);
        } else {
index 531ba1843574c50d141d774fcf159d49ee80123e..e7321d583c86833f0577fca65bf09ee1171f3146 100644 (file)
@@ -95,6 +95,8 @@ flag = {
     name      = issuer-name;
     value     = i;
     ifdef     = OPENSSL;
+    arg-type  = string;
+    arg-name  = issuer-name;
     descrip   = "set issuer name";
     doc = <<-  _EndOfDoc_
        Set the suject name to name.  This is used as the subject field
index 82a4bb68f3b1bfda0d591c99baab687c6b4916c7..48a7af2f976cf387bdc7143334234bac8c525ae0 100644 (file)
@@ -31,7 +31,8 @@
  *     but not data encryption
  *
  * ntpkey_IFFpar_<hostname>.<filestamp>
- * ntpkey_iff_<hostname> (IFF server/client) link
+ * ntpkey_iff_<hostname> (IFF server) link
+ * ntpkey_IFFkey_<hostname>.<filestamp>
  * ntpkey_iffkey_<hostname> (IFF client) link
  *     Schnorr (IFF) server/client identity parameters
  *
@@ -154,6 +155,7 @@ EVP_PKEY *gen_mv    (char *);
 int    x509            (EVP_PKEY *, const EVP_MD *, char *, char *);
 void   cb              (int, int, void *);
 EVP_PKEY *genkey       (char *, char *);
+EVP_PKEY *readkey      (char *, char *, u_int *);
 u_long asn2ntp         (ASN1_TIME *);
 #endif /* OPENSSL */
 
@@ -163,14 +165,14 @@ u_long    asn2ntp         (ASN1_TIME *);
 extern char *optarg;           /* command line argument */
 char   *progname;
 int    debug = 0;              /* debug, not de bug */
-int    rval;                   /* return status */
 #ifdef OPENSSL
 u_int  modulus = PLEN;         /* prime modulus size (bits) */
 #endif
 int    nkeys = 0;              /* MV keys */
 time_t epoch;                  /* Unix epoch (seconds) since 1970 */
-char   *hostname;              /* host name (subject name) */
-char   *trustname;             /* trusted host name (issuer name) */
+u_int  fstamp;                 /* NTP filestamp */
+char   *hostname = NULL;       /* host name (subject name) */
+char   *trustname = NULL;      /* trusted host name (issuer name) */
 char   filename[MAXFILENAME + 1]; /* file name */
 char   *passwd1 = NULL;        /* input private key password */
 char   *passwd2 = NULL;        /* output private key password */
@@ -281,7 +283,6 @@ main(
        gethostname(hostbuf, MAXHOSTNAME);
        hostname = hostbuf;
 #ifdef OPENSSL
-       trustname = hostbuf;
        passwd1 = hostbuf;
 #endif
 #ifndef SYS_WINNT
@@ -290,7 +291,6 @@ main(
        gettimeofday(&tv);
 #endif
        epoch = tv.tv_sec;
-       rval = 0;
 
        {
                int optct = optionProcess(&ntp_keygenOptions, argc, argv);
@@ -356,8 +356,9 @@ main(
                mvkey++;
                nkeys = OPT_VALUE_MV_KEYS;
        }
+       if (trustname == NULL)
+               trustname = hostname;
 #endif
-
        if (passwd1 != NULL && passwd2 == NULL)
                passwd2 = passwd1;
 #ifdef OPENSSL
@@ -389,215 +390,153 @@ main(
        if (md5key)
                gen_md5("MD5");
 #ifdef OPENSSL
-       if (hostkey)
-               pkey_host = genkey("RSA", "host");
-       if (sign != NULL)
-               pkey_sign = genkey(sign, "sign");
-       if (iffkey)
-               pkey_iff = gen_iff("iff");
-       if (gqpar)
-               pkey_gq = gen_gqpar("gq");
-       if (mvpar)
-               pkey_mv = gen_mv("mv");
-
        /*
-        * If there is no new host key, look for an existing one. If not
-        * found, create it.
+        * Create new host keys if requested; otherwise, look for
+        * existing host keys. If not found, create a new host RSA
+        * public/private key pair.
         */
-       while (pkey_host == NULL && rval == 0 && !HAVE_OPT(ID_KEY)) {
+       if (hostkey)
+               pkey_host = genkey("RSA", "host");
+       if (pkey_host == NULL) {
                sprintf(filename, "ntpkey_host_%s", hostname);
-               if ((fstr = fopen(filename, "r")) != NULL) {
-                       pkey_host = PEM_read_PrivateKey(fstr, NULL,
-                           NULL, passwd1);
-                       fclose(fstr);
-                       readlink(filename, filename,  sizeof(filename));
+               pkey_host = readkey(filename, passwd1, &fstamp);
+               if (pkey_host == NULL) {
+                       pkey_host = genkey("RSA", "host");
                        if (pkey_host == NULL) {
-                               fprintf(stderr, "Host key\n%s\n",
-                                   ERR_error_string(ERR_get_error(),
-                                   NULL));
-                               rval = -1;
-                       } else {
-                               fprintf(stderr,
-                                   "Using host key %s\n", filename);
+                               fprintf(stderr, "No host key %s\n",
+                                   filename);
+                               return (-1);
                        }
-                       break;
-
-               } else if ((pkey_host = genkey("RSA", "host")) ==
-                   NULL) {
-                       rval = -1;
-                       break;
+               } else {
+                       readlink(filename, filename, sizeof(filename));
+                       fprintf(stderr, "Using host key %s\n",
+                           filename);
                }
        }
 
        /*
-        * If there is no new sign key, look for an existing one. If not
-        * found, use the host key instead.
+        * Create new sign keys if requested; otherwise, look for
+        * existing sign keys. If not found, use the host keys instead.
+        * Either RSA or DSA keys can be selected by option.
         */
-       pkey = pkey_sign;
-       while (pkey_sign == NULL && rval == 0 && !HAVE_OPT(ID_KEY)) {
+       if (sign != NULL)
+               pkey_sign = genkey(sign, "sign");
+       if (pkey_sign == NULL) {
                sprintf(filename, "ntpkey_sign_%s", hostname);
-               if ((fstr = fopen(filename, "r")) != NULL) {
-                       pkey_sign = PEM_read_PrivateKey(fstr, NULL,
-                           NULL, passwd1);
-                       fclose(fstr);
-                       readlink(filename, filename, sizeof(filename));
-                       if (pkey_sign == NULL) {
-                               fprintf(stderr, "Sign key\n%s\n",
-                                   ERR_error_string(ERR_get_error(),
-                                   NULL));
-                               rval = -1;
-                       } else {
-                               fprintf(stderr, "Using sign key %s\n",
-                                   filename);
-                       }
-                       break;
-               } else {
-                       pkey = pkey_host;
+               pkey_sign = readkey(filename, passwd1, &fstamp);
+               if (pkey_sign == NULL) {
+                       pkey_sign = pkey_host;
                        fprintf(stderr, "Using host key as sign key\n");
-                       break;
+               } else {
+                       readlink(filename, filename, sizeof(filename));
+                       fprintf(stderr, "Using sign key %s\n",
+                           filename);
                }
        }
 
        /*
-        * If there is no new IFF file, look for an existing one.
+        * Create new GQ parameters if requested; otherwise, look for
+        * existing GQ parameters.
         */
-       if (pkey_iff == NULL && rval == 0) {
-               sprintf(filename, "ntpkey_iff_%s", hostname);
-               if ((fstr = fopen(filename, "r")) != NULL) {
-                       pkey_iff = PEM_read_PrivateKey(fstr, NULL,
-                           NULL, passwd1);
-                       fclose(fstr);
+       if (gqpar)
+               pkey_gq = gen_gqpar("gq");
+       if (pkey_gq == NULL) {
+               sprintf(filename, "ntpkey_gq_%s", trustname);
+               pkey_gq = readkey(filename, passwd1, &fstamp);
+               if (pkey_gq != NULL) {
                        readlink(filename, filename, sizeof(filename));
-                       if (pkey_iff == NULL) {
-                               fprintf(stderr, "IFF parameters\n%s\n",
-                                   ERR_error_string(ERR_get_error(),
-                                   NULL));
-                               rval = -1;
-                       } else {
-                               fprintf(stderr,
-                                   "Using IFF parameters %s\n",
-                                   filename);
-                       }
+                       fprintf(stderr, "Using GQ parameters %s\n",
+                           filename);
                }
        }
 
        /*
-        * If there is no new GQ file, look for an existing one.
+        * If GQ parameters are available, extract the public key for
+        * the certificate.
         */
-       if (pkey_gq == NULL && rval == 0 && !HAVE_OPT(ID_KEY)) {
-               sprintf(filename, "ntpkey_gq_%s", hostname);
-               if ((fstr = fopen(filename, "r")) != NULL) {
-                       pkey_gq = PEM_read_PrivateKey(fstr, NULL, NULL,
-                           passwd1);
-                       fclose(fstr);
+       if (pkey_gq != NULL)
+               grpkey = BN_bn2hex(pkey_gq->pkey.rsa->q);
+
+       /*
+        * Create new MB parameters if requested. Not clear what to do
+        * with MV for now.
+        */
+       if (mvpar)
+               pkey_mv = gen_mv("mv");
+
+       /*
+        * Create new IFF server parameters if requested; otherwise,
+        * look for existing IFF server parameters.
+        */
+       if (iffkey)
+               pkey_iff = gen_iff("iff");
+       if (pkey_iff == NULL) {
+               sprintf(filename, "ntpkey_iff_%s", trustname);
+               pkey_iff = readkey(filename, passwd1, &fstamp);
+               if (pkey_iff != NULL) {
                        readlink(filename, filename, sizeof(filename));
-                       if (pkey_gq == NULL) {
-                               fprintf(stderr, "GQ parameters\n%s\n",
-                                   ERR_error_string(ERR_get_error(),
-                                   NULL));
-                               rval = -1;
-                       } else {
-                               fprintf(stderr,
-                                   "Using GQ parameters %s\n",
-                                   filename);
-                       }
+                       fprintf(stderr, "Using IFF parameters %s\n",
+                           filename);
                }
        }
 
        /*
-        * If there is a GQ parameter file, create GQ private/public
-        * keys and extract the public key for the certificate.
+        * Create new IFF client parameters if requested. Use the public
+        * keys and filestamp of the IFF server parameters.
         */
-       if (pkey_gq != NULL && rval == 0) {
-               gen_gqkey("gq", pkey_gq);
-               grpkey = BN_bn2hex(pkey_gq->pkey.rsa->q);
+       if (pkey_iff != NULL && HAVE_OPT(ID_KEY)) {
+               DSA     *dsa;
+               FILE    *str;
+
+               fprintf(stderr,
+                   "Generating IFF client parameters (%d bits)...\n",
+                   modulus);
+               epoch = fstamp - JAN_1970;
+               str = fheader("IFFkey", trustname);
+               dsa = pkey_iff->pkey.dsa;
+               BN_copy(dsa->priv_key, BN_value_one());
+               pkey = EVP_PKEY_new();
+               EVP_PKEY_assign_DSA(pkey, dsa);
+               PEM_write_PrivateKey(str, pkey, passwd2 ?
+                   EVP_des_cbc()  : NULL, NULL, 0, NULL, passwd2);
+               fclose(str);
+               if (debug)
+                       DSA_print_fp(stdout, dsa, 0);
+               fslink("iffkey", trustname);
+               return (0);
        }
 
        /*
         * Generate a X509v3 certificate.
         */
-       while (scheme == NULL && rval == 0 && !HAVE_OPT(ID_KEY)) {
+       if (scheme == NULL) {
+               scheme = "RSA-MD5";
                sprintf(filename, "ntpkey_cert_%s", hostname);
                if ((fstr = fopen(filename, "r")) != NULL) {
                        cert = PEM_read_X509(fstr, NULL, NULL, NULL);
                        fclose(fstr);
                        readlink(filename, filename, sizeof(filename));
-                       if (cert == NULL) {
-                               fprintf(stderr, "Cert \n%s\n",
-                                   ERR_error_string(ERR_get_error(),
-                                   NULL));
-                               rval = -1;
-                       } else {
+                       if (cert != NULL) {
                                nid = OBJ_obj2nid(
                                 cert->cert_info->signature->algorithm);
                                scheme = OBJ_nid2sn(nid);
                                fprintf(stderr,
                                    "Using scheme %s from %s\n", scheme,
                                     filename);
-                               break;
                        }
                }
-               scheme = "RSA-MD5";
-       }
-       if (pkey != NULL && rval == 0 && !HAVE_OPT(ID_KEY)) {
-               ectx = EVP_get_digestbyname(scheme);
-               if (ectx == NULL) {
-                       fprintf(stderr,
-                           "Invalid digest/signature combination %s\n",
-                           scheme);
-                       rval = -1;
-               } else {
-                       x509(pkey, ectx, grpkey, exten);
-               }
        }
-
-       /*
-        * Write the IFF client parameters and keys as a DSA private key
-        * encoded in PEM. Note the private key is obscured.
-        */
-       if (pkey_iff != NULL && rval == 0 && HAVE_OPT(ID_KEY)) {
-               DSA     *dsa;
-               char    *sptr;
-               char    *tld;
-
-               sptr = strrchr(filename, '.');
-               tld = emalloc(strlen(sptr));    /* we have an extra byte ... */
-               strcpy(tld, 1+sptr);            /* ... see? */
-               sprintf(filename, "ntpkey_IFFkey_%s.%s", trustname,
-                   tld);
-               free(tld);
-               fprintf(stderr, "Writing new IFF key %s\n", filename);
-               fprintf(stdout, "# %s\n# %s", filename, ctime(&epoch));
-               dsa = pkey_iff->pkey.dsa;
-               NTP_INSIST(dsa != NULL);
-               BN_copy(dsa->priv_key, BN_value_one());
-               pkey = EVP_PKEY_new();
-               NTP_INSIST(pkey != NULL);
-               EVP_PKEY_assign_DSA(pkey, dsa);
-               PEM_write_PrivateKey(stdout, pkey, passwd2 ?
-                   EVP_des_cbc() : NULL, NULL, 0, NULL, passwd2);
-               fclose(stdout);
-               if (debug)
-                       DSA_print_fp(stdout, dsa, 0);
+       ectx = EVP_get_digestbyname(scheme);
+       if (ectx == NULL) {
+               fprintf(stderr,
+                   "Invalid digest/signature combination %s\n",
+                   scheme);
+                       return (-1);
+       } else {
+               x509(pkey_sign, ectx, grpkey, exten);
        }
-
-       /*
-        * Return the marbles.
-        */
-       if (grpkey != NULL)
-               OPENSSL_free(grpkey);
-       if (pkey_host != NULL)
-               EVP_PKEY_free(pkey_host);
-       if (pkey_sign != NULL)
-               EVP_PKEY_free(pkey_sign);
-       if (pkey_iff != NULL)
-               EVP_PKEY_free(pkey_iff);
-       if (pkey_gq != NULL)
-               EVP_PKEY_free(pkey_gq);
-       if (pkey_mv != NULL)
-               EVP_PKEY_free(pkey_mv);
 #endif /* OPENSSL */
-       return (rval);
+       return (0);
 }
 
 
@@ -616,7 +555,7 @@ gen_md5(
        u_char  bin[16];
 
        fprintf(stderr, "Generating MD5 keys...\n");
-       str = fheader("MD5key", hostname);
+       str = fheader("MD5key", trustname);
        keyid = BN_new(); key = BN_new();
        NTP_INSIST(keyid != NULL);
        NTP_INSIST(key != NULL);
@@ -625,7 +564,7 @@ gen_md5(
        BN_bn2bin(key, bin);
        PEM_write_fp(str, MD5, NULL, bin);
        fclose(str);
-       fslink(id, hostname);
+       fslink(id, trustname);
        return (1);
 }
 
@@ -641,11 +580,11 @@ gen_md5(
 {
        u_char  md5key[16];     /* MD5 key */
        FILE    *str;
-       u_int   temp = 0;       /* Initialize to prevent warnings during compile */
+       u_int   temp = 0;       /* prevent warnings during compile */
        int     i, j;
 
        fprintf(stderr, "Generating MD5 keys...\n");
-       str = fheader("MD5key", hostname);
+       str = fheader("MD5key", trustname);
        ntp_srandom(epoch);
        for (i = 1; i <= MD5KEYS; i++) {
                for (j = 0; j < 16; j++) {
@@ -663,13 +602,80 @@ gen_md5(
                    md5key);
        }
        fclose(str);
-       fslink(id, hostname);
+       fslink(id, trustname);
        return (1);
 }
-#endif /* OPENSSL */
-
+#endif /* 0 */
 
 #ifdef OPENSSL
+/*
+ * readkey - load cryptographic parameters and keys
+ *
+ * This routine loads a PEM-encoded file of given name and password and
+ * extracts the filestamp from the file name. It returns the key pointer
+ * if valid, NULL if not.
+ */
+EVP_PKEY *                     /* public/private key pair */
+readkey(
+       char    *cp,            /* file name */
+       char    *passwd,        /* password */
+       u_int   *estamp         /* file stamp */
+       )
+{
+       FILE    *str;           /* file handle */
+       EVP_PKEY *pkey = NULL;  /* public/private key */
+       u_int   gstamp;         /* filestamp */
+       char    linkname[MAXFILENAME]; /* filestamp buffer) */
+       char    *ptr;
+
+       /*
+        * Open the key file.
+        */
+       str = fopen(cp, "r");
+       if (str == NULL)
+               return (NULL);
+
+       /*
+        * Read the filestamp, which is contained in the first line.
+        */
+       if ((ptr = fgets(linkname, MAXFILENAME, str)) == NULL) {
+               fprintf(stderr, "readkey: empty file %s", cp);
+               fclose(str);
+               return (NULL);
+       }
+       if ((ptr = strrchr(ptr, '.')) == NULL) {
+               fprintf(stderr, "readkey: no filestamp %s", cp);
+               fclose(str);
+               return (NULL);
+       }
+       if (sscanf(++ptr, "%u", &gstamp) != 1) {
+               fprintf(stderr, "readkey: invalid filestamp %s", cp);
+               fclose(str);
+               return (NULL);
+       }
+
+       /*
+        * Read and decrypt PEM-encoded private key.
+        */
+       pkey = PEM_read_PrivateKey(str, NULL, NULL, passwd);
+       fclose(str);
+       if (pkey == NULL) {
+               fprintf(stderr, "readkey: %s",
+                   ERR_error_string(ERR_get_error(), NULL));
+               fclose(str);
+               return (NULL);
+       }
+       *estamp = gstamp;
+       if (debug) {
+               if (pkey->type == EVP_PKEY_DSA)
+                       DSA_print_fp(stderr, pkey->pkey.dsa, 0);
+               else if (pkey->type == EVP_PKEY_RSA)
+                       RSA_print_fp(stderr, pkey->pkey.rsa, 0);
+       }
+       return (pkey);
+}
+
+
 /*
  * Generate RSA public/private key pair
  */
@@ -688,7 +694,6 @@ gen_rsa(
        if (rsa == NULL) {
                fprintf(stderr, "RSA generate keys fails\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
-               rval = -1;
                return (NULL);
        }
 
@@ -702,7 +707,6 @@ gen_rsa(
                fprintf(stderr, "Invalid RSA key\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
                RSA_free(rsa);
-               rval = -1;
                return (NULL);
        }
 
@@ -749,7 +753,6 @@ gen_dsa(
        if (dsa == NULL) {
                fprintf(stderr, "DSA generate parameters fails\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
-               rval = -1;
                return (NULL);
        }
 
@@ -761,7 +764,6 @@ gen_dsa(
                fprintf(stderr, "DSA generate keys fails\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
                DSA_free(dsa);
-               rval = -1;
                return (NULL);
        }
 
@@ -832,7 +834,6 @@ gen_iff(
        if (dsa == NULL) {
                fprintf(stderr, "DSA generate parameters fails\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
-               rval = -1;
                return (NULL);;
        }
 
@@ -840,7 +841,6 @@ gen_iff(
         * Generate the private and public keys. The DSA parameters and
         * these keys are distributed to all members of the group.
         */
-       fprintf(stderr, "Generating IFF keys (%d bits)...\n", modulus);
        b = BN_new(); r = BN_new(); k = BN_new();
        NTP_INSIST(b != NULL);
        NTP_INSIST(r != NULL);
@@ -856,6 +856,7 @@ gen_iff(
        BN_mod_exp(v, dsa->g, v, dsa->p, ctx); /* g^(q - b) mod p */
        BN_mod_exp(u, dsa->g, b, dsa->p, ctx);  /* g^b mod p */
        BN_mod_mul(u, u, v, dsa->p, ctx);
+       NTP_INSIST(u->d != NULL);
        temp = BN_is_one(u);
        fprintf(stderr,
            "Confirm g^(q - b) g^b = 1 mod p: %s\n", temp == 1 ?
@@ -863,7 +864,6 @@ gen_iff(
        if (!temp) {
                BN_free(b); BN_free(r); BN_free(k);
                BN_free(u); BN_free(v); BN_free(w); BN_CTX_free(ctx);
-               rval = -1;
                return (NULL);
        }
        dsa->priv_key = BN_dup(b);              /* private key */
@@ -905,7 +905,6 @@ gen_iff(
        BN_free(u); BN_free(v); BN_free(w); BN_CTX_free(ctx);
        if (temp != 0) {
                DSA_free(dsa);
-               rval = -1;
                return (NULL);
        }
 
@@ -921,7 +920,6 @@ gen_iff(
         */
        str = fheader("IFFpar", trustname);
        pkey = EVP_PKEY_new();
-       NTP_INSIST(pkey != NULL);
        EVP_PKEY_assign_DSA(pkey, dsa);
        PEM_write_PrivateKey(str, pkey, passwd2 ? EVP_des_cbc() : NULL,
            NULL, 0, NULL, passwd2);
@@ -977,7 +975,6 @@ gen_gqpar(
        if (rsa == NULL) {
                fprintf(stderr, "RSA generate keys fails\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
-               rval = -1;
                return (NULL);
        }
 
@@ -1081,7 +1078,6 @@ gen_gqkey(
                BN_free(g); BN_free(k); BN_free(r); BN_free(y);
                BN_CTX_free(ctx);
                RSA_free(rsa);
-               rval = -1;
                return (NULL);
        }
        BN_copy(rsa->p, u);                     /* private key */
@@ -1122,7 +1118,6 @@ gen_gqkey(
        BN_free(g); BN_free(k); BN_free(r); BN_free(y);
        if (temp != 0) {
                RSA_free(rsa);
-               rval = -1;
                return (NULL);
        }
 
@@ -1263,8 +1258,8 @@ gen_mv(
        NTP_INSIST(dsa->q != NULL);
        dsa->g = BN_new();
        NTP_INSIST(dsa->g != NULL);
-       s = emalloc((n + 1) * sizeof(BIGNUM));
-       s1 = emalloc((n + 1) * sizeof(BIGNUM));
+       s = malloc((n + 1) * sizeof(BIGNUM));
+       s1 = malloc((n + 1) * sizeof(BIGNUM));
        for (j = 1; j <= n; j++) {
                s1[j] = BN_new();
                NTP_INSIST(s1[j] != NULL);
@@ -1337,6 +1332,7 @@ gen_mv(
                BN_rand(dsa->g, BN_num_bits(dsa->p) - 1, 0, 0);
                BN_mod(dsa->g, dsa->g, dsa->p, ctx);
                BN_gcd(u, dsa->g, v, ctx);
+               NTP_INSIST(u->d != NULL);
                if (!BN_is_one(u))
                        continue;
 
@@ -1367,7 +1363,7 @@ gen_mv(
        fprintf(stderr,
            "Generating polynomial coefficients for %d roots (%d bits)\n",
            n, BN_num_bits(dsa->q)); 
-       x = emalloc((n + 1) * sizeof(BIGNUM));
+       x = malloc((n + 1) * sizeof(BIGNUM));
        for (j = 1; j <= n; j++) {
                x[j] = BN_new();
                NTP_INSIST(x[j] != NULL);
@@ -1385,7 +1381,7 @@ gen_mv(
         * expansion of root products (x - x[j]) mod q for all j. The
         * method is a present from Charlie Boncelet.
         */
-       a = emalloc((n + 1) * sizeof(BIGNUM));
+       a = malloc((n + 1) * sizeof(BIGNUM));
        for (i = 0; i <= n; i++) {
                a[i] = BN_new();
                NTP_INSIST(a[i] != NULL);
@@ -1407,7 +1403,7 @@ gen_mv(
         * Generate g[i] = g^a[i] mod p for all i and the generator g.
         */
        fprintf(stderr, "Generating g[i] parameters\n");
-       g = emalloc((n + 1) * sizeof(BIGNUM));
+       g = malloc((n + 1) * sizeof(BIGNUM));
        for (i = 0; i <= n; i++) {
                g[i] = BN_new();
                NTP_INSIST(g[i] != NULL);
@@ -1437,7 +1433,6 @@ gen_mv(
            "Confirm prod(g[i]^(x[j]^i)) = 1 for all i, j: %s\n", temp ?
            "yes" : "no");
        if (!temp) {
-               rval = -1;
                return (NULL);
        }
 
@@ -1477,8 +1472,8 @@ gen_mv(
         * or the product s = prod(s'[j]) mod q, which is the enabling
         * key.
         */
-       xbar = emalloc((n + 1) * sizeof(BIGNUM));
-       xhat = emalloc((n + 1) * sizeof(BIGNUM));
+       xbar = malloc((n + 1) * sizeof(BIGNUM));
+       xhat = malloc((n + 1) * sizeof(BIGNUM));
        for (j = 1; j <= n; j++) {
                xbar[j] = BN_new(); xhat[j] = BN_new();
                NTP_INSIST(xbar[j] != NULL);
@@ -1705,7 +1700,6 @@ x509      (
                fprintf(stderr, "Assign key fails\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
                X509_free(cert);
-               rval = -1;
                return (0);
        }
 
@@ -1725,7 +1719,6 @@ x509      (
        if (!X509_add_ext(cert, ex, -1)) {
                fprintf(stderr, "Add extension field fails\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
-               rval = -1;
                return (0);
        }
        X509_EXTENSION_free(ex);
@@ -1739,7 +1732,6 @@ x509      (
        if (!X509_add_ext(cert, ex, -1)) {
                fprintf(stderr, "Add extension field fails\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
-               rval = -1;
                return (0);
        }
        X509_EXTENSION_free(ex);
@@ -1755,7 +1747,6 @@ x509      (
                        fprintf(stderr,
                            "Add extension field fails\n%s\n",
                            ERR_error_string(ERR_get_error(), NULL));
-                       rval = -1;
                        return (0);
                }
                X509_EXTENSION_free(ex);
@@ -1777,7 +1768,6 @@ x509      (
                        fprintf(stderr,
                            "Add extension field fails\n%s\n",
                            ERR_error_string(ERR_get_error(), NULL));
-                       rval = -1;
                        return (0);
                }
                X509_EXTENSION_free(ex);
@@ -1791,7 +1781,6 @@ x509      (
                fprintf(stderr, "Verify %s certificate fails\n%s\n", id,
                    ERR_error_string(ERR_get_error(), NULL));
                X509_free(cert);
-               rval = -1;
                return (0);
        }
 
@@ -1899,7 +1888,6 @@ genkey(
                return (gen_dsa(id));
 
        fprintf(stderr, "Invalid %s key type %s\n", id, type);
-       rval = -1;
        return (NULL);
 }
 #endif /* OPENSSL */