Prevent multiple copies of a file on OS X - objective-c

I have a file somewhere on the hard drive and I would like to make sure it is only accessed by a particular program and not
backed up by Time Machine
copied by the Versions feature of OS X 10.7
in any other way copied by the system - unless the user explicitly does so i.e. by copying it to an other directory.
Is it possible to do this programmatically in Objective-C or C?

As far as I know, using CSBackupSetItemExcluded should be enough - you'll need to link against the CoreServices framework to access this. This takes care of Time Machine and Versions. I'm not aware of any other cases where the system will automatically copy the file unless explicitly done by the user.

It is impossible to make sure with absolute certainty that only a particular program can access a local file on a user's computer. This is because all possible methods can be bypassed if the user is savvy enough.
A common (though complicated) way of doing this is by encrypting the file with a key that is provided by a web server. In order to acquire the key and unlock the file, the program will have to contact the web server, authenticate, and then use the key to decrypt the file. If you change the keys often and tie them to the user, it will be difficult for an attacker to bypass this. The attack would include dumping the process memory while the file is in memory unencrypted, and then accessing it that way. This tough, but doable. This method stops all but the most sophisticated attackers. Many PDF and other document DRM is implemented this way (Amazon assigns a key to each device and install, but otherwise is same idea).

Related

How to make the uploaded file available for use after saving it with GetRandomFileName according to the FileHelpers example?

In the documentation sample code for how to deal with user uploaded files, they save it as a trusted filename for filestorage via GetRandomFileName, and a trusted filename for HTML display.
In the comments it says: "In most production scenarios, an anti-virus/anti-malware scanner API is used on the file before making the file available for download or for use by other systems."
Is that going to be before it is saved with a random filename or after? Because that is the point of saving it as a random filename, so that it doesn't get executed? And when the scanning is done, how is the file going to be made available? I guess the file just has to be renamed if it passes the scan or else deleted? If so, what is the proper way to get the original file extenstion? And do you know of any good scanners that are gratis that are popular to use?
I try to learn web development. Thanks for your time and help.
The renaming of the file here has nothing to do with the anti-virus protection. The files don't tend to execute themselves whatever their name is. Same with the virus scan: it's not for the server protection, it's for the users protection. If your server executes the binary it gets from the client, it's a security breach regardless of whether it's a virus or not.
The renaming here is probably done just to be able to store the duplicates. That being said, in the production scenarios you'll probably never store the incoming files as physical files on the FS. They usually go to the DB as blobs, so the name is not an issue.
This is just a sample app designed to teach how to work with binary streams and file controllers. Don't expect too much from it in terms of applicability to the real solutions.

Saving data so it is persistent in Objective-C

Over many different Objective-C iOS coding projects I have frequently come across the issue of having data be accessible after I initially got it.
For example, currently I am reading from the stackoverflow API. I do this with a session and get a dictionary back (my JSON response).
But outside the scope of the session, the dictionary is unavailable! I can't copy the contents to a different dictionary that I've defined globally, or anything. It's like it disappears outside of the session.
So I am wondering, what's the best way to save this data that I want to use? From what I've been reading it seems like NSUserDefaults or maybe creating a plist file, although admittedly I've been having trouble with both options. If there is a method that is best for this then I can concentrate on that.
Thank you!
It depends on how persistent you want to be.
If you save this dictionary into a global variable, it is stored in the part of device's RAM that is reserved for the running app. When the app stops running (gets killed by OS or removed by the user) or if your device reboots - this memory is lost.
If you save this dictionary onto the device's flash memory drive (and its file system) - it will live past restarts/reboots.
Usually people combine the approaches: when you get the data from the network, you keep it in a global variable, and save it to the file system. After the app restart you try to load the data from the file system. The reason for not using the FS all the time is that it is much slower than RAM access. I guess I'm describing caching.
Note that you can implement manual caching (using plain data or text files, NSUserDefaults, Core Data or other libraries), but also you can utilize a builtin HTTP cache - NSURLCache. If you create a session with NSURLSession.sharedSession it will use the default NSURLCache and respect a caching policy dictated by the server side.
For more control and full offline support I'd recommend to implement caching manually. See this about reading and writing plists and writeToFile:atomically:.

win8 store app access local storage

I am developing a Win8 Store app which allows users to download different types of files from an online learning platform and store them locally. I am also considering the function to help users organize these downloaded files by placing them in different folders (based on course name and etc.).
I was using Documents Library previously. But for every type of file that the user could download, I need to add a file type association, which does not make a lot of sense since my app would be able to open such files. So which local storage should my app use?
Many thanks in advance.
Kaizhi
The access to storage by Windows Store apps is quite restrictive, especially the DocumentsLibrary.
As you have noticed, you need to declare a file type association for every file type you want to read from or write to the DocumentsLibrary. This means your app need to handle file activations for these types in a meaningful way, which your app probably should not do.
But even if you jump through this hoop, there is another one that is not documented on the MSDN page of the DocumentsLibrary, but "hidden" in a lengthy page about app capability declarations: According to the current rules, you are not allowed to use the DocumentsLibrary for anything but offline access to SkyDrive! Bummer...
So what's left?
You can use SkyDrive or another cloud storage to put files in a well known place (which might or might not be somewhere on the hard disk). This is probably both overkill and undesirable in your case.
Or you save the files in the local app storage, provide your own in-app file browser and open the files with their default app. Seems viable to me.
Or, maybe, you can do something with share contracts or other contracts. I don't know much about these yet, but I doubt that they are helpful in your situation.
And that's it...
(Based on my current experience. No guaranty for correctness or completeness)

Where can I put temporary files that I don't want show to the user?

in my Mac software I need decrypt a file and, after I do my operations on it, I will remove it. My problem is: Where can I put this file? I don't want show it to the user.
The following API will give you a directory path that is "out of the way":
NSTemporaryDirectory();
Do you mean "decrypt a file in a place the user can't access?" Any place your app can write to, the user can see. And in theory, a user can access any bit or byte on a computer to which they have physical access.
There are obfuscations and such that reduce the odds a user will come across sensitive data, but they are meant for particular situations.
Can you tell us more about your end goal here? Are you trying to implement a DRM/copy protection scheme? Are you trying to prevent cheating in a game? Do you just not trust your user? What?
I think your best bet would be to keep it in memory.
If that's not an option, it depends on what you want to do with it. It's possible you can open a temporary file, and immediately delete it - keeping the valid filehandle open, but not keeping a link to it on the disk.
Another option, perhaps - can you get your secondary program to read from STDIN or a pipe? You could then decrypt the file and pass it's content via a pipe? Clearly, the more complex this process is, the more weak links it might have, but sometimes you just have to get things working.

OSX: Hook file read event

I have a particular file I want to monitor for file read attempts by all applications on OSX. I'd like to be able to interrupt the requests so I could decide which applications have permission to read the file and which don't (by querying the user, or checking a cache of user responses). Is this possible with the OSX API? If not, is it even possible to get a list of which applications or processes do read a file?
I'm not saying there's no way to do this, but what #Jonathan is talking about isn't it.
That API is for tracking the creation, change, and destruction of files. Notably this tool is used by things like Spotlight to watch activity on the filesystem for new, interesting files.
But, wisely, reading isn't one of the events it tracks.
And even if reading WAS tracked, it is still the wrong mechanism, as it's a notification system after the fact, not in line with the call itself.
I seriously doubt what you want is possible the way you describe it.
With Access Control Lists, you can limit access at the user level (Fred can read the file, but Bob can not). This is a setting on the file itself. But there's no mechanism to allow Bobs App1 to read a file, while Bobs App2 can not, since there's really no formal mechanism of "application identity" beyond the command to executed, or whatever the program "says" its name is (both of which can be spoofed if motivated enough).
However, feel free to crawl the Darwin sources -- no doubt the answer is buried in there somewhere near the open(2) call.
EDIT, regarding comment.
What are you trying to do? What's the overall context?
Another thing that you may want to try is to use FUSE.
FUSE is a utility that let's you have "user space filesystems". People use FUSE for many purposes, like reading NTFS volumes, or mounting remote system via SSH.
They have a simple example, that gives you a skeleton that you can fill in for your purposes.
For most of the use cases, you'll simple defer to the system. However, for OPEN you will add your logic. Then you could point your FUSE utility at a directory, and "mount it". Then all of the files below that directory can use your new behavior.
I'm still not sure how you will identify Apps by name, but if it's not a real "security" issue, just for local control, I imaging you can come up with something. Activity Monitor has apps names, so they must be available, and FUSE will be running within the process space (I think), rather than through some external mechanism.
All that said, I think FUSE is your best bet, but it's probably not appropriate if you want to do this to "any file" with no preparation by the user (like not installing FUSE). If you wanted to do "any file", your FUSE system would need to be mounted at root, and then you'll simply have a full "clone" of the filesystem, with those files from the normal root "unprotected", while those from your new FUSE root will be protected. So, if someone wanted to NOT use your FUSE system, the real file is readily available to them through the actual file location.
If not, is it even possible to get a list of which applications or processes do read a file?
The command-line tool fs_util allows you to monitor filesystem activity, including reading.
The writings of Amit Singh should come in very handy. He explored the API that provides FileSystem events a few years ago, and provided a sample tool that allows you to intercept FS events. It's open source!
If i remember his conclusion properly, their isn't an official API, but you can use apple's tools to achieve what you want.