authreadkeys.c (294554) | authreadkeys.c (298695) |
---|---|
1/* 2 * authreadkeys.c - routines to support the reading of the key file 3 */ 4#include <config.h> 5#include <stdio.h> 6#include <ctype.h> 7 8#include "ntpd.h" /* Only for DPRINTF */ --- 87 unchanged lines hidden (view full) --- 96 97static void 98log_maybe( 99 u_int *pnerr, 100 const char *fmt , 101 ...) 102{ 103 va_list ap; | 1/* 2 * authreadkeys.c - routines to support the reading of the key file 3 */ 4#include <config.h> 5#include <stdio.h> 6#include <ctype.h> 7 8#include "ntpd.h" /* Only for DPRINTF */ --- 87 unchanged lines hidden (view full) --- 96 97static void 98log_maybe( 99 u_int *pnerr, 100 const char *fmt , 101 ...) 102{ 103 va_list ap; |
104 if (++(*pnerr) <= nerr_loglimit) { | 104 if ((NULL == pnerr) || (++(*pnerr) <= nerr_loglimit)) { |
105 va_start(ap, fmt); 106 mvsyslog(LOG_ERR, fmt, ap); 107 va_end(ap); 108 } 109} 110 | 105 va_start(ap, fmt); 106 mvsyslog(LOG_ERR, fmt, ap); 107 va_end(ap); 108 } 109} 110 |
111static void 112free_keydata( 113 KeyDataT *node 114 ) 115{ 116 KeyAccT *kap; 117 118 if (node) { 119 while (node->keyacclist) { 120 kap = node->keyacclist; 121 node->keyacclist = kap->next; 122 free(kap); 123 } 124 125 /* purge secrets from memory before free()ing it */ 126 memset(node, 0, sizeof(*node) + node->seclen); 127 free(node); 128 } 129} 130 |
|
111/* 112 * authreadkeys - (re)read keys from a file. 113 */ 114int 115authreadkeys( 116 const char *file 117 ) 118{ --- 32 unchanged lines hidden (view full) --- 151 token = nexttok(&line); 152 if (token == NULL) 153 continue; 154 155 /* 156 * First is key number. See if it is okay. 157 */ 158 keyno = atoi(token); | 131/* 132 * authreadkeys - (re)read keys from a file. 133 */ 134int 135authreadkeys( 136 const char *file 137 ) 138{ --- 32 unchanged lines hidden (view full) --- 171 token = nexttok(&line); 172 if (token == NULL) 173 continue; 174 175 /* 176 * First is key number. See if it is okay. 177 */ 178 keyno = atoi(token); |
159 if (keyno == 0) { | 179 if (keyno < 1) { |
160 log_maybe(&nerr, 161 "authreadkeys: cannot change key %s", 162 token); 163 continue; 164 } 165 166 if (keyno > NTP_MAXKEY) { 167 log_maybe(&nerr, --- 7 unchanged lines hidden (view full) --- 175 */ 176 token = nexttok(&line); 177 if (token == NULL) { 178 log_maybe(&nerr, 179 "authreadkeys: no key type for key %d", 180 keyno); 181 continue; 182 } | 180 log_maybe(&nerr, 181 "authreadkeys: cannot change key %s", 182 token); 183 continue; 184 } 185 186 if (keyno > NTP_MAXKEY) { 187 log_maybe(&nerr, --- 7 unchanged lines hidden (view full) --- 195 */ 196 token = nexttok(&line); 197 if (token == NULL) { 198 log_maybe(&nerr, 199 "authreadkeys: no key type for key %d", 200 keyno); 201 continue; 202 } |
203 204 /* We want to silently ignore keys where we do not 205 * support the requested digest type. OTOH, we want to 206 * make sure the file is well-formed. That means we 207 * have to process the line completely and have to 208 * finally throw away the result... This is a bit more 209 * work, but it also results in better error detection. 210 */ |
|
183#ifdef OPENSSL 184 /* 185 * The key type is the NID used by the message digest 186 * algorithm. There are a number of inconsistencies in 187 * the OpenSSL database. We attempt to discover them 188 * here and prevent use of inconsistent data later. 189 */ 190 keytype = keytype_from_text(token, NULL); 191 if (keytype == 0) { | 211#ifdef OPENSSL 212 /* 213 * The key type is the NID used by the message digest 214 * algorithm. There are a number of inconsistencies in 215 * the OpenSSL database. We attempt to discover them 216 * here and prevent use of inconsistent data later. 217 */ 218 keytype = keytype_from_text(token, NULL); 219 if (keytype == 0) { |
192 log_maybe(&nerr, | 220 log_maybe(NULL, |
193 "authreadkeys: invalid type for key %d", 194 keyno); | 221 "authreadkeys: invalid type for key %d", 222 keyno); |
195 continue; 196 } 197 if (EVP_get_digestbynid(keytype) == NULL) { 198 log_maybe(&nerr, | 223 } else if (EVP_get_digestbynid(keytype) == NULL) { 224 log_maybe(NULL, |
199 "authreadkeys: no algorithm for key %d", 200 keyno); | 225 "authreadkeys: no algorithm for key %d", 226 keyno); |
201 continue; | 227 keytype = 0; |
202 } 203#else /* !OPENSSL follows */ | 228 } 229#else /* !OPENSSL follows */ |
204 | |
205 /* 206 * The key type is unused, but is required to be 'M' or 207 * 'm' for compatibility. 208 */ 209 if (!(*token == 'M' || *token == 'm')) { | 230 /* 231 * The key type is unused, but is required to be 'M' or 232 * 'm' for compatibility. 233 */ 234 if (!(*token == 'M' || *token == 'm')) { |
210 log_maybe(&nerr, | 235 log_maybe(NULL, |
211 "authreadkeys: invalid type for key %d", 212 keyno); | 236 "authreadkeys: invalid type for key %d", 237 keyno); |
213 continue; | 238 keytype = 0; 239 } else { 240 keytype = KEY_TYPE_MD5; |
214 } | 241 } |
215 keytype = KEY_TYPE_MD5; | |
216#endif /* !OPENSSL */ 217 218 /* 219 * Finally, get key and insert it. If it is longer than 20 220 * characters, it is a binary string encoded in hex; 221 * otherwise, it is a text string of printable ASCII 222 * characters. 223 */ --- 40 unchanged lines hidden (view full) --- 264 next->keyacclist = NULL; 265 next->keyid = keyno; 266 next->keytype = keytype; 267 next->seclen = len; 268 memcpy(next->secbuf, keystr, len); 269 } 270 271 token = nexttok(&line); | 242#endif /* !OPENSSL */ 243 244 /* 245 * Finally, get key and insert it. If it is longer than 20 246 * characters, it is a binary string encoded in hex; 247 * otherwise, it is a text string of printable ASCII 248 * characters. 249 */ --- 40 unchanged lines hidden (view full) --- 290 next->keyacclist = NULL; 291 next->keyid = keyno; 292 next->keytype = keytype; 293 next->seclen = len; 294 memcpy(next->secbuf, keystr, len); 295 } 296 297 token = nexttok(&line); |
272DPRINTF(0, ("authreadkeys: full access list <%s>\n", (token) ? token : "NULL")); | 298 DPRINTF(0, ("authreadkeys: full access list <%s>\n", (token) ? token : "NULL")); |
273 if (token != NULL) { /* A comma-separated IP access list */ 274 char *tp = token; 275 276 while (tp) { 277 char *i; | 299 if (token != NULL) { /* A comma-separated IP access list */ 300 char *tp = token; 301 302 while (tp) { 303 char *i; |
278 KeyAccT ka; | 304 sockaddr_u addr; |
279 280 i = strchr(tp, (int)','); 281 if (i) 282 *i = '\0'; | 305 306 i = strchr(tp, (int)','); 307 if (i) 308 *i = '\0'; |
283DPRINTF(0, ("authreadkeys: access list: <%s>\n", tp)); | 309 DPRINTF(0, ("authreadkeys: access list: <%s>\n", tp)); |
284 | 310 |
285 if (is_ip_address(tp, AF_UNSPEC, &ka.addr)) { 286 KeyAccT *kap; 287 288 kap = emalloc(sizeof(KeyAccT)); 289 memcpy(kap, &ka, sizeof ka); 290 kap->next = next->keyacclist; 291 next->keyacclist = kap; | 311 if (is_ip_address(tp, AF_UNSPEC, &addr)) { 312 next->keyacclist = keyacc_new_push( 313 next->keyacclist, &addr); |
292 } else { 293 log_maybe(&nerr, 294 "authreadkeys: invalid IP address <%s> for key %d", 295 tp, keyno); 296 } 297 298 if (i) { 299 tp = i + 1; 300 } else { 301 tp = 0; 302 } 303 } 304 } 305 | 314 } else { 315 log_maybe(&nerr, 316 "authreadkeys: invalid IP address <%s> for key %d", 317 tp, keyno); 318 } 319 320 if (i) { 321 tp = i + 1; 322 } else { 323 tp = 0; 324 } 325 } 326 } 327 |
328 /* check if this has to be weeded out... */ 329 if (0 == keytype) { 330 free_keydata(next); 331 next = NULL; 332 continue; 333 } 334 |
|
306 INSIST(NULL != next); 307 next->next = list; 308 list = next; 309 } 310 fclose(fp); | 335 INSIST(NULL != next); 336 next->next = list; 337 list = next; 338 } 339 fclose(fp); |
311 if (nerr > nerr_maxlimit) { 312 msyslog(LOG_ERR, 313 "authreadkeys: rejecting file '%s' after %u errors (emergency break)", 314 file, nerr); 315 goto onerror; 316 } | |
317 if (nerr > 0) { | 340 if (nerr > 0) { |
341 const char * why = ""; 342 if (nerr > nerr_maxlimit) 343 why = " (emergency break)"; |
|
318 msyslog(LOG_ERR, | 344 msyslog(LOG_ERR, |
319 "authreadkeys: rejecting file '%s' after %u error(s)", 320 file, nerr); | 345 "authreadkeys: rejecting file '%s' after %u error(s)%s", 346 file, nerr, why); |
321 goto onerror; 322 } 323 324 /* first remove old file-based keys */ 325 auth_delkeys(); 326 /* insert the new key material */ 327 while (NULL != (next = list)) { 328 list = next->next; 329 MD5auth_setkey(next->keyid, next->keytype, 330 next->secbuf, next->seclen, next->keyacclist); | 347 goto onerror; 348 } 349 350 /* first remove old file-based keys */ 351 auth_delkeys(); 352 /* insert the new key material */ 353 while (NULL != (next = list)) { 354 list = next->next; 355 MD5auth_setkey(next->keyid, next->keytype, 356 next->secbuf, next->seclen, next->keyacclist); |
331 /* purge secrets from memory before free()ing it */ 332 memset(next, 0, sizeof(*next) + next->seclen); 333 free(next); | 357 next->keyacclist = NULL; /* consumed by MD5auth_setkey */ 358 free_keydata(next); |
334 } 335 return (1); 336 337 onerror: 338 /* Mop up temporary storage before bailing out. */ 339 while (NULL != (next = list)) { 340 list = next->next; | 359 } 360 return (1); 361 362 onerror: 363 /* Mop up temporary storage before bailing out. */ 364 while (NULL != (next = list)) { 365 list = next->next; |
341 342 while (next->keyacclist) { 343 KeyAccT *kap = next->keyacclist; 344 345 next->keyacclist = kap->next; 346 free(kap); 347 } 348 349 /* purge secrets from memory before free()ing it */ 350 memset(next, 0, sizeof(*next) + next->seclen); 351 free(next); | 366 free_keydata(next); |
352 } 353 return (0); 354} | 367 } 368 return (0); 369} |