]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
dumb_socketpair(): Try a whole series of plausible temporary/writable directories...
authorDaniel Lenski <dlenski@gmail.com>
Mon, 3 Jan 2022 16:26:52 +0000 (11:26 -0500)
committerDaniel Lenski <dlenski@gmail.com>
Thu, 13 Jan 2022 05:41:53 +0000 (21:41 -0800)
This is probably trying too hard.  Discussed in
https://gitlab.com/openconnect/openconnect/-/merge_requests/320#note_800005154

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
compat.c

index 841d092a76e7e1c01caa1ad56e6f598d194f4076..e7b56343fbd41e85971d557b8ea496693423e97f 100644 (file)
--- a/compat.c
+++ b/compat.c
@@ -428,26 +428,52 @@ int dumb_socketpair(OPENCONNECT_CMD_SOCKET socks[2], int make_overlapped)
              * https://github.com/microsoft/WSL/issues/4240#issuecomment-549663217
              *
              * So we must use a named path, and that comes with all the attendant
-             * problems of permissions and collisions. Generating a path in the
-             * temporary directory, combining current high-res time and PID, seems
-             * like a less-bad option.
+             * problems of permissions and collisions. Trying various temporary
+             * directories and putting high-res time and PID in the filename, that
+             * seems like a less-bad option.
              */
             LARGE_INTEGER ticks;
-            DWORD n = GetTempPath(UNIX_PATH_MAX, a.unaddr.sun_path);
-            /* If temp dir is too long, give up and just use current directory. */
-            if (n >= UNIX_PATH_MAX - 8)
-                n = 0;
-            /* GetTempFileName could be used here.
-             * (https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea)
-             * However it only adds 16 bits of time-based random bits,
-             * fails if there isn't room for a 14-character filename, and
-             * seems to offers no other apparent advantages. So we will
-             * use high-res timer ticks and PID for filename.
-             */
-            QueryPerformanceCounter(&ticks);
-            snprintf(a.unaddr.sun_path + n, UNIX_PATH_MAX - n,
-                     "%"PRIx64"-%"PRId32".$$$", ticks.QuadPart, GetCurrentProcessId());
-            a.unaddr.sun_family = AF_UNIX;
+            DWORD n;
+            int bind_try = 0;
+
+            for (;;) {
+                switch (bind_try++) {
+                case 0:
+                    /* "The returned string ends with a backslash" */
+                    n = GetTempPath(UNIX_PATH_MAX, a.unaddr.sun_path);
+                    break;
+                case 1:
+                    /* Heckuva job with API consistency, Microsoft!
+                     * unless the Windows directory is the root directory."
+                     */
+                    n = GetWindowsDirectory(a.unaddr.sun_path, UNIX_PATH_MAX);
+                    n += snprintf(a.unaddr.sun_path + n, UNIX_PATH_MAX - n, "\\Temp\\");
+                    break;
+                case 2:
+                    n = snprintf(a.unaddr.sun_path, UNIX_PATH_MAX, "C:\\Temp\\");
+                    break;
+                case 3:
+                    n = 0; /* Current directory */
+                    break;
+                case 4:
+                    goto fallback;
+                }
+
+                /* GetTempFileName could be used here.
+                 * (https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea)
+                 * However it only adds 16 bits of time-based random bits,
+                 * fails if there isn't room for a 14-character filename, and
+                 * seems to offers no other apparent advantages. So we will
+                 * use high-res timer ticks and PID for filename.
+                 */
+                QueryPerformanceCounter(&ticks);
+                snprintf(a.unaddr.sun_path + n, UNIX_PATH_MAX - n,
+                         "%"PRIx64"-%"PRId32".$$$", ticks.QuadPart, GetCurrentProcessId());
+                a.unaddr.sun_family = AF_UNIX;
+
+                if (bind(listener, &a.addr, addrlen) != SOCKET_ERROR)
+                    break;
+            }
         } else {
             a.inaddr.sin_family = AF_INET;
             a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -456,12 +482,10 @@ int dumb_socketpair(OPENCONNECT_CMD_SOCKET socks[2], int make_overlapped)
             if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
                            (char *) &reuse, (socklen_t) sizeof(reuse)) == -1)
                 goto fallback;;
-        }
 
-        if (bind(listener, &a.addr, addrlen) == SOCKET_ERROR)
-            goto fallback;
+            if (bind(listener, &a.addr, addrlen) == SOCKET_ERROR)
+                goto fallback;
 
-        if (domain == AF_INET) {
             memset(&a, 0, sizeof(a));
             if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR)
                 goto fallback;