diff options
48 files changed, 490 insertions, 2377 deletions
@@ -1,5 +1,3 @@ -20110117 - emu/Nt/ipif.c changed to work with ipv6 interface changes 20110116 add Plan9/arm support [provided by richard miller] 20110110 diff --git a/appl/cmd/auth/dsagen.b b/appl/cmd/auth/dsagen.b index 51b50a12..3e24df2f 100644 --- a/appl/cmd/auth/dsagen.b +++ b/appl/cmd/auth/dsagen.b @@ -5,12 +5,9 @@ include "sys.m"; include "draw.m"; -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; +include "keyring.m"; + kr: Keyring; + IPint, DSAsk, DSApk, DSAsig: import kr; include "arg.m"; @@ -22,8 +19,7 @@ Dsagen: module init(nil: ref Draw->Context, args: list of string) { sys = load Sys Sys->PATH; - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; + kr = load Keyring Keyring->PATH; arg := load Arg Arg->PATH; arg->init(args); @@ -41,7 +37,7 @@ init(nil: ref Draw->Context, args: list of string) arg->usage(); arg = nil; - sk := crypt->dsagen(nil); + sk := DSAsk.gen(nil); if(tag != nil) tag = " "+tag; s := add("p", sk.pk.p); diff --git a/appl/cmd/auth/factotum/proto/rsa.b b/appl/cmd/auth/factotum/proto/rsa.b index 8af64578..24dcef43 100644 --- a/appl/cmd/auth/factotum/proto/rsa.b +++ b/appl/cmd/auth/factotum/proto/rsa.b @@ -1,10 +1,6 @@ implement Authproto; -# SSH RSA authentication -# -# this version is compatible with Plan 9 factotum -# Plan 9 port's factotum works differently, and eventually -# we'll support both (the role= attribute distinguishes the cases), but not today +# SSH RSA authentication. # # Client protocol: # read public key @@ -20,38 +16,35 @@ include "sys.m"; include "draw.m"; -include "ipints.m"; - ipints: IPints; - IPint: import ipints; -include "crypt.m"; - crypt: Crypt; - SK, PK: import crypt; +include "keyring.m"; + kr: Keyring; + IPint, RSAsk, RSApk: import kr; include "../authio.m"; authio: Authio; Aattr, Aval, Aquery: import Authio; - Attr, IO, Key: import authio; + Attr, IO, Key, Authinfo: import authio; eqbytes, memrandom: import authio; - findattrval: import authio; + lookattrval: import authio; init(f: Authio): string { authio = f; sys = load Sys Sys->PATH; - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; + kr = load Keyring Keyring->PATH; +# base16 = load Encoding Encoding->BASE16PATH; return nil; } interaction(attrs: list of ref Attr, io: ref IO): string { - role := findattrval(attrs, "role"); + role := lookattrval(attrs, "role"); if(role == nil) return "role not specified"; if(role != "client") return "only client role supported"; - sk: ref SK.RSA; + sk: ref RSAsk; keys: list of ref Key; err: string; for(;;){ @@ -74,7 +67,7 @@ interaction(attrs: list of ref Attr, io: ref IO): string io.error("invalid challenge value"); continue; } - m := crypt->rsadecrypt(sk, chal); + m := sk.decrypt(chal); b := array of byte m.iptostr(16); io.write(b, len b); io.done(nil); @@ -96,33 +89,30 @@ waitread(io: ref IO) Badkey: exception(string); -kv(key: ref Key, name: string): ref IPint raises Badkey +ipint(attrs: list of ref Attr, name: string): ref IPint raises Badkey { - if(name[0] == '!') - a := authio->findattrval(key.secrets, name); - else - a = authio->findattrval(key.attrs, name); - if(a == nil) + s := lookattrval(attrs, name); + if(s == nil) raise Badkey("missing attribute "+name); - m := IPint.strtoip(a, 16); + m := IPint.strtoip(s, 16); if(m == nil) - raise Badkey("bad value for "+name); + raise Badkey("invalid value for "+name); return m; } -keytorsa(k: ref Key): (ref SK.RSA, string) +keytorsa(k: ref Key): (ref RSAsk, string) { - sk := ref SK.RSA; - sk.pk = ref PK.RSA; + sk := ref RSAsk; + sk.pk = ref RSApk; { - sk.pk.ek = kv(k, "ek"); - sk.pk.n = kv(k, "n"); - sk.dk = kv(k, "!dk"); - sk.p = kv(k, "!p"); - sk.q = kv(k, "!q"); - sk.kp = kv(k, "!kp"); - sk.kq = kv(k, "!kq"); - sk.c2 = kv(k, "!c2"); + sk.pk.ek = ipint(k.attrs, "ek"); + sk.pk.n = ipint(k.attrs, "n"); + sk.dk = ipint(k.secrets, "!dk"); + sk.p = ipint(k.secrets, "!p"); + sk.q = ipint(k.secrets, "!q"); + sk.kp = ipint(k.secrets, "!kp"); + sk.kq = ipint(k.secrets, "!kq"); + sk.c2 = ipint(k.secrets, "!c2"); }exception e{ Badkey => return (nil, "rsa key "+e); diff --git a/appl/cmd/auth/getpk.b b/appl/cmd/auth/getpk.b index e2273d17..24283340 100644 --- a/appl/cmd/auth/getpk.b +++ b/appl/cmd/auth/getpk.b @@ -3,14 +3,10 @@ include "sys.m"; sys: Sys; include "draw.m"; include "arg.m"; -include "ipints.m"; -include "crypt.m"; - crypt: Crypt; -include "oldauth.m"; - oldauth: Oldauth; +include "keyring.m"; + keyring: Keyring; -Getpk: module -{ +Getpk: module { init: fn(nil: ref Draw->Context, argv: list of string); }; @@ -23,18 +19,14 @@ badmodule(p: string) init(nil: ref Draw->Context, argv: list of string) { sys = load Sys Sys->PATH; - crypt = load Crypt Crypt->PATH; - if(crypt == nil) - badmodule(Crypt->PATH); - oldauth = load Oldauth Oldauth->PATH; - if(oldauth == nil) - badmodule(Oldauth->PATH); - oldauth->init(); + keyring = load Keyring Keyring->PATH; + if(keyring == nil) + badmodule(Keyring->PATH); arg := load Arg Arg->PATH; if(arg == nil) badmodule(Arg->PATH); arg->init(argv); - arg->setusage("getpk [-asu] file..."); + arg->setusage("usage: getpk [-asu] file..."); aflag := 0; sflag := 0; uflag := 0; @@ -55,7 +47,7 @@ init(nil: ref Draw->Context, argv: list of string) arg->usage(); multi := len argv > 1; for(; argv != nil; argv = tl argv){ - info := oldauth->readauthinfo(hd argv); + info := keyring->readauthinfo(hd argv); if(info == nil){ sys->fprint(sys->fildes(2), "getpk: cannot read %s: %r\n", hd argv); continue; @@ -63,13 +55,13 @@ init(nil: ref Draw->Context, argv: list of string) pk := info.mypk; if(sflag) pk = info.spk; - s := oldauth->pktostr(pk, info.owner); + s := keyring->pktostr(pk); if(!aflag) s = hex(hash(s)); if(multi) s = hd argv + ": " + s; if(uflag) - s += " " + info.owner; + s += " " + pk.owner; sys->print("%s\n", s); } } @@ -77,8 +69,8 @@ init(nil: ref Draw->Context, argv: list of string) hash(s: string): array of byte { d := array of byte s; - digest := array[Crypt->SHA1dlen] of byte; - crypt->sha1(d, len d, digest, nil); + digest := array[Keyring->SHA1dlen] of byte; + keyring->sha1(d, len d, digest, nil); return digest; } diff --git a/appl/cmd/auth/rsagen.b b/appl/cmd/auth/rsagen.b index 48fcba6d..a1a4477c 100644 --- a/appl/cmd/auth/rsagen.b +++ b/appl/cmd/auth/rsagen.b @@ -5,12 +5,8 @@ include "sys.m"; include "draw.m"; -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; +include "keyring.m"; + kr: Keyring; include "arg.m"; @@ -22,8 +18,7 @@ Rsagen: module init(nil: ref Draw->Context, args: list of string) { sys = load Sys Sys->PATH; - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; + kr = load Keyring Keyring->PATH; arg := load Arg Arg->PATH; arg->init(args); @@ -48,31 +43,34 @@ init(nil: ref Draw->Context, args: list of string) arg->usage(); arg = nil; - sk := crypt->rsagen(nbits, 6, 0); + sk := kr->genSK("rsa", "", nbits); if(sk == nil) error("unable to generate key"); + s := kr->sktoattr(sk); + # need to fix the attr interface so the following isn't needed: + s = skip(s, "alg"); + s = skip(s, "owner"); if(tag != nil) tag = " "+tag; - s := add("ek", sk.pk.ek); - s += add("n", sk.pk.n); - s += add("!dk", sk.dk); - s += add("!p", sk.p); - s += add("!q", sk.q); - s += add("!kp", sk.kp); - s += add("!kq", sk.kq); - s += add("!c2", sk.c2); - a := sys->aprint("key proto=rsa%s size=%d%s\n", tag, sk.pk.n.bits(), s); + a := sys->aprint("key proto=rsa%s size=%d %s\n", tag, nbits, s); if(sys->write(sys->fildes(1), a, len a) != len a) error(sys->sprint("error writing key: %r")); } -error(s: string) +skip(s: string, attr: string): string { - sys->fprint(sys->fildes(2), "rsagen: %s\n", s); - raise "fail:error"; + for(i := 0; i < len s && s[i] != ' '; i++) + {} + if(i >= len s) + return s; + (nf, fld) := sys->tokenize(s[0:i], "="); + if(nf == 2 && hd fld == attr) + s = s[i+1:]; + return s; } -add(name: string, b: ref IPint): string +error(s: string) { - return " "+name+"="+b.iptostr(16); + sys->fprint(sys->fildes(2), "rsagen: %s\n", s); + raise "fail:error"; } diff --git a/appl/cmd/auth/signer.b b/appl/cmd/auth/signer.b index b27a719c..b3f4669d 100644 --- a/appl/cmd/auth/signer.b +++ b/appl/cmd/auth/signer.b @@ -5,20 +5,10 @@ include "sys.m"; include "draw.m"; -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; - -include "oldauth.m"; - oldauth: Oldauth; - -include "msgio.m"; - msgio: Msgio; - include "keyring.m"; + kr: Keyring; + IPint: import kr; + include "security.m"; random: Random; @@ -39,12 +29,7 @@ init(nil: ref Draw->Context, nil: list of string) { sys = load Sys Sys->PATH; random = load Random Random->PATH; - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; - oldauth = load Oldauth Oldauth->PATH; - oldauth->init(); - msgio = load Msgio Msgio->PATH; - msgio->init(); + kr = load Keyring Keyring->PATH; stdin = sys->fildes(0); stdout = sys->fildes(1); @@ -70,75 +55,75 @@ sign(): string return "can't read key"; # send public part to client - mypkbuf := array of byte oldauth->pktostr(crypt->sktopk(info.mysk), info.owner); - msgio->sendmsg(stdout, mypkbuf, len mypkbuf); + mypkbuf := array of byte kr->pktostr(kr->sktopk(info.mysk)); + kr->sendmsg(stdout, mypkbuf, len mypkbuf); alphabuf := array of byte info.alpha.iptob64(); - msgio->sendmsg(stdout, alphabuf, len alphabuf); + kr->sendmsg(stdout, alphabuf, len alphabuf); pbuf := array of byte info.p.iptob64(); - msgio->sendmsg(stdout, pbuf, len pbuf); + kr->sendmsg(stdout, pbuf, len pbuf); # get client's public key - hisPKbuf := msgio->getmsg(stdin); + hisPKbuf := kr->getmsg(stdin); if(hisPKbuf == nil) return "caller hung up"; - (hisPK, hisname) := oldauth->strtopk(string hisPKbuf); + hisPK := kr->strtopk(string hisPKbuf); if(hisPK == nil) return "illegal caller PK"; # hash, sign, and blind - state := crypt->sha1(hisPKbuf, len hisPKbuf, nil, nil); - cert := oldauth->sign(info.mysk, info.owner, 0, state, "sha1"); + state := kr->sha1(hisPKbuf, len hisPKbuf, nil, nil); + cert := kr->sign(info.mysk, 0, state, "sha1"); # sanity clause - state = crypt->sha1(hisPKbuf, len hisPKbuf, nil, nil); - if(oldauth->verify(info.mypk, cert, state) == 0) + state = kr->sha1(hisPKbuf, len hisPKbuf, nil, nil); + if(kr->verify(info.mypk, cert, state) == 0) return "bad signer certificate"; - certbuf := array of byte oldauth->certtostr(cert); + certbuf := array of byte kr->certtostr(cert); blind := random->randombuf(random->ReallyRandom, len certbuf); for(i := 0; i < len blind; i++) certbuf[i] = certbuf[i] ^ blind[i]; # sum PKs and blinded certificate - state = crypt->md5(mypkbuf, len mypkbuf, nil, nil); - crypt->md5(hisPKbuf, len hisPKbuf, nil, state); + state = kr->md5(mypkbuf, len mypkbuf, nil, nil); + kr->md5(hisPKbuf, len hisPKbuf, nil, state); digest := array[Keyring->MD5dlen] of byte; - crypt->md5(certbuf, len certbuf, digest, state); + kr->md5(certbuf, len certbuf, digest, state); # save sum and blinded cert in a file - file := "signed/"+hisname; + file := "signed/"+hisPK.owner; fd := sys->create(file, Sys->OWRITE, 8r600); if(fd == nil) return "can't create "+file+sys->sprint(": %r"); - if(msgio->sendmsg(fd, blind, len blind) < 0 || - msgio->sendmsg(fd, digest, len digest) < 0){ + if(kr->sendmsg(fd, blind, len blind) < 0 || + kr->sendmsg(fd, digest, len digest) < 0){ sys->remove(file); return "can't write "+file+sys->sprint(": %r"); } # send blinded cert to client - msgio->sendmsg(stdout, certbuf, len certbuf); + kr->sendmsg(stdout, certbuf, len certbuf); return nil; } -signerkey(filename: string): ref Oldauth->Authinfo +signerkey(filename: string): ref Keyring->Authinfo { - info := oldauth->readauthinfo(filename); + info := kr->readauthinfo(filename); if(info != nil) return info; # generate a local key - info = ref Oldauth->Authinfo; - info.mysk = crypt->genSK("elgamal", PKmodlen); - info.mypk = crypt->sktopk(info.mysk); - info.spk = crypt->sktopk(info.mysk); - myPKbuf := array of byte oldauth->pktostr(info.mypk, "*"); - state := crypt->sha1(myPKbuf, len myPKbuf, nil, nil); - info.cert = oldauth->sign(info.mysk, "*", 0, state, "sha1"); - (info.alpha, info.p) = crypt->dhparams(DHmodlen); - - if(oldauth->writeauthinfo(filename, info) < 0){ + info = ref Keyring->Authinfo; + info.mysk = kr->genSK("elgamal", "*", PKmodlen); + info.mypk = kr->sktopk(info.mysk); + info.spk = kr->sktopk(info.mysk); + myPKbuf := array of byte kr->pktostr(info.mypk); + state := kr->sha1(myPKbuf, len myPKbuf, nil, nil); + info.cert = kr->sign(info.mysk, 0, state, "sha1"); + (info.alpha, info.p) = kr->dhparams(DHmodlen); + + if(kr->writeauthinfo(filename, info) < 0){ sys->fprint(stderr, "can't write signerkey file: %r\n"); return nil; } diff --git a/appl/cmd/auth/verify.b b/appl/cmd/auth/verify.b index 91fe1a86..d829a76c 100644 --- a/appl/cmd/auth/verify.b +++ b/appl/cmd/auth/verify.b @@ -3,8 +3,8 @@ implement Verify; include "sys.m"; sys: Sys; -include "msgio.m"; - msgio: Msgio; +include "keyring.m"; + kr: Keyring; include "draw.m"; @@ -25,8 +25,7 @@ pro := array[] of { init(nil: ref Draw->Context, args: list of string) { sys = load Sys Sys->PATH; - msgio = load Msgio Msgio->PATH; - msgio->init(); + kr = load Keyring Keyring->PATH; stdin = sys->fildes(0); stderr = sys->fildes(2); @@ -51,8 +50,8 @@ init(nil: ref Draw->Context, args: list of string) sys->fprint(stderr, "signer: can't open %s: %r\n", file); raise "fail:no certificate"; } - certbuf := msgio->getmsg(fd); - digest := msgio->getmsg(fd); + certbuf := kr->getmsg(fd); + digest := kr->getmsg(fd); if(digest == nil || certbuf == nil){ sys->fprint(stderr, "signer: can't read %s: %r\n", file); raise "fail:bad certificate"; @@ -79,7 +78,7 @@ init(nil: ref Draw->Context, args: list of string) sys->fprint(stderr, "signer: can't create %s: %r\n", nfile); raise "fail:create"; } - if(msgio->sendmsg(fd, certbuf, len certbuf) < 0){ + if(kr->sendmsg(fd, certbuf, len certbuf) < 0){ sys->fprint(stderr, "signer: can't write %s: %r\n", nfile); raise "fail:write"; } diff --git a/appl/cmd/cpu.b b/appl/cmd/cpu.b index 8acab430..75728e57 100644 --- a/appl/cmd/cpu.b +++ b/appl/cmd/cpu.b @@ -5,9 +5,6 @@ include "sys.m"; stderr: ref Sys->FD; include "draw.m"; Context: import Draw; - -include "dial.m"; - include "string.m"; str: String; include "arg.m"; @@ -53,9 +50,6 @@ init(nil: ref Context, argv: list of string) kr := load Keyring Keyring->PATH; if (kr == nil) badmodule(Keyring->PATH); - dial := load Dial Dial->PATH; - if(dial == nil) badmodule(Dial->PATH); - arg->init(argv); alg := ""; while ((opt := arg->opt()) != 0) { @@ -85,7 +79,7 @@ init(nil: ref Context, argv: list of string) user := getuser(); kd := "/usr/" + user + "/keyring/"; - cert := kd + dial->netmkaddr(mach, "tcp", ""); + cert := kd + netmkaddr(mach, "tcp", ""); if (!exists(cert)) { cert = kd + "default"; if (!exists(cert)) { @@ -98,8 +92,8 @@ init(nil: ref Context, argv: list of string) if(!exists("/dev/draw/new")) sys->bind("#d", "/dev", Sys->MBEFORE); - c := dial->dial(dial->netmkaddr(mach, "net", "rstyx"), nil); - if(c == nil){ + (ok, c) := sys->dial(netmkaddr(mach, "net", "rstyx"), nil); + if(ok < 0){ sys->fprint(stderr, "Error: cpu: dial: %r\n"); return; } @@ -157,3 +151,18 @@ getuser(): string return string buf[0:n]; } + +netmkaddr(addr, net, svc: string): string +{ + if(net == nil) + net = "net"; + (n, nil) := sys->tokenize(addr, "!"); + if(n <= 1){ + if(svc== nil) + return sys->sprint("%s!%s", net, addr); + return sys->sprint("%s!%s!%s", net, addr, svc); + } + if(svc == nil || n > 2) + return addr; + return sys->sprint("%s!%s", addr, svc); +} diff --git a/appl/cmd/dial.b b/appl/cmd/dial.b index 8821b49a..c562a570 100644 --- a/appl/cmd/dial.b +++ b/appl/cmd/dial.b @@ -1,4 +1,4 @@ -implement Dialcmd; +implement Dial; include "sys.m"; sys: Sys; include "draw.m"; @@ -7,12 +7,11 @@ include "keyring.m"; keyring: Keyring; include "security.m"; auth: Auth; -include "dial.m"; include "sh.m"; sh: Sh; Context: import sh; -Dialcmd: module { +Dial: module { init: fn(nil: ref Draw->Context, argv: list of string); }; @@ -36,9 +35,6 @@ init(drawctxt: ref Draw->Context, argv: list of string) arg := load Arg Arg->PATH; if (arg == nil) badmodule(Arg->PATH); - dial := load Dial Dial->PATH; - if(dial == nil) - badmodule(Dial->PATH); sh = load Sh Sh->PATH; if (sh == nil) badmodule(Sh->PATH); @@ -91,8 +87,8 @@ init(drawctxt: ref Draw->Context, argv: list of string) } } - c := dial->dial(addr, nil); - if (c == nil) { + (ok, c) := sys->dial(addr, nil); + if (ok == -1) { sys->fprint(stderr(), "dial: cannot dial %s:: %r\n", addr); raise "fail:errors"; } diff --git a/appl/cmd/listen.b b/appl/cmd/listen.b index 5a06892d..25869223 100644 --- a/appl/cmd/listen.b +++ b/appl/cmd/listen.b @@ -7,8 +7,6 @@ include "keyring.m"; keyring: Keyring; include "security.m"; auth: Auth; -include "dial.m"; - dial: Dial; include "sh.m"; sh: Sh; Context: import sh; @@ -33,9 +31,6 @@ init(drawctxt: ref Draw->Context, argv: list of string) auth = load Auth Auth->PATH; if (auth == nil) badmodule(Auth->PATH); - dial = load Dial Dial->PATH; - if (dial == nil) - badmodule(Dial->PATH); sh = load Sh Sh->PATH; if (sh == nil) badmodule(Sh->PATH); @@ -125,8 +120,8 @@ listen1(drawctxt: ref Draw->Context, addr: string, argv: list of string, sys->pctl(Sys->FORKFD, nil); ctxt := Context.new(drawctxt); - acon := dial->announce(addr); - if (acon == nil) { + (ok, acon) := sys->announce(addr); + if (ok == -1) { sys->fprint(stderr(), "listen: failed to announce on '%s': %r\n", addr); sync <-= "cannot announce"; exit; @@ -151,15 +146,15 @@ listen1(drawctxt: ref Draw->Context, addr: string, argv: list of string, } sync <-= nil; - listench := chan of ref Dial->Connection; - authch := chan of (string, ref Dial->Connection); + listench := chan of (int, Sys->Connection); + authch := chan of (string, Sys->Connection); spawn listener(listench, acon, addr); for (;;) { user := ""; - ccon: ref Dial->Connection; + ccon: Sys->Connection; alt { - c := <-listench => - if (c == nil){ + (lok, c) := <-listench => + if (lok == -1){ sync <-= "listen"; exit; } @@ -187,13 +182,13 @@ listen1(drawctxt: ref Draw->Context, addr: string, argv: list of string, } } -listener(listench: chan of ref Dial->Connection, c: ref Dial->Connection, addr: string) +listener(listench: chan of (int, Sys->Connection), c: Sys->Connection, addr: string) { for (;;) { - nc := dial->listen(c); - if (nc == nil) { + (ok, nc) := sys->listen(c); + if (ok == -1) { sys->fprint(stderr(), "listen: listen error on '%s': %r\n", addr); - listench <-= nc; + listench <-= (-1, nc); exit; } if (verbose) @@ -205,13 +200,13 @@ listener(listench: chan of ref Dial->Connection, c: ref Dial->Connection, addr: else{ if(nc.cfd != nil) sys->fprint(nc.cfd, "keepalive"); - listench <-= nc; + listench <-= (ok, nc); } } } -authenticator(authch: chan of (string, ref Dial->Connection), - c: ref Dial->Connection, algs: list of string, addr: string) +authenticator(authch: chan of (string, Sys->Connection), + c: Sys->Connection, algs: list of string, addr: string) { err: string; (c.dfd, err) = auth->server(algs, serverkey, c.dfd, 0); diff --git a/appl/cmd/sh/mpexpr.b b/appl/cmd/sh/mpexpr.b index 0aaf6cda..682c01e8 100644 --- a/appl/cmd/sh/mpexpr.b +++ b/appl/cmd/sh/mpexpr.b @@ -3,9 +3,9 @@ implement Shellbuiltin; include "sys.m"; sys: Sys; include "draw.m"; -include "ipints.m"; - ipints: IPints; - IPint: import ipints; +include "keyring.m"; + keyring: Keyring; + IPint: import keyring; include "sh.m"; sh: Sh; Listnode, Context: import sh; @@ -17,7 +17,7 @@ One: Big; initbuiltin(ctxt: ref Context, shmod: Sh): string { sys = load Sys Sys->PATH; - ipints = load IPints IPints->PATH; + keyring = load Keyring Keyring->PATH; sh = shmod; myself = load Shellbuiltin "$self"; if (myself == nil) @@ -233,7 +233,7 @@ oper(ctxt: ref Context, args: list of Big, op, lastop, lastn: int, BITS => r = mki(n1.bits()); EXPMOD => r = n1.expmod(n2, n3); EXP => r = n1.expmod(n2, nil); - RAND => r = IPint.random(n1.iptoint()); + RAND => r = IPint.random(0, n1.iptoint()); INVERT => r = n1.invert(n2); } return r :: stk; diff --git a/appl/cmd/spki/verify.b b/appl/cmd/spki/verify.b index daf563ac..9eab6b41 100644 --- a/appl/cmd/spki/verify.b +++ b/appl/cmd/spki/verify.b @@ -11,11 +11,9 @@ include "sys.m"; include "draw.m"; -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; +include "keyring.m"; + kr: Keyring; + IPint: import kr; include "bufio.m"; bufio: Bufio; @@ -46,7 +44,7 @@ debug := 0; init(nil: ref Draw->Context, args: list of string) { sys = load Sys Sys->PATH; - ipints = load IPints IPints->PATH; + kr = load Keyring Keyring->PATH; bufio = load Bufio Bufio->PATH; sexprs = load Sexprs Sexprs->PATH; spki = load SPKI SPKI->PATH; diff --git a/appl/cmd/ssh/authpassword.b b/appl/cmd/ssh/authpassword.b deleted file mode 100644 index 1a149117..00000000 --- a/appl/cmd/ssh/authpassword.b +++ /dev/null @@ -1,68 +0,0 @@ -implement Auth; - -include "sys.m"; - sys: Sys; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; # TO DO: needed to avoid compiler error - -include "factotum.m"; - factotum: Factotum; - -include "sshio.m"; - sshio: Sshio; - Conn, Msg: import sshio; - -id(): int -{ - return SSH_AUTH_PASSWORD; -} - -init(mod: Sshio) -{ - sys = load Sys Sys->PATH; - sshio = mod; -} - -firstmsg(): int -{ - return SSH_CMSG_AUTH_PASSWORD; -} - -authsrv(c: ref Conn, m: ref Msg): ref AuthInfo -{ - pass := m.getstring(); -# return auth_userpasswd(c.user, pass); - return ref AuthInfo(c.user, nil); # TO DO: -} - -auth(c: ref Conn): int -{ - if(factotum == nil) - factotum = load Factotum Factotum->PATH; - (user, pass) := factotum->getuserpasswd(sys->sprint("proto=pass service=ssh server=%q user=%q", c.host, c.user)); - if(user == nil){ - sshio->debug(DBG_AUTH, "getuserpasswd failed"); - return -1; - } - - sshio->debug(DBG_AUTH, "try using password from factotum\n"); - m := Msg.mk(SSH_CMSG_AUTH_PASSWORD, 4+Sys->UTFmax*len pass); - m.putstring(pass); - c.out <-= m; - - m = sshio->recvmsg(c, -1); - case m.mtype { - SSH_SMSG_SUCCESS => - return 0; - SSH_SMSG_FAILURE => - return -1; - * => - sshio->badmsg(m, 0, nil); - return -1; - } -} diff --git a/appl/cmd/ssh/authrsa.b b/appl/cmd/ssh/authrsa.b deleted file mode 100644 index 427355d5..00000000 --- a/appl/cmd/ssh/authrsa.b +++ /dev/null @@ -1,188 +0,0 @@ -implement Auth; - -include "sys.m"; - sys: Sys; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; - PK, SK: import crypt; - -include "factotum.m"; - factotum: Factotum; - Attr: import factotum; - findattrval: import factotum; - -include "sshio.m"; - sshio: Sshio; - Conn, Msg: import sshio; - debug: import sshio; - -id(): int -{ - return SSH_AUTH_RSA; -} - -init(mod: Sshio) -{ - sshio = mod; - sys = load Sys Sys->PATH; - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; - factotum = load Factotum Factotum->PATH; - factotum->init(); -} - -firstmsg(): int -{ - return SSH_CMSG_AUTH_RSA; -} - -authsrv(c: ref Conn, m: ref Msg): ref AuthInfo -{ - # TO DO: use factotum - hismod := m.getipint(); - if(hismod.bits() < 512){ - debug(DBG_AUTH, sys->sprint("rsa key for %s < 512 bits\n", c.user)); - return nil; - } - hispk := readpk("/keydb/ssh/"+c.user); - if(hispk == nil){ - debug(DBG_AUTH, sys->sprint("no ssh/rsa key for %s: %r\n", c.user)); - return nil; - } - if(!hispk.n.eq(hismod)){ - debug(DBG_AUTH, sys->sprint("%s rsa key doesn't match modulus\n", c.user)); - return nil; - } - # encrypt a challenge with his pk -# chal := IPint.random(256).expmod(IPint.inttoip(1), hismod); - chal := IPint.random(256); - echal := crypt->rsaencrypt(hispk, x := sshio->rsapad(chal, (hispk.n.bits()+7)/8)); -debug(DBG_AUTH, sys->sprint("padded %s\nrsa chal %s\n", x.iptostr(16), echal.iptostr(16))); - m = Msg.mk(SSH_SMSG_AUTH_RSA_CHALLENGE, 2048); - m.putipint(echal); - c.out <-= m; - - m = sshio->recvmsg(c, SSH_CMSG_AUTH_RSA_RESPONSE); - response := m.getbytes(Crypt->MD5dlen); - chalbuf := array[32+SESSIDLEN] of byte; - sshio->iptorjustbe(chal, chalbuf, 32); - debug(DBG_AUTH, sys->sprint("\trjusted %s\n", sshio->hex(chalbuf[0:32]))); - chalbuf[32:] = c.sessid[0: SESSIDLEN]; - debug(DBG_AUTH, sys->sprint("\tappend sessid %s\n", sshio->hex(chalbuf))); - expected := array[Crypt->MD5dlen] of byte; - crypt->md5(chalbuf, 32+SESSIDLEN, expected, nil); - if(sshio->eqbytes(expected, response, len expected)) - return ref AuthInfo(c.user, nil); - return nil; -} - -readpk(file: string): ref PK.RSA -{ - fd := sys->open(file, Sys->OREAD); - if(fd == nil) - return nil; - buf := array[8192] of byte; - nr := sys->readn(fd, buf, len buf); - if(nr < 0) - return nil; - attrs := factotum->parseattrs(string buf[0: nr]); - if(findattrval(attrs, "proto") != "rsa" || - (ns := findattrval(attrs, "n")) == nil || - (eks := findattrval(attrs, "ek")) == nil){ - sys->werrstr("missing rsa key attributes"); - return nil; - } - n := IPint.strtoip(ns, 16); - ek := IPint.strtoip(eks, 16); - if(n == nil || ek == nil){ - sys->werrstr("invalid rsa key values"); - return nil; - } - return ref PK.RSA(n, ek); -} - -auth(c: ref Conn): int -{ - chalbuf := array[32+SESSIDLEN] of byte; - response := array[Crypt->MD5dlen] of byte; - - debug(DBG_AUTH, "authrsa\n"); - - afd := sys->open("/mnt/factotum/rpc", Sys->ORDWR); - if(afd == nil){ - debug(DBG_AUTH, sys->sprint("open /mnt/factotum/rpc: %r\n")); - return -1; - } - s := "proto=rsa role=client"; - if(factotum->rpc(afd, "start", array of byte s).t0 != "ok"){ - debug(DBG_AUTH, sys->sprint("auth_rpc start %s failed: %r\n", s)); - return -1; - } - - debug(DBG_AUTH, "trying factotum rsa keys\n"); - for(;;){ - (tag, value) := factotum->rpc(afd, "read", nil); - if(tag != "ok") - break; - textkey := string value; - sshio->debug(DBG_AUTH, sys->sprint("try %q\n", textkey)); - mod := IPint.strtoip(textkey, 16); - m := Msg.mk(SSH_CMSG_AUTH_RSA, 16+(mod.bits()+7/8)); - m.putipint(mod); - c.out <-= m; - - m = sshio->recvmsg(c, -1); - case m.mtype { - SSH_SMSG_FAILURE => - debug(DBG_AUTH, "\tnot accepted\n"); - continue; - SSH_SMSG_AUTH_RSA_CHALLENGE => - ; - * => - sshio->badmsg(m, 0, nil); - } - chal := m.getipint(); - p := chal.iptostr(16); - debug(DBG_AUTH, sys->sprint("\tgot challenge %s\n", p)); - unpad: ref IPint; - if(factotum->rpc(afd, "write", array of byte p).t0 == "ok" && - ((tag, value) = factotum->rpc(afd, "read", nil)).t0 == "ok"){ - debug(DBG_AUTH, sys->sprint("\tfactotum said %q\n", string value)); - decr := IPint.strtoip(string value, 16); - if(decr != nil){ - debug(DBG_AUTH, sys->sprint("\tdecrypted %s\n", decr.iptostr(16))); - unpad = sshio->rsaunpad(decr); - }else - unpad = IPint.inttoip(0); - }else{ - debug(DBG_AUTH, sys->sprint("\tauth_rpc write or read failed: %r\n")); - unpad = IPint.inttoip(0); # it will fail, we'll go round again - } - debug(DBG_AUTH, sys->sprint("\tunpadded %s\n", unpad.iptostr(16))); - sshio->iptorjustbe(unpad, chalbuf, 32); -# debug(DBG_AUTH, sys->sprint("\trjusted %.*H\n", 32, chalbuf)); - chalbuf[32:] = c.sessid[0: SESSIDLEN]; -# debug(DBG_AUTH, sys->sprint("\tappend sesskey %.*H\n", 32, chalbuf)); - crypt->md5(chalbuf, 32+SESSIDLEN, response, nil); - - m = Msg.mk(SSH_CMSG_AUTH_RSA_RESPONSE, Crypt->MD5dlen); - m.putbytes(response, Crypt->MD5dlen); - c.out <-= m; - - m = sshio->recvmsg(c, -1); - case m.mtype { - SSH_SMSG_FAILURE => - ; # retry - SSH_SMSG_SUCCESS => - return 0; - * => - sshio->badmsg(m, 0, nil); - } - } - return -1; -} diff --git a/appl/cmd/ssh/authtis.b b/appl/cmd/ssh/authtis.b deleted file mode 100644 index 0fd5edd6..00000000 --- a/appl/cmd/ssh/authtis.b +++ /dev/null @@ -1,119 +0,0 @@ -implement Auth; - -# TO DO: add chal/resp to Factotum - -include "sys.m"; - sys: Sys; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; # avoid compiler error - -include "factotum.m"; - factotum: Factotum; - Attr: import factotum; - findattrval: import factotum; - -include "sshio.m"; - sshio: Sshio; - Conn, Msg: import sshio; - debug: import sshio; - -id(): int -{ - return SSH_AUTH_TIS; -} - -init(mod: Sshio) -{ - sshio = mod; - sys = load Sys Sys->PATH; - ipints = load IPints IPints->PATH; - factotum = load Factotum Factotum->PATH; - factotum->init(); -} - -firstmsg(): int -{ - return SSH_CMSG_AUTH_TIS; -} - -authsrv(conn: ref Conn, nil: ref Msg): ref AuthInfo -{ - if((c := factotum->challenge(sys->sprint("proto=p9cr user=%q role=server", conn.user))) == nil){ -# sshlog("auth_challenge failed for %s", conn.user); - return nil; - } - s := sys->sprint("Challenge: %s\nResponse: ", c.chal); - m := Msg.mk(SSH_SMSG_AUTH_TIS_CHALLENGE, 4+len s); - m.putstring(s); - conn.out <-= m; - - m = sshio->recvmsg(conn, 0); - if(m == nil) - return nil; - if(m.mtype != SSH_CMSG_AUTH_TIS_RESPONSE){ - # - # apparently you can just give up on - # this protocol and start a new one. - # - sshio->unrecvmsg(conn, m); - return nil; - } - - ai := factotum->response(c, m.getstring()); - if(ai == nil){ - debug(DBG_AUTH, sys->sprint("response rejected: %r\n")); - return nil; - } - return ref AuthInfo(ai.cuid, ai.cap); -} - -auth(c: ref Conn): int -{ - if(!c.interactive) - return -1; - - debug(DBG_AUTH, "try TIS\n"); - c.out <-= Msg.mk(SSH_CMSG_AUTH_TIS, 0); - - m := sshio->recvmsg(c, -1); - case m.mtype { - SSH_SMSG_FAILURE => - return -1; - SSH_SMSG_AUTH_TIS_CHALLENGE => - ; - * => - sshio->badmsg(m, SSH_SMSG_AUTH_TIS_CHALLENGE, nil); - } - - chal := m.getstring(); - - if((fd := sys->open("/dev/cons", Sys->ORDWR)) == nil) - sshio->error(sys->sprint("can't open /dev/cons: %r")); - - sys->fprint(fd, "TIS Authentication\n%s", chal); - resp := array[256] of byte; - n := sys->read(fd, resp, len resp); - if(n <= 0 || resp[0] == byte '\n') - return -1; - - m = Msg.mk(SSH_CMSG_AUTH_TIS_RESPONSE, 4+n); - m.put4(len resp); - m.putbytes(resp, n); - c.out <-= m; - - m = sshio->recvmsg(c, -1); - case m.mtype { - SSH_SMSG_SUCCESS => - return 0; - SSH_SMSG_FAILURE => - return -1; - * => - sshio->badmsg(m, 0, nil); - return -1; - } -} diff --git a/appl/cmd/ssh/cipher3des.b b/appl/cmd/ssh/cipher3des.b deleted file mode 100644 index e6f347f1..00000000 --- a/appl/cmd/ssh/cipher3des.b +++ /dev/null @@ -1,51 +0,0 @@ -implement Cipher; - -include "sys.m"; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; - DESstate: import crypt; - -include "sshio.m"; - -Cipherstate: adt -{ - enc: array of ref DESstate; - dec: array of ref DESstate; -}; - -cs: ref Cipherstate; - -id(): int -{ - return SSH_CIPHER_3DES; -} - -init(key: array of byte, nil: int) -{ - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; - cs = ref Cipherstate(array[3] of ref DESstate, array[3] of ref DESstate); - for(i := 0; i < 3; i++){ - cs.enc[i] = crypt->dessetup(key[i*8:], nil); - cs.dec[i] = crypt->dessetup(key[i*8:], nil); - } -} - -encrypt(buf: array of byte, nbuf: int) -{ - crypt->descbc(cs.enc[0], buf, nbuf, Crypt->Encrypt); - crypt->descbc(cs.enc[1], buf, nbuf, Crypt->Decrypt); - crypt->descbc(cs.enc[2], buf, nbuf, Crypt->Encrypt); -} - -decrypt(buf: array of byte, nbuf: int) -{ - crypt->descbc(cs.dec[2], buf, nbuf, Crypt->Decrypt); - crypt->descbc(cs.dec[1], buf, nbuf, Crypt->Encrypt); - crypt->descbc(cs.dec[0], buf, nbuf, Crypt->Decrypt); -} diff --git a/appl/cmd/ssh/cipherblowfish.b b/appl/cmd/ssh/cipherblowfish.b deleted file mode 100644 index 8d3b0c31..00000000 --- a/appl/cmd/ssh/cipherblowfish.b +++ /dev/null @@ -1,43 +0,0 @@ -implement Cipher; - -include "sys.m"; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; - BFstate: import crypt; - -include "sshio.m"; - -Cipherstate: adt -{ - enc: ref BFstate; - dec: ref BFstate; -}; - -cs: ref Cipherstate; - -id(): int -{ - return SSH_CIPHER_BLOWFISH; -} - -init(key: array of byte, nil: int) -{ - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; - cs = ref Cipherstate(crypt->blowfishsetup(key, nil), crypt->blowfishsetup(key, nil)); -} - -encrypt(buf: array of byte, nbuf: int) -{ - crypt->blowfishcbc(cs.enc, buf, nbuf, Crypt->Encrypt); -} - -decrypt(buf: array of byte, nbuf: int) -{ - crypt->blowfishcbc(cs.dec, buf, nbuf, Crypt->Decrypt); -} diff --git a/appl/cmd/ssh/cipherdes.b b/appl/cmd/ssh/cipherdes.b deleted file mode 100644 index 7de0a7ca..00000000 --- a/appl/cmd/ssh/cipherdes.b +++ /dev/null @@ -1,43 +0,0 @@ -implement Cipher; - -include "sys.m"; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; - DESstate: import crypt; - -include "sshio.m"; - -Cipherstate: adt -{ - enc: ref DESstate; - dec: ref DESstate; -}; - -cs: ref Cipherstate; - -id(): int -{ - return SSH_CIPHER_DES; -} - -init(key: array of byte, nil: int) -{ - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; - cs = ref Cipherstate(crypt->dessetup(key, nil), crypt->dessetup(key, nil)); -} - -encrypt(buf: array of byte, nbuf: int) -{ - crypt->descbc(cs.enc, buf, nbuf, Crypt->Encrypt); -} - -decrypt(buf: array of byte, nbuf: int) -{ - crypt->descbc(cs.dec, buf, nbuf, Crypt->Decrypt); -} diff --git a/appl/cmd/ssh/ciphernone.b b/appl/cmd/ssh/ciphernone.b deleted file mode 100644 index 01a7a1f3..00000000 --- a/appl/cmd/ssh/ciphernone.b +++ /dev/null @@ -1,28 +0,0 @@ -implement Cipher; - -include "sys.m"; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - -include "sshio.m"; - -id(): int -{ - return SSH_CIPHER_NONE; -} - -init(nil: array of byte, nil: int) -{ -} - -encrypt(nil: array of byte, nil: int) -{ -} - -decrypt(nil: array of byte, nil: int) -{ -} diff --git a/appl/cmd/ssh/cipherrc4.b b/appl/cmd/ssh/cipherrc4.b deleted file mode 100644 index f43f9c8d..00000000 --- a/appl/cmd/ssh/cipherrc4.b +++ /dev/null @@ -1,46 +0,0 @@ -implement Cipher; - -include "sys.m"; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; - RC4state: import crypt; - -include "sshio.m"; - -Cipherstate: adt -{ - enc: ref RC4state; - dec: ref RC4state; -}; - -cs: ref Cipherstate; - -id(): int -{ - return SSH_CIPHER_RC4; -} - -init(key: array of byte, isserver: int) -{ - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; - if(isserver) - cs = ref Cipherstate(crypt->rc4setup(key[0:16]), crypt->rc4setup(key[16:32])); - else - cs = ref Cipherstate(crypt->rc4setup(key[16:32]), crypt->rc4setup(key[0:16])); -} - -encrypt(buf: array of byte, nbuf: int) -{ - crypt->rc4(cs.enc, buf, nbuf); -} - -decrypt(buf: array of byte, nbuf: int) -{ - crypt->rc4(cs.dec, buf, nbuf); -} diff --git a/appl/cmd/ssh/mkfile b/appl/cmd/ssh/mkfile deleted file mode 100644 index afb4c903..00000000 --- a/appl/cmd/ssh/mkfile +++ /dev/null @@ -1,29 +0,0 @@ -<../../../mkconfig - -TARG=\ - authpassword.dis\ - authrsa.dis\ - authtis.dis\ - cipher3des.dis\ - cipherblowfish.dis\ - cipherdes.dis\ - ciphernone.dis\ - cipherrc4.dis\ - sshio.dis\ - sshserve.dis\ -# ssh.dis\ - -SYSMODULES=\ - arg.m\ - keyring.m\ - security.m\ - rand.m\ - sys.m\ - draw.m\ - -MODULES=\ - sshio.m\ - -DISBIN=$ROOT/dis/ssh - -<$ROOT/mkfiles/mkdis diff --git a/appl/cmd/ssh/sshio.b b/appl/cmd/ssh/sshio.b deleted file mode 100644 index 942b06df..00000000 --- a/appl/cmd/ssh/sshio.b +++ /dev/null @@ -1,586 +0,0 @@ -implement Sshio; - -include "sys.m"; - sys: Sys; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; - PK, SK: import crypt; - -include "sshio.m"; - -include "rand.m"; - rand: Rand; - -init() -{ - sys = load Sys Sys->PATH; - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; - rand = load Rand Rand->PATH; - rand->init(sys->millisec()); -} - -msgnames := array[45] of { - "SSH_MSG_NONE", # 0 - "SSH_MSG_DISCONNECT", - "SSH_SMSG_PUBLIC_KEY", - "SSH_CMSG_SESSION_KEY", - "SSH_CMSG_USER", - "SSH_CMSG_AUTH_RHOSTS", - "SSH_CMSG_AUTH_RSA", - "SSH_SMSG_AUTH_RSA_CHALLENGE", - "SSH_CMSG_AUTH_RSA_RESPONSE", - "SSH_CMSG_AUTH_PASSWORD", - "SSH_CMSG_REQUEST_PTY", # 10 - "SSH_CMSG_WINDOW_SIZE", - "SSH_CMSG_EXEC_SHELL", - "SSH_CMSG_EXEC_CMD", - "SSH_SMSG_SUCCESS", - "SSH_SMSG_FAILURE", - "SSH_CMSG_STDIN_DATA", - "SSH_SMSG_STDOUT_DATA", - "SSH_SMSG_STDERR_DATA", - "SSH_CMSG_EOF", - "SSH_SMSG_EXITSTATUS", # 20 - "SSH_MSG_CHANNEL_OPEN_CONFIRMATION", - "SSH_MSG_CHANNEL_OPEN_FAILURE", - "SSH_MSG_CHANNEL_DATA", - "SSH_MSG_CHANNEL_INPUT_EOF", - "SSH_MSG_CHANNEL_OUTPUT_CLOSED", - "SSH_MSG_UNIX_DOMAIN_X11_FORWARDING (obsolete)", - "SSH_SMSG_X11_OPEN", - "SSH_CMSG_PORT_FORWARD_REQUEST", - "SSH_MSG_PORT_OPEN", - "SSH_CMSG_AGENT_REQUEST_FORWARDING", # 30 - "SSH_SMSG_AGENT_OPEN", - "SSH_MSG_IGNORE", - "SSH_CMSG_EXIT_CONFIRMATION", - "SSH_CMSG_X11_REQUEST_FORWARDING", - "SSH_CMSG_AUTH_RHOSTS_RSA", - "SSH_MSG_DEBUG", - "SSH_CMSG_REQUEST_COMPRESSION", - "SSH_CMSG_MAX_PACKET_SIZE", - "SSH_CMSG_AUTH_TIS", - "SSH_SMSG_AUTH_TIS_CHALLENGE", # 40 - "SSH_CMSG_AUTH_TIS_RESPONSE", - "SSH_CMSG_AUTH_KERBEROS", - "SSH_SMSG_AUTH_KERBEROS_RESPONSE", - "SSH_CMSG_HAVE_KERBEROS_TGT", -}; - -Conn.mk(host: string, fd: ref Sys->FD): ref Conn -{ - c := ref Conn; - c.host = host; - c.sesskey = array[SESSKEYLEN] of byte; - c.sessid = array[SESSIDLEN] of byte; - c.in = chan of (ref Msg, string); - c.out = chan of ref Msg; - c.flags = 0; - c.interactive = 0; - sync := chan of int; - spawn msgreader(c, fd, sync); - <-sync; - spawn msgwriter(c, fd, sync); - <-sync; - return c; -} - -Conn.setkey(c: self ref Conn, key: ref PK.RSA) -{ - c.hostkey = key; -} - -msgreader(c: ref Conn, fd: ref Sys->FD, sync: chan of int) -{ - sys->pctl(Sys->NEWFD, 2 :: fd.fd :: nil); - sync <-= 1; - fd = sys->fildes(fd.fd); - for(;;){ - m := readmsg(c, fd); - if(m == nil){ - c.in <-= (nil, sys->sprint("%r")); - break; - } - debug(DBG_PROTO, sys->sprint("<-[%d] %s\n", m.ep-m.rp, m.fulltext())); - case m.mtype { - SSH_MSG_IGNORE => - ; - SSH_MSG_DEBUG => - debug(DBG_PROTO, sys->sprint("remote DEBUG: %s\n", m.getstring())); - * => - c.in <-= (m, nil); - } - } -} - -msgwriter(c: ref Conn, fd: ref Sys->FD, sync: chan of int) -{ - sys->pctl(Sys->NEWFD, 2 :: fd.fd :: nil); - sync <-= 1; - fd = sys->fildes(fd.fd); - while((m := <-c.out) != nil) - if(writemsg(c, m, fd) < 0){ - while(<-c.out != nil) - {} # flush - exit; - } -} - -# -# read initial SSH-m.n-comment line -# -readversion(fd: ref Sys->FD): (int, int, string) -{ - buf := array[128] of byte; - if((n := readstrnl(fd, buf, len buf)) < 0) - return (-1, -1, sys->sprint("error reading version: %r")); - # id string is "SSH-m.n-comment". We need m=1, n>=5. - s := string buf[0: n]; - (nf, fld) := sys->tokenize(s, "-\r\n"); - if(nf < 3 || hd fld != "SSH") - return (-1, -1, sys->sprint("unexpected protocol reply: %s", s)); - (nf, fld) = sys->tokenize(hd tl fld, "."); - if(nf < 2) - return (-1, -1, "invalid SSH version string in "+s); - return (1, int hd tl fld, s); -} - -calcsessid(hostmod: ref IPint, servermod: ref IPint, cookie: array of byte): array of byte -{ - b1 := hostmod.iptobebytes(); - b2 := servermod.iptobebytes(); - buf := array[len b1+len b2+COOKIELEN] of byte; - buf[0:] = b1; - buf[len b1:] = b2; - buf[len b1+len b2:] = cookie[0: COOKIELEN]; - sessid := array[Crypt->MD5dlen] of byte; - crypt->md5(buf, len buf, sessid, nil); - return sessid; -} - -Msg.text(m: self ref Msg): string -{ - if(0 <= m.mtype && m.mtype < len msgnames) - return msgnames[m.mtype]; - return sys->sprint("<unknown type %d>", m.mtype); -} - -Msg.fulltext(m: self ref Msg): string -{ - s := m.text(); - n := m.ep; - if(n > 64) - n = 64; - for(i := 0; i < n; i++) - s += sys->sprint(" %.2ux", int m.data[i]); - if(n != m.ep) - s += " ..."; - return s; -} - -badmsg(m: ref Msg, want: int, errmsg: string) -{ - if(m == nil) - s := sys->sprint("<early eof: %s>", errmsg); - else - s = m.text(); - if(want) - error(sys->sprint("got %s message expecting %s", s, msgnames[want])); - error(sys->sprint("got unexpected %s message", s)); -} - -Msg.mk(mtype: int, length: int): ref Msg -{ - if(length > 256*1024) - raise "message too large"; - return ref Msg(mtype, array[4+8+1+length+4] of byte, 0, 0, length); -} - -# used by auth tis -unrecvmsg(c: ref Conn, m: ref Msg) -{ - debug(DBG_PROTO, sys->sprint("unreceived %s len %d\n", msgnames[m.mtype], m.ep-m.rp)); - c.unget = m; -} - -readmsg(c: ref Conn, fd: ref Sys->FD): ref Msg -{ - if(c.unget != nil){ # TO DO: assumes state of processes ensures exclusive access - m := c.unget; - c.unget = nil; - return m; - } - buf := array[4] of byte; - if((n := sys->readn(fd, buf, len buf)) != len buf){ - if(n < 0) - sys->werrstr("short net read: %r"); - else - sys->werrstr("short net read"); - return nil; - } - length := get4(buf, 0); - if(length < 5 || length > 256*1024){ - sys->werrstr(sys->sprint("implausible packet length: %.8ux", length)); - return nil; - } - pad := 8-length%8; - m := ref Msg(0, array[pad+length] of byte, pad, 0, pad+length-4); - if(sys->readn(fd, m.data, len m.data) != len m.data){ - sys->werrstr(sys->sprint("short net read: %r")); - return nil; - } - if(c.cipher != nil) - c.cipher->decrypt(m.data, length+pad); - crc := sum32(0, m.data, m.ep); - crc0 := get4(m.data, m.ep); - if(crc != crc0){ - sys->werrstr(sys->sprint("bad crc %#ux != %#ux (packet length %ud)", crc, crc0, length)); - return nil; - } - m.mtype = int m.data[m.rp++]; - return m; -} - -recvmsg(c: ref Conn, mtype: int): ref Msg -{ - (m, errmsg) := <-c.in; - if(mtype == 0){ - # no checking - }else if(mtype == -1){ - # must not be nil - if(m == nil) - error(Ehangup); - }else if(m == nil || m.mtype != mtype) # must be given type - badmsg(m, mtype, errmsg); - return m; -} - -writemsg(c: ref Conn, m: ref Msg, fd: ref Sys->FD): int -{ - datalen := m.wp; - length := datalen+1+4; # will add type and crc - pad := 8-length%8; - debug(DBG_PROTO, sys->sprint("->[%d] %s\n", datalen, m.fulltext())); - m.data[4+pad+1:] = m.data[0: datalen]; # slide data to correct position (is this guaranteed?) TO DO - put4(m.data, 0, length); - p := 4; - if(c.cipher != nil) - for(i := 0; i < pad; i++) - m.data[p++] = byte fastrand(); - else{ - for(i = 0; i < pad; i++) - m.data[p++] = byte 0; - } - m.data[p++] = byte m.mtype; - # data already in position - p += datalen; - crc := sum32(0, m.data[4:], pad+1+datalen); - put4(m.data, p, crc); - p += 4; - if(c.cipher != nil) - c.cipher->encrypt(m.data[4:], length+pad); - if(sys->write(fd, m.data, p) != p) - return -1; - return 0; -} - -Msg.get1(m: self ref Msg): int -{ - if(m.rp >= m.ep) - raise Edecode; - return int m.data[m.rp++]; -} - -Msg.get2(m: self ref Msg): int -{ - if(m.rp+2 > m.ep) - raise Edecode; - x := (int m.data[m.rp+0]<<8) | int m.data[m.rp+1]; - m.rp += 2; - return x; -} - -Msg.get4(m: self ref Msg): int -{ - if(m.rp+4 > m.ep) - raise Edecode; - x := int m.data[m.rp+0]<<24|int m.data[m.rp+1]<<16|int m.data[m.rp+2]<<8|int m.data[m.rp+3]; - m.rp += 4; - return x; -} - -Msg.getarray(m: self ref Msg): array of byte -{ - length := m.get4(); - if(m.rp+length > m.ep) - raise Edecode; - p := m.data[m.rp: m.rp+length]; - m.rp += length; - return p; -} - -Msg.getstring(m: self ref Msg): string -{ - return string m.getarray(); -} - -Msg.getbytes(m: self ref Msg, n: int): array of byte -{ - if(m.rp+n > m.ep) - raise Edecode; - p := m.data[m.rp: m.rp+n]; - m.rp += n; - return p; -} - -Msg.getipint(m: self ref Msg): ref IPint -{ - n := (m.get2()+7)/8; # get2 returns # bits - return IPint.bebytestoip(m.getbytes(n)); -} - -Msg.getpk(m: self ref Msg): ref PK.RSA -{ - m.get4(); - ek := m.getipint(); - n := m.getipint(); - return ref PK.RSA(n, ek); -} - -Msg.put1(m: self ref Msg, x: int) -{ - if(m.wp >= m.ep) - raise Eencode; - m.data[m.wp++] = byte x; -} - -Msg.put2(m: self ref Msg, x: int) -{ - if(m.wp+2 > m.ep) - raise Eencode; - (m.data[m.wp+0], m.data[m.wp+1]) = (byte (x>>8), byte x); - m.wp += 2; -} - -Msg.put4(m: self ref Msg, x: int) -{ - if(m.wp+4 > m.ep) - raise Eencode; - (m.data[m.wp+0], m.data[m.wp+1], m.data[m.wp+2], m.data[m.wp+3]) = (byte (x>>24), byte (x>>16), byte (x>>8), byte x); - m.wp += 4; -} - -Msg.putstring(m: self ref Msg, s: string) -{ - b := array of byte s; - m.put4(len b); - m.putbytes(b, len b); -} - -Msg.putbytes(m: self ref Msg, a: array of byte, n: int) -{ - if(m.wp+n > m.ep) - raise Eencode; - m.data[m.wp:] = a[0: n]; - m.wp += n; -} - -Msg.putipint(m: self ref Msg, b: ref IPint) -{ - bits := b.bits(); - m.put2(bits); -# n := (bits+7)/8; - ba := b.iptobebytes(); - n := len ba; - if(m.wp+n > m.ep) - raise Eencode; - m.data[m.wp:] = ba; - m.wp += n; -} - -Msg.putpk(m: self ref Msg, key: ref PK.RSA) -{ - m.put4(key.n.bits()); - m.putipint(key.ek); - m.putipint(key.n); -} - -crctab := array[256] of int; - -initsum32() -{ - poly := int 16redb88320; - for(i := 0; i < 256; i++){ - crc := i; - for(j := 0; j < 8; j++) - if(crc&1) - crc = ((crc>>1) & int ~16r80000000)^poly; # need unsigned shift - else - crc = (crc>>1) & int ~16r80000000; - crctab[i] = crc; - } -} - -first_38: int = 1; - -sum32(lcrc: int, buf: array of byte, n: int): int -{ - crc := lcrc; - if(first_38){ - first_38 = 0; - initsum32(); - } - s := 0; - while(n-- > 0) - crc = crctab[(crc^int buf[s++])&16rff]^((crc>>8)&int ~16rFF000000); - return crc; -} - -erase(b: array of byte) -{ - for(i := 0; i < len b; i++) - b[i] = byte 0; -} - -# -# PKCS#1 padding -# -rsapad(b: ref IPint, n: int): ref IPint -{ - a := b.iptobebytes(); - pad := n - len a - 3; - if(pad < 0) - error("value too large to pad"); # can't happen if keys are required size - buf := array[n] of byte; - buf[0] = byte 0; - buf[1] = byte 2; - for(i := 2; --pad >= 0; i++) - buf[i] = byte (1+fastrand()%255); - buf[i++] = byte 0; - buf[i:] = a; - c := IPint.bebytestoip(buf); - erase(buf); - erase(a); - return c; -} - -rsaunpad(b: ref IPint): ref IPint -{ - buf := b.iptobebytes(); - i := 0; - if(buf[0] == byte 0) - i++; - if(buf[i] != byte 2) - error("bad data in rsaunpad"); - for(; i < len buf; i++) - if(buf[i] == byte 0) - break; - c := IPint.bebytestoip(buf[i:]); - erase(buf); - return c; -} - -rsaencryptbuf(key: ref PK.RSA, buf: array of byte, nbuf: int): ref IPint -{ - n := (key.n.bits()+7)/8; - a := IPint.bebytestoip(buf[0: nbuf]); - b := rsapad(a, n); - return crypt->rsaencrypt(key, b); -} - -iptorjustbe(b: ref IPint, buf: array of byte, length: int) -{ - a := b.iptobebytes(); - if(len a < length){ - length -= len a; - erase(buf[0: length]); - buf[length:] = a; - }else - buf[0:] = a[0: length]; - erase(a); -} - -hex(a: array of byte): string -{ - s := ""; - for(i := 0; i < len a; i++) - s += sys->sprint("%.2ux", int a[i]); - return s; -} - -debug(n: int, s: string) -{ - sys->fprint(sys->fildes(2), "debug: %s", s); -} - -error(s: string) -{ - sys->fprint(sys->fildes(2), "error: %s\n", s); - raise "error"; -} - -rsagen(bits: int): ref SK.RSA -{ - return crypt->rsagen(bits, 6, 0); -} - -rsaencrypt(key: ref PK.RSA, b: ref IPint): ref IPint -{ - return crypt->rsaencrypt(key, b); -} - -rsadecrypt(key: ref SK.RSA, b: ref IPint): ref IPint -{ - return crypt->rsadecrypt(key, b); -} - -fastrand(): int -{ - return int rand->bigrand(4294967295); -} - -readstrnl(fd: ref Sys->FD, buf: array of byte, nbuf: int): int -{ - for(i := 0; i < nbuf; i++) - case sys->read(fd, buf[i:], 1) { - -1 => - return -1; - 0 => - sys->werrstr("unexpected EOF"); - return -1; - * => - if(buf[i] == byte '\n') - return i; - } - sys->werrstr("line too long"); - return -1; -} - -eqbytes(a: array of byte, b: array of byte, n: int): int -{ - if(len a > n || len b > n) - return 0; - for(i := 0; i < n; i++) - if(a[i] != b[i]) - return 0; - return 1; -} - -get4(a: array of byte, o: int): int -{ - return int a[o+0]<<24 | int a[o+1]<<16 | int a[o+2]<<8 | int a[o+3]; -} - -put4(a: array of byte, o: int, v: int) -{ - a[o+0] = byte (v>>24); - a[o+1] = byte (v>>16); - a[o+2] = byte (v>>8); - a[o+3] = byte v; -} diff --git a/appl/cmd/ssh/sshio.m b/appl/cmd/ssh/sshio.m deleted file mode 100644 index 6c186e63..00000000 --- a/appl/cmd/ssh/sshio.m +++ /dev/null @@ -1,194 +0,0 @@ - - # internal debugging flags - DBG, DBG_CRYPTO, DBG_PACKET, DBG_AUTH, DBG_PROC, DBG_PROTO, DBG_IO, DBG_SCP: con 1<<iota; - - # protocol packet types - SSH_MSG_NONE, # 0 - SSH_MSG_DISCONNECT, - SSH_SMSG_PUBLIC_KEY, - SSH_CMSG_SESSION_KEY, - SSH_CMSG_USER, - SSH_CMSG_AUTH_RHOSTS, - SSH_CMSG_AUTH_RSA, - SSH_SMSG_AUTH_RSA_CHALLENGE, - SSH_CMSG_AUTH_RSA_RESPONSE, - SSH_CMSG_AUTH_PASSWORD, # 10 - SSH_CMSG_REQUEST_PTY, - SSH_CMSG_WINDOW_SIZE, - SSH_CMSG_EXEC_SHELL, - SSH_CMSG_EXEC_CMD, - SSH_SMSG_SUCCESS, - SSH_SMSG_FAILURE, - SSH_CMSG_STDIN_DATA, - SSH_SMSG_STDOUT_DATA, - SSH_SMSG_STDERR_DATA, - SSH_CMSG_EOF, # 20 - SSH_SMSG_EXITSTATUS, - SSH_MSG_CHANNEL_OPEN_CONFIRMATION, - SSH_MSG_CHANNEL_OPEN_FAILURE, - SSH_MSG_CHANNEL_DATA, - SSH_MSG_CHANNEL_INPUT_EOF, - SSH_MSG_CHANNEL_OUTPUT_CLOSED, - SSH_MSG_UNIX_DOMAIN_X11_FORWARDING, # obsolete - SSH_SMSG_X11_OPEN, - SSH_CMSG_PORT_FORWARD_REQUEST, - SSH_MSG_PORT_OPEN, # 30 - SSH_CMSG_AGENT_REQUEST_FORWARDING, - SSH_SMSG_AGENT_OPEN, - SSH_MSG_IGNORE, - SSH_CMSG_EXIT_CONFIRMATION, - SSH_CMSG_X11_REQUEST_FORWARDING, - SSH_CMSG_AUTH_RHOSTS_RSA, - SSH_MSG_DEBUG, - SSH_CMSG_REQUEST_COMPRESSION, - SSH_CMSG_MAX_PACKET_SIZE, - SSH_CMSG_AUTH_TIS, # 40 - SSH_SMSG_AUTH_TIS_CHALLENGE, - SSH_CMSG_AUTH_TIS_RESPONSE, - SSH_CMSG_AUTH_KERBEROS, - SSH_SMSG_AUTH_KERBEROS_RESPONSE, - SSH_CMSG_HAVE_KERBEROS_TGT: con iota; - - SSH_MSG_ERROR: con -1; - - # protocol flags - SSH_PROTOFLAG_SCREEN_NUMBER: con 1<<0; - SSH_PROTOFLAG_HOST_IN_FWD_OPEN: con 1<<1; - - # agent protocol packet types - SSH_AGENTC_NONE, - SSH_AGENTC_REQUEST_RSA_IDENTITIES, - SSH_AGENT_RSA_IDENTITIES_ANSWER, - SSH_AGENTC_RSA_CHALLENGE, - SSH_AGENT_RSA_RESPONSE, - SSH_AGENT_FAILURE, - SSH_AGENT_SUCCESS, - SSH_AGENTC_ADD_RSA_IDENTITY, - SSH_AGENTC_REMOVE_RSA_IDENTITY: con iota; - - # protocol constants - SSH_MAX_DATA: con 256*1024; - SSH_MAX_MSG: con SSH_MAX_DATA+4; - SESSKEYLEN: con 32; - SESSIDLEN: con 16; - COOKIELEN: con 8; - - # crypto ids - SSH_CIPHER_NONE, - SSH_CIPHER_IDEA, - SSH_CIPHER_DES, - SSH_CIPHER_3DES, - SSH_CIPHER_TSS, - SSH_CIPHER_RC4, - SSH_CIPHER_BLOWFISH: con iota; - - # auth method ids - SSH_AUTH_RHOSTS, - SSH_AUTH_RSA, - SSH_AUTH_PASSWORD, - SSH_AUTH_RHOSTS_RSA, - SSH_AUTH_TIS, - SSH_AUTH_USER_RSA: con 1+iota; - -Edecode: con "error decoding input packet"; -Eencode: con "out of space encoding output packet (BUG)"; -Ehangup: con "hungup connection"; -Ememory: con "out of memory"; - -Cipher: module -{ - id: fn(): int; - init: fn(key: array of byte, isserver: int); - encrypt: fn(a: array of byte, n: int); - decrypt: fn(a: array of byte, n: int); -}; - -Auth: module -{ - AuthInfo: adt{ - user: string; - cap: string; - }; - - id: fn(): int; - firstmsg: fn(): int; - init: fn(nil: Sshio); - authsrv: fn(nil: ref Sshio->Conn, nil: ref Sshio->Msg): ref AuthInfo; - auth: fn(nil: ref Sshio->Conn): int; -}; - -Sshio: module -{ - PATH: con "sshio.dis"; - - Conn: adt{ - in: chan of (ref Msg, string); - out: chan of ref Msg; - - sessid: array of byte; - sesskey: array of byte; - hostkey: ref Crypt->PK.RSA; - flags: int; - cipher: Cipher; # chosen cipher - user: string; - host: string; - interactive: int; - unget: ref Msg; - - mk: fn(host: string, fd: ref Sys->FD): ref Conn; - setkey: fn(c: self ref Conn, key: ref Crypt->PK.RSA); - }; - - Msg: adt{ - mtype: int; - data: array of byte; - rp: int; # read pointer - wp: int; # write pointer - ep: int; # byte just beyond message data - - mk: fn(mtype: int, length: int): ref Msg; - text: fn(m: self ref Msg): string; - fulltext: fn(m: self ref Msg): string; - - get1: fn(m: self ref Msg): int; - get2: fn(m: self ref Msg): int; - get4: fn(m: self ref Msg): int; - getstring: fn(m: self ref Msg): string; - getbytes: fn(m: self ref Msg, n: int): array of byte; - getarray: fn(m: self ref Msg): array of byte; - getipint: fn(m: self ref Msg): ref IPints->IPint; - getpk: fn(m: self ref Msg): ref Crypt->PK.RSA; - - put1: fn(m: self ref Msg, nil: int); - put2: fn(m: self ref Msg, nil: int); - put4: fn(m: self ref Msg, nil: int); - putstring: fn(m: self ref Msg, s: string); - putbytes: fn(m: self ref Msg, a: array of byte, n: int); - putipint: fn(m: self ref Msg, mp: ref IPints->IPint); - putpk: fn(m: self ref Msg, pk: ref Crypt->PK.RSA); - }; - - init: fn(); - - badmsg: fn(nil: ref Msg, nil: int, err: string); - recvmsg: fn(nil: ref Conn, nil: int): ref Msg; - unrecvmsg: fn(nil: ref Conn, nil: ref Msg); - rsapad: fn(nil: ref IPints->IPint, nil: int): ref IPints->IPint; - rsaunpad: fn(nil: ref IPints->IPint): ref IPints->IPint; - iptorjustbe: fn(nil: ref IPints->IPint, nil: array of byte, nil: int); - rsaencryptbuf: fn(nil: ref Crypt->PK.RSA, nil: array of byte, nil: int): ref IPints->IPint; - rsagen: fn(nbits: int): ref Crypt->SK.RSA; - rsaencrypt: fn(key: ref Crypt->PK.RSA, b: ref IPints->IPint): ref IPints->IPint; - rsadecrypt: fn(key: ref Crypt->SK.RSA, b: ref IPints->IPint): ref IPints->IPint; - - debug: fn(nil: int, nil: string); - error: fn(nil: string); - readstrnl: fn(fd: ref Sys->FD, buf: array of byte, nbytes: int): int; - calcsessid: fn(hostmod: ref IPints->IPint, servermod: ref IPints->IPint, cookie: array of byte): array of byte; -# sshlog: fn(nil: array of byte); # TBA was ... - - fastrand: fn(): int; - eqbytes: fn(a: array of byte, b: array of byte, n: int): int; - readversion: fn(fd: ref Sys->FD): (int, int, string); - hex: fn(a: array of byte): string; -}; diff --git a/appl/cmd/ssh/sshserve.b b/appl/cmd/ssh/sshserve.b deleted file mode 100644 index dc8bbd31..00000000 --- a/appl/cmd/ssh/sshserve.b +++ /dev/null @@ -1,495 +0,0 @@ -implement Sshserve; - -include "sys.m"; - sys: Sys; - -include "draw.m"; - -include "ipints.m"; - ipints: IPints; - IPint: import ipints; - -include "crypt.m"; - crypt: Crypt; - PK, SK: import crypt; - -include "env.m"; - env: Env; - -include "sh.m"; - sh: Sh; - -include "wait.m"; - wait: Wait; - -include "arg.m"; - -include "sshio.m"; - sshio: Sshio; - Conn, Msg: import sshio; - recvmsg: import sshio; - error, debug: import sshio; - -Sshserve: module -{ - init: fn(nil: ref Draw->Context, argl: list of string); -}; - -AuthRpc: adt {}; -debuglevel := 0; - -cipherlist := "blowfish rc4 3des"; -ciphers: list of Cipher; - -authlist := "rsa password tis"; -authsrvs: list of Auth; - -maxmsg := 256*1024; - -serverpriv: ref SK.RSA; -serverkey: ref PK.RSA; -hostpriv: ref SK.RSA; - -init(nil: ref Draw->Context, args: list of string) -{ - sys = load Sys Sys->PATH; - ipints = load IPints IPints->PATH; - crypt = load Crypt Crypt->PATH; - env = load Env Env->PATH; - sh = load Sh Sh->PATH; - sshio = load Sshio Sshio->PATH; - sshio->init(); - wait = load Wait Wait->PATH; - wait->init(); -# fmtinstall('B', mpfmt); -# fmtinstall('H', encodefmt); - sys->pctl(Sys->NEWPGRP|Sys->FORKFD|Sys->FORKNS|Sys->FORKENV, nil); - keyfile: string; - arg := load Arg Arg->PATH; - arg->setusage("sshserve [-A authlist] [-c cipherlist] [-k keyfile] client-ip-address"); - arg->init(args); - while((o := arg->opt()) != 0){ - case o { - 'D' => - debuglevel = int arg->earg(); - 'A' => - authlist = arg->earg(); - 'c' => - cipherlist = arg->earg(); - 'k' => - keyfile = arg->earg(); - * => - arg->usage(); - } - } - args = arg->argv(); - if(len args != 1) - arg->usage(); - arg = nil; - - sys->dup(2, 1); -# if(keyfile != nil) -# ; # read hostpriv from file -# sshlog("connect from %s", c.host); - authsrvs = loadlist("auth", authlist, authload); - ciphers = loadlist("cipher", cipherlist, cipherload); - hostpriv = crypt->rsagen(1024, 6, 0); - serverpriv = crypt->rsagen(768, 6, 0); - serverkey = serverpriv.pk; - { - versioning(sys->fildes(0)); - c := Conn.mk(hd args, sys->fildes(0)); - c.setkey(hostpriv.pk); - authenticate(c); - comms(c); - }exception e{ - "fail:*" => - raise e; - "error*" => - notegrp(sys->pctl(0, nil), "error"); - raise "fail:"+e; - } -} - -authload(f: string): Auth -{ - return load Auth f; -} - -cipherload(f: string): Cipher -{ - return load Cipher f; -} - -loadlist[T](sort: string, set: string, loadf: ref fn(f: string): T): list of T -{ - l: list of T; - (nil, fld) := sys->tokenize(set, " \t,"); - for(; fld != nil; fld = tl fld){ - f := "/dis/ssh/"+sort+hd fld+".dis"; - m := loadf(f); - if(m == nil) - error(sys->sprint("unknown %s scheme %s (%s)", sort, hd fld, f)); - l = m :: l; - } - return l; -} - -comms(c: ref Conn) -{ - (kidpid, infd, waiting) := prelude(c); -Work: - for(;;)alt{ - (m, nil) := <-c.in => - if(m == nil){ - notegrp(kidpid, "hungup"); - exit; - } - case m.mtype { - * => - sshio->badmsg(m, 0, nil); - SSH_MSG_DISCONNECT => - notegrp(kidpid, "hungup"); - sysfatal("client disconnected"); - SSH_CMSG_STDIN_DATA => - if(infd != nil){ - n := m.get4(); - sys->write(infd, m.getbytes(n), n); - } - SSH_CMSG_EOF => - infd = nil; - SSH_CMSG_EXIT_CONFIRMATION => - # sent by some clients as dying breath - notegrp(kidpid, "hungup"); - break Work; - SSH_CMSG_WINDOW_SIZE => - ; # we don't care - } - (pid, nil, status) := <-waiting => - if(pid == kidpid){ - if(status != "" && status != "0"){ - m := Msg.mk(SSH_MSG_DISCONNECT, 4+Sys->UTFmax*len status); - m.putstring(status); - sendmsg(c, m); - }else{ - m := Msg.mk(SSH_SMSG_EXITSTATUS, 4); - m.put4(0); - sendmsg(c, m); - } - sendmsg(c, nil); - break Work; - } - } - notegrp(sys->pctl(0, nil), "done"); -} - -prelude(c: ref Conn): (int, ref Sys->FD, chan of (int, string, string)) -{ - for(;;){ - m := recvmsg(c, -1); - if(m == nil) - return (-1, nil, nil); - case m.mtype { - * => - sendmsg(c, Msg.mk(SSH_SMSG_FAILURE, 0)); - SSH_MSG_DISCONNECT => - sysfatal("client disconnected"); - SSH_CMSG_REQUEST_PTY => - sendmsg(c, Msg.mk(SSH_SMSG_SUCCESS, 0)); - SSH_CMSG_MAX_PACKET_SIZE => - n := m.get4(); - if(n >= 32 && n <= SSH_MAX_MSG){ - maxmsg = n; - sendmsg(c, Msg.mk(SSH_SMSG_SUCCESS, 0)); - }else - sendmsg(c, Msg.mk(SSH_SMSG_FAILURE, 0)); - SSH_CMSG_EXEC_SHELL => - return startcmd(c, nil); - SSH_CMSG_EXEC_CMD => - cmd := m.getstring(); - return startcmd(c, cmd); - } - } -} - -copyout(c: ref Conn, fd: ref Sys->FD, mtype: int) -{ - buf := array[8192] of byte; - max := len buf; - if(max > maxmsg-32) # 32 is an overestimate of packet overhead - max = maxmsg-32; - if(max <= 0) - sysfatal("maximum message size too small"); - while((n := sys->read(fd, buf, max)) > 0){ - m := Msg.mk(mtype, 4+n); - m.put4(n); - m.putbytes(buf, n); - sendmsg(c, m); - } -} - -send_ssh_smsg_public_key(c: ref Conn, cookie: array of byte) -{ - m := Msg.mk(SSH_SMSG_PUBLIC_KEY, 2048); - m.putbytes(cookie, COOKIELEN); - m.putpk(serverkey); - m.putpk(c.hostkey); - m.put4(c.flags); - ciphermask := 0; - for(l1 := ciphers; l1 != nil; l1 = tl l1) - ciphermask |= 1<<(hd l1)->id(); - m.put4(ciphermask); - authmask := 0; - for(l2 := authsrvs; l2 != nil; l2 = tl l2) - authmask |= 1<<(hd l2)->id(); - m.put4(authmask); - sendmsg(c, m); -} - -rpcdecrypt(rpc: ref AuthRpc, b: ref IPint): ref IPint -{ - raise "rpcdecrypt"; -# p := array of byte b.iptostr(16); -# if(auth_rpc(rpc, "write", p, len p) != ARok) -# sysfatal("factotum rsa write: %r"); -# if(auth_rpc(rpc, "read", nil, 0) != ARok) -# sysfatal("factotum rsa read: %r"); -# return strtomp(rpc.arg, nil, 16, nil); -} - -recv_ssh_cmsg_session_key(c: ref Conn, rpc: ref AuthRpc, cookie: array of byte) -{ - m := recvmsg(c, SSH_CMSG_SESSION_KEY); - id := m.get1(); - c.cipher = nil; - for(l := ciphers; l != nil; l = tl l) - if((hd l)->id() == id){ - c.cipher = hd l; - break; - } - if(c.cipher == nil) - sysfatal(sys->sprint("invalid cipher %d selected", id)); - if(!sshio->eqbytes(m.getbytes(COOKIELEN), cookie, len cookie)) - sysfatal("bad cookie"); - serverkeylen := serverkey.n.bits(); - hostkeylen := c.hostkey.n.bits(); - ksmall, kbig: ref SK.RSA; - if(serverkeylen+128 <= hostkeylen){ - ksmall = serverpriv; - kbig = nil; - }else if(hostkeylen+128 <= serverkeylen){ - ksmall = nil; - kbig = serverpriv; - }else - sysfatal("server session and host keys do not differ by at least 128 bits"); - b := m.getipint(); - debug(DBG_CRYPTO, sys->sprint("encrypted with kbig is %s\n", b.iptostr(16))); - if(kbig != nil) - b = sshio->rsadecrypt(kbig, b); - else -# b = rpcdecrypt(rpc, b); - b = sshio->rsadecrypt(hostpriv, b); - b = sshio->rsaunpad(b); - sshio->debug(DBG_CRYPTO, sys->sprint("encrypted with ksmall is %s\n", b.iptostr(16))); - if(ksmall != nil) - b = sshio->rsadecrypt(ksmall, b); - else -# b = rpcdecrypt(rpc, b); - b = sshio->rsadecrypt(hostpriv, b); - b = sshio->rsaunpad(b); - debug(DBG_CRYPTO, sys->sprint("munged is %s\n", b.iptostr(16))); - n := (b.bits()+7)/8; - if(n < SESSKEYLEN) - sysfatal("client sent short session key"); - buf := array[SESSKEYLEN] of byte; - sshio->iptorjustbe(b, buf, SESSKEYLEN); - for(i := 0; i < SESSIDLEN; i++) - buf[i] ^= c.sessid[i]; - c.sesskey[0: ] = buf[0: SESSKEYLEN]; - debug(DBG_CRYPTO, sys->sprint("unmunged is %.*s\n", SESSKEYLEN*2, sshio->hex(buf))); - c.flags = m.get4(); -} - -authsrvuser(c: ref Conn) -{ - m := recvmsg(c, SSH_CMSG_USER); - user := m.getstring(); - c.user = user; - inited := 0; - ai: ref Auth->AuthInfo; - while(authsrvs != nil && ai == nil){ -# # -# # * clumsy: if the client aborted the auth_tis early -# # * we don't send a new failure. we check this by -# # * looking at c->unget, which is only used in that -# # * case. -# # - if(c.unget == nil) - sendmsg(c, Msg.mk(SSH_SMSG_FAILURE, 0)); - m = recvmsg(c, -1); - for(l := authsrvs; l != nil; l = tl l) - if((hd l)->firstmsg() == m.mtype){ - bit := 1 << (hd l)->id(); - if((inited & bit) == 0){ - (hd l)->init(sshio); - inited |= bit; - } - ai = (hd l)->authsrv(c, m); - break; - } - if(l == nil) - sshio->badmsg(m, 0, nil); - } - sendmsg(c, Msg.mk(SSH_SMSG_SUCCESS, 0)); -# if(noworld(ai.cuid)) -# ns := "/lib/namespace.noworld"; -# else -# ns = nil; -# if(auth_chuid(ai, ns) < 0){ -# sshlog("auth_chuid to %s: %r", ai.cuid); -# sysfatal("auth_chuid: %r"); -# } -# sshlog("logged in as %q", ai.user); - if(ai != nil) - sys->print("logged in as %q\n", ai.user); -} - -keyjunk() -{ - p: array of byte; - m: ref IPint; - rpc: ref AuthRpc; - key: ref PK.RSA; - -# # -# # BUG: should use `attr' to get the key attributes -# # after the read, but that's not implemented yet. -# # -# if((b = Bopen("/mnt/factotum/ctl", OREAD)) == nil) -# sysfatal("open /mnt/factotum/ctl: %r"); -# while((p = Brdline(b, '\n')) != nil){ -# if(strstr(p, " proto=rsa ") != nil && strstr(p, " service=sshserve ") != nil) -# break; -# } -# if(p == nil) -# sysfatal("no sshserve keys found in /mnt/factotum/ctl"); -# a = _parseattr(p); -# Bterm(b); -# key = rsaprivalloc(); -# if((p = _strfindattr(a, "n")) == nil) -# sysfatal("no n in sshserve key"); -# if((key.n = IPint.strtoip(p, 16)) == nil) -# sysfatal("bad n in sshserve key"); -# if((p = _strfindattr(a, "ek")) == nil) -# sysfatal("no ek in sshserve key"); -# if((key.ek = IPint.strtoip(p, 16)) == nil) -# sysfatal("bad ek in sshserve key"); -# _freeattr(a); -# if((afd = sys->open("/mnt/factotum/rpc", ORDWR)) == nil) -# sysfatal("open /mnt/factotum/rpc: %r"); -# if((rpc = auth_allocrpc(afd)) == nil) -# sysfatal("auth_allocrpc: %r"); -# p = "proto=rsa role=client service=sshserve"; -# if(auth_rpc(rpc, "start", p, len p) != ARok) -# sysfatal("auth_rpc start %s: %r", p); -# if(auth_rpc(rpc, "read", nil, 0) != ARok) -# sysfatal("auth_rpc read: %r"); -# m = strtomp(rpc.arg, nil, 16, nil); -# if(mpcmp(m, key.n) != 0) -# sysfatal("key in /mnt/factotum/ctl does not match rpc key"); -# mpfree(m); -# c.hostkey = key; -} - -versioning(fd: ref Sys->FD) -{ - sys->fprint(fd, "SSH-1.5-Inferno\n"); - (maj, min, err_or_id) := sshio->readversion(fd); - if(maj < 0) - sysfatal(err_or_id); - if(maj != 1 || min < 5) - sysfatal(sys->sprint("protocol mismatch; got %s, need SSH-1.x for x >= 5", err_or_id)); -} - -authenticate(c: ref Conn) -{ - rpc: ref AuthRpc; - - cookie := array[COOKIELEN] of {* => byte sshio->fastrand()}; - c.sessid = sshio->calcsessid(c.hostkey.n, serverkey.n, cookie); - send_ssh_smsg_public_key(c, cookie); - recv_ssh_cmsg_session_key(c, rpc, cookie); -# afd = nil; - c.cipher->init(c.sesskey, 1); # turns on encryption - sendmsg(c, Msg.mk(SSH_SMSG_SUCCESS, 0)); - authsrvuser(c); -} - -startcmd(c: ref Conn, cmd: string): (int, ref Sys->FD, chan of (int, string, string)) -{ - pfd := array[3] of {* => array[2] of ref Sys->FD}; - for(i := 0; i < 3; i++) - if(sys->pipe(pfd[i]) < 0) - sysfatal(sys->sprint("pipe: %r")); - wfd := sys->open("#p/"+string sys->pctl(0, nil)+"/wait", Sys->OREAD); - if(wfd == nil) - sysfatal(sys->sprint("open wait: %r")); - pidc := chan of int; - spawn startcmd1(c, cmd, pfd, pidc); - kidpid := <-pidc; - (nil, waited) := wait->monitor(wfd); - spawn copyout(c, pfd[1][0], SSH_SMSG_STDOUT_DATA); - pfd[1][0] = nil; - spawn copyout(c, pfd[2][0], SSH_SMSG_STDERR_DATA); - pfd[2][0] = nil; - return (kidpid, pfd[0][0], waited); -} - -startcmd1(c: ref Conn, cmd: string, pfd: array of array of ref Sys->FD, pidc: chan of int) -{ - sysname := env->getenv("sysname"); - tz := env->getenv("timezone"); - sys->pctl(Sys->FORKFD, nil); - for(i := 0; i < len pfd; i++) - if(sys->dup(pfd[i][1].fd, i) < 0) - sysfatal(sys->sprint("dup: %r")); - pfd = nil; - sys->pctl(Sys->NEWPGRP|Sys->FORKNS|Sys->FORKENV|Sys->NEWFD, 0::1::2::nil); - pidc <-= sys->pctl(0, nil); - env->setenv("user", c.user); - if(sysname != nil) - env->setenv("sysname", sysname); - if(tz != nil) - env->setenv("tz", tz); - if(sys->chdir("/usr/"+c.user) < 0) - sys->chdir("/"); - if(cmd != nil){ - env->setenv("service", "rx"); - status := sh->run(nil, list of {"/dis/sh.dis", "-lc", cmd}); - if(status != nil) - raise "fail:"+status; - }else{ - env->setenv("service", "con"); - #execl("/bin/ip/telnetd", "telnetd", "-tn", nil); # TO DO: just for echo and line editing - sys->fprint(sys->fildes(2), "sshserve: cannot run /dis/ip/telnetd: %r"); - } -} - -sysfatal(s: string) -{ - sys->print("sysfatal: %s\n", s); - notegrp(sys->pctl(0, nil), "zap"); - exit; -} - -notegrp(pid: int, nil: string) -{ - fd := sys->open("#p/"+string pid+"/ctl", Sys->OWRITE); - if(fd != nil) - sys->fprint(fd, "killgrp"); -} - -sendmsg(c: ref Conn, m: ref Msg) -{ - c.out <-= m; -} diff --git a/appl/cmd/styxlisten.b b/appl/cmd/styxlisten.b index 4c8bcc94..df136e47 100644 --- a/appl/cmd/styxlisten.b +++ b/appl/cmd/styxlisten.b @@ -1,8 +1,6 @@ implement Styxlisten; include "sys.m"; sys: Sys; -include "dial.m"; - dial: Dial; include "draw.m"; include "keyring.m"; keyring: Keyring; @@ -30,9 +28,6 @@ init(ctxt: ref Draw->Context, argv: list of string) auth = load Auth Auth->PATH; if (auth == nil) badmodule(Auth->PATH); - dial = load Dial Dial->PATH; - if (dial == nil) - badmodule(Dial->PATH); if ((e := auth->init()) != nil) error("auth init failed: " + e); keyring = load Keyring Keyring->PATH; @@ -81,7 +76,7 @@ init(ctxt: ref Draw->Context, argv: list of string) arg = nil; if (doauth && algs == nil) algs = getalgs(); - addr := dial->netmkaddr(hd argv, "tcp", "styx"); + addr := netmkaddr(hd argv, "tcp", "styx"); cmd := tl argv; authinfo: ref Keyring->Authinfo; @@ -93,8 +88,8 @@ init(ctxt: ref Draw->Context, argv: list of string) error(sys->sprint("cannot read %s: %r", keyfile)); } - c := dial->announce(addr); - if (c == nil) + (ok, c) := sys->announce(addr); + if (ok == -1) error(sys->sprint("cannot announce on %s: %r", addr)); if(!trusted){ sys->unmount(nil, "/mnt/keys"); # should do for now @@ -108,17 +103,17 @@ init(ctxt: ref Draw->Context, argv: list of string) spawn listener(c, popen(ctxt, cmd, lsync), authinfo, algs, lsync); } -listener(c: ref Dial->Connection, mfd: ref Sys->FD, authinfo: ref Keyring->Authinfo, algs: list of string, lsync: chan of int) +listener(c: Sys->Connection, mfd: ref Sys->FD, authinfo: ref Keyring->Authinfo, algs: list of string, lsync: chan of int) { lsync <-= sys->pctl(0, nil); for (;;) { - nc := dial->listen(c); - if (nc == nil) + (n, nc) := sys->listen(c); + if (n == -1) error(sys->sprint("listen failed: %r")); if (verbose) sys->fprint(stderr(), "styxlisten: got connection from %s", readfile(nc.dir + "/remote")); - dfd := dial->accept(nc); + dfd := sys->open(nc.dir + "/data", Sys->ORDWR); if (dfd != nil) { if(nc.cfd != nil) sys->fprint(nc.cfd, "keepalive"); @@ -250,3 +245,18 @@ stderr(): ref Sys->FD { return sys->fildes(2); } + +netmkaddr(addr, net, svc: string): string +{ + if(net == nil) + net = "net"; + (n, nil) := sys->tokenize(addr, "!"); + if(n <= 1){ + if(svc== nil) + return sys->sprint("%s!%s", net, addr); + return sys->sprint("%s!%s!%s", net, addr, svc); + } + if(svc == nil || n > 2) + return addr; + return sys->sprint("%s!%s", addr, svc); +} diff --git a/appl/lib/factotum.b b/appl/lib/factotum.b index bcf65e6c..97138fe1 100644 --- a/appl/lib/factotum.b +++ b/appl/lib/factotum.b @@ -11,8 +11,6 @@ include "sys.m"; include "string.m"; -include "encoding.m"; - include "factotum.m"; debug := 0; @@ -185,37 +183,12 @@ rpc(afd: ref Sys->FD, verb: string, a: array of byte): (string, array of byte) Authinfo.read(fd: ref Sys->FD): ref Authinfo { - (o, a) := rpc(fd, "authinfo", nil); # deprecated in p9p factotum - e := sys->sprint("%r"); - attrs := rpcattrs(fd); - cuid := findattrval(attrs, "cuid"); - suid := findattrval(attrs, "suid"); - secret16 := findattrval(attrs, "secret"); - secret: array of byte; - if(secret16 != nil){ - enc16 := load Encoding Encoding->BASE16PATH; - if(enc16 != nil) - secret = enc16->dec(secret16); - } - cap := findattrval(attrs, "cap"); - if(o != "ok"){ - if(cuid != nil || suid != nil || secret != nil || cap != nil || attrs != nil) - return ref Authinfo(cuid, suid, cap, secret, attrs); - sys->werrstr(e); + (o, a) := rpc(fd, "authinfo", nil); + if(o != "ok") return nil; - } (n, ai) := Authinfo.unpack(a); if(n <= 0) sys->werrstr("bad auth info from factotum"); - ai.attrs = attrs; - if(ai.cuid == nil) - ai.cuid = cuid; - if(ai.suid == nil) - ai.suid = suid; - if(ai.cap == nil) - ai.cap = cap; - if(ai.secret == nil) - ai.secret = secret; return ai; } diff --git a/appl/lib/spki/spki.b b/appl/lib/spki/spki.b index 7a4854df..615aa48e 100644 --- a/appl/lib/spki/spki.b +++ b/appl/lib/spki/spki.b @@ -1,7 +1,7 @@ implement SPKI; # -# Copyright © 2004,2008 Vita Nuova Holdings Limited +# Copyright © 2004 Vita Nuova Holdings Limited # # To do: # - diagnostics @@ -14,13 +14,11 @@ include "sys.m"; include "daytime.m"; daytime: Daytime; -include "ipints.m"; - ipints: IPints; - IPint: import ipints; +include "keyring.m"; + kr: Keyring; + IPint, Certificate, PK, SK: import kr; -include "crypt.m"; - crypt: Crypt; - PK, PKsig, SK: import crypt; +include "security.m"; include "bufio.m"; @@ -39,7 +37,7 @@ debug: con 0; init() { sys = load Sys Sys->PATH; - crypt = load Crypt Crypt->PATH; + kr = load Keyring Keyring->PATH; daytime = load Daytime Daytime->PATH; sexprs = load Sexprs Sexprs->PATH; base16 = load Encoding Encoding->BASE16PATH; @@ -265,24 +263,23 @@ parsesig(e: ref Sexp): ref Signature sigalg: string; if(k != nil) sigalg = k.sigalg(); - return ref Signature(hash, k, sigalg, array[] of {("", val.asdata())}); + return ref Signature(hash, k, sigalg, (nil, val.asdata()) :: nil); } sigalg := val.op(); if(sigalg == nil) return nil; - vals := array[len val.args()] of (string, array of byte); - i := 0; + rl: list of (string, array of byte); for(els := val.args(); els != nil; els = tl els){ g := hd els; if(g.islist()){ arg := onlyarg(g); if(arg == nil) return nil; - vals[i++] = (g.op(), arg.asdata()); + rl = (g.op(), arg.asdata()) :: rl; }else - vals[i++] = ("", g.asdata()); + rl = (nil, g.asdata()) :: rl; } - return ref Signature(hash, k, sigalg, vals); + return ref Signature(hash, k, sigalg, revt(rl)); } parsecompound(e: ref Sexp): ref Name @@ -362,30 +359,31 @@ parsekey(e: ref Sexp): ref Key kl := (hd l).args(); if(kl == nil) return nil; - els := array[len kl] of (string, array of byte); - i := 0; + els: list of (string, ref IPint); for(; kl != nil; kl = tl kl){ t := (hd kl).op(); a := onlyarg(hd kl).asdata(); if(a == nil) return nil; - els[i++] = (t, a); + ip := IPint.bebytestoip(a); + if(ip == nil) + return nil; + els = (t, ip) :: els; + } + krp := ref Keyrep.PK(alg, "sdsi", els); + (pk, nbits) := krp.mkpk(); + if(pk == nil){ + sys->print("can't convert public-key\n"); + return nil; } - pk: ref Crypt->PK; - sk: ref Crypt->SK; - nbits := 0; + sk: ref Keyring->SK; if(issk){ - (sk, pk, nbits) = mksk(alg, els); + krp = ref Keyrep.SK(alg, "sdsi", els); + sk = krp.mksk(); if(sk == nil){ - sys->werrstr("can't convert private-key"); + sys->print("can't convert private-key\n"); return nil; } - }else{ - (pk, nbits) = mkpk(alg, els); - if(pk == nil){ - sys->werrstr("can't convert public-key"); - return nil; - } } #(ref Key(pk,nil,"md5",nil,nil)).hashed("md5"); # TEST return ref Key(pk, sk, nbits, mha, enc, nil); @@ -552,12 +550,12 @@ checksig(c: ref Cert, sig: ref Signature): string return "missing key for signature"; if(sig.hash == nil) return "missing hash for signature"; - if(sig.params == nil) + if(sig.sig == nil) return "missing signature value"; pk := sig.key.pk; if(pk == nil) - return "missing Crypt->PK for signature"; # TO DO (need a way to tell that key was just a hash) -#rsacomp((hd sig.params).t1, sig.key); + return "missing Keyring->PK for signature"; # TO DO (need a way to tell that key was just a hash) +#rsacomp((hd sig.sig).t1, sig.key); #sys->print("nbits= %d\n", sig.key.nbits); (alg, enc, hashalg) := sig.algs(); if(alg == nil) @@ -576,12 +574,10 @@ checksig(c: ref Cert, sig: ref Signature): string #dump("check/hashed", hash); #dump("check/h", h); ip := IPint.bebytestoip(h); - isig := sig2isig(sig); + isig := sig2icert(sig, "sdsi", 0); if(isig == nil) - return "couldn't convert SPKI signature to Crypt form"; - if(tagof pk != tagof isig) - return "signature and public key are incompatible"; - if(!crypt->verify(pk, isig, ip)) + return "couldn't convert SPKI signature to Keyring form"; + if(!kr->verifym(pk, isig, ip)) return "signature does not match"; return nil; } @@ -602,7 +598,7 @@ signcert(c: ref Cert, sigalg: string, key: ref Key): (ref Signature, string) signbytes(data: array of byte, sigalg: string, key: ref Key): (ref Signature, string) { if(key.sk == nil) - return (nil, "missing private key for signature"); + return (nil, "missing Keyring->SK for signature"); pubkey := ref *key; pubkey.sk = nil; sig := ref Signature(nil, pubkey, sigalg, nil); # ref Hash, key, alg, sig: list of (string, array of byte) @@ -624,16 +620,18 @@ signbytes(data: array of byte, sigalg: string, key: ref Key): (ref Signature, st #dump("sign/h", h); sig.hash = ref Hash(hashalg, hash); ip := IPint.bebytestoip(h); - pick isig := crypt->sign(key.sk, ip) { - RSA => - sig.params = array[] of {("", isig.n.iptobebytes())}; - DSA => - sig.params = array[] of {("r", isig.r.iptobebytes()), ("s", isig.s.iptobebytes())}; - Elgamal => - sig.params = array[] of {("r", isig.r.iptobebytes()), ("s", isig.s.iptobebytes())}; - * => - return (nil, "unsupported signature type"); # don't know the elements - } + icert := kr->signm(key.sk, ip, hashalg); + if(icert == nil) + return (nil, "signature failed"); # can't happen? + (nil, nil, nil, vals) := icert2els(icert); + if(vals == nil) + return (nil, "couldn't extract values from Keyring Certificate"); + l: list of (string, array of byte); + for(; vals != nil; vals = tl vals){ + (n, v) := hd vals; + l = (f2s("rsa", n), v) :: l; + } + sig.sig = revt(l); return (sig, nil); } @@ -647,11 +645,11 @@ hashbytes(a: array of byte, alg: string): array of byte hash: array of byte; case alg { "md5" => - hash = array[Crypt->MD5dlen] of byte; - crypt->md5(a, len a, hash, nil); + hash = array[Keyring->MD5dlen] of byte; + kr->md5(a, len a, hash, nil); "sha" or "sha1" => - hash = array[Crypt->SHA1dlen] of byte; - crypt->sha1(a, len a, hash, nil); + hash = array[Keyring->SHA1dlen] of byte; + kr->sha1(a, len a, hash, nil); * => raise "Spki->hashbytes: unknown algorithm: "+alg; } @@ -703,10 +701,10 @@ sigalgs(alg: string): (string, string, string) Signature.sexp(sg: self ref Signature): ref Sexp { sv: ref Sexp; - if(len sg.params != 1){ + if(len sg.sig != 1){ l: list of ref Sexp; - for(i := 0; i < len sg.params; i++){ - (op, val) := sg.params[i]; + for(els := sg.sig; els != nil; els = tl els){ + (op, val) := hd els; if(op != nil) l = ref Sexp.List(ref Sexp.String(op,nil) :: ref Sexp.Binary(val,nil) :: nil) :: l; else @@ -714,7 +712,7 @@ Signature.sexp(sg: self ref Signature): ref Sexp } sv = ref Sexp.List(rev(l)); }else - sv = ref Sexp.Binary(sg.params[0].t1, nil); # no list if signature has one component + sv = ref Sexp.Binary((hd sg.sig).t1, nil); # no list if signature has one component if(sg.sa != nil) sv = ref Sexp.List(ref Sexp.String(sg.sa,nil) :: sv :: nil); return ref Sexp.List(ref Sexp.String("signature",nil) :: sg.hash.sexp() :: sg.key.sexp() :: @@ -1007,16 +1005,11 @@ Name.eq(a: self ref Name, b: ref Name): int Key.public(key: self ref Key): ref Key { if(key.sk != nil){ - pk := key.pk; - if(pk == nil){ - pk = crypt->sktopk(key.sk); - if(pk == nil) - return nil; - } - key = ref *key; - key.pk = pk; - key.sk = nil; - return key; + pk := ref *key; + if(pk.pk == nil) + pk.pk = kr->sktopk(pk.sk); + pk.sk = nil; + return pk; } if(key.pk == nil) return nil; @@ -1056,9 +1049,9 @@ Key.hashexp(key: self ref Key, alg: string): ref Hash Key.sigalg(k: self ref Key): string { if(k.pk != nil) - alg := pkalg(k.pk); + alg := k.pk.sa.name; else if(k.sk != nil) - alg = skalg(k.sk); + alg = k.sk.sa.name; else return nil; if(k.halg != nil){ @@ -1069,30 +1062,6 @@ Key.sigalg(k: self ref Key): string return alg; } -skalg(sk: ref SK): string -{ - if(sk == nil) - return "nil"; - case tagof sk { - tagof SK.RSA => return "rsa"; - tagof SK.Elgamal => return "elgamal"; - tagof SK.DSA => return "dsa"; - * => return "gok"; - } -} - -pkalg(pk: ref PK): string -{ - if(pk == nil) - return "nil"; - case tagof pk { - tagof PK.RSA => return "rsa"; - tagof PK.Elgamal => return "elgamal"; - tagof PK.DSA => return "dsa"; - * => return "gok"; - } -} - Key.text(k: self ref Key): string { e := k.sexp(); @@ -1109,19 +1078,24 @@ Key.sexp(k: self ref Key): ref Sexp return nil; } sort := "public-key"; - els: array of (string, ref IPint); + els: list of (string, ref IPint); if(k.sk != nil){ - els = repsk(k.sk); + krp := Keyrep.sk(k.sk); + if(krp == nil) + return nil; + els = krp.els; sort = "private-key"; - }else - els = reppk(k.pk); - if(els == nil) - return nil; + }else{ + krp := Keyrep.pk(k.pk); + if(krp == nil) + return nil; + els = krp.els; + } rl: list of ref Sexp; - for(i := 0; i < len els; i++){ - (n, v) := els[i]; + for(; els != nil; els = tl els){ + (n, v) := hd els; a := pre0(v.iptobebytes()); - rl = ref Sexp.List(ref Sexp.String(n,nil) :: ref Sexp.Binary(a,nil) :: nil) :: rl; + rl = ref Sexp.List(ref Sexp.String(f2s("rsa", n),nil) :: ref Sexp.Binary(a,nil) :: nil) :: rl; } return ref Sexp.List(ref Sexp.String(sort, nil) :: ref Sexp.List(ref Sexp.String(k.sigalg(),nil) :: rev(rl)) :: nil); @@ -1141,27 +1115,8 @@ Key.eq(k1: self ref Key, k2: ref Key): int return 1; } } - if(k1.pk != nil && k2.pk != nil){ - pick rk1 := k1.pk { - RSA => - pick rk2 := k2.pk { - RSA => - return rk1.n.eq(rk2.n) && rk1.ek.eq(rk2.n); - } - DSA => - pick rk2 := k2.pk { - DSA => - return rk1.p.eq(rk2.p) && rk1.q.eq(rk2.q) && - rk1.alpha.eq(rk2.alpha) && rk1.key.eq(rk2.key); - } - Elgamal => - pick rk2 := k2.pk { - Elgamal => - return rk1.p.eq(rk2.p) && rk1.alpha.eq(rk2.alpha) && - rk1.key.eq(rk2.key); - } - } - } + if(k1.pk != nil && k2.pk != nil) + return kr->pktostr(k1.pk) == kr->pktostr(k2.pk); # TO DO return 0; } @@ -2077,133 +2032,250 @@ rev[T](l: list of T): list of T return rl; } +revt[S,T](l: list of (S,T)): list of (S,T) +{ + rl: list of (S,T); + for(; l != nil; l = tl l) + rl = hd l :: rl; + return rl; +} + # -# these are in the order given in draft-ietf-spki-cert-structure-06.txt +# the following should probably be in a separate Limbo library module, +# or provided in some way directly by Keyring # -mkpk(alg: string, els: array of (string, array of byte)): (ref Crypt->PK, int) +Keyrep: adt { + alg: string; + owner: string; + els: list of (string, ref IPint); + pick{ # keeps a type distance between public and private keys + PK => + SK => + } + + pk: fn(pk: ref Keyring->PK): ref Keyrep.PK; + sk: fn(sk: ref Keyring->SK): ref Keyrep.SK; + mkpk: fn(k: self ref Keyrep): (ref Keyring->PK, int); + mksk: fn(k: self ref Keyrep): ref Keyring->SK; + get: fn(k: self ref Keyrep, n: string): ref IPint; + getb: fn(k: self ref Keyrep, n: string): array of byte; + eq: fn(k1: self ref Keyrep, k2: ref Keyrep): int; +}; + +# +# convert an Inferno key into a (name, IPint) representation, +# where `names' maps between Inferno key component offsets and factotum names +# +keyextract(flds: list of string, names: list of (string, int)): list of (string, ref IPint) { - case alg { - "rsa" => - a := getparams(els, "e" :: "n" :: nil); - if(a == nil) - break; - return (ref PK.RSA(a[1], a[0]), a[1].bits()); - "dsa" => - a := getparams(els, "p" :: "g" :: "q" :: "y" :: nil); - if(a == nil) - break; - return (ref PK.DSA(a[0], a[2], a[1], a[3]), a[0].bits()); - "elgamal" => - a := getparams(els, "p" :: "g" :: "y" :: nil); - if(a == nil) - break; - return (ref PK.Elgamal(a[0], a[1], a[2]), a[0].bits()); + a := array[len flds] of ref IPint; + for(i := 0; i < len a; i++){ + a[i] = IPint.b64toip(hd flds); + flds = tl flds; } - return (nil, 0); + rl: list of (string, ref IPint); + for(; names != nil; names = tl names){ + (n, p) := hd names; + if(p < len a) + rl = (n, a[p]) :: rl; + } + return revt(rl); } -reppk(pk: ref Crypt->PK): array of (string, ref IPint) +Keyrep.pk(pk: ref Keyring->PK): ref Keyrep.PK { - pick k := pk { - RSA => - return array[] of {("e", k.ek), ("n", k.n)}; - DSA => - return array[] of {("p", k.p), ("g", k.alpha), ("q", k.q), ("y", k.key)}; - Elgamal => - return array[] of {("p", k.p), ("g", k.alpha), ("y", k.key)}; + s := kr->pktostr(pk); + (nf, flds) := sys->tokenize(s, "\n"); + if((nf -= 2) < 0) + return nil; + case hd flds { + "rsa" => + return ref Keyrep.PK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("ek",1), ("n",0)})); + "elgamal" => + return ref Keyrep.PK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("p",0), ("alpha",1), ("key",2)})); + "dsa" => + return ref Keyrep.PK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("p",0), ("alpha",2), ("q",1), ("key",3)})); * => return nil; } } -mksk(alg: string, els: array of (string, array of byte)): (ref Crypt->SK, ref Crypt->PK, int) +Keyrep.sk(pk: ref Keyring->SK): ref Keyrep.SK { - case alg { + s := kr->sktostr(pk); + (nf, flds) := sys->tokenize(s, "\n"); + if((nf -= 2) < 0) + return nil; + # the ordering of components below should match the one defined in the spki spec + case hd flds { "rsa" => - a := getparams(els, "e" :: "n" :: "d" :: "p" :: "q" :: "a" :: "b" :: "c" :: nil); - if(a == nil) - break; - # NB: p and q (and a and b) roles are reversed between libsec and pkcs - pk := ref PK.RSA(a[1], a[0]); - sk := ref SK.RSA(pk, a[2], a[4], a[3], a[6], a[5], a[7]); - return (sk, pk, a[1].bits()); - "dsa" => - a := getparams(els, "p" :: "g" :: "q" :: "y" :: "x" :: nil); - if(a == nil) - break; - pk := ref PK.DSA(a[0], a[2], a[1], a[3]); - sk := ref SK.DSA(pk, a[4]); - return (sk, pk, a[0].bits()); + return ref Keyrep.SK(hd flds, hd tl flds, + keyextract(tl tl flds,list of {("ek",1), ("n",0), ("!dk",2), ("!q",4), ("!p",3), ("!kq",6), ("!kp",5), ("!c2",7)})); # see comment elsewhere about p, q "elgamal" => - a := getparams(els, "p" :: "g" :: "y" :: "x" :: nil); - if(a == nil) - break; - pk := ref PK.Elgamal(a[0], a[1], a[2]); - sk := ref SK.Elgamal(pk, a[3]); - return (sk, pk, a[0].bits()); + return ref Keyrep.SK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("p",0), ("alpha",1), ("key",2), ("!secret",3)})); + "dsa" => + return ref Keyrep.SK(hd flds, hd tl flds, + keyextract(tl tl flds, list of {("p",0), ("alpha",2), ("q",1), ("key",3), ("!secret",4)})); + * => + return nil; } - return (nil, nil, 0); } -repsk(sk: ref Crypt->SK): array of (string, ref IPint) +Keyrep.get(k: self ref Keyrep, n: string): ref IPint { - pick k := sk { - RSA => - return array[] of - {("e", k.pk.ek), ("n", k.pk.n), ("d", k.dk), ("p", k.q), ("q", k.p), ("a", k.kq), ("b", k.kp), ("c", k.c2)}; - DSA => - return array[] of {("p", k.pk.p), ("g", k.pk.alpha), ("q", k.pk.q), ("y", k.pk.key), ("x", k.secret)}; - Elgamal => - return array[] of {("p", k.pk.p), ("g", k.pk.alpha), ("y", k.pk.key), ("x", k.secret)}; - * => + n1 := f2s("rsa", n); + for(el := k.els; el != nil; el = tl el) + if((hd el).t0 == n || (hd el).t0 == n1) + return (hd el).t1; + return nil; +} + +Keyrep.getb(k: self ref Keyrep, n: string): array of byte +{ + v := k.get(n); + if(v == nil) return nil; + return pre0(v.iptobebytes()); +} + +Keyrep.mkpk(k: self ref Keyrep): (ref Keyring->PK, int) +{ + case k.alg { + "rsa" => + e := k.get("ek"); + n := k.get("n"); + if(e == nil || n == nil) + return (nil, 0); + return (kr->strtopk(sys->sprint("rsa\n%s\n%s\n%s\n", k.owner, n.iptob64(), e.iptob64())), n.bits()); + * => + raise "Keyrep: unknown algorithm"; } } -sig2isig(sig: ref Signature): ref Crypt->PKsig +Keyrep.mksk(k: self ref Keyrep): ref Keyring->SK { - if(sig.params == nil) - return nil; - case sig.algs().t0 { + case k.alg { "rsa" => - ip := getp(sig.params, ""); - if(ip == nil) + e := k.get("ek"); + n := k.get("n"); + dk := k.get("!dk"); + p := k.get("!p"); + q := k.get("!q"); + kp := k.get("!kp"); + kq := k.get("!kq"); + c12 := k.get("!c2"); + if(e == nil || n == nil || dk == nil || p == nil || q == nil || kp == nil || kq == nil || c12 == nil) return nil; - return ref PKsig.RSA(ip); + return kr->strtosk(sys->sprint("rsa\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", + k.owner, n.iptob64(), e.iptob64(), dk.iptob64(), p.iptob64(), q.iptob64(), + kp.iptob64(), kq.iptob64(), c12.iptob64())); + * => + raise "Keyrep: unknown algorithm"; + } +} + +# +# account for naming differences between keyring and factotum, and spki. +# this might not be the best place for this. +# +s2f(s: string): string +{ + case s { + "e" => return "ek"; + "d" => return "!dk"; + "p" => return "!q"; # NB: p and q (kp and kq) roles are reversed between libsec and pkcs + "q" => return "!p"; + "a" => return "!kq"; + "b" => return "!kp"; + "c" => return "!c2"; + * => return s; + } +} + +f2s(alg: string, s: string): string +{ + case alg { + "rsa" => + case s { + "ek" => return "e"; + "!p" => return "q"; # see above + "!q" => return "p"; + "!dk" => return "d"; + "!kp" => return "b"; + "!kq" => return "a"; + "!c2" => return "c"; + } "dsa" => - a := getparams(sig.params, "r" :: "s" :: nil); - if(a == nil) - return nil; - return ref PKsig.DSA(a[0], a[1]); - "elgamal" => - a := getparams(sig.params, "r" :: "s" :: nil); - if(a == nil) - return nil; - return ref PKsig.Elgamal(a[0], a[1]); + case s { + "p" or "q" => return s; + "alpha" => return "g"; + "key" => return "y"; + } * => - return nil; + ; } + if(s != nil && s[0] == '!') + return s[1:]; + return s; } -getparams(v: array of (string, array of byte), names: list of string): array of ref IPint +Keyrep.eq(k1: self ref Keyrep, k2: ref Keyrep): int { - r := array[len names] of ref IPint; - for(i := 0; names != nil; names = tl names){ - r[i] = getp(v, hd names); - if(r[i] == nil) - return nil; - i++; + # n but n is small + for(l1 := k1.els; l1 != nil; l1 = tl l1){ + (n, v1) := hd l1; + v2 := k2.get(n); + if(v2 == nil || !v1.eq(v2)) + return 0; } - return r; + for(l2 := k2.els; l2 != nil; l2 = tl l2) + if(k1.get((hd l2).t0) == nil) + return 0; + return 1; } -getp(v: array of (string, array of byte), name: string): ref IPint +sig2icert(sig: ref Signature, signer: string, exp: int): ref Keyring->Certificate { - for(i := 0; i < len v; i++) - if(v[i].t0 == name) - return IPint.bebytestoip(v[i].t1); - return nil; + if(sig.sig == nil) + return nil; + s := sys->sprint("%s\n%s\n%s\n%d\n%s\n", "rsa", sig.hash.alg, signer, exp, base64->enc((hd sig.sig).t1)); +#sys->print("alg %s *** %s\n", sig.sa, base64->enc((hd sig.sig).t1)); + return kr->strtocert(s); +} + +icert2els(cert: ref Keyring->Certificate): (string, string, string, list of (string, array of byte)) +{ + s := kr->certtoattr(cert); + if(s == nil) + return (nil, nil, nil, nil); + (nil, l) := sys->tokenize(s, " "); # really need parseattr, and a better interface + vals: list of (string, array of byte); + alg, hashalg, signer: string; + for(; l != nil; l = tl l){ + (nf, fld) := sys->tokenize(hd l, "="); + if(nf != 2) + continue; + case hd fld { + "sigalg" => + (nf, fld) = sys->tokenize(hd tl fld, "-"); + if(nf != 2) + continue; + alg = hd fld; + hashalg = hd tl fld; + "signer" => + signer = hd tl fld; + "expires" => + ; # don't care + * => + vals = (hd fld, base16->dec(hd tl fld)) :: vals; + } + } + return (alg, hashalg, signer, revt(vals)); } # @@ -2271,27 +2343,23 @@ pkcs1_encode(ha: string, hash: array of byte, mlen: int): array of byte # rsacomp(block: array of byte, akey: ref Key): array of byte { - pick pk := akey.pk { - RSA => - x := IPint.bebytestoip(block); - y := x.expmod(pk.ek, pk.n); - ybytes := y.iptobebytes(); - #dump("rsacomp", ybytes); - k := 1024; # key.modlen; - ylen := len ybytes; - if(ylen < k) { - a := array[k] of { * => byte 0}; - a[k-ylen:] = ybytes[0:]; - ybytes = a; - } - else if(ylen > k) { - # assume it has leading zeros (mod should make it so) - a := array[k] of byte; - a[0:] = ybytes[ylen-k:]; - ybytes = a; - } - return ybytes; - * => - return nil; - } + key := Keyrep.pk(akey.pk); + x := kr->IPint.bebytestoip(block); + y := x.expmod(key.get("e"), key.get("n")); + ybytes := y.iptobebytes(); +#dump("rsacomp", ybytes); + k := 1024; # key.modlen; + ylen := len ybytes; + if(ylen < k) { + a := array[k] of { * => byte 0}; + a[k-ylen:] = ybytes[0:]; + ybytes = a; + } + else if(ylen > k) { + # assume it has leading zeros (mod should make it so) + a := array[k] of byte; + a[0:] = ybytes[ylen-k:]; + ybytes = a; + } + return ybytes; } diff --git a/appl/lib/spki/verifier.b b/appl/lib/spki/verifier.b index b2304a10..ffcdfcad 100644 --- a/appl/lib/spki/verifier.b +++ b/appl/lib/spki/verifier.b @@ -7,8 +7,9 @@ implement Verifier; include "sys.m"; sys: Sys; -include "ipints.m"; -include "crypt.m"; +include "keyring.m"; + kr: Keyring; + IPint: import kr; include "bufio.m"; bufio: Bufio; @@ -31,6 +32,7 @@ debug := 0; init() { sys = load Sys Sys->PATH; + kr = load Keyring Keyring->PATH; bufio = load Bufio Bufio->PATH; sexprs = load Sexprs Sexprs->PATH; spki = load SPKI SPKI->PATH; diff --git a/dis/auth/dsagen.dis b/dis/auth/dsagen.dis Binary files differindex 78fe7da1..758a1806 100644 --- a/dis/auth/dsagen.dis +++ b/dis/auth/dsagen.dis diff --git a/dis/auth/getpk.dis b/dis/auth/getpk.dis Binary files differindex dc6b16d7..3a522754 100644 --- a/dis/auth/getpk.dis +++ b/dis/auth/getpk.dis diff --git a/dis/auth/proto/rsa.dis b/dis/auth/proto/rsa.dis Binary files differindex bec1e441..bfddb804 100644 --- a/dis/auth/proto/rsa.dis +++ b/dis/auth/proto/rsa.dis diff --git a/dis/auth/rsagen.dis b/dis/auth/rsagen.dis Binary files differindex f30f9dd4..24734321 100644 --- a/dis/auth/rsagen.dis +++ b/dis/auth/rsagen.dis diff --git a/dis/auth/signer.dis b/dis/auth/signer.dis Binary files differindex e41b5930..f20c2f6f 100644 --- a/dis/auth/signer.dis +++ b/dis/auth/signer.dis diff --git a/dis/auth/verify.dis b/dis/auth/verify.dis Binary files differindex 619d0f02..e8daba6f 100644 --- a/dis/auth/verify.dis +++ b/dis/auth/verify.dis diff --git a/dis/cpu.dis b/dis/cpu.dis Binary files differindex a9f5aecf..edec37ab 100644 --- a/dis/cpu.dis +++ b/dis/cpu.dis diff --git a/dis/dial.dis b/dis/dial.dis Binary files differindex b716d75f..192730dc 100644 --- a/dis/dial.dis +++ b/dis/dial.dis diff --git a/dis/lib/factotum.dis b/dis/lib/factotum.dis Binary files differindex eb3ff1bf..868c7a84 100644 --- a/dis/lib/factotum.dis +++ b/dis/lib/factotum.dis diff --git a/dis/lib/spki/spki.dis b/dis/lib/spki/spki.dis Binary files differindex 0a1b53a9..d6b89a34 100644 --- a/dis/lib/spki/spki.dis +++ b/dis/lib/spki/spki.dis diff --git a/dis/lib/spki/verifier.dis b/dis/lib/spki/verifier.dis Binary files differindex 5e7e1a54..daab55f7 100644 --- a/dis/lib/spki/verifier.dis +++ b/dis/lib/spki/verifier.dis diff --git a/dis/listen.dis b/dis/listen.dis Binary files differindex 9884f417..021cf334 100644 --- a/dis/listen.dis +++ b/dis/listen.dis diff --git a/dis/sh/mpexpr.dis b/dis/sh/mpexpr.dis Binary files differindex 873fd1f8..41fc53e3 100644 --- a/dis/sh/mpexpr.dis +++ b/dis/sh/mpexpr.dis diff --git a/dis/spki/verify.dis b/dis/spki/verify.dis Binary files differindex 86fa6042..c1560f3f 100644 --- a/dis/spki/verify.dis +++ b/dis/spki/verify.dis diff --git a/dis/styxlisten.dis b/dis/styxlisten.dis Binary files differindex 549a469f..6b927cf6 100644 --- a/dis/styxlisten.dis +++ b/dis/styxlisten.dis diff --git a/emu/Nt/ipif.c b/emu/Nt/ipif.c index f8c5c043..d2cf4521 100644 --- a/emu/Nt/ipif.c +++ b/emu/Nt/ipif.c @@ -9,9 +9,6 @@ #include "ip.h" #include "error.h" -typedef int socklen_t; /* Windows is leading edge as always */ - - extern int SOCK_SELECT; char Enotv4[] = "address not IPv4"; diff --git a/include/version.h b/include/version.h index f092c2ad..f3babaa1 100644 --- a/include/version.h +++ b/include/version.h @@ -1 +1 @@ -#define VERSION "Fourth Edition (20110117)" +#define VERSION "Fourth Edition (20110104)" diff --git a/man/2/factotum b/man/2/factotum index 1d243495..338e6022 100644 --- a/man/2/factotum +++ b/man/2/factotum @@ -12,7 +12,6 @@ Authinfo: adt{ suid: string; # ID on server cap: string; # capability (only valid on server side) secret: array of byte; # key for encryption - attrs: list of ref Attr; # attributes after authentication }; AuthRpcMax: con \fR...\fP; @@ -116,8 +115,6 @@ value containing the agreed user IDs, a capability for that is valid only on the server, and an array of bytes containing a shared secret that can be used by client and server to create encryption and hashing keys for the conversation. -There might also be an optional list of attributes provided during the authentication protocol; -which of those attributes, if any, are authenticated depends on the protocol. .PP .B Getuserpasswd returns a tuple diff --git a/module/factotum.m b/module/factotum.m index beb238cc..5d1df5f8 100644 --- a/module/factotum.m +++ b/module/factotum.m @@ -9,10 +9,10 @@ Factotum: module suid: string; # server id cap: string; # capability (only valid on server side) secret: array of byte; - attrs: list of ref Attr; # attributes after authentication + # TO DO: add attrs - unpack: fn(a: array of byte): (int, ref Authinfo); # excludes attributes - read: fn(facfd: ref Sys->FD): ref Authinfo; # includes attributes + unpack: fn(a: array of byte): (int, ref Authinfo); + read: fn(fd: ref Sys->FD): ref Authinfo; }; mount: fn(fd: ref Sys->FD, mnt: string, flags: int, aname: string, keyspec: string): (int, ref Authinfo); diff --git a/module/spki.m b/module/spki.m index 3ddeb661..fbb82ba7 100644 --- a/module/spki.m +++ b/module/spki.m @@ -37,8 +37,8 @@ SPKI: module }; Key: adt { - pk: ref Crypt->PK; # either pk/sk or hash might be nil - sk: ref Crypt->SK; + pk: ref Keyring->PK; # either pk/sk or hash might be nil + sk: ref Keyring->SK; nbits: int; halg: string; # basic signature hash algorithm henc: string; # pre-signature encoding @@ -49,9 +49,9 @@ SPKI: module ishash: fn(k: self ref Key): int; public: fn(k: self ref Key): ref Key; sigalg: fn(k: self ref Key): string; - text: fn(k: self ref Key): string; + text: fn(k: self ref Key): string; sexp: fn(k: self ref Key): ref Sexprs->Sexp; - eq: fn(k1: self ref Key, k2: ref Key): int; + eq: fn(k1: self ref Key, k2: ref Key): int; }; Name: adt { @@ -120,7 +120,7 @@ SPKI: module hash: ref Hash; key: ref Key; # find by hash if necessary sa: string; # alg[-[encoding-]hash] - params: array of (string, array of byte); + sig: list of (string, array of byte); algs: fn(s: self ref Signature): (string, string, string); sexp: fn(s: self ref Signature): ref Sexprs->Sexp; @@ -197,7 +197,7 @@ SPKI: module # signature checking checksig: fn(c: ref Cert, sig: ref Signature): string; - #sig2icert: fn(sig: ref Signature, signer: string, exp: int): ref Oldauth->Certificate; + sig2icert: fn(sig: ref Signature, signer: string, exp: int): ref Keyring->Certificate; # signature making signcert: fn(c: ref Cert, sigalg: string, key: ref Key): (ref Signature, string); |
