]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windows/winnpc.c
GTK2: Return 2.20 compatibility back
[PuTTY.git] / windows / winnpc.c
1 /*
2  * Windows support module which deals with being a named-pipe client.
3  */
4
5 #include <stdio.h>
6 #include <assert.h>
7
8 #define DEFINE_PLUG_METHOD_MACROS
9 #include "tree234.h"
10 #include "putty.h"
11 #include "network.h"
12 #include "proxy.h"
13 #include "ssh.h"
14
15 #if !defined NO_SECURITY
16
17 #include "winsecur.h"
18
19 Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
20                           Plug plug, int overlapped);
21
22 Socket new_named_pipe_client(const char *pipename, Plug plug)
23 {
24     HANDLE pipehandle;
25     PSID usersid, pipeowner;
26     PSECURITY_DESCRIPTOR psd;
27     char *err;
28     Socket ret;
29
30     assert(strncmp(pipename, "\\\\.\\pipe\\", 9) == 0);
31     assert(strchr(pipename + 9, '\\') == NULL);
32
33     while (1) {
34         pipehandle = CreateFile(pipename, GENERIC_READ | GENERIC_WRITE,
35                                 0, NULL, OPEN_EXISTING,
36                                 FILE_FLAG_OVERLAPPED, NULL);
37
38         if (pipehandle != INVALID_HANDLE_VALUE)
39             break;
40
41         if (GetLastError() != ERROR_PIPE_BUSY) {
42             err = dupprintf("Unable to open named pipe '%s': %s",
43                             pipename, win_strerror(GetLastError()));
44             ret = new_error_socket(err, plug);
45             sfree(err);
46             return ret;
47         }
48
49         /*
50          * If we got ERROR_PIPE_BUSY, wait for the server to
51          * create a new pipe instance. (Since the server is
52          * expected to be winnps.c, which will do that immediately
53          * after a previous connection is accepted, that shouldn't
54          * take excessively long.)
55          */
56         if (!WaitNamedPipe(pipename, NMPWAIT_USE_DEFAULT_WAIT)) {
57             err = dupprintf("Error waiting for named pipe '%s': %s",
58                             pipename, win_strerror(GetLastError()));
59             ret = new_error_socket(err, plug);
60             sfree(err);
61             return ret;
62         }
63     }
64
65     if ((usersid = get_user_sid()) == NULL) {
66         CloseHandle(pipehandle);
67         err = dupprintf("Unable to get user SID");
68         ret = new_error_socket(err, plug);
69         sfree(err);
70         return ret;
71     }
72
73     if (p_GetSecurityInfo(pipehandle, SE_KERNEL_OBJECT,
74                           OWNER_SECURITY_INFORMATION,
75                           &pipeowner, NULL, NULL, NULL,
76                           &psd) != ERROR_SUCCESS) {
77         err = dupprintf("Unable to get named pipe security information: %s",
78                         win_strerror(GetLastError()));
79         ret = new_error_socket(err, plug);
80         sfree(err);
81         CloseHandle(pipehandle);
82         return ret;
83     }
84
85     if (!EqualSid(pipeowner, usersid)) {
86         err = dupprintf("Owner of named pipe '%s' is not us", pipename);
87         ret = new_error_socket(err, plug);
88         sfree(err);
89         CloseHandle(pipehandle);
90         LocalFree(psd);
91         return ret;
92     }
93
94     LocalFree(psd);
95
96     return make_handle_socket(pipehandle, pipehandle, NULL, plug, TRUE);
97 }
98
99 #endif /* !defined NO_SECURITY */