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 */ 33 static char *nexttok P((char **)); 34 35 /* 36 * nexttok - basic internal tokenizing routine 37 */ 38 static char * 39 nexttok( 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 */ 82 int 83 authreadkeys( 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