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

Collapse All | Expand All

(-)a/auth2-pubkey.c (-12 / +66 lines)
Lines 518-526 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
518
	int ok, found_key = 0;
518
	int ok, found_key = 0;
519
	struct passwd *pw;
519
	struct passwd *pw;
520
	struct stat st;
520
	struct stat st;
521
	int status, devnull, p[2], i;
521
	int status, devnull, p[2], i, argc;
522
	pid_t pid;
522
	pid_t pid;
523
	char *username, errmsg[512];
523
	char *username, errmsg[512];
524
	char *cp, *command = NULL, **argv = NULL;
525
	char *authorized_keys_command_path;
526
	char *key_fp = NULL, *keytext = NULL;
527
	size_t keytextlen;
524
528
525
	if (options.authorized_keys_command == NULL ||
529
	if (options.authorized_keys_command == NULL ||
526
	    options.authorized_keys_command[0] != '/')
530
	    options.authorized_keys_command[0] != '/')
Lines 544-555 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
544
548
545
	temporarily_use_uid(pw);
549
	temporarily_use_uid(pw);
546
550
547
	if (stat(options.authorized_keys_command, &st) < 0) {
551
	if (strstr(options.authorized_keys_command, "%f") != NULL) {
552
		key_fp = key_fingerprint(key, options.fingerprint_hash,
553
		    SSH_FP_DEFAULT);
554
		if (key_fp == NULL) {
555
			error("AuthorizedKeysCommand %%f parameter expansion failed");
556
			goto out;
557
		}
558
	}
559
	if (strstr(options.authorized_keys_command, "%k") != NULL) {
560
		if (key_to_base64(key, &keytext, &keytextlen) != 0) {
561
			error("AuthorizedKeysCommand %%k parameter expansion failed");
562
			goto out;
563
		}
564
	}
565
	command = cp = percent_expand(options.authorized_keys_command,
566
	    "u", user_pw->pw_name, "h", user_pw->pw_dir, "t", key_ssh_name(key),
567
	    "f", key_fp == NULL ? "" : key_fp,
568
	    "k", keytext == NULL ? "" : keytext, (char *)NULL);
569
	i = 0;
570
	argc = 10;
571
	while (cp != NULL) {
572
		if (argv == NULL || i == argc - 1) {
573
			argc *= 2;
574
			argv = xrealloc(argv, argc, sizeof(argv[0]));
575
		}
576
		argv[i++] = strdelim(&cp);
577
		argv[i] = NULL;
578
		debug3("AuthorizedKeysCommand argv[%d]: %s",
579
		    i - 1, argv[i - 1]);
580
	}
581
	if (argv[1] == NULL) {
582
		argv[1] = user_pw->pw_name;
583
		argv[2] = NULL;
584
		debug3("AuthorizedKeysCommand argv[1]: %s", argv[1]);
585
	}
586
	authorized_keys_command_path = argv[0];
587
588
	if (stat(authorized_keys_command_path, &st) < 0) {
548
		error("Could not stat AuthorizedKeysCommand \"%s\": %s",
589
		error("Could not stat AuthorizedKeysCommand \"%s\": %s",
549
		    options.authorized_keys_command, strerror(errno));
590
		    authorized_keys_command_path, strerror(errno));
550
		goto out;
591
		goto out;
551
	}
592
	}
552
	if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0,
593
	if (auth_secure_path(authorized_keys_command_path, &st, NULL, 0,
553
	    errmsg, sizeof(errmsg)) != 0) {
594
	    errmsg, sizeof(errmsg)) != 0) {
554
		error("Unsafe AuthorizedKeysCommand: %s", errmsg);
595
		error("Unsafe AuthorizedKeysCommand: %s", errmsg);
555
		goto out;
596
		goto out;
Lines 560-567 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
560
		goto out;
601
		goto out;
561
	}
602
	}
562
603
563
	debug3("Running AuthorizedKeysCommand: \"%s %s\" as \"%s\"",
604
	debug3("Running AuthorizedKeysCommand: \"%s ...\" as \"%s\"",
564
	    options.authorized_keys_command, user_pw->pw_name, pw->pw_name);
605
	    authorized_keys_command_path, pw->pw_name);
565
606
566
	/*
607
	/*
567
	 * Don't want to call this in the child, where it can fatal() and
608
	 * Don't want to call this in the child, where it can fatal() and
Lines 574-579 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
574
		error("%s: fork: %s", __func__, strerror(errno));
615
		error("%s: fork: %s", __func__, strerror(errno));
575
		close(p[0]);
616
		close(p[0]);
576
		close(p[1]);
617
		close(p[1]);
618
		free(argv);
619
		free(command);
620
		if (keytext != NULL)
621
			free(keytext);
622
		if (key_fp != NULL)
623
			free(key_fp);
577
		return 0;
624
		return 0;
578
	case 0: /* child */
625
	case 0: /* child */
579
		for (i = 0; i < NSIG; i++)
626
		for (i = 0; i < NSIG; i++)
Lines 609-619 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
609
			_exit(1);
656
			_exit(1);
610
		}
657
		}
611
658
612
		execl(options.authorized_keys_command,
659
		execv(authorized_keys_command_path, argv);
613
		    options.authorized_keys_command, user_pw->pw_name, NULL);
614
660
615
		error("AuthorizedKeysCommand %s exec failed: %s",
661
		error("AuthorizedKeysCommand %s exec failed: %s",
616
		    options.authorized_keys_command, strerror(errno));
662
		    authorized_keys_command_path, strerror(errno));
617
		_exit(127);
663
		_exit(127);
618
	default: /* parent */
664
	default: /* parent */
619
		break;
665
		break;
Lines 631-637 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
631
			;
677
			;
632
		goto out;
678
		goto out;
633
	}
679
	}
634
	ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
680
	ok = check_authkeys_file(f, authorized_keys_command_path, key, pw);
635
	fclose(f);
681
	fclose(f);
636
682
637
	while (waitpid(pid, &status, 0) == -1) {
683
	while (waitpid(pid, &status, 0) == -1) {
Lines 642-656 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
642
	}
688
	}
643
	if (WIFSIGNALED(status)) {
689
	if (WIFSIGNALED(status)) {
644
		error("AuthorizedKeysCommand %s exited on signal %d",
690
		error("AuthorizedKeysCommand %s exited on signal %d",
645
		    options.authorized_keys_command, WTERMSIG(status));
691
		    authorized_keys_command_path, WTERMSIG(status));
646
		goto out;
692
		goto out;
647
	} else if (WEXITSTATUS(status) != 0) {
693
	} else if (WEXITSTATUS(status) != 0) {
648
		error("AuthorizedKeysCommand %s returned status %d",
694
		error("AuthorizedKeysCommand %s returned status %d",
649
		    options.authorized_keys_command, WEXITSTATUS(status));
695
		    authorized_keys_command_path, WEXITSTATUS(status));
650
		goto out;
696
		goto out;
651
	}
697
	}
652
	found_key = ok;
698
	found_key = ok;
653
 out:
699
 out:
700
	if (argv != NULL)
701
		free(argv);
702
	if (command != NULL)
703
		free(command);
704
	if (keytext != NULL)
705
		free(keytext);
706
	if (key_fp != NULL)
707
		free(key_fp);
654
	restore_uid();
708
	restore_uid();
655
	return found_key;
709
	return found_key;
656
}
710
}
(-)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 / +8 lines)
Lines 232-238 of a single authentication method is sufficient. Link Here
232
Specifies a program to be used to look up the user's public keys.
232
Specifies a program to be used to look up the user's public keys.
233
The program must be owned by root and not writable by group or others.
233
The program must be owned by root and not writable by group or others.
234
It will be invoked with a single argument of the username
234
It will be invoked with a single argument of the username
235
being authenticated, and should produce on standard output zero or
235
being authenticated, unless any of the following tokens, which are
236
expanded at runtime, are provided: %% is replaced by a literal '%',
237
%u is replaced by the username being authenticated, %h is replaced
238
by the home directory of the user being authenticated, %t is replaced
239
with the key type offered for authentication, %f is replaced with the
240
fingerprint of the key, and %k is replaced with the key being offered
241
for authentication.
242
The program should produce on standard output zero or
236
more lines of authorized_keys output (see AUTHORIZED_KEYS in
243
more lines of authorized_keys output (see AUTHORIZED_KEYS in
237
.Xr sshd 8 ) .
244
.Xr sshd 8 ) .
238
If a key supplied by AuthorizedKeysCommand does not successfully authenticate
245
If a key supplied by AuthorizedKeysCommand does not successfully authenticate
(-)a/sshkey.c (+73 lines)
Lines 1463-1468 sshkey_write(const struct sshkey *key, FILE *f) Link Here
1463
	return ret;
1463
	return ret;
1464
}
1464
}
1465
1465
1466
int
1467
sshkey_to_base64(const struct sshkey *key, char **blobp, size_t *lenp)
1468
{
1469
	int ret = SSH_ERR_INTERNAL_ERROR;
1470
	struct sshbuf *b = NULL, *bb = NULL;
1471
	char *uu = NULL;
1472
	size_t len;
1473
1474
	if (lenp != NULL)
1475
		*lenp = 0;
1476
	if (blobp != NULL)
1477
		*blobp = NULL;
1478
1479
	if (sshkey_is_cert(key)) {
1480
		if (key->cert == NULL)
1481
			return SSH_ERR_EXPECTED_CERT;
1482
		if (sshbuf_len(key->cert->certblob) == 0)
1483
			return SSH_ERR_KEY_LACKS_CERTBLOB;
1484
	}
1485
	if ((b = sshbuf_new()) == NULL)
1486
		return SSH_ERR_ALLOC_FAIL;
1487
	switch (key->type) {
1488
#ifdef WITH_OPENSSL
1489
	case KEY_DSA:
1490
	case KEY_DSA_CERT_V00:
1491
	case KEY_DSA_CERT:
1492
	case KEY_ECDSA:
1493
	case KEY_ECDSA_CERT:
1494
	case KEY_RSA:
1495
	case KEY_RSA_CERT_V00:
1496
	case KEY_RSA_CERT:
1497
#endif /* WITH_OPENSSL */
1498
	case KEY_ED25519:
1499
	case KEY_ED25519_CERT:
1500
		if ((bb = sshbuf_new()) == NULL) {
1501
			ret = SSH_ERR_ALLOC_FAIL;
1502
			goto out;
1503
		}
1504
		if ((ret = sshkey_to_blob_buf(key, bb)) != 0)
1505
			goto out;
1506
		if ((uu = sshbuf_dtob64(bb)) == NULL) {
1507
			ret = SSH_ERR_ALLOC_FAIL;
1508
			goto out;
1509
		}
1510
		if ((ret = sshbuf_put(b, uu, strlen(uu))) != 0)
1511
			goto out;
1512
		break;
1513
	default:
1514
		ret = SSH_ERR_KEY_TYPE_UNKNOWN;
1515
		goto out;
1516
	}
1517
	len = sshbuf_len(b);
1518
	if (lenp != NULL)
1519
		*lenp = len;
1520
	if (blobp != NULL) {
1521
		if ((*blobp = malloc(len + 1)) == NULL) {
1522
			ret = SSH_ERR_ALLOC_FAIL;
1523
			goto out;
1524
		}
1525
		memset(*blobp, 0, len + 1);
1526
		memcpy(*blobp, sshbuf_ptr(b), len);
1527
	}
1528
	ret = 0;
1529
 out:
1530
	if (b != NULL)
1531
		sshbuf_free(b);
1532
	if (bb != NULL)
1533
		sshbuf_free(bb);
1534
	if (uu != NULL)
1535
		free(uu);
1536
	return ret;
1537
}
1538
1466
const char *
1539
const char *
1467
sshkey_cert_type(const struct sshkey *k)
1540
sshkey_cert_type(const struct sshkey *k)
1468
{
1541
{
(-)a/sshkey.h (-1 / +2 lines)
Lines 165-170 int sshkey_to_blob(const struct sshkey *, u_char **, size_t *); Link Here
165
int	 sshkey_plain_to_blob_buf(const struct sshkey *, struct sshbuf *);
165
int	 sshkey_plain_to_blob_buf(const struct sshkey *, struct sshbuf *);
166
int	 sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
166
int	 sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
167
167
168
int	 sshkey_to_base64(const struct sshkey *, char **, size_t *);
169
168
int	 sshkey_sign(const struct sshkey *, u_char **, size_t *,
170
int	 sshkey_sign(const struct sshkey *, u_char **, size_t *,
169
    const u_char *, size_t, u_int);
171
    const u_char *, size_t, u_int);
170
int	 sshkey_verify(const struct sshkey *, const u_char *, size_t,
172
int	 sshkey_verify(const struct sshkey *, const u_char *, size_t,
171
- 

Return to bug 2081