authrsa.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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=sshrsa 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. if(m == nil)
  39. badmsg(m, 0);
  40. switch(m->type){
  41. case SSH_SMSG_FAILURE:
  42. debug(DBG_AUTH, "\tnot accepted\n", (char*)rpc->arg);
  43. free(m);
  44. continue;
  45. default:
  46. badmsg(m, 0);
  47. case SSH_SMSG_AUTH_RSA_CHALLENGE:
  48. break;
  49. }
  50. chal = getmpint(m);
  51. debug(DBG_AUTH, "\tgot challenge %B\n", chal);
  52. free(m);
  53. p = mptoa(chal, 16, nil, 0);
  54. mpfree(chal);
  55. if(p == nil){
  56. debug(DBG_AUTH, "\tmptoa failed: %r\n");
  57. unpad = mpnew(0);
  58. goto Keepgoing;
  59. }
  60. if(auth_rpc(rpc, "write", p, strlen(p)) != ARok){
  61. debug(DBG_AUTH, "\tauth_rpc write failed: %r\n");
  62. free(p);
  63. unpad = mpnew(0); /* it will fail, we'll go round again */
  64. goto Keepgoing;
  65. }
  66. free(p);
  67. if(auth_rpc(rpc, "read", nil, 0) != ARok){
  68. debug(DBG_AUTH, "\tauth_rpc read failed: %r\n");
  69. unpad = mpnew(0);
  70. goto Keepgoing;
  71. }
  72. decr = strtomp(rpc->arg, nil, 16, nil);
  73. debug(DBG_AUTH, "\tdecrypted %B\n", decr);
  74. unpad = rsaunpad(decr);
  75. debug(DBG_AUTH, "\tunpadded %B\n", unpad);
  76. mpfree(decr);
  77. Keepgoing:
  78. mptoberjust(unpad, chalbuf, 32);
  79. mpfree(unpad);
  80. debug(DBG_AUTH, "\trjusted %.*H\n", 32, chalbuf);
  81. memmove(chalbuf+32, c->sessid, SESSIDLEN);
  82. debug(DBG_AUTH, "\tappend sesskey %.*H\n", 32, chalbuf);
  83. md5(chalbuf, 32+SESSIDLEN, response, nil);
  84. m = allocmsg(c, SSH_CMSG_AUTH_RSA_RESPONSE, MD5dlen);
  85. putbytes(m, response, MD5dlen);
  86. sendmsg(m);
  87. m = recvmsg(c, 0);
  88. if(m == nil)
  89. badmsg(m, 0);
  90. switch(m->type){
  91. case SSH_SMSG_FAILURE:
  92. free(m);
  93. continue;
  94. default:
  95. badmsg(m, 0);
  96. case SSH_SMSG_SUCCESS:
  97. break;
  98. }
  99. ret = 0;
  100. break;
  101. }
  102. auth_freerpc(rpc);
  103. close(afd);
  104. return ret;
  105. }
  106. Auth authrsa =
  107. {
  108. SSH_AUTH_RSA,
  109. "rsa",
  110. authrsafn,
  111. };