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 #include "tree234.h"
11 #include "putty.h"
12 #include "network.h"
13 #include "proxy.h"
14
platform_new_connection(SockAddr * addr,const char * hostname,int port,bool privport,bool oobinline,bool nodelay,bool keepalive,Plug * plug,Conf * conf)15 Socket *platform_new_connection(SockAddr *addr, const char *hostname,
16 int port, bool privport,
17 bool oobinline, bool nodelay, bool keepalive,
18 Plug *plug, Conf *conf)
19 {
20 char *cmd;
21 HANDLE us_to_cmd, cmd_from_us;
22 HANDLE us_from_cmd, cmd_to_us;
23 HANDLE us_from_cmd_err, cmd_err_to_us;
24 SECURITY_ATTRIBUTES sa;
25 STARTUPINFO si;
26 PROCESS_INFORMATION pi;
27
28 if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
29 return NULL;
30
31 cmd = format_telnet_command(addr, port, conf);
32
33 /* We are responsible for this and don't need it any more */
34 sk_addr_free(addr);
35
36 {
37 char *msg = dupprintf("Starting local proxy command: %s", cmd);
38 plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
39 sfree(msg);
40 }
41
42 /*
43 * Create the pipes to the proxy command, and spawn the proxy
44 * command process.
45 */
46 sa.nLength = sizeof(sa);
47 sa.lpSecurityDescriptor = NULL; /* default */
48 sa.bInheritHandle = true;
49 if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
50 sfree(cmd);
51 return new_error_socket_fmt(
52 plug, "Unable to create pipes for proxy command: %s",
53 win_strerror(GetLastError()));
54 }
55
56 if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
57 sfree(cmd);
58 CloseHandle(us_from_cmd);
59 CloseHandle(cmd_to_us);
60 return new_error_socket_fmt(
61 plug, "Unable to create pipes for proxy command: %s",
62 win_strerror(GetLastError()));
63 }
64
65 if (!CreatePipe(&us_from_cmd_err, &cmd_err_to_us, &sa, 0)) {
66 sfree(cmd);
67 CloseHandle(us_from_cmd);
68 CloseHandle(cmd_to_us);
69 CloseHandle(us_to_cmd);
70 CloseHandle(cmd_from_us);
71 return new_error_socket_fmt(
72 plug, "Unable to create pipes for proxy command: %s",
73 win_strerror(GetLastError()));
74 }
75
76 SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
77 SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);
78 if (us_from_cmd_err != NULL)
79 SetHandleInformation(us_from_cmd_err, HANDLE_FLAG_INHERIT, 0);
80
81 si.cb = sizeof(si);
82 si.lpReserved = NULL;
83 si.lpDesktop = NULL;
84 si.lpTitle = NULL;
85 si.dwFlags = STARTF_USESTDHANDLES;
86 si.cbReserved2 = 0;
87 si.lpReserved2 = NULL;
88 si.hStdInput = cmd_from_us;
89 si.hStdOutput = cmd_to_us;
90 si.hStdError = cmd_err_to_us;
91 CreateProcess(NULL, cmd, NULL, NULL, true,
92 CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
93 NULL, NULL, &si, &pi);
94 CloseHandle(pi.hProcess);
95 CloseHandle(pi.hThread);
96
97 sfree(cmd);
98
99 CloseHandle(cmd_from_us);
100 CloseHandle(cmd_to_us);
101
102 if (cmd_err_to_us != NULL)
103 CloseHandle(cmd_err_to_us);
104
105 return make_handle_socket(us_to_cmd, us_from_cmd, us_from_cmd_err,
106 plug, false);
107 }
108