Annotation of embedaddon/ntp/libntp/authreadkeys.c, revision 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>