1
0

winproxy.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. #define DEFINE_PLUG_METHOD_MACROS
  9. #include "tree234.h"
  10. #include "putty.h"
  11. #include "network.h"
  12. #include "proxy.h"
  13. Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
  14. Plug plug, int overlapped);
  15. Socket platform_new_connection(SockAddr addr, const char *hostname,
  16. int port, int privport,
  17. int oobinline, int nodelay, int 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. if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
  28. return NULL;
  29. cmd = format_telnet_command(addr, port, conf);
  30. /* We are responsible for this and don't need it any more */
  31. sk_addr_free(addr);
  32. {
  33. char *msg = dupprintf("Starting local proxy command: %s", cmd);
  34. plug_log(plug, 2, NULL, 0, msg, 0);
  35. sfree(msg);
  36. }
  37. /*
  38. * Create the pipes to the proxy command, and spawn the proxy
  39. * command process.
  40. */
  41. sa.nLength = sizeof(sa);
  42. sa.lpSecurityDescriptor = NULL; /* default */
  43. sa.bInheritHandle = TRUE;
  44. if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
  45. Socket ret =
  46. new_error_socket("Unable to create pipes for proxy command", plug);
  47. sfree(cmd);
  48. return ret;
  49. }
  50. if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
  51. Socket ret =
  52. new_error_socket("Unable to create pipes for proxy command", plug);
  53. sfree(cmd);
  54. CloseHandle(us_from_cmd);
  55. CloseHandle(cmd_to_us);
  56. return ret;
  57. }
  58. if (flags & FLAG_STDERR) {
  59. /* If we have a sensible stderr, the proxy command can send
  60. * its own standard error there, so we won't interfere. */
  61. us_from_cmd_err = cmd_err_to_us = NULL;
  62. } else {
  63. /* If we don't have a sensible stderr, we should catch the
  64. * proxy command's standard error to put in our event log. */
  65. if (!CreatePipe(&us_from_cmd_err, &cmd_err_to_us, &sa, 0)) {
  66. Socket ret = new_error_socket
  67. ("Unable to create pipes for proxy command", plug);
  68. sfree(cmd);
  69. CloseHandle(us_from_cmd);
  70. CloseHandle(cmd_to_us);
  71. CloseHandle(us_to_cmd);
  72. CloseHandle(cmd_from_us);
  73. return ret;
  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. si.cb = sizeof(si);
  81. si.lpReserved = NULL;
  82. si.lpDesktop = NULL;
  83. si.lpTitle = NULL;
  84. si.dwFlags = STARTF_USESTDHANDLES;
  85. si.cbReserved2 = 0;
  86. si.lpReserved2 = NULL;
  87. si.hStdInput = cmd_from_us;
  88. si.hStdOutput = cmd_to_us;
  89. si.hStdError = cmd_err_to_us;
  90. CreateProcess(NULL, cmd, NULL, NULL, TRUE,
  91. CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
  92. NULL, NULL, &si, &pi);
  93. CloseHandle(pi.hProcess);
  94. CloseHandle(pi.hThread);
  95. sfree(cmd);
  96. CloseHandle(cmd_from_us);
  97. CloseHandle(cmd_to_us);
  98. if (cmd_err_to_us != NULL)
  99. CloseHandle(cmd_err_to_us);
  100. return make_handle_socket(us_to_cmd, us_from_cmd, us_from_cmd_err,
  101. plug, FALSE);
  102. }