authreadkeys.c revision 82498
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#ifdef	DES
13/*
14 * Types of ascii representations for keys.  "Standard" means a 64 bit
15 * hex number in NBS format, i.e. with the low order bit of each byte
16 * a parity bit.  "NTP" means a 64 bit key in NTP format, with the
17 * high order bit of each byte a parity bit.  "Ascii" means a 1-to-8
18 * character string whose ascii representation is used as the key.
19 */
20#define	KEY_TYPE_STD	1
21#define	KEY_TYPE_NTP	2
22#define	KEY_TYPE_ASCII	3
23#endif
24
25/*
26 *  Arbitrary long string of ASCII characters.
27 */
28#define	KEY_TYPE_MD5	4
29
30/* Forwards */
31static char *nexttok P((char **));
32
33/*
34 * nexttok - basic internal tokenizing routine
35 */
36static char *
37nexttok(
38	char **str
39	)
40{
41	register char *cp;
42	char *starttok;
43
44	cp = *str;
45
46	/*
47	 * Space past white space
48	 */
49	while (*cp == ' ' || *cp == '\t')
50	    cp++;
51
52	/*
53	 * Save this and space to end of token
54	 */
55	starttok = cp;
56	while (*cp != '\0' && *cp != '\n' && *cp != ' '
57	       && *cp != '\t' && *cp != '#')
58	    cp++;
59
60	/*
61	 * If token length is zero return an error, else set end of
62	 * token to zero and return start.
63	 */
64	if (starttok == cp)
65	    return 0;
66
67	if (*cp == ' ' || *cp == '\t')
68	    *cp++ = '\0';
69	else
70	    *cp = '\0';
71
72	*str = cp;
73	return starttok;
74}
75
76
77/*
78 * authreadkeys - (re)read keys from a file.
79 */
80int
81authreadkeys(
82	const char *file
83	)
84{
85	FILE *fp;
86	char *line;
87	char *token;
88	u_long keyno;
89	int keytype;
90	char buf[512];		/* lots of room for line */
91
92	/*
93	 * Open file.  Complain and return if it can't be opened.
94	 */
95	fp = fopen(file, "r");
96	if (fp == NULL) {
97		msyslog(LOG_ERR, "can't open key file %s: %m", file);
98		return 0;
99	}
100
101	/*
102	 * Remove all existing keys
103	 */
104	auth_delkeys();
105
106	/*
107	 * Now read lines from the file, looking for key entries
108	 */
109	while ((line = fgets(buf, sizeof buf, fp)) != NULL) {
110		token = nexttok(&line);
111		if (token == 0)
112		    continue;
113
114		/*
115		 * First is key number.  See if it is okay.
116		 */
117		keyno = atoi(token);
118		if (keyno == 0) {
119			msyslog(LOG_ERR,
120				"cannot change keyid 0, key entry `%s' ignored",
121				token);
122			continue;
123		}
124
125		if (keyno > NTP_MAXKEY) {
126			msyslog(LOG_ERR,
127				"keyid's > %d reserved for autokey, key entry `%s' ignored",
128				NTP_MAXKEY, token);
129			continue;
130		}
131
132		/*
133		 * Next is keytype.  See if that is all right.
134		 */
135		token = nexttok(&line);
136		if (token == 0) {
137			msyslog(LOG_ERR,
138				"no key type for key number %ld, entry ignored",
139				keyno);
140			continue;
141		}
142		switch (*token) {
143#ifdef	DES
144		    case 'S':
145		    case 's':
146			keytype = KEY_TYPE_STD; break;
147
148		    case 'N':
149		    case 'n':
150			keytype = KEY_TYPE_NTP; break;
151
152		    case 'A':
153		    case 'a':
154			keytype = KEY_TYPE_ASCII; break;
155#endif
156		    case 'M':
157		    case 'm':
158			keytype = KEY_TYPE_MD5; break;
159		    default:
160			msyslog(LOG_ERR,
161				"invalid key type for key number %ld, entry ignored",
162				keyno);
163			continue;
164		}
165
166		/*
167		 * Finally, get key and insert it
168		 */
169		token = nexttok(&line);
170		if (token == 0) {
171			msyslog(LOG_ERR,
172				"no key for number %ld entry, entry ignored",
173				keyno);
174		} else {
175			switch(keytype) {
176#ifdef	DES
177			    case KEY_TYPE_STD:
178			    case KEY_TYPE_NTP:
179			    case KEY_TYPE_ASCII:
180				if (!authusekey(keyno, keytype,
181						(u_char *)token))
182				    msyslog(LOG_ERR,
183					    "format/parity error for DES key %ld, not used",
184					    keyno);
185				break;
186#endif
187			    case KEY_TYPE_MD5:
188				if (!authusekey(keyno, keytype,
189						(u_char *)token))
190				    msyslog(LOG_ERR,
191					    "format/parity error for MD5 key %ld, not used",
192					    keyno);
193				break;
194			}
195		}
196	}
197	(void) fclose(fp);
198	return 1;
199}
200