View | Details | Raw Unified | Return to bug 3131
Collapse All | Expand All

(-)a/.gitignore (+1 lines)
Lines 17-22 survey.sh Link Here
17
**/*.out
17
**/*.out
18
**/*.a
18
**/*.a
19
autom4te.cache/
19
autom4te.cache/
20
.idea/
20
scp
21
scp
21
sftp
22
sftp
22
sftp-server
23
sftp-server
(-)a/auth-options.c (+54 lines)
Lines 135-140 cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob, Link Here
135
				opts->force_command = command;
135
				opts->force_command = command;
136
				found = 1;
136
				found = 1;
137
			}
137
			}
138
			if (strcmp(name, "chroot-directory") == 0) {
139
				if ((r = sshbuf_get_cstring(data, &command,
140
				    NULL)) != 0) {
141
					error("Unable to parse \"%s\" "
142
					    "section: %s", name, ssh_err(r));
143
					goto out;
144
				}
145
				if (opts->chroot_directory != NULL) {
146
					error("Certificate has multiple "
147
					    "chroot-directory options");
148
					free(command);
149
					goto out;
150
				}
151
				opts->chroot_directory = command;
152
				found = 1;
153
			}
138
			if (strcmp(name, "source-address") == 0) {
154
			if (strcmp(name, "source-address") == 0) {
139
				if ((r = sshbuf_get_cstring(data, &allowed,
155
				if ((r = sshbuf_get_cstring(data, &allowed,
140
				    NULL)) != 0) {
156
				    NULL)) != 0) {
Lines 207-212 sshauthopt_free(struct sshauthopt *opts) Link Here
207
223
208
	free(opts->cert_principals);
224
	free(opts->cert_principals);
209
	free(opts->force_command);
225
	free(opts->force_command);
226
	free(opts->chroot_directory);
210
	free(opts->required_from_host_cert);
227
	free(opts->required_from_host_cert);
211
	free(opts->required_from_host_keys);
228
	free(opts->required_from_host_keys);
212
229
Lines 364-369 sshauthopt_parse(const char *opts, const char **errstrp) Link Here
364
			ret->force_command = opt_dequote(&opts, &errstr);
381
			ret->force_command = opt_dequote(&opts, &errstr);
365
			if (ret->force_command == NULL)
382
			if (ret->force_command == NULL)
366
				goto fail;
383
				goto fail;
384
		} else if (opt_match(&opts, "chroot-directory")) {
385
			if (ret->chroot_directory != NULL) {
386
				errstr = "multiple \"chroot-directory\" clauses";
387
				goto fail;
388
			}
389
			ret->chroot_directory = opt_dequote(&opts, &errstr);
390
			if (ret->chroot_directory == NULL)
391
				goto fail;
367
		} else if (opt_match(&opts, "principals")) {
392
		} else if (opt_match(&opts, "principals")) {
368
			if (ret->cert_principals != NULL) {
393
			if (ret->cert_principals != NULL) {
369
				errstr = "multiple \"principals\" clauses";
394
				errstr = "multiple \"principals\" clauses";
Lines 614-619 sshauthopt_merge(const struct sshauthopt *primary, Link Here
614
		    additional->force_command)) == NULL)
639
		    additional->force_command)) == NULL)
615
			goto alloc_fail;
640
			goto alloc_fail;
616
	}
641
	}
642
643
	/*
644
	 * When both multiple chroot-directory are specified, only
645
	 * proceed if they are identical, otherwise fail.
646
	 */
647
	if (primary->chroot_directory != NULL &&
648
	    additional->chroot_directory != NULL) {
649
		if (strcmp(primary->chroot_directory,
650
		    additional->chroot_directory) == 0) {
651
			/* ok */
652
			ret->chroot_directory = strdup(primary->chroot_directory);
653
			if (ret->chroot_directory == NULL)
654
				goto alloc_fail;
655
		} else {
656
			errstr = "chroot directory options do not match";
657
			goto fail;
658
		}
659
	} else if (primary->chroot_directory != NULL) {
660
		if ((ret->chroot_directory = strdup(
661
		    primary->chroot_directory)) == NULL)
662
			goto alloc_fail;
663
	} else if (additional->chroot_directory != NULL) {
664
		if ((ret->chroot_directory = strdup(
665
		    additional->chroot_directory)) == NULL)
666
			goto alloc_fail;
667
	}
617
	/* success */
668
	/* success */
618
	if (errstrp != NULL)
669
	if (errstrp != NULL)
619
		*errstrp = NULL;
670
		*errstrp = NULL;
Lines 660-665 sshauthopt_copy(const struct sshauthopt *orig) Link Here
660
	} while (0)
711
	} while (0)
661
	OPTSTRING(cert_principals);
712
	OPTSTRING(cert_principals);
662
	OPTSTRING(force_command);
713
	OPTSTRING(force_command);
714
	OPTSTRING(chroot_directory);
663
	OPTSTRING(required_from_host_cert);
715
	OPTSTRING(required_from_host_cert);
664
	OPTSTRING(required_from_host_keys);
716
	OPTSTRING(required_from_host_keys);
665
#undef OPTSTRING
717
#undef OPTSTRING
Lines 799-804 sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m, Link Here
799
	    (r = serialise_nullable_string(m,
851
	    (r = serialise_nullable_string(m,
800
	    untrusted ? "true" : opts->force_command)) != 0 ||
852
	    untrusted ? "true" : opts->force_command)) != 0 ||
801
	    (r = serialise_nullable_string(m,
853
	    (r = serialise_nullable_string(m,
854
	    untrusted ? "true" : opts->chroot_directory)) != 0 ||
855
	    (r = serialise_nullable_string(m,
802
	    untrusted ? NULL : opts->required_from_host_cert)) != 0 ||
856
	    untrusted ? NULL : opts->required_from_host_cert)) != 0 ||
803
	    (r = serialise_nullable_string(m,
857
	    (r = serialise_nullable_string(m,
804
	     untrusted ? NULL : opts->required_from_host_keys)) != 0)
858
	     untrusted ? NULL : opts->required_from_host_keys)) != 0)
(-)a/auth-options.h (+1 lines)
Lines 49-54 struct sshauthopt { Link Here
49
49
50
	int force_tun_device;
50
	int force_tun_device;
51
	char *force_command;
51
	char *force_command;
52
	char *chroot_directory;
52
53
53
	/* Custom environment */
54
	/* Custom environment */
54
	size_t nenv;
55
	size_t nenv;
(-)a/auth.c (-1 / +2 lines)
Lines 1006-1014 auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote) Link Here
1006
1006
1007
	snprintf(buf, sizeof(buf), "%d", opts->force_tun_device);
1007
	snprintf(buf, sizeof(buf), "%d", opts->force_tun_device);
1008
	/* Try to keep this alphabetically sorted */
1008
	/* Try to keep this alphabetically sorted */
1009
	snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1009
	snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1010
	    opts->permit_agent_forwarding_flag ? " agent-forwarding" : "",
1010
	    opts->permit_agent_forwarding_flag ? " agent-forwarding" : "",
1011
	    opts->force_command == NULL ? "" : " command",
1011
	    opts->force_command == NULL ? "" : " command",
1012
	    opts->chroot_directory == NULL ? "" : " chroot-directory",
1012
	    do_env ?  " environment" : "",
1013
	    do_env ?  " environment" : "",
1013
	    opts->valid_before == 0 ? "" : "expires",
1014
	    opts->valid_before == 0 ? "" : "expires",
1014
	    do_permitopen ?  " permitopen" : "",
1015
	    do_permitopen ?  " permitopen" : "",
(-)a/auth2-pubkey.c (+14 lines)
Lines 611-616 check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, Link Here
611
		auth_debug_add("%s: bad key options: %s", loc, reason);
611
		auth_debug_add("%s: bad key options: %s", loc, reason);
612
		goto out;
612
		goto out;
613
	}
613
	}
614
	/* Allowing users to have a shell which is chrooted may allow them to escape
615
	 * with SUID binaries
616
	 */
617
	if (keyopts->chroot_directory &&
618
		!(keyopts->restricted
619
		    && keyopts->force_command
620
		    && strcmp(keyopts->force_command, INTERNAL_SFTP_NAME) == 0)) {
621
		debug("%s: cannot use 'chroot-directory' without 'restrict' and "
622
		    "'command=\"" INTERNAL_SFTP_NAME "\"'", loc);
623
		auth_debug_add("%s: cannot use 'chroot-directory' without "
624
		    "'restrict' and 'command=\"" INTERNAL_SFTP_NAME "\"'", loc);
625
		goto out;
626
	}
627
614
	/* Ignore keys that don't match or incorrectly marked as CAs */
628
	/* Ignore keys that don't match or incorrectly marked as CAs */
615
	if (sshkey_is_cert(key)) {
629
	if (sshkey_is_cert(key)) {
616
		/* Certificate; check signature key against CA */
630
		/* Certificate; check signature key against CA */
(-)a/session.c (-4 / +12 lines)
Lines 1362-1368 safely_chroot(const char *path, uid_t uid) Link Here
1362
void
1362
void
1363
do_setusercontext(struct passwd *pw)
1363
do_setusercontext(struct passwd *pw)
1364
{
1364
{
1365
	char uidstr[32], *chroot_path, *tmp;
1365
	char uidstr[32], *chroot_path, *tmp, *chroot_directory = NULL;
1366
1366
1367
	platform_setusercontext(pw);
1367
	platform_setusercontext(pw);
1368
1368
Lines 1390-1398 do_setusercontext(struct passwd *pw) Link Here
1390
1390
1391
		platform_setusercontext_post_groups(pw);
1391
		platform_setusercontext_post_groups(pw);
1392
1392
1393
		if (!in_chroot && options.chroot_directory != NULL &&
1393
		if (options.chroot_directory) {
1394
		    strcasecmp(options.chroot_directory, "none") != 0) {
1394
			chroot_directory = options.chroot_directory;
1395
                        tmp = tilde_expand_filename(options.chroot_directory,
1395
		} else if (auth_opts->chroot_directory != NULL) {
1396
			chroot_directory = auth_opts->chroot_directory;
1397
		}
1398
1399
		if (!in_chroot && chroot_directory != NULL &&
1400
		    strcasecmp(chroot_directory, "none") != 0) {
1401
                        tmp = tilde_expand_filename(chroot_directory,
1396
			    pw->pw_uid);
1402
			    pw->pw_uid);
1397
			snprintf(uidstr, sizeof(uidstr), "%llu",
1403
			snprintf(uidstr, sizeof(uidstr), "%llu",
1398
			    (unsigned long long)pw->pw_uid);
1404
			    (unsigned long long)pw->pw_uid);
Lines 1404-1409 do_setusercontext(struct passwd *pw) Link Here
1404
			/* Make sure we don't attempt to chroot again */
1410
			/* Make sure we don't attempt to chroot again */
1405
			free(options.chroot_directory);
1411
			free(options.chroot_directory);
1406
			options.chroot_directory = NULL;
1412
			options.chroot_directory = NULL;
1413
			free(auth_opts->chroot_directory);
1414
			auth_opts->chroot_directory = NULL;
1407
			in_chroot = 1;
1415
			in_chroot = 1;
1408
		}
1416
		}
1409
1417

Return to bug 3131