Code Monkey home page Code Monkey logo

letsmove's People

Contributors

1951fdg avatar andypotion avatar applingua avatar boyvanamstel avatar c-had avatar cstigler avatar fulldecent avatar inndy avatar kapeli avatar klacoste avatar ksuther avatar mattprowse avatar minh-ton avatar monsterzz avatar pegolon avatar pilotmoon avatar pointum avatar potionfactory avatar rm1210 avatar robrix avatar rsms avatar scosman avatar sergiomiranda avatar tjw avatar venj avatar vitu avatar vlahupetar avatar vslavik avatar wbyoung avatar xhruso00 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

letsmove's Issues

Doesn't work with sandboxed apps

I tried using LetsMove in my sandboxed app, and I kept getting errAuthorizationDenied when requesting the authorization to do the move. It turns out that according to Apple's Sandbox Design guide, sandboxed apps can't use Authorization Services.

A note at the top of README.md could save people some time.

(Alternately, you could detect if the app is sandboxed, and show an alert advising the user to quit and move the app manually.)

Detect/disable translocation when moving app on macOS Sierra

As outlined at http://weblog.rogueamoeba.com/2016/06/29/sierra-and-gatekeeper-path-randomization/, macOS Sierra introduces a new security feature called "Gatekeeper Path Randomization" (or "app translocation", as it's called on the API level). The basic gist is that if you download and run a Gatekeeper app from the Downloads folder, the OS will copy the app into a read-only disk image and run it from there instead. See the link above for more details.

This applies until the user moves the app to any other location (not just the Applications folder), after which the OS will just run the app normally. However, the move is only recognized if performed using the Finder. If you move the app another way, e.g. using "mv" in the Terminal, the app will continue to be translocated when run, even if it's in /Applications.

I've only gotten a little chance to fool around with this on the WWDC seed, but it does appear that the move performed by PFMoveApplication using NSFileManager doesn't disable translocation. So, the app will be moved successfully, but will still be run translocated, even when launching from /Applications. This will also cause PFMoveApplication to prompt the user to move the app a second time, since the app is in fact not being run from /Applications, but rather from its translocated read-only disk image.

I haven't had a chance to try any of this yet, but a new header in the 10.12 SDK at <Security/SecTranslocate.h> contains an API named SecTranslocateURLShouldRunTranslocated() which outlines the circumstances under which an app should be run as translocated. It reads:

@discussion The policy is as follows:
    1. If path is already on a nullfs mountpoint - no translocation
    2. No quarantine attributes - no translocation
    3. If QTN_FLAG_DO_NOT_TRANSLOCATE is set or QTN_FLAG_TRANSLOCATE is not set - no translocations
    4. Otherwise, if QTN_FLAG_TRANSLOCATE is set - translocation

So, I think what the Finder is doing is to set that QTN_FLAG_DO_NOT_TRANSLOCATE flag in the quarantine attributes for the file when the user moves it to a different location. I did some quick digging with xattr in the Terminal, and I do see a bit getting flipped in the com.apple.quarantine attribute when moving a downloaded app on Sierra. Assuming this is correct, then this should be fairly simple for PFMoveApplication to set that same quarantine attribute when it performs its move as well.

It might also be worth adding some logic to check and see whether the app is running from a translocated location (there is other API in SecTranslocate.h that lets you detect this). If it's already being translocated from /Applications, then instead of needing to recopy the entire app, we could potentially just set the quarantine flag on the existing app, so that it doesn't get translocated anymore.

Public domain license alternatives

Could this library perhaps be released under the CC0 or MIT or similar license? IIRC with just a plain 'public domain' notice this may limit this library's use in projects developed or distributed in certain jurisdictions.

Xcode warning

Hi,

I get the following warning in Xcode 4 when building a project with PFMoveApplication:

warning: no previous prototype for function 'PFMoveToApplicationsFolderIfNecessary' [-Wmissing-prototypes,2]

There are a few apparent fixes:
(1) add "void" as the function's parameter as per http://stackoverflow.com/a/7764651/111870
(2) disable -Wmissing-prototypes

I /could/ do #2, but I -Wmissing-prototypes is pretty standard, and I think it would be reasonable to add the void parameter instead. Thoughts?

Thanks!
Ari

10.4 compat

if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_4) {

in IsInDownloadsFolder()
has two problems:

  1. it will match 10.4.x releases while it looks like it should only match on 10_5. It should probably be: floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_5

  2. NSAppKitVersionNumber10_4 is only defined in 10.5 SDK (and NSAppKitVersionNumber10_5 only in 10.6 SDK) so you'll need to introduce private copy for 10.4 SDK anyway with sth. like:

    // only defined in SDK 10.6

    ifndef NSAppKitVersionNumber10_5

    define NSAppKitVersionNumber10_5 949

    endif

Not pretty, but works.

  1. Also, when building with 10.4 SDK compiler complains in:
    if (![fm copyItemAtPath:bundlePath toPath:destinationPath error:&error]) {
    because copyItemAtPath:toPath:error: is 10.5 only so it probably won't work

App deletes itself when unzipped into /Applications as root

A user filed this issue report against my app:

https://gitlab.com/gnachman/iterm2/-/issues/11033

I am able to reproduce it. Here are the exact steps:

  1. Download a zip file of my app (or any app that uses LetsMove) into ~/Downloads/app.zip.
  2. In Terminal, cd /Applications; sudo unzip -x ~/Downloads/app.zip
  3. Launch the app and agree to move it to /Applications.
  4. You are left with an empty folder.

I added some logging and here's what's happening:

bundlePath is /private/var/folders/jk/2nklbh0x5ksc192jsm9nhnhc0000gn/T/AppTranslocation/F5172787-71B6-4B5D-A94D-E50E9670D998/d/iTerm2.app

IsInApplicationsFolder() returns false

destinationPath is /Applications/iTerm2.app

needAuthorziation is YES (destination folder exists and is not writable)

LetsMove attempts to trash /private/var/folders/jk/2nklbh0x5ksc192jsm9nhnhc0000gn/T/AppTranslocation/F5172787-71B6-4B5D-A94D-E50E9670D998/d/iTerm2.app next.

All the methods fail, ending with the following applescript error dictionary:

{
    NSAppleScriptErrorAppName = Finder;
    NSAppleScriptErrorBriefMessage = "Not authorized to send Apple events to Finder.";
    NSAppleScriptErrorMessage = "Not authorized to send Apple events to Finder.";
    NSAppleScriptErrorNumber = "-1743";
    NSAppleScriptErrorRange = "NSRange: {200, 39}";
}

But it succeeded enough to leave behind an empty folder.

% ls -laR /Applications/iTerm2.app/
total 0
0 drwxr-xr-x@   2 root  admin    64 Aug  6 10:57 ./
0 drwxrwxr-x  110 root  admin  3520 Aug  6 10:57 ../

I don't think it'll be possible to detect that /Applications/myapp is the same as the translocation folder (maybe inode numbers would match? But I wouldn't count on it). One possible fix would be to rename the destination, copy the app over, and then delete the renamed folder. That has the downside that a failed move would leave behind a randomly named folder in /Applications.

Maybe someone on the project will have a better idea. I'm happy to send a PR once we have a plan in place.

LetsMove dialog breaks with Screen Time enabled, and blocks app opening

I'm a developer with LetsMove integrated into my app SelfControl. In macOS Big Sur, you can turn on "Downtime" or other app limits using the Screen Time. In this case, affected apps have their windows taken over and show a "Time Limit" screen, with some buttons allowing the user to ignore the limit and continue.

When opening my app during Downtime without LetsMove, it opens fine (shows the Time Limit screen, and can be bypassed using the Ignore Limit button). With the LetsMove dialog enabled, the app still shows the "Time Limit" screen but the buttons aren't clickable. So there's no way to bypass the dialog and continue. It looks like it's some sort of window focus issue.

Screen Shot 2021-03-20 at 11 56 02 PM

Ideally, LetsMove would work seamlessly with Screen Time and the buttons would be clickable!

new release

Hi,

could you make a new point release with that last commit? That would let me remove some hack from the Podfile that renames the lproj directory names locally.

Fails silently if it tries to replace an already running application

If you have an old instance of your program running from the Applications folder
and people launch a new instance (let's say from the Downloads folder) the moving will fail silently as it cannot replace the already running application.

What the system does when you e.g. drag and drop the new one into the Applications folder is show you a Warning message:

"The operation can’t be completed because the item “XYZ.app” is in use."

I think LetsMove needs a customizable warning message where we can say "Close the old version of XYZ so we can replace it in your Applications folder."

10.7 and 10.8 Compatibility

I tried converting the code to ARC compatible one, it worked for the most part, but it broke on clang error.

Silicon Support

The linked and embedded framework 'LetsMove.framework' is missing one or more architectures required by this target: arm64.

Just a note that the above is received when trying to build a Universal app in Xcode 12 beta with this framework.

Logging an issue for others and my projects.

Odd installation behavior

Using the Lets Move Test app I noticed this that I got this alert:

screen shot 2016-09-08 at 9 39 37 pm

I noticed that this line:
NSArray *userApplicationsDirs = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSUserDomainMask, YES);

produces an array like similar to this:
screen shot 2016-09-08 at 9 39 55 pm

Passing NO instead of YES gives you this:

screen shot 2016-09-08 at 9 40 15 pm

And therefore, the installing in /Applications/... instead of /Users/username/Applications

screen shot 2016-09-08 at 9 40 25 pm

I'm guessing this is a mistake or am I'm missing something here?

Extra arguments treated as documents by NSDocument based applications

I tried adding this into a document based application, but it means I get 2 alerts after relaunch, as it tries to open both the arguments as documents. I don't see anywhere where you use the arguments (app path and old pid). I can easily just remove the arguments but I thought you might like to know about the issue.

10.4/10.5 SDKs in Project Settings

The project still has code and references to the old SDKs:

screen shot 2017-11-21 at 14 16 41

This causes this warning:
libarclite_macosx.a(arclite.o)) was built for newer OSX version (10.6) than being linked (10.5)

I thought this commit is supposed to drop anything below 10.6. I could make a PR that removes obsolete settings and code.

Link against Security.framework

Hello. The readme mentions that as a part of the setup I am supposed to link my application against Security.framework. I looked this up but didn't find any information about this. Is this still needed or is it outdated? Thanks in advance

Add tags to repository

I'd like to create a spec to allow easy integration of the code using CocoaPods. However, to do this cleanly, the repository needs to have version tags.

Could you push tags (at least) for the latest version?

Some fixes (NSTask, escaping, better process/disk image detection)

Sorry to dump these but I figured it was better than not sharing at all.

ContainingDiskImageDevice, ShellQuotedString, DeleteOrTrash and the various NSTask invocations should be everything, or there's little enough code that you can probably just diff PFMoveApplication.m.

nriley/Pester@6457a9e
(Of course, the OS compatibility/strings changes are ones you won't want.)

Github download outdated.

Hi!

I just wanted to let you know if you download LetsMove (from the download button) you get an older version. (it only has 2 localizations).

Apart from that, great code pal!

Question about performing actions with privileges

A comment here (https://github.com/potionfactory/LetsMove/blob/master/PFMoveApplication.m#L481-L485) says "AuthorizationExecuteWithPrivileges is deprecated. We want to still use it since there's no good alternative (without requiring code signing)." Does anyone know if there is any alternative?

In my application, I need to add a wireless network to the top of the preferred networks list and later remove it. For this I can use this function: https://developer.apple.com/documentation/securityfoundation/sfauthorization/1417652-obtainwithright. But then the password is still in the user's Keychain, and I'd like to clean that up as well. There is another function, CWKeychainDeleteWiFiPassword, but it does not have a parameter to pass in an authorization, and so unless you're running it as root, you can't delete from the system Keychain. I don't want to use SMJobBless as I don't want to install privileged helpers (this is a standalone utility that should not require installation), and I don't want to pay Apple $99/year just to allow a user to delete a password. Thanks for any help you can provide.

Problem with "xattr -r" on 10.5

The -r flag should not be present when calling xattr on 10.5. Currently on 10.5 the call is doing nothing, because xattr is balking at the -r flag.

I'm guessing this is simply a mistake and the code has it is the wrong way round, setting -r for 10.5 and not for 10.6, when it should be vice versa.

This does, however, raise the question of why -r would be needed on 10.6, since it's not being used for 10.6 at the moment and things seem to be working?

Move as root (i.e. ask permission and create app with root owner)

First off, great little library you've created here! Thanks!

I was just wondering if it's possible to make LetsMove create the bundle with root privileges?
Because I have an app which accesses system resources so ideally I'd like it to not only move but also change the ownership to root (similar to how Tunnelblick does it). Can this be achieved with LetsMove?

Thanks again!

App not being deleted on macOS Big Sur and later

The framework copies the app to /Applications but doesn't remove it from ~/Downloads.

When an app is running with the attribute "com.apple.quarantine" (meaning downloaded from the Internet) it's running in so called translocation mode and the current workaround for this - trashing the app via AppleScript using Finder. Well, it no longer works on macOS Big Sur and Monterey obviously:

Trash AppleScript error: {
NSAppleScriptErrorAppName = Finder;
NSAppleScriptErrorBriefMessage = "Not authorized to send Apple events to Finder.";
NSAppleScriptErrorMessage = "Not authorized to send Apple events to Finder.";
NSAppleScriptErrorNumber = "-1743";
NSAppleScriptErrorRange = "NSRange: {267, 70}";

There's a solution but as a result a user must allow to control Finder (which is not cool unfortunately 😢 ):

Screen Shot 2021-09-27 at 9 55 41 PM

You will need to:

  • add "com.apple.security.automation.apple-events" attribute to your code signing entitlements
  • add NSAppleEventsUsageDescription to the app plist file, e.g.
<key>NSAppleEventsUsageDescription</key>
<string>Please allow the app to move itself via Apple Script.</string>

crash if user chooses not to move

On some machine/macOS versions, our app would crash with

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSApp with wrong _running count'

after the user clicked the 'do not move' button.

We avoided the crash by calling PFMoveToApplicationsFolderIfNecessary inside of application *DID* FinishLaunching instead of application *WILL* FinishLaunching.

Endless while loop in -[NSString stringByIterativelyResolvingSymlinkOrAlias] when link is in /private/var/...

I accidentally noticed this problem when I tried to use my app to open an image created but not yet saved by Slicy app. (I hit Space bar in Slicy to view the image in QuickLook, then pressed the "Open with MyApp" button to launch my app.)

The path appeared to be the following:

/private/var/folders/zz/tgcc5k_17cscxxwb212fydw80000gn/T/CB856778-0148-4C5F-B15C-839B6EF77469/SNPlaceholder.png

My app uses your -[NSString stringByResolvingSymlinksAndAliases] to resolve possible symlink in the path before opening the file, however, this causes an endless while loop in -[NSString stringByIterativelyResolvingSymlinkOrAlias].

I'm not sure how to fix it myself. Your help would be greatly appreciated!

Support for nested applications (apps contained in a bundle)

My latest commit at my fork enables support for nested applications, I have submitted a pull request for all commits except this one, I left this commit out because I don't know if you approve of the changes.

1951FDG@29165bb

I made the changes because I have an app (1) which contains app (2), which can be launched from within app (1), similar to Performance Tools of Xcode. I don't want app (2) to be deleted in app (1) when moved. I added a new function, hope you like the name "IsApplicationAtPathNested". Tested the code. Comments welcome!

Example Directory Structure (Note the fact that there is a component named Applications!):

APP1.app/Contents/Applications/APP2.app

PList settings to control behaviour

It would be great if a few details could be controlled by settings in the application's plist. Here are my suggestions:

  • LMForceMove (bool): Defaults to false. If set to true it disables the options "Do Not Move" and "Do not show this message again" and has a "Cancel" button in place of "Do Not Move" which closes the application.
  • LMUserDirectory (string: auto | always | never): Defaults to auto.
    • auto: current behaviour.
    • never: will always install to /Applications.
    • always: will always install to ~/Applications (providing this exists).

For LMUserDirectory another option might be a simple boolean which disables the user directory and forces install to /Applications. This would suffice for my use-case.

Would you be willing to accept a PR with the above? I have a requirement for them and rather than create a fork it would be awesome if others could also benefit from this.

The main window also appears?

Your sample project seems working fine. But when I create a new project and add your components. The main window will appear along with your window. I'm using the latest version of xcode and OS X. Could you please tell me that what I should I do? Thanks.

Copy fails for non-administrator users

Using NSFileManager operations as a standard user (not administrator) will fail to copy into /Applications. I believe the right thing to do here is to use an Authorization, but it's a bit of a pain as you have to do a lot of work and spawn a separate process that does the privileged operation. Any thoughts on a better way to handle this? If not I'd be happy to write a patch that uses an Authorization.

After re-launch, application is no longer the active application

In my testing, the application is no longer the active application after it relaunches. The best I can figure right now is that this is because it starts running while the old application is running, and that when the old copy resigns its active status the next application down the stack takes focus. A simple hack to fix this is to have the new application wait a couple seconds before launching, like this:

[NSTask launchedTaskWithLaunchPath:@"/bin/bash" arguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"/bin/sleep 2 ; /usr/bin/open "%@"", destinationPath], nil]];

That's a bit of hack though, as it just assumes that 2 seconds is enough for the previous app to finish. Something more correct would likely check for the previous pid still existing in a loop before launching the new copy.

deprecation warnings on 10.9

I'm not sure if there's any interest to look into that given the retro compat argument, but here it goes, feel free to close this as necessary..

NSString+SymlinksAndAliases.m:214:7: warning: 'CFURLGetFSRef' is deprecated: first deprecated in OS X 10.9 [-Wdeprecated-declarations]
                if (CFURLGetFSRef(url, &fsRef))

NSString+SymlinksAndAliases.m:217:16: warning: 'FSResolveAliasFileWithMountFlags' is deprecated: first deprecated in OS X 10.8 [-Wdeprecated-declarations]
                        OSErr err = FSResolveAliasFileWithMountFlags(

NSString+SymlinksAndAliases.m:221:28: warning: 'CFURLCreateFromFSRef' is deprecated: first deprecated in OS X 10.9 [-Wdeprecated-declarations]
                                CFURLRef resolvedUrl = CFURLCreateFromFSRef(kCFAllocatorDefault, &fsRef);

CocoaPods support

Please add this library to CocoaPods so it's easier to integrate it into projects.

LetsMove crashes my app on High Sierra when trying to trash it

Hello! Hoping somebody might have an idea about why LetsMove is crashing in my open-source Mac app SelfControl on the High Sierra public beta (just tried to add it last week).

The behavior I’m seeing:

  1. Open SelfControl from the Downloads folder.
  2. Prompt appears, click to move it to the Applications folder.
  3. SelfControl appears to be moved correctly to the Applications folder, but is not restarted.
  4. Open SelfControl again from the Applications folder.
  5. Prompt appears again asking to move it to the Applications folder.
  6. Click to move it to the Applications folder again.
  7. SelfControl quits and is trashed away from the Applications folder.

I didn’t do anything special with the integration - just the one-line call. You can see the full diff (+6 lines) of the installation here.

I determined that the issue is the AppleScript that gets run on line 390 of PFMoveApplication.m to trash the app. On the LetsMove sample app, it runs successfully. But in SelfControl, despite having basically identical parameters (the app is in the /AppTranslocation/ folder in both cases), running that AppleScript crashes the app and it never gets further. I also see an error logged in the console that isn’t logged for LetsMove: OSErr AERemoveEventHandler(AEEventClass, AEEventID, AEEventHandlerUPP, Boolean)(spec,phac handler=0x7fff8fde98ee isSys=YES) err=0/noErr

Any ideas what this could be? I’ll keep trying to debug but I’m not sure where to go from here.

Need to detect existing Mac App Store app as needing authorization.

// Path where we would expect a Mac App Sore receipt.
NSString *destinationMASReceiptPath = [NSString stringWithFormat:@"%@/Contents/_MASReceipt/receipt",destinationPath];
BOOL needMASAuthorization = [fm fileExistsAtPath:destinationMASReceiptPath isDirectory:FALSE];

// Check if we need admin password to write to the Applications directory
BOOL needAuthorization = ([fm isWritableFileAtPath:applicationsDirectory] == NO);

if(needMASAuthorization)needAuthorization=TRUE;

AuthorizedInstall fails

This is on 10.13, but I'm not sure OS version is important

pid = wait(&status); returns immediately with EINTR

checking for EINTR and repeating wait seems to fix it

        do {
            pid = wait(&status);
        } while (pid == -1 && errno == EINTR);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.