Accepting request 1123220 from home:jsegitz:branches:network
- 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
This commit is contained in:
parent
ac7d1e8af4
commit
74e20db9ed
132
openssh-6.6.1p1-selinux-contexts.patch
Normal file
132
openssh-6.6.1p1-selinux-contexts.patch
Normal file
@ -0,0 +1,132 @@
|
||||
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
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */
|
||||
#include "servconf.h"
|
||||
#include "port-linux.h"
|
||||
+#include "misc.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
@@ -451,7 +452,7 @@ sshd_selinux_setup_exec_context(char *pw
|
||||
void
|
||||
sshd_selinux_copy_context(void)
|
||||
{
|
||||
- security_context_t *ctx;
|
||||
+ char *ctx;
|
||||
|
||||
if (!sshd_selinux_enabled())
|
||||
return;
|
||||
@@ -470,6 +471,72 @@ sshd_selinux_copy_context(void)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+sshd_selinux_change_privsep_preauth_context(void)
|
||||
+{
|
||||
+ int len;
|
||||
+ char line[1024], *preauth_context = NULL, *cp, *arg;
|
||||
+ const char *contexts_path;
|
||||
+ FILE *contexts_file;
|
||||
+ struct stat sb;
|
||||
+
|
||||
+ contexts_path = selinux_openssh_contexts_path();
|
||||
+ if (contexts_path == NULL) {
|
||||
+ debug3_f("Failed to get the path to SELinux context");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if ((contexts_file = fopen(contexts_path, "r")) == NULL) {
|
||||
+ debug_f("Failed to open SELinux context file");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (fstat(fileno(contexts_file), &sb) != 0 ||
|
||||
+ sb.st_uid != 0 || (sb.st_mode & 022) != 0) {
|
||||
+ logit_f("SELinux context file needs to be owned by root"
|
||||
+ " and not writable by anyone else");
|
||||
+ fclose(contexts_file);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while (fgets(line, sizeof(line), contexts_file)) {
|
||||
+ /* Strip trailing whitespace */
|
||||
+ for (len = strlen(line) - 1; len > 0; len--) {
|
||||
+ if (strchr(" \t\r\n", line[len]) == NULL)
|
||||
+ break;
|
||||
+ line[len] = '\0';
|
||||
+ }
|
||||
+
|
||||
+ if (line[0] == '\0')
|
||||
+ continue;
|
||||
+
|
||||
+ cp = line;
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (arg && *arg == '\0')
|
||||
+ arg = strdelim(&cp);
|
||||
+
|
||||
+ if (arg && strcmp(arg, "privsep_preauth") == 0) {
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (!arg || *arg == '\0') {
|
||||
+ debug_f("privsep_preauth is empty");
|
||||
+ fclose(contexts_file);
|
||||
+ return;
|
||||
+ }
|
||||
+ preauth_context = xstrdup(arg);
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(contexts_file);
|
||||
+
|
||||
+ if (preauth_context == NULL) {
|
||||
+ debug_f("Unable to find 'privsep_preauth' option in"
|
||||
+ " SELinux context file");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ssh_selinux_change_context(preauth_context);
|
||||
+ free(preauth_context);
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Index: openssh-9.3p2/openbsd-compat/port-linux.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/openbsd-compat/port-linux.c
|
||||
+++ openssh-9.3p2/openbsd-compat/port-linux.c
|
||||
@@ -182,7 +182,7 @@ ssh_selinux_change_context(const char *n
|
||||
strlcpy(newctx + len, newname, newlen - len);
|
||||
if ((cx = index(cx + 1, ':')))
|
||||
strlcat(newctx, cx, newlen);
|
||||
- debug3("%s: setting context from '%s' to '%s'", __func__,
|
||||
+ debug_f("setting context from '%s' to '%s'",
|
||||
oldctx, newctx);
|
||||
if (setcon(newctx) < 0)
|
||||
do_log2(log_level, "%s: setcon %s from %s failed with %s",
|
||||
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
|
||||
@@ -27,6 +27,7 @@ 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_change_privsep_preauth_context(void);
|
||||
#endif
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
Index: openssh-9.3p2/sshd.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/sshd.c
|
||||
+++ openssh-9.3p2/sshd.c
|
||||
@@ -511,7 +511,7 @@ privsep_preauth_child(struct ssh *ssh)
|
||||
demote_sensitive_data(ssh);
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
- ssh_selinux_change_context("sshd_net_t");
|
||||
+ sshd_selinux_change_privsep_preauth_context();
|
||||
#endif
|
||||
|
||||
/* Demote the child */
|
491
openssh-6.6p1-keycat.patch
Normal file
491
openssh-6.6p1-keycat.patch
Normal file
@ -0,0 +1,491 @@
|
||||
Index: openssh-9.3p2/misc.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/misc.c
|
||||
+++ openssh-9.3p2/misc.c
|
||||
@@ -2770,6 +2770,13 @@ subprocess(const char *tag, const char *
|
||||
error("%s: dup2: %s", tag, strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (sshd_selinux_setup_env_variables() < 0) {
|
||||
+ error ("failed to copy environment: %s",
|
||||
+ strerror(errno));
|
||||
+ _exit(127);
|
||||
+ }
|
||||
+#endif
|
||||
if (env != NULL)
|
||||
execve(av[0], av, env);
|
||||
else
|
||||
Index: openssh-9.3p2/HOWTO.ssh-keycat
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ openssh-9.3p2/HOWTO.ssh-keycat
|
||||
@@ -0,0 +1,12 @@
|
||||
+The ssh-keycat retrieves the content of the ~/.ssh/authorized_keys
|
||||
+of an user in any environment. This includes environments with
|
||||
+polyinstantiation of home directories and SELinux MLS policy enabled.
|
||||
+
|
||||
+To use ssh-keycat, set these options in /etc/ssh/sshd_config file:
|
||||
+ AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat
|
||||
+ AuthorizedKeysCommandUser root
|
||||
+
|
||||
+Do not forget to enable public key authentication:
|
||||
+ PubkeyAuthentication yes
|
||||
+
|
||||
+
|
||||
Index: openssh-9.3p2/Makefile.in
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/Makefile.in
|
||||
+++ openssh-9.3p2/Makefile.in
|
||||
@@ -24,6 +24,7 @@ SSH_PROGRAM=@bindir@/ssh
|
||||
ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
|
||||
SFTP_SERVER=$(libexecdir)/sftp-server
|
||||
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
|
||||
+SSH_KEYCAT=$(libexecdir)/ssh-keycat
|
||||
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
|
||||
SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper
|
||||
SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper
|
||||
@@ -57,6 +58,7 @@ CHANNELLIBS=@CHANNELLIBS@
|
||||
K5LIBS=@K5LIBS@
|
||||
GSSLIBS=@GSSLIBS@
|
||||
SSHDLIBS=@SSHDLIBS@
|
||||
+KEYCATLIBS=@KEYCATLIBS@
|
||||
LIBEDIT=@LIBEDIT@
|
||||
LIBFIDO2=@LIBFIDO2@
|
||||
LIBWTMPDB=@LIBWTMPDB@
|
||||
@@ -75,7 +77,7 @@ MKDIR_P=@MKDIR_P@
|
||||
|
||||
.SUFFIXES: .lo
|
||||
|
||||
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT)
|
||||
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT)
|
||||
|
||||
TARGETS += cavstest-ctr$(EXEEXT) cavstest-kdf$(EXEEXT)
|
||||
|
||||
@@ -245,6 +247,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
|
||||
ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)
|
||||
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)
|
||||
|
||||
+ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o
|
||||
+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
|
||||
+
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
|
||||
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS)
|
||||
|
||||
@@ -431,6 +436,7 @@ install-files:
|
||||
$(INSTALL) -m 0755 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \
|
||||
fi
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT)
|
||||
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) cavstest-ctr$(EXEEXT) $(DESTDIR)$(libexecdir)/cavstest-ctr$(EXEEXT)
|
||||
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
|
||||
@@ -23,8 +23,10 @@ void ssh_selinux_setup_pty(char *, const
|
||||
void ssh_selinux_change_context(const char *);
|
||||
void ssh_selinux_setfscreatecon(const char *);
|
||||
|
||||
+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);
|
||||
#endif
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
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
|
||||
@@ -53,6 +53,20 @@ 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)
|
||||
+{
|
||||
+ static int enabled = -1;
|
||||
+
|
||||
+ if (enabled == -1) {
|
||||
+ enabled = (is_selinux_enabled() == 1);
|
||||
+ debug("SELinux support %s", enabled ? "enabled" : "disabled");
|
||||
+ }
|
||||
+
|
||||
+ return (enabled);
|
||||
+}
|
||||
+
|
||||
/* Send audit message */
|
||||
static int
|
||||
sshd_selinux_send_audit_message(int success, security_context_t default_context,
|
||||
@@ -318,7 +332,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
|
||||
/* Setup environment variables for pam_selinux */
|
||||
static int
|
||||
-sshd_selinux_setup_pam_variables(void)
|
||||
+sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
|
||||
{
|
||||
const char *reqlvl;
|
||||
char *role;
|
||||
@@ -329,16 +343,16 @@ sshd_selinux_setup_pam_variables(void)
|
||||
|
||||
ssh_selinux_get_role_level(&role, &reqlvl);
|
||||
|
||||
- rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
|
||||
+ rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
|
||||
|
||||
if (inetd_flag && !rexeced_flag) {
|
||||
use_current = "1";
|
||||
} else {
|
||||
use_current = "";
|
||||
- rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
|
||||
+ rv = rv || set_it("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
|
||||
}
|
||||
|
||||
- rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current);
|
||||
+ rv = rv || set_it("SELINUX_USE_CURRENT_RANGE", use_current);
|
||||
|
||||
if (role != NULL)
|
||||
free(role);
|
||||
@@ -346,6 +360,24 @@ sshd_selinux_setup_pam_variables(void)
|
||||
return rv;
|
||||
}
|
||||
|
||||
+static int
|
||||
+sshd_selinux_setup_pam_variables(void)
|
||||
+{
|
||||
+ return sshd_selinux_setup_variables(do_pam_putenv);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_setenv(char *name, const char *value)
|
||||
+{
|
||||
+ return setenv(name, value, 1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+sshd_selinux_setup_env_variables(void)
|
||||
+{
|
||||
+ return sshd_selinux_setup_variables(do_setenv);
|
||||
+}
|
||||
+
|
||||
/* Set the execution context to the default for the specified user */
|
||||
void
|
||||
sshd_selinux_setup_exec_context(char *pwname)
|
||||
@@ -354,7 +386,7 @@ sshd_selinux_setup_exec_context(char *pw
|
||||
int r = 0;
|
||||
security_context_t default_ctx = NULL;
|
||||
|
||||
- if (!ssh_selinux_enabled())
|
||||
+ if (!sshd_selinux_enabled())
|
||||
return;
|
||||
|
||||
if (options.use_pam) {
|
||||
@@ -421,7 +453,7 @@ sshd_selinux_copy_context(void)
|
||||
{
|
||||
security_context_t *ctx;
|
||||
|
||||
- if (!ssh_selinux_enabled())
|
||||
+ if (!sshd_selinux_enabled())
|
||||
return;
|
||||
|
||||
if (getexeccon((security_context_t *)&ctx) != 0) {
|
||||
Index: openssh-9.3p2/platform.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/platform.c
|
||||
+++ openssh-9.3p2/platform.c
|
||||
@@ -100,7 +100,7 @@ platform_setusercontext(struct passwd *p
|
||||
{
|
||||
#ifdef WITH_SELINUX
|
||||
/* Cache selinux status for later use */
|
||||
- (void)ssh_selinux_enabled();
|
||||
+ (void)sshd_selinux_enabled();
|
||||
#endif
|
||||
|
||||
#ifdef USE_SOLARIS_PROJECTS
|
||||
Index: openssh-9.3p2/ssh-keycat.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ openssh-9.3p2/ssh-keycat.c
|
||||
@@ -0,0 +1,241 @@
|
||||
+/*
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
+ * are met:
|
||||
+ * 1. Redistributions of source code must retain the above copyright
|
||||
+ * notice, and the entire permission notice in its entirety,
|
||||
+ * including the disclaimer of warranties.
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ * 3. The name of the author may not be used to endorse or promote
|
||||
+ * products derived from this software without specific prior
|
||||
+ * written permission.
|
||||
+ *
|
||||
+ * ALTERNATIVELY, this product may be distributed under the terms of
|
||||
+ * the GNU Public License, in which case the provisions of the GPL are
|
||||
+ * required INSTEAD OF the above restrictions. (This clause is
|
||||
+ * necessary due to a potential bad interaction between the GPL and
|
||||
+ * the restrictions contained in a BSD-style copyright.)
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2011 Red Hat, Inc.
|
||||
+ * Written by Tomas Mraz <tmraz@redhat.com>
|
||||
+*/
|
||||
+
|
||||
+#define _GNU_SOURCE
|
||||
+
|
||||
+#include "config.h"
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <pwd.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+#ifdef HAVE_STDINT_H
|
||||
+#include <stdint.h>
|
||||
+#endif
|
||||
+
|
||||
+#include <security/pam_appl.h>
|
||||
+
|
||||
+#include "uidswap.h"
|
||||
+#include "misc.h"
|
||||
+
|
||||
+#define ERR_USAGE 1
|
||||
+#define ERR_PAM_START 2
|
||||
+#define ERR_OPEN_SESSION 3
|
||||
+#define ERR_CLOSE_SESSION 4
|
||||
+#define ERR_PAM_END 5
|
||||
+#define ERR_GETPWNAM 6
|
||||
+#define ERR_MEMORY 7
|
||||
+#define ERR_OPEN 8
|
||||
+#define ERR_FILE_MODE 9
|
||||
+#define ERR_FDOPEN 10
|
||||
+#define ERR_STAT 11
|
||||
+#define ERR_WRITE 12
|
||||
+#define ERR_PAM_PUTENV 13
|
||||
+#define BUFLEN 4096
|
||||
+
|
||||
+/* Just ignore the messages in the conversation function */
|
||||
+static int
|
||||
+dummy_conv(int num_msg, const struct pam_message **msgm,
|
||||
+ struct pam_response **response, void *appdata_ptr)
|
||||
+{
|
||||
+ struct pam_response *rsp;
|
||||
+
|
||||
+ (void)msgm;
|
||||
+ (void)appdata_ptr;
|
||||
+
|
||||
+ if (num_msg <= 0)
|
||||
+ return PAM_CONV_ERR;
|
||||
+
|
||||
+ /* Just allocate the array as empty responses */
|
||||
+ rsp = calloc (num_msg, sizeof (struct pam_response));
|
||||
+ if (rsp == NULL)
|
||||
+ return PAM_CONV_ERR;
|
||||
+
|
||||
+ *response = rsp;
|
||||
+ return PAM_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static struct pam_conv conv = {
|
||||
+ dummy_conv,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+char *
|
||||
+make_auth_keys_name(const struct passwd *pwd)
|
||||
+{
|
||||
+ char *fname;
|
||||
+
|
||||
+ if (asprintf(&fname, "%s/.ssh/authorized_keys", pwd->pw_dir) < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return fname;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+dump_keys(const char *user)
|
||||
+{
|
||||
+ struct passwd *pwd;
|
||||
+ int fd = -1;
|
||||
+ FILE *f = NULL;
|
||||
+ char *fname = NULL;
|
||||
+ int rv = 0;
|
||||
+ char buf[BUFLEN];
|
||||
+ size_t len;
|
||||
+ struct stat st;
|
||||
+
|
||||
+ if ((pwd = getpwnam(user)) == NULL) {
|
||||
+ return ERR_GETPWNAM;
|
||||
+ }
|
||||
+
|
||||
+ if ((fname = make_auth_keys_name(pwd)) == NULL) {
|
||||
+ return ERR_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ temporarily_use_uid(pwd);
|
||||
+
|
||||
+ if ((fd = open(fname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) < 0) {
|
||||
+ rv = ERR_OPEN;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (fstat(fd, &st) < 0) {
|
||||
+ rv = ERR_STAT;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (!S_ISREG(st.st_mode) ||
|
||||
+ (st.st_uid != pwd->pw_uid && st.st_uid != 0)) {
|
||||
+ rv = ERR_FILE_MODE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ unset_nonblock(fd);
|
||||
+
|
||||
+ if ((f = fdopen(fd, "r")) == NULL) {
|
||||
+ rv = ERR_FDOPEN;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ fd = -1;
|
||||
+
|
||||
+ while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
|
||||
+ rv = fwrite(buf, 1, len, stdout) != len ? ERR_WRITE : 0;
|
||||
+ }
|
||||
+
|
||||
+fail:
|
||||
+ if (fd != -1)
|
||||
+ close(fd);
|
||||
+ if (f != NULL)
|
||||
+ fclose(f);
|
||||
+ free(fname);
|
||||
+ restore_uid();
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+static const char *env_names[] = { "SELINUX_ROLE_REQUESTED",
|
||||
+ "SELINUX_LEVEL_REQUESTED",
|
||||
+ "SELINUX_USE_CURRENT_RANGE"
|
||||
+};
|
||||
+
|
||||
+extern char **environ;
|
||||
+
|
||||
+int
|
||||
+set_pam_environment(pam_handle_t *pamh)
|
||||
+{
|
||||
+ int i;
|
||||
+ size_t j;
|
||||
+
|
||||
+ for (j = 0; j < sizeof(env_names)/sizeof(env_names[0]); ++j) {
|
||||
+ int len = strlen(env_names[j]);
|
||||
+
|
||||
+ for (i = 0; environ[i] != NULL; ++i) {
|
||||
+ if (strncmp(env_names[j], environ[i], len) == 0 &&
|
||||
+ environ[i][len] == '=') {
|
||||
+ if (pam_putenv(pamh, environ[i]) != PAM_SUCCESS)
|
||||
+ return ERR_PAM_PUTENV;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main(int argc, char *argv[])
|
||||
+{
|
||||
+ pam_handle_t *pamh = NULL;
|
||||
+ int retval;
|
||||
+ int ev = 0;
|
||||
+
|
||||
+ if (argc != 2) {
|
||||
+ fprintf(stderr, "Usage: %s <user-name>\n", argv[0]);
|
||||
+ return ERR_USAGE;
|
||||
+ }
|
||||
+
|
||||
+ retval = pam_start("ssh-keycat", argv[1], &conv, &pamh);
|
||||
+ if (retval != PAM_SUCCESS) {
|
||||
+ return ERR_PAM_START;
|
||||
+ }
|
||||
+
|
||||
+ ev = set_pam_environment(pamh);
|
||||
+ if (ev != 0)
|
||||
+ goto finish;
|
||||
+
|
||||
+ retval = pam_open_session(pamh, PAM_SILENT);
|
||||
+ if (retval != PAM_SUCCESS) {
|
||||
+ ev = ERR_OPEN_SESSION;
|
||||
+ goto finish;
|
||||
+ }
|
||||
+
|
||||
+ ev = dump_keys(argv[1]);
|
||||
+
|
||||
+ retval = pam_close_session(pamh, PAM_SILENT);
|
||||
+ if (retval != PAM_SUCCESS) {
|
||||
+ ev = ERR_CLOSE_SESSION;
|
||||
+ }
|
||||
+
|
||||
+finish:
|
||||
+ retval = pam_end (pamh,retval);
|
||||
+ if (retval != PAM_SUCCESS) {
|
||||
+ ev = ERR_PAM_END;
|
||||
+ }
|
||||
+ return ev;
|
||||
+}
|
||||
Index: openssh-9.3p2/configure.ac
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/configure.ac
|
||||
+++ openssh-9.3p2/configure.ac
|
||||
@@ -3632,6 +3632,7 @@ AC_ARG_WITH([pam],
|
||||
PAM_MSG="yes"
|
||||
|
||||
SSHDLIBS="$SSHDLIBS -lpam"
|
||||
+ KEYCATLIBS="$KEYCATLIBS -lpam"
|
||||
AC_DEFINE([USE_PAM], [1],
|
||||
[Define if you want to enable PAM support])
|
||||
|
||||
@@ -3642,6 +3643,7 @@ AC_ARG_WITH([pam],
|
||||
;;
|
||||
*)
|
||||
SSHDLIBS="$SSHDLIBS -ldl"
|
||||
+ KEYCATLIBS="$KEYCATLIBS -ldl"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
@@ -4875,6 +4877,7 @@ AC_ARG_WITH([selinux],
|
||||
fi ]
|
||||
)
|
||||
AC_SUBST([SSHDLIBS])
|
||||
+AC_SUBST([KEYCATLIBS])
|
||||
|
||||
# Check whether user wants Kerberos 5 support
|
||||
KRB5_MSG="no"
|
||||
@@ -5905,6 +5908,9 @@ fi
|
||||
if test ! -z "${SSHDLIBS}"; then
|
||||
echo " +for sshd: ${SSHDLIBS}"
|
||||
fi
|
||||
+if test ! -z "${KEYCATLIBS}"; then
|
||||
+echo " +for ssh-keycat: ${KEYCATLIBS}"
|
||||
+fi
|
||||
|
||||
echo ""
|
||||
|
125
openssh-6.6p1-privsep-selinux.patch
Normal file
125
openssh-6.6p1-privsep-selinux.patch
Normal file
@ -0,0 +1,125 @@
|
||||
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
|
||||
@@ -23,6 +23,7 @@ void ssh_selinux_setup_pty(char *, const
|
||||
void ssh_selinux_change_context(const char *);
|
||||
void ssh_selinux_setfscreatecon(const char *);
|
||||
|
||||
+void sshd_selinux_copy_context(void);
|
||||
void sshd_selinux_setup_exec_context(char *);
|
||||
#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
|
||||
@@ -416,6 +416,28 @@ sshd_selinux_setup_exec_context(char *pw
|
||||
debug3_f("done");
|
||||
}
|
||||
|
||||
+void
|
||||
+sshd_selinux_copy_context(void)
|
||||
+{
|
||||
+ security_context_t *ctx;
|
||||
+
|
||||
+ if (!ssh_selinux_enabled())
|
||||
+ return;
|
||||
+
|
||||
+ if (getexeccon((security_context_t *)&ctx) != 0) {
|
||||
+ logit_f("getexeccon failed with %s", strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+ if (ctx != NULL) {
|
||||
+ /* unset exec context before we will lose this capabililty */
|
||||
+ if (setexeccon(NULL) != 0)
|
||||
+ fatal_f("setexeccon failed with %s", strerror(errno));
|
||||
+ if (setcon(ctx) != 0)
|
||||
+ fatal_f("setcon failed with %s", strerror(errno));
|
||||
+ freecon(ctx);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Index: openssh-9.3p2/session.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/session.c
|
||||
+++ openssh-9.3p2/session.c
|
||||
@@ -1403,7 +1403,7 @@ do_setusercontext(struct passwd *pw)
|
||||
|
||||
platform_setusercontext(pw);
|
||||
|
||||
- if (platform_privileged_uidswap()) {
|
||||
+ if (platform_privileged_uidswap() && (!is_child || !use_privsep)) {
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if (setusercontext(lc, pw, pw->pw_uid,
|
||||
(LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
|
||||
@@ -1435,6 +1435,9 @@ do_setusercontext(struct passwd *pw)
|
||||
(unsigned long long)pw->pw_uid);
|
||||
chroot_path = percent_expand(tmp, "h", pw->pw_dir,
|
||||
"u", pw->pw_name, "U", uidstr, (char *)NULL);
|
||||
+#ifdef WITH_SELINUX
|
||||
+ sshd_selinux_copy_context();
|
||||
+#endif
|
||||
safely_chroot(chroot_path, pw->pw_uid);
|
||||
free(tmp);
|
||||
free(chroot_path);
|
||||
@@ -1470,6 +1473,11 @@ do_setusercontext(struct passwd *pw)
|
||||
/* Permanently switch to the desired uid. */
|
||||
permanently_set_uid(pw);
|
||||
#endif
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (in_chroot == 0)
|
||||
+ sshd_selinux_copy_context();
|
||||
+#endif
|
||||
} else if (options.chroot_directory != NULL &&
|
||||
strcasecmp(options.chroot_directory, "none") != 0) {
|
||||
fatal("server lacks privileges to chroot to ChrootDirectory");
|
||||
@@ -1487,9 +1495,6 @@ do_pwchange(Session *s)
|
||||
if (s->ttyfd != -1) {
|
||||
fprintf(stderr,
|
||||
"You must change your password now and login again!\n");
|
||||
-#ifdef WITH_SELINUX
|
||||
- setexeccon(NULL);
|
||||
-#endif
|
||||
#ifdef PASSWD_NEEDS_USERNAME
|
||||
execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
|
||||
(char *)NULL);
|
||||
@@ -1723,9 +1728,6 @@ do_child(struct ssh *ssh, Session *s, co
|
||||
argv[i] = NULL;
|
||||
optind = optreset = 1;
|
||||
__progname = argv[0];
|
||||
-#ifdef WITH_SELINUX
|
||||
- ssh_selinux_change_context("sftpd_t");
|
||||
-#endif
|
||||
exit(sftp_server_main(i, argv, s->pw));
|
||||
}
|
||||
|
||||
Index: openssh-9.3p2/sshd.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/sshd.c
|
||||
+++ openssh-9.3p2/sshd.c
|
||||
@@ -510,6 +510,10 @@ privsep_preauth_child(struct ssh *ssh)
|
||||
/* Demote the private keys to public keys. */
|
||||
demote_sensitive_data(ssh);
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ ssh_selinux_change_context("sshd_net_t");
|
||||
+#endif
|
||||
+
|
||||
/* Demote the child */
|
||||
if (privsep_chroot) {
|
||||
/* Change our root directory */
|
||||
@@ -602,6 +606,9 @@ privsep_postauth(struct ssh *ssh, Authct
|
||||
{
|
||||
#ifdef DISABLE_FD_PASSING
|
||||
if (1) {
|
||||
+#elif defined(WITH_SELINUX)
|
||||
+ if (0) {
|
||||
+ /* even root user can be confined by SELinux */
|
||||
#else
|
||||
if (authctxt->pw->pw_uid == 0) {
|
||||
#endif
|
291
openssh-7.6p1-cleanup-selinux.patch
Normal file
291
openssh-7.6p1-cleanup-selinux.patch
Normal file
@ -0,0 +1,291 @@
|
||||
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);
|
885
openssh-7.8p1-role-mls.patch
Normal file
885
openssh-7.8p1-role-mls.patch
Normal file
@ -0,0 +1,885 @@
|
||||
Index: openssh-9.3p2/auth2.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/auth2.c
|
||||
+++ openssh-9.3p2/auth2.c
|
||||
@@ -262,6 +262,9 @@ input_userauth_request(int type, u_int32
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Authmethod *m = NULL;
|
||||
char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
|
||||
+#ifdef WITH_SELINUX
|
||||
+ char *role = NULL;
|
||||
+#endif
|
||||
int r, authenticated = 0;
|
||||
double tstart = monotime_double();
|
||||
|
||||
@@ -275,6 +278,11 @@ input_userauth_request(int type, u_int32
|
||||
debug("userauth-request for user %s service %s method %s", user, service, method);
|
||||
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if ((role = strchr(user, '/')) != NULL)
|
||||
+ *role++ = 0;
|
||||
+#endif
|
||||
+
|
||||
if ((style = strchr(user, ':')) != NULL)
|
||||
*style++ = 0;
|
||||
|
||||
@@ -302,8 +310,15 @@ input_userauth_request(int type, u_int32
|
||||
use_privsep ? " [net]" : "");
|
||||
authctxt->service = xstrdup(service);
|
||||
authctxt->style = style ? xstrdup(style) : NULL;
|
||||
- if (use_privsep)
|
||||
+#ifdef WITH_SELINUX
|
||||
+ authctxt->role = role ? xstrdup(role) : NULL;
|
||||
+#endif
|
||||
+ if (use_privsep) {
|
||||
mm_inform_authserv(service, style);
|
||||
+#ifdef WITH_SELINUX
|
||||
+ mm_inform_authrole(role);
|
||||
+#endif
|
||||
+ }
|
||||
userauth_banner(ssh);
|
||||
if (auth2_setup_methods_lists(authctxt) != 0)
|
||||
ssh_packet_disconnect(ssh,
|
||||
Index: openssh-9.3p2/auth2-gss.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/auth2-gss.c
|
||||
+++ openssh-9.3p2/auth2-gss.c
|
||||
@@ -325,6 +325,7 @@ input_gssapi_mic(int type, u_int32_t ple
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Gssctxt *gssctxt;
|
||||
int r, authenticated = 0;
|
||||
+ char *micuser;
|
||||
struct sshbuf *b;
|
||||
gss_buffer_desc mic, gssbuf;
|
||||
const char *displayname;
|
||||
@@ -342,7 +343,13 @@ input_gssapi_mic(int type, u_int32_t ple
|
||||
fatal_f("sshbuf_new failed");
|
||||
mic.value = p;
|
||||
mic.length = len;
|
||||
- ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (authctxt->role && authctxt->role[0] != 0)
|
||||
+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role);
|
||||
+ else
|
||||
+#endif
|
||||
+ micuser = authctxt->user;
|
||||
+ ssh_gssapi_buildmic(b, micuser, authctxt->service,
|
||||
"gssapi-with-mic", ssh->kex->session_id);
|
||||
|
||||
if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
|
||||
@@ -356,6 +363,8 @@ input_gssapi_mic(int type, u_int32_t ple
|
||||
logit("GSSAPI MIC check failed");
|
||||
|
||||
sshbuf_free(b);
|
||||
+ if (micuser != authctxt->user)
|
||||
+ free(micuser);
|
||||
free(mic.value);
|
||||
|
||||
if ((!use_privsep || mm_is_monitor()) &&
|
||||
Index: openssh-9.3p2/auth2-hostbased.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/auth2-hostbased.c
|
||||
+++ openssh-9.3p2/auth2-hostbased.c
|
||||
@@ -128,7 +128,16 @@ userauth_hostbased(struct ssh *ssh, cons
|
||||
/* reconstruct packet */
|
||||
if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 ||
|
||||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ (authctxt->role
|
||||
+ ? ( (r = sshbuf_put_u32(b, strlen(authctxt->user)+strlen(authctxt->role)+1)) != 0 ||
|
||||
+ (r = sshbuf_put(b, authctxt->user, strlen(authctxt->user))) != 0 ||
|
||||
+ (r = sshbuf_put_u8(b, '/') != 0) ||
|
||||
+ (r = sshbuf_put(b, authctxt->role, strlen(authctxt->role))) != 0)
|
||||
+ : (r = sshbuf_put_cstring(b, authctxt->user)) != 0) ||
|
||||
+#else
|
||||
(r = sshbuf_put_cstring(b, authctxt->user)) != 0 ||
|
||||
+#endif
|
||||
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, method)) != 0 ||
|
||||
(r = sshbuf_put_string(b, pkalg, alen)) != 0 ||
|
||||
Index: openssh-9.3p2/auth2-pubkey.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/auth2-pubkey.c
|
||||
+++ openssh-9.3p2/auth2-pubkey.c
|
||||
@@ -200,9 +200,16 @@ userauth_pubkey(struct ssh *ssh, const c
|
||||
goto done;
|
||||
}
|
||||
/* reconstruct packet */
|
||||
- xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
||||
+ xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user,
|
||||
authctxt->style ? ":" : "",
|
||||
- authctxt->style ? authctxt->style : "");
|
||||
+ authctxt->style ? authctxt->style : "",
|
||||
+#ifdef WITH_SELINUX
|
||||
+ authctxt->role ? "/" : "",
|
||||
+ authctxt->role ? authctxt->role : ""
|
||||
+#else
|
||||
+ "", ""
|
||||
+#endif
|
||||
+ );
|
||||
if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, userstyle)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
|
||||
Index: openssh-9.3p2/auth.h
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/auth.h
|
||||
+++ openssh-9.3p2/auth.h
|
||||
@@ -65,6 +65,9 @@ struct Authctxt {
|
||||
char *service;
|
||||
struct passwd *pw; /* set if 'valid' */
|
||||
char *style;
|
||||
+#ifdef WITH_SELINUX
|
||||
+ char *role;
|
||||
+#endif
|
||||
|
||||
/* Method lists for multiple authentication */
|
||||
char **auth_methods; /* modified from server config */
|
||||
Index: openssh-9.3p2/auth-pam.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/auth-pam.c
|
||||
+++ openssh-9.3p2/auth-pam.c
|
||||
@@ -1240,7 +1240,7 @@ is_pam_session_open(void)
|
||||
* during the ssh authentication process.
|
||||
*/
|
||||
int
|
||||
-do_pam_putenv(char *name, char *value)
|
||||
+do_pam_putenv(char *name, const char *value)
|
||||
{
|
||||
int ret = 1;
|
||||
char *compound;
|
||||
Index: openssh-9.3p2/auth-pam.h
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/auth-pam.h
|
||||
+++ openssh-9.3p2/auth-pam.h
|
||||
@@ -33,7 +33,7 @@ u_int do_pam_account(void);
|
||||
void do_pam_session(struct ssh *);
|
||||
void do_pam_setcred(int );
|
||||
void do_pam_chauthtok(void);
|
||||
-int do_pam_putenv(char *, char *);
|
||||
+int do_pam_putenv(char *, const char *);
|
||||
char ** fetch_pam_environment(void);
|
||||
char ** fetch_pam_child_environment(void);
|
||||
void free_pam_environment(char **);
|
||||
Index: openssh-9.3p2/misc.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/misc.c
|
||||
+++ openssh-9.3p2/misc.c
|
||||
@@ -745,6 +745,7 @@ char *
|
||||
colon(char *cp)
|
||||
{
|
||||
int flag = 0;
|
||||
+ int start = 1;
|
||||
|
||||
if (*cp == ':') /* Leading colon is part of file name. */
|
||||
return NULL;
|
||||
@@ -760,6 +761,13 @@ colon(char *cp)
|
||||
return (cp);
|
||||
if (*cp == '/')
|
||||
return NULL;
|
||||
+ if (start) {
|
||||
+ /* Slash on beginning or after dots only denotes file name. */
|
||||
+ if (*cp == '/')
|
||||
+ return (0);
|
||||
+ if (*cp != '.')
|
||||
+ start = 0;
|
||||
+ }
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
Index: openssh-9.3p2/monitor.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/monitor.c
|
||||
+++ openssh-9.3p2/monitor.c
|
||||
@@ -120,6 +120,9 @@ int mm_answer_sign(struct ssh *, int, st
|
||||
int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_authserv(struct ssh *, int, struct sshbuf *);
|
||||
+#ifdef WITH_SELINUX
|
||||
+int mm_answer_authrole(struct ssh *, int, struct sshbuf *);
|
||||
+#endif
|
||||
int mm_answer_authpassword(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *);
|
||||
@@ -203,6 +206,9 @@ struct mon_table mon_dispatch_proto20[]
|
||||
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
|
||||
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
|
||||
{MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
|
||||
+#ifdef WITH_SELINUX
|
||||
+ {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
|
||||
+#endif
|
||||
{MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
|
||||
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
|
||||
#ifdef USE_PAM
|
||||
@@ -832,6 +838,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in
|
||||
|
||||
/* Allow service/style information on the auth context */
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
|
||||
+#ifdef WITH_SELINUX
|
||||
+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
|
||||
+#endif
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
|
||||
|
||||
#ifdef USE_PAM
|
||||
@@ -906,6 +915,26 @@ key_base_type_match(const char *method,
|
||||
return found;
|
||||
}
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+int
|
||||
+mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
+{
|
||||
+ int r;
|
||||
+ monitor_permit_authentications(1);
|
||||
+
|
||||
+ if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0)
|
||||
+ fatal_f("buffer error: %s", ssh_err(r));
|
||||
+ debug3_f("role=%s", authctxt->role);
|
||||
+
|
||||
+ if (strlen(authctxt->role) == 0) {
|
||||
+ free(authctxt->role);
|
||||
+ authctxt->role = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return (0);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
int
|
||||
mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
{
|
||||
@@ -1278,7 +1307,7 @@ monitor_valid_userblob(struct ssh *ssh,
|
||||
struct sshbuf *b;
|
||||
struct sshkey *hostkey = NULL;
|
||||
const u_char *p;
|
||||
- char *userstyle, *cp;
|
||||
+ char *userstyle, *s, *cp;
|
||||
size_t len;
|
||||
u_char type;
|
||||
int hostbound = 0, r, fail = 0;
|
||||
@@ -1309,6 +1338,8 @@ monitor_valid_userblob(struct ssh *ssh,
|
||||
fail++;
|
||||
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
|
||||
fatal_fr(r, "parse userstyle");
|
||||
+ if ((s = strchr(cp, '/')) != NULL)
|
||||
+ *s = '\0';
|
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
||||
authctxt->style ? ":" : "",
|
||||
authctxt->style ? authctxt->style : "");
|
||||
@@ -1359,7 +1390,7 @@ monitor_valid_hostbasedblob(const u_char
|
||||
{
|
||||
struct sshbuf *b;
|
||||
const u_char *p;
|
||||
- char *cp, *userstyle;
|
||||
+ char *cp, *s, *userstyle;
|
||||
size_t len;
|
||||
int r, fail = 0;
|
||||
u_char type;
|
||||
@@ -1380,6 +1411,8 @@ monitor_valid_hostbasedblob(const u_char
|
||||
fail++;
|
||||
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
|
||||
fatal_fr(r, "parse userstyle");
|
||||
+ if ((s = strchr(cp, '/')) != NULL)
|
||||
+ *s = '\0';
|
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
||||
authctxt->style ? ":" : "",
|
||||
authctxt->style ? authctxt->style : "");
|
||||
Index: openssh-9.3p2/monitor.h
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/monitor.h
|
||||
+++ openssh-9.3p2/monitor.h
|
||||
@@ -55,6 +55,10 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49,
|
||||
MONITOR_REQ_TERM = 50,
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ MONITOR_REQ_AUTHROLE = 80,
|
||||
+#endif
|
||||
+
|
||||
MONITOR_REQ_PAM_START = 100,
|
||||
MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103,
|
||||
MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105,
|
||||
Index: openssh-9.3p2/monitor_wrap.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/monitor_wrap.c
|
||||
+++ openssh-9.3p2/monitor_wrap.c
|
||||
@@ -396,6 +396,27 @@ mm_inform_authserv(char *service, char *
|
||||
sshbuf_free(m);
|
||||
}
|
||||
|
||||
+/* Inform the privileged process about role */
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+void
|
||||
+mm_inform_authrole(char *role)
|
||||
+{
|
||||
+ int r;
|
||||
+ struct sshbuf *m;
|
||||
+
|
||||
+ debug3_f("entering");
|
||||
+
|
||||
+ if ((m = sshbuf_new()) == NULL)
|
||||
+ fatal_f("sshbuf_new failed");
|
||||
+ if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0)
|
||||
+ fatal_f("buffer error: %s", ssh_err(r));
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m);
|
||||
+
|
||||
+ sshbuf_free(m);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* Do the password authentication */
|
||||
int
|
||||
mm_auth_password(struct ssh *ssh, char *password)
|
||||
Index: openssh-9.3p2/monitor_wrap.h
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/monitor_wrap.h
|
||||
+++ openssh-9.3p2/monitor_wrap.h
|
||||
@@ -49,6 +49,9 @@ int mm_sshkey_sign(struct ssh *, struct
|
||||
const u_char *, size_t, const char *, const char *,
|
||||
const char *, u_int compat);
|
||||
void mm_inform_authserv(char *, char *);
|
||||
+#ifdef WITH_SELINUX
|
||||
+void mm_inform_authrole(char *);
|
||||
+#endif
|
||||
struct passwd *mm_getpwnamallow(struct ssh *, const char *);
|
||||
char *mm_auth2_read_banner(void);
|
||||
int mm_auth_password(struct ssh *, char *);
|
||||
Index: openssh-9.3p2/openbsd-compat/Makefile.in
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/openbsd-compat/Makefile.in
|
||||
+++ openssh-9.3p2/openbsd-compat/Makefile.in
|
||||
@@ -100,7 +100,8 @@ PORTS= port-aix.o \
|
||||
port-prngd.o \
|
||||
port-solaris.o \
|
||||
port-net.o \
|
||||
- port-uw.o
|
||||
+ port-uw.o \
|
||||
+ port-linux-sshd.o
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $<
|
||||
Index: openssh-9.3p2/openbsd-compat/port-linux.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/openbsd-compat/port-linux.c
|
||||
+++ openssh-9.3p2/openbsd-compat/port-linux.c
|
||||
@@ -100,37 +100,6 @@ ssh_selinux_getctxbyname(char *pwname)
|
||||
return sc;
|
||||
}
|
||||
|
||||
-/* Set the execution context to the default for the specified user */
|
||||
-void
|
||||
-ssh_selinux_setup_exec_context(char *pwname)
|
||||
-{
|
||||
- char *user_ctx = NULL;
|
||||
-
|
||||
- if (!ssh_selinux_enabled())
|
||||
- return;
|
||||
-
|
||||
- debug3("%s: setting execution context", __func__);
|
||||
-
|
||||
- user_ctx = ssh_selinux_getctxbyname(pwname);
|
||||
- if (setexeccon(user_ctx) != 0) {
|
||||
- switch (security_getenforce()) {
|
||||
- case -1:
|
||||
- fatal("%s: security_getenforce() failed", __func__);
|
||||
- case 0:
|
||||
- error("%s: Failed to set SELinux execution "
|
||||
- "context for %s", __func__, pwname);
|
||||
- break;
|
||||
- default:
|
||||
- fatal("%s: Failed to set SELinux execution context "
|
||||
- "for %s (in enforcing mode)", __func__, pwname);
|
||||
- }
|
||||
- }
|
||||
- if (user_ctx != NULL)
|
||||
- freecon(user_ctx);
|
||||
-
|
||||
- debug3("%s: done", __func__);
|
||||
-}
|
||||
-
|
||||
/* Set the TTY context for the specified user */
|
||||
void
|
||||
ssh_selinux_setup_pty(char *pwname, const char *tty)
|
||||
@@ -143,7 +112,11 @@ ssh_selinux_setup_pty(char *pwname, cons
|
||||
|
||||
debug3("%s: setting TTY context on %s", __func__, tty);
|
||||
|
||||
- user_ctx = ssh_selinux_getctxbyname(pwname);
|
||||
+ if (getexeccon(&user_ctx) != 0) {
|
||||
+ error_f("getexeccon: %s", strerror(errno));
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
|
||||
/* XXX: should these calls fatal() upon failure in enforcing mode? */
|
||||
|
||||
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
|
||||
@@ -20,9 +20,10 @@
|
||||
#ifdef WITH_SELINUX
|
||||
int ssh_selinux_enabled(void);
|
||||
void ssh_selinux_setup_pty(char *, const char *);
|
||||
-void ssh_selinux_setup_exec_context(char *);
|
||||
void ssh_selinux_change_context(const char *);
|
||||
void ssh_selinux_setfscreatecon(const char *);
|
||||
+
|
||||
+void sshd_selinux_setup_exec_context(char *);
|
||||
#endif
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
Index: openssh-9.3p2/openbsd-compat/port-linux-sshd.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ openssh-9.3p2/openbsd-compat/port-linux-sshd.c
|
||||
@@ -0,0 +1,421 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
|
||||
+ * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Linux-specific portability code - just SELinux support for sshd at present
|
||||
+ */
|
||||
+
|
||||
+#include "includes.h"
|
||||
+
|
||||
+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
|
||||
+#include <errno.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include "log.h"
|
||||
+#include "xmalloc.h"
|
||||
+#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */
|
||||
+#include "servconf.h"
|
||||
+#include "port-linux.h"
|
||||
+#include "sshkey.h"
|
||||
+#include "hostfile.h"
|
||||
+#include "auth.h"
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+#include <selinux/context.h>
|
||||
+#include <selinux/get_context_list.h>
|
||||
+#include <selinux/get_default_type.h>
|
||||
+
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+#include <libaudit.h>
|
||||
+#include <unistd.h>
|
||||
+#endif
|
||||
+
|
||||
+extern ServerOptions options;
|
||||
+extern Authctxt *the_authctxt;
|
||||
+extern int inetd_flag;
|
||||
+extern int rexeced_flag;
|
||||
+
|
||||
+/* Send audit message */
|
||||
+static int
|
||||
+sshd_selinux_send_audit_message(int success, security_context_t default_context,
|
||||
+ security_context_t selected_context)
|
||||
+{
|
||||
+ int rc=0;
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+ char *msg = NULL;
|
||||
+ int audit_fd = audit_open();
|
||||
+ security_context_t default_raw=NULL;
|
||||
+ security_context_t selected_raw=NULL;
|
||||
+ rc = -1;
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
+ errno == EAFNOSUPPORT)
|
||||
+ return 0; /* No audit support in kernel */
|
||||
+ error("Error connecting to audit system.");
|
||||
+ return rc;
|
||||
+ }
|
||||
+ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) {
|
||||
+ error("Error translating default context.");
|
||||
+ default_raw = NULL;
|
||||
+ }
|
||||
+ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) {
|
||||
+ error("Error translating selected context.");
|
||||
+ selected_raw = NULL;
|
||||
+ }
|
||||
+ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s",
|
||||
+ default_raw ? default_raw : (default_context ? default_context: "?"),
|
||||
+ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) {
|
||||
+ error("Error allocating memory.");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE,
|
||||
+ msg, NULL, NULL, NULL, success) <= 0) {
|
||||
+ error("Error sending audit message.");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ rc = 0;
|
||||
+ out:
|
||||
+ free(msg);
|
||||
+ freecon(default_raw);
|
||||
+ freecon(selected_raw);
|
||||
+ close(audit_fd);
|
||||
+#endif
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mls_range_allowed(security_context_t src, security_context_t dst)
|
||||
+{
|
||||
+ struct av_decision avd;
|
||||
+ int retval;
|
||||
+ access_vector_t bit;
|
||||
+ security_class_t class;
|
||||
+
|
||||
+ debug_f("src:%s dst:%s", src, dst);
|
||||
+ class = string_to_security_class("context");
|
||||
+ if (!class) {
|
||||
+ error("string_to_security_class failed to translate security class context");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ bit = string_to_av_perm(class, "contains");
|
||||
+ if (!bit) {
|
||||
+ error("string_to_av_perm failed to translate av perm contains");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ retval = security_compute_av(src, dst, class, bit, &avd);
|
||||
+ if (retval || ((bit & avd.allowed) != bit))
|
||||
+ return 0;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+get_user_context(const char *sename, const char *role, const char *lvl,
|
||||
+ security_context_t *sc) {
|
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
|
||||
+ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) {
|
||||
+ /* User may have requested a level completely outside of his
|
||||
+ allowed range. We get a context just for auditing as the
|
||||
+ range check below will certainly fail for default context. */
|
||||
+#endif
|
||||
+ if (get_default_context(sename, NULL, sc) != 0) {
|
||||
+ *sc = NULL;
|
||||
+ return -1;
|
||||
+ }
|
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
|
||||
+ }
|
||||
+#endif
|
||||
+ if (role != NULL && role[0]) {
|
||||
+ context_t con;
|
||||
+ char *type=NULL;
|
||||
+ if (get_default_type(role, &type) != 0) {
|
||||
+ error("get_default_type: failed to get default type for '%s'",
|
||||
+ role);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ con = context_new(*sc);
|
||||
+ if (!con) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ context_role_set(con, role);
|
||||
+ context_type_set(con, type);
|
||||
+ freecon(*sc);
|
||||
+ *sc = strdup(context_str(con));
|
||||
+ context_free(con);
|
||||
+ if (!*sc)
|
||||
+ return -1;
|
||||
+ }
|
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
|
||||
+ if (lvl != NULL && lvl[0]) {
|
||||
+ /* verify that the requested range is obtained */
|
||||
+ context_t con;
|
||||
+ security_context_t obtained_raw;
|
||||
+ security_context_t requested_raw;
|
||||
+ con = context_new(*sc);
|
||||
+ if (!con) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ context_range_set(con, lvl);
|
||||
+ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) {
|
||||
+ context_free(con);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) {
|
||||
+ freecon(obtained_raw);
|
||||
+ context_free(con);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ debug("get_user_context: obtained context '%s' requested context '%s'",
|
||||
+ obtained_raw, requested_raw);
|
||||
+ if (strcmp(obtained_raw, requested_raw)) {
|
||||
+ /* set the context to the real requested one but fail */
|
||||
+ freecon(requested_raw);
|
||||
+ freecon(obtained_raw);
|
||||
+ freecon(*sc);
|
||||
+ *sc = strdup(context_str(con));
|
||||
+ context_free(con);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ freecon(requested_raw);
|
||||
+ freecon(obtained_raw);
|
||||
+ context_free(con);
|
||||
+ }
|
||||
+#endif
|
||||
+ return 0;
|
||||
+ out:
|
||||
+ freecon(*sc);
|
||||
+ *sc = NULL;
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ssh_selinux_get_role_level(char **role, const char **level)
|
||||
+{
|
||||
+ *role = NULL;
|
||||
+ *level = NULL;
|
||||
+ if (the_authctxt) {
|
||||
+ if (the_authctxt->role != NULL) {
|
||||
+ char *slash;
|
||||
+ *role = xstrdup(the_authctxt->role);
|
||||
+ if ((slash = strchr(*role, '/')) != NULL) {
|
||||
+ *slash = '\0';
|
||||
+ *level = slash + 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* 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)
|
||||
+{
|
||||
+ char *sename, *lvl;
|
||||
+ char *role;
|
||||
+ const char *reqlvl;
|
||||
+ int r = 0;
|
||||
+ context_t con = NULL;
|
||||
+
|
||||
+ ssh_selinux_get_role_level(&role, &reqlvl);
|
||||
+
|
||||
+#ifdef HAVE_GETSEUSERBYNAME
|
||||
+ if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
|
||||
+ sename = NULL;
|
||||
+ lvl = NULL;
|
||||
+ }
|
||||
+#else
|
||||
+ sename = pwname;
|
||||
+ lvl = "";
|
||||
+#endif
|
||||
+
|
||||
+ if (r == 0) {
|
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
|
||||
+ r = get_default_context_with_level(sename, lvl, NULL, default_sc);
|
||||
+#else
|
||||
+ r = get_default_context(sename, NULL, default_sc);
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ if (r == 0) {
|
||||
+ /* If launched from xinetd, we must use current level */
|
||||
+ if (inetd_flag && !rexeced_flag) {
|
||||
+ security_context_t sshdsc=NULL;
|
||||
+
|
||||
+ if (getcon_raw(&sshdsc) < 0)
|
||||
+ fatal("failed to allocate security context");
|
||||
+
|
||||
+ if ((con=context_new(sshdsc)) == NULL)
|
||||
+ fatal("failed to allocate selinux context");
|
||||
+ reqlvl = context_range_get(con);
|
||||
+ freecon(sshdsc);
|
||||
+ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0)
|
||||
+ /* we actually don't change level */
|
||||
+ reqlvl = "";
|
||||
+
|
||||
+ debug_f("current connection level '%s'", reqlvl);
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) {
|
||||
+ r = get_user_context(sename, role, reqlvl, user_sc);
|
||||
+
|
||||
+ if (r == 0 && reqlvl != NULL && reqlvl[0]) {
|
||||
+ security_context_t default_level_sc = *default_sc;
|
||||
+ if (role != NULL && role[0]) {
|
||||
+ if (get_user_context(sename, role, lvl, &default_level_sc) < 0)
|
||||
+ default_level_sc = *default_sc;
|
||||
+ }
|
||||
+ /* verify that the requested range is contained in the user range */
|
||||
+ if (mls_range_allowed(default_level_sc, *user_sc)) {
|
||||
+ logit("permit MLS level %s (user range %s)", reqlvl, lvl);
|
||||
+ } else {
|
||||
+ r = -1;
|
||||
+ error("deny MLS level %s (user range %s)", reqlvl, lvl);
|
||||
+ }
|
||||
+ if (default_level_sc != *default_sc)
|
||||
+ freecon(default_level_sc);
|
||||
+ }
|
||||
+ } else {
|
||||
+ *user_sc = *default_sc;
|
||||
+ }
|
||||
+ }
|
||||
+ if (r != 0) {
|
||||
+ error_f("Failed to get default SELinux security "
|
||||
+ "context for %s", pwname);
|
||||
+ }
|
||||
+
|
||||
+#ifdef HAVE_GETSEUSERBYNAME
|
||||
+ free(sename);
|
||||
+ free(lvl);
|
||||
+#endif
|
||||
+
|
||||
+ if (role != NULL)
|
||||
+ free(role);
|
||||
+ if (con)
|
||||
+ context_free(con);
|
||||
+
|
||||
+ return (r);
|
||||
+}
|
||||
+
|
||||
+/* Setup environment variables for pam_selinux */
|
||||
+static int
|
||||
+sshd_selinux_setup_pam_variables(void)
|
||||
+{
|
||||
+ const char *reqlvl;
|
||||
+ char *role;
|
||||
+ char *use_current;
|
||||
+ int rv;
|
||||
+
|
||||
+ debug3_f("setting execution context");
|
||||
+
|
||||
+ ssh_selinux_get_role_level(&role, &reqlvl);
|
||||
+
|
||||
+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
|
||||
+
|
||||
+ if (inetd_flag && !rexeced_flag) {
|
||||
+ use_current = "1";
|
||||
+ } else {
|
||||
+ use_current = "";
|
||||
+ rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
|
||||
+ }
|
||||
+
|
||||
+ rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current);
|
||||
+
|
||||
+ if (role != NULL)
|
||||
+ free(role);
|
||||
+
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+/* Set the execution context to the default for the specified user */
|
||||
+void
|
||||
+sshd_selinux_setup_exec_context(char *pwname)
|
||||
+{
|
||||
+ security_context_t user_ctx = NULL;
|
||||
+ int r = 0;
|
||||
+ security_context_t default_ctx = NULL;
|
||||
+
|
||||
+ if (!ssh_selinux_enabled())
|
||||
+ return;
|
||||
+
|
||||
+ if (options.use_pam) {
|
||||
+ /* do not compute context, just setup environment for pam_selinux */
|
||||
+ if (sshd_selinux_setup_pam_variables()) {
|
||||
+ switch (security_getenforce()) {
|
||||
+ case -1:
|
||||
+ fatal_f("security_getenforce() failed");
|
||||
+ case 0:
|
||||
+ error_f("SELinux PAM variable setup failure. Continuing in permissive mode.");
|
||||
+ break;
|
||||
+ default:
|
||||
+ fatal_f("SELinux PAM variable setup failure. Aborting connection.");
|
||||
+ }
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ debug3_f("setting execution context");
|
||||
+
|
||||
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
|
||||
+ if (r >= 0) {
|
||||
+ r = setexeccon(user_ctx);
|
||||
+ if (r < 0) {
|
||||
+ error_f("Failed to set SELinux execution context %s for %s",
|
||||
+ user_ctx, pwname);
|
||||
+ }
|
||||
+#ifdef HAVE_SETKEYCREATECON
|
||||
+ else if (setkeycreatecon(user_ctx) < 0) {
|
||||
+ error_f("Failed to set SELinux keyring creation context %s for %s",
|
||||
+ user_ctx, pwname);
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
+ if (user_ctx == NULL) {
|
||||
+ user_ctx = default_ctx;
|
||||
+ }
|
||||
+ if (r < 0 || user_ctx != default_ctx) {
|
||||
+ /* audit just the case when user changed a role or there was
|
||||
+ a failure */
|
||||
+ sshd_selinux_send_audit_message(r >= 0, default_ctx, user_ctx);
|
||||
+ }
|
||||
+ if (r < 0) {
|
||||
+ switch (security_getenforce()) {
|
||||
+ case -1:
|
||||
+ fatal_f("security_getenforce() failed");
|
||||
+ case 0:
|
||||
+ error_f("ELinux failure. Continuing in permissive mode.");
|
||||
+ break;
|
||||
+ default:
|
||||
+ fatal_f("SELinux failure. Aborting connection.");
|
||||
+ }
|
||||
+ }
|
||||
+ if (user_ctx != NULL && user_ctx != default_ctx)
|
||||
+ freecon(user_ctx);
|
||||
+ if (default_ctx != NULL)
|
||||
+ freecon(default_ctx);
|
||||
+
|
||||
+ debug3_f("done");
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
Index: openssh-9.3p2/platform.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/platform.c
|
||||
+++ openssh-9.3p2/platform.c
|
||||
@@ -185,7 +185,7 @@ platform_setusercontext_post_groups(stru
|
||||
}
|
||||
#endif /* HAVE_SETPCRED */
|
||||
#ifdef WITH_SELINUX
|
||||
- ssh_selinux_setup_exec_context(pw->pw_name);
|
||||
+ sshd_selinux_setup_exec_context(pw->pw_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
Index: openssh-9.3p2/sshd.c
|
||||
===================================================================
|
||||
--- openssh-9.3p2.orig/sshd.c
|
||||
+++ openssh-9.3p2/sshd.c
|
||||
@@ -2388,6 +2388,9 @@ main(int ac, char **av)
|
||||
restore_uid();
|
||||
}
|
||||
#endif
|
||||
+#ifdef WITH_SELINUX
|
||||
+ sshd_selinux_setup_exec_context(authctxt->pw->pw_name);
|
||||
+#endif
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam) {
|
||||
do_pam_setcred(1);
|
@ -1,3 +1,27 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Nov 3 10:44:14 UTC 2023 - Johannes Segitz <jsegitz@suse.com>
|
||||
|
||||
- Enhanced SELinux functionality. Added
|
||||
* 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
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Oct 24 10:56:31 UTC 2023 - Dominique Leuenberger <dimstar@opensuse.org>
|
||||
|
||||
|
@ -119,6 +119,11 @@ Patch52: logind_set_tty.patch
|
||||
# PATCH-FIx-UPSTREAM cb4ed12f.patch -- Fix build with zlib 1.3
|
||||
Patch53: https://github.com/openssh/openssh-portable/commit/cb4ed12f.patch
|
||||
Patch100: fix-missing-lz.patch
|
||||
Patch102: openssh-7.8p1-role-mls.patch
|
||||
Patch103: openssh-6.6p1-privsep-selinux.patch
|
||||
Patch104: openssh-6.6p1-keycat.patch
|
||||
Patch105: openssh-6.6.1p1-selinux-contexts.patch
|
||||
Patch106: openssh-7.6p1-cleanup-selinux.patch
|
||||
BuildRequires: audit-devel
|
||||
BuildRequires: automake
|
||||
BuildRequires: groff
|
||||
@ -383,6 +388,9 @@ install -D -m 0755 %{SOURCE9} %{buildroot}%{_sbindir}/sshd-gen-keys-start
|
||||
mkdir -p %{buildroot}%{_sysusersdir}
|
||||
install -m 644 %{SOURCE14} %{buildroot}%{_sysusersdir}/sshd.conf
|
||||
|
||||
rm %{buildroot}/usr/libexec/ssh/ssh-keycat
|
||||
#rm -r %{buildroot}/usr/lib/debug/.build-id
|
||||
|
||||
# the hmac hashes - taken from openssl
|
||||
#
|
||||
# re-define the __os_install_post macro: the macro strips
|
||||
|
Loading…
Reference in New Issue
Block a user