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

📄 smsg.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "ssh.h"#include <bio.h>static voidsend_ssh_smsg_public_key(Conn *c){	int i;	Msg *m;	m = allocmsg(c, SSH_SMSG_PUBLIC_KEY, 2048);	putbytes(m, c->cookie, COOKIELEN);	putRSApub(m, c->serverkey);	putRSApub(m, c->hostkey);	putlong(m, c->flags);	for(i=0; i<c->nokcipher; i++)		c->ciphermask |= 1<<c->okcipher[i]->id;	putlong(m, c->ciphermask);	for(i=0; i<c->nokauthsrv; i++)		c->authmask |= 1<<c->okauthsrv[i]->id;	putlong(m, c->authmask);	sendmsg(m);}static mpint*rpcdecrypt(AuthRpc *rpc, mpint *b){	mpint *a;	char *p;	p = mptoa(b, 16, nil, 0);	if(auth_rpc(rpc, "write", p, strlen(p)) != ARok)		sysfatal("factotum rsa write: %r");	free(p);	if(auth_rpc(rpc, "read", nil, 0) != ARok)		sysfatal("factotum rsa read: %r");	a = strtomp(rpc->arg, nil, 16, nil);	mpfree(b);	return a;}static voidrecv_ssh_cmsg_session_key(Conn *c, AuthRpc *rpc){	int i, id, n, serverkeylen, hostkeylen;	mpint *a, *b;	uchar *buf;	Msg *m;	RSApriv *ksmall, *kbig;	m = recvmsg(c, SSH_CMSG_SESSION_KEY);	id = getbyte(m);	c->cipher = nil;	for(i=0; i<c->nokcipher; i++)		if(c->okcipher[i]->id == id)			c->cipher = c->okcipher[i];	if(c->cipher == nil)		sysfatal("invalid cipher selected");	if(memcmp(getbytes(m, COOKIELEN), c->cookie, COOKIELEN) != 0)		sysfatal("bad cookie");	serverkeylen = mpsignif(c->serverkey->n);	hostkeylen = mpsignif(c->hostkey->n);	ksmall = kbig = nil;	if(serverkeylen+128 <= hostkeylen){		ksmall = c->serverpriv;		kbig = nil;	}else if(hostkeylen+128 <= serverkeylen){		ksmall = nil;		kbig = c->serverpriv;	}else		sysfatal("server session and host keys do not differ by at least 128 bits");	b = getmpint(m);	debug(DBG_CRYPTO, "encrypted with kbig is %B\n", b);	if(kbig){		a = rsadecrypt(kbig, b, nil);		mpfree(b);		b = a;	}else		b = rpcdecrypt(rpc, b);	a = rsaunpad(b);	mpfree(b);	b = a;	debug(DBG_CRYPTO, "encrypted with ksmall is %B\n", b);	if(ksmall){		a = rsadecrypt(ksmall, b, nil);		mpfree(b);		b = a;	}else		b = rpcdecrypt(rpc, b);	a = rsaunpad(b);	mpfree(b);	b = a;	debug(DBG_CRYPTO, "munged is %B\n", b);	n = (mpsignif(b)+7)/8;	if(n > SESSKEYLEN)		sysfatal("client sent short session key");	buf = emalloc(SESSKEYLEN);	mptoberjust(b, buf, SESSKEYLEN);	mpfree(b);	for(i=0; i<SESSIDLEN; i++)		buf[i] ^= c->sessid[i];	memmove(c->sesskey, buf, SESSKEYLEN);	debug(DBG_CRYPTO, "unmunged is %.*H\n", SESSKEYLEN, buf);	c->flags = getlong(m);	free(m);}static AuthInfo*responselogin(char *user, char *resp){	Chalstate *c;	AuthInfo *ai;	if((c = auth_challenge("proto=p9cr user=%q role=server", user)) == nil){		sshlog("auth_challenge failed for %s", user);		return nil;	}	c->resp = resp;	c->nresp = strlen(resp);	ai = auth_response(c);	auth_freechal(c);	return ai;}static AuthInfo*authusername(Conn *c){	char *p;	AuthInfo *ai;	/*	 * hack for sam users: 'name numbers' gets tried as securid login.	 */	if(p = strchr(c->user, ' ')){		*p++ = '\0';		if((ai=responselogin(c->user, p)) != nil)			return ai;		*--p = ' ';		sshlog("bad response: %s", c->user);	}	return nil;}static voidauthsrvuser(Conn *c){	int i;	char *ns, *user;	AuthInfo *ai;	Msg *m;	m = recvmsg(c, SSH_CMSG_USER);	user = getstring(m);	c->user = emalloc(strlen(user)+1);	strcpy(c->user, user);	free(m);	ai = authusername(c);	while(ai == nil){		/*		 * clumsy: if the client aborted the auth_tis early		 * we don't send a new failure.  we check this by		 * looking at c->unget, which is only used in that		 * case.		 */		if(c->unget != nil)			goto skipfailure;		sendmsg(allocmsg(c, SSH_SMSG_FAILURE, 0));	skipfailure:		m = recvmsg(c, -1);		for(i=0; i<c->nokauthsrv; i++)			if(c->okauthsrv[i]->firstmsg == m->type){				ai = (*c->okauthsrv[i]->fn)(c, m);				break;			}		if(i==c->nokauthsrv)			badmsg(m, 0);	}	sendmsg(allocmsg(c, SSH_SMSG_SUCCESS, 0));	if(noworld(ai->cuid))		ns = "/lib/namespace.noworld";	else		ns = nil;	if(auth_chuid(ai, ns) < 0){		sshlog("auth_chuid to %s: %r", ai->cuid);		sysfatal("auth_chuid: %r");	}	sshlog("logged in as %s", ai->cuid);	auth_freeAI(ai);}voidsshserverhandshake(Conn *c){	char *p, buf[128];	Biobuf *b;	Attr *a;	int i, afd;	mpint *m;	AuthRpc *rpc;	RSApub *key;	/*	 * BUG: should use `attr' to get the key attributes	 * after the read, but that's not implemented yet.	 */	if((b = Bopen("/mnt/factotum/ctl", OREAD)) == nil)		sysfatal("open /mnt/factotum/ctl: %r");	while((p = Brdline(b, '\n')) != nil){		p[Blinelen(b)-1] = '\0';		if(strstr(p, " proto=rsa ") && strstr(p, " service=sshserve "))			break;	}	if(p == nil)		sysfatal("no sshserve keys found in /mnt/factotum/ctl");	a = _parseattr(p);	Bterm(b);	key = emalloc(sizeof(*key));	if((p = _strfindattr(a, "n")) == nil)		sysfatal("no n in sshserve key");	if((key->n = strtomp(p, &p, 16, nil)) == nil || *p != 0)		sysfatal("bad n in sshserve key");	if((p = _strfindattr(a, "ek")) == nil)		sysfatal("no ek in sshserve key");	if((key->ek = strtomp(p, &p, 16, nil)) == nil || *p != 0)		sysfatal("bad ek in sshserve key");	_freeattr(a);	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)		sysfatal("open /mnt/factotum/rpc: %r");	if((rpc = auth_allocrpc(afd)) == nil)		sysfatal("auth_allocrpc: %r");	p = "proto=rsa role=client service=sshserve";	if(auth_rpc(rpc, "start", p, strlen(p)) != ARok)		sysfatal("auth_rpc start %s: %r", p);	if(auth_rpc(rpc, "read", nil, 0) != ARok)		sysfatal("auth_rpc read: %r");	m = strtomp(rpc->arg, nil, 16, nil);	if(mpcmp(m, key->n) != 0)		sysfatal("key in /mnt/factotum/ctl does not match rpc key");	mpfree(m);	c->hostkey = key;	/* send id string */	fprint(c->fd[0], "SSH-1.5-Plan9\n");	/* receive id string */	if(readstrnl(c->fd[0], buf, sizeof buf) < 0)		sysfatal("reading server version: %r");	/* id string is "SSH-m.n-comment".  We need m=1, n>=5. */	if(strncmp(buf, "SSH-", 4) != 0	|| strtol(buf+4, &p, 10) != 1	|| *p != '.'	|| strtol(p+1, &p, 10) < 5	|| *p != '-')		sysfatal("protocol mismatch; got %s, need SSH-1.x for x>=5", buf);	for(i=0; i<COOKIELEN; i++)		c->cookie[i] = fastrand();	calcsessid(c);	send_ssh_smsg_public_key(c);	recv_ssh_cmsg_session_key(c, rpc);	auth_freerpc(rpc);	close(afd);	c->cstate = (*c->cipher->init)(c, 1);		/* turns on encryption */	sendmsg(allocmsg(c, SSH_SMSG_SUCCESS, 0));	authsrvuser(c);}

⌨️ 快捷键说明

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