Annotation of embedaddon/ntp/libntp/authreadkeys.c, revision 1.1.1.1

1.1       misho       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 "ntp_fp.h"
                      9: #include "ntp.h"
                     10: #include "ntp_syslog.h"
                     11: #include "ntp_stdlib.h"
                     12: 
                     13: #ifdef OPENSSL
                     14: #include "openssl/objects.h"
                     15: #endif /* OPENSSL */
                     16: 
                     17: /* Forwards */
                     18: static char *nexttok (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 (NULL);
                     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:        keyid_t keyno;
                     76:        int     keytype;
                     77:        char    buf[512];               /* lots of room for line */
                     78:        u_char  keystr[20];
                     79:        int     len;
                     80:        int     j;
                     81: 
                     82:        /*
                     83:         * Open file.  Complain and return if it can't be opened.
                     84:         */
                     85:        fp = fopen(file, "r");
                     86:        if (fp == NULL) {
                     87:                msyslog(LOG_ERR, "authreadkeys: file %s: %m",
                     88:                    file);
                     89:                return (0);
                     90:        }
                     91:        INIT_SSL();
                     92: 
                     93:        /*
                     94:         * Remove all existing keys
                     95:         */
                     96:        auth_delkeys();
                     97: 
                     98:        /*
                     99:         * Now read lines from the file, looking for key entries
                    100:         */
                    101:        while ((line = fgets(buf, sizeof buf, fp)) != NULL) {
                    102:                token = nexttok(&line);
                    103:                if (token == NULL)
                    104:                        continue;
                    105:                
                    106:                /*
                    107:                 * First is key number.  See if it is okay.
                    108:                 */
                    109:                keyno = atoi(token);
                    110:                if (keyno == 0) {
                    111:                        msyslog(LOG_ERR,
                    112:                            "authreadkeys: cannot change key %s", token);
                    113:                        continue;
                    114:                }
                    115: 
                    116:                if (keyno > NTP_MAXKEY) {
                    117:                        msyslog(LOG_ERR,
                    118:                            "authreadkeys: key %s > %d reserved for Autokey",
                    119:                            token, NTP_MAXKEY);
                    120:                        continue;
                    121:                }
                    122: 
                    123:                /*
                    124:                 * Next is keytype. See if that is all right.
                    125:                 */
                    126:                token = nexttok(&line);
                    127:                if (token == NULL) {
                    128:                        msyslog(LOG_ERR,
                    129:                            "authreadkeys: no key type for key %d", keyno);
                    130:                        continue;
                    131:                }
                    132: #ifdef OPENSSL
                    133:                /*
                    134:                 * The key type is the NID used by the message digest 
                    135:                 * algorithm. There are a number of inconsistencies in
                    136:                 * the OpenSSL database. We attempt to discover them
                    137:                 * here and prevent use of inconsistent data later.
                    138:                 */
                    139:                keytype = keytype_from_text(token, NULL);
                    140:                if (keytype == 0) {
                    141:                        msyslog(LOG_ERR,
                    142:                            "authreadkeys: invalid type for key %d", keyno);
                    143:                        continue;
                    144:                }
                    145:                if (EVP_get_digestbynid(keytype) == NULL) {
                    146:                        msyslog(LOG_ERR,
                    147:                            "authreadkeys: no algorithm for key %d", keyno);
                    148:                        continue;
                    149:                }
                    150: #else /* OPENSSL */
                    151: 
                    152:                /*
                    153:                 * The key type is unused, but is required to be 'M' or
                    154:                 * 'm' for compatibility.
                    155:                 */
                    156:                if (!(*token == 'M' || *token == 'm')) {
                    157:                        msyslog(LOG_ERR,
                    158:                            "authreadkeys: invalid type for key %d", keyno);
                    159:                        continue;
                    160:                }
                    161:                keytype = KEY_TYPE_MD5;
                    162: #endif /* OPENSSL */
                    163: 
                    164:                /*
                    165:                 * Finally, get key and insert it. If it is longer than 20
                    166:                 * characters, it is a binary string encoded in hex;
                    167:                 * otherwise, it is a text string of printable ASCII
                    168:                 * characters.
                    169:                 */
                    170:                token = nexttok(&line);
                    171:                if (token == NULL) {
                    172:                        msyslog(LOG_ERR,
                    173:                            "authreadkeys: no key for key %d", keyno);
                    174:                        continue;
                    175:                }
                    176:                len = strlen(token);
                    177:                if (len <= 20) {
                    178:                        MD5auth_setkey(keyno, keytype, (u_char *)token, len);
                    179:                } else {
                    180:                        char    hex[] = "0123456789abcdef";
                    181:                        u_char  temp;
                    182:                        char    *ptr;
                    183:                        int     jlim;
                    184: 
                    185:                        jlim = min(len, 2 * sizeof(keystr));
                    186:                        for (j = 0; j < jlim; j++) {
                    187:                                ptr = strchr(hex, tolower(token[j]));
                    188:                                if (ptr == NULL) {
                    189:                                        msyslog(LOG_ERR,
                    190:                                            "authreadkeys: invalid hex digit for key %d", keyno);
                    191:                                        continue;
                    192:                                }
                    193:                                temp = (u_char)(ptr - hex);
                    194:                                if (j & 1)
                    195:                                        keystr[j / 2] |= temp;
                    196:                                else
                    197:                                        keystr[j / 2] = temp << 4;
                    198:                        }
                    199:                        MD5auth_setkey(keyno, keytype, keystr, jlim / 2);
                    200:                }
                    201:        }
                    202:        fclose(fp);
                    203:        return (1);
                    204: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>