Annotation of 43BSDTahoe/lib/libc/net/ruserpass.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  */
                     17: 
                     18: #if defined(LIBC_SCCS) && !defined(lint)
                     19: static char sccsid[] = "@(#)ruserpass.c        5.5 (Berkeley) 6/27/88";
                     20: #endif /* LIBC_SCCS and not lint */
                     21: 
                     22: #include <stdio.h>
                     23: #include <utmp.h>
                     24: #include <ctype.h>
                     25: #include <sys/types.h>
                     26: #include <sys/stat.h>
                     27: #include <errno.h>
                     28: 
                     29: char   *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin();
                     30: struct utmp *getutmp();
                     31: static FILE *cfile;
                     32: 
                     33: ruserpass(host, aname, apass)
                     34:        char *host, **aname, **apass;
                     35: {
                     36: 
                     37:        renv(host, aname, apass);
                     38:        if (*aname == 0 || *apass == 0)
                     39:                rnetrc(host, aname, apass);
                     40:        if (*aname == 0) {
                     41:                char *myname = getlogin();
                     42:                *aname = malloc(16);
                     43:                printf("Name (%s:%s): ", host, myname);
                     44:                fflush(stdout);
                     45:                if (read(2, *aname, 16) <= 0)
                     46:                        exit(1);
                     47:                if ((*aname)[0] == '\n')
                     48:                        *aname = myname;
                     49:                else
                     50:                        if (index(*aname, '\n'))
                     51:                                *index(*aname, '\n') = 0;
                     52:        }
                     53:        if (*aname && *apass == 0) {
                     54:                printf("Password (%s:%s): ", host, *aname);
                     55:                fflush(stdout);
                     56:                *apass = getpass("");
                     57:        }
                     58: }
                     59: 
                     60: static
                     61: renv(host, aname, apass)
                     62:        char *host, **aname, **apass;
                     63: {
                     64:        register char *cp;
                     65:        char *stemp, fgetlogin, *comma;
                     66: 
                     67:        cp = renvlook(host);
                     68:        if (cp == NULL)
                     69:                return;
                     70:        if (!isalpha(cp[0]))
                     71:                return;
                     72:        comma = index(cp, ',');
                     73:        if (comma == 0)
                     74:                return;
                     75:        if (*aname == 0) {
                     76:                *aname = malloc(comma - cp + 1);
                     77:                strncpy(*aname, cp, comma - cp);
                     78:        } else
                     79:                if (strncmp(*aname, cp, comma - cp))
                     80:                        return;
                     81:        comma++;
                     82:        cp = malloc(strlen(comma)+1);
                     83:        strcpy(cp, comma);
                     84:        *apass = malloc(16);
                     85:        mkpwclear(cp, host[0], *apass);
                     86: }
                     87: 
                     88: static
                     89: char *
                     90: renvlook(host)
                     91:        char *host;
                     92: {
                     93:        register char *cp, **env;
                     94:        extern char **environ;
                     95: 
                     96:        env = environ;
                     97:        for (env = environ; *env != NULL; env++)
                     98:                if (!strncmp(*env, "MACH", 4)) {
                     99:                        cp = index(*env, '=');
                    100:                        if (cp == 0)
                    101:                                continue;
                    102:                        if (strncmp(*env+4, host, cp-(*env+4)))
                    103:                                continue;
                    104:                        return (cp+1);
                    105:                }
                    106:        return (NULL);
                    107: }
                    108: 
                    109: #define        DEFAULT 1
                    110: #define        LOGIN   2
                    111: #define        PASSWD  3
                    112: #define        NOTIFY  4
                    113: #define        WRITE   5
                    114: #define        YES     6
                    115: #define        NO      7
                    116: #define        COMMAND 8
                    117: #define        FORCE   9
                    118: #define        ID      10
                    119: #define        MACHINE 11
                    120: 
                    121: static char tokval[100];
                    122: 
                    123: static struct toktab {
                    124:        char *tokstr;
                    125:        int tval;
                    126: } toktab[]= {
                    127:        "default",      DEFAULT,
                    128:        "login",        LOGIN,
                    129:        "password",     PASSWD,
                    130:        "notify",       NOTIFY,
                    131:        "write",        WRITE,
                    132:        "yes",          YES,
                    133:        "y",            YES,
                    134:        "no",           NO,
                    135:        "n",            NO,
                    136:        "command",      COMMAND,
                    137:        "force",        FORCE,
                    138:        "machine",      MACHINE,
                    139:        0,              0
                    140: };
                    141: 
                    142: static
                    143: rnetrc(host, aname, apass)
                    144:        char *host, **aname, **apass;
                    145: {
                    146:        char *hdir, buf[BUFSIZ];
                    147:        int t;
                    148:        struct stat stb;
                    149:        extern int errno;
                    150: 
                    151:        hdir = getenv("HOME");
                    152:        if (hdir == NULL)
                    153:                hdir = ".";
                    154:        (void)sprintf(buf, "%s/.netrc", hdir);
                    155:        cfile = fopen(buf, "r");
                    156:        if (cfile == NULL) {
                    157:                if (errno != ENOENT)
                    158:                        perror(buf);
                    159:                return;
                    160:        }
                    161: next:
                    162:        while ((t = token())) switch(t) {
                    163: 
                    164:        case DEFAULT:
                    165:                (void) token();
                    166:                continue;
                    167: 
                    168:        case MACHINE:
                    169:                if (token() != ID || strcmp(host, tokval))
                    170:                        continue;
                    171:                while ((t = token()) && t != MACHINE) switch(t) {
                    172: 
                    173:                case LOGIN:
                    174:                        if (token())
                    175:                                if (*aname == 0) { 
                    176:                                        *aname = malloc(strlen(tokval) + 1);
                    177:                                        strcpy(*aname, tokval);
                    178:                                } else {
                    179:                                        if (strcmp(*aname, tokval))
                    180:                                                goto next;
                    181:                                }
                    182:                        break;
                    183:                case PASSWD:
                    184:                        if (fstat(fileno(cfile), &stb) >= 0
                    185:                            && (stb.st_mode & 077) != 0) {
                    186:        fprintf(stderr, "Error - .netrc file not correct mode.\n");
                    187:        fprintf(stderr, "Remove password or correct mode.\n");
                    188:                                exit(1);
                    189:                        }
                    190:                        if (token() && *apass == 0) {
                    191:                                *apass = malloc(strlen(tokval) + 1);
                    192:                                strcpy(*apass, tokval);
                    193:                        }
                    194:                        break;
                    195:                case COMMAND:
                    196:                case NOTIFY:
                    197:                case WRITE:
                    198:                case FORCE:
                    199:                        (void) token();
                    200:                        break;
                    201:                default:
                    202:        fprintf(stderr, "Unknown .netrc option %s\n", tokval);
                    203:                        break;
                    204:                }
                    205:                goto done;
                    206:        }
                    207: done:
                    208:        fclose(cfile);
                    209: }
                    210: 
                    211: static
                    212: token()
                    213: {
                    214:        char *cp;
                    215:        int c;
                    216:        struct toktab *t;
                    217: 
                    218:        if (feof(cfile))
                    219:                return (0);
                    220:        while ((c = getc(cfile)) != EOF &&
                    221:            (c == '\n' || c == '\t' || c == ' ' || c == ','))
                    222:                continue;
                    223:        if (c == EOF)
                    224:                return (0);
                    225:        cp = tokval;
                    226:        if (c == '"') {
                    227:                while ((c = getc(cfile)) != EOF && c != '"') {
                    228:                        if (c == '\\')
                    229:                                c = getc(cfile);
                    230:                        *cp++ = c;
                    231:                }
                    232:        } else {
                    233:                *cp++ = c;
                    234:                while ((c = getc(cfile)) != EOF
                    235:                    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
                    236:                        if (c == '\\')
                    237:                                c = getc(cfile);
                    238:                        *cp++ = c;
                    239:                }
                    240:        }
                    241:        *cp = 0;
                    242:        if (tokval[0] == 0)
                    243:                return (0);
                    244:        for (t = toktab; t->tokstr; t++)
                    245:                if (!strcmp(t->tokstr, tokval))
                    246:                        return (t->tval);
                    247:        return (ID);
                    248: }
                    249: /* rest is nbs.c stolen from berknet */
                    250: 
                    251: char *deblknot(), *deblkclr();
                    252: char *nbs8decrypt(), *nbs8encrypt();
                    253: static char    E[48];
                    254: 
                    255: /*
                    256:  * The E bit-selection table.
                    257:  */
                    258: static char    e[] = {
                    259:        32, 1, 2, 3, 4, 5,
                    260:         4, 5, 6, 7, 8, 9,
                    261:         8, 9,10,11,12,13,
                    262:        12,13,14,15,16,17,
                    263:        16,17,18,19,20,21,
                    264:        20,21,22,23,24,25,
                    265:        24,25,26,27,28,29,
                    266:        28,29,30,31,32, 1,
                    267: };
                    268: static
                    269: char *nbsencrypt(str,key,result)
                    270:   char *result;
                    271:   char *str, *key; {
                    272:        static char buf[20],oldbuf[20];
                    273:        register int j;
                    274:        result[0] = 0;
                    275:        strcpy(oldbuf,key);
                    276:        while(*str){
                    277:                for(j=0;j<10;j++)buf[j] = 0;
                    278:                for(j=0;j<8 && *str;j++)buf[j] = *str++;
                    279:                strcat(result,nbs8encrypt(buf,oldbuf));
                    280:                strcat(result,"$");
                    281:                strcpy(oldbuf,buf);
                    282:                }
                    283:        return(result);
                    284:        }
                    285: static
                    286: char *nbsdecrypt(cpt,key,result)
                    287:   char *result;
                    288:   char *cpt,*key; {
                    289:        char *s;
                    290:        char c,oldbuf[20];
                    291:        result[0] = 0;
                    292:        strcpy(oldbuf,key);
                    293:        while(*cpt){
                    294:                for(s = cpt;*s && *s != '$';s++);
                    295:                c = *s;
                    296:                *s = 0;
                    297:                strcpy(oldbuf,nbs8decrypt(cpt,oldbuf));
                    298:                strcat(result,oldbuf);
                    299:                if(c == 0)break;
                    300:                cpt = s + 1;
                    301:                }
                    302:        return(result);
                    303:        }
                    304: 
                    305: static
                    306: char *nbs8encrypt(str,key)
                    307: char *str, *key; {
                    308:        static char keyblk[100], blk[100];
                    309:        register int i;
                    310: 
                    311:        enblkclr(keyblk,key);
                    312:        nbssetkey(keyblk);
                    313: 
                    314:        for(i=0;i<48;i++) E[i] = e[i];
                    315:        enblkclr(blk,str);
                    316:        blkencrypt(blk,0);                      /* forward dir */
                    317: 
                    318:        return(deblknot(blk));
                    319: }
                    320: 
                    321: static
                    322: char *nbs8decrypt(crp,key)
                    323: char *crp, *key; {
                    324:        static char keyblk[100], blk[100];
                    325:        register int i;
                    326: 
                    327:        enblkclr(keyblk,key);
                    328:        nbssetkey(keyblk);
                    329: 
                    330:        for(i=0;i<48;i++) E[i] = e[i];
                    331:        enblknot(blk,crp);
                    332:        blkencrypt(blk,1);                      /* backward dir */
                    333: 
                    334:        return(deblkclr(blk));
                    335: }
                    336: 
                    337: static
                    338: enblkclr(blk,str)              /* ignores top bit of chars in string str */
                    339: char *blk,*str; {
                    340:        register int i,j;
                    341:        char c;
                    342:        for(i=0;i<70;i++)blk[i] = 0;
                    343:        for(i=0; (c= *str) && i<64; str++){
                    344:                for(j=0; j<7; j++, i++)
                    345:                        blk[i] = (c>>(6-j)) & 01;
                    346:                i++;
                    347:                }
                    348:        }
                    349: 
                    350: static
                    351: char *deblkclr(blk)
                    352: char *blk; {
                    353:        register int i,j;
                    354:        char c;
                    355:        static char iobuf[30];
                    356:        for(i=0; i<10; i++){
                    357:                c = 0;
                    358:                for(j=0; j<7; j++){
                    359:                        c <<= 1;
                    360:                        c |= blk[8*i+j];
                    361:                        }
                    362:                iobuf[i] = c;
                    363:        }
                    364:        iobuf[i] = 0;
                    365:        return(iobuf);
                    366:        }
                    367: 
                    368: static
                    369: enblknot(blk,crp)
                    370: char *blk;
                    371: char *crp; {
                    372:        register int i,j;
                    373:        char c;
                    374:        for(i=0;i<70;i++)blk[i] = 0;
                    375:        for(i=0; (c= *crp) && i<64; crp++){
                    376:                if(c>'Z') c -= 6;
                    377:                if(c>'9') c -= 7;
                    378:                c -= '.';
                    379:                for(j=0; j<6; j++, i++)
                    380:                        blk[i] = (c>>(5-j)) & 01;
                    381:                }
                    382:        }
                    383: 
                    384: static
                    385: char *deblknot(blk)
                    386: char *blk; {
                    387:        register int i,j;
                    388:        char c;
                    389:        static char iobuf[30];
                    390:        for(i=0; i<11; i++){
                    391:                c = 0;
                    392:                for(j=0; j<6; j++){
                    393:                        c <<= 1;
                    394:                        c |= blk[6*i+j];
                    395:                        }
                    396:                c += '.';
                    397:                if(c > '9')c += 7;
                    398:                if(c > 'Z')c += 6;
                    399:                iobuf[i] = c;
                    400:        }
                    401:        iobuf[i] = 0;
                    402:        return(iobuf);
                    403: }
                    404: 
                    405: /*
                    406:  * This program implements the
                    407:  * Proposed Federal Information Processing
                    408:  *  Data Encryption Standard.
                    409:  * See Federal Register, March 17, 1975 (40FR12134)
                    410:  */
                    411: 
                    412: /*
                    413:  * Initial permutation,
                    414:  */
                    415: static char    IP[] = {
                    416:        58,50,42,34,26,18,10, 2,
                    417:        60,52,44,36,28,20,12, 4,
                    418:        62,54,46,38,30,22,14, 6,
                    419:        64,56,48,40,32,24,16, 8,
                    420:        57,49,41,33,25,17, 9, 1,
                    421:        59,51,43,35,27,19,11, 3,
                    422:        61,53,45,37,29,21,13, 5,
                    423:        63,55,47,39,31,23,15, 7,
                    424: };
                    425: 
                    426: /*
                    427:  * Final permutation, FP = IP^(-1)
                    428:  */
                    429: static char    FP[] = {
                    430:        40, 8,48,16,56,24,64,32,
                    431:        39, 7,47,15,55,23,63,31,
                    432:        38, 6,46,14,54,22,62,30,
                    433:        37, 5,45,13,53,21,61,29,
                    434:        36, 4,44,12,52,20,60,28,
                    435:        35, 3,43,11,51,19,59,27,
                    436:        34, 2,42,10,50,18,58,26,
                    437:        33, 1,41, 9,49,17,57,25,
                    438: };
                    439: 
                    440: /*
                    441:  * Permuted-choice 1 from the key bits
                    442:  * to yield C and D.
                    443:  * Note that bits 8,16... are left out:
                    444:  * They are intended for a parity check.
                    445:  */
                    446: static char    PC1_C[] = {
                    447:        57,49,41,33,25,17, 9,
                    448:         1,58,50,42,34,26,18,
                    449:        10, 2,59,51,43,35,27,
                    450:        19,11, 3,60,52,44,36,
                    451: };
                    452: 
                    453: static char    PC1_D[] = {
                    454:        63,55,47,39,31,23,15,
                    455:         7,62,54,46,38,30,22,
                    456:        14, 6,61,53,45,37,29,
                    457:        21,13, 5,28,20,12, 4,
                    458: };
                    459: 
                    460: /*
                    461:  * Sequence of shifts used for the key schedule.
                    462: */
                    463: static char    shifts[] = {
                    464:        1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
                    465: };
                    466: 
                    467: /*
                    468:  * Permuted-choice 2, to pick out the bits from
                    469:  * the CD array that generate the key schedule.
                    470:  */
                    471: static char    PC2_C[] = {
                    472:        14,17,11,24, 1, 5,
                    473:         3,28,15, 6,21,10,
                    474:        23,19,12, 4,26, 8,
                    475:        16, 7,27,20,13, 2,
                    476: };
                    477: 
                    478: static char    PC2_D[] = {
                    479:        41,52,31,37,47,55,
                    480:        30,40,51,45,33,48,
                    481:        44,49,39,56,34,53,
                    482:        46,42,50,36,29,32,
                    483: };
                    484: 
                    485: /*
                    486:  * The C and D arrays used to calculate the key schedule.
                    487:  */
                    488: 
                    489: static char    C[28];
                    490: static char    D[28];
                    491: /*
                    492:  * The key schedule.
                    493:  * Generated from the key.
                    494:  */
                    495: static char    KS[16][48];
                    496: 
                    497: /*
                    498:  * Set up the key schedule from the key.
                    499:  */
                    500: 
                    501: static
                    502: nbssetkey(key)
                    503: char *key;
                    504: {
                    505:        register i, j, k;
                    506:        int t;
                    507: 
                    508:        /*
                    509:         * First, generate C and D by permuting
                    510:         * the key.  The low order bit of each
                    511:         * 8-bit char is not used, so C and D are only 28
                    512:         * bits apiece.
                    513:         */
                    514:        for (i=0; i<28; i++) {
                    515:                C[i] = key[PC1_C[i]-1];
                    516:                D[i] = key[PC1_D[i]-1];
                    517:        }
                    518:        /*
                    519:         * To generate Ki, rotate C and D according
                    520:         * to schedule and pick up a permutation
                    521:         * using PC2.
                    522:         */
                    523:        for (i=0; i<16; i++) {
                    524:                /*
                    525:                 * rotate.
                    526:                 */
                    527:                for (k=0; k<shifts[i]; k++) {
                    528:                        t = C[0];
                    529:                        for (j=0; j<28-1; j++)
                    530:                                C[j] = C[j+1];
                    531:                        C[27] = t;
                    532:                        t = D[0];
                    533:                        for (j=0; j<28-1; j++)
                    534:                                D[j] = D[j+1];
                    535:                        D[27] = t;
                    536:                }
                    537:                /*
                    538:                 * get Ki. Note C and D are concatenated.
                    539:                 */
                    540:                for (j=0; j<24; j++) {
                    541:                        KS[i][j] = C[PC2_C[j]-1];
                    542:                        KS[i][j+24] = D[PC2_D[j]-28-1];
                    543:                }
                    544:        }
                    545: }
                    546: 
                    547: 
                    548: /*
                    549:  * The 8 selection functions.
                    550:  * For some reason, they give a 0-origin
                    551:  * index, unlike everything else.
                    552:  */
                    553: static char    S[8][64] = {
                    554:        14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
                    555:         0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
                    556:         4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
                    557:        15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
                    558: 
                    559:        15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
                    560:         3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
                    561:         0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
                    562:        13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
                    563: 
                    564:        10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
                    565:        13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
                    566:        13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
                    567:         1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
                    568: 
                    569:         7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
                    570:        13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
                    571:        10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
                    572:         3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
                    573: 
                    574:         2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
                    575:        14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
                    576:         4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
                    577:        11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
                    578: 
                    579:        12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
                    580:        10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
                    581:         9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
                    582:         4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
                    583: 
                    584:         4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
                    585:        13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
                    586:         1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
                    587:         6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
                    588: 
                    589:        13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
                    590:         1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
                    591:         7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
                    592:         2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
                    593: };
                    594: 
                    595: /*
                    596:  * P is a permutation on the selected combination
                    597:  * of the current L and key.
                    598:  */
                    599: static char    P[] = {
                    600:        16, 7,20,21,
                    601:        29,12,28,17,
                    602:         1,15,23,26,
                    603:         5,18,31,10,
                    604:         2, 8,24,14,
                    605:        32,27, 3, 9,
                    606:        19,13,30, 6,
                    607:        22,11, 4,25,
                    608: };
                    609: 
                    610: /*
                    611:  * The current block, divided into 2 halves.
                    612:  */
                    613: static char    L[32], R[32];
                    614: static char    tempL[32];
                    615: static char    f[32];
                    616: 
                    617: /*
                    618:  * The combination of the key and the input, before selection.
                    619:  */
                    620: static char    preS[48];
                    621: 
                    622: /*
                    623:  * The payoff: encrypt a block.
                    624:  */
                    625: 
                    626: static
                    627: blkencrypt(block, edflag)
                    628: char *block;
                    629: {
                    630:        int i, ii;
                    631:        register t, j, k;
                    632: 
                    633:        /*
                    634:         * First, permute the bits in the input
                    635:         */
                    636:        for (j=0; j<64; j++)
                    637:                L[j] = block[IP[j]-1];
                    638:        /*
                    639:         * Perform an encryption operation 16 times.
                    640:         */
                    641:        for (ii=0; ii<16; ii++) {
                    642:                /*
                    643:                 * Set direction
                    644:                 */
                    645:                if (edflag)
                    646:                        i = 15-ii;
                    647:                else
                    648:                        i = ii;
                    649:                /*
                    650:                 * Save the R array,
                    651:                 * which will be the new L.
                    652:                 */
                    653:                for (j=0; j<32; j++)
                    654:                        tempL[j] = R[j];
                    655:                /*
                    656:                 * Expand R to 48 bits using the E selector;
                    657:                 * exclusive-or with the current key bits.
                    658:                 */
                    659:                for (j=0; j<48; j++)
                    660:                        preS[j] = R[E[j]-1] ^ KS[i][j];
                    661:                /*
                    662:                 * The pre-select bits are now considered
                    663:                 * in 8 groups of 6 bits each.
                    664:                 * The 8 selection functions map these
                    665:                 * 6-bit quantities into 4-bit quantities
                    666:                 * and the results permuted
                    667:                 * to make an f(R, K).
                    668:                 * The indexing into the selection functions
                    669:                 * is peculiar; it could be simplified by
                    670:                 * rewriting the tables.
                    671:                 */
                    672:                for (j=0; j<8; j++) {
                    673:                        t = 6*j;
                    674:                        k = S[j][(preS[t+0]<<5)+
                    675:                                (preS[t+1]<<3)+
                    676:                                (preS[t+2]<<2)+
                    677:                                (preS[t+3]<<1)+
                    678:                                (preS[t+4]<<0)+
                    679:                                (preS[t+5]<<4)];
                    680:                        t = 4*j;
                    681:                        f[t+0] = (k>>3)&01;
                    682:                        f[t+1] = (k>>2)&01;
                    683:                        f[t+2] = (k>>1)&01;
                    684:                        f[t+3] = (k>>0)&01;
                    685:                }
                    686:                /*
                    687:                 * The new R is L ^ f(R, K).
                    688:                 * The f here has to be permuted first, though.
                    689:                 */
                    690:                for (j=0; j<32; j++)
                    691:                        R[j] = L[j] ^ f[P[j]-1];
                    692:                /*
                    693:                 * Finally, the new L (the original R)
                    694:                 * is copied back.
                    695:                 */
                    696:                for (j=0; j<32; j++)
                    697:                        L[j] = tempL[j];
                    698:        }
                    699:        /*
                    700:         * The output L and R are reversed.
                    701:         */
                    702:        for (j=0; j<32; j++) {
                    703:                t = L[j];
                    704:                L[j] = R[j];
                    705:                R[j] = t;
                    706:        }
                    707:        /*
                    708:         * The final output
                    709:         * gets the inverse permutation of the very original.
                    710:         */
                    711:        for (j=0; j<64; j++)
                    712:                block[j] = L[FP[j]-1];
                    713: }
                    714: /*
                    715:        getutmp()
                    716:        return a pointer to the system utmp structure associated with
                    717:        terminal sttyname, e.g. "/dev/tty3"
                    718:        Is version independent-- will work on v6 systems
                    719:        return NULL if error
                    720: */
                    721: static
                    722: struct utmp *getutmp(sttyname)
                    723: char *sttyname;
                    724: {
                    725:        static struct utmp utmpstr;
                    726:        FILE *fdutmp;
                    727: 
                    728:        if(sttyname == NULL || sttyname[0] == 0)return(NULL);
                    729: 
                    730:        fdutmp = fopen("/etc/utmp","r");
                    731:        if(fdutmp == NULL)return(NULL);
                    732: 
                    733:        while(fread(&utmpstr,1,sizeof utmpstr,fdutmp) == sizeof utmpstr)
                    734:                if(strcmp(utmpstr.ut_line,sttyname+5) == 0){
                    735:                        fclose(fdutmp);
                    736:                        return(&utmpstr);
                    737:                }
                    738:        fclose(fdutmp);
                    739:        return(NULL);
                    740: }
                    741: 
                    742: static
                    743: sreverse(sto, sfrom)
                    744:        register char *sto, *sfrom;
                    745: {
                    746:        register int i;
                    747: 
                    748:        i = strlen(sfrom);
                    749:        while (i >= 0)
                    750:                *sto++ = sfrom[i--];
                    751: }
                    752: 
                    753: static
                    754: char *mkenvkey(mch)
                    755:        char mch;
                    756: {
                    757:        static char skey[40];
                    758:        register struct utmp *putmp;
                    759:        char stemp[40], stemp1[40], sttyname[30];
                    760:        register char *sk,*p;
                    761: 
                    762:        if (isatty(2))
                    763:                strcpy(sttyname,ttyname(2));
                    764:        else if (isatty(0))
                    765:                strcpy(sttyname,ttyname(0));
                    766:        else if (isatty(1))
                    767:                strcpy(sttyname,ttyname(1));
                    768:        else
                    769:                return (NULL);
                    770:        putmp = getutmp(sttyname);
                    771:        if (putmp == NULL)
                    772:                return (NULL);
                    773:        sk = skey;
                    774:        p = putmp->ut_line;
                    775:        while (*p)
                    776:                *sk++ = *p++;
                    777:        *sk++ = mch;
                    778:        (void)sprintf(stemp, "%ld", putmp->ut_time);
                    779:        sreverse(stemp1, stemp);
                    780:        p = stemp1;
                    781:        while (*p)
                    782:                *sk++ = *p++;
                    783:        *sk = 0;
                    784:        return (skey);
                    785: }
                    786: 
                    787: mkpwunclear(spasswd,mch,sencpasswd)
                    788:        char mch, *spasswd, *sencpasswd;
                    789: {
                    790:        register char *skey;
                    791: 
                    792:        if (spasswd[0] == 0) {
                    793:                sencpasswd[0] = 0;
                    794:                return;
                    795:        }
                    796:        skey = mkenvkey(mch);
                    797:        if (skey == NULL) {
                    798:                fprintf(stderr, "Can't make key\n");
                    799:                exit(1);
                    800:        }
                    801:        nbsencrypt(spasswd, skey, sencpasswd);
                    802: }
                    803: 
                    804: mkpwclear(sencpasswd,mch,spasswd)
                    805:        char mch, *spasswd, *sencpasswd;
                    806: {
                    807:        register char *skey;
                    808: 
                    809:        if (sencpasswd[0] == 0) {
                    810:                spasswd[0] = 0;
                    811:                return;
                    812:        }
                    813:        skey = mkenvkey(mch);
                    814:        if (skey == NULL) {
                    815:                fprintf(stderr, "Can't make key\n");
                    816:                exit(1);
                    817:        }
                    818:        nbsdecrypt(sencpasswd, skey, spasswd);
                    819: }

unix.superglobalmegacorp.com

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