File: local-proxy.c

package info (click to toggle)
putty 0.83-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 13,216 kB
  • sloc: ansic: 148,476; python: 8,466; perl: 1,830; makefile: 128; sh: 117
file content (118 lines) | stat: -rw-r--r-- 3,748 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * local-proxy.c: Windows implementation of platform_new_connection(),
 * supporting an OpenSSH-like proxy command via the handle-io.c
 * mechanism.
 */

#include <stdio.h>
#include <assert.h>

#include "tree234.h"
#include "putty.h"
#include "network.h"
#include "proxy/proxy.h"

char *platform_setup_local_proxy(Socket *socket, const char *cmd)
{
    HANDLE us_to_cmd, cmd_from_us;
    HANDLE us_from_cmd, cmd_to_us;
    HANDLE us_from_cmd_err, cmd_err_to_us;
    SECURITY_ATTRIBUTES sa;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    /*
     * Create the pipes to the proxy command, and spawn the proxy
     * command process.
     */
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;    /* default */
    sa.bInheritHandle = true;
    if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
        return dupprintf("Unable to create pipes for proxy command: %s",
                         win_strerror(GetLastError()));
    }

    if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
        CloseHandle(us_from_cmd);
        CloseHandle(cmd_to_us);
        return dupprintf("Unable to create pipes for proxy command: %s",
                         win_strerror(GetLastError()));
    }

    if (!CreatePipe(&us_from_cmd_err, &cmd_err_to_us, &sa, 0)) {
        CloseHandle(us_from_cmd);
        CloseHandle(cmd_to_us);
        CloseHandle(us_to_cmd);
        CloseHandle(cmd_from_us);
        return dupprintf("Unable to create pipes for proxy command: %s",
                         win_strerror(GetLastError()));
    }

    SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
    SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);
    if (us_from_cmd_err != NULL)
        SetHandleInformation(us_from_cmd_err, HANDLE_FLAG_INHERIT, 0);

    si.cb = sizeof(si);
    si.lpReserved = NULL;
    si.lpDesktop = NULL;
    si.lpTitle = NULL;
    si.dwFlags = STARTF_USESTDHANDLES;
    si.cbReserved2 = 0;
    si.lpReserved2 = NULL;
    si.hStdInput = cmd_from_us;
    si.hStdOutput = cmd_to_us;
    si.hStdError = cmd_err_to_us;
    char *cmd_mutable = dupstr(cmd); /* CreateProcess needs non-const char * */
    CreateProcess(NULL, cmd_mutable, NULL, NULL, true,
                  CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
                  NULL, NULL, &si, &pi);
    sfree(cmd_mutable);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    CloseHandle(cmd_from_us);
    CloseHandle(cmd_to_us);

    if (cmd_err_to_us != NULL)
        CloseHandle(cmd_err_to_us);

    setup_handle_socket(socket, us_to_cmd, us_from_cmd, us_from_cmd_err,
                        false);

    return NULL;
}

Socket *platform_new_connection(SockAddr *addr, const char *hostname,
                                int port, bool privport,
                                bool oobinline, bool nodelay, bool keepalive,
                                Plug *plug, Conf *conf, Interactor *itr)
{
    if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
        return NULL;

    DeferredSocketOpener *opener = local_proxy_opener(
        addr, port, plug, conf, itr);
    Socket *socket = make_deferred_handle_socket(opener, addr, port, plug);
    local_proxy_opener_set_socket(opener, socket);
    return socket;
}

Socket *platform_start_subprocess(const char *cmd, Plug *plug,
                                  const char *prefix)
{
    Socket *socket = make_deferred_handle_socket(
        null_deferred_socket_opener(),
        sk_nonamelookup("<local command>"), 0, plug);
    char *err = platform_setup_local_proxy(socket, cmd);
    handle_socket_set_psb_prefix(socket, prefix);

    if (err) {
        sk_close(socket);
        socket = new_error_socket_fmt(plug, "%s", err);
        sfree(err);
    }

    return socket;
}