1 This patch is to fix a X11 connection failure when a user's home directory
4 Oracle contributed back this fix to the OpenSSH upstream community. For
5 more information, see https://bugzilla.mindrot.org/show_bug.cgi?id=2440
6 In the future, if this fix is accepted by the upsteam in a later release, we
7 will remove this patch when we upgrade to that release.
9 --- hpn-ssh-hpn-18.4.2/session.c.orig
10 +++ hpn-ssh-hpn-18.4.2/session.c
15 +#ifdef PER_SESSION_XAUTHFILE
19 #include "openbsd-compat/sys-queue.h"
24 static int session_pty_req(struct ssh *, Session *);
26 +#ifdef PER_SESSION_XAUTHFILE
27 +void session_xauthfile_cleanup(Session *);
28 +void cleanup_all_session_xauthfile();
32 extern ServerOptions options;
33 extern char *__progname;
34 @@ -1104,6 +1113,11 @@
38 +#ifdef PER_SESSION_XAUTHFILE
39 + if (s->auth_file != NULL)
40 + child_set_env(&env, &envsize, "XAUTHORITY", s->auth_file);
43 /* Set custom environment options from pubkey authentication. */
44 if (options.permit_user_env) {
45 for (n = 0 ; n < auth_opts->nenv; n++) {
46 @@ -2006,6 +2020,11 @@
48 u_char single_connection = 0;
50 +#ifdef PER_SESSION_XAUTHFILE
52 + char xauthdir[] = "/tmp/ssh-xauth-XXXXXX";
55 if (s->auth_proto != NULL || s->auth_data != NULL) {
56 error("session_x11_req: session %d: "
57 "x11 forwarding already active", s->self);
58 @@ -2020,19 +2039,82 @@
60 s->single_connection = single_connection;
62 - if (xauth_valid_string(s->auth_proto) &&
63 - xauth_valid_string(s->auth_data))
64 - success = session_setup_x11fwd(ssh, s);
66 + if (!xauth_valid_string(s->auth_proto) ||
67 + !xauth_valid_string(s->auth_data)) {
69 error("Invalid X11 forwarding data");
73 +#ifdef PER_SESSION_XAUTHFILE
75 + * Create per session X authority file in the /tmp directory.
77 + * If mkdtemp() or open() fails then s->auth_file remains NULL which
78 + * means that we won't set XAUTHORITY variable in child's environment
79 + * and xauth(1) will use the default location for the authority file.
81 + temporarily_use_uid(s->pw);
82 + if (mkdtemp(xauthdir) != NULL) {
83 + s->auth_file = xmalloc(MAXPATHLEN);
84 + if (snprintf(s->auth_file, MAXPATHLEN, "%s/xauthfile",
85 + xauthdir) >= MAXPATHLEN) {
86 + error("temporary X authority file name was too long "
87 + "for the buffer allocated");
93 + * we don't want that "creating new authority file" message to
94 + * be printed by xauth(1) so we must create that file
97 + if ((fd = open(s->auth_file, O_CREAT | O_EXCL | O_RDONLY,
98 + S_IRUSR | S_IWUSR)) == -1) {
99 + error("failed to create the temporary X authority "
100 + "file %s: %.100s; will use the default one",
101 + s->auth_file, strerror(errno));
102 + free(s->auth_file);
103 + s->auth_file = NULL;
104 + if (rmdir(xauthdir) == -1) {
105 + error("cannot remove xauth directory "
106 + "%s: %.100s", xauthdir, strerror(errno));
109 + if (close(fd) != 0) {
110 + error("close() failed on temporary X authority "
111 + "file: %s", strerror(errno));
116 + debug("temporary X authority file %s created",
118 + debug("session number = %d", s->self);
121 + error("failed to create a directory for the temporary X "
122 + "authority file: %.100s; will use the default xauth file",
128 + success = session_setup_x11fwd(ssh, s);
134 s->auth_proto = NULL;
136 +#ifdef PER_SESSION_XAUTHFILE
137 + free(s->auth_file);
138 + s->auth_file = NULL;
145 @@ -2312,6 +2394,51 @@
146 PRIVSEP(session_pty_cleanup2(s));
149 +#ifdef PER_SESSION_XAUTHFILE
151 + * We use a different temporary X authority file per session so we should
152 + * remove those files when cleanup_exit() is called.
155 +session_xauthfile_cleanup(Session *s)
157 + if (s == NULL || s->auth_file == NULL) {
161 + debug("session_xauthfile_cleanup: session %d removing %s", s->self,
164 + if (unlink(s->auth_file) == -1) {
165 + error("session_xauthfile_cleanup: cannot remove xauth file "
166 + "%s: %.100s", s->auth_file, strerror(errno));
170 + /* dirname() will modify s->auth_file but that's ok */
171 + if (rmdir(dirname(s->auth_file)) == -1) {
172 + error("session_xauthfile_cleanup: "
173 + "cannot remove xauth directory %s: %.100s",
174 + s->auth_file, strerror(errno));
177 + free(s->auth_file);
178 + s->auth_file = NULL;
182 + * This is called by do_cleanup() when cleanup_exit() is called.
185 +cleanup_all_session_xauthfile()
188 + for (i = 0; i < sessions_nalloc; i++) {
189 + session_xauthfile_cleanup(&sessions[i]);
197 @@ -2459,6 +2586,9 @@
198 free(s->auth_display);
201 +#ifdef PER_SESSION_XAUTHFILE
202 + session_xauthfile_cleanup(s);
205 if (s->env != NULL) {
206 for (i = 0; i < s->num_env; i++) {
207 @@ -2714,6 +2844,10 @@
208 auth_info_file = NULL;
211 +#ifdef PER_SESSION_XAUTHFILE
212 + cleanup_all_session_xauthfile();
216 * Cleanup ptys/utmp only if privsep is disabled,
217 * or if running in monitor.
218 --- hpn-ssh-hpn-18.4.2/session.h.orig
219 +++ hpn-ssh-hpn-18.4.2/session.h
224 +#ifdef PER_SESSION_XAUTHFILE
225 + char *auth_file; /* xauth(1) authority file */
227 int single_connection;