winproxy.c 3.2 KB

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