2 * winproxy.c: Windows implementation of platform_new_connection(),
3 * supporting an OpenSSH-like proxy command via the winhandl.c
10 #define DEFINE_PLUG_METHOD_MACROS
16 Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
17 Plug plug, int overlapped);
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)
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;
30 PROCESS_INFORMATION pi;
32 if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
35 cmd = format_telnet_command(addr, port, conf);
37 /* We are responsible for this and don't need it any more */
41 char *msg = dupprintf("Starting local proxy command: %s", cmd);
42 plug_log(plug, 2, NULL, 0, msg, 0);
47 * Create the pipes to the proxy command, and spawn the proxy
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)) {
55 new_error_socket("Unable to create pipes for proxy command", plug);
60 if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
62 new_error_socket("Unable to create pipes for proxy command", plug);
64 CloseHandle(us_from_cmd);
65 CloseHandle(cmd_to_us);
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;
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);
80 CloseHandle(us_from_cmd);
81 CloseHandle(cmd_to_us);
82 CloseHandle(us_to_cmd);
83 CloseHandle(cmd_from_us);
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);
97 si.dwFlags = STARTF_USESTDHANDLES;
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);
111 CloseHandle(cmd_from_us);
112 CloseHandle(cmd_to_us);
114 if (cmd_err_to_us != NULL)
115 CloseHandle(cmd_err_to_us);
117 return make_handle_socket(us_to_cmd, us_from_cmd, us_from_cmd_err,