diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/getauthinfo.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/cmd/getauthinfo.b')
| -rw-r--r-- | appl/cmd/getauthinfo.b | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/appl/cmd/getauthinfo.b b/appl/cmd/getauthinfo.b new file mode 100644 index 00000000..84c0f1d4 --- /dev/null +++ b/appl/cmd/getauthinfo.b @@ -0,0 +1,185 @@ +implement Getauthinfo; + +# +# get and save a certificate from a signer in exchange for a valid secret +# + +include "sys.m"; + sys: Sys; + stdin, stdout, stderr: ref Sys->FD; + +include "draw.m"; + +include "keyring.m"; + kr: Keyring; + +include "security.m"; + login: Login; + +include "string.m"; + str: String; + +include "promptstring.b"; + +Getauthinfo: module +{ + init: fn(ctxt: ref Draw->Context, argv: list of string); +}; + +usage() +{ + sys->fprint(stderr, "usage: getauthinfo {net!hostname | default | /file}\n"); + raise "fail:usage"; +} + +init(nil: ref Draw->Context, argv: list of string) +{ + sys = load Sys Sys->PATH; + stdin = sys->fildes(0); + stdout = sys->fildes(1); + stderr = sys->fildes(2); + + # Disable echoing in RAWON mode + RAWON_STR = nil; + + argv = tl argv; + if(argv == nil) + usage(); + keyname := hd argv; + if(keyname == nil) + usage(); + + kr = load Keyring Keyring->PATH; + if(kr == nil) + nomod(Keyring->PATH); + + str = load String String->PATH; + if(str == nil) + nomod(String->PATH); + + login = load Login Login->PATH; + if(login == nil) + nomod(Login->PATH); + + user := user(); + path := keyname; + if(path[0] != '/' || len path < 2 || path[0:2] != "./") + path = "/usr/" + user + "/keyring/" + keyname; + + signer := defaultsigner(); + if(signer == nil){ + sys->fprint(stderr, "getauthinfo: warning: can't get default signer server name\n"); + signer = "$SIGNER"; + } + + passwd := ""; + save := "yes"; + redo := "yes"; + for(;;) { + signer = promptstring("use signer", signer, RAWOFF); + user = promptstring("remote user name", user, RAWOFF); + passwd = promptstring("password", passwd, RAWON); + + info := logon(user, passwd, signer, path, save); + if(info != nil) + break; + } +} + +logon(user, passwd, server, path, save: string): ref Keyring->Authinfo +{ + (err, info) := login->login(user, passwd, "net!"+server+"!inflogin"); + if(err != nil){ + sys->fprint(stderr, "getauthinfo: failed to authenticate: %s\n", err); + return nil; + } + + # save the info somewhere for later access + save = promptstring("save in file", save, RAWOFF); + if(save[0] != 'y'){ + (dir, file) := str->splitr(path, "/"); + if(sys->bind("#s", dir, Sys->MBEFORE) < 0){ + sys->fprint(stderr, "getauthinfo: can't bind file channel on %s: %r\n", dir); + return nil; + } + filio := sys->file2chan(dir, file); + if(filio == nil) { + sys->fprint(stderr, "getauthinfo: can't make file2chan %s: %r\n", path); + return nil; + } + sync := chan of int; + spawn infofile(filio, sync); + <-sync; + } + + if(kr->writeauthinfo(path, info) < 0) { + sys->fprint(stderr, "getauthinfo: can't write certificate to %s: %r\n", path); + return nil; + } + + return info; +} + +user(): string +{ + sys = load Sys Sys->PATH; + + fd := sys->open("/dev/user", sys->OREAD); + if(fd == nil) + return ""; + + buf := array[128] of byte; + n := sys->read(fd, buf, len buf); + if(n < 0) + return ""; + + return string buf[0:n]; +} + +infofile(fileio: ref Sys->FileIO, sync: chan of int) +{ + infodata := array[0] of byte; + + sys->pctl(Sys->NEWPGRP|Sys->NEWFD, nil); + sync <-= 1; + + for(;;) alt { + (off, nbytes, fid, rc) := <-fileio.read => + if(rc == nil) + break; + if(off > len infodata){ + rc <-= (nil, nil); + } else { + if(off + nbytes > len infodata) + nbytes = len infodata - off; + rc <-= (infodata[off:off+nbytes], nil); + } + + (off, data, fid, wc) := <-fileio.write => + if(wc == nil) + break; + + if(off != len infodata){ + wc <-= (0, "cannot be rewritten"); + } else { + nid := array[len infodata+len data] of byte; + nid[0:] = infodata; + nid[len infodata:] = data; + infodata = nid; + wc <-= (len data, nil); + } + data = nil; + } +} + +# get default signer server name +defaultsigner(): string +{ + return "$SIGNER"; +} + +nomod(s: string) +{ + sys->fprint(stderr, "getauthinfo: can't load %s: %r\n", s); + raise "fail:load"; +} |
