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

📄 keyfs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
			if(strcmp(data, status[i]) == 0){				f->user->status = i;				break;			}		if(i == Smax)			return "unknown status";		f->user->bad = 0;		thdr.count = n;		break;	case Qexpire:		data[n] = '\0';		if(p = strchr(data, '\n'))			*p = '\0';		else			p = &data[n];		if(strcmp(data, "never") == 0)			expire = 0;		else{			expire = strtoul(data, &data, 10);			if(data != p)				return "bad expiration date";		}		f->user->expire = expire;		f->user->warnings = 0;		thdr.count = n;		break;	case Qlog:		data[n] = '\0';		if(strcmp(data, "good") == 0)			f->user->bad = 0;		else			f->user->bad++;		if(f->user->bad && ((f->user->bad)%MAXBAD) == 0)			f->user->purgatory = time(0) + f->user->bad;		return 0;	case Qwarnings:		data[n] = '\0';		f->user->warnings = strtoul(data, 0, 10);		thdr.count = n;		break;	case Qroot:	case Quser:	default:		return "permission denied";	}	writeusers();	return 0;}char *Remove(Fid *f){	if(!f->busy)		return "permission denied";	if(f->qtype == Qwarnings)		f->user->warnings = 0;	else if(f->qtype == Quser)		removeuser(f->user);	else {		Clunk(f);		return "permission denied";	}	Clunk(f);	writeusers();	return 0;}char *Stat(Fid *f){	static uchar statbuf[1024];	if(!f->busy)		return "stat on unattached fid";	thdr.nstat = dostat(f->user, f->qtype, statbuf, sizeof statbuf);	if(thdr.nstat <= BIT16SZ)		return "stat buffer too small";	thdr.stat = statbuf;	return 0;}char *Wstat(Fid *f){	Dir d;	int n;	char buf[1024];	if(!f->busy || f->qtype != Quser)		return "permission denied";	if(rhdr.nstat > sizeof buf)		return "wstat buffer too big";	if(convM2D(rhdr.stat, rhdr.nstat, &d, buf) == 0)		return "bad stat buffer";	n = strlen(d.name);	if(n == 0 || n >= Namelen)		return "bad user name";	if(finduser(d.name))		return "user already exists";	if(!removeuser(f->user))		return "user previously removed";	free(f->user->name);	f->user->name = strdup(d.name);	if(f->user->name == nil)		error("wstat: malloc failed: %r");	insertuser(f->user);	writeusers();	return 0;}Qidmkqid(User *u, ulong qtype){	Qid q;	q.vers = 0;	q.path = qtype;	if(u)		q.path |= u->uniq * 0x100;	if(qtype == Quser || qtype == Qroot)		q.type = QTDIR;	else		q.type = QTFILE;	return q;}intdostat(User *user, ulong qtype, void *p, int n){	Dir d;	if(qtype == Quser)		d.name = user->name;	else		d.name = qinfo[qtype];	d.uid = d.gid = d.muid = "auth";	d.qid = mkqid(user, qtype);	if(d.qid.type & QTDIR)		d.mode = 0777|DMDIR;	else		d.mode = 0666;	d.atime = d.mtime = time(0);	d.length = 0;	return convD2M(&d, p, n);}intpassline(Biobuf *b, void *vbuf){	char *buf = vbuf;	if(Bread(b, buf, KEYDBLEN) != KEYDBLEN)		return 0;	decrypt(authkey, buf, KEYDBLEN);	buf[Namelen-1] = '\0';	return 1;}voidrandombytes(uchar *p, int len){	int i, fd;	fd = open("/dev/random", OREAD);	if(fd < 0){		fprint(2, "keyfs: can't open /dev/random, using rand()\n");		srand(time(0));		for(i = 0; i < len; i++)			p[i] = rand();		return;	}	read(fd, p, len);	close(fd);}voidoldCBCencrypt(char *key7, uchar *p, int len){	uchar ivec[8];	uchar key[8];	DESstate s;	memset(ivec, 0, 8);	des56to64((uchar*)key7, key);	setupDESstate(&s, key, ivec);	desCBCencrypt((uchar*)p, len, &s);}voidoldCBCdecrypt(char *key7, uchar *p, int len){	uchar ivec[8];	uchar key[8];	DESstate s;	memset(ivec, 0, 8);	des56to64((uchar*)key7, key);	setupDESstate(&s, key, ivec);	desCBCdecrypt((uchar*)p, len, &s);}voidwriteusers(void){	int fd, i, nu;	User *u;	uchar *p, *buf;	ulong expire;	/* count users */	nu = 0;	for(i = 0; i < Nuser; i++)		for(u = users[i]; u; u = u->link)			nu++;	/* pack into buffer */	buf = malloc(KEYDBOFF + nu*KEYDBLEN);	if(buf == 0){		fprint(2, "keyfs: can't write keys file, out of memory\n");		return;	}	p = buf;	randombytes(p, KEYDBOFF);	p += KEYDBOFF;	for(i = 0; i < Nuser; i++)		for(u = users[i]; u; u = u->link){			strncpy((char*)p, u->name, Namelen);			p += Namelen;			memmove(p, u->key, DESKEYLEN);			p += DESKEYLEN;			*p++ = u->status;			*p++ = u->warnings;			expire = u->expire;			*p++ = expire;			*p++ = expire >> 8;			*p++ = expire >> 16;			*p++ = expire >> 24;			memmove(p, u->secret, SECRETLEN);			p += SECRETLEN;		}	/* encrypt */	oldCBCencrypt(authkey, buf, p - buf);	/* write file */	fd = create(userkeys, OWRITE, 0660);	if(fd < 0){		free(buf);		fprint(2, "keyfs: can't write keys file\n");		return;	}	if(write(fd, buf, p - buf) != (p - buf))		fprint(2, "keyfs: can't write keys file\n");	free(buf);	close(fd);}intreadusers(void){	int fd, i, n, nu;	uchar *p, *buf, *ep;	User *u;	Dir *d;	/* read file into an array */	fd = open(userkeys, OREAD);	if(fd < 0)		return 0;	d = dirfstat(fd);	if(d == nil){		close(fd);		return 0;	}	buf = malloc(d->length);	if(buf == 0){		close(fd);		free(d);		return 0;	}	n = readn(fd, buf, d->length);	close(fd);	free(d);	if(n != d->length){		free(buf);		return 0;	}	/* decrypt */	n -= n % KEYDBLEN;	oldCBCdecrypt(authkey, buf, n);	/* unpack */	nu = 0;	for(i = KEYDBOFF; i < n; i += KEYDBLEN){		ep = buf + i;		u = finduser((char*)ep);		if(u == 0)			u = installuser((char*)ep);		memmove(u->key, ep + Namelen, DESKEYLEN);		p = ep + Namelen + DESKEYLEN;		u->status = *p++;		u->warnings = *p++;		if(u->status >= Smax)			fprint(2, "keyfs: warning: bad status in key file\n");		u->expire = p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24);		p += 4;		memmove(u->secret, p, SECRETLEN);		u->secret[SECRETLEN-1] = 0;		nu++;	}	free(buf);	print("%d keys read\n", nu);	return 1;}User *installuser(char *name){	User *u;	int h;	h = hash(name);	u = emalloc(sizeof *u);	u->name = strdup(name);	if(u->name == nil)		error("malloc failed: %r");	u->removed = 0;	u->ref = 0;	u->purgatory = 0;	u->expire = 0;	u->status = Sok;	u->bad = 0;	u->warnings = 0;	u->uniq = uniq++;	u->link = users[h];	users[h] = u;	return u;}User *finduser(char *name){	User *u;	for(u = users[hash(name)]; u; u = u->link)		if(strcmp(name, u->name) == 0)			return u;	return 0;}intremoveuser(User *user){	User *u, **last;	char *name;	user->removed = 1;	name = user->name;	last = &users[hash(name)];	for(u = *last; u; u = *last){		if(strcmp(name, u->name) == 0){			*last = u->link;			return 1;		}		last = &u->link;	}	return 0;}voidinsertuser(User *user){	int h;	user->removed = 0;	h = hash(user->name);	user->link = users[h];	users[h] = user;}ulonghash(char *s){	ulong h;	h = 0;	while(*s)		h = (h << 1) ^ *s++;	return h % Nuser;}Fid *findfid(int fid){	Fid *f, *ff;	ff = 0;	for(f = fids; f; f = f->next)		if(f->fid == fid)			return f;		else if(!ff && !f->busy)			ff = f;	if(ff){		ff->fid = fid;		return ff;	}	f = emalloc(sizeof *f);	f->fid = fid;	f->busy = 0;	f->user = 0;	f->next = fids;	fids = f;	return f;}voidio(int in, int out){	char *err;	int n;	long now, lastwarning;	/* after restart, let the system settle for 5 mins before warning */	lastwarning = time(0) - 24*60*60 + 5*60;	for(;;){		n = read9pmsg(in, mdata, messagesize);		if(n == 0)			continue;		if(n < 0)			error("mount read %d", n);		if(convM2S(mdata, n, &rhdr) == 0)			continue;		if(newkeys())			readusers();		thdr.data = (char*)mdata + IOHDRSZ;		thdr.fid = rhdr.fid;		if(!fcalls[rhdr.type])			err = "fcall request";		else					err = (*fcalls[rhdr.type])(findfid(rhdr.fid));		thdr.tag = rhdr.tag;		thdr.type = rhdr.type+1;		if(err){			thdr.type = Rerror;			thdr.ename = err;		}		n = convS2M(&thdr, mdata, messagesize);		if(write(out, mdata, n) != n)			error("mount write");		now = time(0);		if(warnarg && (now - lastwarning > 24*60*60)){			syslog(0, "auth", "keyfs starting warnings: %lux %lux", now, lastwarning);			warning();			lastwarning = now;		}	}}intnewkeys(void){	Dir *d;	static long ftime;	d = dirstat(userkeys);	if(d == nil)		return 0;	if(d->mtime > ftime){		ftime = d->mtime;		free(d);		return 1;	}	free(d);	return 0;}void *emalloc(ulong n){	void *p;	if(p = malloc(n))		return p;	error("out of memory");	return 0;		/* not reached */}voidwarning(void){	int i;	char buf[64];	snprint(buf, sizeof buf, "-%s", warnarg);	switch(rfork(RFPROC|RFNAMEG|RFNOTEG|RFNOWAIT|RFENVG|RFFDG)){	case 0:		i = open("/sys/log/auth", OWRITE);		if(i >= 0){			dup(i, 2);			seek(2, 0, 2);			close(i);		}		execl("/bin/auth/warning", "warning", warnarg, nil);		error("can't exec warning");	}}

⌨️ 快捷键说明

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