⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "dat.h"static char secstore[100];   /* server name *//* bind in the default network and cs */static intbindnetcs(void){	int srvfd;	if(access("/net/tcp", AEXIST) < 0)		bind("#I", "/net", MBEFORE);	if(access("/net/cs", AEXIST) < 0){		if((srvfd = open("#s/cs", ORDWR)) >= 0){			if(mount(srvfd, -1, "/net", MBEFORE, "") >= 0)				return 0;			close(srvfd);		}		return -1;	}	return 0;}int_authdial(char *net, char *authdom){	int fd, vanilla;	vanilla = net==nil || strcmp(net, "/net")==0;	if(!vanilla || bindnetcs()>=0)		return authdial(net, authdom);	/*	 * If we failed to mount /srv/cs, assume that	 * we're still bootstrapping the system and dial	 * the one auth server passed to us on the command line.	 * In normal operation, it is important *not* to do this,	 * because the bootstrap auth server is only good for	 * a single auth domain.	 *	 * The ticket request code should really check the	 * remote authentication domain too.	 */	/* use the auth sever passed to us as an arg */	if(authaddr == nil)		return -1;	fd = dial(netmkaddr(authaddr, "il", "566"), 0, 0, 0);	if(fd >= 0)		return fd;	return dial(netmkaddr(authaddr, "tcp", "567"), 0, 0, 0);}intsecdial(void){	char *p, buf[80], *f[3];	int fd, nf;	p = secstore; /* take it from writehostowner, if set there */	if(*p == 0)	  /* else use the authserver */		p = "$auth";	if(bindnetcs() >= 0)		return dial(netmkaddr(p, "net", "secstore"), 0, 0, 0);	/* translate $auth ourselves.	 * authaddr is something like il!host!566 or tcp!host!567.	 * extract host, accounting for a change of format to something	 * like il!host or tcp!host or host.	 */	if(strcmp(p, "$auth")==0){		if(authaddr == nil)			return -1;		safecpy(buf, authaddr, sizeof buf);		nf = getfields(buf, f, nelem(f), 0, "!");		switch(nf){		default:			return -1;		case 1:			p = f[0];			break;		case 2:		case 3:			p = f[1];			break;		}	}	fd = dial(netmkaddr(p, "tcp", "5356"), 0, 0, 0);	if(fd >= 0)		return fd;	return -1;}/* *  prompt user for a key.  don't care about memory leaks, runs standalone */static Attr*promptforkey(char *params){	char *v;	int fd;	Attr *a, *attr;	char *def;	fd = open("/dev/cons", ORDWR);	if(fd < 0)		sysfatal("opening /dev/cons: %r");	attr = _parseattr(params);	fprint(fd, "\n!Adding key:");	for(a=attr; a; a=a->next)		if(a->type != AttrQuery && a->name[0] != '!')			fprint(fd, " %q=%q", a->name, a->val);	fprint(fd, "\n");	for(a=attr; a; a=a->next){		v = a->name;		if(a->type != AttrQuery || v[0]=='!')			continue;		def = nil;		if(strcmp(v, "user") == 0)			def = getuser();		a->val = readcons(v, def, 0);		if(a->val == nil)			sysfatal("user terminated key input");		a->type = AttrNameval;	}	for(a=attr; a; a=a->next){		v = a->name;		if(a->type != AttrQuery || v[0]!='!')			continue;		def = nil;		if(strcmp(v+1, "user") == 0)			def = getuser();		a->val = readcons(v+1, def, 1);		if(a->val == nil)			sysfatal("user terminated key input");		a->type = AttrNameval;	}	fprint(fd, "!\n");	close(fd);	return attr;}/* *  send a key to the mounted factotum */static intsendkey(Attr *attr){	int fd, rv;	char buf[1024];	fd = open("/mnt/factotum/ctl", ORDWR);	if(fd < 0)		sysfatal("opening /mnt/factotum/ctl: %r");	rv = fprint(fd, "key %A\n", attr);	read(fd, buf, sizeof buf);	close(fd);	return rv;}/* askuser */voidaskuser(char *params){	Attr *attr;	attr = promptforkey(params);	if(attr == nil)		sysfatal("no key supplied");	if(sendkey(attr) < 0)		sysfatal("sending key to factotum: %r");}ulong conftaggen;intcanusekey(Fsstate *fss, Key *k){	int i;	if(_strfindattr(k->attr, "confirm")){		for(i=0; i<fss->nconf; i++)			if(fss->conf[i].key == k)				return fss->conf[i].canuse;		if(fss->nconf%16 == 0)			fss->conf = erealloc(fss->conf, (fss->nconf+16)*(sizeof(fss->conf[0])));		fss->conf[fss->nconf].key = k;		k->ref++;		fss->conf[fss->nconf].canuse = -1;		fss->conf[fss->nconf].tag = conftaggen++;		fss->nconf++;		return -1;	}	return 1;}/* closekey */voidclosekey(Key *k){	if(k == nil)		return;	if(--k->ref != 0)		return;	if(k->proto && k->proto->closekey)		(*k->proto->closekey)(k);	_freeattr(k->attr);	_freeattr(k->privattr);	k->attr = (void*)~1;	k->privattr = (void*)~1;	k->proto = nil;	free(k);}static uchar*pstring(uchar *p, uchar *e, char *s){	uint n;	if(p == nil)		return nil;	if(s == nil)		s = "";	n = strlen(s);	if(p+n+BIT16SZ >= e)		return nil;	PBIT16(p, n);	p += BIT16SZ;	memmove(p, s, n);	p += n;	return p;}static uchar*pcarray(uchar *p, uchar *e, uchar *s, uint n){	if(p == nil)		return nil;	if(s == nil){		if(n > 0)			sysfatal("pcarray");		s = (uchar*)"";	}	if(p+n+BIT16SZ >= e)		return nil;	PBIT16(p, n);	p += BIT16SZ;	memmove(p, s, n);	p += n;	return p;}uchar*convAI2M(AuthInfo *ai, uchar *p, int n){	uchar *e = p+n;	p = pstring(p, e, ai->cuid);	p = pstring(p, e, ai->suid);	p = pstring(p, e, ai->cap);	p = pcarray(p, e, ai->secret, ai->nsecret);	return p;}intfailure(Fsstate *s, char *fmt, ...){	char e[ERRMAX];	va_list arg;	if(fmt == nil)		rerrstr(s->err, sizeof(s->err));	else {		va_start(arg, fmt);		snprint(e, sizeof e, fmt, arg);		va_end(arg);		strecpy(s->err, s->err+sizeof(s->err), e);		errstr(e, sizeof e);	}	flog("%d: failure %s", s->seqnum, s->err);	return RpcFailure;}static inthasqueries(Attr *a){	for(; a; a=a->next)		if(a->type == AttrQuery)			return 1;	return 0;}char *ignored[] = {	"role",	"disabled",};static intignoreattr(char *s){	int i;	for(i=0; i<nelem(ignored); i++)		if(strcmp(ignored[i], s)==0)			return 1;	return 0;}Keyinfo*mkkeyinfo(Keyinfo *k, Fsstate *fss, Attr *attr){	memset(k, 0, sizeof *k);	k->fss = fss;	k->user = fss->sysuser;	if(attr)		k->attr = attr;	else		k->attr = fss->attr;	return k;}intfindkey(Key **ret, Keyinfo *ki, char *fmt, ...){	int i, s, nmatch;	char buf[1024], *p, *who;	va_list arg;	Attr *a, *attr0, *attr1, *attr2, *attr3, **l;	Key *k;	*ret = nil;	who = ki->user;	attr0 = ki->attr;	if(fmt){		va_start(arg, fmt);		vseprint(buf, buf+sizeof buf, fmt, arg);		va_end(arg);		attr1 = _parseattr(buf);	}else		attr1 = nil;	if(who && strcmp(who, owner) == 0)		who = nil;	if(who){		snprint(buf, sizeof buf, "owner=%q", who);		attr2 = _parseattr(buf);		attr3 = _parseattr("owner=*");	}else		attr2 = attr3 = nil;	p = _strfindattr(attr0, "proto");	if(p == nil)		p = _strfindattr(attr1, "proto");	if(p && findproto(p) == nil){		werrstr("unknown protocol %s", p);		_freeattr(attr1);		_freeattr(attr2);		_freeattr(attr3);		return failure(ki->fss, nil);	}	nmatch = 0; 	for(i=0; i<ring->nkey; i++){		k = ring->key[i];		if(_strfindattr(k->attr, "disabled") && !ki->usedisabled)			continue;		if(matchattr(attr0, k->attr, k->privattr) && matchattr(attr1, k->attr, k->privattr)){			/* check ownership */			if(!matchattr(attr2, k->attr, nil) && !matchattr(attr3, k->attr, nil))				continue;			if(nmatch++ < ki->skip)				continue;			if(!ki->noconf){				switch(canusekey(ki->fss, k)){				case -1:					_freeattr(attr1);					return RpcConfirm;				case 0:					continue;				case 1:					break;				}			}			_freeattr(attr1);			_freeattr(attr2);			_freeattr(attr3);			k->ref++;			*ret = k;			return RpcOk;		}	}	flog("%d: no key matches %A %A %A %A", ki->fss->seqnum, attr0, attr1, attr2, attr3);	werrstr("no key matches %A %A", attr0, attr1);	_freeattr(attr2);	_freeattr(attr3);	s = RpcFailure;	if(askforkeys && who==nil && (hasqueries(attr0) || hasqueries(attr1))){		if(nmatch == 0){			attr0 = _copyattr(attr0);			for(l=&attr0; *l; l=&(*l)->next)				;			*l = attr1;			for(l=&attr0; *l; ){				if(ignoreattr((*l)->name)){					a = *l;					*l = (*l)->next;					a->next = nil;					_freeattr(a);				}else					l = &(*l)->next;			}			attr0 = sortattr(attr0);			snprint(ki->fss->keyinfo, sizeof ki->fss->keyinfo, "%A", attr0);			_freeattr(attr0);			attr1 = nil;	/* attr1 was linked to attr0 */		}else			ki->fss->keyinfo[0] = '\0';		s = RpcNeedkey;	}	_freeattr(attr1);	if(s == RpcFailure)		return failure(ki->fss, nil);	/* loads error string */	return s;}intfindp9authkey(Key **k, Fsstate *fss){	char *dom;	Keyinfo ki;	/*	 * We don't use fss->attr here because we don't	 * care about what the user name is set to, for instance.	 */	mkkeyinfo(&ki, fss, nil);	ki.attr = nil;	ki.user = nil;	if(dom = _strfindattr(fss->attr, "dom"))		return findkey(k, &ki, "proto=p9sk1 dom=%q role=server user?", dom);	else		return findkey(k, &ki, "proto=p9sk1 role=server dom? user?");}Proto*findproto(char *name){	int i;	for(i=0; prototab[i]; i++)		if(strcmp(name, prototab[i]->name) == 0)			return prototab[i];	return nil;}char*getnvramkey(int flag, char **secstorepw){	char *s;	Nvrsafe safe;	char spw[CONFIGLEN+1];	int i;	memset(&safe, 0, sizeof safe);	/*	 * readnvram can return -1 meaning nvram wasn't written,	 * but safe still holds good data.	 */	if(readnvram(&safe, flag)<0 && safe.authid[0]==0) 		return nil;	/*	 *  we're using the config area to hold the secstore	 *  password.  if there's anything there, return it.	 */	memmove(spw, safe.config, CONFIGLEN);	spw[CONFIGLEN] = 0;	if(spw[0] != 0)		*secstorepw = estrdup(spw);	/*	 *  only use nvram key if it is non-zero	 */	for(i = 0; i < DESKEYLEN; i++)		if(safe.machkey[i] != 0)			break;	if(i == DESKEYLEN)		return nil;	s = emalloc(512);	fmtinstall('H', encodefmt);	sprint(s, "key proto=p9sk1 user=%q dom=%q !hex=%.*H !password=______", 		safe.authid, safe.authdom, DESKEYLEN, safe.machkey);	writehostowner(safe.authid);	return s;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -