Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / ntp / libntp / authreadkeys.c
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 */
31 static char *nexttok P((char **));
32
33 /*
34  * nexttok - basic internal tokenizing routine
35  */
36 static char *
37 nexttok(
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  */
80 int
81 authreadkeys(
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 }