Conflicts:
	smcFanControl.xcodeproj/project.pbxproj
This commit is contained in:
Hendrik Holtmann
2014-10-20 16:41:03 +02:00
4 changed files with 107 additions and 127 deletions

View File

@ -31,9 +31,10 @@
#import "SystemVersion.h" #import "SystemVersion.h"
@interface FanControl () @interface FanControl ()
+(void)copyMachinesIfNecessary; + (void)copyMachinesIfNecessary;
- (BOOL)isInAutoStart; - (BOOL)isInAutoStart;
- (void) setStartAtLogin:(BOOL)enabled; - (void)setStartAtLogin:(BOOL)enabled;
+ (void)checkRightStatus:(OSStatus)status;
@end @end
@implementation FanControl @implementation FanControl
@ -773,6 +774,20 @@ NSUserDefaults *defaults;
LSSharedFileListItemRemove(loginItems, existingItem); LSSharedFileListItemRemove(loginItems, existingItem);
} }
+(void) checkRightStatus:(OSStatus) status
{
if (status != errAuthorizationSuccess) {
NSAlert *alert = [NSAlert alertWithMessageText:@"Authorization failed" defaultButton:@"Quit" alternateButton:nil otherButton:nil informativeTextWithFormat:[NSString stringWithFormat:@"Authorization failed with code %d",status]];
[alert setAlertStyle:2];
NSInteger result = [alert runModal];
if (result == NSAlertDefaultReturn) {
[[NSApplication sharedApplication] terminate:self];
}
}
}
#pragma mark **SMC-Binary Owner/Right Check** #pragma mark **SMC-Binary Owner/Right Check**
//TODO: It looks like this function is called inefficiently. //TODO: It looks like this function is called inefficiently.
//call smc binary with sudo rights and apply //call smc binary with sudo rights and apply
@ -791,15 +806,9 @@ NSUserDefaults *defaults;
AuthorizationRights gencright = { 1, &gencitem }; AuthorizationRights gencright = { 1, &gencitem };
int flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed; int flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed;
OSStatus status = AuthorizationCreate(&gencright, kAuthorizationEmptyEnvironment, flags, &authorizationRef); OSStatus status = AuthorizationCreate(&gencright, kAuthorizationEmptyEnvironment, flags, &authorizationRef);
if (status != errAuthorizationSuccess) {
NSAlert *alert = [NSAlert alertWithMessageText:@"Authorization failed" defaultButton:@"Quit" alternateButton:nil otherButton:nil informativeTextWithFormat:[NSString stringWithFormat:@"Authorization failed with code %d",status]];
[alert setAlertStyle:2];
NSInteger result = [alert runModal];
if (result == NSAlertDefaultReturn) { [self checkRightStatus:status];
[[NSApplication sharedApplication] terminate:self];
}
}
NSString *tool=@"/usr/sbin/chown"; NSString *tool=@"/usr/sbin/chown";
NSArray *argsArray = [NSArray arrayWithObjects: @"root:admin",smcpath,nil]; NSArray *argsArray = [NSArray arrayWithObjects: @"root:admin",smcpath,nil];
int i; int i;
@ -809,15 +818,9 @@ NSUserDefaults *defaults;
} }
args[i] = NULL; args[i] = NULL;
status=AuthorizationExecuteWithPrivileges(authorizationRef,[tool UTF8String],0,args,&commPipe); status=AuthorizationExecuteWithPrivileges(authorizationRef,[tool UTF8String],0,args,&commPipe);
if (status != errAuthorizationSuccess) {
NSAlert *alert = [NSAlert alertWithMessageText:@"Authorization failed" defaultButton:@"Quit" alternateButton:nil otherButton:nil informativeTextWithFormat:[NSString stringWithFormat:@"Authorization failed with code %d",status]];
[alert setAlertStyle:2];
NSInteger result = [alert runModal];
if (result == NSAlertDefaultReturn) { [self checkRightStatus:status];
[[NSApplication sharedApplication] terminate:self];
}
}
//second call for suid-bit //second call for suid-bit
tool=@"/bin/chmod"; tool=@"/bin/chmod";
argsArray = [NSArray arrayWithObjects: @"6555",smcpath,nil]; argsArray = [NSArray arrayWithObjects: @"6555",smcpath,nil];
@ -826,15 +829,8 @@ NSUserDefaults *defaults;
} }
args[i] = NULL; args[i] = NULL;
status=AuthorizationExecuteWithPrivileges(authorizationRef,[tool UTF8String],0,args,&commPipe); status=AuthorizationExecuteWithPrivileges(authorizationRef,[tool UTF8String],0,args,&commPipe);
if (status != errAuthorizationSuccess) {
NSAlert *alert = [NSAlert alertWithMessageText:@"Authorization failed" defaultButton:@"Quit" alternateButton:nil otherButton:nil informativeTextWithFormat:[NSString stringWithFormat:@"Authorization failed with code %d",status]];
[alert setAlertStyle:2];
NSInteger result = [alert runModal];
if (result == NSAlertDefaultReturn) { [self checkRightStatus:status];
[[NSApplication sharedApplication] terminate:self];
}
}
} }

View File

@ -31,117 +31,90 @@ NSString * const DirectoryLocationDomain = @"DirectoryLocationDomain";
@implementation NSFileManager (DirectoryLocations) @implementation NSFileManager (DirectoryLocations)
//
// findOrCreateDirectory:inDomain:appendPathComponent:error: /*! Method to tie together the steps of:
// 1) Locate a standard directory by search path and domain mask
// Method to tie together the steps of: 2) Select the first path in the results
// 1) Locate a standard directory by search path and domain mask 3) Append a subdirectory to that path
// 2) Select the first path in the results 4) Create the directory and intermediate directories if needed
// 3) Append a subdirectory to that path 5) Handle errors by emitting a proper NSError object
// 4) Create the directory and intermediate directories if needed
// 5) Handle errors by emitting a proper NSError object * \pararm searchPathDirectory - the search path passed to NSSearchPathForDirectoriesInDomains
// * \pararm domainMask - the domain mask passed to NSSearchPathForDirectoriesInDomains
// Parameters: * \pararm appendComponent - the subdirectory appended
// searchPathDirectory - the search path passed to NSSearchPathForDirectoriesInDomains * \pararm errorOut - any error from file operations
// domainMask - the domain mask passed to NSSearchPathForDirectoriesInDomains
// appendComponent - the subdirectory appended * \returns returns the path to the directory (if path found and exists), nil otherwise
// errorOut - any error from file operations */
//
// returns the path to the directory (if path found and exists), nil otherwise
//
- (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory - (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory
inDomain:(NSSearchPathDomainMask)domainMask inDomain:(NSSearchPathDomainMask)domainMask
appendPathComponent:(NSString *)appendComponent appendPathComponent:(NSString *)appendComponent
error:(NSError **)errorOut error:(NSError **)errorOut
{ {
// Declare an NSError first, so we don't need to check errorOut again and again
NSError *error;
if (errorOut) {
error = *errorOut;
}
else {
error = nil;
}
// //
// Search for the path // Search for the path
// //
NSArray* paths = NSSearchPathForDirectoriesInDomains( NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory,domainMask,YES);
searchPathDirectory,
domainMask,
YES);
if ([paths count] == 0) if ([paths count] == 0)
{ {
if (errorOut) NSDictionary *userInfo = @{NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"No path found for directory in domain.",@"Errors",nil),
{ @"NSSearchPathDirectory":@(searchPathDirectory),
NSDictionary *userInfo = @"NSSearchPathDomainMask":@(domainMask)};
[NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedStringFromTable( error = [NSError errorWithDomain:DirectoryLocationDomain
@"No path found for directory in domain.",
@"Errors",
nil),
NSLocalizedDescriptionKey,
[NSNumber numberWithInteger:searchPathDirectory],
@"NSSearchPathDirectory",
[NSNumber numberWithInteger:domainMask],
@"NSSearchPathDomainMask",
nil];
*errorOut =
[NSError
errorWithDomain:DirectoryLocationDomain
code:DirectoryLocationErrorNoPathFound code:DirectoryLocationErrorNoPathFound
userInfo:userInfo]; userInfo:userInfo];
}
return nil; return nil;
} }
// //
// Normally only need the first path returned // Normally only need the first path returned
// //
NSString *resolvedPath = [paths objectAtIndex:0]; NSString *resolvedPath = paths[0];
// //
// Append the extra path component // Append the extra path component
// //
if (appendComponent) if (appendComponent)
{ {
resolvedPath = [resolvedPath resolvedPath = [resolvedPath stringByAppendingPathComponent:appendComponent];
stringByAppendingPathComponent:appendComponent];
} }
// //
// Create the path if it doesn't exist // Create the path if it doesn't exist
// //
NSError *error = nil;
BOOL success = [self
createDirectoryAtPath:resolvedPath
withIntermediateDirectories:YES
attributes:nil
error:&error];
if (!success)
{
if (errorOut)
{
*errorOut = error;
}
return nil;
}
//
// If we've made it this far, we have a success if ([self createDirectoryAtPath:resolvedPath withIntermediateDirectories:YES
// attributes:nil error:&error])
if (errorOut)
{
*errorOut = nil;
}
return resolvedPath; return resolvedPath;
else
return nil;
} }
//
// applicationSupportDirectory /*! applicationSupportDirectory
//
// Returns the path to the applicationSupportDirectory (creating it if it doesn't * \returns The path to the applicationSupportDirectory (creating it if it doesn't exist).
// exist). */
//
- (NSString *)applicationSupportDirectory - (NSString *)applicationSupportDirectory
{ {
NSString *executableName = NSString *executableName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
NSError *error; NSError *error = nil;
NSString *result =
[self NSString *result = [self findOrCreateDirectory:NSApplicationSupportDirectory
findOrCreateDirectory:NSApplicationSupportDirectory
inDomain:NSUserDomainMask inDomain:NSUserDomainMask
appendPathComponent:executableName appendPathComponent:executableName
error:&error]; error:&error];

View File

@ -24,8 +24,6 @@
#import "smcWrapper.h" #import "smcWrapper.h"
#import <CommonCrypto/CommonDigest.h> #import <CommonCrypto/CommonDigest.h>
//TODO: This is the smcFanControl 2.5ß checksum, it needs to be updated for the next release.
NSString * const smc_checksum=@"03548c5634bd01315b19c46bf329cceb";
static NSArray *allSensors = nil; static NSArray *allSensors = nil;
@ -153,26 +151,39 @@ static NSArray *allSensors = nil;
} }
+ (NSString*)createCheckSum:(NSString*)path { + (BOOL)validateSMC:(NSString*)path
NSData *d=[NSData dataWithContentsOfMappedFile:path]; {
unsigned char result[CC_MD5_DIGEST_LENGTH]; SecStaticCodeRef ref = NULL;
CC_MD5((void *)[d bytes], [d length], result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2]; NSURL * url = [NSURL URLWithString:path];
int i;
for(i = 0; i<CC_MD5_DIGEST_LENGTH; i++) { OSStatus status;
[ret appendFormat:@"%02x",result[i]];
// obtain the cert info from the executable
status = SecStaticCodeCreateWithPath((CFURLRef)url, kSecCSDefaultFlags, &ref);
if (status != noErr) {
return false;
} }
return ret;
status = SecStaticCodeCheckValidity(ref, kSecCSDefaultFlags, nil);
if (status != noErr) {
NSLog(@"Codesign verification failed: Error id = %d",status);
return false;
}
return true;
} }
//call smc binary with setuid rights and apply //call smc binary with setuid rights and apply
// The smc binary is given root permissions in FanControl.m with the setRights method. // The smc binary is given root permissions in FanControl.m with the setRights method.
+(void)setKey_external:(NSString *)key value:(NSString *)value{ +(void)setKey_external:(NSString *)key value:(NSString *)value{
NSString *launchPath = [[NSBundle mainBundle] pathForResource:@"smc" ofType:@""]; NSString *launchPath = [[NSBundle mainBundle] pathForResource:@"smc" ofType:@""];
NSString *checksum=[smcWrapper createCheckSum:launchPath];
//first check if it's the right binary (security) //first check if it's the right binary (security)
// MW: Disabled smc binary checksum. This should be re-enabled in an official release. // MW: Disabled smc binary checksum. This should be re-enabled in an official release.
if (![checksum isEqualToString:smc_checksum]) { if (![smcWrapper validateSMC:launchPath]) {
NSLog(@"smcFanControl: Security Error: smc-binary is not the distributed one"); NSLog(@"smcFanControl: Security Error: smc-binary is not the distributed one");
return; return;
} }