Recent

Author Topic: [SOLVED] Linking plists into executable - Trying to create a privileged helper  (Read 900 times)

Hansaplast

  • Hero Member
  • *****
  • Posts: 535
  • Tweaking4All.com
    • Tweaking4All

I've been tinkering with this for quite a while now, and I feel like I'm getting closer to creating a SMJobBless example using Lazarus Pascal, for when an application needs elevated access rights (root).

The principle seems easy enough (debugging is definitely a challenge though);
One basically has 2 "programs" - the GUI application, and a (privileged) Helper tool.

The Helper tool has no GUI, and is located in "project1.app/Contents/Library/LaunchServices/", and launched by launchd by calling SMJobBless().
The only thing the Helper tool does, is execute the task(s) that require root access and communicate with the GUI application (for example over XPC - a problem for another day).

So far, I've managed to create a very simple setup for this; a simple GUI application, with the intend to start an even simpler Helper tool (which only puts a message in the system log with NSLog). The GUI application does manage to authenticate just fine (using AuthorizationCreate()), but throws a "CFErrorDomainLaunchd Code=2]" when it calls SMJobBless().

Note: The Helper is in de right location, but I suspect there is a linking and signing issue here (I do have an Apple Dev cert to sign applications).
This error indicates that launchd cannot a qualifying helper tool. I've had the error Code=5 first, which changed once I moved the helper application in the right file location.

By Apple's rules, only the predefined GUI Application, signed by a given developer, can start, stop and communicate with the Helper tool.
To accomplish this, besides signing the applications, one needs to define 3 plist files.
One Info.plist for the GUI application (the usual) and ... 2 (yes indeed, two!) plist files for the Helper tool (Info.plist and Launchd.plist), which need to be linked to the binary (from what I understand - see these examples QtPrivilegedHelperExample, Swift: Privileged Helper).

Note: all these plist files point to each other using their CFBundleIdentifiers, SMAuthorizedClients, SMPrivilegedExecutables and a Label for launchd.

The two examples mentioned, use of a linker option: "sectcreate __TEXT" (I'm guessing they are GCC based, and create some sorts of TEXT section?) - which is my guess why launchd doesn't seem to like my helper tool:

Code: [Select]
-sectcreate __TEXT __info_plist Helper-Info.plist -sectcreate __TEXT __launchd_plist Helper-Launchd.plist
Now, I'm definitely not an expert when it comes to linkers, very far from it, and was wondering if anyone can help me with this.
I've looked at linker and compiler options, but I couldn't find a way to accomplish this.
« Last Edit: March 01, 2019, 01:37:38 pm by Hansaplast »

Hansaplast

  • Hero Member
  • *****
  • Posts: 535
  • Tweaking4All.com
    • Tweaking4All
Re: Linking plists into executable - Trying to create a privileged helper tool
« Reply #1 on: February 27, 2019, 02:25:04 pm »
I did find the solution to the linker issue,... it took me some extra coffee I guess ...
I figured I'll post it here, just in case it will be helpful for others, even though it does not resolve my "Code=2" error.

Per "ld" man page ...

-sectcreate segname sectname file

   The section sectname in the segment segname is created from  the
   contents  of file.  The combination of segname and sectname must
   be unique; there cannot already be a section  (segname,sectname)
   in  any  input  object  file.  This option was previously called
   -segcreate, which will continue to be recognized.


and;

Sections created from files with the -sectcreate option will be laid out at after sections from .o files.
The use of the -order_file option will alter the layout rules above, and move the symbols specified to start of their section.


After some more coffee, I figured out I can use the "-k" option to pass parameters to the linker in the project options. So I've added:

Code: [Select]
-sectcreate __TEXT __info_plist SMJobBlessHelper-Info.plist -sectcreate __TEXT __launchd_plist SMJobBlessHelper-Launchd.plist
Per launchctl man page, on how to read embedded plist info;

plist [segment,section] Mach-O
  Prints the the property list embedded in the __TEXT,__info_plist segment/section of the target Mach-O or the
  specified segment/section.


Testing if these were really embedded:

Code: [Select]
$ launchctl plist __TEXT,__launchd_plist SMJobBlessHelper
{
// launchd.plist info here ...
};
Code: [Select]
$ launchctl plist __TEXT,__info_plist SMJobBlessHelper
{
// info.plist info here ...
};


This worked for both sections.