Files
Sparkle/Tests/SUInstallerTest.m
Zorg fc4f8cb753 Harden policy on what operations clients are allowed to take
* For the Installer and Downloader XPC Services, if these executables are code signed with an Apple issued Team ID, then the connecting client must also be code signed with a matching Team ID.
* For the Downloader XPC Service, the request URL must be http/https
* For Autoupdate, if stage 1 of installation hasn't been completed yet and this executable is code signed with an Apple issued Team ID, then the connecting client must also be code signed with a matching Team ID. As before, multiple simultaneous connections are still disallowed.
* For Autoupdate, if it's not signed with Apple issued certificate, when installing package updates the bundle being updated must be itself and owned by root on disk (as one expects from a PKG installation)
* The authorization prompt message in the Installer Service is more computed inside the service so the client can't pass a completely arbitrary message
* Add extra nullable checking of parameters coming from XPC endpoints
* Add more thread-safe synchronization for Autoupdate installer
* Add logs for more failure points
2025-09-07 18:06:30 -07:00

85 lines
2.7 KiB
Objective-C

//
// SUInstallerTest.m
// Sparkle
//
// Created by Kornel on 24/04/2015.
// Copyright (c) 2015 Sparkle Project. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>
#import "SUHost.h"
#import "SUInstaller.h"
#import "SUInstallerProtocol.h"
#import "SPUInstallationType.h"
#import <unistd.h>
@interface SUInstallerTest : XCTestCase
@end
@implementation SUInstallerTest
- (void)setUp
{
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
#if SPARKLE_BUILD_PACKAGE_SUPPORT
- (void)testInstallIfRoot
{
uid_t uid = getuid();
if (uid != 0) {
NSLog(@"Test must be run as root: sudo xcodebuild -project Sparkle.xcodeproj -scheme Sparkle '-only-testing:Sparkle Unit Tests/SUInstallerTest/testInstallIfRoot' test");
return;
}
NSString *expectedDestination = @"/tmp/sparklepkgtest.app";
NSFileManager *fm = [NSFileManager defaultManager];
[fm removeItemAtPath:expectedDestination error:nil];
XCTAssertFalse([fm fileExistsAtPath:expectedDestination isDirectory:nil]);
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:@"test" ofType:@"pkg"];
XCTAssertNotNil(path);
SUHost *host = [[SUHost alloc] initWithBundle:bundle];
NSError *installerError = nil;
// Note: we may not be using the "correct" home directory or user name (they will be root) but our test pkg does not have
// pre/post install scripts so it doesn't matter
id<SUInstallerProtocol> installer = [SUInstaller installerForHost:host expectedInstallationType:SPUInstallationTypeGuidedPackage updateDirectory:[path stringByDeletingLastPathComponent] connectionCodeSigningValidationSkipped:NO homeDirectory:NSHomeDirectory() userName:NSUserName() error:&installerError];
if (installer == nil) {
XCTFail(@"Installer is nil with error: %@", installerError);
return;
}
NSError *initialInstallError = nil;
if (![installer performInitialInstallation:&initialInstallError]) {
XCTFail(@"Initial Installation failed with error: %@", initialInstallError);
return;
}
NSError *finalInstallError = nil;
if (![installer performFinalInstallationProgressBlock:nil error:&finalInstallError]) {
XCTFail(@"Final installation failed with error: %@", finalInstallError);
return;
}
XCTAssertTrue([fm fileExistsAtPath:expectedDestination isDirectory:nil]);
[fm removeItemAtPath:expectedDestination error:nil];
}
#endif
@end