xref: /freebsd/contrib/ntp/libntp/authreadkeys.c (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
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 */
18 static char *nexttok P((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 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  */
67 int
68 authreadkeys(
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