I'm writing a framework for OS X that may be used by applications with or without a connection to the OS X WindowServer (i.e. both GUI apps and command-line apps run via, e.g. an ssh session). One class in the framework is for tracking files in the user's home folder across netework and mobile home directories (on OS X, users can have their home directory served via AFP from a server--a "network home directory"--or have the same home folder syncrhonized for offline access--a "mobile home directory").
Because I need to track files across filesystems, we've chosen to use relative paths, rather than OS X aliases (or the 10.6 NSURL bookmarks). When a file can't be found, I need to ask the user for input to relocate that file (like how the Alias Manager prompts the user to reconnect a broken alias). If the application has (or can make) a connection to the WindowServer, this is as simple as using an NSOpenPanel. However, when the app can't make a connection to the WindowServer I need to use an alternative method to get the user input.
So, how can I tell which method to use from within the famework code? Is there a way to programatically determine if a WindowServer connection is available (or possible)?
I recognize that an alternative architecture, where the framework client provides a callback mechanism to prompt the user would let the input-gathering strategy be provided by the calling application. I'd like to make things as simple as possible for the calling application, however, so my first choice would be to encapsulate these details in the framework if I can.
There's an environment variable named SECURITYSESSIONID that is set by loginwindow.app and get's passed to the user's applications. The variable is not set if you login via ssh. It serves as kind of a handle to talk to the window server.
Problem: The existence of this variable does not mean that this user currently controls the window manager (think fast user switching).
There's a function called CGSessionCopyCurrentDictionary in the ApplicationServices framework which looks promising:
Return Value: A window server session dictionary, or NULL if the caller is not running within a Quartz GUI session or the window server is disabled. You should release the dictionary when you are finished using it. For information about the key-value pairs in this dictionary, see "Window Server Session Properties."
Related
It may be because I'm not developing a traditional Swift app, instead I'm using the https://github.com/zserge/webview library to develop a cross platform app.
My app has 2 parts, divided into 2 different threads: one thread launches the window and displays a JS app. The second thread contains a background server bound to an ephemeral port and serves a json api, written in Rust. The Rust side is also the one talking with the File System and making all requests. On Linux I don't have any problem, but on Mac it works only when requesting resources from root and home directories but not from Documents/Desktop etc
The first problem I had when running it on Mac has been allowing access to the server from the window: I had to add a new entry to the info.plist file, according to this answer in stackoverflow: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection
This resolved the issue I had talking to the server bound to the ephemeral port. Truth be said I have to also say that now it requests me to allow access to external resources every time I launch the app.
But, when trying to execute a function which requires access from the Rust side to the Desktop (for example), it doesn't work and it does not show any popup and never did
Btw, if you want to have a look at the final product, maybe to help you understand better the app, have a look here: http://getdevspace.com/
Check the ch mode file system
Even had the same problem so i checked the ch mode so it worked
Thanks
I'm implementing API which allows to launch other apps (using NSTask) inside VFS (FUSE on macOS). After VFS is mounted a bunch of processes start accessing launched VFS in which my app works, and I'd like to implement some kind of filtering mechnism which will allow to detect whether process which is accessing the VFS is created by system (and potentially safe) or not, and if so it'll be granted an access to the file system where my app runs.
So far I'm able to get basic information of the process by it's pid. For example: process path, uid, ppid, code signature of the process etc (using Security framework, libproc etc)
I've done a couple of tests and see that there are process with uid != 0 and still critical for my app to run (if I deny access to them app which is started in VFS crashes) (e.g. /usr/libexec/secinitd, /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock), so looks like approach with filtering processes by pids, uids, ppids might not work.
So the question is: is it possible to distinguish whether process which is accessing my app was created by system and is potentially safe? I also don't want to do too much work by denying accees to critical system processes which will allow the app to successfully start and run in VFS.
Judging from the comment thread, your threat model is data theft via malware etc.
In this case, you can trust almost nothing, so the best way is probably to maintain an explicit whitelist of processes which are allowed to access your mount point, and block access to everything else by default. Log any processes to which access is denied, and allow the user to reverse that decision and add them to the whitelist. In other words, let the user decide what applications they consider safe.
Your said that according to your inspection, there were several processes which were mandatory for the process to run, so why won't use try-and-error approach.
You deploy you FUSE drive on clean environment and record all processes that attempt to access your files - try to prevent each process and keep only those which crash your apps, and add them to a white-list.
Of course that this list is subject to change in different macOS versions, but it can give you the general idea.
Alternatively, you can break your app into couple of parts. for example, put the sensitive logic inside separated dylib file, and prevent access to this file only.. since dylib is not the main executable in your app, I believe fewer processes require mandatory access it.
Is it possible for a Windows service to force a user to login from the windows user login screen? I've seen where LogMeIn can do it. This is assuming, of course, that I have both the username and password for the user.
Is LogMeIn using an actual method (non-automated), or are they simply quickly automating the task of logging in my selecting the username and password fields and typing it in?
You should create a WindowStation, and a Desktop inside that. Your service would create the WindowStation and connect that to the user you want to log in, then I suppose you would periodically take a screenshot of the created desktop to present somewhere else.
You may want to start reading the documentation at https://msdn.microsoft.com/en-us/library/windows/desktop/ms687105%28v=vs.85%29.aspx and linked pages, then ask a more specific question.
I don't know if this method can be used to log in at the Console (the window station attached to the physical video card/keyboard of the computer), but if this has to happen automatically I'd avoid using the Console, but a separate Window Station.
EDIT: as it happens to say on the very page I linked (my bad), if a session for the user exists and the service tries to connect to it, it is opened; if it does not exist then it is created anew, and a desktop (named "default") is attached to it. If your service only has to log the interactive user in you should use the auto-login feature of windows instead.
Yes, you can auto login using Windows.
You didn't specify OS but for Windows 7/8 read this, and for Server 2003/2008 (and possibly 2012, but I haven't checked)
check out this Microsoft article.
I run Windows 7.
I run windows service that runs a program with GUI.
I cannot see the GUI of my program because it was started from another session by system or even my user.
Is there a way for me to see my program?
Switch desktop to system user?
Use SetThreadDesktop() to change the thread's context in your service to the user's desktop.
SetThreadDesktop() takes a handle to the desktop as it's first parameter; to get that handle, use EnumDesktops().
EnumDesktops() takes a handle to the window station as it's first parameter; to get that handle, use EnumWindowStations()
To understand what's going on with Window Stations and Desktops, try reading this overview from from MSDN.
Be cautious with this technique. Higher-privileged processes (i.e., services) interacting with the user's desktop are the basis for shatter attacks. You need to write a separate application that runs in the user's context and communicates with your service via pipes or similar.
I have an application that can list the opened windows of the current session. It uses the EnumWindows method from the user32.dll.
I would like to run this code from a windows service, but as the service is not attached to a user session, it returns nothing obviously.
So the question is, how can I enumerate the open windows of another user session (e.g. with a specific logon user)?
Similarly to EnumWindows, I also would like to get the foreground window of the user session as well (like GetForegroundWindow works for the current user).
As far as I'm aware, you can't access the windows of one session from another. It's also worth noting that there's not really any such thing as "the current session" - there may be multiple users logged on through terminal services, or XP's fast user switching.
One approach to this would be to add a program to each user's profile with no UI that just communicates with your service. You'd still have to cope with the fact that there could be multiple active sessions, though.
According to this document you can create a process in an other user's logon session using CreateProcessAsUser, and could enumerate the windows there. You will still need some IPC mechanism to communicate with the service.
The accepted answer is not correct.
So the question is, how can I enumerate the open windows of another user session?
You can enumerate the open windows of any session if you're running as a service running as the local System account.
To do this first enumerate the sessions with WTSEnumerateSessions. Then enumerate the window stations inside each session with EnumWindowStations. Then enumerate the desktops for each Window Station with EnumDesktops. Finally you an enumerate the Windows in those Desktops with EnumWindows.
(e.g. with a specific logon user)
There can be many concurrent logged on users via Terminal services or fast user switching.
Similarly to EnumWindows, I also would like to get the foreground window of the user session as well (like GetForegroundWindow works for the current user).
This can be done by launching an app with a found user token in the Session, Window Station, and Desktop. From there you can call any Win32 API like GetForegroundWindow and report the info back to your parent process.
You can learn more about how Sessions, Window Stations, and Desktops work here.