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

📄 msg.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "ssh.h"static ulong sum32(ulong, void*, int);char *msgnames[] ={/* 0 */	"SSH_MSG_NONE",	"SSH_MSG_DISCONNECT",	"SSH_SMSG_PUBLIC_KEY",	"SSH_CMSG_SESSION_KEY",	"SSH_CMSG_USER",	"SSH_CMSG_AUTH_RHOSTS",	"SSH_CMSG_AUTH_RSA",	"SSH_SMSG_AUTH_RSA_CHALLENGE",	"SSH_CMSG_AUTH_RSA_RESPONSE",	"SSH_CMSG_AUTH_PASSWORD",/* 10 */	"SSH_CMSG_REQUEST_PTY",	"SSH_CMSG_WINDOW_SIZE",	"SSH_CMSG_EXEC_SHELL",	"SSH_CMSG_EXEC_CMD",	"SSH_SMSG_SUCCESS",	"SSH_SMSG_FAILURE",	"SSH_CMSG_STDIN_DATA",	"SSH_SMSG_STDOUT_DATA",	"SSH_SMSG_STDERR_DATA",	"SSH_CMSG_EOF",/* 20 */	"SSH_SMSG_EXITSTATUS",	"SSH_MSG_CHANNEL_OPEN_CONFIRMATION",	"SSH_MSG_CHANNEL_OPEN_FAILURE",	"SSH_MSG_CHANNEL_DATA",	"SSH_MSG_CHANNEL_INPUT_EOF",	"SSH_MSG_CHANNEL_OUTPUT_CLOSED",	"SSH_MSG_UNIX_DOMAIN_X11_FORWARDING (obsolete)",	"SSH_SMSG_X11_OPEN",	"SSH_CMSG_PORT_FORWARD_REQUEST",	"SSH_MSG_PORT_OPEN",/* 30 */	"SSH_CMSG_AGENT_REQUEST_FORWARDING",	"SSH_SMSG_AGENT_OPEN",	"SSH_MSG_IGNORE",	"SSH_CMSG_EXIT_CONFIRMATION",	"SSH_CMSG_X11_REQUEST_FORWARDING",	"SSH_CMSG_AUTH_RHOSTS_RSA",	"SSH_MSG_DEBUG",	"SSH_CMSG_REQUEST_COMPRESSION",	"SSH_CMSG_MAX_PACKET_SIZE",	"SSH_CMSG_AUTH_TIS",/* 40 */	"SSH_SMSG_AUTH_TIS_CHALLENGE",	"SSH_CMSG_AUTH_TIS_RESPONSE",	"SSH_CMSG_AUTH_KERBEROS",	"SSH_SMSG_AUTH_KERBEROS_RESPONSE",	"SSH_CMSG_HAVE_KERBEROS_TGT"};voidbadmsg(Msg *m, int want){	char *s, buf[20+ERRMAX];	if(m==nil){		snprint(buf, sizeof buf, "<early eof: %r>");		s = buf;	}else{		snprint(buf, sizeof buf, "<unknown type %d>", m->type);		s = buf;		if(0 <= m->type && m->type < nelem(msgnames))			s = msgnames[m->type];	}	if(want)		error("got %s message expecting %s", s, msgnames[want]);	error("got unexpected %s message", s);}Msg*allocmsg(Conn *c, int type, int len){	uchar *p;	Msg *m;	if(len > 256*1024)		abort();	m = (Msg*)emalloc(sizeof(Msg)+4+8+1+len+4);	setmalloctag(m, getcallerpc(&c));	p = (uchar*)&m[1];	m->c = c;	m->bp = p;	m->ep = p+len;	m->wp = p;	m->type = type;	return m;}voidunrecvmsg(Conn *c, Msg *m){	debug(DBG_PROTO, "unreceived %s len %d\n", msgnames[m->type], m->ep - m->rp);	free(c->unget);	c->unget = m;}static Msg*recvmsg0(Conn *c){	int pad;	uchar *p, buf[4];	ulong crc, crc0, len;	Msg *m;	if(c->unget){		m = c->unget;		c->unget = nil;		return m;	}	if(readn(c->fd[0], buf, 4) != 4){		werrstr("short net read: %r");		return nil;	}	len = LONG(buf);	if(len > 256*1024){		werrstr("packet size far too big: %.8lux", len);		return nil;	}	pad = 8 - len%8;	m = (Msg*)emalloc(sizeof(Msg)+pad+len);	setmalloctag(m, getcallerpc(&c));	m->c = c;	m->bp = (uchar*)&m[1];	m->ep = m->bp + pad+len-4;	/* -4: don't include crc */	m->rp = m->bp;	if(readn(c->fd[0], m->bp, pad+len) != pad+len){		werrstr("short net read: %r");		free(m);		return nil;	}	if(c->cipher)		c->cipher->decrypt(c->cstate, m->bp, len+pad);	crc = sum32(0, m->bp, pad+len-4);	p = m->bp + pad+len-4;	crc0 = LONG(p);	if(crc != crc0){		werrstr("bad crc %#lux != %#lux (packet length %lud)", crc, crc0, len);		free(m);		return nil;	}	m->rp += pad;	m->type = *m->rp++;	return m;}Msg*recvmsg(Conn *c, int type){	Msg *m;	while((m = recvmsg0(c)) != nil){		debug(DBG_PROTO, "received %s len %d\n", msgnames[m->type], m->ep - m->rp);		if(m->type != SSH_MSG_DEBUG && m->type != SSH_MSG_IGNORE)			break;		if(m->type == SSH_MSG_DEBUG)			debug(DBG_PROTO, "remote DEBUG: %s\n", getstring(m));		free(m);	}	if(type == 0){		/* no checking */	}else if(type == -1){		/* must not be nil */		if(m == nil)			error(Ehangup);	}else{		/* must be given type */		if(m==nil || m->type!=type)			badmsg(m, type);	}	setmalloctag(m, getcallerpc(&c));	return m;}intsendmsg(Msg *m){	int i, pad;	uchar *p;	ulong datalen, len, crc;	Conn *c;	datalen = m->wp - m->bp;	len = datalen + 5;	pad = 8 - len%8;	debug(DBG_PROTO, "sending %s len %d\n", msgnames[m->type], datalen);	p = m->bp;	memmove(m->bp+4+pad+1, m->bp, datalen);	/* slide data to correct position */	PLONG(p, len);	p += 4;	if(m->c->cstate){		for(i=0; i<pad; i++)			*p++ = fastrand();	}else{		memset(p, 0, pad);		p += pad;	}	*p++ = m->type;	/* data already in position */	p += datalen;	crc = sum32(0, m->bp+4, pad+1+datalen);	PLONG(p, crc);	p += 4;	c = m->c;	qlock(c);	if(c->cstate)		c->cipher->encrypt(c->cstate, m->bp+4, len+pad);	if(write(c->fd[1], m->bp, p - m->bp) != p-m->bp){		qunlock(c);		free(m);		return -1;	}	qunlock(c);	free(m);	return 0;}uchargetbyte(Msg *m){	if(m->rp >= m->ep)		error(Edecode);	return *m->rp++;}ushortgetshort(Msg *m){	ushort x;	if(m->rp+2 > m->ep)		error(Edecode);	x = SHORT(m->rp);	m->rp += 2;	return x;}ulonggetlong(Msg *m){	ulong x;	if(m->rp+4 > m->ep)		error(Edecode);	x = LONG(m->rp);	m->rp += 4;	return x;}char*getstring(Msg *m){	char *p;	ulong len;	/* overwrites length to make room for NUL */	len = getlong(m);	if(m->rp+len > m->ep)		error(Edecode);	p = (char*)m->rp-1;	memmove(p, m->rp, len);	p[len] = '\0';	return p;}void*getbytes(Msg *m, int n){	uchar *p;	if(m->rp+n > m->ep)		error(Edecode);	p = m->rp;	m->rp += n;	return p;}mpint*getmpint(Msg *m){	int n;	n = (getshort(m)+7)/8;	/* getshort returns # bits */	return betomp(getbytes(m, n), n, nil);}RSApub*getRSApub(Msg *m){	RSApub *key;	getlong(m);	key = rsapuballoc();	if(key == nil)		error(Ememory);	key->ek = getmpint(m);	key->n = getmpint(m);	setmalloctag(key, getcallerpc(&m));	return key;}voidputbyte(Msg *m, uchar x){	if(m->wp >= m->ep)		error(Eencode);	*m->wp++ = x;}voidputshort(Msg *m, ushort x){	if(m->wp+2 > m->ep)		error(Eencode);	PSHORT(m->wp, x);	m->wp += 2;}voidputlong(Msg *m, ulong x){	if(m->wp+4 > m->ep)		error(Eencode);	PLONG(m->wp, x);	m->wp += 4;}voidputstring(Msg *m, char *s){	int len;	len = strlen(s);	putlong(m, len);	putbytes(m, s, len);}voidputbytes(Msg *m, void *a, long n){	if(m->wp+n > m->ep)		error(Eencode);	memmove(m->wp, a, n);	m->wp += n;}voidputmpint(Msg *m, mpint *b){	int bits, n;	bits = mpsignif(b);	putshort(m, bits);	n = (bits+7)/8;	if(m->wp+n > m->ep)		error(Eencode);	mptobe(b, m->wp, n, nil);	m->wp += n;}voidputRSApub(Msg *m, RSApub *key){	putlong(m, mpsignif(key->n));	putmpint(m, key->ek);	putmpint(m, key->n);}static ulong crctab[256];static voidinitsum32(void){	ulong crc, poly;	int i, j;	poly = 0xEDB88320;	for(i = 0; i < 256; i++){		crc = i;		for(j = 0; j < 8; j++){			if(crc & 1)				crc = (crc >> 1) ^ poly;			else				crc >>= 1;		}		crctab[i] = crc;	}}static ulongsum32(ulong lcrc, void *buf, int n){	static int first=1;	uchar *s = buf;	ulong crc = lcrc;	if(first){		first=0;		initsum32();	}	while(n-- > 0)		crc = crctab[(crc^*s++)&0xff] ^ (crc>>8);	return crc;}mpint*rsapad(mpint *b, int n){	int i, pad, nbuf;	uchar buf[2560];	mpint *c;	if(n > sizeof buf)		error("buffer too small in rsapad");	nbuf = (mpsignif(b)+7)/8;	pad = n - nbuf;	assert(pad >= 3);	mptobe(b, buf, nbuf, nil);	memmove(buf+pad, buf, nbuf);	buf[0] = 0;	buf[1] = 2;	for(i=2; i<pad-1; i++)		buf[i]=1+fastrand()%255;	buf[pad-1] = 0;	c = betomp(buf, n, nil);	memset(buf, 0, sizeof buf);	return c;}mpint*rsaunpad(mpint *b){	int i, n;	uchar buf[2560];	n = (mpsignif(b)+7)/8;	if(n > sizeof buf)		error("buffer too small in rsaunpad");	mptobe(b, buf, n, nil);	/* the initial zero has been eaten by the betomp -> mptobe sequence */	if(buf[0] != 2)		error("bad data in rsaunpad");	for(i=1; i<n; i++)		if(buf[i]==0)			break;	return betomp(buf+i, n-i, nil);}voidmptoberjust(mpint *b, uchar *buf, int len){	int n;	n = mptobe(b, buf, len, nil);	assert(n >= 0);	if(n < len){		len -= n;		memmove(buf+len, buf, n);		memset(buf, 0, len);	}}mpint*rsaencryptbuf(RSApub *key, uchar *buf, int nbuf){	int n;	mpint *a, *b, *c;	n = (mpsignif(key->n)+7)/8;	a = betomp(buf, nbuf, nil);	b = rsapad(a, n);	mpfree(a);	c = rsaencrypt(key, b, nil);	mpfree(b);	return c;}

⌨️ 快捷键说明

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