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