diff options
Diffstat (limited to 'libntp/authreadkeys.c')
-rw-r--r-- | libntp/authreadkeys.c | 134 |
1 files changed, 88 insertions, 46 deletions
diff --git a/libntp/authreadkeys.c b/libntp/authreadkeys.c index 22020f3..063515e 100644 --- a/libntp/authreadkeys.c +++ b/libntp/authreadkeys.c @@ -1,6 +1,7 @@ /* * authreadkeys.c - routines to support the reading of the key file */ +#include <config.h> #include <stdio.h> #include <ctype.h> @@ -9,20 +10,19 @@ #include "ntp_syslog.h" #include "ntp_stdlib.h" -/* - * Arbitrary long string of ASCII characters. - */ -#define KEY_TYPE_MD5 4 +#ifdef OPENSSL +#include "openssl/objects.h" +#endif /* OPENSSL */ /* Forwards */ -static char *nexttok P((char **)); +static char *nexttok (char **); /* * nexttok - basic internal tokenizing routine */ static char * nexttok( - char **str + char **str ) { register char *cp; @@ -49,7 +49,7 @@ nexttok( * token to zero and return start. */ if (starttok == cp) - return 0; + return (NULL); if (*cp == ' ' || *cp == '\t') *cp++ = '\0'; @@ -69,21 +69,26 @@ authreadkeys( const char *file ) { - FILE *fp; - char *line; - char *token; - u_long keyno; - int keytype; - char buf[512]; /* lots of room for line */ + FILE *fp; + char *line; + char *token; + keyid_t keyno; + int keytype; + char buf[512]; /* lots of room for line */ + u_char keystr[20]; + int len; + int j; /* * Open file. Complain and return if it can't be opened. */ fp = fopen(file, "r"); if (fp == NULL) { - msyslog(LOG_ERR, "can't open key file %s: %m", file); - return 0; + msyslog(LOG_ERR, "authreadkeys: file %s: %m", + file); + return (0); } + INIT_SSL(); /* * Remove all existing keys @@ -95,8 +100,8 @@ authreadkeys( */ while ((line = fgets(buf, sizeof buf, fp)) != NULL) { token = nexttok(&line); - if (token == 0) - continue; + if (token == NULL) + continue; /* * First is key number. See if it is okay. @@ -104,59 +109,96 @@ authreadkeys( keyno = atoi(token); if (keyno == 0) { msyslog(LOG_ERR, - "cannot change keyid 0, key entry `%s' ignored", - token); + "authreadkeys: cannot change key %s", token); continue; } if (keyno > NTP_MAXKEY) { msyslog(LOG_ERR, - "keyid's > %d reserved for autokey, key entry `%s' ignored", - NTP_MAXKEY, token); + "authreadkeys: key %s > %d reserved for Autokey", + token, NTP_MAXKEY); continue; } /* - * Next is keytype. See if that is all right. + * Next is keytype. See if that is all right. */ token = nexttok(&line); - if (token == 0) { + if (token == NULL) { msyslog(LOG_ERR, - "no key type for key number %ld, entry ignored", - keyno); + "authreadkeys: no key type for key %d", keyno); continue; } - switch (*token) { - case 'M': - case 'm': - keytype = KEY_TYPE_MD5; break; - default: +#ifdef OPENSSL + /* + * The key type is the NID used by the message digest + * algorithm. There are a number of inconsistencies in + * the OpenSSL database. We attempt to discover them + * here and prevent use of inconsistent data later. + */ + keytype = keytype_from_text(token, NULL); + if (keytype == 0) { msyslog(LOG_ERR, - "invalid key type for key number %ld, entry ignored", - keyno); + "authreadkeys: invalid type for key %d", keyno); continue; } + if (EVP_get_digestbynid(keytype) == NULL) { + msyslog(LOG_ERR, + "authreadkeys: no algorithm for key %d", keyno); + continue; + } +#else /* OPENSSL */ /* - * Finally, get key and insert it + * The key type is unused, but is required to be 'M' or + * 'm' for compatibility. + */ + if (!(*token == 'M' || *token == 'm')) { + msyslog(LOG_ERR, + "authreadkeys: invalid type for key %d", keyno); + continue; + } + keytype = KEY_TYPE_MD5; +#endif /* OPENSSL */ + + /* + * Finally, get key and insert it. If it is longer than 20 + * characters, it is a binary string encoded in hex; + * otherwise, it is a text string of printable ASCII + * characters. */ token = nexttok(&line); - if (token == 0) { + if (token == NULL) { msyslog(LOG_ERR, - "no key for number %ld entry, entry ignored", - keyno); + "authreadkeys: no key for key %d", keyno); + continue; + } + len = strlen(token); + if (len <= 20) { + MD5auth_setkey(keyno, keytype, (u_char *)token, len); } else { - switch(keytype) { - case KEY_TYPE_MD5: - if (!authusekey(keyno, keytype, - (u_char *)token)) - msyslog(LOG_ERR, - "format/parity error for MD5 key %ld, not used", - keyno); - break; + char hex[] = "0123456789abcdef"; + u_char temp; + char *ptr; + int jlim; + + jlim = min(len, 2 * sizeof(keystr)); + for (j = 0; j < jlim; j++) { + ptr = strchr(hex, tolower(token[j])); + if (ptr == NULL) { + msyslog(LOG_ERR, + "authreadkeys: invalid hex digit for key %d", keyno); + continue; + } + temp = (u_char)(ptr - hex); + if (j & 1) + keystr[j / 2] |= temp; + else + keystr[j / 2] = temp << 4; } + MD5auth_setkey(keyno, keytype, keystr, jlim / 2); } } - (void) fclose(fp); - return 1; + fclose(fp); + return (1); } |