components/openssh/patches/031-per_session_xauthfile.patch
branchs11u3-sru
changeset 5324 5683175b6e99
child 5613 27ea636da8ce
equal deleted inserted replaced
5322:e8cdd896f216 5324:5683175b6e99
       
     1 #
       
     2 # This patch is to fix a X11 connection failure when a user's home directory
       
     3 # is read-only. 
       
     4 #
       
     5 # We have contributed back this fix to the OpenSSH upstream community. For
       
     6 # more information, see https://bugzilla.mindrot.org/show_bug.cgi?id=2440
       
     7 # In the future, if this fix is accepted by the upsteam in a later release, we
       
     8 # will remove this patch when we upgrade to that release.
       
     9 #
       
    10 --- orig/session.c	Thu Jul 30 10:35:15 2015
       
    11 +++ new/session.c	Tue Aug  4 11:29:22 2015
       
    12 @@ -62,6 +62,10 @@
       
    13  #include <unistd.h>
       
    14  #include <limits.h>
       
    15  
       
    16 +#ifdef PER_SESSION_XAUTHFILE
       
    17 +#include <libgen.h>
       
    18 +#endif
       
    19 +
       
    20  #include "openbsd-compat/sys-queue.h"
       
    21  #include "xmalloc.h"
       
    22  #include "ssh.h"
       
    23 @@ -132,6 +136,11 @@
       
    24  
       
    25  static int session_pty_req(Session *);
       
    26  
       
    27 +#ifdef PER_SESSION_XAUTHFILE
       
    28 +void   session_xauthfile_cleanup(Session *);
       
    29 +void   cleanup_all_session_xauthfile();
       
    30 +#endif
       
    31 +
       
    32  /* import */
       
    33  extern ServerOptions options;
       
    34  extern char *__progname;
       
    35 @@ -1218,6 +1227,11 @@
       
    36  	if (getenv("TZ"))
       
    37  		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
       
    38  
       
    39 +#ifdef PER_SESSION_XAUTHFILE
       
    40 +        if (s->auth_file != NULL)
       
    41 +                child_set_env(&env, &envsize, "XAUTHORITY", s->auth_file);
       
    42 +#endif
       
    43 +
       
    44  	/* Set custom environment options from RSA authentication. */
       
    45  	if (!options.use_login) {
       
    46  		while (custom_environment) {
       
    47 @@ -2170,6 +2184,11 @@
       
    48  {
       
    49  	int success;
       
    50  
       
    51 +#ifdef PER_SESSION_XAUTHFILE
       
    52 +	int fd;
       
    53 +        char xauthdir[] = "/tmp/ssh-xauth-XXXXXX";
       
    54 +#endif
       
    55 +
       
    56  	if (s->auth_proto != NULL || s->auth_data != NULL) {
       
    57  		error("session_x11_req: session %d: "
       
    58  		    "x11 forwarding already active", s->self);
       
    59 @@ -2188,6 +2207,48 @@
       
    60  		s->auth_proto = NULL;
       
    61  		s->auth_data = NULL;
       
    62  	}
       
    63 +
       
    64 +#ifdef PER_SESSION_XAUTHFILE
       
    65 +	/*
       
    66 +	 * Create per session X authority file in the /tmp directory.
       
    67 +	 *
       
    68 +	 * If mkdtemp() or open() fails then s->auth_file remains NULL which
       
    69 +	 * means that we won't set XAUTHORITY variable in child's environment
       
    70 +	 * and xauth(1) will use the default location for the authority file.
       
    71 +	 */
       
    72 +	if (mkdtemp(xauthdir) != NULL) {
       
    73 +		s->auth_file = xmalloc(MAXPATHLEN);
       
    74 +		snprintf(s->auth_file, MAXPATHLEN, "%s/xauthfile",
       
    75 +		    xauthdir);
       
    76 +		/*
       
    77 +		 * we don't want that "creating new authority file" message to
       
    78 +                 * be printed by xauth(1) so we must create that file
       
    79 +		 * beforehand.
       
    80 +		 */
       
    81 +		if ((fd = open(s->auth_file, O_CREAT | O_EXCL | O_RDONLY,
       
    82 +		    S_IRUSR | S_IWUSR)) == -1) {
       
    83 +			error("failed to create the temporary X authority "
       
    84 +			    "file %s: %.100s; will use the default one",
       
    85 +			    s->auth_file, strerror(errno));
       
    86 +			free(s->auth_file);
       
    87 +			s->auth_file = NULL;
       
    88 +			if (rmdir(xauthdir) == -1) {
       
    89 +				error("cannot remove xauth directory "
       
    90 +				    "%s: %.100s", xauthdir, strerror(errno));
       
    91 +			}
       
    92 +		} else {
       
    93 +			close(fd);
       
    94 +			debug("temporary X authority file %s created",
       
    95 +			    s->auth_file);
       
    96 +                        debug("session number = %d", s->self);
       
    97 +		}
       
    98 +	}
       
    99 +	else {
       
   100 +		error("failed to create a directory for the temporary X "
       
   101 +		    "authority file: %.100s; will use the default xauth file",
       
   102 +		    strerror(errno));
       
   103 +	}
       
   104 +#endif
       
   105  	return success;
       
   106  }
       
   107  
       
   108 @@ -2378,6 +2439,50 @@
       
   109  	PRIVSEP(session_pty_cleanup2(s));
       
   110  }
       
   111  
       
   112 +#ifdef PER_SESSION_XAUTHFILE
       
   113 +/*
       
   114 + * We use a different temporary X authority file per session so we should
       
   115 + * remove those files when cleanup_exit() is called.
       
   116 + */
       
   117 +void
       
   118 +session_xauthfile_cleanup(Session *s)
       
   119 +{
       
   120 +	if (s == NULL || s->auth_file == NULL) {
       
   121 +		return;
       
   122 +	}
       
   123 +
       
   124 +	debug("session_xauthfile_cleanup: session %d removing %s", s->self,
       
   125 +	    s->auth_file);
       
   126 +
       
   127 +	if (unlink(s->auth_file) == -1) {
       
   128 +		error("session_xauthfile_cleanup: cannot remove xauth file: "
       
   129 +		    "%.100s", strerror(errno));
       
   130 +		return;
       
   131 +	}
       
   132 +
       
   133 +	/* dirname() will modify s->auth_file but that's ok */
       
   134 +	if (rmdir(dirname(s->auth_file)) == -1) {
       
   135 +		error("session_xauthfile_cleanup: "
       
   136 +		    "cannot remove xauth directory: %.100s", strerror(errno));
       
   137 +		return;
       
   138 +	}
       
   139 +	free(s->auth_file);
       
   140 +	s->auth_file = NULL;
       
   141 +}
       
   142 +
       
   143 +/*
       
   144 + * This is called by do_cleanup() when cleanup_exit() is called. 
       
   145 + */
       
   146 +void
       
   147 +cleanup_all_session_xauthfile()
       
   148 +{
       
   149 +	int i;
       
   150 +	for (i = 0; i < sessions_nalloc; i++) {
       
   151 +                session_xauthfile_cleanup(&sessions[i]);
       
   152 +	}
       
   153 +}
       
   154 +#endif
       
   155 +
       
   156  static char *
       
   157  sig2name(int sig)
       
   158  {
       
   159 @@ -2512,6 +2617,9 @@
       
   160  	free(s->auth_display);
       
   161  	free(s->auth_data);
       
   162  	free(s->auth_proto);
       
   163 +#ifdef PER_SESSION_XAUTHFILE
       
   164 +	session_xauthfile_cleanup(s);
       
   165 +#endif
       
   166  	free(s->subsys);
       
   167  	if (s->env != NULL) {
       
   168  		for (i = 0; i < s->num_env; i++) {
       
   169 @@ -2763,6 +2871,10 @@
       
   170  	/* remove agent socket */
       
   171  	auth_sock_cleanup_proc(authctxt->pw);
       
   172  
       
   173 +#ifdef PER_SESSION_XAUTHFILE
       
   174 +	cleanup_all_session_xauthfile();
       
   175 +#endif
       
   176 +
       
   177  	/*
       
   178  	 * Cleanup ptys/utmp only if privsep is disabled,
       
   179  	 * or if running in monitor.
       
   180 --- orig/session.h	Thu Jul 30 10:35:12 2015
       
   181 +++ new/session.h	Tue Aug  4 11:30:04 2015
       
   182 @@ -49,6 +49,9 @@
       
   183  	char	*auth_display;
       
   184  	char	*auth_proto;
       
   185  	char	*auth_data;
       
   186 +#ifdef PER_SESSION_XAUTHFILE
       
   187 +	char    *auth_file;	/* xauth(1) authority file */
       
   188 +#endif
       
   189  	int	single_connection;
       
   190  
       
   191  	/* proto 2 */