xref: /plan9/sys/src/cmd/auth/lib/netcheck.c (revision f54edc786b9c49b2c7ab1c0695cdc8c698b11f4d)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "authcmdlib.h"
5 
6 /*
7  * compute the key verification checksum
8  */
9 void
checksum(char key[],char csum[])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%.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 *
netresp(char * key,long chal,char * answer)25 netresp(char *key, long chal, char *answer)
26 {
27 	uchar buf[8];
28 
29 	memset(buf, 0, 8);
30 	snprint((char *)buf, sizeof 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 *
netdecimal(char * answer)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
netcheck(void * key,long chal,char * response)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
smartcheck(void * key,long chal,char * response)85 smartcheck(void *key, long chal, char *response)
86 {
87 	uchar buf[2*8];
88 	int i, c, cslo, cshi;
89 
90 	snprint((char*)buf, sizeof 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