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