summaryrefslogtreecommitdiff
path: root/appl/cmd/getauthinfo.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/getauthinfo.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/cmd/getauthinfo.b')
-rw-r--r--appl/cmd/getauthinfo.b185
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";
+}