Annotation of embedaddon/ntp/libntp/authreadkeys.c, revision 1.1
1.1 ! misho 1: /*
! 2: * authreadkeys.c - routines to support the reading of the key file
! 3: */
! 4: #include <config.h>
! 5: #include <stdio.h>
! 6: #include <ctype.h>
! 7:
! 8: #include "ntp_fp.h"
! 9: #include "ntp.h"
! 10: #include "ntp_syslog.h"
! 11: #include "ntp_stdlib.h"
! 12:
! 13: #ifdef OPENSSL
! 14: #include "openssl/objects.h"
! 15: #endif /* OPENSSL */
! 16:
! 17: /* Forwards */
! 18: static char *nexttok (char **);
! 19:
! 20: /*
! 21: * nexttok - basic internal tokenizing routine
! 22: */
! 23: static char *
! 24: nexttok(
! 25: char **str
! 26: )
! 27: {
! 28: register char *cp;
! 29: char *starttok;
! 30:
! 31: cp = *str;
! 32:
! 33: /*
! 34: * Space past white space
! 35: */
! 36: while (*cp == ' ' || *cp == '\t')
! 37: cp++;
! 38:
! 39: /*
! 40: * Save this and space to end of token
! 41: */
! 42: starttok = cp;
! 43: while (*cp != '\0' && *cp != '\n' && *cp != ' '
! 44: && *cp != '\t' && *cp != '#')
! 45: cp++;
! 46:
! 47: /*
! 48: * If token length is zero return an error, else set end of
! 49: * token to zero and return start.
! 50: */
! 51: if (starttok == cp)
! 52: return (NULL);
! 53:
! 54: if (*cp == ' ' || *cp == '\t')
! 55: *cp++ = '\0';
! 56: else
! 57: *cp = '\0';
! 58:
! 59: *str = cp;
! 60: return starttok;
! 61: }
! 62:
! 63:
! 64: /*
! 65: * authreadkeys - (re)read keys from a file.
! 66: */
! 67: int
! 68: authreadkeys(
! 69: const char *file
! 70: )
! 71: {
! 72: FILE *fp;
! 73: char *line;
! 74: char *token;
! 75: keyid_t keyno;
! 76: int keytype;
! 77: char buf[512]; /* lots of room for line */
! 78: u_char keystr[20];
! 79: int len;
! 80: int j;
! 81:
! 82: /*
! 83: * Open file. Complain and return if it can't be opened.
! 84: */
! 85: fp = fopen(file, "r");
! 86: if (fp == NULL) {
! 87: msyslog(LOG_ERR, "authreadkeys: file %s: %m",
! 88: file);
! 89: return (0);
! 90: }
! 91: INIT_SSL();
! 92:
! 93: /*
! 94: * Remove all existing keys
! 95: */
! 96: auth_delkeys();
! 97:
! 98: /*
! 99: * Now read lines from the file, looking for key entries
! 100: */
! 101: while ((line = fgets(buf, sizeof buf, fp)) != NULL) {
! 102: token = nexttok(&line);
! 103: if (token == NULL)
! 104: continue;
! 105:
! 106: /*
! 107: * First is key number. See if it is okay.
! 108: */
! 109: keyno = atoi(token);
! 110: if (keyno == 0) {
! 111: msyslog(LOG_ERR,
! 112: "authreadkeys: cannot change key %s", token);
! 113: continue;
! 114: }
! 115:
! 116: if (keyno > NTP_MAXKEY) {
! 117: msyslog(LOG_ERR,
! 118: "authreadkeys: key %s > %d reserved for Autokey",
! 119: token, NTP_MAXKEY);
! 120: continue;
! 121: }
! 122:
! 123: /*
! 124: * Next is keytype. See if that is all right.
! 125: */
! 126: token = nexttok(&line);
! 127: if (token == NULL) {
! 128: msyslog(LOG_ERR,
! 129: "authreadkeys: no key type for key %d", keyno);
! 130: continue;
! 131: }
! 132: #ifdef OPENSSL
! 133: /*
! 134: * The key type is the NID used by the message digest
! 135: * algorithm. There are a number of inconsistencies in
! 136: * the OpenSSL database. We attempt to discover them
! 137: * here and prevent use of inconsistent data later.
! 138: */
! 139: keytype = keytype_from_text(token, NULL);
! 140: if (keytype == 0) {
! 141: msyslog(LOG_ERR,
! 142: "authreadkeys: invalid type for key %d", keyno);
! 143: continue;
! 144: }
! 145: if (EVP_get_digestbynid(keytype) == NULL) {
! 146: msyslog(LOG_ERR,
! 147: "authreadkeys: no algorithm for key %d", keyno);
! 148: continue;
! 149: }
! 150: #else /* OPENSSL */
! 151:
! 152: /*
! 153: * The key type is unused, but is required to be 'M' or
! 154: * 'm' for compatibility.
! 155: */
! 156: if (!(*token == 'M' || *token == 'm')) {
! 157: msyslog(LOG_ERR,
! 158: "authreadkeys: invalid type for key %d", keyno);
! 159: continue;
! 160: }
! 161: keytype = KEY_TYPE_MD5;
! 162: #endif /* OPENSSL */
! 163:
! 164: /*
! 165: * Finally, get key and insert it. If it is longer than 20
! 166: * characters, it is a binary string encoded in hex;
! 167: * otherwise, it is a text string of printable ASCII
! 168: * characters.
! 169: */
! 170: token = nexttok(&line);
! 171: if (token == NULL) {
! 172: msyslog(LOG_ERR,
! 173: "authreadkeys: no key for key %d", keyno);
! 174: continue;
! 175: }
! 176: len = strlen(token);
! 177: if (len <= 20) {
! 178: MD5auth_setkey(keyno, keytype, (u_char *)token, len);
! 179: } else {
! 180: char hex[] = "0123456789abcdef";
! 181: u_char temp;
! 182: char *ptr;
! 183: int jlim;
! 184:
! 185: jlim = min(len, 2 * sizeof(keystr));
! 186: for (j = 0; j < jlim; j++) {
! 187: ptr = strchr(hex, tolower(token[j]));
! 188: if (ptr == NULL) {
! 189: msyslog(LOG_ERR,
! 190: "authreadkeys: invalid hex digit for key %d", keyno);
! 191: continue;
! 192: }
! 193: temp = (u_char)(ptr - hex);
! 194: if (j & 1)
! 195: keystr[j / 2] |= temp;
! 196: else
! 197: keystr[j / 2] = temp << 4;
! 198: }
! 199: MD5auth_setkey(keyno, keytype, keystr, jlim / 2);
! 200: }
! 201: }
! 202: fclose(fp);
! 203: return (1);
! 204: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>