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

unix.superglobalmegacorp.com

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