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