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

Collapse All | Expand All

(-)a/auth2-pubkey.c (-12 / +65 lines)
Lines 507-515 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
507
	int ok, found_key = 0;
507
	int ok, found_key = 0;
508
	struct passwd *pw;
508
	struct passwd *pw;
509
	struct stat st;
509
	struct stat st;
510
	int status, devnull, p[2], i;
510
	int status, devnull, p[2], i, argc;
511
	pid_t pid;
511
	pid_t pid;
512
	char *username, errmsg[512];
512
	char *username, errmsg[512];
513
	char *cp, *command = NULL, **argv = NULL;
514
	char *authorized_keys_command_path;
515
	char *key_fp = NULL, *keytext = NULL;
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
			goto out;
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
			goto out;
551
		}
552
	}
553
	command = cp = percent_expand(options.authorized_keys_command,
554
	    "u", user_pw->pw_name, "h", user_pw->pw_dir, "t", key_ssh_name(key),
555
	    "f", key_fp == NULL ? "" : key_fp,
556
	    "k", keytext == NULL ? "" : keytext, (char *)NULL);
557
	i = 0;
558
	argc = 10;
559
	while (cp != NULL) {
560
		if (argv == NULL || i == argc - 1) {
561
			argc *= 2;
562
			argv = xrealloc(argv, argc, sizeof(char *));
563
		}
564
		argv[i++] = strdelim(&cp);
565
		argv[i] = NULL;
566
		debug3("AuthorizedKeysCommand argv[%d]: %s",
567
		    i - 1, argv[i - 1]);
568
	}
569
	if (argv[1] == NULL) {
570
		argv[1] = user_pw->pw_name;
571
		argv[2] = NULL;
572
		debug3("AuthorizedKeysCommand argv[1]: %s", argv[1]);
573
	}
574
	authorized_keys_command_path = argv[0];
575
576
	if (stat(authorized_keys_command_path, &st) < 0) {
537
		error("Could not stat AuthorizedKeysCommand \"%s\": %s",
577
		error("Could not stat AuthorizedKeysCommand \"%s\": %s",
538
		    options.authorized_keys_command, strerror(errno));
578
		    authorized_keys_command_path, strerror(errno));
539
		goto out;
579
		goto out;
540
	}
580
	}
541
	if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0,
581
	if (auth_secure_path(authorized_keys_command_path, &st, NULL, 0,
542
	    errmsg, sizeof(errmsg)) != 0) {
582
	    errmsg, sizeof(errmsg)) != 0) {
543
		error("Unsafe AuthorizedKeysCommand: %s", errmsg);
583
		error("Unsafe AuthorizedKeysCommand: %s", errmsg);
544
		goto out;
584
		goto out;
Lines 549-556 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
549
		goto out;
589
		goto out;
550
	}
590
	}
551
591
552
	debug3("Running AuthorizedKeysCommand: \"%s %s\" as \"%s\"",
592
	debug3("Running AuthorizedKeysCommand: \"%s ...\" as \"%s\"",
553
	    options.authorized_keys_command, user_pw->pw_name, pw->pw_name);
593
	    authorized_keys_command_path, pw->pw_name);
554
594
555
	/*
595
	/*
556
	 * Don't want to call this in the child, where it can fatal() and
596
	 * 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));
603
		error("%s: fork: %s", __func__, strerror(errno));
564
		close(p[0]);
604
		close(p[0]);
565
		close(p[1]);
605
		close(p[1]);
606
		free(argv);
607
		free(command);
608
		if (keytext != NULL)
609
			free(keytext);
610
		if (key_fp != NULL)
611
			free(key_fp);
566
		return 0;
612
		return 0;
567
	case 0: /* child */
613
	case 0: /* child */
568
		for (i = 0; i < NSIG; i++)
614
		for (i = 0; i < NSIG; i++)
Lines 598-608 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
598
			_exit(1);
644
			_exit(1);
599
		}
645
		}
600
646
601
		execl(options.authorized_keys_command,
647
		execv(authorized_keys_command_path, argv);
602
		    options.authorized_keys_command, user_pw->pw_name, NULL);
603
648
604
		error("AuthorizedKeysCommand %s exec failed: %s",
649
		error("AuthorizedKeysCommand %s exec failed: %s",
605
		    options.authorized_keys_command, strerror(errno));
650
		    authorized_keys_command_path, strerror(errno));
606
		_exit(127);
651
		_exit(127);
607
	default: /* parent */
652
	default: /* parent */
608
		break;
653
		break;
Lines 620-626 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
620
			;
665
			;
621
		goto out;
666
		goto out;
622
	}
667
	}
623
	ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
668
	ok = check_authkeys_file(f, authorized_keys_command_path, key, pw);
624
	fclose(f);
669
	fclose(f);
625
670
626
	while (waitpid(pid, &status, 0) == -1) {
671
	while (waitpid(pid, &status, 0) == -1) {
Lines 631-645 user_key_command_allowed2(struct passwd *user_pw, Key *key) Link Here
631
	}
676
	}
632
	if (WIFSIGNALED(status)) {
677
	if (WIFSIGNALED(status)) {
633
		error("AuthorizedKeysCommand %s exited on signal %d",
678
		error("AuthorizedKeysCommand %s exited on signal %d",
634
		    options.authorized_keys_command, WTERMSIG(status));
679
		    authorized_keys_command_path, WTERMSIG(status));
635
		goto out;
680
		goto out;
636
	} else if (WEXITSTATUS(status) != 0) {
681
	} else if (WEXITSTATUS(status) != 0) {
637
		error("AuthorizedKeysCommand %s returned status %d",
682
		error("AuthorizedKeysCommand %s returned status %d",
638
		    options.authorized_keys_command, WEXITSTATUS(status));
683
		    authorized_keys_command_path, WEXITSTATUS(status));
639
		goto out;
684
		goto out;
640
	}
685
	}
641
	found_key = ok;
686
	found_key = ok;
642
 out:
687
 out:
688
	if (argv != NULL)
689
		free(argv);
690
	if (command != NULL)
691
		free(command);
692
	if (keytext != NULL)
693
		free(keytext);
694
	if (key_fp != NULL)
695
		free(key_fp);
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 / +8 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: %% is replaced by a literal '%',
225
%u is replaced by the username being authenticated, %h is replaced
226
by the home directory of the user being authenticated, %t is replaced
227
with the key type offered for authentication, %f is replaced with the
228
fingerprint of the key, and %k is replaced with the key being offered
229
for authentication.
230
The program should produce on standard output zero or
224
more lines of authorized_keys output (see AUTHORIZED_KEYS in
231
more lines of authorized_keys output (see AUTHORIZED_KEYS in
225
.Xr sshd 8 ) .
232
.Xr sshd 8 ) .
226
If a key supplied by AuthorizedKeysCommand does not successfully authenticate
233
If a key supplied by AuthorizedKeysCommand does not successfully authenticate
(-)a/sshkey.c (+73 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 + 1)) == NULL) {
1486
			ret = SSH_ERR_ALLOC_FAIL;
1487
			goto out;
1488
		}
1489
		memset(*blobp, 0, len + 1);
1490
		memcpy(*blobp, sshbuf_ptr(b), len);
1491
	}
1492
	ret = 0;
1493
 out:
1494
	if (b != NULL)
1495
		sshbuf_free(b);
1496
	if (bb != NULL)
1497
		sshbuf_free(bb);
1498
	if (uu != NULL)
1499
		free(uu);
1500
	return ret;
1501
}
1502
1430
const char *
1503
const char *
1431
sshkey_cert_type(const struct sshkey *k)
1504
sshkey_cert_type(const struct sshkey *k)
1432
{
1505
{
(-)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