예제 #1
0
Socket new_named_pipe_client(const char *pipename, Plug plug)
{
    HANDLE pipehandle;
    PSID usersid, pipeowner;
    PSECURITY_DESCRIPTOR psd;
    char *err;
    Socket ret;

    assert(strncmp(pipename, "\\\\.\\pipe\\", 9) == 0);
    assert(strchr(pipename + 9, '\\') == NULL);

    while (1) {
        pipehandle = CreateFile(pipename, GENERIC_READ | GENERIC_WRITE,
                                0, NULL, OPEN_EXISTING,
                                FILE_FLAG_OVERLAPPED, NULL);

        if (pipehandle != INVALID_HANDLE_VALUE)
            break;

        if (GetLastError() != ERROR_PIPE_BUSY) {
            err = dupprintf("Unable to open named pipe '%s': %s",
                            pipename, win_strerror(GetLastError()));
            ret = new_error_socket(err, plug);
            sfree(err);
            return ret;
        }

        /*
         * If we got ERROR_PIPE_BUSY, wait for the server to
         * create a new pipe instance. (Since the server is
         * expected to be winnps.c, which will do that immediately
         * after a previous connection is accepted, that shouldn't
         * take excessively long.)
         */
        if (!WaitNamedPipe(pipename, NMPWAIT_USE_DEFAULT_WAIT)) {
            err = dupprintf("Error waiting for named pipe '%s': %s",
                            pipename, win_strerror(GetLastError()));
            ret = new_error_socket(err, plug);
            sfree(err);
            return ret;
        }
    }

    if ((usersid = get_user_sid()) == NULL) {
        CloseHandle(pipehandle);
        err = dupprintf("Unable to get user SID");
        ret = new_error_socket(err, plug);
        sfree(err);
        return ret;
    }

    if (p_GetSecurityInfo(pipehandle, SE_KERNEL_OBJECT,
                          OWNER_SECURITY_INFORMATION,
                          &pipeowner, NULL, NULL, NULL,
                          &psd) != ERROR_SUCCESS) {
        err = dupprintf("Unable to get named pipe security information: %s",
                        win_strerror(GetLastError()));
        ret = new_error_socket(err, plug);
        sfree(err);
        CloseHandle(pipehandle);
        return ret;
    }

    if (!EqualSid(pipeowner, usersid)) {
        err = dupprintf("Owner of named pipe '%s' is not us", pipename);
        ret = new_error_socket(err, plug);
        sfree(err);
        CloseHandle(pipehandle);
        LocalFree(psd);
        return ret;
    }

    LocalFree(psd);

    return make_handle_socket(pipehandle, pipehandle, NULL, plug, TRUE);
}
예제 #2
0
파일: winproxy.c 프로젝트: bestustc/PuTTY
Socket platform_new_connection(SockAddr addr, const char *hostname,
			       int port, int privport,
			       int oobinline, int nodelay, int keepalive,
			       Plug plug, Conf *conf)
{
    char *cmd;
    HANDLE us_to_cmd, us_from_cmd, cmd_to_us, cmd_from_us;
    SECURITY_ATTRIBUTES sa;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
	return NULL;

    cmd = format_telnet_command(addr, port, conf);

    /* We are responsible for this and don't need it any more */
    sk_addr_free(addr);

    {
	char *msg = dupprintf("Starting local proxy command: %s", cmd);
	/* We're allowed to pass NULL here, because we're part of the Windows
	 * front end so we know logevent doesn't expect any data. */
	logevent(NULL, msg);
	sfree(msg);
    }

    /*
     * Create the pipes to the proxy command, and spawn the proxy
     * command process.
     */
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;    /* default */
    sa.bInheritHandle = TRUE;
    if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
	Socket ret =
            new_error_socket("Unable to create pipes for proxy command", plug);
        sfree(cmd);
	return ret;
    }

    if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
	Socket ret =
            new_error_socket("Unable to create pipes for proxy command", plug);
        sfree(cmd);
	CloseHandle(us_from_cmd);
	CloseHandle(cmd_to_us);
	return ret;
    }

    SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
    SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);

    si.cb = sizeof(si);
    si.lpReserved = NULL;
    si.lpDesktop = NULL;
    si.lpTitle = NULL;
    si.dwFlags = STARTF_USESTDHANDLES;
    si.cbReserved2 = 0;
    si.lpReserved2 = NULL;
    si.hStdInput = cmd_from_us;
    si.hStdOutput = cmd_to_us;
    si.hStdError = NULL;
    CreateProcess(NULL, cmd, NULL, NULL, TRUE,
		  CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
		  NULL, NULL, &si, &pi);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    sfree(cmd);

    CloseHandle(cmd_from_us);
    CloseHandle(cmd_to_us);

    return make_handle_socket(us_to_cmd, us_from_cmd, plug, FALSE);
}
예제 #3
0
Socket platform_new_connection(SockAddr addr,
                               const char *hostname,
                               int port,
                               int privport,
                               int oobinline,
                               int nodelay,
                               int keepalive,
                               Plug plug,
                               Conf *conf)
{
  char *cmd;
  HANDLE us_to_cmd, cmd_from_us;
  HANDLE us_from_cmd, cmd_to_us;
  HANDLE us_from_cmd_err, cmd_err_to_us;
  SECURITY_ATTRIBUTES sa;
  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
    return NULL;

  cmd = format_telnet_command(addr, port, conf);

  /* We are responsible for this and don't need it any more */
  sk_addr_free(addr);

  {
    char *msg = dupprintf("Starting local proxy command: %s", cmd);
    plug_log(plug, 2, NULL, 0, msg, 0);
    sfree(msg);
  }

  /*
   * Create the pipes to the proxy command, and spawn the proxy
   * command process.
   */
  sa.nLength = sizeof(sa);
  sa.lpSecurityDescriptor = NULL; /* default */
  sa.bInheritHandle = TRUE;
  if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
    Socket ret =
        new_error_socket("Unable to create pipes for proxy command", plug);
    sfree(cmd);
    return ret;
  }

  if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
    Socket ret =
        new_error_socket("Unable to create pipes for proxy command", plug);
    sfree(cmd);
    CloseHandle(us_from_cmd);
    CloseHandle(cmd_to_us);
    return ret;
  }

  if (flags & FLAG_STDERR) {
    /* If we have a sensible stderr, the proxy command can send
     * its own standard error there, so we won't interfere. */
    us_from_cmd_err = cmd_err_to_us = NULL;
  } else {
    /* If we don't have a sensible stderr, we should catch the
     * proxy command's standard error to put in our event log. */
    if (!CreatePipe(&us_from_cmd_err, &cmd_err_to_us, &sa, 0)) {
      Socket ret =
          new_error_socket("Unable to create pipes for proxy command", plug);
      sfree(cmd);
      CloseHandle(us_from_cmd);
      CloseHandle(cmd_to_us);
      CloseHandle(us_to_cmd);
      CloseHandle(cmd_from_us);
      return ret;
    }
  }

  SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
  SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);
  if (us_from_cmd_err != NULL)
    SetHandleInformation(us_from_cmd_err, HANDLE_FLAG_INHERIT, 0);

  si.cb = sizeof(si);
  si.lpReserved = NULL;
  si.lpDesktop = NULL;
  si.lpTitle = NULL;
  si.dwFlags = STARTF_USESTDHANDLES;
  si.cbReserved2 = 0;
  si.lpReserved2 = NULL;
  si.hStdInput = cmd_from_us;
  si.hStdOutput = cmd_to_us;
  si.hStdError = cmd_err_to_us;
  CreateProcess(NULL,
                cmd,
                NULL,
                NULL,
                TRUE,
                CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
                NULL,
                NULL,
                &si,
                &pi);
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);

  sfree(cmd);

  CloseHandle(cmd_from_us);
  CloseHandle(cmd_to_us);

  if (cmd_err_to_us != NULL)
    CloseHandle(cmd_err_to_us);

  return make_handle_socket(
      us_to_cmd, us_from_cmd, us_from_cmd_err, plug, FALSE);
}