Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/ssh1/pubkey.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "ssh.h"
2
#include <bio.h>
3
#include <ctype.h>
4
 
5
static int
6
parsepubkey(char *s, RSApub *key, char **sp, int base)
7
{
8
	int n;
9
	char *host, *p, *z;
10
 
11
	z = nil;
12
	n = strtoul(s, &p, 10);
13
	host = nil;
14
	if(n < 256 || !isspace(*p)){	/* maybe this is a host name */
15
		host = s;
16
		s = strpbrk(s, " \t");
17
		if(s == nil)
18
			return -1;
19
		z = s;
20
		*s++ = '\0';
21
		s += strspn(s, " \t");
22
 
23
		n = strtoul(s, &p, 10);
24
		if(n < 256 || !isspace(*p)){
25
			if(z)
26
				*z = ' ';
27
			return -1;
28
		}
29
	}
30
 
31
	if((key->ek = strtomp(p, &p, base, nil)) == nil
32
	|| (key->n = strtomp(p, &p, base, nil)) == nil
33
	|| (*p != '\0' && !isspace(*p))
34
	|| mpsignif(key->n) < 256){	/* 256 is just a sanity check */
35
		mpfree(key->ek);
36
		mpfree(key->n);
37
		key->ek = nil;
38
		key->n = nil;
39
		if(z)
40
			*z = ' ';
41
		return -1;
42
	}
43
	if(host == nil){
44
		if(*p != '\0'){
45
			p += strspn(p, " \t");
46
			if(*p != '\0'){
47
				host = emalloc(strlen(p)+1);
48
				strcpy(host, p);
49
			}
50
		}
51
		free(s);
52
	}
53
	*sp = host;
54
	return 0;
55
}
56
 
57
RSApub*
58
readpublickey(Biobuf *b, char **sp)
59
{
60
	char *s;
61
	RSApub *key;
62
 
63
	key = rsapuballoc();
64
	if(key == nil)
65
		return nil;
66
 
67
	for(;;){
68
		if((s = Brdstr(b, '\n', 1)) == nil){
69
			rsapubfree(key);
70
			return nil;
71
		}
72
		if(s[0]=='#'){
73
			free(s);
74
			continue;
75
		}
76
		if(parsepubkey(s, key, sp, 10)==0
77
		|| parsepubkey(s, key, sp, 16)==0)
78
			return key;
79
		fprint(2, "warning: skipping line '%s'; cannot parse\n", s);
80
		free(s);
81
	}
82
}
83
 
84
static int
85
match(char *pattern, char *aliases)
86
{
87
	char *s, *snext;
88
	char *a, *anext, *ae;
89
 
90
	for(s=pattern; s && *s; s=snext){
91
		if((snext=strchr(s, ',')) != nil)
92
			*snext++ = '\0';
93
		for(a=aliases; a && *a; a=anext){
94
			if((anext=strchr(a, ',')) != nil){
95
				ae = anext;
96
				anext++;
97
			}else
98
				ae = a+strlen(a);
99
			if(ae-a == strlen(s) && memcmp(s, a, ae-a)==0)
100
				return 0;
101
		}
102
	}
103
	return 1;
104
}
105
 
106
int
107
findkey(char *keyfile, char *host, RSApub *key)
108
{
109
	char *h;
110
	Biobuf *b;
111
	RSApub *k;
112
 
113
	if((b = Bopen(keyfile, OREAD)) == nil)
114
		return NoKeyFile;
115
 
116
	for(;;){
117
		if((k = readpublickey(b, &h)) == nil){
118
			Bterm(b);
119
			return NoKey;
120
		}
121
		if(match(h, host) != 0){
122
			free(h);
123
			rsapubfree(k);
124
			continue;
125
		}
126
		if(mpcmp(k->n, key->n) != 0 || mpcmp(k->ek, key->ek) != 0){
127
			free(h);
128
			rsapubfree(k);
129
			Bterm(b);
130
			return KeyWrong;
131
		}
132
		free(h);
133
		rsapubfree(k);
134
		Bterm(b);
135
		return KeyOk;
136
	}
137
}
138
 
139
int
140
replacekey(char *keyfile, char *host, RSApub *hostkey)
141
{
142
	char *h, *nkey, *p;
143
	Biobuf *br, *bw;
144
	Dir *d, nd;
145
	RSApub *k;
146
 
147
	nkey = smprint("%s.new", keyfile);
148
	if(nkey == nil)
149
		return -1;
150
 
151
	if((br = Bopen(keyfile, OREAD)) == nil){
152
		free(nkey);
153
		return -1;
154
	}
155
	if((bw = Bopen(nkey, OWRITE)) == nil){
156
		Bterm(br);
157
		free(nkey);
158
		return -1;
159
	}
160
 
161
	while((k = readpublickey(br, &h)) != nil){
162
		if(match(h, host) != 0){
163
			Bprint(bw, "%s %d %.10B %.10B\n",
164
				h, mpsignif(k->n), k->ek, k->n);
165
		}
166
		free(h);
167
		rsapubfree(k);
168
	}
169
	Bprint(bw, "%s %d %.10B %.10B\n", host, mpsignif(hostkey->n), hostkey->ek, hostkey->n);
170
	Bterm(bw);
171
	Bterm(br);
172
 
173
	d = dirstat(nkey);
174
	if(d == nil){
175
		fprint(2, "new key file disappeared?\n");
176
		free(nkey);
177
		return -1;
178
	}
179
 
180
	p = strrchr(d->name, '.');
181
	if(p==nil || strcmp(p, ".new")!=0){
182
		fprint(2, "new key file changed names? %s to %s\n", nkey, d->name);
183
		free(d);
184
		free(nkey);
185
		return -1;
186
	}
187
 
188
	*p = '\0';
189
	nulldir(&nd);
190
	nd.name = d->name;
191
	if(remove(keyfile) < 0){
192
		fprint(2, "error removing %s: %r\n", keyfile);
193
		free(d);
194
		free(nkey);
195
		return -1;
196
	}
197
	if(dirwstat(nkey, &nd) < 0){
198
		fprint(2, "error renaming %s to %s: %r\n", nkey, d->name);
199
		free(nkey);
200
		free(d);
201
		return -1;
202
	}
203
	free(d);
204
	free(nkey);
205
	return 0;
206
}
207
 
208
int
209
appendkey(char *keyfile, char *host, RSApub *key)
210
{
211
	int fd;
212
 
213
	if((fd = open(keyfile, OWRITE)) < 0){
214
		fd = create(keyfile, OWRITE, 0666);
215
		if(fd < 0){
216
			fprint(2, "cannot open nor create %s: %r\n", keyfile);
217
			return -1;
218
		}
219
	}
220
	if(seek(fd, 0, 2) < 0
221
	|| fprint(fd, "%s %d %.10B %.10B\n", host, mpsignif(key->n), key->ek, key->n) < 0){
222
		close(fd);
223
		return -1;
224
	}
225
	close(fd);
226
	return 0;
227
}