summaryrefslogtreecommitdiffstats
path: root/libntp/authreadkeys.c
diff options
context:
space:
mode:
Diffstat (limited to 'libntp/authreadkeys.c')
-rw-r--r--libntp/authreadkeys.c134
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);
}
OpenPOWER on IntegriCloud