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

unix.superglobalmegacorp.com

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