]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windows/winproxy.c
Add an assortment of missing frees and closes.
[PuTTY.git] / windows / winproxy.c
1 /*
2  * winproxy.c: Windows implementation of platform_new_connection(),
3  * supporting an OpenSSH-like proxy command via the winhandl.c
4  * mechanism.
5  */
6
7 #include <stdio.h>
8 #include <assert.h>
9
10 #define DEFINE_PLUG_METHOD_MACROS
11 #include "tree234.h"
12 #include "putty.h"
13 #include "network.h"
14 #include "proxy.h"
15
16 Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
17                           Plug plug, int overlapped);
18
19 Socket platform_new_connection(SockAddr addr, const char *hostname,
20                                int port, int privport,
21                                int oobinline, int nodelay, int keepalive,
22                                Plug plug, Conf *conf)
23 {
24     char *cmd;
25     HANDLE us_to_cmd, cmd_from_us;
26     HANDLE us_from_cmd, cmd_to_us;
27     HANDLE us_from_cmd_err, cmd_err_to_us;
28     SECURITY_ATTRIBUTES sa;
29     STARTUPINFO si;
30     PROCESS_INFORMATION pi;
31
32     if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
33         return NULL;
34
35     cmd = format_telnet_command(addr, port, conf);
36
37     /* We are responsible for this and don't need it any more */
38     sk_addr_free(addr);
39
40     {
41         char *msg = dupprintf("Starting local proxy command: %s", cmd);
42         plug_log(plug, 2, NULL, 0, msg, 0);
43         sfree(msg);
44     }
45
46     /*
47      * Create the pipes to the proxy command, and spawn the proxy
48      * command process.
49      */
50     sa.nLength = sizeof(sa);
51     sa.lpSecurityDescriptor = NULL;    /* default */
52     sa.bInheritHandle = TRUE;
53     if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
54         Socket ret =
55             new_error_socket("Unable to create pipes for proxy command", plug);
56         sfree(cmd);
57         return ret;
58     }
59
60     if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
61         Socket ret =
62             new_error_socket("Unable to create pipes for proxy command", plug);
63         sfree(cmd);
64         CloseHandle(us_from_cmd);
65         CloseHandle(cmd_to_us);
66         return ret;
67     }
68
69     if (flags & FLAG_STDERR) {
70         /* If we have a sensible stderr, the proxy command can send
71          * its own standard error there, so we won't interfere. */
72         us_from_cmd_err = cmd_err_to_us = NULL;
73     } else {
74         /* If we don't have a sensible stderr, we should catch the
75          * proxy command's standard error to put in our event log. */
76         if (!CreatePipe(&us_from_cmd_err, &cmd_err_to_us, &sa, 0)) {
77             Socket ret = new_error_socket
78                 ("Unable to create pipes for proxy command", plug);
79             sfree(cmd);
80             CloseHandle(us_from_cmd);
81             CloseHandle(cmd_to_us);
82             CloseHandle(us_to_cmd);
83             CloseHandle(cmd_from_us);
84             return ret;
85         }
86     }
87
88     SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
89     SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);
90     if (us_from_cmd_err != NULL)
91         SetHandleInformation(us_from_cmd_err, HANDLE_FLAG_INHERIT, 0);
92
93     si.cb = sizeof(si);
94     si.lpReserved = NULL;
95     si.lpDesktop = NULL;
96     si.lpTitle = NULL;
97     si.dwFlags = STARTF_USESTDHANDLES;
98     si.cbReserved2 = 0;
99     si.lpReserved2 = NULL;
100     si.hStdInput = cmd_from_us;
101     si.hStdOutput = cmd_to_us;
102     si.hStdError = cmd_err_to_us;
103     CreateProcess(NULL, cmd, NULL, NULL, TRUE,
104                   CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
105                   NULL, NULL, &si, &pi);
106     CloseHandle(pi.hProcess);
107     CloseHandle(pi.hThread);
108
109     sfree(cmd);
110
111     CloseHandle(cmd_from_us);
112     CloseHandle(cmd_to_us);
113
114     if (cmd_err_to_us != NULL)
115         CloseHandle(cmd_err_to_us);
116
117     return make_handle_socket(us_to_cmd, us_from_cmd, us_from_cmd_err,
118                               plug, FALSE);
119 }