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

📄 httpdigest.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * HTTPDIGEST - MD5 challenge/response authentication (RFC 2617) * * Client protocol: *	write challenge: nonce method uri  *	read response: 2*MD5dlen hex digits * * Server protocol: *	unimplemented */#include "dat.h"enum{	CNeedChal,	CHaveResp,	Maxphase,};static char *phasenames[Maxphase] = {[CNeedChal]	"CNeedChal",[CHaveResp]	"CHaveResp",};struct State{	char resp[MD5dlen*2+1];};static inthdinit(Proto *p, Fsstate *fss){	int iscli;	State *s;	if((iscli = isclient(_strfindattr(fss->attr, "role"))) < 0)		return failure(fss, nil);	if(!iscli)		return failure(fss, "%s server not supported", p->name);	s = emalloc(sizeof *s);	fss->phasename = phasenames;	fss->maxphase = Maxphase;	fss->phase = CNeedChal;	fss->ps = s;	return RpcOk;}static voidstrtolower(char *s){	while(*s){		*s = tolower(*s);		s++;	}}static voiddigest(char *user, char *realm, char *passwd,	char *nonce, char *method, char *uri,	char *dig){	uchar b[MD5dlen];	char ha1[MD5dlen*2+1];	char ha2[MD5dlen*2+1];	DigestState *s;	/*	 *  H(A1) = MD5(uid + ":" + realm ":" + passwd)	 */	s = md5((uchar*)user, strlen(user), nil, nil);	md5((uchar*)":", 1, nil, s);	md5((uchar*)realm, strlen(realm), nil, s);	md5((uchar*)":", 1, nil, s);	md5((uchar*)passwd, strlen(passwd), b, s);	enc16(ha1, sizeof(ha1), b, MD5dlen);	strtolower(ha1);	/*	 *  H(A2) = MD5(method + ":" + uri)	 */	s = md5((uchar*)method, strlen(method), nil, nil);	md5((uchar*)":", 1, nil, s);	md5((uchar*)uri, strlen(uri), b, s);	enc16(ha2, sizeof(ha2), b, MD5dlen);	strtolower(ha2);	/*	 *  digest = MD5(H(A1) + ":" + nonce + ":" + H(A2))	 */	s = md5((uchar*)ha1, MD5dlen*2, nil, nil);	md5((uchar*)":", 1, nil, s);	md5((uchar*)nonce, strlen(nonce), nil, s);	md5((uchar*)":", 1, nil, s);	md5((uchar*)ha2, MD5dlen*2, b, s);	enc16(dig, MD5dlen*2+1, b, MD5dlen);	strtolower(dig);}static inthdwrite(Fsstate *fss, void *va, uint n){	State *s;	int ret;	char *a, *p, *r, *u, *t;	char *tok[4];	Key *k;	Keyinfo ki;	Attr *attr;	s = fss->ps;	a = va;	if(fss->phase != CNeedChal)		return phaseerror(fss, "write");	attr = _delattr(_copyattr(fss->attr), "role");	mkkeyinfo(&ki, fss, attr);	ret = findkey(&k, &ki, "%s", fss->proto->keyprompt);	_freeattr(attr);	if(ret != RpcOk)		return ret;	p = _strfindattr(k->privattr, "!password");	if(p == nil)		return failure(fss, "key has no password");	r = _strfindattr(k->attr, "realm");	if(r == nil)		return failure(fss, "key has no realm");	u = _strfindattr(k->attr, "user");	if(u == nil)		return failure(fss, "key has no user");	setattrs(fss->attr, k->attr);	/* copy in case a is not null-terminated */	t = emalloc(n+1);	memcpy(t, a, n);	t[n] = 0;	/* get nonce, method, uri */	if(tokenize(t, tok, 4) != 3)		return failure(fss, "bad challenge");	digest(u, r, p, tok[0], tok[1], tok[2], s->resp);	free(t);	closekey(k);	fss->phase = CHaveResp;	return RpcOk;}static inthdread(Fsstate *fss, void *va, uint *n){	State *s;	s = fss->ps;	if(fss->phase != CHaveResp)		return phaseerror(fss, "read");	if(*n > strlen(s->resp))		*n = strlen(s->resp);	memmove(va, s->resp, *n);	fss->phase = Established;	fss->haveai = 0;	return RpcOk;}static voidhdclose(Fsstate *fss){	State *s;	s = fss->ps;	free(s);}Proto httpdigest = {.name=		"httpdigest",.init=		hdinit,.write=		hdwrite,.read=		hdread,.close=		hdclose,.addkey=	replacekey,.keyprompt=	"user? realm? !password?"};

⌨️ 快捷键说明

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