local-proxy.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * local-proxy.c: Windows implementation of platform_new_connection(),
  3. * supporting an OpenSSH-like proxy command via the handle-io.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/proxy.h"
  12. char *platform_setup_local_proxy(Socket *socket, const char *cmd)
  13. {
  14. HANDLE us_to_cmd, cmd_from_us;
  15. HANDLE us_from_cmd, cmd_to_us;
  16. HANDLE us_from_cmd_err, cmd_err_to_us;
  17. SECURITY_ATTRIBUTES sa;
  18. STARTUPINFO si;
  19. PROCESS_INFORMATION pi;
  20. /*
  21. * Create the pipes to the proxy command, and spawn the proxy
  22. * command process.
  23. */
  24. sa.nLength = sizeof(sa);
  25. sa.lpSecurityDescriptor = NULL; /* default */
  26. sa.bInheritHandle = true;
  27. if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
  28. return dupprintf("Unable to create pipes for proxy command: %s",
  29. win_strerror(GetLastError()));
  30. }
  31. if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
  32. CloseHandle(us_from_cmd);
  33. CloseHandle(cmd_to_us);
  34. return dupprintf("Unable to create pipes for proxy command: %s",
  35. win_strerror(GetLastError()));
  36. }
  37. if (!CreatePipe(&us_from_cmd_err, &cmd_err_to_us, &sa, 0)) {
  38. CloseHandle(us_from_cmd);
  39. CloseHandle(cmd_to_us);
  40. CloseHandle(us_to_cmd);
  41. CloseHandle(cmd_from_us);
  42. return dupprintf("Unable to create pipes for proxy command: %s",
  43. win_strerror(GetLastError()));
  44. }
  45. SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
  46. SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);
  47. if (us_from_cmd_err != NULL)
  48. SetHandleInformation(us_from_cmd_err, HANDLE_FLAG_INHERIT, 0);
  49. si.cb = sizeof(si);
  50. si.lpReserved = NULL;
  51. si.lpDesktop = NULL;
  52. si.lpTitle = NULL;
  53. si.dwFlags = STARTF_USESTDHANDLES;
  54. si.cbReserved2 = 0;
  55. si.lpReserved2 = NULL;
  56. si.hStdInput = cmd_from_us;
  57. si.hStdOutput = cmd_to_us;
  58. si.hStdError = cmd_err_to_us;
  59. { // WINSCP
  60. char *cmd_mutable = dupstr(cmd); /* CreateProcess needs non-const char * */
  61. CreateProcess(NULL, cmd_mutable, NULL, NULL, true,
  62. CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
  63. NULL, NULL, &si, &pi);
  64. sfree(cmd_mutable);
  65. CloseHandle(pi.hProcess);
  66. CloseHandle(pi.hThread);
  67. CloseHandle(cmd_from_us);
  68. CloseHandle(cmd_to_us);
  69. if (cmd_err_to_us != NULL)
  70. CloseHandle(cmd_err_to_us);
  71. setup_handle_socket(socket, us_to_cmd, us_from_cmd, us_from_cmd_err,
  72. false);
  73. return NULL;
  74. } // WINSCP
  75. }
  76. Socket *platform_new_connection(SockAddr *addr, const char *hostname,
  77. int port, bool privport,
  78. bool oobinline, bool nodelay, bool keepalive,
  79. Plug *plug, Conf *conf, Interactor *itr)
  80. {
  81. if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
  82. return NULL;
  83. { // WINSCP
  84. DeferredSocketOpener *opener = local_proxy_opener(
  85. addr, port, plug, conf, itr);
  86. Socket *socket = make_deferred_handle_socket(opener, addr, port, plug);
  87. local_proxy_opener_set_socket(opener, socket);
  88. return socket;
  89. } // WINSCP
  90. }
  91. Socket *platform_start_subprocess(const char *cmd, Plug *plug,
  92. const char *prefix)
  93. {
  94. Socket *socket = make_deferred_handle_socket(
  95. null_deferred_socket_opener(),
  96. sk_nonamelookup("<local command>"), 0, plug);
  97. char *err = platform_setup_local_proxy(socket, cmd);
  98. handle_socket_set_psb_prefix(socket, prefix);
  99. if (err) {
  100. sk_close(socket);
  101. socket = new_error_socket_fmt(plug, "%s", err);
  102. sfree(err);
  103. }
  104. return socket;
  105. }