forked from pool/openssh
74e20db9ed
- Enhanced SELinux functionality. Added Fedora patches: * openssh-7.8p1-role-mls.patch Proper handling of MLS systems and basis for other SELinux improvements * openssh-6.6p1-privsep-selinux.patch Properly set contexts during privilege separation * openssh-6.6p1-keycat.patch Add ssh-keycat command to allow retrival of authorized_keys on MLS setups with polyinstantiation * openssh-6.6.1p1-selinux-contexts.patch Additional changes to set the proper context during privilege separation * openssh-7.6p1-cleanup-selinux.patch Various changes and putting the pieces together For now we don't ship the ssh-keycat command, but we need the patch for the other SELinux infrastructure This change fixes issues like bsc#1214788, where the ssh daemon needs to act on behalf of a user and needs a proper context for this OBS-URL: https://build.opensuse.org/request/show/1123220 OBS-URL: https://build.opensuse.org/package/show/network/openssh?expand=0&rev=252
292 lines
9.6 KiB
Diff
292 lines
9.6 KiB
Diff
Index: openssh-9.3p2/auth2-pubkey.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/auth2-pubkey.c
|
|
+++ openssh-9.3p2/auth2-pubkey.c
|
|
@@ -72,6 +72,9 @@
|
|
|
|
/* import */
|
|
extern ServerOptions options;
|
|
+extern int inetd_flag;
|
|
+extern int rexeced_flag;
|
|
+extern Authctxt *the_authctxt;
|
|
|
|
static char *
|
|
format_key(const struct sshkey *key)
|
|
@@ -459,7 +462,8 @@ match_principals_command(struct passwd *
|
|
if ((pid = subprocess("AuthorizedPrincipalsCommand", command,
|
|
ac, av, &f,
|
|
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
|
|
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
|
|
+ runas_pw, temporarily_use_uid, restore_uid,
|
|
+ (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
|
|
goto out;
|
|
|
|
uid_swapped = 1;
|
|
@@ -727,7 +731,8 @@ user_key_command_allowed2(struct passwd
|
|
if ((pid = subprocess("AuthorizedKeysCommand", command,
|
|
ac, av, &f,
|
|
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
|
|
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
|
|
+ runas_pw, temporarily_use_uid, restore_uid,
|
|
+ (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
|
|
goto out;
|
|
|
|
uid_swapped = 1;
|
|
Index: openssh-9.3p2/misc.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/misc.c
|
|
+++ openssh-9.3p2/misc.c
|
|
@@ -2637,7 +2637,8 @@ stdfd_devnull(int do_stdin, int do_stdou
|
|
pid_t
|
|
subprocess(const char *tag, const char *command,
|
|
int ac, char **av, FILE **child, u_int flags,
|
|
- struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs)
|
|
+ struct passwd *pw, privdrop_fn *drop_privs,
|
|
+ privrestore_fn *restore_privs, int inetd, void *the_authctxt)
|
|
{
|
|
FILE *f = NULL;
|
|
struct stat st;
|
|
@@ -2771,7 +2772,7 @@ subprocess(const char *tag, const char *
|
|
_exit(1);
|
|
}
|
|
#ifdef WITH_SELINUX
|
|
- if (sshd_selinux_setup_env_variables() < 0) {
|
|
+ if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) {
|
|
error ("failed to copy environment: %s",
|
|
strerror(errno));
|
|
_exit(127);
|
|
Index: openssh-9.3p2/misc.h
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/misc.h
|
|
+++ openssh-9.3p2/misc.h
|
|
@@ -110,7 +110,7 @@ typedef void privrestore_fn(void);
|
|
#define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */
|
|
#define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */
|
|
pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int,
|
|
- struct passwd *, privdrop_fn *, privrestore_fn *);
|
|
+ struct passwd *, privdrop_fn *, privrestore_fn *, int, void *);
|
|
|
|
typedef struct arglist arglist;
|
|
struct arglist {
|
|
Index: openssh-9.3p2/openbsd-compat/port-linux.h
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/openbsd-compat/port-linux.h
|
|
+++ openssh-9.3p2/openbsd-compat/port-linux.h
|
|
@@ -25,8 +25,8 @@ void ssh_selinux_setfscreatecon(const ch
|
|
|
|
int sshd_selinux_enabled(void);
|
|
void sshd_selinux_copy_context(void);
|
|
-void sshd_selinux_setup_exec_context(char *);
|
|
-int sshd_selinux_setup_env_variables(void);
|
|
+void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int);
|
|
+int sshd_selinux_setup_env_variables(int inetd, void *);
|
|
void sshd_selinux_change_privsep_preauth_context(void);
|
|
#endif
|
|
|
|
Index: openssh-9.3p2/openbsd-compat/port-linux-sshd.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/openbsd-compat/port-linux-sshd.c
|
|
+++ openssh-9.3p2/openbsd-compat/port-linux-sshd.c
|
|
@@ -49,11 +49,6 @@
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
-extern ServerOptions options;
|
|
-extern Authctxt *the_authctxt;
|
|
-extern int inetd_flag;
|
|
-extern int rexeced_flag;
|
|
-
|
|
/* Wrapper around is_selinux_enabled() to log its return value once only */
|
|
int
|
|
sshd_selinux_enabled(void)
|
|
@@ -223,7 +218,8 @@ get_user_context(const char *sename, con
|
|
}
|
|
|
|
static void
|
|
-ssh_selinux_get_role_level(char **role, const char **level)
|
|
+ssh_selinux_get_role_level(char **role, const char **level,
|
|
+ Authctxt *the_authctxt)
|
|
{
|
|
*role = NULL;
|
|
*level = NULL;
|
|
@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role,
|
|
|
|
/* Return the default security context for the given username */
|
|
static int
|
|
-sshd_selinux_getctxbyname(char *pwname,
|
|
- security_context_t *default_sc, security_context_t *user_sc)
|
|
+sshd_selinux_getctxbyname(char *pwname, security_context_t *default_sc,
|
|
+ security_context_t *user_sc, int inetd, Authctxt *the_authctxt)
|
|
{
|
|
char *sename, *lvl;
|
|
char *role;
|
|
@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
|
int r = 0;
|
|
context_t con = NULL;
|
|
|
|
- ssh_selinux_get_role_level(&role, &reqlvl);
|
|
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
|
|
|
|
#ifdef HAVE_GETSEUSERBYNAME
|
|
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
|
|
@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
|
|
|
if (r == 0) {
|
|
/* If launched from xinetd, we must use current level */
|
|
- if (inetd_flag && !rexeced_flag) {
|
|
+ if (inetd) {
|
|
security_context_t sshdsc=NULL;
|
|
|
|
if (getcon_raw(&sshdsc) < 0)
|
|
@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
|
|
|
|
/* Setup environment variables for pam_selinux */
|
|
static int
|
|
-sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
|
|
+sshd_selinux_setup_variables(int(*set_it)(char *, const char *), int inetd,
|
|
+ Authctxt *the_authctxt)
|
|
{
|
|
const char *reqlvl;
|
|
char *role;
|
|
@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
|
|
|
|
debug3_f("setting execution context");
|
|
|
|
- ssh_selinux_get_role_level(&role, &reqlvl);
|
|
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
|
|
|
|
rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
|
|
|
|
- if (inetd_flag && !rexeced_flag) {
|
|
+ if (inetd) {
|
|
use_current = "1";
|
|
} else {
|
|
use_current = "";
|
|
@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it
|
|
}
|
|
|
|
static int
|
|
-sshd_selinux_setup_pam_variables(void)
|
|
+sshd_selinux_setup_pam_variables(int inetd,
|
|
+ int(pam_setenv)(char *, const char *), Authctxt *the_authctxt)
|
|
{
|
|
- return sshd_selinux_setup_variables(do_pam_putenv);
|
|
+ return sshd_selinux_setup_variables(pam_setenv, inetd, the_authctxt);
|
|
}
|
|
|
|
static int
|
|
@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value)
|
|
}
|
|
|
|
int
|
|
-sshd_selinux_setup_env_variables(void)
|
|
+sshd_selinux_setup_env_variables(int inetd, void *the_authctxt)
|
|
{
|
|
- return sshd_selinux_setup_variables(do_setenv);
|
|
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
|
|
+ return sshd_selinux_setup_variables(do_setenv, inetd, authctxt);
|
|
}
|
|
|
|
/* Set the execution context to the default for the specified user */
|
|
void
|
|
-sshd_selinux_setup_exec_context(char *pwname)
|
|
+sshd_selinux_setup_exec_context(char *pwname, int inetd,
|
|
+ int(pam_setenv)(char *, const char *), void *the_authctxt, int use_pam)
|
|
{
|
|
security_context_t user_ctx = NULL;
|
|
int r = 0;
|
|
security_context_t default_ctx = NULL;
|
|
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
|
|
|
|
if (!sshd_selinux_enabled())
|
|
return;
|
|
|
|
- if (options.use_pam) {
|
|
+ if (use_pam) {
|
|
/* do not compute context, just setup environment for pam_selinux */
|
|
- if (sshd_selinux_setup_pam_variables()) {
|
|
+ if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) {
|
|
switch (security_getenforce()) {
|
|
case -1:
|
|
fatal_f("security_getenforce() failed");
|
|
@@ -408,7 +409,7 @@ sshd_selinux_setup_exec_context(char *pw
|
|
|
|
debug3_f("setting execution context");
|
|
|
|
- r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
|
|
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt);
|
|
if (r >= 0) {
|
|
r = setexeccon(user_ctx);
|
|
if (r < 0) {
|
|
Index: openssh-9.3p2/platform.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/platform.c
|
|
+++ openssh-9.3p2/platform.c
|
|
@@ -34,6 +34,9 @@
|
|
|
|
extern int use_privsep;
|
|
extern ServerOptions options;
|
|
+extern int inetd_flag;
|
|
+extern int rexeced_flag;
|
|
+extern Authctxt *the_authctxt;
|
|
|
|
void
|
|
platform_pre_listen(void)
|
|
@@ -185,7 +188,9 @@ platform_setusercontext_post_groups(stru
|
|
}
|
|
#endif /* HAVE_SETPCRED */
|
|
#ifdef WITH_SELINUX
|
|
- sshd_selinux_setup_exec_context(pw->pw_name);
|
|
+ sshd_selinux_setup_exec_context(pw->pw_name,
|
|
+ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt,
|
|
+ options.use_pam);
|
|
#endif
|
|
}
|
|
|
|
Index: openssh-9.3p2/sshd.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/sshd.c
|
|
+++ openssh-9.3p2/sshd.c
|
|
@@ -166,7 +166,7 @@ int debug_flag = 0;
|
|
static int test_flag = 0;
|
|
|
|
/* Flag indicating that the daemon is being started from inetd. */
|
|
-static int inetd_flag = 0;
|
|
+int inetd_flag = 0;
|
|
|
|
/* Flag indicating that sshd should not detach and become a daemon. */
|
|
static int no_daemon_flag = 0;
|
|
@@ -179,7 +179,7 @@ static char **saved_argv;
|
|
static int saved_argc;
|
|
|
|
/* re-exec */
|
|
-static int rexeced_flag = 0;
|
|
+int rexeced_flag = 0;
|
|
static int rexec_flag = 1;
|
|
static int rexec_argc = 0;
|
|
static char **rexec_argv;
|
|
@@ -2396,7 +2396,9 @@ main(int ac, char **av)
|
|
}
|
|
#endif
|
|
#ifdef WITH_SELINUX
|
|
- sshd_selinux_setup_exec_context(authctxt->pw->pw_name);
|
|
+ sshd_selinux_setup_exec_context(authctxt->pw->pw_name,
|
|
+ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt,
|
|
+ options.use_pam);
|
|
#endif
|
|
#ifdef USE_PAM
|
|
if (options.use_pam) {
|
|
Index: openssh-9.3p2/sshconnect.c
|
|
===================================================================
|
|
--- openssh-9.3p2.orig/sshconnect.c
|
|
+++ openssh-9.3p2/sshconnect.c
|
|
@@ -893,7 +893,7 @@ load_hostkeys_command(struct hostkeys *h
|
|
|
|
if ((pid = subprocess(tag, command, ac, av, &f,
|
|
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH|
|
|
- SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL)) == 0)
|
|
+ SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL, 0, NULL)) == 0)
|
|
goto out;
|
|
|
|
load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1);
|