Bugzilla – Attachment 3361 Details for
Bug 3131
[PATCH] Adding a chroot-directory option per key in authorized_keys file
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch file to add a per-key chroot-directory option
0001-chroot-directory-per-key-in-authorized-keys.patch (text/plain), 6.95 KB, created by
David Shlemayev
on 2020-03-06 22:13:47 AEDT
(
hide
)
Description:
Patch file to add a per-key chroot-directory option
Filename:
MIME Type:
Creator:
David Shlemayev
Created:
2020-03-06 22:13:47 AEDT
Size:
6.95 KB
patch
obsolete
>diff --git a/.gitignore b/.gitignore >index 34a95721..6f227a7f 100644 >--- a/.gitignore >+++ b/.gitignore >@@ -17,6 +17,7 @@ survey.sh > **/*.out > **/*.a > autom4te.cache/ >+.idea/ > scp > sftp > sftp-server >diff --git a/auth-options.c b/auth-options.c >index 2d200944..7a9515a4 100644 >--- a/auth-options.c >+++ b/auth-options.c >@@ -135,6 +135,22 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob, > opts->force_command = command; > found = 1; > } >+ if (strcmp(name, "chroot-directory") == 0) { >+ if ((r = sshbuf_get_cstring(data, &command, >+ NULL)) != 0) { >+ error("Unable to parse \"%s\" " >+ "section: %s", name, ssh_err(r)); >+ goto out; >+ } >+ if (opts->chroot_directory != NULL) { >+ error("Certificate has multiple " >+ "chroot-directory options"); >+ free(command); >+ goto out; >+ } >+ opts->chroot_directory = command; >+ found = 1; >+ } > if (strcmp(name, "source-address") == 0) { > if ((r = sshbuf_get_cstring(data, &allowed, > NULL)) != 0) { >@@ -207,6 +223,7 @@ sshauthopt_free(struct sshauthopt *opts) > > free(opts->cert_principals); > free(opts->force_command); >+ free(opts->chroot_directory); > free(opts->required_from_host_cert); > free(opts->required_from_host_keys); > >@@ -364,6 +381,14 @@ sshauthopt_parse(const char *opts, const char **errstrp) > ret->force_command = opt_dequote(&opts, &errstr); > if (ret->force_command == NULL) > goto fail; >+ } else if (opt_match(&opts, "chroot-directory")) { >+ if (ret->chroot_directory != NULL) { >+ errstr = "multiple \"chroot-directory\" clauses"; >+ goto fail; >+ } >+ ret->chroot_directory = opt_dequote(&opts, &errstr); >+ if (ret->chroot_directory == NULL) >+ goto fail; > } else if (opt_match(&opts, "principals")) { > if (ret->cert_principals != NULL) { > errstr = "multiple \"principals\" clauses"; >@@ -614,6 +639,32 @@ sshauthopt_merge(const struct sshauthopt *primary, > additional->force_command)) == NULL) > goto alloc_fail; > } >+ >+ /* >+ * When both multiple chroot-directory are specified, only >+ * proceed if they are identical, otherwise fail. >+ */ >+ if (primary->chroot_directory != NULL && >+ additional->chroot_directory != NULL) { >+ if (strcmp(primary->chroot_directory, >+ additional->chroot_directory) == 0) { >+ /* ok */ >+ ret->chroot_directory = strdup(primary->chroot_directory); >+ if (ret->chroot_directory == NULL) >+ goto alloc_fail; >+ } else { >+ errstr = "chroot directory options do not match"; >+ goto fail; >+ } >+ } else if (primary->chroot_directory != NULL) { >+ if ((ret->chroot_directory = strdup( >+ primary->chroot_directory)) == NULL) >+ goto alloc_fail; >+ } else if (additional->chroot_directory != NULL) { >+ if ((ret->chroot_directory = strdup( >+ additional->chroot_directory)) == NULL) >+ goto alloc_fail; >+ } > /* success */ > if (errstrp != NULL) > *errstrp = NULL; >@@ -660,6 +711,7 @@ sshauthopt_copy(const struct sshauthopt *orig) > } while (0) > OPTSTRING(cert_principals); > OPTSTRING(force_command); >+ OPTSTRING(chroot_directory); > OPTSTRING(required_from_host_cert); > OPTSTRING(required_from_host_keys); > #undef OPTSTRING >@@ -799,6 +851,8 @@ sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m, > (r = serialise_nullable_string(m, > untrusted ? "true" : opts->force_command)) != 0 || > (r = serialise_nullable_string(m, >+ untrusted ? "true" : opts->chroot_directory)) != 0 || >+ (r = serialise_nullable_string(m, > untrusted ? NULL : opts->required_from_host_cert)) != 0 || > (r = serialise_nullable_string(m, > untrusted ? NULL : opts->required_from_host_keys)) != 0) >diff --git a/auth-options.h b/auth-options.h >index d96ffede..12d4bdd6 100644 >--- a/auth-options.h >+++ b/auth-options.h >@@ -49,6 +49,7 @@ struct sshauthopt { > > int force_tun_device; > char *force_command; >+ char *chroot_directory; > > /* Custom environment */ > size_t nenv; >diff --git a/auth.c b/auth.c >index 086b8ebb..b5e09edc 100644 >--- a/auth.c >+++ b/auth.c >@@ -1006,9 +1006,10 @@ auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote) > > snprintf(buf, sizeof(buf), "%d", opts->force_tun_device); > /* Try to keep this alphabetically sorted */ >- snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s", >+ snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", > opts->permit_agent_forwarding_flag ? " agent-forwarding" : "", > opts->force_command == NULL ? "" : " command", >+ opts->chroot_directory == NULL ? "" : " chroot-directory", > do_env ? " environment" : "", > opts->valid_before == 0 ? "" : "expires", > do_permitopen ? " permitopen" : "", >diff --git a/auth2-pubkey.c b/auth2-pubkey.c >index 815ea0f2..25577f8f 100644 >--- a/auth2-pubkey.c >+++ b/auth2-pubkey.c >@@ -611,6 +611,20 @@ check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, > auth_debug_add("%s: bad key options: %s", loc, reason); > goto out; > } >+ /* Allowing users to have a shell which is chrooted may allow them to escape >+ * with SUID binaries >+ */ >+ if (keyopts->chroot_directory && >+ !(keyopts->restricted >+ && keyopts->force_command >+ && strcmp(keyopts->force_command, INTERNAL_SFTP_NAME) == 0)) { >+ debug("%s: cannot use 'chroot-directory' without 'restrict' and " >+ "'command=\"" INTERNAL_SFTP_NAME "\"'", loc); >+ auth_debug_add("%s: cannot use 'chroot-directory' without " >+ "'restrict' and 'command=\"" INTERNAL_SFTP_NAME "\"'", loc); >+ goto out; >+ } >+ > /* Ignore keys that don't match or incorrectly marked as CAs */ > if (sshkey_is_cert(key)) { > /* Certificate; check signature key against CA */ >diff --git a/session.c b/session.c >index 8c0e54f7..4ad7eb18 100644 >--- a/session.c >+++ b/session.c >@@ -1362,7 +1362,7 @@ safely_chroot(const char *path, uid_t uid) > void > do_setusercontext(struct passwd *pw) > { >- char uidstr[32], *chroot_path, *tmp; >+ char uidstr[32], *chroot_path, *tmp, *chroot_directory = NULL; > > platform_setusercontext(pw); > >@@ -1390,9 +1390,15 @@ do_setusercontext(struct passwd *pw) > > platform_setusercontext_post_groups(pw); > >- if (!in_chroot && options.chroot_directory != NULL && >- strcasecmp(options.chroot_directory, "none") != 0) { >- tmp = tilde_expand_filename(options.chroot_directory, >+ if (options.chroot_directory) { >+ chroot_directory = options.chroot_directory; >+ } else if (auth_opts->chroot_directory != NULL) { >+ chroot_directory = auth_opts->chroot_directory; >+ } >+ >+ if (!in_chroot && chroot_directory != NULL && >+ strcasecmp(chroot_directory, "none") != 0) { >+ tmp = tilde_expand_filename(chroot_directory, > pw->pw_uid); > snprintf(uidstr, sizeof(uidstr), "%llu", > (unsigned long long)pw->pw_uid); >@@ -1404,6 +1410,8 @@ do_setusercontext(struct passwd *pw) > /* Make sure we don't attempt to chroot again */ > free(options.chroot_directory); > options.chroot_directory = NULL; >+ free(auth_opts->chroot_directory); >+ auth_opts->chroot_directory = NULL; > in_chroot = 1; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 3131
: 3361