154359Sroberto/* 254359Sroberto * authreadkeys.c - routines to support the reading of the key file 354359Sroberto */ 454359Sroberto#include <stdio.h> 554359Sroberto#include <ctype.h> 654359Sroberto 754359Sroberto#include "ntp_fp.h" 854359Sroberto#include "ntp.h" 982498Sroberto#include "ntp_syslog.h" 1054359Sroberto#include "ntp_stdlib.h" 1154359Sroberto 1254359Sroberto/* 1354359Sroberto * Arbitrary long string of ASCII characters. 1454359Sroberto */ 1554359Sroberto#define KEY_TYPE_MD5 4 1654359Sroberto 1754359Sroberto/* Forwards */ 1854359Srobertostatic char *nexttok P((char **)); 1954359Sroberto 2054359Sroberto/* 2154359Sroberto * nexttok - basic internal tokenizing routine 2254359Sroberto */ 2354359Srobertostatic char * 2454359Srobertonexttok( 2554359Sroberto char **str 2654359Sroberto ) 2754359Sroberto{ 2854359Sroberto register char *cp; 2954359Sroberto char *starttok; 3054359Sroberto 3154359Sroberto cp = *str; 3254359Sroberto 3354359Sroberto /* 3454359Sroberto * Space past white space 3554359Sroberto */ 3654359Sroberto while (*cp == ' ' || *cp == '\t') 3754359Sroberto cp++; 3854359Sroberto 3954359Sroberto /* 4054359Sroberto * Save this and space to end of token 4154359Sroberto */ 4254359Sroberto starttok = cp; 4354359Sroberto while (*cp != '\0' && *cp != '\n' && *cp != ' ' 4454359Sroberto && *cp != '\t' && *cp != '#') 4554359Sroberto cp++; 4654359Sroberto 4754359Sroberto /* 4854359Sroberto * If token length is zero return an error, else set end of 4954359Sroberto * token to zero and return start. 5054359Sroberto */ 5154359Sroberto if (starttok == cp) 5254359Sroberto return 0; 5354359Sroberto 5454359Sroberto if (*cp == ' ' || *cp == '\t') 5554359Sroberto *cp++ = '\0'; 5654359Sroberto else 5754359Sroberto *cp = '\0'; 5854359Sroberto 5954359Sroberto *str = cp; 6054359Sroberto return starttok; 6154359Sroberto} 6254359Sroberto 6354359Sroberto 6454359Sroberto/* 6554359Sroberto * authreadkeys - (re)read keys from a file. 6654359Sroberto */ 6754359Srobertoint 6854359Srobertoauthreadkeys( 6954359Sroberto const char *file 7054359Sroberto ) 7154359Sroberto{ 7254359Sroberto FILE *fp; 7354359Sroberto char *line; 7454359Sroberto char *token; 7554359Sroberto u_long keyno; 7654359Sroberto int keytype; 7754359Sroberto char buf[512]; /* lots of room for line */ 7854359Sroberto 7954359Sroberto /* 8054359Sroberto * Open file. Complain and return if it can't be opened. 8154359Sroberto */ 8254359Sroberto fp = fopen(file, "r"); 8354359Sroberto if (fp == NULL) { 8454359Sroberto msyslog(LOG_ERR, "can't open key file %s: %m", file); 8554359Sroberto return 0; 8654359Sroberto } 8754359Sroberto 8854359Sroberto /* 8954359Sroberto * Remove all existing keys 9054359Sroberto */ 9154359Sroberto auth_delkeys(); 9254359Sroberto 9354359Sroberto /* 9454359Sroberto * Now read lines from the file, looking for key entries 9554359Sroberto */ 9654359Sroberto while ((line = fgets(buf, sizeof buf, fp)) != NULL) { 9754359Sroberto token = nexttok(&line); 9854359Sroberto if (token == 0) 9954359Sroberto continue; 10054359Sroberto 10154359Sroberto /* 10254359Sroberto * First is key number. See if it is okay. 10354359Sroberto */ 10454359Sroberto keyno = atoi(token); 10554359Sroberto if (keyno == 0) { 10654359Sroberto msyslog(LOG_ERR, 10754359Sroberto "cannot change keyid 0, key entry `%s' ignored", 10854359Sroberto token); 10954359Sroberto continue; 11054359Sroberto } 11154359Sroberto 11254359Sroberto if (keyno > NTP_MAXKEY) { 11354359Sroberto msyslog(LOG_ERR, 11454359Sroberto "keyid's > %d reserved for autokey, key entry `%s' ignored", 11554359Sroberto NTP_MAXKEY, token); 11654359Sroberto continue; 11754359Sroberto } 11854359Sroberto 11954359Sroberto /* 12054359Sroberto * Next is keytype. See if that is all right. 12154359Sroberto */ 12254359Sroberto token = nexttok(&line); 12354359Sroberto if (token == 0) { 12454359Sroberto msyslog(LOG_ERR, 12554359Sroberto "no key type for key number %ld, entry ignored", 12654359Sroberto keyno); 12754359Sroberto continue; 12854359Sroberto } 12954359Sroberto switch (*token) { 13054359Sroberto case 'M': 13154359Sroberto case 'm': 13254359Sroberto keytype = KEY_TYPE_MD5; break; 13354359Sroberto default: 13454359Sroberto msyslog(LOG_ERR, 13554359Sroberto "invalid key type for key number %ld, entry ignored", 13654359Sroberto keyno); 13754359Sroberto continue; 13854359Sroberto } 13954359Sroberto 14054359Sroberto /* 14154359Sroberto * Finally, get key and insert it 14254359Sroberto */ 14354359Sroberto token = nexttok(&line); 14454359Sroberto if (token == 0) { 14554359Sroberto msyslog(LOG_ERR, 14654359Sroberto "no key for number %ld entry, entry ignored", 14754359Sroberto keyno); 14854359Sroberto } else { 14954359Sroberto switch(keytype) { 15054359Sroberto case KEY_TYPE_MD5: 15154359Sroberto if (!authusekey(keyno, keytype, 15254359Sroberto (u_char *)token)) 15354359Sroberto msyslog(LOG_ERR, 15454359Sroberto "format/parity error for MD5 key %ld, not used", 15554359Sroberto keyno); 15654359Sroberto break; 15754359Sroberto } 15854359Sroberto } 15954359Sroberto } 16054359Sroberto (void) fclose(fp); 16154359Sroberto return 1; 16254359Sroberto} 163