Esempio n. 1
0
def openWindow():
    '''
   Attempts to open a window on the Winlogon desktop. This can also be
   used to just test opening a window on the Application desktop.

   NOTE: The Winlogon desktop part is not currently working with this
         example installed as an interactive service. It may be necessary
         instead to set this up as something started by a Winlogon
         Notification Package.
   '''
    logging.basicConfig(
        level=logging.DEBUG,
        format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
        datefmt='%m-%d %H:%M',
        filename=r'C:\temp\myapp.log',
        filemode='w')

    logging.debug("Starting")
    cur_winsta = win32service.GetProcessWindowStation()
    logging.debug("Got process window station")
    cur_desktop = win32service.GetThreadDesktop(win32api.GetCurrentThreadId())
    logging.debug("Got current desktop")

    try:
        new_winsta = win32service.OpenWindowStation(
            "winsta0", False, win32con.WINSTA_ACCESSCLIPBOARD
            | win32con.WINSTA_ACCESSGLOBALATOMS | win32con.WINSTA_CREATEDESKTOP
            | win32con.WINSTA_ENUMDESKTOPS | win32con.WINSTA_ENUMERATE
            | win32con.WINSTA_EXITWINDOWS | win32con.WINSTA_READATTRIBUTES
            | win32con.WINSTA_READSCREEN | win32con.WINSTA_WRITEATTRIBUTES)
        new_winsta.SetProcessWindowStation()

        desktop = win32service.OpenDesktop(
            "Winlogon", 0, False, win32con.DESKTOP_CREATEMENU
            | win32con.DESKTOP_CREATEWINDOW | win32con.DESKTOP_ENUMERATE
            | win32con.DESKTOP_HOOKCONTROL | win32con.DESKTOP_JOURNALPLAYBACK
            | win32con.DESKTOP_JOURNALRECORD | win32con.DESKTOP_READOBJECTS
            | win32con.DESKTOP_SWITCHDESKTOP | win32con.DESKTOP_WRITEOBJECTS)

        desktop.SetThreadDesktop()
        logging.debug("Running calculator")
        os.system("calc")
        logging.debug("Done")

    except:
        logging.debug("Caught exception:")
        logging.debug(sys.exc_info()[0])  # Print the exception type
        logging.debug(sys.exc_info()[1])  # Print the exception info

    cur_winsta.SetProcessWindowStation()
    cur_desktop.SetThreadDesktop()
    cur_desktop.CloseDesktop()
    cur_winsta.CloseWindowStation()

    if new_winsta is not None:
        new_winsta.CloseWindowStation()

    if desktop is not None:
        desktop.CloseDesktop()
Esempio n. 2
0
def icon_wndproc(hwnd, msg, wp, lp):
    """Window proc for the tray icons"""
    if lp == win32con.WM_LBUTTONDOWN:
        ## popup menu won't disappear if you don't do this
        win32gui.SetForegroundWindow(hwnd)

        curr_desktop = win32service.OpenInputDesktop(0, True, win32con.MAXIMUM_ALLOWED)
        curr_desktop_name = win32service.GetUserObjectInformation(
            curr_desktop, win32con.UOI_NAME
        )
        winsta = win32service.GetProcessWindowStation()
        desktops = winsta.EnumDesktops()
        m = win32gui.CreatePopupMenu()
        desktop_cnt = len(desktops)
        ## *don't* create an item 0
        for d in range(1, desktop_cnt + 1):
            mf_flags = win32con.MF_STRING
            ## if you switch to winlogon yourself, there's nothing there and you're stuck
            if desktops[d - 1].lower() in ("winlogon", "disconnect"):
                mf_flags = mf_flags | win32con.MF_GRAYED | win32con.MF_DISABLED
            if desktops[d - 1] == curr_desktop_name:
                mf_flags = mf_flags | win32con.MF_CHECKED
            win32gui.AppendMenu(m, mf_flags, d, desktops[d - 1])
        win32gui.AppendMenu(m, win32con.MF_STRING, desktop_cnt + 1, "Create new ...")
        win32gui.AppendMenu(m, win32con.MF_STRING, desktop_cnt + 2, "Exit")

        x, y = win32gui.GetCursorPos()
        d = win32gui.TrackPopupMenu(
            m,
            win32con.TPM_LEFTBUTTON | win32con.TPM_RETURNCMD | win32con.TPM_NONOTIFY,
            x,
            y,
            0,
            hwnd,
            None,
        )
        win32gui.PumpWaitingMessages()
        win32gui.DestroyMenu(m)
        if d == desktop_cnt + 1:  ## Create new
            get_new_desktop_name(hwnd)
        elif d == desktop_cnt + 2:  ## Exit
            win32gui.PostQuitMessage(0)
            win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, window_info[hwnd])
            del window_info[hwnd]
            origin_desktop.SwitchDesktop()
        elif d > 0:
            hdesk = win32service.OpenDesktop(
                desktops[d - 1], 0, 0, win32con.MAXIMUM_ALLOWED
            )
            hdesk.SwitchDesktop()
        return 0
    else:
        return win32gui.DefWindowProc(hwnd, msg, wp, lp)
Esempio n. 3
0
def _CreateAltDesktop(window_station, name: str):
    """Creates an alternate desktop.

  Args:
    window_station: Handle to window station.
    name: Name of the desktop.

  Returns:
    A handle to the alternate desktop.
  """
    current_desktop = win32service.GetThreadDesktop(
        win32api.GetCurrentThreadId())
    security_attributes = _GetSecurityAttributes(current_desktop)
    current_station = win32service.GetProcessWindowStation()
    window_station.SetProcessWindowStation()
    desktop = win32service.CreateDesktop(
        name, 0, (DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS
                  | ntsecuritycon.READ_CONTROL
                  | ntsecuritycon.WRITE_DAC | ntsecuritycon.WRITE_OWNER),
        security_attributes)
    current_station.SetProcessWindowStation()
    return desktop
Esempio n. 4
0
def _CreateWindowStation(name: Optional[str], access: int):
    """Creates a window station.

  Args:
    name: Name of the window station.
    access: The type of access the returned handle has to the window station.

  Returns:
    A handle to the created window station.
  """
    current_station = win32service.GetProcessWindowStation()
    security_attributes = _GetSecurityAttributes(current_station)
    # The try/except originates from the Chromium sandbox code.
    # They try to create the window station with various level of privilege.
    try:
        return win32service.CreateWindowStation(
            name, 0, access | win32file.GENERIC_READ | WINSTA_CREATEDESKTOP,
            security_attributes)
    except pywintypes.error as e:
        if e.winerror != winerror.ERROR_ACCESS_DENIED:
            raise
        return win32service.CreateWindowStation(
            name, 0, access | WINSTA_READATTRIBUTES | WINSTA_CREATEDESKTOP,
            security_attributes)
Esempio n. 5
0
    def __init__(self,
                 userHandle,
                 userSID,
                 userName,
                 domain,
                 forceSidAdd=False):
        """
      Constructs a Windows-specific user perspective used to access the
      event manager.
      @pre userHandle is a valid PyHANDLE object.
      @param userHandle  Handle to the user's authentication.
      @param userSID     The SID for the user represented by this avatar.
      @param userName    The name of the user represented by this avatar.
      @param domain      The domain for the user.
      @param forceSidAdd Causes the given ID to be added to the window
                         station and desktop ACLs even if it is already
                         present. Use with caution!
      """
        assert (userHandle is not None)

        UserPerspective.__init__(self)

        self.mUserHandle = userHandle
        self.mUserSID = userSID
        self.mWinsta = None
        self.mDesktop = None
        self.mAddedHandles = []

        self.mLogger = logging.getLogger('daemon.WindowsAvatar')

        # Save the current window station for later.
        cur_winsta = win32service.GetProcessWindowStation()

        # Open window station winsta0 and make it the window station for this
        # process.
        winsta_flags = win32con.READ_CONTROL | win32con.WRITE_DAC
        new_winsta = win32service.OpenWindowStation("winsta0", False,
                                                    winsta_flags)
        new_winsta.SetProcessWindowStation()

        # Get a handle to the default desktop so that we can change its access
        # control list.
        desktop_flags = win32con.READ_CONTROL         | \
                        win32con.WRITE_DAC            | \
                        win32con.DESKTOP_WRITEOBJECTS | \
                        win32con.DESKTOP_READOBJECTS
        desktop = win32service.OpenDesktop("default", 0, False, desktop_flags)

        # If user_sid is not already among the SIDs who have access to
        # new_winsta, then add it now. It will be removed in logout().
        if forceSidAdd or not windesktop.handleHasSID(new_winsta,
                                                      self.mUserSID):
            windesktop.addUserToWindowStation(new_winsta, self.mUserSID)
            self.mAddedHandles.append(new_winsta)
            self.mLogger.debug("Added SID to new_winsta")

        # If user_sid is not already among the SIDs who have access to desktop,
        # then add it now. It will be removed in logout().
        if forceSidAdd or not windesktop.handleHasSID(desktop, self.mUserSID):
            windesktop.addUserToDesktop(desktop, self.mUserSID)
            self.mAddedHandles.append(desktop)
            self.mLogger.debug("Added SID to desktop")

        cur_winsta.SetProcessWindowStation()

        self.mWinsta = new_winsta
        self.mDesktop = desktop

        #      (username, domain, acct_type) = \
        #         win32security.LookupAccountSid(dc_name, self.mUserSID)
        #      self.mUserName = username
        #      self.mDomain   = domain
        self.mUserName = userName
        self.mDomain = domain

        # Get name of domain controller.
        try:
            dc_name = win32net.NetGetDCName()
        except:
            dc_name = None

        user_info_4 = win32net.NetUserGetInfo(dc_name, self.mUserName, 4)
        profilepath = user_info_4['profile']
        # LoadUserProfile apparently doesn't like an empty string
        if not profilepath:
            profilepath = None

        try:
            # Leave Flags in since 2.3 still chokes on some types of optional
            # keyword args
            self.mUserProfile = win32profile.LoadUserProfile(
                self.mUserHandle, {
                    'UserName': self.mUserName,
                    'Flags': 0,
                    'ProfilePath': profilepath
                })
            self.mLogger.debug("self.mUserProfile = %s" %
                               str(self.mUserProfile))
            self.mLogger.info("Loaded profile %s" % profilepath)
        except pywintypes.error, error:
            self.mLogger.error("Error loading profile: %s" % error)
Esempio n. 6
0
def runCommandAsOtherUser():
    '''
   Runs a command (C:\Python24\python.exe C:\read_files.py) as another
   user (as determined by the global variables USERNAME, DOMAIN, and
   PASSWORD). The python.exe process will be owned by USERNAME and have
   access to that user's files. Hence, for this test to be useful, the
   value in LOG_FILE should be a file to which only DOMAIN\USERNAME has
   write access, and TEST_DIR should be a directory from which only
   DOMAIN\USERNAME can read.
   '''
    logging.basicConfig(
        level=logging.DEBUG,
        format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
        datefmt='%m-%d %H:%M',
        filename=r'C:\temp\myapp2.log',
        filemode='w')

    logging.debug("Starting")

    try:
        cur_winsta = win32service.GetProcessWindowStation()
        logging.debug("Got process window station")

        new_winsta = win32service.OpenWindowStation(
            "winsta0", False, win32con.READ_CONTROL | win32con.WRITE_DAC)
        new_winsta.SetProcessWindowStation()

        desktop = win32service.OpenDesktop(
            "default", 0, False, win32con.READ_CONTROL | win32con.WRITE_DAC
            | win32con.DESKTOP_WRITEOBJECTS | win32con.DESKTOP_READOBJECTS)

        handle = win32security.LogonUser(USERNAME, DOMAIN, PASSWORD,
                                         win32con.LOGON32_LOGON_INTERACTIVE,
                                         win32con.LOGON32_PROVIDER_DEFAULT)

        tic = win32security.GetTokenInformation(handle,
                                                ntsecuritycon.TokenGroups)
        user_sid = None
        for sid, flags in tic:
            if flags & win32con.SE_GROUP_LOGON_ID:
                user_sid = sid
                break

        if user_sid is None:
            raise Exception('Failed to determine logon ID')

        winsta_ace_indices = addUserToWindowStation(new_winsta, user_sid)
        desktop_ace_indices = addUserToDesktop(desktop, user_sid)

        si = win32process.STARTUPINFO()
        # Copied from process.py. I don't know what these should be in general.
        si.dwFlags = win32process.STARTF_USESHOWWINDOW ^ win32con.STARTF_USESTDHANDLES
        si.wShowWindow = win32con.SW_NORMAL
        si.lpDesktop = r"winsta0\default"
        create_flags = win32process.CREATE_NEW_CONSOLE

        win32security.ImpersonateLoggedOnUser(handle)

        # Hard-coded paths are bad except that this is just a proof-of-concept
        # service.
        # This command validates that the process has the access rights of the
        # logged on (impersonated) user.
        #      logging.debug('LOG_FILE = ' + LOG_FILE)
        #      logging.debug('TEST_DIR = ' + TEST_DIR)
        #      (process, thread, proc_id, thread_id) = \
        #         win32process.CreateProcessAsUser(handle, None,
        #                                          r"C:\Python24\python.exe C:\read_files.py %s %s" % (LOG_FILE, TEST_DIR),
        #                                          None, None, 1, create_flags, None,
        #                                          None, si)

        # This command validates that the process is allowed to open a window
        # on the current desktop.
        (process, thread, proc_id, thread_id) = \
           win32process.CreateProcessAsUser(handle, None,
                                            r"C:\windows\system32\calc.exe",
                                            None, None, 1, create_flags, None,
                                            None, si)

        cur_winsta.SetProcessWindowStation()

        win32security.RevertToSelf()
        handle.Close()

        logging.debug("Waiting for completion")
        win32event.WaitForSingleObject(process, win32event.INFINITE)
        logging.debug("Done!")

        logging.debug("Removing added ACEs from new_winsta")
        removeACEs(new_winsta, winsta_ace_indices)
        logging.debug("Removing added ACEs from desktop")
        removeACEs(desktop, desktop_ace_indices)

        new_winsta.CloseWindowStation()
        desktop.CloseDesktop()
    except TypeError, ex:
        logging.debug(ex)