authrsafile.c 2.9 KB

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