230 lines · 3.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <authsrv.h>#include <fcall.h>#include <bio.h>#include <mp.h>#include <libsec.h>#include "authcmdlib.h" typedef struct User User;struct User{	char	*name;	char	key[DESKEYLEN];	char	secret[SECRETLEN];	ulong	expire;			/* 0 == never */	uchar	status;	ulong	bad;			/* number of consecutive bad authentication attempts */	int	ref;	char	removed;	uchar	warnings;	long	purgatory;		/* time purgatory ends */	ulong	uniq;	User	*link;}; enum{	Namelen	= ANAMELEN,}; enum{	Sok,	Sdisabled,	Smax,}; char authkey[8];char *userkeys; #pragma	varargck	type	"W"	char* intwierdfmt(Fmt *f){	char *s, buf[ANAMELEN*4+1];	int i, j, n;	Rune r; 	s = va_arg(f->args, char*); 	j = 0;	for(i = 0; i < ANAMELEN; i += n){		n = chartorune(&r, s+i);		if(r == Runeerror)			j += sprint(buf+j, "[%.2x]", buf[i]);		else if(r < ' ')			j += sprint(buf+j, "[%.2x]", r);		else if(r == ' ' || r == '/')			j += sprint(buf+j, "[%c]", r);		else			j += sprint(buf+j, "%C", r);	}	return fmtstrcpy(f, buf);} intcheckuser(char *user, int nu){	char buf[ANAMELEN+1];	int i, n, rv;	Rune r; 	memset(buf, 0, sizeof buf);	memcpy(buf, user, ANAMELEN); 	if(buf[ANAMELEN-1] != 0){		fprint(2, "name %d no termination: %W\n", nu, buf);		return -1;	} 	rv = 0;	for(i = 0; buf[i]; i += n){		n = chartorune(&r, buf+i);		if(r == Runeerror){//			fprint(2, "name %W bad rune byte %d\n", buf, i);			rv = -1;		}		if(r <= ' ' || r == '/'){//			fprint(2, "name %W bad char %C\n", buf, r);			rv = -1;		}	} 	if(i == 0){		fprint(2, "nil name\n");		return -1;	}	if(rv == -1)		fprint(2, "name %d bad: %W\n", nu, buf);	return rv;} voidprintuser(User *u, int nu){	print("%d: %.28s %ux %ux %.11lud\n", nu, u->name, u->status, u->warnings, u->expire); } 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); } User U; 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){		fprint(2, "dirfstat: %r\n");		close(fd);		return 0;	}	buf = malloc(d->length);	if(buf == 0){		fprint(2, "malloc: %r\n");		close(fd);		free(d);		return 0;	}	n = readn(fd, buf, d->length);	close(fd);	free(d);	if(n != d->length){		fprint(2, "readn: %r\n");		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;		if(checkuser((char*)ep, i/KEYDBLEN))			continue;u = &U;memset(u, 0, sizeof *u);u->name = (char*)ep;//		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++;printuser(u, i/KEYDBLEN);	}	free(buf); 	print("%d keys read\n", nu);	return 1;} voidusage(void){	fprint(2, "usage: keyvalidate [-k keyfile] [-p]\n");	exits("usage");} voidmain(int argc, char *argv[]){	int p[2], usepass; 	userkeys = "/adm/keys";	usepass = 0;	ARGBEGIN{	case 'k':		userkeys = EARGF(usage());		break;	case 'p':		usepass = 1;		break;	}ARGEND 	userkeys = "/adm/keys";	if(argc > 0)		userkeys = argv[0]; 	if(usepass)		getpass(authkey, nil, 0, 0);	else{		if(!getauthkey(authkey))			print("keyfs: warning: can't read /dev/key\n");	} 	fmtinstall('W', wierdfmt);	readusers();	exits("");}