authrsa.c 2.5 KB

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