authreadkeys.c revision 132451
1/*
2 * authreadkeys.c - routines to support the reading of the key file
3 */
4#include <stdio.h>
5#include <ctype.h>
6
7#include "ntp_fp.h"
8#include "ntp.h"
9#include "ntp_syslog.h"
10#include "ntp_stdlib.h"
11
12/*
13 *  Arbitrary long string of ASCII characters.
14 */
15#define	KEY_TYPE_MD5	4
16
17/* Forwards */
18static char *nexttok P((char **));
19
20/*
21 * nexttok - basic internal tokenizing routine
22 */
23static char *
24nexttok(
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 0;
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 */
67int
68authreadkeys(
69	const char *file
70	)
71{
72	FILE *fp;
73	char *line;
74	char *token;
75	u_long keyno;
76	int keytype;
77	char buf[512];		/* lots of room for line */
78
79	/*
80	 * Open file.  Complain and return if it can't be opened.
81	 */
82	fp = fopen(file, "r");
83	if (fp == NULL) {
84		msyslog(LOG_ERR, "can't open key file %s: %m", file);
85		return 0;
86	}
87
88	/*
89	 * Remove all existing keys
90	 */
91	auth_delkeys();
92
93	/*
94	 * Now read lines from the file, looking for key entries
95	 */
96	while ((line = fgets(buf, sizeof buf, fp)) != NULL) {
97		token = nexttok(&line);
98		if (token == 0)
99		    continue;
100
101		/*
102		 * First is key number.  See if it is okay.
103		 */
104		keyno = atoi(token);
105		if (keyno == 0) {
106			msyslog(LOG_ERR,
107				"cannot change keyid 0, key entry `%s' ignored",
108				token);
109			continue;
110		}
111
112		if (keyno > NTP_MAXKEY) {
113			msyslog(LOG_ERR,
114				"keyid's > %d reserved for autokey, key entry `%s' ignored",
115				NTP_MAXKEY, token);
116			continue;
117		}
118
119		/*
120		 * Next is keytype.  See if that is all right.
121		 */
122		token = nexttok(&line);
123		if (token == 0) {
124			msyslog(LOG_ERR,
125				"no key type for key number %ld, entry ignored",
126				keyno);
127			continue;
128		}
129		switch (*token) {
130		    case 'M':
131		    case 'm':
132			keytype = KEY_TYPE_MD5; break;
133		    default:
134			msyslog(LOG_ERR,
135				"invalid key type for key number %ld, entry ignored",
136				keyno);
137			continue;
138		}
139
140		/*
141		 * Finally, get key and insert it
142		 */
143		token = nexttok(&line);
144		if (token == 0) {
145			msyslog(LOG_ERR,
146				"no key for number %ld entry, entry ignored",
147				keyno);
148		} else {
149			switch(keytype) {
150			    case KEY_TYPE_MD5:
151				if (!authusekey(keyno, keytype,
152						(u_char *)token))
153				    msyslog(LOG_ERR,
154					    "format/parity error for MD5 key %ld, not used",
155					    keyno);
156				break;
157			}
158		}
159	}
160	(void) fclose(fp);
161	return 1;
162}
163