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