View | Details | Raw Unified | Return to bug 2472 | Differences between
and this patch

Collapse All | Expand All

(-)a/ssh-agent.c (-17 / +95 lines)
Lines 109-117 typedef struct { Link Here
109
u_int sockets_alloc = 0;
109
u_int sockets_alloc = 0;
110
SocketEntry *sockets = NULL;
110
SocketEntry *sockets = NULL;
111
111
112
typedef struct refcountkey {
113
	struct sshkey *key;
114
	int count;
115
} RefcountKey;
116
112
typedef struct identity {
117
typedef struct identity {
113
	TAILQ_ENTRY(identity) next;
118
	TAILQ_ENTRY(identity) next;
114
	struct sshkey *key;
119
	RefcountKey *idkey;
120
	RefcountKey *shadowed_key;
115
	char *comment;
121
	char *comment;
116
	char *provider;
122
	char *provider;
117
	time_t death;
123
	time_t death;
Lines 185-200 idtab_lookup(int version) Link Here
185
	return &idtable[version];
191
	return &idtable[version];
186
}
192
}
187
193
194
static RefcountKey *
195
refkey_new(struct sshkey *key)
196
{
197
	RefcountKey *ref = xcalloc(1, sizeof(RefcountKey));
198
199
	ref->key = key;
200
	ref->count = 1;
201
202
	return ref;
203
}
204
205
static RefcountKey *
206
refkey_addref(RefcountKey *refkey)
207
{
208
	++refkey->count;
209
	return refkey;
210
}
211
212
static void refkey_unref(RefcountKey *refkey)
213
{
214
	if (refkey && --refkey->count <= 0) {
215
		sshkey_free(refkey->key);
216
		free(refkey);
217
	}
218
}
219
188
static void
220
static void
189
free_identity(Identity *id)
221
free_identity(Identity *id)
190
{
222
{
191
	sshkey_free(id->key);
223
	refkey_unref(id->idkey);
224
	refkey_unref(id->shadowed_key);
192
	free(id->provider);
225
	free(id->provider);
193
	free(id->comment);
226
	free(id->comment);
194
	free(id);
227
	free(id);
195
}
228
}
196
229
197
/* return matching private key for given public key */
230
/* return matching Identity for given public key */
198
static Identity *
231
static Identity *
199
lookup_identity(struct sshkey *key, int version)
232
lookup_identity(struct sshkey *key, int version)
200
{
233
{
Lines 202-208 lookup_identity(struct sshkey *key, int version) Link Here
202
235
203
	Idtab *tab = idtab_lookup(version);
236
	Idtab *tab = idtab_lookup(version);
204
	TAILQ_FOREACH(id, &tab->idlist, next) {
237
	TAILQ_FOREACH(id, &tab->idlist, next) {
205
		if (sshkey_equal(key, id->key))
238
		if (sshkey_equal(key, id->idkey->key))
239
			return (id);
240
	}
241
	return (NULL);
242
}
243
244
/* return matching private key for given public key */
245
static Identity *
246
lookup_identity_unshadowed_key(struct sshkey *key, int version)
247
{
248
	Identity *id;
249
250
	Idtab *tab = idtab_lookup(version);
251
	TAILQ_FOREACH(id, &tab->idlist, next) {
252
		if (sshkey_equal_public(key, id->idkey->key) &&
253
		    id->shadowed_key == NULL)
206
			return (id);
254
			return (id);
207
	}
255
	}
208
	return (NULL);
256
	return (NULL);
Lines 215-221 confirm_key(Identity *id) Link Here
215
	char *p;
263
	char *p;
216
	int ret = -1;
264
	int ret = -1;
217
265
218
	p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);
266
	p = sshkey_fingerprint(id->idkey->key, fingerprint_hash, SSH_FP_DEFAULT);
219
	if (p != NULL &&
267
	if (p != NULL &&
220
	    ask_permission("Allow use of key %s?\nKey fingerprint %s.",
268
	    ask_permission("Allow use of key %s?\nKey fingerprint %s.",
221
	    id->comment, p))
269
	    id->comment, p))
Lines 253-266 process_request_identities(SocketEntry *e, int version) Link Here
253
	    (r = sshbuf_put_u32(msg, tab->nentries)) != 0)
301
	    (r = sshbuf_put_u32(msg, tab->nentries)) != 0)
254
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
302
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
255
	TAILQ_FOREACH(id, &tab->idlist, next) {
303
	TAILQ_FOREACH(id, &tab->idlist, next) {
256
		if (id->key->type == KEY_RSA1) {
304
		if (id->idkey->key->type == KEY_RSA1) {
257
#ifdef WITH_SSH1
305
#ifdef WITH_SSH1
258
			if ((r = sshbuf_put_u32(msg,
306
			if ((r = sshbuf_put_u32(msg,
259
			    BN_num_bits(id->key->rsa->n))) != 0 ||
307
			    BN_num_bits(id->idkey->key->rsa->n))) != 0 ||
260
			    (r = sshbuf_put_bignum1(msg,
308
			    (r = sshbuf_put_bignum1(msg,
261
			    id->key->rsa->e)) != 0 ||
309
			    id->idkey->key->rsa->e)) != 0 ||
262
			    (r = sshbuf_put_bignum1(msg,
310
			    (r = sshbuf_put_bignum1(msg,
263
			    id->key->rsa->n)) != 0)
311
			    id->idkey->key->rsa->n)) != 0)
264
				fatal("%s: buffer error: %s",
312
				fatal("%s: buffer error: %s",
265
				    __func__, ssh_err(r));
313
				    __func__, ssh_err(r));
266
#endif
314
#endif
Lines 268-274 process_request_identities(SocketEntry *e, int version) Link Here
268
			u_char *blob;
316
			u_char *blob;
269
			size_t blen;
317
			size_t blen;
270
318
271
			if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) {
319
			if ((r = sshkey_to_blob(id->idkey->key, &blob, &blen)) != 0) {
272
				error("%s: sshkey_to_blob: %s", __func__,
320
				error("%s: sshkey_to_blob: %s", __func__,
273
				    ssh_err(r));
321
				    ssh_err(r));
274
				continue;
322
				continue;
Lines 324-330 process_authentication_challenge1(SocketEntry *e) Link Here
324
372
325
	id = lookup_identity(key, 1);
373
	id = lookup_identity(key, 1);
326
	if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
374
	if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
327
		struct sshkey *private = id->key;
375
		struct sshkey *private = id->idkey->key;
328
		/* Decrypt the challenge using the private key. */
376
		/* Decrypt the challenge using the private key. */
329
		if ((r = rsa_private_decrypt(challenge, challenge,
377
		if ((r = rsa_private_decrypt(challenge, challenge,
330
		    private->rsa) != 0)) {
378
		    private->rsa) != 0)) {
Lines 377-383 process_sign_request2(SocketEntry *e) Link Here
377
	u_int compat = 0, flags;
425
	u_int compat = 0, flags;
378
	int r, ok = -1;
426
	int r, ok = -1;
379
	struct sshbuf *msg;
427
	struct sshbuf *msg;
380
	struct sshkey *key;
428
	struct sshkey *key, *sign_key;
381
	struct identity *id;
429
	struct identity *id;
382
430
383
	if ((msg = sshbuf_new()) == NULL)
431
	if ((msg = sshbuf_new()) == NULL)
Lines 400-406 process_sign_request2(SocketEntry *e) Link Here
400
		verbose("%s: user refused key", __func__);
448
		verbose("%s: user refused key", __func__);
401
		goto send;
449
		goto send;
402
	}
450
	}
403
	if ((r = sshkey_sign(id->key, &signature, &slen,
451
452
	if (id->shadowed_key)
453
		sign_key = id->shadowed_key->key;
454
	else
455
		sign_key = id->idkey->key;
456
	if ((r = sshkey_sign(sign_key, &signature, &slen,
404
	    data, dlen, compat)) != 0) {
457
	    data, dlen, compat)) != 0) {
405
		error("%s: sshkey_sign: %s", __func__, ssh_err(ok));
458
		error("%s: sshkey_sign: %s", __func__, ssh_err(ok));
406
		goto send;
459
		goto send;
Lines 640-651 process_add_identity(SocketEntry *e, int version) Link Here
640
		}
693
		}
641
	}
694
	}
642
695
643
	success = 1;
644
	if (lifetime && !death)
696
	if (lifetime && !death)
645
		death = monotime() + lifetime;
697
		death = monotime() + lifetime;
698
699
	/* handle additional certificates for an existing private key */
700
	if (!sshkey_is_private(k)) {
701
		id = lookup_identity_unshadowed_key(k, version);
702
		/* ensure we have a private key and this cert is new */
703
		if (id != NULL && lookup_identity(k, version) == NULL) {
704
			Identity *certid = xcalloc(1, sizeof(Identity));
705
			certid->idkey = refkey_new(k);
706
			certid->shadowed_key = refkey_addref(id->idkey);
707
			if (id->provider)
708
				certid->provider = xstrdup(id->provider);
709
			if (id->comment)
710
				certid->comment = xstrdup(id->comment); /* XXX */
711
			certid->death = death;
712
			certid->confirm = confirm | id->confirm;
713
714
			TAILQ_INSERT_TAIL(&tab->idlist, certid, next);
715
			tab->nentries++;
716
			success = 1;
717
		} else
718
			sshkey_free(k);
719
720
		free(comment);
721
		goto send;
722
	}
723
724
	success = 1;
646
	if ((id = lookup_identity(k, version)) == NULL) {
725
	if ((id = lookup_identity(k, version)) == NULL) {
647
		id = xcalloc(1, sizeof(Identity));
726
		id = xcalloc(1, sizeof(Identity));
648
		id->key = k;
727
		id->idkey = refkey_new(k);
649
		TAILQ_INSERT_TAIL(&tab->idlist, id, next);
728
		TAILQ_INSERT_TAIL(&tab->idlist, id, next);
650
		/* Increment the number of identities. */
729
		/* Increment the number of identities. */
651
		tab->nentries++;
730
		tab->nentries++;
Lines 771-777 process_add_smartcard_key(SocketEntry *e) Link Here
771
		tab = idtab_lookup(version);
850
		tab = idtab_lookup(version);
772
		if (lookup_identity(k, version) == NULL) {
851
		if (lookup_identity(k, version) == NULL) {
773
			id = xcalloc(1, sizeof(Identity));
852
			id = xcalloc(1, sizeof(Identity));
774
			id->key = k;
853
			id->idkey = refkey_new(k);
775
			id->provider = xstrdup(provider);
854
			id->provider = xstrdup(provider);
776
			id->comment = xstrdup(provider); /* XXX */
855
			id->comment = xstrdup(provider); /* XXX */
777
			id->death = death;
856
			id->death = death;
778
- 

Return to bug 2472