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

(-)a/regress/Makefile (-2 / +3 lines)
Lines 11-17 prep: Link Here
11
11
12
clean:
12
clean:
13
	for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done
13
	for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done
14
	test -z "${SUDO}" || ${SUDO} rm -f ${SUDO_CLEAN}
14
	test -z "${SUDO}" || ${SUDO} rm -df ${SUDO_CLEAN}
15
	rm -rf $(OBJ).putty
15
	rm -rf $(OBJ).putty
16
16
17
distclean:	clean
17
distclean:	clean
Lines 43-48 LTESTS= connect \ Link Here
43
		scp \
43
		scp \
44
		sftp \
44
		sftp \
45
		sftp-chroot \
45
		sftp-chroot \
46
		sftp-chdir \
46
		sftp-cmds \
47
		sftp-cmds \
47
		sftp-badcmds \
48
		sftp-badcmds \
48
		sftp-batch \
49
		sftp-batch \
Lines 107-113 CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ Link Here
107
		key.ed25519-512.pub netcat host_krl_* host_revoked_* \
108
		key.ed25519-512.pub netcat host_krl_* host_revoked_* \
108
		kh.* user_*key* agent-key.* known_hosts.* hkr.*
109
		kh.* user_*key* agent-key.* known_hosts.* hkr.*
109
110
110
SUDO_CLEAN+=	/var/run/testdata_${USER} /var/run/keycommand_${USER}
111
SUDO_CLEAN+=	/var/run/testdata_${USER} /var/run/testlanddir_${USER}{/testdata_${USER},} /var/run/keycommand_${USER}
111
112
112
# Enable all malloc(3) randomisations and checks
113
# Enable all malloc(3) randomisations and checks
113
TEST_ENV=      "MALLOC_OPTIONS=AFGJPRX"
114
TEST_ENV=      "MALLOC_OPTIONS=AFGJPRX"
(-)a/regress/sftp-chdir.sh (+30 lines)
Line 0 Link Here
1
#	$OpenBSD: sftp-chroot.sh,v 1.4 2014/01/20 00:00:30 dtucker Exp $
2
#	Placed in the Public Domain.
3
4
tid="sftp in chroot with chdir"
5
6
CHROOT=/var/run
7
CHDIR=testlanddir_${USER}
8
CHDIROUT=${CHROOT}/${CHDIR}
9
FILENAME=testdata_${USER}
10
PRIVDATA=${CHDIROUT}/${FILENAME}
11
12
if [ -z "$SUDO" ]; then
13
  echo "skipped: need SUDO to create file in /var/run, test won't work without"
14
  exit 0
15
fi
16
17
$SUDO sh -c "mkdir -p $CHDIROUT && echo mekmitastdigoat > $PRIVDATA" || \
18
	fatal "create $PRIVDATA failed"
19
20
start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp" -oChangeDirectory=$CHDIR
21
22
verbose "test $tid: get"
23
${SFTP} -S "$SSH" -F $OBJ/ssh_config host:${FILENAME} $COPY \
24
    >>$TEST_REGRESS_LOGFILE 2>&1 || \
25
	fatal "Fetch ${FILENAME} failed"
26
cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ"
27
28
$SUDO rm $PRIVDATA
29
$SUDO rmdir $CHDIROUT
30
(-)a/servconf.c (-1 / +14 lines)
Lines 167-172 initialize_server_options(ServerOptions *options) Link Here
167
	options->ip_qos_bulk = -1;
167
	options->ip_qos_bulk = -1;
168
	options->version_addendum = NULL;
168
	options->version_addendum = NULL;
169
	options->fingerprint_hash = -1;
169
	options->fingerprint_hash = -1;
170
	options->change_directory = NULL;
170
}
171
}
171
172
172
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
173
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
Lines 411-417 typedef enum { Link Here
411
	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
412
	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
412
	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
413
	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
413
	sStreamLocalBindMask, sStreamLocalBindUnlink,
414
	sStreamLocalBindMask, sStreamLocalBindUnlink,
414
	sAllowStreamLocalForwarding, sFingerprintHash,
415
	sAllowStreamLocalForwarding, sFingerprintHash, sChangeDirectory,
415
	sDeprecated, sUnsupported
416
	sDeprecated, sUnsupported
416
} ServerOpCodes;
417
} ServerOpCodes;
417
418
Lines 549-554 static struct { Link Here
549
	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
550
	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
550
	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
551
	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
551
	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
552
	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
553
	{ "changedirectory", sChangeDirectory, SSHCFG_ALL },
552
	{ NULL, sBadOption, 0 }
554
	{ NULL, sBadOption, 0 }
553
};
555
};
554
556
Lines 1826-1831 process_server_config_line(ServerOptions *options, char *line, Link Here
1826
			options->fingerprint_hash = value;
1828
			options->fingerprint_hash = value;
1827
		break;
1829
		break;
1828
1830
1831
	case sChangeDirectory:
1832
		arg = strdelim(&cp);
1833
		if (!arg || *arg == '\0')
1834
			fatal("%s line %d: missing directory name.",
1835
			    filename, linenum);
1836
		if (*activep && !options->change_directory)
1837
			options->change_directory = xstrdup(arg);
1838
		break;
1839
1829
	case sDeprecated:
1840
	case sDeprecated:
1830
		logit("%s line %d: Deprecated option %s",
1841
		logit("%s line %d: Deprecated option %s",
1831
		    filename, linenum, arg);
1842
		    filename, linenum, arg);
Lines 2007-2012 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) Link Here
2007
2018
2008
	M_CP_STROPT(adm_forced_command);
2019
	M_CP_STROPT(adm_forced_command);
2009
	M_CP_STROPT(chroot_directory);
2020
	M_CP_STROPT(chroot_directory);
2021
	M_CP_STROPT(change_directory);
2010
}
2022
}
2011
2023
2012
#undef M_CP_INTOPT
2024
#undef M_CP_INTOPT
Lines 2281-2286 dump_config(ServerOptions *o) Link Here
2281
	    o->hostbased_key_types : KEX_DEFAULT_PK_ALG);
2293
	    o->hostbased_key_types : KEX_DEFAULT_PK_ALG);
2282
	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
2294
	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
2283
	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2295
	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2296
	dump_cfg_string(sChangeDirectory, o->change_directory);
2284
2297
2285
	/* string arguments requiring a lookup */
2298
	/* string arguments requiring a lookup */
2286
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2299
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
(-)a/servconf.h (+2 lines)
Lines 194-199 typedef struct { Link Here
194
	char   *auth_methods[MAX_AUTH_METHODS];
194
	char   *auth_methods[MAX_AUTH_METHODS];
195
195
196
	int	fingerprint_hash;
196
	int	fingerprint_hash;
197
198
	char   *change_directory;
197
}       ServerOptions;
199
}       ServerOptions;
198
200
199
/* Information about the incoming connection as used by Match */
201
/* Information about the incoming connection as used by Match */
(-)a/session.c (-8 / +15 lines)
Lines 1670-1675 do_child(Session *s, const char *command) Link Here
1670
	char *argv[ARGV_MAX];
1670
	char *argv[ARGV_MAX];
1671
	const char *shell, *shell0, *hostname = NULL;
1671
	const char *shell, *shell0, *hostname = NULL;
1672
	struct passwd *pw = s->pw;
1672
	struct passwd *pw = s->pw;
1673
	char *landingdir;
1673
	int r = 0;
1674
	int r = 0;
1674
1675
1675
	/* remove hostkey from the child's memory */
1676
	/* remove hostkey from the child's memory */
Lines 1784-1803 do_child(Session *s, const char *command) Link Here
1784
	}
1785
	}
1785
#endif
1786
#endif
1786
1787
1787
	/* Change current directory to the user's home directory. */
1788
	/* Change current directory to landing directory (either home or
1788
	if (chdir(pw->pw_dir) < 0) {
1789
	 * set by config). */
1789
		/* Suppress missing homedir warning for chroot case */
1790
	if (!options.change_directory || !strcasecmp(options.change_directory, "none"))
1791
		landingdir = pw->pw_dir;
1792
	else
1793
		landingdir = percent_expand(options.change_directory,
1794
		    "h", pw->pw_dir, "u", pw->pw_name, (char*)NULL);
1795
	if (chdir(landingdir) < 0) {
1790
#ifdef HAVE_LOGIN_CAP
1796
#ifdef HAVE_LOGIN_CAP
1791
		r = login_getcapbool(lc, "requirehome", 0);
1797
		r = login_getcapbool(lc, "requirehome", 0);
1792
#endif
1798
#endif
1793
		if (r || options.chroot_directory == NULL ||
1799
		fprintf(stderr, "Could not chdir to landing "
1794
		    strcasecmp(options.chroot_directory, "none") == 0)
1800
		    "directory %s: %s\n", landingdir,
1795
			fprintf(stderr, "Could not chdir to home "
1801
		    strerror(errno));
1796
			    "directory %s: %s\n", pw->pw_dir,
1802
1797
			    strerror(errno));
1798
		if (r)
1803
		if (r)
1799
			exit(1);
1804
			exit(1);
1800
	}
1805
	}
1806
	if (options.change_directory && strcasecmp(options.change_directory, "none"))
1807
		free(landingdir);
1801
1808
1802
	closefrom(STDERR_FILENO + 1);
1809
	closefrom(STDERR_FILENO + 1);
1803
1810
(-)a/sshd_config (+1 lines)
Lines 118-123 UsePrivilegeSeparation sandbox # Default for new installations. Link Here
118
#PermitTunnel no
118
#PermitTunnel no
119
#ChrootDirectory none
119
#ChrootDirectory none
120
#VersionAddendum none
120
#VersionAddendum none
121
#ChangeDirectory none
121
122
122
# no default banner path
123
# no default banner path
123
#Banner none
124
#Banner none
(-)a/sshd_config.5 (-2 / +15 lines)
Lines 378-383 PAM or through authentication styles supported in Link Here
378
.Xr login.conf 5 )
378
.Xr login.conf 5 )
379
The default is
379
The default is
380
.Dq yes .
380
.Dq yes .
381
.It Cm ChangeDirectory
382
Specifies the pathname of a directory to
383
.Xr chdir 2
384
to after authentication, and after entering the chroot if
385
.Cm ChrootDirectory
386
were specified.
387
.Pp
388
The pathname may contain the following tokens that are expanded at runtime once
389
the connecting user has been authenticated: %% is replaced by a literal '%',
390
%h is replaced by the home directory of the user being authenticated, and
391
%u is replaced by the username of that user.
381
.It Cm ChrootDirectory
392
.It Cm ChrootDirectory
382
Specifies the pathname of a directory to
393
Specifies the pathname of a directory to
383
.Xr chroot 2
394
.Xr chroot 2
Lines 388-394 checks that all components of the pathname are root-owned directories Link Here
388
which are not writable by any other user or group.
399
which are not writable by any other user or group.
389
After the chroot,
400
After the chroot,
390
.Xr sshd 8
401
.Xr sshd 8
391
changes the working directory to the user's home directory.
402
changes the working directory to the user's home directory (by default), or
403
to directory specified with
404
.Cm ChangeDirectory .
392
.Pp
405
.Pp
393
The pathname may contain the following tokens that are expanded at runtime once
406
The pathname may contain the following tokens that are expanded at runtime once
394
the connecting user has been authenticated: %% is replaced by a literal '%',
407
the connecting user has been authenticated: %% is replaced by a literal '%',
Lines 1041-1046 Available keywords are Link Here
1041
.Cm AuthorizedKeysFile ,
1054
.Cm AuthorizedKeysFile ,
1042
.Cm AuthorizedPrincipalsFile ,
1055
.Cm AuthorizedPrincipalsFile ,
1043
.Cm Banner ,
1056
.Cm Banner ,
1057
.Cm ChangeDirectory ,
1044
.Cm ChrootDirectory ,
1058
.Cm ChrootDirectory ,
1045
.Cm DenyGroups ,
1059
.Cm DenyGroups ,
1046
.Cm DenyUsers ,
1060
.Cm DenyUsers ,
1047
- 

Return to bug 2452