1*37da2899SCharles.Forsythimplement Netkey; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsythinclude "sys.m"; 4*37da2899SCharles.Forsyth sys: Sys; 5*37da2899SCharles.Forsyth 6*37da2899SCharles.Forsythinclude "draw.m"; 7*37da2899SCharles.Forsyth 8*37da2899SCharles.Forsythinclude "keyring.m"; 9*37da2899SCharles.Forsyth keyring: Keyring; 10*37da2899SCharles.Forsyth 11*37da2899SCharles.ForsythNetkey: module 12*37da2899SCharles.Forsyth{ 13*37da2899SCharles.Forsyth init: fn(nil: ref Draw->Context, nil: list of string); 14*37da2899SCharles.Forsyth}; 15*37da2899SCharles.Forsyth 16*37da2899SCharles.ForsythANAMELEN: con 28; 17*37da2899SCharles.ForsythDESKEYLEN: con 7; 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsythinit(nil: ref Draw->Context, args: list of string) 20*37da2899SCharles.Forsyth{ 21*37da2899SCharles.Forsyth sys = load Sys Sys->PATH; 22*37da2899SCharles.Forsyth keyring = load Keyring Keyring->PATH; 23*37da2899SCharles.Forsyth 24*37da2899SCharles.Forsyth if(len args > 1){ 25*37da2899SCharles.Forsyth sys->fprint(sys->fildes(2), "usage: netkey\n"); 26*37da2899SCharles.Forsyth raise "fail:usage"; 27*37da2899SCharles.Forsyth } 28*37da2899SCharles.Forsyth (pw, err) := readconsline("Password: ", 1); 29*37da2899SCharles.Forsyth if(err != nil){ 30*37da2899SCharles.Forsyth sys->fprint(sys->fildes(2), "netkey: %s\n", err); 31*37da2899SCharles.Forsyth raise "fail:error"; 32*37da2899SCharles.Forsyth } 33*37da2899SCharles.Forsyth if(pw != nil) 34*37da2899SCharles.Forsyth while((chal := readconsline("challenge: ", 0).t0) != nil) 35*37da2899SCharles.Forsyth sys->print("response: %s\n", netcrypt(passtokey(pw), string int chal)); 36*37da2899SCharles.Forsyth} 37*37da2899SCharles.Forsyth 38*37da2899SCharles.Forsythreadconsline(prompt: string, raw: int): (string, string) 39*37da2899SCharles.Forsyth{ 40*37da2899SCharles.Forsyth fd := sys->open("/dev/cons", Sys->ORDWR); 41*37da2899SCharles.Forsyth if(fd == nil) 42*37da2899SCharles.Forsyth return (nil, sys->sprint("can't open cons: %r")); 43*37da2899SCharles.Forsyth sys->fprint(fd, "%s", prompt); 44*37da2899SCharles.Forsyth fdctl: ref Sys->FD; 45*37da2899SCharles.Forsyth if(raw){ 46*37da2899SCharles.Forsyth fdctl = sys->open("/dev/consctl", sys->OWRITE); 47*37da2899SCharles.Forsyth if(fdctl == nil || sys->fprint(fdctl, "rawon") < 0) 48*37da2899SCharles.Forsyth return (nil, sys->sprint("can't open consctl: %r")); 49*37da2899SCharles.Forsyth } 50*37da2899SCharles.Forsyth line := array[256] of byte; 51*37da2899SCharles.Forsyth o := 0; 52*37da2899SCharles.Forsyth err: string; 53*37da2899SCharles.Forsyth buf := array[1] of byte; 54*37da2899SCharles.Forsyth Read: 55*37da2899SCharles.Forsyth while((r := sys->read(fd, buf, len buf)) > 0){ 56*37da2899SCharles.Forsyth c := int buf[0]; 57*37da2899SCharles.Forsyth case c { 58*37da2899SCharles.Forsyth 16r7F => 59*37da2899SCharles.Forsyth err = "interrupt"; 60*37da2899SCharles.Forsyth break Read; 61*37da2899SCharles.Forsyth '\b' => 62*37da2899SCharles.Forsyth if(o > 0) 63*37da2899SCharles.Forsyth o--; 64*37da2899SCharles.Forsyth '\n' or '\r' or 16r4 => 65*37da2899SCharles.Forsyth break Read; 66*37da2899SCharles.Forsyth * => 67*37da2899SCharles.Forsyth if(o > len line){ 68*37da2899SCharles.Forsyth err = "line too long"; 69*37da2899SCharles.Forsyth break Read; 70*37da2899SCharles.Forsyth } 71*37da2899SCharles.Forsyth line[o++] = byte c; 72*37da2899SCharles.Forsyth } 73*37da2899SCharles.Forsyth } 74*37da2899SCharles.Forsyth if(r < 0) 75*37da2899SCharles.Forsyth err = sys->sprint("can't read cons: %r"); 76*37da2899SCharles.Forsyth if(raw){ 77*37da2899SCharles.Forsyth sys->fprint(fdctl, "rawoff"); 78*37da2899SCharles.Forsyth sys->fprint(fd, "\n"); 79*37da2899SCharles.Forsyth } 80*37da2899SCharles.Forsyth if(err != nil) 81*37da2899SCharles.Forsyth return (nil, err); 82*37da2899SCharles.Forsyth return (string line[0:o], err); 83*37da2899SCharles.Forsyth} 84*37da2899SCharles.Forsyth 85*37da2899SCharles.Forsyth# 86*37da2899SCharles.Forsyth# duplicates auth9 but keeps this self-contained 87*37da2899SCharles.Forsyth# 88*37da2899SCharles.Forsyth 89*37da2899SCharles.Forsythnetcrypt(key: array of byte, chal: string): string 90*37da2899SCharles.Forsyth{ 91*37da2899SCharles.Forsyth buf := array[8] of {* => byte 0}; 92*37da2899SCharles.Forsyth a := array of byte chal; 93*37da2899SCharles.Forsyth if(len a > 7) 94*37da2899SCharles.Forsyth a = a[0:7]; 95*37da2899SCharles.Forsyth buf[0:] = a; 96*37da2899SCharles.Forsyth encrypt(key, buf, len buf); 97*37da2899SCharles.Forsyth return sys->sprint("%.2ux%.2ux%.2ux%.2ux", int buf[0], int buf[1], int buf[2], int buf[3]); 98*37da2899SCharles.Forsyth} 99*37da2899SCharles.Forsyth 100*37da2899SCharles.Forsythpasstokey(p: string): array of byte 101*37da2899SCharles.Forsyth{ 102*37da2899SCharles.Forsyth a := array of byte p; 103*37da2899SCharles.Forsyth n := len a; 104*37da2899SCharles.Forsyth if(n >= ANAMELEN) 105*37da2899SCharles.Forsyth n = ANAMELEN-1; 106*37da2899SCharles.Forsyth buf := array[ANAMELEN] of {* => byte ' '}; 107*37da2899SCharles.Forsyth buf[0:] = a[0:n]; 108*37da2899SCharles.Forsyth buf[n] = byte 0; 109*37da2899SCharles.Forsyth key := array[DESKEYLEN] of {* => byte 0}; 110*37da2899SCharles.Forsyth t := 0; 111*37da2899SCharles.Forsyth for(;;){ 112*37da2899SCharles.Forsyth for(i := 0; i < DESKEYLEN; i++) 113*37da2899SCharles.Forsyth key[i] = byte ((int buf[t+i] >> i) + (int buf[t+i+1] << (8 - (i+1)))); 114*37da2899SCharles.Forsyth if(n <= 8) 115*37da2899SCharles.Forsyth return key; 116*37da2899SCharles.Forsyth n -= 8; 117*37da2899SCharles.Forsyth t += 8; 118*37da2899SCharles.Forsyth if(n < 8){ 119*37da2899SCharles.Forsyth t -= 8 - n; 120*37da2899SCharles.Forsyth n = 8; 121*37da2899SCharles.Forsyth } 122*37da2899SCharles.Forsyth encrypt(key, buf[t:], 8); 123*37da2899SCharles.Forsyth } 124*37da2899SCharles.Forsyth} 125*37da2899SCharles.Forsyth 126*37da2899SCharles.Forsythparity := array[] of { 127*37da2899SCharles.Forsyth byte 16r01, byte 16r02, byte 16r04, byte 16r07, byte 16r08, byte 16r0b, byte 16r0d, byte 16r0e, 128*37da2899SCharles.Forsyth byte 16r10, byte 16r13, byte 16r15, byte 16r16, byte 16r19, byte 16r1a, byte 16r1c, byte 16r1f, 129*37da2899SCharles.Forsyth byte 16r20, byte 16r23, byte 16r25, byte 16r26, byte 16r29, byte 16r2a, byte 16r2c, byte 16r2f, 130*37da2899SCharles.Forsyth byte 16r31, byte 16r32, byte 16r34, byte 16r37, byte 16r38, byte 16r3b, byte 16r3d, byte 16r3e, 131*37da2899SCharles.Forsyth byte 16r40, byte 16r43, byte 16r45, byte 16r46, byte 16r49, byte 16r4a, byte 16r4c, byte 16r4f, 132*37da2899SCharles.Forsyth byte 16r51, byte 16r52, byte 16r54, byte 16r57, byte 16r58, byte 16r5b, byte 16r5d, byte 16r5e, 133*37da2899SCharles.Forsyth byte 16r61, byte 16r62, byte 16r64, byte 16r67, byte 16r68, byte 16r6b, byte 16r6d, byte 16r6e, 134*37da2899SCharles.Forsyth byte 16r70, byte 16r73, byte 16r75, byte 16r76, byte 16r79, byte 16r7a, byte 16r7c, byte 16r7f, 135*37da2899SCharles.Forsyth byte 16r80, byte 16r83, byte 16r85, byte 16r86, byte 16r89, byte 16r8a, byte 16r8c, byte 16r8f, 136*37da2899SCharles.Forsyth byte 16r91, byte 16r92, byte 16r94, byte 16r97, byte 16r98, byte 16r9b, byte 16r9d, byte 16r9e, 137*37da2899SCharles.Forsyth byte 16ra1, byte 16ra2, byte 16ra4, byte 16ra7, byte 16ra8, byte 16rab, byte 16rad, byte 16rae, 138*37da2899SCharles.Forsyth byte 16rb0, byte 16rb3, byte 16rb5, byte 16rb6, byte 16rb9, byte 16rba, byte 16rbc, byte 16rbf, 139*37da2899SCharles.Forsyth byte 16rc1, byte 16rc2, byte 16rc4, byte 16rc7, byte 16rc8, byte 16rcb, byte 16rcd, byte 16rce, 140*37da2899SCharles.Forsyth byte 16rd0, byte 16rd3, byte 16rd5, byte 16rd6, byte 16rd9, byte 16rda, byte 16rdc, byte 16rdf, 141*37da2899SCharles.Forsyth byte 16re0, byte 16re3, byte 16re5, byte 16re6, byte 16re9, byte 16rea, byte 16rec, byte 16ref, 142*37da2899SCharles.Forsyth byte 16rf1, byte 16rf2, byte 16rf4, byte 16rf7, byte 16rf8, byte 16rfb, byte 16rfd, byte 16rfe, 143*37da2899SCharles.Forsyth}; 144*37da2899SCharles.Forsyth 145*37da2899SCharles.Forsythdes56to64(k56: array of byte): array of byte 146*37da2899SCharles.Forsyth{ 147*37da2899SCharles.Forsyth k64 := array[8] of byte; 148*37da2899SCharles.Forsyth hi := (int k56[0]<<24)|(int k56[1]<<16)|(int k56[2]<<8)|int k56[3]; 149*37da2899SCharles.Forsyth lo := (int k56[4]<<24)|(int k56[5]<<16)|(int k56[6]<<8); 150*37da2899SCharles.Forsyth 151*37da2899SCharles.Forsyth k64[0] = parity[(hi>>25)&16r7f]; 152*37da2899SCharles.Forsyth k64[1] = parity[(hi>>18)&16r7f]; 153*37da2899SCharles.Forsyth k64[2] = parity[(hi>>11)&16r7f]; 154*37da2899SCharles.Forsyth k64[3] = parity[(hi>>4)&16r7f]; 155*37da2899SCharles.Forsyth k64[4] = parity[((hi<<3)|int ((big lo & big 16rFFFFFFFF)>>29))&16r7f]; # watch the sign extension 156*37da2899SCharles.Forsyth k64[5] = parity[(lo>>22)&16r7f]; 157*37da2899SCharles.Forsyth k64[6] = parity[(lo>>15)&16r7f]; 158*37da2899SCharles.Forsyth k64[7] = parity[(lo>>8)&16r7f]; 159*37da2899SCharles.Forsyth return k64; 160*37da2899SCharles.Forsyth} 161*37da2899SCharles.Forsyth 162*37da2899SCharles.Forsythencrypt(key: array of byte, data: array of byte, n: int) 163*37da2899SCharles.Forsyth{ 164*37da2899SCharles.Forsyth ds := keyring->dessetup(des56to64(key), nil); 165*37da2899SCharles.Forsyth keyring->desecb(ds, data, n, Keyring->Encrypt); 166*37da2899SCharles.Forsyth} 167