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