mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-04-11 16:27:19 +10:00
PrivilegedHelperTool: Add source
Note: Currently not in use
This commit is contained in:
13
payloads/Tools/PrivilegedHelperTool/Makefile
Normal file
13
payloads/Tools/PrivilegedHelperTool/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
CC=clang
|
||||
OUTPUT=com.dortania.opencore-legacy-patcher.privileged-helper
|
||||
|
||||
all: clean release
|
||||
|
||||
release: main.m
|
||||
$(CC) -framework Foundation -framework Security -arch x86_64 -arch arm64 -mmacosx-version-min=10.9 -o $(OUTPUT) main.m
|
||||
|
||||
debug: main.m
|
||||
$(CC) -framework Foundation -framework Security -arch x86_64 -arch arm64 -mmacosx-version-min=10.9 -o $(OUTPUT) main.m -DDEBUG
|
||||
|
||||
clean:
|
||||
/bin/rm -f $(OUTPUT)
|
||||
54
payloads/Tools/PrivilegedHelperTool/install.sh
Executable file
54
payloads/Tools/PrivilegedHelperTool/install.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/zsh --no-rcs
|
||||
# ------------------------------------------------------
|
||||
# Privileged Helper Tool Installer
|
||||
# ------------------------------------------------------
|
||||
# Moves to expected destination and sets SUID bit.
|
||||
# ------------------------------------------------------
|
||||
# Developed for internal testing, end users should be
|
||||
# using the PKG installer when released.
|
||||
# ------------------------------------------------------
|
||||
|
||||
|
||||
# MARK: Variables
|
||||
# ---------------------------
|
||||
helperName="com.dortania.opencore-legacy-patcher.privileged-helper"
|
||||
helperPath="/Library/PrivilegedHelperTools/$helperName"
|
||||
|
||||
# MARK: Functions
|
||||
# ---------------------------
|
||||
|
||||
function _setSUIDBit() {
|
||||
local binaryPath=$1
|
||||
|
||||
# Check if path is a directory
|
||||
if [[ -d $binaryPath ]]; then
|
||||
/bin/chmod -R +s $binaryPath
|
||||
else
|
||||
/bin/chmod +s $binaryPath
|
||||
fi
|
||||
}
|
||||
|
||||
function _copyHelper() {
|
||||
local sourcePath=$1
|
||||
local destinationPath=$2
|
||||
|
||||
# Check if destination path exists
|
||||
if [[ -e $destinationPath ]]; then
|
||||
# Check if destination path is a directory
|
||||
if [[ -d $destinationPath ]]; then
|
||||
/bin/rm -rf $destinationPath
|
||||
else
|
||||
/bin/rm -f $destinationPath
|
||||
fi
|
||||
fi
|
||||
|
||||
# Copy source to destination
|
||||
/bin/cp -R $sourcePath $destinationPath
|
||||
}
|
||||
|
||||
|
||||
# MARK: Main
|
||||
# ---------------------------
|
||||
|
||||
_copyHelper "./$helperName" $helperPath
|
||||
_setSUIDBit $helperPath
|
||||
152
payloads/Tools/PrivilegedHelperTool/main.m
Normal file
152
payloads/Tools/PrivilegedHelperTool/main.m
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
------------------------------------------------
|
||||
OpenCore Legacy Patcher Privileged Helper Tool
|
||||
------------------------------------------------
|
||||
Designed as an alternative to an XPC service,
|
||||
this tool is used to run commands as root.
|
||||
------------------------------------------------
|
||||
Server and client must have the same signing
|
||||
certificate in order to run commands.
|
||||
------------------------------------------------
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Security/Security.h>
|
||||
#include <libproc.h>
|
||||
|
||||
#define UTILITY_VERSION "1.0.0"
|
||||
|
||||
#define VALID_CLIENT_TEAM_ID @"S74BDJXQMD"
|
||||
|
||||
#define OCLP_PHT_ERROR_MISSING_ARGUMENTS 160
|
||||
#define OCLP_PHT_ERROR_SET_UID_MISSING 161
|
||||
#define OCLP_PHT_ERROR_SET_UID_FAILED 162
|
||||
#define OCLP_PHT_ERROR_SELF_PATH_MISSING 163
|
||||
#define OCLP_PHT_ERROR_PARENT_PATH_MISSING 164
|
||||
#define OCLP_PHT_ERROR_SIGNING_INFORMATION_MISSING 165
|
||||
#define OCLP_PHT_ERROR_INVALID_TEAM_ID 166
|
||||
#define OCLP_PHT_ERROR_INVALID_CERTIFICATES 167
|
||||
#define OCLP_PHT_ERROR_COMMAND_MISSING 168
|
||||
#define OCLP_PHT_ERROR_COMMAND_FAILED 169
|
||||
#define OCLP_PHT_ERROR_CATCH_ALL 170
|
||||
|
||||
|
||||
NSDictionary *getSigningInformationFromPath(NSString *path) {
|
||||
SecStaticCodeRef codeRef;
|
||||
OSStatus status = SecStaticCodeCreateWithPath((__bridge CFURLRef)[NSURL fileURLWithPath:path], kSecCSDefaultFlags, &codeRef);
|
||||
if (status != errSecSuccess) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
CFDictionaryRef codeDict = NULL;
|
||||
status = SecCodeCopySigningInformation(codeRef, kSecCSSigningInformation, &codeDict);
|
||||
if (status != errSecSuccess) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return (__bridge NSDictionary *)codeDict;
|
||||
}
|
||||
|
||||
NSString *getParentProcessPath() {
|
||||
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
|
||||
if (proc_pidpath(getppid(), pathbuf, sizeof(pathbuf)) <= 0) {
|
||||
return nil;
|
||||
}
|
||||
NSString *path = [NSString stringWithUTF8String:pathbuf];
|
||||
return path;
|
||||
}
|
||||
|
||||
NSString *getProcessPath() {
|
||||
NSString *path = [[NSBundle mainBundle] executablePath];
|
||||
return path;
|
||||
}
|
||||
|
||||
BOOL isSBitSet(NSString *path) {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:nil];
|
||||
if (attributes == nil) {
|
||||
return NO;
|
||||
}
|
||||
return (attributes.filePosixPermissions & S_ISUID) != 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
// We simply return if no arguments are passed
|
||||
if (argc < 2) {
|
||||
return OCLP_PHT_ERROR_MISSING_ARGUMENTS;
|
||||
}
|
||||
|
||||
if (argc == 2 && (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-v") == 0)) {
|
||||
printf("%s\n", UTILITY_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Verify whether we can run as root
|
||||
NSString *processPath = getProcessPath();
|
||||
if (processPath == nil) {
|
||||
return OCLP_PHT_ERROR_SELF_PATH_MISSING;
|
||||
}
|
||||
|
||||
if (!isSBitSet(processPath)) {
|
||||
return OCLP_PHT_ERROR_SET_UID_MISSING;
|
||||
}
|
||||
|
||||
setuid(0);
|
||||
if (getuid() != 0) {
|
||||
return OCLP_PHT_ERROR_SET_UID_FAILED;
|
||||
}
|
||||
|
||||
NSString *parentProcessPath = getParentProcessPath();
|
||||
if (parentProcessPath == nil) {
|
||||
return OCLP_PHT_ERROR_PARENT_PATH_MISSING;
|
||||
}
|
||||
|
||||
NSDictionary *processSigningInformation = getSigningInformationFromPath(processPath);
|
||||
NSDictionary *parentProcessSigningInformation = getSigningInformationFromPath(parentProcessPath);
|
||||
|
||||
if (processSigningInformation == nil || parentProcessSigningInformation == nil) {
|
||||
return OCLP_PHT_ERROR_SIGNING_INFORMATION_MISSING;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Skip Team ID check in debug mode
|
||||
// DO NOT USE IN PRODUCTION
|
||||
#else
|
||||
// Check Team ID
|
||||
if (![processSigningInformation[@"teamIdentifier"] isEqualToString:VALID_CLIENT_TEAM_ID] || ![parentProcessSigningInformation[@"teamIdentifier"] isEqualToString:VALID_CLIENT_TEAM_ID]) {
|
||||
return OCLP_PHT_ERROR_INVALID_TEAM_ID;
|
||||
}
|
||||
|
||||
// Check Certificates
|
||||
if (![processSigningInformation[@"certificates"] isEqualToArray:parentProcessSigningInformation[@"certificates"]]) {
|
||||
return OCLP_PHT_ERROR_INVALID_CERTIFICATES;
|
||||
}
|
||||
#endif
|
||||
|
||||
NSString *command = nil;
|
||||
NSArray *arguments = @[];
|
||||
if (argc == 2) {
|
||||
command = [NSString stringWithUTF8String:argv[1]];
|
||||
} else {
|
||||
command = [NSString stringWithUTF8String:argv[1]];
|
||||
for (int i = 2; i < argc; i++) {
|
||||
arguments = [arguments arrayByAddingObject:[NSString stringWithUTF8String:argv[i]]];
|
||||
}
|
||||
}
|
||||
|
||||
// Verify command exists
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:command]) {
|
||||
return OCLP_PHT_ERROR_COMMAND_MISSING;
|
||||
}
|
||||
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
[task setLaunchPath:command];
|
||||
[task setArguments:arguments];
|
||||
[task launch];
|
||||
[task waitUntilExit];
|
||||
return [task terminationStatus];
|
||||
}
|
||||
return OCLP_PHT_ERROR_CATCH_ALL; // Should never reach here
|
||||
}
|
||||
Reference in New Issue
Block a user