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

📄 authp9any.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * 4th Edition p9any/p9sk1 authentication based on auth9p1.c * Nigel Roles (nigel@9fs.org) 2003 */#include <plan9.h>#include <fcall.h>#include <u9fs.h>#include <stdlib.h>	/* for random stuff */typedef struct	Ticket		Ticket;typedef struct	Ticketreq	Ticketreq;typedef struct	Authenticator	Authenticator;enum{	DOMLEN=		48,		/* length of an authentication domain name */	CHALLEN=	8		/* length of a challenge */};enum {	HaveProtos,	NeedProto,	NeedChal,	HaveTreq,	NeedTicket,	HaveAuth,	Established,};/* encryption numberings (anti-replay) */enum{	AuthTreq=1,	/* ticket request */	AuthChal=2,	/* challenge box request */	AuthPass=3,	/* change password */	AuthOK=4,	/* fixed length reply follows */	AuthErr=5,	/* error follows */	AuthMod=6,	/* modify user */	AuthApop=7,	/* apop authentication for pop3 */	AuthOKvar=9,	/* variable length reply follows */	AuthChap=10,	/* chap authentication for ppp */	AuthMSchap=11,	/* MS chap authentication for ppp */	AuthCram=12,	/* CRAM verification for IMAP (RFC2195 & rfc2104) */	AuthHttp=13,	/* http domain login */	AuthVNC=14,	/* http domain login */	AuthTs=64,	/* ticket encrypted with server's key */	AuthTc,		/* ticket encrypted with client's key */	AuthAs,		/* server generated authenticator */	AuthAc,		/* client generated authenticator */	AuthTp,		/* ticket encrypted with client's key for password change */	AuthHr		/* http reply */};struct Ticketreq{	char	type;	char	authid[NAMELEN];	/* server's encryption id */	char	authdom[DOMLEN];	/* server's authentication domain */	char	chal[CHALLEN];		/* challenge from server */	char	hostid[NAMELEN];	/* host's encryption id */	char	uid[NAMELEN];		/* uid of requesting user on host */};#define	TICKREQLEN	(3*NAMELEN+CHALLEN+DOMLEN+1)struct Ticket{	char	num;			/* replay protection */	char	chal[CHALLEN];		/* server challenge */	char	cuid[NAMELEN];		/* uid on client */	char	suid[NAMELEN];		/* uid on server */	char	key[DESKEYLEN];		/* nonce DES key */};#define	TICKETLEN	(CHALLEN+2*NAMELEN+DESKEYLEN+1)struct Authenticator{	char	num;			/* replay protection */	char	chal[CHALLEN];	ulong	id;			/* authenticator id, ++'d with each auth */};#define	AUTHENTLEN	(CHALLEN+4+1)extern int chatty9p;static	int	convT2M(Ticket*, char*, char*);static	void	convM2T(char*, Ticket*, char*);static	void	convM2Tnoenc(char*, Ticket*);static	int	convA2M(Authenticator*, char*, char*);static	void	convM2A(char*, Authenticator*, char*);static	int	convTR2M(Ticketreq*, char*);static	void	convM2TR(char*, Ticketreq*);static	int	passtokey(char*, char*);/* * destructively encrypt the buffer, which * must be at least 8 characters long. */static intencrypt9p(void *key, void *vbuf, int n){	char ekey[128], *buf;	int i, r;	if(n < 8)		return 0;	key_setup(key, ekey);	buf = vbuf;	n--;	r = n % 7;	n /= 7;	for(i = 0; i < n; i++){		block_cipher(ekey, buf, 0);		buf += 7;	}	if(r)		block_cipher(ekey, buf - 7 + r, 0);	return 1;}/* * destructively decrypt the buffer, which * must be at least 8 characters long. */static intdecrypt9p(void *key, void *vbuf, int n){	char ekey[128], *buf;	int i, r;	if(n < 8)		return 0;	key_setup(key, ekey);	buf = vbuf;	n--;	r = n % 7;	n /= 7;	buf += n * 7;	if(r)		block_cipher(ekey, buf - 7 + r, 1);	for(i = 0; i < n; i++){		buf -= 7;		block_cipher(ekey, buf, 1);	}	return 1;}#define	CHAR(x)		*p++ = f->x#define	SHORT(x)	p[0] = f->x; p[1] = f->x>>8; p += 2#define	VLONG(q)	p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4#define	LONG(x)		VLONG(f->x)#define	STRING(x,n)	memmove(p, f->x, n); p += nstatic intconvTR2M(Ticketreq *f, char *ap){	int n;	uchar *p;	p = (uchar*)ap;	CHAR(type);	STRING(authid, NAMELEN);	STRING(authdom, DOMLEN);	STRING(chal, CHALLEN);	STRING(hostid, NAMELEN);	STRING(uid, NAMELEN);	n = p - (uchar*)ap;	return n;}static intconvT2M(Ticket *f, char *ap, char *key){	int n;	uchar *p;	p = (uchar*)ap;	CHAR(num);	STRING(chal, CHALLEN);	STRING(cuid, NAMELEN);	STRING(suid, NAMELEN);	STRING(key, DESKEYLEN);	n = p - (uchar*)ap;	if(key)		encrypt9p(key, ap, n);	return n;}intconvA2M(Authenticator *f, char *ap, char *key){	int n;	uchar *p;	p = (uchar*)ap;	CHAR(num);	STRING(chal, CHALLEN);	LONG(id);	n = p - (uchar*)ap;	if(key)		encrypt9p(key, ap, n);	return n;}#undef CHAR#undef SHORT#undef VLONG#undef LONG#undef STRING#define	CHAR(x)		f->x = *p++#define	SHORT(x)	f->x = (p[0] | (p[1]<<8)); p += 2#define	VLONG(q)	q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4#define	LONG(x)		VLONG(f->x)#define	STRING(x,n)	memmove(f->x, p, n); p += nvoidconvM2A(char *ap, Authenticator *f, char *key){	uchar *p;	if(key)		decrypt9p(key, ap, AUTHENTLEN);	p = (uchar*)ap;	CHAR(num);	STRING(chal, CHALLEN);	LONG(id);	USED(p);}voidconvM2T(char *ap, Ticket *f, char *key){	uchar *p;	if(key)		decrypt9p(key, ap, TICKETLEN);	p = (uchar*)ap;	CHAR(num);	STRING(chal, CHALLEN);	STRING(cuid, NAMELEN);	f->cuid[NAMELEN-1] = 0;	STRING(suid, NAMELEN);	f->suid[NAMELEN-1] = 0;	STRING(key, DESKEYLEN);	USED(p);}#undef CHAR#undef SHORT#undef LONG#undef VLONG#undef STRINGstatic intpasstokey(char *key, char *p){	uchar buf[NAMELEN], *t;	int i, n;	n = strlen(p);	if(n >= NAMELEN)		n = NAMELEN-1;	memset(buf, ' ', 8);	t = buf;	strncpy((char*)t, p, n);	t[n] = 0;	memset(key, 0, DESKEYLEN);	for(;;){		for(i = 0; i < DESKEYLEN; i++)			key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1)));		if(n <= 8)			return 1;		n -= 8;		t += 8;		if(n < 8){			t -= 8 - n;			n = 8;		}		encrypt9p(key, t, 8);	}	return 1;	/* not reached */}static char authkey[DESKEYLEN];static char *authid;static char *authdom;static char *haveprotosmsg;static char *needprotomsg;static voidp9anyinit(void){	int n, fd;	char abuf[200];	char *af, *f[4];	af = autharg;	if(af == nil)		af = "/etc/u9fs.key";	if((fd = open(af, OREAD)) < 0)		sysfatal("can't open key file '%s'", af);	if((n = readn(fd, abuf, sizeof(abuf)-1)) < 0)		sysfatal("can't read key file '%s'", af);	if (n > 0 && abuf[n - 1] == '\n')		n--;	abuf[n] = '\0';	if(getfields(abuf, f, nelem(f), 0, "\n") != 3)		sysfatal("key file '%s' not exactly 3 lines", af);	passtokey(authkey, f[0]);	authid = strdup(f[1]);	authdom = strdup(f[2]);	haveprotosmsg = malloc(strlen("p9sk1") + 1 + strlen(authdom) + 1);	sprint(haveprotosmsg, "p9sk1@%s", authdom);	needprotomsg = malloc(strlen("p9sk1") + 1 + strlen(authdom) + 1);	sprint(needprotomsg, "p9sk1 %s", authdom);}typedef struct AuthSession {	int state;	char *uname;	char *aname;	char cchal[CHALLEN];	Ticketreq tr;	Ticket t;} AuthSession;static char*p9anyauth(Fcall *rx, Fcall *tx){	AuthSession *sp;	Fid *f;	char *ep;	sp = malloc(sizeof(AuthSession));	f = newauthfid(rx->afid, sp, &ep);	if (f == nil) {		free(sp);		return ep;	}	if (chatty9p)		fprint(2, "p9anyauth: afid %d\n", rx->afid);	sp->state = HaveProtos;	sp->uname = strdup(rx->uname);	sp->aname = strdup(rx->aname);	tx->aqid.type = QTAUTH;	tx->aqid.path = 1;	tx->aqid.vers = 0;	return nil;}static char *p9anyattach(Fcall *rx, Fcall *tx){	AuthSession *sp;	Fid *f;	char *ep;	f = oldauthfid(rx->afid, (void **)&sp, &ep);	if (f == nil)		return ep;	if (chatty9p)		fprint(2, "p9anyattach: afid %d state %d\n", rx->afid, sp->state);	if (sp->state == Established && strcmp(rx->uname, sp->uname) == 0		&& strcmp(rx->aname, sp->aname) == 0)		return nil;	return "authentication failed";}static intreadstr(Fcall *rx, Fcall *tx, char *s, int len){	if (rx->offset >= len)		return 0;	tx->count = len - rx->offset;	if (tx->count > rx->count)		tx->count = rx->count;	memcpy(tx->data, s + rx->offset, tx->count);	return tx->count;}static char *p9anyread(Fcall *rx, Fcall *tx){	AuthSession *sp;	char *ep;	Fid *f;	f = oldauthfid(rx->afid, (void **)&sp, &ep);	if (f == nil)		return ep;	if (chatty9p)		fprint(2, "p9anyread: afid %d state %d\n", rx->fid, sp->state);	switch (sp->state) {	case HaveProtos:		readstr(rx, tx, haveprotosmsg, strlen(haveprotosmsg) + 1);		if (rx->offset + tx->count == strlen(haveprotosmsg) + 1)			sp->state = NeedProto;		return nil;	case HaveTreq:		if (rx->count != TICKREQLEN)			goto botch;		convTR2M(&sp->tr, tx->data);		tx->count = TICKREQLEN;		sp->state = NeedTicket;		return nil;	case HaveAuth: {		Authenticator a;		if (rx->count != AUTHENTLEN)			goto botch;		a.num = AuthAs;		memmove(a.chal, sp->cchal, CHALLEN);		a.id = 0;		convA2M(&a, (char*)tx->data, sp->t.key);		memset(sp->t.key, 0, sizeof(sp->t.key));		tx->count = rx->count;		sp->state = Established;		return nil;	}	default:	botch:		return "protocol botch";	}}static char *p9anywrite(Fcall *rx, Fcall *tx){	AuthSession *sp;	char *ep;	Fid *f;	f = oldauthfid(rx->afid, (void **)&sp, &ep);	if (f == nil)		return ep;	if (chatty9p)		fprint(2, "p9anywrite: afid %d state %d\n", rx->fid, sp->state);	switch (sp->state) {	case NeedProto:		if (rx->count != strlen(needprotomsg) + 1)			return "protocol response wrong length";		if (memcmp(rx->data, needprotomsg, rx->count) != 0)			return "unacceptable protocol";		sp->state = NeedChal;		tx->count = rx->count;		return nil;	case NeedChal:		if (rx->count != CHALLEN)			goto botch;		memmove(sp->cchal, rx->data, CHALLEN);		sp->tr.type = AuthTreq;		safecpy(sp->tr.authid, authid, sizeof(sp->tr.authid));		safecpy(sp->tr.authdom, authdom, sizeof(sp->tr.authdom));		randombytes((uchar *)sp->tr.chal, CHALLEN);		safecpy(sp->tr.hostid, "", sizeof(sp->tr.hostid));		safecpy(sp->tr.uid, "", sizeof(sp->tr.uid));		tx->count = rx->count;		sp->state = HaveTreq;		return nil;	case NeedTicket: {		Authenticator a;		if (rx->count != TICKETLEN + AUTHENTLEN) {			fprint(2, "bad length in attach");			goto botch;		}		convM2T((char*)rx->data, &sp->t, authkey);		if (sp->t.num != AuthTs) {			fprint(2, "bad AuthTs in attach\n");			goto botch;		}		if (memcmp(sp->t.chal, sp->tr.chal, CHALLEN) != 0) {			fprint(2, "bad challenge in attach\n");			goto botch;		}		convM2A((char*)rx->data + TICKETLEN, &a, sp->t.key);		if (a.num != AuthAc) {			fprint(2, "bad AuthAs in attach\n");			goto botch;		}		if(memcmp(a.chal, sp->tr.chal, CHALLEN) != 0) {			fprint(2, "bad challenge in attach 2\n");			goto botch;		}		sp->state = HaveAuth;		tx->count = rx->count;		return nil;	}	default:	botch:		return "protocol botch";	}}static voidsafefree(char *p){	if (p) {		memset(p, 0, strlen(p));		free(p);	}}static char *p9anyclunk(Fcall *rx, Fcall *tx){	Fid *f;	AuthSession *sp;	char *ep;	f = oldauthfid(rx->afid, (void **)&sp, &ep);	if (f == nil)		return ep;	if (chatty9p)		fprint(2, "p9anyclunk: afid %d\n", rx->fid);	safefree(sp->uname);	safefree(sp->aname);	memset(sp, 0, sizeof(sp));	free(sp);	return nil;}Auth authp9any = {	"p9any",	p9anyauth,	p9anyattach,	p9anyinit,	p9anyread,	p9anywrite,	p9anyclunk,};

⌨️ 快捷键说明

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