xref: /plan9/sys/src/cmd/ssh1/authrsa.c (revision 63afb9a5d3f910047231762bcce0ee49fed3d07c)
1*63afb9a5SDavid du Colombier #include "ssh.h"
2*63afb9a5SDavid du Colombier 
3*63afb9a5SDavid du Colombier static int
authrsafn(Conn * c)4*63afb9a5SDavid du Colombier authrsafn(Conn *c)
5*63afb9a5SDavid du Colombier {
6*63afb9a5SDavid du Colombier 	uchar chalbuf[32+SESSIDLEN], response[MD5dlen];
7*63afb9a5SDavid du Colombier 	char *s, *p;
8*63afb9a5SDavid du Colombier 	int afd, ret;
9*63afb9a5SDavid du Colombier 	AuthRpc *rpc;
10*63afb9a5SDavid du Colombier 	Msg *m;
11*63afb9a5SDavid du Colombier 	mpint *chal, *decr, *unpad, *mod;
12*63afb9a5SDavid du Colombier 
13*63afb9a5SDavid du Colombier 	debug(DBG_AUTH, "rsa!\n");
14*63afb9a5SDavid du Colombier 
15*63afb9a5SDavid du Colombier 	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
16*63afb9a5SDavid du Colombier 		debug(DBG_AUTH, "open /mnt/factotum/rpc: %r\n");
17*63afb9a5SDavid du Colombier 		return -1;
18*63afb9a5SDavid du Colombier 	}
19*63afb9a5SDavid du Colombier 	if((rpc = auth_allocrpc(afd)) == nil){
20*63afb9a5SDavid du Colombier 		debug(DBG_AUTH, "auth_allocrpc: %r\n");
21*63afb9a5SDavid du Colombier 		close(afd);
22*63afb9a5SDavid du Colombier 		return -1;
23*63afb9a5SDavid du Colombier 	}
24*63afb9a5SDavid du Colombier 	s = "proto=rsa role=client";
25*63afb9a5SDavid du Colombier 	if(auth_rpc(rpc, "start", s, strlen(s)) != ARok){
26*63afb9a5SDavid du Colombier 		debug(DBG_AUTH, "auth_rpc start %s failed: %r\n", s);
27*63afb9a5SDavid du Colombier 		auth_freerpc(rpc);
28*63afb9a5SDavid du Colombier 		close(afd);
29*63afb9a5SDavid du Colombier 		return -1;
30*63afb9a5SDavid du Colombier 	}
31*63afb9a5SDavid du Colombier 
32*63afb9a5SDavid du Colombier 	ret = -1;
33*63afb9a5SDavid du Colombier 	debug(DBG_AUTH, "trying factotum rsa keys\n");
34*63afb9a5SDavid du Colombier 	while(auth_rpc(rpc, "read", nil, 0) == ARok){
35*63afb9a5SDavid du Colombier 		debug(DBG_AUTH, "try %s\n", (char*)rpc->arg);
36*63afb9a5SDavid du Colombier 		mod = strtomp(rpc->arg, nil, 16, nil);
37*63afb9a5SDavid du Colombier 		m = allocmsg(c, SSH_CMSG_AUTH_RSA, 16+(mpsignif(mod)+7/8));
38*63afb9a5SDavid du Colombier 		putmpint(m, mod);
39*63afb9a5SDavid du Colombier 		sendmsg(m);
40*63afb9a5SDavid du Colombier 		mpfree(mod);
41*63afb9a5SDavid du Colombier 		m = recvmsg(c, -1);
42*63afb9a5SDavid du Colombier 		switch(m->type){
43*63afb9a5SDavid du Colombier 		case SSH_SMSG_FAILURE:
44*63afb9a5SDavid du Colombier 			debug(DBG_AUTH, "\tnot accepted %s\n", (char*)rpc->arg);
45*63afb9a5SDavid du Colombier 			free(m);
46*63afb9a5SDavid du Colombier 			continue;
47*63afb9a5SDavid du Colombier 		default:
48*63afb9a5SDavid du Colombier 			badmsg(m, 0);
49*63afb9a5SDavid du Colombier 		case SSH_SMSG_AUTH_RSA_CHALLENGE:
50*63afb9a5SDavid du Colombier 			break;
51*63afb9a5SDavid du Colombier 		}
52*63afb9a5SDavid du Colombier 		chal = getmpint(m);
53*63afb9a5SDavid du Colombier 		debug(DBG_AUTH, "\tgot challenge %B\n", chal);
54*63afb9a5SDavid du Colombier 		free(m);
55*63afb9a5SDavid du Colombier 		p = mptoa(chal, 16, nil, 0);
56*63afb9a5SDavid du Colombier 		mpfree(chal);
57*63afb9a5SDavid du Colombier 		if(p == nil){
58*63afb9a5SDavid du Colombier 			debug(DBG_AUTH, "\tmptoa failed: %r\n");
59*63afb9a5SDavid du Colombier 			unpad = mpnew(0);
60*63afb9a5SDavid du Colombier 			goto Keepgoing;
61*63afb9a5SDavid du Colombier 		}
62*63afb9a5SDavid du Colombier 		if(auth_rpc(rpc, "write", p, strlen(p)) != ARok){
63*63afb9a5SDavid du Colombier 			debug(DBG_AUTH, "\tauth_rpc write failed: %r\n");
64*63afb9a5SDavid du Colombier 			free(p);
65*63afb9a5SDavid du Colombier 			unpad = mpnew(0);	/* it will fail, we'll go round again */
66*63afb9a5SDavid du Colombier 			goto Keepgoing;
67*63afb9a5SDavid du Colombier 		}
68*63afb9a5SDavid du Colombier 		free(p);
69*63afb9a5SDavid du Colombier 		if(auth_rpc(rpc, "read", nil, 0) != ARok){
70*63afb9a5SDavid du Colombier 			debug(DBG_AUTH, "\tauth_rpc read failed: %r\n");
71*63afb9a5SDavid du Colombier 			unpad = mpnew(0);
72*63afb9a5SDavid du Colombier 			goto Keepgoing;
73*63afb9a5SDavid du Colombier 		}
74*63afb9a5SDavid du Colombier 		decr = strtomp(rpc->arg, nil, 16, nil);
75*63afb9a5SDavid du Colombier 		debug(DBG_AUTH, "\tdecrypted %B\n", decr);
76*63afb9a5SDavid du Colombier 		unpad = rsaunpad(decr);
77*63afb9a5SDavid du Colombier 		debug(DBG_AUTH, "\tunpadded %B\n", unpad);
78*63afb9a5SDavid du Colombier 		mpfree(decr);
79*63afb9a5SDavid du Colombier 	Keepgoing:
80*63afb9a5SDavid du Colombier 		mptoberjust(unpad, chalbuf, 32);
81*63afb9a5SDavid du Colombier 		mpfree(unpad);
82*63afb9a5SDavid du Colombier 		debug(DBG_AUTH, "\trjusted %.*H\n", 32, chalbuf);
83*63afb9a5SDavid du Colombier 		memmove(chalbuf+32, c->sessid, SESSIDLEN);
84*63afb9a5SDavid du Colombier 		debug(DBG_AUTH, "\tappend sesskey %.*H\n", 32, chalbuf);
85*63afb9a5SDavid du Colombier 		md5(chalbuf, 32+SESSIDLEN, response, nil);
86*63afb9a5SDavid du Colombier 		m = allocmsg(c, SSH_CMSG_AUTH_RSA_RESPONSE, MD5dlen);
87*63afb9a5SDavid du Colombier 		putbytes(m, response, MD5dlen);
88*63afb9a5SDavid du Colombier 		sendmsg(m);
89*63afb9a5SDavid du Colombier 
90*63afb9a5SDavid du Colombier 		m = recvmsg(c, -1);
91*63afb9a5SDavid du Colombier 		switch(m->type){
92*63afb9a5SDavid du Colombier 		case SSH_SMSG_FAILURE:
93*63afb9a5SDavid du Colombier 			free(m);
94*63afb9a5SDavid du Colombier 			continue;
95*63afb9a5SDavid du Colombier 		default:
96*63afb9a5SDavid du Colombier 			badmsg(m, 0);
97*63afb9a5SDavid du Colombier 		case SSH_SMSG_SUCCESS:
98*63afb9a5SDavid du Colombier 			break;
99*63afb9a5SDavid du Colombier 		}
100*63afb9a5SDavid du Colombier 		ret = 0;
101*63afb9a5SDavid du Colombier 		break;
102*63afb9a5SDavid du Colombier 	}
103*63afb9a5SDavid du Colombier 	auth_freerpc(rpc);
104*63afb9a5SDavid du Colombier 	close(afd);
105*63afb9a5SDavid du Colombier 	return ret;
106*63afb9a5SDavid du Colombier }
107*63afb9a5SDavid du Colombier 
108*63afb9a5SDavid du Colombier Auth authrsa =
109*63afb9a5SDavid du Colombier {
110*63afb9a5SDavid du Colombier 	SSH_AUTH_RSA,
111*63afb9a5SDavid du Colombier 	"rsa",
112*63afb9a5SDavid du Colombier 	authrsafn,
113*63afb9a5SDavid du Colombier };
114