Example #1
0
    def __init__(self, path):
        self.hInRead = None
        self.hInWrite = None
        self.hOutRead = None
        self.hOutWrite = None
        sa = pywintypes.SECURITY_ATTRIBUTES()
        sa.SetSecurityDescriptorDacl(1, None, 0)

        self.hInRead, self.hInWrite = win32pipe.CreatePipe(sa, 0)
        self.hOutRead, self.hOutWrite = win32pipe.CreatePipe(sa, 0)

        si = win32process.STARTUPINFO()
        si.dwFlags = win32con.STARTF_USESTDHANDLES | \
                           win32process.STARTF_USESHOWWINDOW
        si.hStdError = self.hOutWrite
        si.hStdOutput = self.hOutWrite
        si.hStdInput = self.hInRead
        si.wShowWindow = win32con.SW_HIDE

        create_flags = win32process.CREATE_NEW_CONSOLE
        self.info = win32process.CreateProcess(None, path, None, None, \
         True, create_flags, None, None, si)

        if self.info[0]:
            print('create process success')
Example #2
0
    def start(self, cmd):
        sAttr = win32security.SECURITY_ATTRIBUTES()
        sAttr.bInheritHandle = True

        stdout_r, stdout_w = win32pipe.CreatePipe(sAttr, 0)
        stdin_r, stdin_w = win32pipe.CreatePipe(sAttr, 0)
        self.read_handle = stdout_r
        self.write_handle = stdout_w
        self.stdin_write = stdin_w

        si = win32process.STARTUPINFO()
        si.dwFlags = win32process.STARTF_USESHOWWINDOW | win32process.STARTF_USESTDHANDLES
        si.wShowWindow = win32con.SW_HIDE
        si.hStdInput = stdin_r  # file descriptor of origin stdin
        si.hStdOutput = stdout_w
        si.hStdError = stdout_w
        hProcess, hThread, dwProcessID, dwThreadID = win32process.CreateProcess(
            None, "cmd", None, None, True, win32process.CREATE_NEW_CONSOLE,
            None, None, si)
        self.dwProcessID = dwProcessID
        self.hProcess = hProcess
        sleep(0.5)
        if self.hProcess == 0:
            DebugOutput("Start Process Fail:{:d}".format(
                win32api.GetLastError()))
        DebugOutput('[*] pid: {:x}'.format(self.dwProcessID))
        self.Console_hwnd = get_hwnds_for_pid(self.dwProcessID)
        if len(self.Console_hwnd) == 0:
            raise Exception("Fail to run,No Process!")
        DebugOutput('[*] hwnd:{:x}'.format(self.Console_hwnd[0]))
Example #3
0
    def __init__(self, cmd, shell=False):
        self.queue = Queue.Queue()
        self.is_terminated = False
        self.wake_up_event = win32event.CreateEvent(None, 0, 0, None)

        exec_dir = os.getcwd()
        comspec = os.environ.get("COMSPEC", "cmd.exe")
        cmd = comspec + ' /c ' + cmd

        win32event.ResetEvent(self.wake_up_event)

        currproc = win32api.GetCurrentProcess()

        sa = win32security.SECURITY_ATTRIBUTES()
        sa.bInheritHandle = 1

        child_stdout_rd, child_stdout_wr = win32pipe.CreatePipe(sa, 0)
        child_stdout_rd_dup = win32api.DuplicateHandle(
            currproc, child_stdout_rd, currproc, 0, 0,
            win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(child_stdout_rd)

        child_stderr_rd, child_stderr_wr = win32pipe.CreatePipe(sa, 0)
        child_stderr_rd_dup = win32api.DuplicateHandle(
            currproc, child_stderr_rd, currproc, 0, 0,
            win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(child_stderr_rd)

        child_stdin_rd, child_stdin_wr = win32pipe.CreatePipe(sa, 0)
        child_stdin_wr_dup = win32api.DuplicateHandle(
            currproc, child_stdin_wr, currproc, 0, 0,
            win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(child_stdin_wr)

        startup_info = win32process.STARTUPINFO()
        startup_info.hStdInput = child_stdin_rd
        startup_info.hStdOutput = child_stdout_wr
        startup_info.hStdError = child_stderr_wr
        startup_info.dwFlags = win32process.STARTF_USESTDHANDLES

        cr_flags = 0
        cr_flags = win32process.CREATE_NEW_PROCESS_GROUP

        env = os.environ.copy()
        self.h_process, h_thread, dw_pid, dw_tid = win32process.CreateProcess(
            None, cmd, None, None, 1, cr_flags, env, os.path.abspath(exec_dir),
            startup_info)

        win32api.CloseHandle(h_thread)

        win32file.CloseHandle(child_stdin_rd)
        win32file.CloseHandle(child_stdout_wr)
        win32file.CloseHandle(child_stderr_wr)

        self.__child_stdout = child_stdout_rd_dup
        self.__child_stderr = child_stderr_rd_dup
        self.__child_stdin = child_stdin_wr_dup

        self.exit_code = -1
Example #4
0
    def _launch_idle_process(self, command_line, dir=None):
        (hChildStdinRd, hChildStdinWr) = win32pipe.CreatePipe(None, 0)
        (hChildStdoutRd, hChildStdoutWr) = win32pipe.CreatePipe(None, 0)

        hChildStdinRd = self.make_inheritable(hChildStdinRd)
        hChildStdoutWr = self.make_inheritable(hChildStdoutWr)

        startupinfo = win32process.STARTUPINFO()
        startupinfo.dwFlags = \
            win32process.STARTF_USESTDHANDLES | \
            win32process.STARTF_USESHOWWINDOW
        startupinfo.hStdInput = hChildStdinRd
        startupinfo.hStdOutput = hChildStdoutWr
        startupinfo.hStdError = hChildStdoutWr

        appName = None
        commandLine = command_line
        processAttributes = None
        threadAttributes = None
        bInheritHandles = 1
        dwCreationFlags = win32process.IDLE_PRIORITY_CLASS
        newEnvironment = os.environ
        currentDirectory = None
        if dir:
            currentDirectory = os.path.normpath(os.path.join(os.getcwd(), dir))

        ## no dialog boxes that hang the build system
        SEM_FAILCRITICALERRORS = 0x0001
        SEM_NOGPFAULTERRORBOX = 0x0002
        SEM_NOALIGNMENTFAULTEXCEPT = 0x0004
        SEM_NOOPENFILEERRORBOX = 0x8000

        win32api.SetErrorMode(
            SEM_FAILCRITICALERRORS|\
            SEM_NOGPFAULTERRORBOX|\
            SEM_NOOPENFILEERRORBOX)

        try:
            (hProcess, hThread, dwProcessId, dwThreadId) = \
                win32process.CreateProcess(
                appName,
                commandLine,
                processAttributes,
                threadAttributes,
                bInheritHandles,
                dwCreationFlags,
                newEnvironment,
                currentDirectory,
                startupinfo)
        except pywintypes.error:
            return None

        ## close the thread handle, as well as the other I/O handles
        win32api.CloseHandle(hThread)
        win32api.CloseHandle(hChildStdinRd)
        win32api.CloseHandle(hChildStdoutWr)

        return hProcess, hChildStdinWr, hChildStdoutRd
Example #5
0
    def __init__(self):
        # Pipes to stream outputs.
        security_attributes = win32security.SECURITY_ATTRIBUTES()
        security_attributes.bInheritHandle = 1
        stdout_r, stdout_w = win32pipe.CreatePipe(security_attributes, 0)
        stderr_r, stderr_w = win32pipe.CreatePipe(security_attributes, 0)
        self.stdout_r = stdout_r.Detach()
        self.stdout_w = self._MakeInheritable(stdout_w)
        self.stderr_r = stderr_r.Detach()
        self.stderr_w = self._MakeInheritable(stderr_w)

        # Threads to read pipes and the actual contents returned.
        self.stdout_read_thread = None
        self.stdout = None
        self.stderr_read_thread = None
        self.stderr = None
Example #6
0
def run_command_win32(cmd):
    sa = win32security.SECURITY_ATTRIBUTES()
    sa.bInheritHandle = True
    stdout_r, stdout_w = win32pipe.CreatePipe(sa, 0)

    si = win32process.STARTUPINFO()
    si.dwFlags = (win32process.STARTF_USESTDHANDLES
                  | win32process.STARTF_USESHOWWINDOW)
    si.wShowWindow = win32con.SW_HIDE
    si.hStdOutput = stdout_w

    process, thread, pid, tid = \
             win32process.CreateProcess(None, cmd, None, None, True,
                                        0, None, None, si)
    if process == None:
        return -1, ""

    # Must close the write handle in this process, or ReadFile will hang.
    stdout_w.Close()

    # Read the pipe until we get an error (including ERROR_BROKEN_PIPE,
    # which is okay because it happens when child process ends).
    data = ""
    error = 0
    while 1:
        try:
            hr, buffer = win32file.ReadFile(stdout_r, 4096)
            if hr != winerror.ERROR_IO_PENDING:
                data = data + buffer

        except pywintypes.error, e:
            if e.args[0] != winerror.ERROR_BROKEN_PIPE:
                error = 1
            break
Example #7
0
    def startBackgroundProcess(self):
        """Method to start a process running in the background.
		
		"""
        with process_lock:
            # security attributes for pipes
            sAttrs = win32security.SECURITY_ATTRIBUTES()
            sAttrs.bInheritHandle = 1

            # create pipes for the process to write to
            hStdin_r, hStdin = win32pipe.CreatePipe(sAttrs, 0)
            hStdout = win32file.CreateFile(
                _stringToUnicode(self.stdout),
                win32file.GENERIC_WRITE | win32file.GENERIC_READ,
                win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ
                | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS,
                win32file.FILE_ATTRIBUTE_NORMAL, None)
            hStderr = win32file.CreateFile(
                _stringToUnicode(self.stderr),
                win32file.GENERIC_WRITE | win32file.GENERIC_READ,
                win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ
                | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS,
                win32file.FILE_ATTRIBUTE_NORMAL, None)

            # set the info structure for the new process.
            StartupInfo = win32process.STARTUPINFO()
            StartupInfo.hStdInput = hStdin_r
            StartupInfo.hStdOutput = hStdout
            StartupInfo.hStdError = hStderr
            StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

            # Create new handles for the thread ends of the pipes. The duplicated handles will
            # have their inheritence properties set to false so that any children inheriting these
            # handles will not have non-closeable handles to the pipes
            pid = win32api.GetCurrentProcess()
            tmp = win32api.DuplicateHandle(pid, hStdin, pid, 0, 0,
                                           win32con.DUPLICATE_SAME_ACCESS)
            win32file.CloseHandle(hStdin)
            hStdin = tmp

            # start the process, and close down the copies of the process handles
            # we have open after the process creation (no longer needed here)
            old_command = command = self.__quotePath(self.command)
            for arg in self.arguments:
                command = '%s %s' % (command, self.__quotePath(arg))
            try:
                self.__hProcess, self.__hThread, self.pid, self.__tid = win32process.CreateProcess(
                    None, command, None, None, 1, 0, self.environs,
                    os.path.normpath(self.workingDir), StartupInfo)
            except pywintypes.error as e:
                raise ProcessError("Error creating process %s: %s" %
                                   (old_command, e))

            win32file.CloseHandle(hStdin_r)
            win32file.CloseHandle(hStdout)
            win32file.CloseHandle(hStderr)

            # set the handle to the stdin of the process
            self.__stdin = hStdin
Example #8
0
def CreatePipe(readInheritable, writeInheritable):
  """Create a new pipe specifying whether the read and write ends are
  inheritable and whether they should be created for blocking or nonblocking
  I/O."""

  r, w = win32pipe.CreatePipe(None, SPOOL_BYTES)
  if readInheritable:
    r = MakeInheritedHandle(r)
  if writeInheritable:
    w = MakeInheritedHandle(w)
  return r, w
Example #9
0
    def __init__(self, inherit_handle=True):
        """Create a pipe for Windows

        Create a new pipe

        Args:
            inherit_handle (bool): Whether the child can inherit this handle

        Returns:
            WinPipe: ``WinPipe`` instance.
        """
        attr = win32security.SECURITY_ATTRIBUTES()
        attr.bInheritHandle = inherit_handle
        self.rp, self.wp = win32pipe.CreatePipe(attr, 0)
Example #10
0
	def run (self, cmdline):

		secAttrs = win32security.SECURITY_ATTRIBUTES()
		secAttrs.bInheritHandle = 1

		"""
		windows file handle redirection:
		http://wiki.wxpython.org/Capturing%20DOS%20Output%20in%20a%20wxWindow
		"""
		hStdin_r, self.hStdin_w  = win32pipe.CreatePipe(secAttrs,0)
		self.hStdout_r, hStdout_w = win32pipe.CreatePipe(secAttrs,0)
		self.hStderr_r, hStderr_w = win32pipe.CreatePipe(secAttrs,0)
		
		pid = win32api.GetCurrentProcess()

		# replace the handles
		self.hStdin_w = self.ReplaceHandle(self.hStdin_w, pid)
		self.hStdout_r = self.ReplaceHandle(self.hStdout_r, pid)
		self.hStderr_r = self.ReplaceHandle(self.hStderr_r, pid)
		
		# create the startupinformation for the process
		StartupInfo = win32process.STARTUPINFO()
		StartupInfo.hStdInput  = hStdin_r
		StartupInfo.hStdOutput = hStdout_w
		StartupInfo.hStdError  = hStderr_w
		StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

		hProcess, hThread, dwPid, dwTid = self.createProcess(cmdline,StartupInfo)
		
		self.stdin = os.fdopen(msvcrt.open_osfhandle(self.hStdin_w, 0), "wb")
		self.stdout = os.fdopen(msvcrt.open_osfhandle(self.hStdout_r, 0), "rb")
		self.stderr = os.fdopen(msvcrt.open_osfhandle(self.hStderr_r, 0), "rb")

		baggage = [self.stdin, self.stdout, self.stderr]

		return baggage
Example #11
0
def windows_create_pipe(sAttrs=-1, nSize=None):
    # Default values if parameters are not passed
    if sAttrs == -1:
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1
    if nSize is None:
        # If this parameter is zero, the system uses the default buffer size.
        nSize = 0

    try:
        (read_pipe, write_pipe) = win32pipe.CreatePipe(sAttrs, nSize)
    except pywintypes.error:
        raise

    return (read_pipe, write_pipe)
Example #12
0
def run_command_win32(cmd):
    sa = win32security.SECURITY_ATTRIBUTES()
    sa.bInheritHandle = True
    stdout_r, stdout_w = win32pipe.CreatePipe(sa, 0)

    si = win32process.STARTUPINFO()
    si.dwFlags = (win32process.STARTF_USESTDHANDLES
                  | win32process.STARTF_USESHOWWINDOW)
    si.wShowWindow = win32con.SW_HIDE
    si.hStdOutput = stdout_w

    process, thread, pid, tid = \
             win32process.CreateProcess(None, cmd, None, None, True,
                                        0, None, None, si)
    if process == None:
        return -1, ""

    # Must close the write handle in this process, or ReadFile will hang.
    stdout_w.Close()

    # Read the pipe until we get an error (including ERROR_BROKEN_PIPE,
    # which is okay because it happens when child process ends).
    data = ""
    error = 0
    while 1:
        try:
            hr, buffer = win32file.ReadFile(stdout_r, 4096)
            if hr != winerror.ERROR_IO_PENDING:
                data = data + buffer

        except pywintypes.error as e:
            if e.args[0] != winerror.ERROR_BROKEN_PIPE:
                error = 1
            break

    if error:
        return -2, ""

    # Everything is okay --- the called process has closed the pipe.
    # For safety, check that the process ended, then pick up its exit code.
    win32event.WaitForSingleObject(process, win32event.INFINITE)
    if win32process.GetExitCodeProcess(process):
        return -3, ""

    global debug
    if debug:
        sys.stdout.write(data)
    return 0, data
Example #13
0
 def _create_pipes(self):
     sa = win32security.SECURITY_ATTRIBUTES()
     sa.bInheritHandle = 1
     self._stdin_read, self._stdin_write = win32pipe.CreatePipe(sa, 0)
     win32api.SetHandleInformation(self._stdin_write,
                                   win32con.HANDLE_FLAG_INHERIT, 0)
     if self._stdout:
         if os.path.isfile(self._stdout):
             shell.remove(self._stdout)
         shell.touch(self._stdout)
         self.stdout_reader = io.open(self._stdout, 'rb+')
     else:
         self._stdout_reader = tempfile.TemporaryFile()
     self._stdout_handle = create_file(self._stdout_reader.name)
     if self._stderr:
         if os.path.isfile(self._stderr):
             shell.remove(self._stderr)
         shell.touch(self._stderr)
         self._stderr_reader = io.open(self._stderr, 'rb+')
     else:
         self._stderr_reader = tempfile.TemporaryFile()
     self._stderr_handle = create_file(self._stderr_reader.name)
Example #14
0
    def _CreatePipe(self):
        """Return a new pipe.

        returns -- A tuple (under UNIX) or list (under Windows)
        consisting of the file descriptors (UNIX) or handles (Windows)
        for the read end and write end of a new pipe.  The pipe is
        inheritable by child processes.  On UNIX the fds will not be
        inherited across 'exec'."""

        if sys.platform == "win32":
            # Create a security descriptor so that we can mark the handles
            # as inheritable.  (A call to os.pipe under Windows
            # returns handles that are not inheritable.)
            sa = pywintypes.SECURITY_ATTRIBUTES()
            sa.bInheritHandle = 1
            # Transform the tuple returned into a list so that the
            # individual elements can be altered.
            r, w = win32pipe.CreatePipe(sa, 0)
            return [r, w]
        else:
            pipe = os.pipe()
            for fd in pipe:
                qm.common.close_file_on_exec(fd)
            return pipe
Example #15
0
    def startBackgroundProcess(self):
        """Method to start a process running in the background.
		
		"""
        with process_lock:
            # security attributes for pipes
            sAttrs = win32security.SECURITY_ATTRIBUTES()
            sAttrs.bInheritHandle = 1

            # create pipes for the process to write to
            hStdin_r, hStdin = win32pipe.CreatePipe(sAttrs, 0)
            hStdout = win32file.CreateFile(
                self.stdout, win32file.GENERIC_WRITE | win32file.GENERIC_READ,
                win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ
                | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS,
                win32file.FILE_ATTRIBUTE_NORMAL, None)
            hStderr = win32file.CreateFile(
                self.stderr, win32file.GENERIC_WRITE | win32file.GENERIC_READ,
                win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ
                | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS,
                win32file.FILE_ATTRIBUTE_NORMAL, None)

            try:

                # set the info structure for the new process.
                StartupInfo = win32process.STARTUPINFO()
                StartupInfo.hStdInput = hStdin_r
                StartupInfo.hStdOutput = hStdout
                StartupInfo.hStdError = hStderr
                StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

                # Create new handles for the thread ends of the pipes. The duplicated handles will
                # have their inheritence properties set to false so that any children inheriting these
                # handles will not have non-closeable handles to the pipes
                pid = win32api.GetCurrentProcess()
                tmp = win32api.DuplicateHandle(pid, hStdin, pid, 0, 0,
                                               win32con.DUPLICATE_SAME_ACCESS)
                win32file.CloseHandle(hStdin)
                hStdin = tmp

                # start the process, and close down the copies of the process handles
                # we have open after the process creation (no longer needed here)
                old_command = command = self.__quotePath(self.command)
                for arg in self.arguments:
                    command = '%s %s' % (command, self.__quotePath(arg))

                # Windows CreateProcess maximum lpCommandLine length is 32,768
                # http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx
                if len(command) >= 32768:  # pragma: no cover
                    raise ValueError(
                        "Command line length exceeded 32768 characters: %s..."
                        % command[:1000])

                dwCreationFlags = 0
                if IS_PRE_WINDOWS_8:  # pragma: no cover
                    # In case PySys is itself running in a job, might need to explicitly breakaway from it so we can give
                    # it its own, but only for old pre-windows 8/2012, which support nested jobs
                    dwCreationFlags = dwCreationFlags | win32process.CREATE_BREAKAWAY_FROM_JOB

                if self.command.lower().endswith(('.bat', '.cmd')):
                    # If we don't start suspended there's a slight race condition but due to some issues with
                    # initially-suspended processes hanging (seen many years ago), to be safe, only bother to close the
                    # race condition for shell scripts (which is the main use case for this anyway)
                    dwCreationFlags = dwCreationFlags | win32con.CREATE_SUSPENDED

                self.__job = self._createParentJob()

                try:
                    self.__hProcess, self.__hThread, self.pid, self.__tid = win32process.CreateProcess(
                        None, command, None, None, 1,
                        dwCreationFlags, self.environs,
                        os.path.normpath(self.workingDir), StartupInfo)
                except pywintypes.error as e:
                    raise ProcessError("Error creating process %s: %s" %
                                       (old_command, e))

                try:
                    if not self.disableKillingChildProcesses:
                        win32job.AssignProcessToJobObject(
                            self.__job, self.__hProcess)
                    else:
                        self.__job = None  # pragma: no cover
                except Exception as e:  # pragma: no cover
                    # Shouldn't fail unless process already terminated (which can happen since
                    # if we didn't use SUSPENDED there's an inherent race here)
                    if win32process.GetExitCodeProcess(
                            self.__hProcess) == win32con.STILL_ACTIVE:
                        log.warning(
                            'Failed to associate process %s with new job: %s (this may prevent automatic cleanup of child processes)'
                            % (self, e))

                    # force use of TerminateProcess not TerminateJobObject if this failed
                    self.__job = None

                if (dwCreationFlags & win32con.CREATE_SUSPENDED) != 0:
                    win32process.ResumeThread(self.__hThread)
            finally:
                win32file.CloseHandle(hStdin_r)
                win32file.CloseHandle(hStdout)
                win32file.CloseHandle(hStderr)

            # set the handle to the stdin of the process
            self.__stdin = hStdin
Example #16
0
    def __init__(self, reactor, protocol, command, args, environment, path):
        _pollingfile._PollingTimer.__init__(self, reactor)
        self.protocol = protocol

        # security attributes for pipes
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1

        # create the pipes which will connect to the secondary process
        self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0)
        self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0)
        hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0)

        win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT,
                                          None, None)

        # set the info structure for the new process.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdOutput = hStdoutW
        StartupInfo.hStdError = hStderrW
        StartupInfo.hStdInput = hStdinR
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

        # Create new handles whose inheritance property is false
        pid = win32api.GetCurrentProcess()

        tmp = win32api.DuplicateHandle(pid, self.hStdoutR, pid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdoutR)
        self.hStdoutR = tmp

        tmp = win32api.DuplicateHandle(pid, self.hStderrR, pid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStderrR)
        self.hStderrR = tmp

        tmp = win32api.DuplicateHandle(pid, self.hStdinW, pid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdinW)
        self.hStdinW = tmp

        # Add the specified environment to the current environment - this is
        # necessary because certain operations are only supported on Windows
        # if certain environment variables are present.
        env = os.environ.copy()
        env.update(environment or {})

        # create the process
        cmdline = ' '.join([cmdLineQuote(a) for a in args])
        # TODO: error detection here.
        self.hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(
            command, cmdline, None, None, 1, 0, env, path, StartupInfo)
        win32file.CloseHandle(hThread)

        # close handles which only the child will use
        win32file.CloseHandle(hStderrW)
        win32file.CloseHandle(hStdoutW)
        win32file.CloseHandle(hStdinR)

        self.closed = 0
        self.closedNotifies = 0

        # set up everything
        self.stdout = _pollingfile._PollableReadPipe(
            self.hStdoutR,
            lambda data: self.protocol.childDataReceived(1, data),
            self.outConnectionLost)

        self.stderr = _pollingfile._PollableReadPipe(
            self.hStderrR,
            lambda data: self.protocol.childDataReceived(2, data),
            self.errConnectionLost)

        self.stdin = _pollingfile._PollableWritePipe(self.hStdinW,
                                                     self.inConnectionLost)

        for pipewatcher in self.stdout, self.stderr, self.stdin:
            self._addPollableResource(pipewatcher)

        # notify protocol
        self.protocol.makeConnection(self)
Example #17
0
    def main(self, token):

        connection = Connection('localhost', port=5672)
        connection.open()
        session = connection.session(str(uuid4()))

        receiver = session.receiver('amq.topic')
        local_ip = socket.gethostbyname(socket.gethostname())
        localhost_name = platform.uname()[1]

        def make_inheritable(token):
            """Return a duplicate of handle, which is inheritable"""
            return win32api.DuplicateHandle(win32api.GetCurrentProcess(),
                                            token,
                                            win32api.GetCurrentProcess(), 0, 1,
                                            win32con.DUPLICATE_SAME_ACCESS)

        while True:
            message = receiver.fetch()
            session.acknowledge()
            sender = session.sender(message.reply_to)
            command = base64.b64decode(message.content)
            if command.startswith('winrs' or 'winrm') != True or command.find(
                    '-r:'
            ) == -1 or command.find('localhost') != -1 or command.find(
                    localhost_name) != -1 or command.find(local_ip) != -1:
                sender.send(
                    Message(
                        base64.b64encode(
                            'Commands against the proxy are not accepted')))
            else:
                #Start the process:

                # First let's create the communication pipes used by the process
                # we need to have the pipes inherit the rights from token
                stdin_read, stdin_write = win32pipe.CreatePipe(None, 0)
                stdin_read = make_inheritable(stdin_read)

                stdout_read, stdout_write = win32pipe.CreatePipe(None, 0)
                stdout_write = make_inheritable(stdout_write)

                stderr_read, stderr_write = win32pipe.CreatePipe(None, 0)
                stderr_write = make_inheritable(stderr_write)

                # Set start-up parameters the process will use.
                #Here we specify the pipes for input, output and error.
                si = win32process.STARTUPINFO()
                si.dwFlags = win32con.STARTF_USESTDHANDLES
                si.hStdInput = stdin_read
                si.hStdOutput = stdout_write
                si.hStdError = stderr_write

                procArgs = (
                    None,  # appName
                    command,  # commandLine
                    None,  # processAttributes
                    None,  # threadAttributes
                    1,  # bInheritHandles
                    0,  # dwCreationFlags
                    None,  # newEnvironment
                    None,  # currentDirectory
                    si)  # startupinfo

                # CreateProcessAsUser takes the first parameter the token,
                # this way the process will impersonate a user
                try:
                    hProcess, hThread, PId, TId = win32process.CreateProcessAsUser(
                        token, *procArgs)

                    hThread.Close()

                    if stdin_read is not None:
                        stdin_read.Close()
                    if stdout_write is not None:
                        stdout_write.Close()
                    if stderr_write is not None:
                        stderr_write.Close()

                    stdin_write = msvcrt.open_osfhandle(
                        stdin_write.Detach(), 0)
                    stdout_read = msvcrt.open_osfhandle(
                        stdout_read.Detach(), 0)
                    stderr_read = msvcrt.open_osfhandle(
                        stderr_read.Detach(), 0)

                    stdin_file = os.fdopen(stdin_write, 'wb', 0)
                    stdout_file = os.fdopen(stdout_read, 'rU', 0)
                    stderr_file = os.fdopen(stderr_read, 'rU', 0)

                    def readerthread(fh, buffer):
                        buffer.append(fh.read())

                    def translate_newlines(data):
                        data = data.replace("\r\n", "\n")
                        data = data.replace("\r", "\n")
                        return data

                    def wait():
                        """Wait for child process to terminate.  Returns returncode
                        attribute."""
                        win32event.WaitForSingleObject(hProcess,
                                                       win32event.INFINITE)
                        returncode = win32process.GetExitCodeProcess(hProcess)
                        return returncode

                    def communicate():

                        if stdout_file:
                            stdout = []
                            stdout_thread = threading.Thread(
                                target=readerthread,
                                args=(stdout_file, stdout))
                            stdout_thread.setDaemon(True)
                            stdout_thread.start()
                        if stderr_file:
                            stderr = []
                            stderr_thread = threading.Thread(
                                target=readerthread,
                                args=(stderr_file, stderr))
                            stderr_thread.setDaemon(True)
                            stderr_thread.start()

                        stdin_file.close()

                        if stdout_file:
                            stdout_thread.join()
                        if stderr_file:
                            stderr_thread.join()

                        if stdout is not None:
                            stdout = stdout[0]
                        if stderr is not None:
                            stderr = stderr[0]

                        if stdout:
                            stdout = translate_newlines(stdout)
                        if stderr:
                            stderr = translate_newlines(stderr)

                        return_code = wait()
                        return (stdout, stderr, return_code)

                    ret_stdout, ret_stderr, retcode = communicate()

                    result = Message(base64.b64encode(str(ret_stdout)))
                    result.properties["retcode"] = base64.b64encode(
                        str(retcode))
                    if ret_stderr:
                        result.properties["stderr"] = base64.b64encode(
                            str(ret_stderr))
                    else:
                        result.properties["stderr"] = base64.b64encode('')

                    sender.send(result)

                except Exception as exception_message:
                    result = Message(base64.b64encode(''))
                    result.properties["retcode"] = base64.b64encode(
                        str(exception_message[0]))
                    result.properties["stderr"] = base64.b64encode(
                        str(exception_message[2]))

                    sender.send(result)
Example #18
0
    def __init__(self, reactor, protocol, command, args, environment, path):
        """
        Create a new child process.
        """
        _pollingfile._PollingTimer.__init__(self, reactor)
        BaseProcess.__init__(self, protocol)

        # security attributes for pipes
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1

        # create the pipes which will connect to the secondary process
        self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0)
        self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0)
        hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0)

        win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT,
                                          None, None)

        # set the info structure for the new process.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdOutput = hStdoutW
        StartupInfo.hStdError = hStderrW
        StartupInfo.hStdInput = hStdinR
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

        # Create new handles whose inheritance property is false
        currentPid = win32api.GetCurrentProcess()

        tmp = win32api.DuplicateHandle(currentPid, self.hStdoutR, currentPid,
                                       0, 0, win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdoutR)
        self.hStdoutR = tmp

        tmp = win32api.DuplicateHandle(currentPid, self.hStderrR, currentPid,
                                       0, 0, win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStderrR)
        self.hStderrR = tmp

        tmp = win32api.DuplicateHandle(currentPid, self.hStdinW, currentPid, 0,
                                       0, win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdinW)
        self.hStdinW = tmp

        # Add the specified environment to the current environment - this is
        # necessary because certain operations are only supported on Windows
        # if certain environment variables are present.

        env = os.environ.copy()
        env.update(environment or {})
        env = {
            os.fsdecode(key): os.fsdecode(value)
            for key, value in env.items()
        }

        # Make sure all the arguments are Unicode.
        args = [os.fsdecode(x) for x in args]

        cmdline = quoteArguments(args)

        # The command, too, needs to be Unicode, if it is a value.
        command = os.fsdecode(command) if command else command
        path = os.fsdecode(path) if path else path

        # TODO: error detection here.  See #2787 and #4184.
        def doCreate():
            flags = win32con.CREATE_NO_WINDOW
            self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess(
                command, cmdline, None, None, 1, flags, env, path, StartupInfo)

        try:
            doCreate()
        except pywintypes.error as pwte:
            if not _invalidWin32App(pwte):
                # This behavior isn't _really_ documented, but let's make it
                # consistent with the behavior that is documented.
                raise OSError(pwte)
            else:
                # look for a shebang line.  Insert the original 'command'
                # (actually a script) into the new arguments list.
                sheb = _findShebang(command)
                if sheb is None:
                    raise OSError("%r is neither a Windows executable, "
                                  "nor a script with a shebang line" % command)
                else:
                    args = list(args)
                    args.insert(0, command)
                    cmdline = quoteArguments(args)
                    origcmd = command
                    command = sheb
                    try:
                        # Let's try again.
                        doCreate()
                    except pywintypes.error as pwte2:
                        # d'oh, failed again!
                        if _invalidWin32App(pwte2):
                            raise OSError("%r has an invalid shebang line: "
                                          "%r is not a valid executable" %
                                          (origcmd, sheb))
                        raise OSError(pwte2)

        # close handles which only the child will use
        win32file.CloseHandle(hStderrW)
        win32file.CloseHandle(hStdoutW)
        win32file.CloseHandle(hStdinR)

        # set up everything
        self.stdout = _pollingfile._PollableReadPipe(
            self.hStdoutR,
            lambda data: self.proto.childDataReceived(1, data),
            self.outConnectionLost,
        )

        self.stderr = _pollingfile._PollableReadPipe(
            self.hStderrR,
            lambda data: self.proto.childDataReceived(2, data),
            self.errConnectionLost,
        )

        self.stdin = _pollingfile._PollableWritePipe(self.hStdinW,
                                                     self.inConnectionLost)

        for pipewatcher in self.stdout, self.stderr, self.stdin:
            self._addPollableResource(pipewatcher)

        # notify protocol
        self.proto.makeConnection(self)

        self._addPollableResource(_Reaper(self))
Example #19
0
    def __init__(self, reactor, protocol, command, args, environment, path):
        _pollingfile._PollingTimer.__init__(self, reactor)
        BaseProcess.__init__(self, protocol)

        # security attributes for pipes
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1

        # create the pipes which will connect to the secondary process
        self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0)
        self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0)
        hStdinR,  self.hStdinW  = win32pipe.CreatePipe(sAttrs, 0)

        win32pipe.SetNamedPipeHandleState(self.hStdinW,
                                          win32pipe.PIPE_NOWAIT,
                                          None,
                                          None)

        # set the info structure for the new process.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdOutput = hStdoutW
        StartupInfo.hStdError  = hStderrW
        StartupInfo.hStdInput  = hStdinR
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

        # Create new handles whose inheritance property is false
        currentPid = win32api.GetCurrentProcess()

        tmp = win32api.DuplicateHandle(currentPid, self.hStdoutR, currentPid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdoutR)
        self.hStdoutR = tmp

        tmp = win32api.DuplicateHandle(currentPid, self.hStderrR, currentPid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStderrR)
        self.hStderrR = tmp

        tmp = win32api.DuplicateHandle(currentPid, self.hStdinW, currentPid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdinW)
        self.hStdinW = tmp

        # Add the specified environment to the current environment - this is
        # necessary because certain operations are only supported on Windows
        # if certain environment variables are present.

        env = os.environ.copy()
        env.update(environment or {})

        cmdline = quoteArguments(args)
        # TODO: error detection here.
        def doCreate():
            self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess(
                command, cmdline, None, None, 1, 0, env, path, StartupInfo)
        try:
            doCreate()
        except pywintypes.error, pwte:
            if not _invalidWin32App(pwte):
                # This behavior isn't _really_ documented, but let's make it
                # consistent with the behavior that is documented.
                raise OSError(pwte)
            else:
                # look for a shebang line.  Insert the original 'command'
                # (actually a script) into the new arguments list.
                sheb = _findShebang(command)
                if sheb is None:
                    raise OSError(
                        "%r is neither a Windows executable, "
                        "nor a script with a shebang line" % command)
                else:
                    args = list(args)
                    args.insert(0, command)
                    cmdline = quoteArguments(args)
                    origcmd = command
                    command = sheb
                    try:
                        # Let's try again.
                        doCreate()
                    except pywintypes.error, pwte2:
                        # d'oh, failed again!
                        if _invalidWin32App(pwte2):
                            raise OSError(
                                "%r has an invalid shebang line: "
                                "%r is not a valid executable" % (
                                    origcmd, sheb))
                        raise OSError(pwte2)
Example #20
0
def CreatePipe():
    pp= win32pipe.CreatePipe(_sa,0)
    win32file.WriteFile(pp[1],"@")
    return pp
Example #21
0
 def newPipe(self):
     sa = win32security.SECURITY_ATTRIBUTES()
     sa.bInheritHandle = True
     return win32pipe.CreatePipe(sa, 0)
Example #22
0
def runas(cmdLine, username, password=None, cwd=None):
    """
    Run a command as another user. If the process is running as an admin or
    system account this method does not require a password. Other non
    privileged accounts need to provide a password for the user to runas.
    Commands are run in with the highest level privileges possible for the
    account provided.
    """
    # Validate the domain and sid exist for the username
    username, domain = split_username(username)
    try:
        _, domain, _ = win32security.LookupAccountName(domain, username)
    except pywintypes.error as exc:
        message = win32api.FormatMessage(exc.winerror).rstrip("\n")
        raise CommandExecutionError(message)

    # Elevate the token from the current process
    access = win32security.TOKEN_QUERY | win32security.TOKEN_ADJUST_PRIVILEGES
    th = win32security.OpenProcessToken(win32api.GetCurrentProcess(), access)
    salt.platform.win.elevate_token(th)

    # Try to impersonate the SYSTEM user. This process needs to be running as a
    # user who as been granted the SeImpersonatePrivilege, Administrator
    # accounts have this permission by default.
    try:
        impersonation_token = salt.platform.win.impersonate_sid(
            salt.platform.win.SYSTEM_SID,
            session_id=0,
            privs=["SeTcbPrivilege"],
        )
    except OSError:  # pylint: disable=undefined-variable
        log.debug("Unable to impersonate SYSTEM user")
        impersonation_token = None
        win32api.CloseHandle(th)

    # Impersonation of the SYSTEM user failed. Fallback to an un-privileged
    # runas.
    if not impersonation_token:
        log.debug("No impersonation token, using unprivileged runas")
        return runas_unpriv(cmdLine, username, password, cwd)

    if domain == "NT AUTHORITY":
        # Logon as a system level account, SYSTEM, LOCAL SERVICE, or NETWORK
        # SERVICE.
        user_token = win32security.LogonUser(
            username,
            domain,
            "",
            win32con.LOGON32_LOGON_SERVICE,
            win32con.LOGON32_PROVIDER_DEFAULT,
        )
    elif password:
        # Login with a password.
        user_token = win32security.LogonUser(
            username,
            domain,
            password,
            win32con.LOGON32_LOGON_INTERACTIVE,
            win32con.LOGON32_PROVIDER_DEFAULT,
        )
    else:
        # Login without a password. This always returns an elevated token.
        user_token = salt.platform.win.logon_msv1_s4u(username).Token

    # Get a linked user token to elevate if needed
    elevation_type = win32security.GetTokenInformation(
        user_token, win32security.TokenElevationType)
    if elevation_type > 1:
        user_token = win32security.GetTokenInformation(
            user_token, win32security.TokenLinkedToken)

    # Elevate the user token
    salt.platform.win.elevate_token(user_token)

    # Make sure the user's token has access to a windows station and desktop
    salt.platform.win.grant_winsta_and_desktop(user_token)

    # Create pipes for standard in, out and error streams
    security_attributes = win32security.SECURITY_ATTRIBUTES()
    security_attributes.bInheritHandle = 1

    stdin_read, stdin_write = win32pipe.CreatePipe(security_attributes, 0)
    stdin_read = salt.platform.win.make_inheritable(stdin_read)

    stdout_read, stdout_write = win32pipe.CreatePipe(security_attributes, 0)
    stdout_write = salt.platform.win.make_inheritable(stdout_write)

    stderr_read, stderr_write = win32pipe.CreatePipe(security_attributes, 0)
    stderr_write = salt.platform.win.make_inheritable(stderr_write)

    # Run the process without showing a window.
    creationflags = (win32process.CREATE_NO_WINDOW
                     | win32process.CREATE_NEW_CONSOLE
                     | win32process.CREATE_SUSPENDED)

    startup_info = salt.platform.win.STARTUPINFO(
        dwFlags=win32con.STARTF_USESTDHANDLES,
        hStdInput=stdin_read.handle,
        hStdOutput=stdout_write.handle,
        hStdError=stderr_write.handle,
    )

    # Create the environment for the user
    env = create_env(user_token, False)

    hProcess = None
    try:
        # Start the process in a suspended state.
        process_info = salt.platform.win.CreateProcessWithTokenW(
            int(user_token),
            logonflags=1,
            applicationname=None,
            commandline=cmdLine,
            currentdirectory=cwd,
            creationflags=creationflags,
            startupinfo=startup_info,
            environment=env,
        )

        hProcess = process_info.hProcess
        hThread = process_info.hThread
        dwProcessId = process_info.dwProcessId
        dwThreadId = process_info.dwThreadId

        # We don't use these so let's close the handle
        salt.platform.win.kernel32.CloseHandle(stdin_write.handle)
        salt.platform.win.kernel32.CloseHandle(stdout_write.handle)
        salt.platform.win.kernel32.CloseHandle(stderr_write.handle)

        ret = {"pid": dwProcessId}
        # Resume the process
        psutil.Process(dwProcessId).resume()

        # Wait for the process to exit and get its return code.
        if (win32event.WaitForSingleObject(
                hProcess, win32event.INFINITE) == win32con.WAIT_OBJECT_0):
            exitcode = win32process.GetExitCodeProcess(hProcess)
            ret["retcode"] = exitcode

        # Read standard out
        fd_out = msvcrt.open_osfhandle(stdout_read.handle,
                                       os.O_RDONLY | os.O_TEXT)
        with os.fdopen(fd_out, "r") as f_out:
            stdout = f_out.read()
            ret["stdout"] = stdout

        # Read standard error
        fd_err = msvcrt.open_osfhandle(stderr_read.handle,
                                       os.O_RDONLY | os.O_TEXT)
        with os.fdopen(fd_err, "r") as f_err:
            stderr = f_err.read()
            ret["stderr"] = stderr
    finally:
        if hProcess is not None:
            salt.platform.win.kernel32.CloseHandle(hProcess)
        win32api.CloseHandle(th)
        win32api.CloseHandle(user_token)
        if impersonation_token:
            win32security.RevertToSelf()
        win32api.CloseHandle(impersonation_token)

    return ret
Example #23
0
    def __init__(self, cmd, mode='t', cwd=None, env=None, avatar=None):
        log.info("Process.__init__(cmd=%r, mode=%r, cwd=%r, env=%r)", cmd,
                 mode, cwd, env)
        # Keep a reference to ensure it is around for this object's destruction.
        self.__log = log
        self.mCmd = cmd
        self.mCwd = cwd
        self.mEnv = env
        self.mAvatar = avatar
        self.mMode = mode
        if self.mMode not in ('t', 'b'):
            raise ProcessError("'mode' must be 't' or 'b'.")
        self.mClosed = False

        si = win32process.STARTUPINFO()
        si.dwFlags = (win32con.STARTF_USESTDHANDLES
                      ^ win32con.STARTF_USESHOWWINDOW)

        # Create pipes for std handles.
        # (Set the bInheritHandle flag so pipe handles are inherited.)
        saAttr = pywintypes.SECURITY_ATTRIBUTES()
        saAttr.bInheritHandle = 1
        #XXX Should maybe try with os.pipe. Dunno what that does for
        #    inheritability though.
        hChildStdinRd, hChildStdinWr = win32pipe.CreatePipe(saAttr, 0)
        hChildStdoutRd, hChildStdoutWr = win32pipe.CreatePipe(saAttr, 0)
        hChildStderrRd, hChildStderrWr = win32pipe.CreatePipe(saAttr, 0)

        try:
            # Duplicate the parent ends of the pipes so they are not
            # inherited.
            hChildStdinWrDup = win32api.DuplicateHandle(
                win32api.GetCurrentProcess(),
                hChildStdinWr,
                win32api.GetCurrentProcess(),
                0,
                0,  # not inherited
                DUPLICATE_SAME_ACCESS)
            win32api.CloseHandle(hChildStdinWr)
            self._hChildStdinWr = hChildStdinWrDup
            hChildStdoutRdDup = win32api.DuplicateHandle(
                win32api.GetCurrentProcess(),
                hChildStdoutRd,
                win32api.GetCurrentProcess(),
                0,
                0,  # not inherited
                DUPLICATE_SAME_ACCESS)
            win32api.CloseHandle(hChildStdoutRd)
            self._hChildStdoutRd = hChildStdoutRdDup
            hChildStderrRdDup = win32api.DuplicateHandle(
                win32api.GetCurrentProcess(),
                hChildStderrRd,
                win32api.GetCurrentProcess(),
                0,
                0,  # not inherited
                DUPLICATE_SAME_ACCESS)
            win32api.CloseHandle(hChildStderrRd)
            self._hChildStderrRd = hChildStderrRdDup

            # Set the translation mode and buffering.
            self._mode = 't'
            if self._mode == 't':
                flags = os.O_TEXT
            else:
                flags = 0
            fdChildStdinWr = msvcrt.open_osfhandle(self._hChildStdinWr, flags)
            fdChildStdoutRd = msvcrt.open_osfhandle(self._hChildStdoutRd,
                                                    flags)
            fdChildStderrRd = msvcrt.open_osfhandle(self._hChildStderrRd,
                                                    flags)

            self.stdin = _FileWrapper(descriptor=fdChildStdinWr,
                                      handle=self._hChildStdinWr)
            logres.info("[%s] Process._start(): create child stdin: %r",
                        id(self), self.stdin)
            self.stdout = _FileWrapper(descriptor=fdChildStdoutRd,
                                       handle=self._hChildStdoutRd)
            logres.info("[%s] Process._start(): create child stdout: %r",
                        id(self), self.stdout)
            self.stderr = _FileWrapper(descriptor=fdChildStderrRd,
                                       handle=self._hChildStderrRd)
            logres.info("[%s] Process._start(): create child stderr: %r",
                        id(self), self.stderr)

            si.hStdInput = hChildStdinRd
            si.hStdOutput = hChildStdoutWr
            si.hStdError = hChildStderrWr
            #si.wShowWindow = show
            si.wShowWindow = 1
            si.dwFlags |= win32process.STARTF_USESTDHANDLES

            creation_flags = win32process.CREATE_NEW_CONSOLE
            (self.mProcess, self.mThread, self.mProcessId, self.mThreadId)\
               = _safeCreateProcess(
                  self.mAvatar,    # Avatar
                  None,            # App name
                  cmd,             # Command
                  None,            # Process security attribs
                  None,            # Primary thread security attribs
                  1,               # Handles are inherited
                  creation_flags,  # Creation Flags
                  self.mEnv,       # Environment
                  self.mCwd,       # Current Working Directory
                  si)              # STARTUPINFO

        finally:
            # Close child ends of pipes on the parent's side (the
            # parent's ends of the pipe are closed in the _FileWrappers.)
            win32file.CloseHandle(hChildStdinRd)
            win32file.CloseHandle(hChildStdoutWr)
            win32file.CloseHandle(hChildStderrWr)
Example #24
0
    def run(self, cmdline):
        # security attributes for pipes
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1

        # create pipes
        hStdin_r, self.hStdin_w = win32pipe.CreatePipe(sAttrs, 0)
        self.hStdout_r, hStdout_w = win32pipe.CreatePipe(sAttrs, 0)
        self.hStderr_r, hStderr_w = win32pipe.CreatePipe(sAttrs, 0)

        # set the info structure for the new process.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdInput = hStdin_r
        StartupInfo.hStdOutput = hStdout_w
        StartupInfo.hStdError = hStderr_w
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES
        # Mark doesn't support wShowWindow yet.
        # StartupInfo.dwFlags = StartupInfo.dwFlags | win32process.STARTF_USESHOWWINDOW
        # StartupInfo.wShowWindow = win32con.SW_HIDE

        # Create new output read handles and the input write handle. Set
        # the inheritance properties to FALSE. Otherwise, the child inherits
        # the these handles; resulting in non-closeable handles to the pipes
        # being created.
        pid = win32api.GetCurrentProcess()

        tmp = win32api.DuplicateHandle(
            pid,
            self.hStdin_w,
            pid,
            0,
            0,  # non-inheritable!!
            win32con.DUPLICATE_SAME_ACCESS)
        # Close the inhertible version of the handle
        win32file.CloseHandle(self.hStdin_w)
        self.hStdin_w = tmp
        tmp = win32api.DuplicateHandle(
            pid,
            self.hStdout_r,
            pid,
            0,
            0,  # non-inheritable!
            win32con.DUPLICATE_SAME_ACCESS)
        # Close the inhertible version of the handle
        win32file.CloseHandle(self.hStdout_r)
        self.hStdout_r = tmp

        # start the process.
        hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(
            None,  # program
            cmdline,  # command line
            None,  # process security attributes
            None,  # thread attributes
            1,  # inherit handles, or USESTDHANDLES won't work.
            # creation flags. Don't access the console.
            0,  # Don't need anything here.
            # If you're in a GUI app, you should use
            # CREATE_NEW_CONSOLE here, or any subprocesses
            # might fall victim to the problem described in:
            # KB article: Q156755, cmd.exe requires
            # an NT console in order to perform redirection..
            None,  # no new environment
            None,  # current directory (stay where we are)
            StartupInfo)
        # normally, we would save the pid etc. here...

        # Child is launched. Close the parents copy of those pipe handles
        # that only the child should have open.
        # You need to make sure that no handles to the write end of the
        # output pipe are maintained in this process or else the pipe will
        # not close when the child process exits and the ReadFile will hang.
        win32file.CloseHandle(hStderr_w)
        win32file.CloseHandle(hStdout_w)
        win32file.CloseHandle(hStdin_r)

        self.stdin = os.fdopen(msvcrt.open_osfhandle(self.hStdin_w, 0), "wb")
        self.stdin.write('hmmmmm\r\n')
        self.stdin.flush()
        self.stdin.close()

        self.stdout = os.fdopen(msvcrt.open_osfhandle(self.hStdout_r, 0), "rb")
        print("Read on stdout: ", repr(self.stdout.read()))

        self.stderr = os.fdopen(msvcrt.open_osfhandle(self.hStderr_r, 0), "rb")
        print("Read on stderr: ", repr(self.stderr.read()))
Example #25
0
def runas_system(cmd, username, password):
    # This only works as system, when salt is running as a service for example

    # Check for a domain
    domain = '.'
    if '@' in username:
        username, domain = username.split('@')
    if '\\' in username:
        domain, username = username.split('\\')

    # Load User and Get Token
    token = win32security.LogonUser(username, domain, password,
                                    win32con.LOGON32_LOGON_INTERACTIVE,
                                    win32con.LOGON32_PROVIDER_DEFAULT)

    # Load the User Profile
    handle_reg = win32profile.LoadUserProfile(token, {'UserName': username})

    try:
        # Get Unrestricted Token (UAC) if this is an Admin Account
        elevated_token = win32security.GetTokenInformation(
            token, win32security.TokenLinkedToken)

        # Get list of privileges this token contains
        privileges = win32security.GetTokenInformation(
            elevated_token, win32security.TokenPrivileges)

        # Create a set of all privileges to be enabled
        enable_privs = set()
        for luid, flags in privileges:
            enable_privs.add((luid, win32con.SE_PRIVILEGE_ENABLED))

        # Enable the privileges
        win32security.AdjustTokenPrivileges(elevated_token, 0, enable_privs)

    except win32security.error as exc:
        # User doesn't have admin, use existing token
        if exc[0] == winerror.ERROR_NO_SUCH_LOGON_SESSION \
                or exc[0] == winerror.ERROR_PRIVILEGE_NOT_HELD:
            elevated_token = token
        else:
            raise

    # Get Security Attributes
    security_attributes = win32security.SECURITY_ATTRIBUTES()
    security_attributes.bInheritHandle = 1

    # Create a pipe to set as stdout in the child. The write handle needs to be
    # inheritable.
    stdin_read, stdin_write = win32pipe.CreatePipe(security_attributes, 0)
    stdin_read = make_inheritable(stdin_read)

    stdout_read, stdout_write = win32pipe.CreatePipe(security_attributes, 0)
    stdout_write = make_inheritable(stdout_write)

    stderr_read, stderr_write = win32pipe.CreatePipe(security_attributes, 0)
    stderr_write = make_inheritable(stderr_write)

    # Get startup info structure
    startup_info = win32process.STARTUPINFO()
    startup_info.dwFlags = win32con.STARTF_USESTDHANDLES
    startup_info.hStdInput = stdin_read
    startup_info.hStdOutput = stdout_write
    startup_info.hStdError = stderr_write

    # Get User Environment
    user_environment = win32profile.CreateEnvironmentBlock(token, False)

    # Build command
    cmd = 'cmd /c {0}'.format(cmd)

    # Run command and return process info structure
    procArgs = (None, cmd, security_attributes, security_attributes, 1, 0,
                user_environment, None, startup_info)

    hProcess, hThread, PId, TId = \
        win32process.CreateProcessAsUser(elevated_token, *procArgs)

    if stdin_read is not None:
        stdin_read.Close()
    if stdout_write is not None:
        stdout_write.Close()
    if stderr_write is not None:
        stderr_write.Close()
    hThread.Close()

    # Initialize ret and set first element
    ret = {'pid': PId}

    # Get Standard Out
    fd_out = msvcrt.open_osfhandle(stdout_read, os.O_RDONLY | os.O_TEXT)
    with os.fdopen(fd_out, 'r') as f_out:
        ret['stdout'] = f_out.read()

    # Get Standard Error
    fd_err = msvcrt.open_osfhandle(stderr_read, os.O_RDONLY | os.O_TEXT)
    with os.fdopen(fd_err, 'r') as f_err:
        ret['stderr'] = f_err.read()

    # Get Return Code
    if win32event.WaitForSingleObject(
            hProcess, win32event.INFINITE) == win32con.WAIT_OBJECT_0:
        exitcode = win32process.GetExitCodeProcess(hProcess)
        ret['retcode'] = exitcode

    # Close handle to process
    win32api.CloseHandle(hProcess)

    # Unload the User Profile
    win32profile.UnloadUserProfile(token, handle_reg)

    return ret
Example #26
0
def runas_system(cmd, username, password):
    # This only works as system, when salt is running as a service for example

    # Check for a domain
    domain = '.'
    if '@' in username:
        username, domain = username.split('@')
    if '\\' in username:
        domain, username = username.split('\\')

    # Get User Token
    token = win32security.LogonUser(username, domain, password,
                                    win32con.LOGON32_LOGON_INTERACTIVE,
                                    win32con.LOGON32_PROVIDER_DEFAULT)

    # Get Security Attributes
    security_attributes = win32security.SECURITY_ATTRIBUTES()
    security_attributes.bInheritHandle = 1

    # Create a pipe to set as stdout in the child. The write handle needs to be
    # inheritable.
    stdin_read, stdin_write = win32pipe.CreatePipe(security_attributes, 0)
    stdin_read = make_inheritable(stdin_read)

    stdout_read, stdout_write = win32pipe.CreatePipe(security_attributes, 0)
    stdout_write = make_inheritable(stdout_write)

    stderr_read, stderr_write = win32pipe.CreatePipe(security_attributes, 0)
    stderr_write = make_inheritable(stderr_write)

    # Get startup info structure
    startup_info = win32process.STARTUPINFO()
    startup_info.dwFlags = win32con.STARTF_USESTDHANDLES
    startup_info.hStdInput = stdin_read
    startup_info.hStdOutput = stdout_write
    startup_info.hStdError = stderr_write

    # Get User Environment
    user_environment = win32profile.CreateEnvironmentBlock(token, False)

    # Build command
    cmd = 'cmd /c {0}'.format(cmd)

    # Run command and return process info structure
    procArgs = (None, cmd, security_attributes, security_attributes, 1, 0,
                user_environment, None, startup_info)

    hProcess, hThread, PId, TId = win32process.CreateProcessAsUser(
        token, *procArgs)

    if stdin_read is not None:
        stdin_read.Close()
    if stdout_write is not None:
        stdout_write.Close()
    if stderr_write is not None:
        stderr_write.Close()
    hThread.Close()

    # Initialize ret and set first element
    ret = {'pid': PId}

    # Get Standard Out
    fd_out = msvcrt.open_osfhandle(stdout_read, os.O_RDONLY | os.O_TEXT)
    with os.fdopen(fd_out, 'r') as f_out:
        ret['stdout'] = f_out.read()

    # Get Standard Error
    fd_err = msvcrt.open_osfhandle(stderr_read, os.O_RDONLY | os.O_TEXT)
    with os.fdopen(fd_err, 'r') as f_err:
        ret['stderr'] = f_err.read()

    # Get Return Code
    if win32event.WaitForSingleObject(
            hProcess, win32event.INFINITE) == win32con.WAIT_OBJECT_0:
        exitcode = win32process.GetExitCodeProcess(hProcess)
        ret['retcode'] = exitcode

    # Close handle to process
    win32api.CloseHandle(hProcess)

    return ret