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