Skip to content

launchd patch

Glen Hansen edited this page Jul 27, 2015 · 1 revision
diff --git a/clientloop.c b/clientloop.c
index 59ad3a2..724acf4 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -313,6 +313,10 @@ client_x11_get_proto(const char *display, const char *xauth_path,
 	struct stat st;
 	u_int now;
 
+#if __APPLE__
+	int is_path_to_socket = 0;
+#endif /* __APPLE__ */
+
 	xauthdir = xauthfile = NULL;
 	*_proto = proto;
 	*_data = data;
@@ -328,6 +332,33 @@ client_x11_get_proto(const char *display, const char *xauth_path,
 			debug("x11_get_proto: DISPLAY not set");
 			return;
 		}
+#if __APPLE__
+		{
+			/*
+			 * If using launchd socket, remove the screen number from the end
+			 * of $DISPLAY. is_path_to_socket is used later in this function
+			 * to determine if an error should be displayed.
+			 */
+			char path[PATH_MAX];
+			struct stat sbuf;
+
+			strlcpy(path, display, sizeof(path));
+			if (0 == stat(path, &sbuf)) {
+				is_path_to_socket = 1;
+			} else {
+				char *dot = strrchr(path, '.');
+				if (dot) {
+					*dot = '\0';
+					/* screen = atoi(dot + 1); */
+					if (0 == stat(path, &sbuf)) {
+						is_path_to_socket = 1;
+						debug("x11_get_proto: $DISPLAY is launchd, removing screennum");
+						setenv("DISPLAY", path, 1);
+					}
+				}
+			}
+		}
+#endif /* __APPLE__ */
 		/*
 		 * Handle FamilyLocal case where $DISPLAY does
 		 * not match an authorization entry.  For this we
@@ -407,6 +437,9 @@ client_x11_get_proto(const char *display, const char *xauth_path,
 	if (!got_data) {
 		u_int32_t rnd = 0;
 
+#if __APPLE__
+		if (!is_path_to_socket)
+#endif /* __APPLE__ */
 		logit("Warning: No xauth data; "
 		    "using fake authentication data for X11 forwarding.");
 		strlcpy(proto, SSH_X11_PROTO, sizeof proto);
diff --git a/channels.c b/channels.c
index 9efe89c..07153aa 100644
--- a/channels.c
+++ b/channels.c
@@ -3576,15 +3576,35 @@ x11_connect_display(void)
 	 * connection to the real X server.
 	 */
 
-	/* Check if the display is from launchd. */
 #ifdef __APPLE__
-	if (strncmp(display, "/tmp/launch", 11) == 0) {
-		sock = connect_local_xsocket_path(display);
-		if (sock < 0)
-			return -1;
+	/* Check if the display is a path to a socket (as set by launchd). */
+	{
+		char path[PATH_MAX];
+		struct stat sbuf;
+		int is_path_to_socket = 0;
+
+		strlcpy(path, display, sizeof(path));
+		if (0 == stat(path, &sbuf)) {
+			is_path_to_socket = 1;
+		} else {
+			char *dot = strrchr(path, '.');
+			if (dot) {
+				*dot = '\0';
+				/* screen = atoi(dot + 1); */
+				if (0 == stat(path, &sbuf)) {
+					is_path_to_socket=1;
+				}
+			}
+		}
 
-		/* OK, we now have a connection to the display. */
-		return sock;
+		if (is_path_to_socket) {
+			sock = connect_local_xsocket_path(path);
+			if (sock < 0)
+				return -1;
+
+			/* OK, we now have a connection to the display. */
+			return sock;
+		}
 	}
 #endif
 	/*
Clone this wiki locally