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 } 200