Annotation of researchv10no/ipc/mgrs/authmgr/secret.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <string.h>
                      3: #include <ctype.h>
                      4: #include <sys/types.h>
                      5: #include <time.h>
                      6: #include "auth.h"
                      7: 
                      8: #define FIELDSIZE      100     /* maximum field size in the keys file */
                      9: #define LARGECH                99999   /* largest challenge */
                     10: 
                     11: typedef struct keydesc keydesc;
                     12: 
                     13: struct keydesc {
                     14:        char    name[FIELDSIZE];
                     15:        char    type[FIELDSIZE];
                     16:        char    key[FIELDSIZE];
                     17:        long    expires;
                     18:        struct keydesc  *next;
                     19: };
                     20: 
                     21: struct keydesc *firstkey;
                     22: struct keydesc *kp;
                     23: enum keytypes kt;
                     24: 
                     25: unsigned long challenge = 0;
                     26: time_t now;                    /* current time, for expiration purposes */
                     27: 
                     28: extern char *keyfile;
                     29: 
                     30:        
                     31: /*
                     32:  * Get challenge string for `login'. `type' is the login type, "" for the
                     33:  * first one found.
                     34:  */
                     35: char *
                     36: getchallenge(login, type, echo)
                     37:        char *login;
                     38:        char *type;
                     39:        int *echo;
                     40: {
                     41:        static char buf[BUFSIZ];
                     42:        static int inited=0;
                     43: 
                     44:        for (kp=firstkey; kp; kp = kp->next)
                     45:                if (strcmp(kp->name, login) == NULL)
                     46:                        if (type == NULL || strcmp(type, "") == NULL ||
                     47:                            strcmp(type, kp->type) == NULL)
                     48:                                break;
                     49: 
                     50:        if (kp == (keydesc *)0 || (strcmp(kp->type, "passwd") != NULL)) {
                     51:                /*
                     52:                 *  atalla entry or illegal user.  Generate a challenge.
                     53:                 */
                     54:                if(!inited)
                     55:                        srand((int)time((long*)0));
                     56:                challenge = lrand()%LARGECH;
                     57:                sprintf(buf, "Enter response code for %lu: ", challenge);
                     58:                if (kp == (keydesc *)0)
                     59:                        kt = NONE;
                     60:                else
                     61:                        kt = ATALLA;
                     62:                *echo = TRUE;
                     63:        } else {
                     64:                kt = PASS;
                     65:                strcpy(buf, "Password: ");
                     66:                *echo = FALSE;
                     67:        }
                     68:        return buf;
                     69: }
                     70: 
                     71: /*
                     72:  * He gave `response'.  Return TRUE iff it is the correct
                     73:  * response.
                     74:  */
                     75: int
                     76: responseok(response)
                     77:        char response[];
                     78: {
                     79:        char b[64];
                     80:        int k[8];
                     81:        char buf[12];
                     82:        int i,j;
                     83:        unsigned long bresponse = 0;
                     84:        char cresponse[10];
                     85: 
                     86:        /*
                     87:         * check expiration date.
                     88:         */
                     89:        if (kt != NONE && kp->expires < now) {
                     90:                fprintf(stderr, "Account `%s' is expired (%d)\n",
                     91:                        kp->name, kp->expires);
                     92:                kt = NONE;
                     93:                kp = (keydesc *)0;
                     94:        }
                     95: 
                     96:        switch(kt) {
                     97:        case NONE:      /* take some time, then say no. */
                     98:                setkey(b);
                     99:                encrypt(b, 0);
                    100:                return FALSE;
                    101:        case PASS:      /* the classic password hash */
                    102:                return (strcmp(crypt(response, kp->key), kp->key) == NULL);
                    103:        case ATALLA:
                    104:                /*
                    105:                 * set the key
                    106:                 */
                    107:                sscanf(kp->key, "%o %o %o %o %o %o %o %o",
                    108:                        &k[0], &k[1], &k[2], &k[3], &k[4], &k[5], &k[6], &k[7]);
                    109:                for(i=0; i<8; i++)
                    110:                        for(j=0; j<8; j++)
                    111:                                b[8*i+j] = (k[i]>>(7-j))&1;
                    112:                setkey(b);
                    113: 
                    114:                /*
                    115:                 * compute the proper response.  We encrypt the ascii of
                    116:                 * challenge number, with trailing binary zero fill.
                    117:                 * This process was derived empirically.
                    118:                 */
                    119:                for(i=0; i<8; buf[i++] = 0)
                    120:                        ;
                    121:                sprintf(buf, "%lu", challenge);
                    122:                for(i=0; i<8; i++)
                    123:                        for(j=0; j<8; j++)
                    124:                                b[8*i+j] = (buf[i]>>(7-j))&1;
                    125:                encrypt(b, 0);
                    126:                for(i=0; i<32; i++) {
                    127:                        bresponse = (bresponse<<1) | b[i];
                    128:                }
                    129: 
                    130:                /*
                    131:                 * check for hex match
                    132:                 */
                    133:                sprintf(cresponse, "%08x", bresponse);
                    134:                for (i=0; response[i]; i++)
                    135:                        if (isupper(response[i]))
                    136:                                response[i] = tolower(response[i]);
                    137:                if (strcmp(response, cresponse) == 0)
                    138:                        return TRUE;    /* Hex matches */
                    139: 
                    140:                /*
                    141:                 * check for decimal match
                    142:                 */
                    143:                for (i=0; cresponse[i]; i++)
                    144:                        if (cresponse[i] == 'a' || cresponse[i] == 'b' ||
                    145:                            cresponse[i] == 'c')
                    146:                                cresponse[i] = '2';
                    147:                        else if (cresponse[i] == 'd' || cresponse[i] == 'e' ||
                    148:                                 cresponse[i] == 'f')
                    149:                                cresponse[i] = '3';
                    150:                return (strcmp(response, cresponse) == NULL);   /* Decimal matches */
                    151:        }
                    152: }
                    153: 
                    154: 
                    155: /*
                    156:  * Read in the keys.  This won't happen in a secret-server version.
                    157:  *
                    158:  * key file has the following colon-separated fields:
                    159:  *
                    160:  *     id      user's id
                    161:  *     type    entry type (`atalla' is only legal entry at the moment)
                    162:  *     key     the key's value: 
                    163:  *             for atalla:     8 blank-separated octal bytes
                    164:  *     expire  expiration date of this entry [optional]
                    165:  *     comment [optional]
                    166:  */
                    167: readkeyfile()
                    168: {
                    169:        FILE *kf;
                    170:        int linenumber = 0;
                    171:        char line[BUFSIZE];
                    172: #define NFLDS  10
                    173:        char *field[NFLDS];
                    174:        keydesc *lastkey = firstkey = (keydesc *)0;
                    175:        time_t t = time((long*)0);
                    176:        struct tm *tm = localtime(&t);
                    177: 
                    178:        now = tm->tm_mday + 100*(tm->tm_mon+1) + 10000*(tm->tm_year+1900);
                    179: 
                    180:        if ((kf = fopen(keyfile, "r")) == NULL) {
                    181:                printf("Could not open key file: get help!\n");
                    182:                exit(100);
                    183:        }
                    184:        setfields(":");
                    185:        while(fgets(line, sizeof(line), kf) != NULL) {
                    186:                int i;
                    187:                char *cp;
                    188: 
                    189:                linenumber++;
                    190:                for(i=0; line[i] == ' ' || line[i] == '\t'; i++)
                    191:                        ;
                    192:                if(line[i] == '#')
                    193:                        continue;
                    194:                if((cp = strchr(&line[i], '\n')) != NULL)
                    195:                        *cp = '\0';
                    196: 
                    197:                i = getfields(&line[i], field, NFLDS);
                    198:                if(i <= 1)      /* blank line */
                    199:                        continue;
                    200:                if (i < 3) {
                    201:                        fprintf(stderr, "Bad key entry for line %d, ignored\n",
                    202:                                linenumber);
                    203:                        continue;
                    204:                }
                    205: 
                    206:                if ((kp = (keydesc *)malloc(sizeof(keydesc))) == (keydesc *)0) {
                    207:                        printf("Out of memory: get help!\n");
                    208:                        fprintf("Out of memory building key table\n");
                    209:                        exit(101);
                    210:                }
                    211:                if (firstkey == (keydesc *)0)
                    212:                        firstkey = kp;
                    213:                if (lastkey)
                    214:                        lastkey->next = kp;
                    215:                strncpy(kp->name, field[0], FIELDSIZE);
                    216:                strncpy(kp->type, field[1], FIELDSIZE);
                    217:                strncpy(kp->key,  field[2], FIELDSIZE);
                    218:                if (i >= 4)
                    219:                        if(strcmp(field[3], "") != 0) {
                    220:                                kp->expires = atol(field[3]);
                    221:                                if (kp->expires < 19700101 ||
                    222:                                    kp->expires > 99991231) {
                    223:                                        fprintf(stderr, "Bad expiration for line %d, ignored\n",
                    224:                                                linenumber);
                    225:                                                continue;
                    226:                                }
                    227:                        } else
                    228:                                kp->expires = 99991231;
                    229:                kp->next = (keydesc *)0;
                    230:                lastkey = kp;
                    231:        }
                    232:        
                    233: }
                    234: 
                    235: dumpkeys()
                    236: {
                    237:        keydesc *kp;
                    238: 
                    239:        for (kp=firstkey; kp; kp = kp->next)
                    240:                printf("%s/%s/%s/%s/\n",
                    241:                        kp->name, kp->type, kp->key, kp->expires);
                    242: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.