Communication issue in Mac OS - macos

I am developing an application on MAC OS . It has 2 parts -- a UI element and a daemon (which needs to run continuously and must restart on being killed). Currently I am using launchctl to restart the daemon.
But there is another issue. I need the 2 parts of my application to communicate with each other . For this I am using distibuted objects for the same (as given here) . However this does not work when I launch the daemon with launchctl. Can anyone suggest some alternative???

I use NSDistributedNotifications to handle this pretty well in one app, even on 10.7. You have to do your own handshaking since this can be lossy (i.e. include an ack notification and resend in case of timeouts). A side effect of this approach is that if there are multiple clients running (particularly under fast user switching), all of them receive the notifications. That's good in the particular case of this app. It's also extremely simple to implement.
For another app, I use two FIFOs. The server writes to one and reads from the other. The client does the opposite. You can of course also use a network socket to achieve the same thing. I tend to prefer FIFOs because you don't have to do deal with locking down a network socket.
That said, what problem are you seeing using distributed objects under launchd? Are you just seeing problems on 10.7 (which changed the rules around the launchd context)?
Are you using launchd to lazy-load the daemon when the port is accessed (this is the normal way to do it). Have you considered using a launchagent instead of a launchdaemon?
EDIT:
Ah... the bootstrap server. Yes. You need to execute things in the correct bootstrap context in order to talk to them. The bootstrap context for the login session is rooted to the windowserver process. LaunchDaemons run in a different context, so they can't directly communicate with the login sessions. Some background reading:
Starting/stopping a launchd agent for all users with GUI sessions
How can you start a LaunchAgent for the first time without rebooting, when your code runs as a LaunchDaemon?
launch agent from daemon in user context
I am not aware of anyway to get processes into the correct context without using launchctl bsexec. Launchd technically has an API (launchctl uses it), but it is not well documented. You can pull the source from opensource.apple.com.
Even if you stay with NSDistributedObject, I would try to use something other than the bootstrap service if you can. As I mentioned, I tend to use other tools and avoid NSDistributedObject. In my opinion, for the same reasons that REST is better than SOAP, simple protocols are usually better than remote objects. (YMMV)

If you are launching your daemon using sudo launchctl; You should not use CFMessagePort and Distributed object for IPC. CFMessagePort and Distributed object are implemented using the bootstrap service(Many Mac OS X subsystems work by exchanging Mach messages with a central service. For such a subsystem to work, it must be able to find the service. This is typically done using the Mach bootstrap service, which allows a process to look up a service by name).
If you will use DO or CFMessagePort; you will run into bootstrap namespace problem.
when you will launch your daemon using sudo launchctl ; your service is register in root bootstrap namespace so your clients(running in user mode) will not able to use that services.
you can check bootstrap service using
$ launchctl bslist
$ sudo launchctl bslist // If you are using sudo lunchctl
You should use UNIX Domain Sockets. UNIX domain sockets are somewhat like TCP/IP sockets, except that the communication is always local to the computer. You access UNIX domain sockets using the same BSD sockets API that you'd use for TCP/IP sockets. The primary difference is the address format. For TCP/IP sockets, the address structure (that which you pass to bind, connect, and so on) is (struct sockaddr_in), which contains an IP address and port number. For UNIX domain sockets, the address structure is (struct sockaddr_un), which contains a path.For an example of using UNIX domain sockets in a client/server environment, see Sample Code 'CFLocalServer'.
Take a look at this Technical Note TN2083 Daemons and Agents
Daemon IPC Recommendations
Mach Bootstrap Basics
Each user has a separate Mach namespace .You cannot communicate
between namespaces.  You'll need to use sockets (NSSocketPort)
instead, which are not limited in such ways.[1]

Related

Can Kernel Control API support multiple, simultaneous client connections?

I'm using the Kernel Control API (SYSPROTO_CONTROL) for a user-land application to request information from a kernel extension, based on the code in Apple's documentation.
All works as expected with a single connected client. If a 2nd client tries to connect whilst the first is connected, it fails with the message: -
Error 16 (Resource busy).
The first client is then automatically disconnected.
Is it possible for two clients to be connected using the Kernel Control API and if not, is the best solution to keep trying to connect if the resource is busy?
I don't know if it is possible but the recommend way is to always only have one user space client that talks to one kernel extension, usually a background daemon running in user space and started by launchd. If you want multiple other apps or processes to access data from your kernel extension or somehow interact with it, then these would talk to the user space daemon and not directly to the kernel extension, which can also cache data in user space as crossing the users space/kernel space bridge is always expensive for data, so when 10 processes all want the same data, it would be better to just pull it once from the kernel and then distribute it 10 times in user space using any IPC mechanism of your choice.
This setup is recommend as you should limit kernel control to root processes (using the CTL_FLAG_PRIVILEGED flag), so your daemon would run as such a root process, whereas normal apps and processes run with the privileges of the current user. Such a root helper daemon can be bundled inside an app bundle and using the SMJobBless API, the daemon is automatically copied to /Library/PrivilegedHelperTools and it's embedded plist (see SMJobBless documentation, which is only available in its header file AFAIK) is copied to /Library/LaunchDaemons and registered with launchd. Within such a plist you can use various triggers when the daemon shall be started by launchd, e.g. when your application tries to connect to a specific IPC UNIX socket. Then all you have to do in your app is trying to open that socket, what launchd will detect and start the daemon for you, which can then use launchd's API to get hold of that connected socket and immediately start talking with your app. So the whole thing is only installed once and then brings up itself each time your app is launched.
For a SMJobBless sample project, see here.

Reliable IPC With Shell Scripts

Okay, so I have two shell scripts, a server and a client, where the server is always run as root, and the clients can be run as standard users in order to communicate with the server.
The method I've chosen to do this is with a world-accessible directory containing named pipes (fifos), one of which is world-writable (to enable initial connection requests) and the others are created per-user and writable only by them (allowing my server script to know who sent a message).
This seems to work fine but it feels like it may be over-engineered or missing a more suitable alternative. It also lacks any means of determining whether the server is currently running, besides searching for its name in the output of ps. This is somewhat problematic as it means that writing to the connection fifo will hang if the server script isn't available to read from it.
Are there better ways to do something like this for a shell script? Of course I know could use an actual program to get access to more capabilities, but this is really just intended to provide secure access to a root service for non-root users (i.e - it's a wrapper for something else).
You could use Unix domain sockets instead of fifos. Domain sockets can be created with nc -lU /path/to/wherever and connected to with nc -U /path/to/wherever. This creates a persistent object in the filesystem (like a fifo, but different). The server should be able to maintain multiple simultaneous connections over the same socket.
If you're willing to write in C (or some other "real" programming language), it's also possible to pass credentials over Unix domain sockets, unlike fifos. This makes it possible for the server to authenticate its clients without needing to rely on filesystem permissions or other indirect means. Unfortunately, I'm not aware of any widely-supported interface for doing this in a shell script.

Impersonating a user on Mac OS X

On Windows it is possible to have a service that allows clients running in a user context to connect to it using sockets or pipes, and then impersonate the connecting user in order to act on behalf of that user, for instance to access files that only the user has access to (or making sure that no other files are accessed).
What is the equivalent way of accomplishing this on Mac OS X (Linux is interesting too)? I would assume that the set*uid functions would be used for this in some way?
But how do I authenticate the user that I want to impersonate and get the uid to set when the user is connecting on a socket?
Also, the set*uid functions seem to affect the entire process, which makes them difficult to use in a multithreaded daemon. Is there a different commonly used design pattern for this type of services on Mac OS X/Linux?
Edit:
pmjordan's answer seems to take care of the set*uid per-process-only issue, and the question How can I pass user credentials through a Unix-domain socket on Mac OS X? seems to take care of the actual authentication problem by using unix domain sockets instead of plain sockets.
For OS X specifics: have you looked at the Authentication, Authorization, and Permissions Guide for Mac OS X?
Generally, in UNIX-like operating systems, processes typically are owned by one specific user, and what they are permitted to do is determined primarily by this. There are some exceptions to this, but generally, the idea tends to be to do this on a per-process granularity. On the plus side, starting new processes is really easy - see the fork() function.
So a typical way for a daemon (such as sshd) to impersonate different users is to run the main process as root. Then, accept incoming connections and pass them off to fork()ed child processes, which, as you say, immediately drop privileges using set*uid. There are various inter-process communication channels, such as pipes, that you can set up if the child processes need to communicate with the parent process. Obviously, the less code runs as root, the better, from a security perspective, so you'll want to aim for the child processes to be autonomous.
If you need users to actually provide their username and password, things get a bit more complicated; you might want to look at the source code for the su and sudo utilities, and read the platform-specific documentation for authentication APIs.
from Technical Note TN2083 - Apple Developer
In some cases it is helpful to impersonate the user, at least as far as the permissions checking done by the BSD subsystem of the kernel. A single-threaded daemon can do this using seteuid and setegid. These set the effective user and group ID of the process as a whole. This will cause problems if your daemon is using multiple threads to handle requests from different users. In that case you can set the effective user and group ID of a thread using pthread_setugid_np. This was introduced in Mac OS X 10.4.

Getting data from my program into snmpd

I guess I have missed the obvious, maybe, but I am lost for a good answer.
I am developing a stand alone program that will be running on a Linux (Ubuntu?) embedded PC inside a piece of hardware. I want it to be the "thing" SNMP talks to. Well, short of compiling in my own SNMD "daemon" code and persuading Linux to let a general user have access to port 161, I think I'll opt for Net-SNMP's snmpd. I am open to suggestions for better products to use. LGPL, BSD, MIT, licenses, please.
I am working separately on the MIB and assigning OIDs, etc. I know what vars I want to set and get, etc.
I have read and reread the stuff on making an SNMP/snmpd Agent and/or subagent. Near as I can tell, they are both compiled into snmp or linked to it as a shared library. Right?
So, how do I get that agent to talk to my sepaprate program running in a separate general user session? Is there a direct technique to use? D-Bus? ppen()? Named pipes? Shared memory? Temp files? UDP port? Something better? Or do I really want to turn my program into a .SO and let snmpd launch it? I assume at that point I'd be abe to tell snmpd where to call in to me to get/set vars. Right?
Thanks!
The "AgentX" protocol is a way for arbitrary applications to supply SNMP services to a running system SNMP daemon. Your application listens on some port other than 161 (typically a library will take care of the details for you), and the system snmpd will forward requests for your OIDs to your subagent. This method doesn't involve linking any code into the system snmpd.
Often an easier way is to configure the system snmpd to run a script to get or set data. The script can, if you like, use some other kind of IPC to talk to your application (such as JSON to an HTTP server, for example).

Many-to-many messaging on local machine without broker

I'm looking for a mechanism to use to create a simple many-to-many messaging system to allow Windows applications to communicate on a single machine but across sessions and desktops.
I have the following hard requirements:
Must work across all Windows sessions on a single machine.
Must work on Windows XP and later.
No global configuration required.
No central coordinator/broker/server.
Must not require elevated privileges from the applications.
I do not require guaranteed delivery of messages.
I have looked at many, many options. This is my last-ditch request for ideas.
The following have been rejected for violating one or more of the above requirements:
ZeroMQ: In order to do many-to-many messaging a central broker is required.
Named pipes: Requires a central server to receive messages and forward them on.
Multicast sockets: Requires a properly configured network card with a valid IP address, i.e. a global configuration.
Shared Memory Queue: To create shared memory in the global namespace requires elevated privileges.
Multicast sockets so nearly works. What else can anyone suggest? I'd consider anything from pre-packaged libraries to bare-metal Windows API functionality.
(Edit 27 September) A bit more context:
By 'central coordinator/broker/server', I mean a separate process that must be running at the time that an application tries to send a message. The problem I see with this is that it is impossible to guarantee that this process really will be running when it is needed. Typically a Windows service would be used, but there is no way to guarantee that a particular service will always be started before any user has logged in, or to guarantee that it has not been stopped for some reason. Run on demand introduces a delay when the first message is sent while the service starts, and raises issues with privileges.
Multicast sockets nearly worked because it manages to avoid completely the need for a central coordinator process and does not require elevated privileges from the applications sending or receiving multicast packets. But you have to have a configured IP address - you can't do multicast on the loopback interface (even though multicast with TTL=0 on a configured NIC behaves as one would expect of loopback multicast) - and that is the deal-breaker.
Maybe I am completely misunderstanding the problem, especially the "no central broker", but have you considered something based on tuple spaces?
--
After the comments exchange, please consider the following as my "definitive" answer, then:
Use a file-based solution, and host the directory tree on a Ramdisk to insure good performance.
I'd also suggest to have a look at the following StackOverflow discussion (even if it's Java based) for possible pointers to how to manage locking and transactions on the filesystem.
This one (.NET based) may be of help, too.
How about UDP broadcasting?
Couldn't you use a localhost socket ?
/Tony
In the end I decided that one of the hard requirements had to go, as the problem could not be solved in any reasonable way as originally stated.
My final solution is a Windows service running a named pipe server. Any application or service can connect to an instance of the pipe and send messages. Any message received by the server is echoed to all pipe instances.
I really liked p.marino's answer, but in the end it looked like a lot of complexity for what is really a very basic piece of functionality.
The other possibility that appealed to me, though again it fell on the complexity hurdle, was to write a kernel driver to manage the multicasting. There would have been several mechanisms possible in this case, but the overhead of writing a bug-free kernel driver was just too high.

Resources