|
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 */ |