1 #include "ssh.h" 2 3 static int 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