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