source: filezilla/trunk/fuentes/src/putty/windows/winnpc.c @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 3 years ago

First release to xenial

File size: 3.0 KB
Line 
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
19Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, Plug plug,
20                          int overlapped);
21
22Socket 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        sfree(usersid);
83        return ret;
84    }
85
86    if (!EqualSid(pipeowner, usersid)) {
87        err = dupprintf("Owner of named pipe '%s' is not us", pipename);
88        ret = new_error_socket(err, plug);
89        sfree(err);
90        CloseHandle(pipehandle);
91        LocalFree(psd);
92        sfree(usersid);
93        return ret;
94    }
95
96    LocalFree(psd);
97    sfree(usersid);
98
99    return make_handle_socket(pipehandle, pipehandle, plug, TRUE);
100}
101
102#endif /* !defined NO_SECURITY */
Note: See TracBrowser for help on using the repository browser.