2 * authreadkeys.c - routines to support the reading of the key file
10 #include "ntp_syslog.h"
11 #include "ntp_stdlib.h"
14 #include "openssl/objects.h"
15 #include "openssl/evp.h"
19 static char *nexttok (char **);
22 * nexttok - basic internal tokenizing routine
35 * Space past white space
37 while (*cp == ' ' || *cp == '\t')
41 * Save this and space to end of token
44 while (*cp != '\0' && *cp != '\n' && *cp != ' '
45 && *cp != '\t' && *cp != '#')
49 * If token length is zero return an error, else set end of
50 * token to zero and return start.
55 if (*cp == ' ' || *cp == '\t')
66 * authreadkeys - (re)read keys from a file.
78 char buf[512]; /* lots of room for line */
79 u_char keystr[32]; /* Bug 2537 */
84 * Open file. Complain and return if it can't be opened.
86 fp = fopen(file, "r");
88 msyslog(LOG_ERR, "authreadkeys: file %s: %m",
95 * Remove all existing keys
100 * Now read lines from the file, looking for key entries
102 while ((line = fgets(buf, sizeof buf, fp)) != NULL) {
103 token = nexttok(&line);
108 * First is key number. See if it is okay.
113 "authreadkeys: cannot change key %s", token);
117 if (keyno > NTP_MAXKEY) {
119 "authreadkeys: key %s > %d reserved for Autokey",
125 * Next is keytype. See if that is all right.
127 token = nexttok(&line);
130 "authreadkeys: no key type for key %d", keyno);
135 * The key type is the NID used by the message digest
136 * algorithm. There are a number of inconsistencies in
137 * the OpenSSL database. We attempt to discover them
138 * here and prevent use of inconsistent data later.
140 keytype = keytype_from_text(token, NULL);
143 "authreadkeys: invalid type for key %d", keyno);
146 if (EVP_get_digestbynid(keytype) == NULL) {
148 "authreadkeys: no algorithm for key %d", keyno);
151 #else /* !OPENSSL follows */
154 * The key type is unused, but is required to be 'M' or
155 * 'm' for compatibility.
157 if (!(*token == 'M' || *token == 'm')) {
159 "authreadkeys: invalid type for key %d", keyno);
162 keytype = KEY_TYPE_MD5;
163 #endif /* !OPENSSL */
166 * Finally, get key and insert it. If it is longer than 20
167 * characters, it is a binary string encoded in hex;
168 * otherwise, it is a text string of printable ASCII
171 token = nexttok(&line);
174 "authreadkeys: no key for key %d", keyno);
178 if (len <= 20) { /* Bug 2537 */
179 MD5auth_setkey(keyno, keytype, (u_char *)token, len);
181 char hex[] = "0123456789abcdef";
186 jlim = min(len, 2 * sizeof(keystr));
187 for (j = 0; j < jlim; j++) {
188 ptr = strchr(hex, tolower((unsigned char)token[j]));
190 break; /* abort decoding */
191 temp = (u_char)(ptr - hex);
193 keystr[j / 2] |= temp;
195 keystr[j / 2] = temp << 4;
199 "authreadkeys: invalid hex digit for key %d", keyno);
202 MD5auth_setkey(keyno, keytype, keystr, jlim / 2);