New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secure architecture for updating in a sandboxed environment #363

Open
kornelski opened this Issue Jul 2, 2014 · 204 comments

Comments

Projects
None yet
@kornelski
Member

kornelski commented Jul 2, 2014

馃敟 Here's the new implementation that will be Sparkle 2.0: https://github.com/sparkle-project/Sparkle/tree/ui-separation-and-xpc 馃敟 It implements the changes discussed in the issue below.


There has been a very old branch with a sandbox support, but Andy has rejected it due to unresolved security issues.

So I'm opening an issue here to start a discussion how we can support sandboxed applications in Sparkle while keeping the sandbox as tight as possible.

I think minimal requirements are:

  • The XPC helper must not trust the host app at all, so it must verify integrity of downloaded update and unpack it by itself. The current approach of telling XPC helper "hey, install this path, I've unpacked it and checked it's ok" can't be secure.
  • the XPC can't trust the host to supply a valid DSA key (a compromised host could give a valid and signed update, but signed by the wrong person). The XPC helper must find the trusted DSA key by itself (i.e. find the app's path and read Info.plist from there) and refuse to update any other path.
  • Apple Code Signing verification code needs to be refactored (or not supported in sandboxed environment), because the host app checks against its own signature, but the host app is not supposed to be doing the checking.
@fernandomorgan

This comment has been minimized.

fernandomorgan commented Jul 2, 2014

Hi, updating my status - so, I do have a fork working since May or so, but I am still waiting the legal department ok to publish it.

I don't think it is in finished in terms of having completely addressing Andy's requirements BUT it does at least code signing validation in the XPC copy process.

I am mailing legal today - I do need to write a small doc about the changes, so I share the blame of the lateness - but I probably won't get an answer until tomorrow (California time), and then I will update this item.

I have distributed around 10 updates or so to around 1000 users, mostly in 10.9. There is a very small percentage in 10.8 and only test machines in 10.7. For a smaller group of 20-30 people I send around 5+ upgrades every day (our dev team, etc).

@SevenBits

This comment has been minimized.

SevenBits commented Jul 2, 2014

@fernandomorgan That's great! Look forward to hearing more on this!

@fernandomorgan

This comment has been minimized.

fernandomorgan commented Jul 3, 2014

Ok, here is the first release - I used a fork from your repo, Pornel

https://github.com/yahoo/Sparkle

@SevenBits

This comment has been minimized.

SevenBits commented Jul 3, 2014

@fernandomorgan Could you perhaps include documentation on how to set it up? Are any special steps required to get it to work with sandboxing?

@fernandomorgan

This comment has been minimized.

fernandomorgan commented Jul 3, 2014

actually you don't need to do anything. If your app isn't sandboxed, it uses the old copy. If the app is sandboxed, it will use a XPC helper - com.yahoo.Sparkle.SandboxService.xpc

I will add a note on distributing this helper

@jakepetroules

This comment has been minimized.

Contributor

jakepetroules commented Jul 3, 2014

@fernandomorgan Can you rebase on the latest master and send us a pull request please?

@fernandomorgan

This comment has been minimized.

fernandomorgan commented Jul 3, 2014

Somewhere, somehow, I guess some git info from the old Pornells fork was lost.

@kornelski

This comment has been minimized.

Member

kornelski commented Jul 3, 2014

I'll rebase it, don't worry

@fernandomorgan

This comment has been minimized.

fernandomorgan commented Jul 3, 2014

great! thanks

@kornelski

This comment has been minimized.

Member

kornelski commented Jul 3, 2014

The yahooxpc branch is ready for review.

Due to recent massive reorganization of the repository (sigh) it wasn't easy to merge and there are some messy merge conflicts/regressions, but at least we can start reviewing security of it and test it on top of the codebase.

screen shot 2014-07-03 at 23 27 42

@jakepetroules

This comment has been minimized.

Contributor

jakepetroules commented Jul 3, 2014

Are you sure you pushed? It looks like it's still 32 commits behind master.

@kornelski

This comment has been minimized.

Member

kornelski commented Jul 3, 2014

ok, 32 more

@jakepetroules

This comment has been minimized.

Contributor

jakepetroules commented Jul 3, 2014

OK, I've fixed this up enough that it actually builds. Some things might have been lost during your merging, Xcode complains of a missing implementation for a method in SUUpdater. Probably should compare diffs manually to look things over.

@kornelski

This comment has been minimized.

Member

kornelski commented Jul 4, 2014

Ah, yes. I've been brutally skipping over conflicting bits that didn't seem worth pulling out, e.g. log statements, 10.4 support.

One notable thing I've skipped was support for JSON appcasts. While JSON is fashionable, I don't think it solves enough problems, also xkcd-927.

@SevenBits

This comment has been minimized.

SevenBits commented Jul 4, 2014

I'd be happy to test things tomorrow; I should have some free time. I've been waiting for this feature for quite awhile so it is nice to see this actually happening.

On Jul 3, 2014, at 7:46 PM, Jake Petroules notifications@github.com wrote:

OK, I've fixed this up enough that it actually builds. Some things might have been lost during your merging, Xcode complains of a missing implementation for a method in SUUpdater. Probably should compare diffs manually to look things over.


Reply to this email directly or view it on GitHub.

@jakepetroules

This comment has been minimized.

Contributor

jakepetroules commented Jul 4, 2014

JSON does not have XML schema validation either. :)

@fernandomorgan

This comment has been minimized.

fernandomorgan commented Jul 4, 2014

Yeah. The thing with JSON is that it's pretty easy for the build process to generate a JSON file automatically. That's how I use it

The fork is 10.7+ only because of JSON. Originally used sbjson for 10.6+ later support but we dropped it. Currently only testing from 10.7 to 10.10 but we use both sandboxed and non-sb versions.

Sent from my iPad

On Jul 3, 2014, at 5:01 PM, Jake Petroules notifications@github.com wrote:

JSON does not have XML schema validation either. :)


Reply to this email directly or view it on GitHub.

@jtbandes

This comment has been minimized.

jtbandes commented Jul 7, 2014

Any updates on this review? Any way others can help?

@SevenBits

This comment has been minimized.

SevenBits commented Jul 7, 2014

I鈥檝e been trying it out and will write a full report when I鈥檓 done. Others may certainly help.

On Jul 7, 2014, at 3:43 PM, Jacob Bandes-Storch notifications@github.com wrote:

Any updates on this review? Any way others can help?


Reply to this email directly or view it on GitHub.

@fernandomorgan

This comment has been minimized.

fernandomorgan commented Jul 7, 2014

Thanks! I am hoping to continue improving it too

On Monday, July 7, 2014 12:44 PM, SevenBits notifications@github.com wrote:

I鈥檝e been trying it out and will write a full report when I鈥檓 done. Others may certainly help.

On Jul 7, 2014, at 3:43 PM, Jacob Bandes-Storch notifications@github.com wrote:

Any updates on this review? Any way others can help?


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub.

@SevenBits

This comment has been minimized.

SevenBits commented Jul 7, 2014

Just to confirm, is the XPC support present in the master branch of this repository and not just in Fernando's fork?

@fernandomorgan

This comment has been minimized.

fernandomorgan commented Jul 7, 2014

AFAIK, it's only in the yahooxpc branch/ 聽https://github.com/yahoo/Sparkle聽)

it needs the XPC service - check the sandbox_service target) 聽then SUBasicUpdateDriver's聽

  • (void)installWithToolAndRelaunch:(BOOL)relaunch displayingUserInterface:(BOOL)showUI

has this to determine if we are in a sandbox environment or not聽

聽 聽NSDictionary* environ = [[NSProcessInfoprocessInfo] environment];
聽 聽 BOOL inSandbox = (nil != [environ objectForKey:@"APP_SANDBOX_CONTAINER_ID"]);
BOOLrunning10_7 = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
BOOL useXPC = running10_7 && inSandbox &&
聽 聽 [[NSFileManagerdefaultManager] fileExistsAtPath: [[hostbundlePath] stringByAppendingPathComponent:@"Contents/XPCServices/com.yahoo.Sparkle.SandboxService.xpc"]];
聽 聽 SULog(@"installWithToolAndRelaunch - using xpc=%d", useXPC);

聽聽
... and in a sandbox, we us the XPC service instead

if( useXPC )
[SUXPC launchTaskWithLaunchPath: relaunchToolPath arguments:arguments];
else
聽 聽 聽 聽 [NSTask launchedTaskWithLaunchPath: relaunchToolPath arguments: arguments];

the XPC service has to include the code signing verifier to, at a minimum (there's room to improve on this), to validate the signature before installing.

On Monday, July 7, 2014 1:00 PM, SevenBits notifications@github.com wrote:

Just to confirm, is the XPC support present in the master branch of this repository and not just in Fernando's fork?

Reply to this email directly or view it on GitHub.

@jakepetroules

This comment has been minimized.

Contributor

jakepetroules commented Jul 7, 2014

@fernandomorgan This is a better way of checking if you're sandboxed:

- (BOOL)isSandboxed
{
    BOOL sandboxed = NO;

    SecStaticCodeRef code = NULL;
    SecStaticCodeCreateWithPath((__bridge CFURLRef)[self bundleURL], kSecCSDefaultFlags, &code);

    SecRequirementRef requirement = NULL;
    SecRequirementCreateWithString(CFSTR("entitlement[\"com.apple.security.app-sandbox\"] exists"), kSecCSDefaultFlags, &requirement);

    if (code && requirement)
        sandboxed = (SecStaticCodeCheckValidity(code, kSecCSBasicValidateOnly, requirement) == errSecSuccess);
    if (requirement)
        CFRelease(requirement);
    if (code)
        CFRelease(code);

    return sandboxed;
}

@SevenBits It's in the yahooxpc branch for now, we've not yet merged it into master.

@kornelski kornelski added this to the 1.9 milestone Jul 14, 2014

@grouchal

This comment has been minimized.

grouchal commented Jul 16, 2014

I have been trying the yahooxpc branch and have tried to configure the Test App to work with the xpc code for an update. It seems the branch is not working at the moment for a few reasons:

  • The sandbox_service target doesn't include the main.m file for the sandbox_service.
  • The sandbox_service doesn't include the sparkle.framework
  • The SANDBOX_SERVICE_NAME_STR seems to be empty
  • The Test App doesn't have the sandbox_service included in the build phases and installed in the XPCServices folder
  • The current code has the xpc check commented out and the check uses the empty SANDBOX_SERVICE_NAME_STR which causes it not to work.
  • The update that is downloaded from the default service is not signed properly and causes update erros.

I have worked around all of these issues and can get the service to work, but think before the xpc changes are merged into the master these issues should be addressed to make it more obvious for others.

@SevenBits

This comment has been minimized.

SevenBits commented Jul 16, 2014

I found those same issues as well. They definitely need to be addressed.

On Jul 16, 2014, at 5:22 AM, Al Briggs notifications@github.com wrote:

I have been trying the yahooxpc branch and have tried to configure the Test App to work with the xpc code for an update. It seems the branch is not working at the moment for a few reasons:

The sandbox_service target doesn't include the main.m file for the sandbox_service.
The sandbox_service doesn't include the sparkle.framework
The SANDBOX_SERVICE_NAME_STR seems to be empty
The Test App doesn't have the sandbox_service included in the build phases and installed in the XPCServices folder
The current code has the xpc check commented out and the check uses the empty SANDBOX_SERVICE_NAME_STR which causes it not to work.
The update that is downloaded from the default service is not signed properly and causes update erros.
I have worked around all of these issues and can get the service to work, but think before the xpc changes are merged into the master these issues should be addressed to make it more obvious for others.


Reply to this email directly or view it on GitHub.

@jtbandes

This comment has been minimized.

jtbandes commented Jul 18, 2014

Testing this stuff out, it seems like the problem experienced by the current master branch, when the host is sandboxed, is that +[NSTask launchedTaskWithLaunchPath:arguments:] fails, raising the exception Couldn't posix_spawn: error 1 and logging the following to the console:

kernel[0]: exec of ~/Library/Containers/.../.Sparkle/Autoupdate.app/Contents/MacOS/Autoupdate denied since it was quarantined by ... and created without user consent, qtn-flags was 0x00000006`

However, it seems the same error occurs on this branch (only in the XPC service, since it's the one doing the +launch...). Is nobody else experiencing this? Setting up LSFileQuarantineExcludedPathPatterns seems like it would be the wrong solution, especially since the non-XPC version has the same issue.

@fernandomorgan

This comment has been minimized.

fernandomorgan commented Jul 18, 2014

There's some code specifically to remove the quarantine bit. Might be missing

Sent from my iPad

On Jul 17, 2014, at 5:21 PM, Jacob Bandes-Storch notifications@github.com wrote:

Testing this stuff out, it seems like the problem experienced by the current master branch, when the host is sandboxed, is that +[NSTask launchedTaskWithLaunchPath:arguments:] fails, raising the exception Couldn't posix_spawn: error 1 and logging the following to the console:

kernel[0]: exec of ~/Library/Containers/.../.Sparkle/Autoupdate.app/Contents/MacOS/Autoupdate denied since it was quarantined by ... and created without user consent, qtn-flags was 0x00000006`

However, it seems the same error occurs on this branch (only in the XPC service, since it's the one doing the +launch...). Is nobody else experiencing this? Setting up LSFileQuarantineExcludedPathPatterns seems like it would be the wrong solution, especially since the non-XPC version has the same issue.


Reply to this email directly or view it on GitHub.

@jtbandes

This comment has been minimized.

jtbandes commented Jul 18, 2014

It seems the removexattr call is failing; errno is set to EPERM. This kind of makes sense. But I'm not sure why it's working for anyone else.

@digitalmoksha

This comment has been minimized.

Contributor

digitalmoksha commented Feb 10, 2017

I'll try to chime in since I've been wrangling with this the last couple of days.

Related thread

Only the Downloader needs entitlements - the other xpc's do not. The codesign_xpc tool takes this into account - if there is an appropriately named entitlement file, it gets applied. Per the INSTALL instructions, since my app itself has the correct entitlements, I'm not including the download xpc.

What I've learned through much trial and error (maybe others would consider them obvious):

  1. The Sparkle.framework needs to be sandboxed
  2. The xpc services should exist in an XPCServices folder in MyApp.app/Contents. I tried placing them in the Sparkle.framework itself and signing them correctly. However verifying the signature of the app produces an error: unsealed contents present in the root directory of an embedded framework. In subcomponent: ....Contents/Frameworks/Sparkle.framework
  3. Make sure you run a codesign -vvvv --deep MyApp.app to verify the entire app is signed correctly. I would love to see the generate_appcast do this as an extra sanity check.
@zorgiepoo

This comment has been minimized.

Member

zorgiepoo commented Feb 10, 2017

@digitalmoksha is pretty correct here.

The downloader service is the only one that can have entitlements. The other XPC services need to be non-sandboxed.

The downloader service doesn't have to be sandboxed, but you most likely want it to be. It just has an exception in the entitlements to make network requests.

The test app has a couple of exceptions that you probably shouldn't worry about, so I wouldn't look at it closely.

If you use Xcode, you can add a build phase to add XPC services, after you've signed them.

Lastly, using the XPC services and sandboxing your application are somewhat orthogonal. Eg: you can make use of the XPC services even if your application is not sandboxed. If your application is sandboxed though, you will have to use the XPC services. If your sandboxed app already has a network exception to download data, you don't have to include the downloader service. XPC services provides privilege separation which is a prerequisite for sandboxing applications, but also fault tolerance, idleness..

@milke

This comment has been minimized.

milke commented Feb 10, 2017

Thanks guys. Some things I've already figured out:

  • I haven't really looked into codesign_xpc, I like to manage my own run scripts with custom file locations, but once I looked into it, things became clearer.
  • XPC services must reside in MyApp.app/Contents/XPCServices and not embedded in a framework (like system frameworks do), I also learnt that one the hard way :-(
  • I know the downloader service is optional and has to be used only if the main application is sandboxed and doesn't allow network access (which is my case). It can be used though in other cases too (improve responsibility separation, security and all that鈥).

My initial question popped-up without examining what XPC services (other than the downloader) do and I immediately wondered why they aren't sandboxed if this branch claims to provide Sparkle for properly sandboxed applications (properly in the sense not only having com.apple.security.app-sandbox = YES, but also taking care not to allow compromised host app to tell XPC helper to execute arbitrary code and completely escape the sandbox and all other things already discussed at the beginning of this thread). I guess I was just too quick to ask the question without studying the whole structure of the framework, with all of its helper components. Bear in mind the last time I've dealt with Sparkle, everything was done right from the framework code and the only external helper (if I remember correctly) was relaunch (or something like that), which relaunched the application after it has been updated :-)

@zorgiepoo

This comment has been minimized.

Member

zorgiepoo commented Feb 10, 2017

I figure it'd be best to clear this up about security because it's causing confusion.

Ensuring proper privilege separation, and having a component (or process) running at a higher level of privileges that doesn't implicitly trust the input from another component running a lower or equivalent level of privileges, actually has very little to do with sandboxing. Supporting sandboxing securely is a small part of the overall picture of privilege separation.

Even if you don't sandbox your app, my branch is still more secure than master right now. And aside from XPC services (which again is orthogonal to sandboxing), to do proper privilege separation, you can't arbitrarily shell out for authorization like master currently does, which is why creating launchd agents and daemons was necessary. Because a daemon runs as root-level, what the installer is allowed to do is also carefully restricted (a privilege separation concept that is unrelated to sandboxing or even XPC services).

So you need a solid privilege separation model even if XPC services & entitlements aren't used. When you add sandboxing on top, that is adding an additional layer of defense. It appears that previous sandbox forks were rejected because the current security model of master (not the forks themselves) is lacking.

[edit]: I think this is a good comparison to make my point: re-read the first post in this thread for the "minimum requirements". Substitute "XPC helper" for "Autoupdate" (the current tool Sparkle uses to perform the installation), and you will realize why master's model fails too.

volodyko pushed a commit to volodyko/Sparkle that referenced this issue Oct 9, 2017

Al Al
Example App works for sandboxed updating
Fixes for sparkle-project#363.

Still remains a problem with the signing of the update - that can only
be fixed by commenting out the checks
@milke

This comment has been minimized.

milke commented Nov 8, 2017

After another nine months, I just want to chime in again to report my experiences on using @zorgiepoo fork (I haven't really checked if it was merged into master or ui-separation-and-xpc branches). I've been using it for updates of this application since mid-March. Firstly it was a limited number of closed-beta testers and since mid-August to roughly 2000 downloaded copies, as the application is now available as public beta. I haven't had problems nor anybody else has reported any. My configuration is pretty simple, so there may be still some hidden bugs, but I haven't hit any of them.

Once again, I'd like to thank to all contributors maintaining the project and especially @zorgiepoo for his hard work on his fork.

@IngmarStein

This comment has been minimized.

IngmarStein commented Nov 8, 2017

I've also used it successfully for months in http://github.com/IngmarStein/Monolingual and have been looking forward to this being merged into master for quite some time now. Thanks @zorgiepoo!

@swisspol

This comment has been minimized.

swisspol commented Feb 13, 2018

I went through the entire thread and linked description but I don鈥檛 get it. Can someone briefly explain how it is even possible for a sandbox app to update itself considering it doesn鈥檛 have read / write access to /Applications? How does going through launchd and XPC makes this not a problem? Or will the installer always prompt for root privileges when updating a sandboxes app? And how is all this not some sort of sandbox bypass Apple will eventually close?

@kornelski

This comment has been minimized.

Member

kornelski commented Feb 13, 2018

Can someone briefly explain how it is even possible for a sandbox app to update itself considering it doesn鈥檛 have read / write access to /Applications?

The app is split in two: main part that doesn't have access, and XPC that does.

This is secure if the XPC service doesn't trust the main part of the app and refuses to write anything that isn't externally signed to be a legitimate update.

And how is all this not some sort of sandbox bypass Apple will eventually close?

This may happen if Apple decides to kill all Mac software except the software in the Mac AppStore. However, so far Apple allows non-Store apps to voluntarily define their own sandbox permissions.

@swisspol

This comment has been minimized.

swisspol commented Feb 13, 2018

Thanks. So basically the XPC service is not sandboxed or sandboxed with entitlements to read / write anywhere? Where is this defined in the code, at a glance I couldn鈥檛 find an entitlement file for the XPC service.

@balthisar

This comment has been minimized.

balthisar commented Mar 4, 2018

I'm finally getting around to implementing this branch, but I'm confused about the deprecation for SUUpdater; right now I'm creating a singleton upon first reference, and not loading from a nib (because no Sparkle references in the App Store version). Later, I'm programmatically binding the UI via referencing the singleton, as needed (i.e., I'm not creating any bindings until the Preferences UI is loaded, which might never happen).

I could use the SPUUpdater, and write my own singleton, but it would look pretty much like SUUpdater does right now.

Right now these deprecation warnings are the only warnings in my code, and anal-retentive me is bothered by them. Is there a best practice for implementing the new API? Thanks.

@ksuther

This comment has been minimized.

Contributor

ksuther commented Mar 5, 2018

What I've found works well enough is to use SPUStandardUpdaterController in the app delegate (_updaterController = [[SPUStandardUpdaterController alloc] initWithUpdaterDelegate:self userDriverDelegate:nil]).

Then when the preferences are shown do something like [preferencesController setUpdater:[[self updaterController] updater]] and bind on self.updater in the nib.

Then it can be #ifdefed for Developer ID builds fairly easily.

@balthisar

This comment has been minimized.

balthisar commented Mar 7, 2018

Thanks, @ksuther, that tip helped. I ended up keeping it simple by creating it my AppController (to hook up the menu, and give it a chance to run), and binding into an NSUserDefaultsController directly in the Preferences pane rather than binding to anything Sparkle-related.

@spearway

This comment has been minimized.

spearway commented Mar 21, 2018

I am trying to use this branch to update an application that is distributed on a dmg without any success, has this been tested?

@digitalmoksha

This comment has been minimized.

Contributor

digitalmoksha commented Mar 22, 2018

I distribute my app on a dmg, and updating it with this branch works no problem. The app does have to be copied off the dmg first...

@sweetppro

This comment has been minimized.

sweetppro commented Mar 22, 2018

I have 9 apps which update via .dmg using this branch.
:)

@milke

This comment has been minimized.

milke commented Mar 22, 2018

Same as with @digitalmoksha and @sweetppro.

@aonez

This comment has been minimized.

aonez commented May 25, 2018

@digitalmoksha, @sweetppro and @milke, have you done something special to change from master to this branch? I'm just getting this error when installing:

kernel: Sandbox: Process(XXX) deny(1) job-creation
com.apple.xpc.launchd[1]: (com.apple.xpc.launchd.user.domain.XXX.Aqua) Caller not allowed to perform action: Process.XXX, action = service submission, code = 1: Operation not permitted, uid = 501, euid = 501, gid = 20, egid = 20, asid = 100007
Process [Sparkle][XXX]: Submit error: Error Domain=CFErrorDomainLaunchd Code=4 "(null)"
Process [Sparkle][XXX]: Failed to submit installer job
Process [Sparkle][XXX]: Error: Failed to gain authorization required to update target

@milke

This comment has been minimized.

milke commented May 25, 2018

@aonez, I haven't used master branch at all, I jumped straight to this one and I haven't experienced any problems. I don't know whether this branch made it into the official Sparkle 2.0 master branch yet.

@sweetppro

This comment has been minimized.

sweetppro commented May 28, 2018

@aonez

This comment has been minimized.

aonez commented May 28, 2018

Make sure you add the XPCServices to your app.

That was it, thanks a lot @sweetppro!

@sweetppro

This comment has been minimized.

sweetppro commented May 28, 2018

@tomeumasco

This comment has been minimized.

tomeumasco commented Jun 28, 2018

Hi, I have a similar problem when trying to install the update.

[Sparkle] Error: Failed to gain authorization required to update target [Sparkle] Error: An error occurred while launching the installer. Please try again later.

but I do not know how to add XPCServices to my app. Can somebody help me?

Thanks for your time.

@digitalmoksha

This comment has been minimized.

Contributor

digitalmoksha commented Jun 30, 2018

My build process is quite different than most (RubyMotion), but at the end of the day, you need the .xpc services in the XPCServices folder:

MyApp.app
   Contents
      ...
      Frameworks
         ...
         Sparkle.framework
      XPCServices
         org.sparkle-project.InstallerConnection.xpc
         org.sparkle-project.InstallerLauncher.xpc
         org.sparkle-project.InstallerStatus.xpc
@tomeumasco

This comment has been minimized.

tomeumasco commented Jul 1, 2018

@digitalmoksha Oh, great. Now I got it.
Thanks a lot!

@kolpanic

This comment has been minimized.

Contributor

kolpanic commented Nov 26, 2018

I've been working to get our apps updated to the latest sandboxed and hardened version.

Since SUUpdater is marked as deprecated, I'm trying to use SPUStandardUpdaterController instead. Since our apps are distributed both on MAS and directly, I set up Sparkle programmatically (instead of instantiating an object in a XIB) like this, appropriately wrapped in #ifs:

    lazy var sparkleUpdater: SPUStandardUpdaterController = {
         return SPUStandardUpdaterController(updaterDelegate: nil, userDriverDelegate: nil)
     }()
     
     @IBAction func checkForUpdates(_ sender: AnyObject?) {
         sparkleUpdater.checkForUpdates(sender as Any)
     }

While this works, I wonder about SPUStandardUpdaterController's updaterDelegate. I'm passing nil, but, if I wanted to pass an object, which delegate methods should be implemented (even though, AFAICT, they're all optional)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment