~kris/9p

9hist

ref: a58e250508740bf66041bd946455d286b4603dec 9hist/boot/userpasswd.c -rw-r--r-- 1.9 KiB
a58e2505 — David du Colombier Plan 9 from Bell Labs 1992-03-17 34 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <u.h>
#include <libc.h>
#include <../boot/boot.h>

char	password[NAMELEN];

static int
passtokey(char *key, char *p, int n)
{
	uchar t[10];
	int c;

	memset(t, ' ', sizeof t);
	if(n < 5)
		return 0;
	if(n > 10)
		n = 10;
	strncpy((char*)t, p, n);
	if(n >= 9){
		c = p[8] & 0xf;
		if(n == 10)
			c += p[9] << 4;
		for(n = 0; n < 8; n++)
			if(c & (1 << n))
				t[n] -= ' ';
	}
	for(n = 0; n < 7; n++)
		key[n] = (t[n] >> n) + (t[n+1] << (8 - (n+1)));
	return 1;
}

/*
 *  get/set user name and password.  verify password with auth server.
 */
void
userpasswd(Method *mp)
{
	char key[7];
	char buf[8 + NAMELEN];
	int fd, crfd;

	if(*username == 0 || strcmp(username, "none") == 0){
		strcpy(username, "none");
		outin("user", username, sizeof(username));
	}
	crfd = fd = -1;
	while(strcmp(username, "none") != 0 && strcmp(mp->name, "local") != 0){
		getpasswd(password, sizeof password);
		if(!passtokey(key, password, strlen(password))){
			print("bad password; try again\n");
			continue;
		}
		fd = open("#c/key", OWRITE);
		if(fd < 0)
			fatal("can't open #c/key; please reboot");
		if(write(fd, key, 7) != 7)
			fatal("can't write #c/key; please reboot");
		close(fd);
		crfd = open("#c/crypt", ORDWR);
		if(crfd < 0)
			fatal("can't open crypt file");
		write(crfd, "E", 1);
		fd = (*mp->auth)();
		if(fd < 0){
			warning("password not checked!");
			break;
		}
		strncpy(buf+8, username, NAMELEN);
		if(read(fd, buf, 8) != 8
		|| write(crfd, buf, 8) != 8
		|| read(crfd, buf, 8) != 8
		|| write(fd, buf, 8 + NAMELEN) != 8 + NAMELEN){
			warning("password not checked!");
			break;
		}
		if(read(fd, buf, 2) == 2 && buf[0]=='O' && buf[1]=='K')
			break;
		close(fd);
		outin("user", username, sizeof(username));
	}
	close(fd);
	close(crfd);

	/* set user now that we're sure */
	fd = open("#c/user", OWRITE|OTRUNC);
	if(fd >= 0){
		if(write(fd, username, strlen(username)) < 0)
			warning("write user name");
		close(fd);
	}else
		warning("open #c/user");
}