forsyth20121205-174063a80cc13 years agoHistory
185 lines · 3.6 KB · Brainfuck
RawDownload
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 namedefaultsigner(): string{	return "$SIGNER";} nomod(s: string){	sys->fprint(stderr, "getauthinfo: can't load %s: %r\n", s);	raise "fail:load";}