netcheck.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <u.h>
  2. #include <libc.h>
  3. #include "authcmdlib.h"
  4. /*
  5. * compute the key verification checksum
  6. */
  7. void
  8. checksum(char key[], char csum[]) {
  9. uchar buf[8];
  10. memset(buf, 0, 8);
  11. encrypt(key, buf, 8);
  12. sprint(csum, "C %.2ux%.2ux%.2ux%.2ux", buf[0], buf[1], buf[2], buf[3]);
  13. }
  14. /*
  15. * compute the proper response. We encrypt the ascii of
  16. * challenge number, with trailing binary zero fill.
  17. * This process was derived empirically.
  18. * this was copied from inet's guard.
  19. */
  20. char *
  21. netresp(char *key, long chal, char *answer)
  22. {
  23. uchar buf[8];
  24. memset(buf, 0, 8);
  25. sprint((char *)buf, "%lud", chal);
  26. if(encrypt(key, buf, 8) < 0)
  27. error("can't encrypt response");
  28. chal = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3];
  29. sprint(answer, "%.8lux", chal);
  30. return answer;
  31. }
  32. char *
  33. netdecimal(char *answer)
  34. {
  35. int i;
  36. for(i = 0; answer[i]; i++)
  37. switch(answer[i]){
  38. case 'a': case 'b': case 'c':
  39. answer[i] = '2';
  40. break;
  41. case 'd': case 'e': case 'f':
  42. answer[i] = '3';
  43. break;
  44. }
  45. return answer;
  46. }
  47. int
  48. netcheck(void *key, long chal, char *response)
  49. {
  50. char answer[32], *p;
  51. int i;
  52. if(smartcheck(key, chal, response))
  53. return 1;
  54. if(p = strchr(response, '\n'))
  55. *p = '\0';
  56. netresp(key, chal, answer);
  57. /*
  58. * check for hex response -- securenet mode 1 or 5
  59. */
  60. for(i = 0; response[i]; i++)
  61. if(response[i] >= 'A' && response[i] <= 'Z')
  62. response[i] -= 'A' - 'a';
  63. if(strcmp(answer, response) == 0)
  64. return 1;
  65. /*
  66. * check for decimal response -- securenet mode 0 or 4
  67. */
  68. return strcmp(netdecimal(answer), response) == 0;
  69. }
  70. int
  71. smartcheck(void *key, long chal, char *response)
  72. {
  73. uchar buf[2*8];
  74. int i, c, cslo, cshi;
  75. sprint((char*)buf, "%lud ", chal);
  76. cslo = 0x52;
  77. cshi = cslo;
  78. for(i = 0; i < 8; i++){
  79. c = buf[i];
  80. if(c >= '0' && c <= '9')
  81. c -= '0';
  82. cslo += c;
  83. if(cslo > 0xff)
  84. cslo -= 0xff;
  85. cshi += cslo;
  86. if(cshi > 0xff)
  87. cshi -= 0xff;
  88. buf[i] = c | (cshi & 0xf0);
  89. }
  90. encrypt(key, buf, 8);
  91. for(i = 0; i < 8; i++)
  92. if(response[i] != buf[i] % 10 + '0')
  93. return 0;
  94. return 1;
  95. }