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

Collapse All | Expand All

(-)a/auth2-pubkey.c (-11 / +64 lines)
Lines 510-515 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
510
	int status, devnull, p[2], i;
510
	int status, devnull, p[2], i;
511
	pid_t pid;
511
	pid_t pid;
512
	char *username, errmsg[512];
512
	char *username, errmsg[512];
513
	char *command, *cp, *argv[4];
514
	char *key_fp = NULL, *keytext = NULL;
515
	char *authorized_keys_command_path;
516
	size_t keytextlen;
513
517
514
	if (options.authorized_keys_command == NULL ||
518
	if (options.authorized_keys_command == NULL ||
515
	    options.authorized_keys_command[0] != '/')
519
	    options.authorized_keys_command[0] != '/')
Lines 533-544 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
533
537
534
	temporarily_use_uid(pw);
538
	temporarily_use_uid(pw);
535
539
536
	if (stat(options.authorized_keys_command, &st) < 0) {
540
	if (strstr(options.authorized_keys_command, "%f") != NULL) {
541
		key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
542
		if (key_fp == NULL) {
543
			error("AuthorizedKeysCommand %%f parameter expansion failed");
544
			return 0;
545
		}
546
	}
547
	if (strstr(options.authorized_keys_command, "%k") != NULL) {
548
		if (key_to_base64(key, &keytext, &keytextlen) != 0) {
549
			error("AuthorizedKeysCommand %%k parameter expansion failed");
550
			free(key_fp);
551
			return 0;
552
		}
553
	}
554
	command = cp = percent_expand(options.authorized_keys_command,
555
	    "u", user_pw->pw_name, "t", key_ssh_name(key),
556
	    "f", key_fp == NULL ? "" : key_fp,
557
	    "k", keytext == NULL ? "" : keytext, (char *)NULL);
558
	if (keytext != NULL)
559
		free(keytext);
560
	if (key_fp != NULL)
561
		free(key_fp);
562
563
	authorized_keys_command_path = strdelim(&cp);
564
	memset(argv, 0, sizeof(argv));
565
	for (i = 0; cp != NULL && (size_t)i < sizeof(argv); i++)
566
		argv[i] = strdelim(&cp);
567
	if (i == 0)
568
		argv[0] = user_pw->pw_name;
569
570
	if (stat(authorized_keys_command_path, &st) < 0) {
537
		error("Could not stat AuthorizedKeysCommand \"%s\": %s",
571
		error("Could not stat AuthorizedKeysCommand \"%s\": %s",
538
		    options.authorized_keys_command, strerror(errno));
572
		    authorized_keys_command_path, strerror(errno));
539
		goto out;
573
		goto out;
540
	}
574
	}
541
	if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0,
575
	if (auth_secure_path(authorized_keys_command_path, &st, NULL, 0,
542
	    errmsg, sizeof(errmsg)) != 0) {
576
	    errmsg, sizeof(errmsg)) != 0) {
543
		error("Unsafe AuthorizedKeysCommand: %s", errmsg);
577
		error("Unsafe AuthorizedKeysCommand: %s", errmsg);
544
		goto out;
578
		goto out;
Lines 549-556 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
549
		goto out;
583
		goto out;
550
	}
584
	}
551
585
552
	debug3("Running AuthorizedKeysCommand: \"%s %s\" as \"%s\"",
586
	debug3("Running AuthorizedKeysCommand: \"%s %s%s%s%s%s%s%s\" as \"%s\"",
553
	    options.authorized_keys_command, user_pw->pw_name, pw->pw_name);
587
	    authorized_keys_command_path, argv[0],
588
	    argv[1] == NULL ? "" : " ", argv[1] == NULL ? "" : argv[1],
589
	    argv[2] == NULL ? "" : " ", argv[2] == NULL ? "" : argv[2],
590
	    argv[3] == NULL ? "" : " ", argv[3] == NULL ? "" : argv[3],
591
	    pw->pw_name);
554
592
555
	/*
593
	/*
556
	 * Don't want to call this in the child, where it can fatal() and
594
	 * Don't want to call this in the child, where it can fatal() and
Lines 563-568 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
563
		error("%s: fork: %s", __func__, strerror(errno));
601
		error("%s: fork: %s", __func__, strerror(errno));
564
		close(p[0]);
602
		close(p[0]);
565
		close(p[1]);
603
		close(p[1]);
604
		free(command);
566
		return 0;
605
		return 0;
567
	case 0: /* child */
606
	case 0: /* child */
568
		for (i = 0; i < NSIG; i++)
607
		for (i = 0; i < NSIG; i++)
Lines 598-608 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
598
			_exit(1);
637
			_exit(1);
599
		}
638
		}
600
639
601
		execl(options.authorized_keys_command,
640
		if (argv[3] != NULL)
602
		    options.authorized_keys_command, user_pw->pw_name, NULL);
641
			execl(authorized_keys_command_path,
642
			    authorized_keys_command_path,
643
			    argv[0], argv[1], argv[2], argv[3], (char *)NULL);
644
		else if (argv[2] != NULL)
645
			execl(authorized_keys_command_path,
646
			    authorized_keys_command_path,
647
			    argv[0], argv[1], argv[2], (char *)NULL);
648
		else if (argv[1] != NULL)
649
			execl(authorized_keys_command_path,
650
			    authorized_keys_command_path,
651
			    argv[0], argv[1], (char *)NULL);
652
		else
653
			execl(authorized_keys_command_path,
654
			    authorized_keys_command_path, argv[0], (char *)NULL);
603
655
604
		error("AuthorizedKeysCommand %s exec failed: %s",
656
		error("AuthorizedKeysCommand %s exec failed: %s",
605
		    options.authorized_keys_command, strerror(errno));
657
		    authorized_keys_command_path, strerror(errno));
606
		_exit(127);
658
		_exit(127);
607
	default: /* parent */
659
	default: /* parent */
608
		break;
660
		break;
Lines 620-626 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
620
			;
672
			;
621
		goto out;
673
		goto out;
622
	}
674
	}
623
	ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
675
	ok = check_authkeys_file(f, authorized_keys_command_path, key, pw);
624
	fclose(f);
676
	fclose(f);
625
677
626
	while (waitpid(pid, &status, 0) == -1) {
678
	while (waitpid(pid, &status, 0) == -1) {
Lines 631-645 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
631
	}
683
	}
632
	if (WIFSIGNALED(status)) {
684
	if (WIFSIGNALED(status)) {
633
		error("AuthorizedKeysCommand %s exited on signal %d",
685
		error("AuthorizedKeysCommand %s exited on signal %d",
634
		    options.authorized_keys_command, WTERMSIG(status));
686
		    authorized_keys_command_path, WTERMSIG(status));
635
		goto out;
687
		goto out;
636
	} else if (WEXITSTATUS(status) != 0) {
688
	} else if (WEXITSTATUS(status) != 0) {
637
		error("AuthorizedKeysCommand %s returned status %d",
689
		error("AuthorizedKeysCommand %s returned status %d",
638
		    options.authorized_keys_command, WEXITSTATUS(status));
690
		    authorized_keys_command_path, WEXITSTATUS(status));
639
		goto out;
691
		goto out;
640
	}
692
	}
641
	found_key = ok;
693
	found_key = ok;
642
 out:
694
 out:
695
	free(command);
643
	restore_uid();
696
	restore_uid();
644
	return found_key;
697
	return found_key;
645
}
698
}
(-)a/key.h (+1 lines)
Lines 61-66 typedef struct sshkey Key; Link Here
61
#define key_dump_ec_point	sshkey_dump_ec_point
61
#define key_dump_ec_point	sshkey_dump_ec_point
62
#define key_dump_ec_key		sshkey_dump_ec_key
62
#define key_dump_ec_key		sshkey_dump_ec_key
63
#define key_fingerprint		sshkey_fingerprint
63
#define key_fingerprint		sshkey_fingerprint
64
#define key_to_base64		sshkey_to_base64
64
#endif
65
#endif
65
66
66
void	 key_add_private(Key *);
67
void	 key_add_private(Key *);
(-)a/sshd_config.5 (-1 / +6 lines)
Lines 220-226 of a single authentication method is sufficient. Link Here
220
Specifies a program to be used to look up the user's public keys.
220
Specifies a program to be used to look up the user's public keys.
221
The program must be owned by root and not writable by group or others.
221
The program must be owned by root and not writable by group or others.
222
It will be invoked with a single argument of the username
222
It will be invoked with a single argument of the username
223
being authenticated, and should produce on standard output zero or
223
being authenticated, unless any of the following tokens, which are
224
expanded at runtime, are provided: %u is replaced by the username
225
being authenticated, %t is replaced with the key type offered for
226
authentication, %f is replaced with the fingerprint of the key, and
227
%k is replaced with the key being offered for authentication.
228
The program should produce on standard output zero or
224
more lines of authorized_keys output (see AUTHORIZED_KEYS in
229
more lines of authorized_keys output (see AUTHORIZED_KEYS in
225
.Xr sshd 8 ) .
230
.Xr sshd 8 ) .
226
If a key supplied by AuthorizedKeysCommand does not successfully authenticate
231
If a key supplied by AuthorizedKeysCommand does not successfully authenticate
(-)a/sshkey.c (+72 lines)
Lines 1427-1432 sshkey_write(const struct sshkey *key, FILE *f) Link Here
1427
	return ret;
1427
	return ret;
1428
}
1428
}
1429
1429
1430
int
1431
sshkey_to_base64(const struct sshkey *key, char **blobp, size_t *lenp)
1432
{
1433
	int ret = SSH_ERR_INTERNAL_ERROR;
1434
	struct sshbuf *b = NULL, *bb = NULL;
1435
	char *uu = NULL;
1436
	size_t len;
1437
1438
	if (lenp != NULL)
1439
		*lenp = 0;
1440
	if (blobp != NULL)
1441
		*blobp = NULL;
1442
1443
	if (sshkey_is_cert(key)) {
1444
		if (key->cert == NULL)
1445
			return SSH_ERR_EXPECTED_CERT;
1446
		if (sshbuf_len(key->cert->certblob) == 0)
1447
			return SSH_ERR_KEY_LACKS_CERTBLOB;
1448
	}
1449
	if ((b = sshbuf_new()) == NULL)
1450
		return SSH_ERR_ALLOC_FAIL;
1451
	switch (key->type) {
1452
#ifdef WITH_OPENSSL
1453
	case KEY_DSA:
1454
	case KEY_DSA_CERT_V00:
1455
	case KEY_DSA_CERT:
1456
	case KEY_ECDSA:
1457
	case KEY_ECDSA_CERT:
1458
	case KEY_RSA:
1459
	case KEY_RSA_CERT_V00:
1460
	case KEY_RSA_CERT:
1461
#endif /* WITH_OPENSSL */
1462
	case KEY_ED25519:
1463
	case KEY_ED25519_CERT:
1464
		if ((bb = sshbuf_new()) == NULL) {
1465
			ret = SSH_ERR_ALLOC_FAIL;
1466
			goto out;
1467
		}
1468
		if ((ret = sshkey_to_blob_buf(key, bb)) != 0)
1469
			goto out;
1470
		if ((uu = sshbuf_dtob64(bb)) == NULL) {
1471
			ret = SSH_ERR_ALLOC_FAIL;
1472
			goto out;
1473
		}
1474
		if ((ret = sshbuf_put(b, uu, strlen(uu))) != 0)
1475
			goto out;
1476
		break;
1477
	default:
1478
		ret = SSH_ERR_KEY_TYPE_UNKNOWN;
1479
		goto out;
1480
	}
1481
	len = sshbuf_len(b);
1482
	if (lenp != NULL)
1483
		*lenp = len;
1484
	if (blobp != NULL) {
1485
		if ((*blobp = malloc(len)) == NULL) {
1486
			ret = SSH_ERR_ALLOC_FAIL;
1487
			goto out;
1488
		}
1489
		memcpy(*blobp, sshbuf_ptr(b), len);
1490
	}
1491
	ret = 0;
1492
 out:
1493
	if (b != NULL)
1494
		sshbuf_free(b);
1495
	if (bb != NULL)
1496
		sshbuf_free(bb);
1497
	if (uu != NULL)
1498
		free(uu);
1499
	return ret;
1500
}
1501
1430
const char *
1502
const char *
1431
sshkey_cert_type(const struct sshkey *k)
1503
sshkey_cert_type(const struct sshkey *k)
1432
{
1504
{
(-)a/sshkey.h (-1 / +2 lines)
Lines 167-172 int sshkey_to_blob(const struct sshkey *, u_char **, size_t *); Link Here
167
int	 sshkey_plain_to_blob_buf(const struct sshkey *, struct sshbuf *);
167
int	 sshkey_plain_to_blob_buf(const struct sshkey *, struct sshbuf *);
168
int	 sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
168
int	 sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
169
169
170
int	 sshkey_to_base64(const struct sshkey *, char **, size_t *);
171
170
int	 sshkey_sign(const struct sshkey *, u_char **, size_t *,
172
int	 sshkey_sign(const struct sshkey *, u_char **, size_t *,
171
    const u_char *, size_t, u_int);
173
    const u_char *, size_t, u_int);
172
int	 sshkey_verify(const struct sshkey *, const u_char *, size_t,
174
int	 sshkey_verify(const struct sshkey *, const u_char *, size_t,
173
- 

Return to bug 2081