File permissions in Android - java

I'm here just to ask something maybe very simple, I'm working with Files, FileOutputStream and FileInputStream, But I just want to get/set a few props from the file, I mean, the owner the file, the permissions read/write, etc.
Looking around I found the classes FileDescriptor and FilePermission but I don't have an idea of which I can use them, so I asking for some help about this; Actually I'm using the method setReadOnly() from the class File but that's now what I'm looking for.

There are a couple of issues here:
An application, by default, has unrestricted access to its own files (read/write/delete/'execute'...whatever execute means) but no access to any other application's files.
Android make it difficult to interact with other applications and their data except through Intents. Intents won't work for permissions because you're dependent on the application receiving the Intent to do/provide what you want; they probably weren't designed to tell anybody their files' permissions. There are ways around it, but only when the applications are desgned to operate in the same JVM (i.e. applications you have designed to operate in the same JVM together)
Your application can get and set permissions for its own files but cannot do that for anyone elses. To my knowledge there is no explicit concept of ownership exposed in the SDK, so you cannot find the owner of a file.
Android is based on the Linux kernel, but it's not Linux. It's been heavily optimized for running on mobile devices. If you have a machine where an application can only play in its own sandbox you can cut out things like permissions and ownership and get a smaller, faster operating system. The only permissions your files have are the one's you place (and enforce) on them. Other applications' files do not exist.

Android uses the standard Java API for handling files and file permissions. Here's a a page discussing permissions in Java.
Basically all you need to do is getting the FilePermission object of the file, then getting the PermissionCollection from the FilePermission object with the newPermissionCollection() method and then add or remove items to or from that collection.

Well...if you only want to SEE the permissions couldn't you just use "ls -l" ?

Related

Why I get error "Your security settings have blocked a local application from running”?

What you do to get rid of this? I wanted to make a game that is accessible from browser. Then I get error "Your security settings have blocked a local application from running".
I changed browser. nothing.
I added exception in "configure java". Nothing.
I looked internet and looked for "medium" security level but it was removed..
Honestly, I'm not sure. But, I might know what's causing the problem. I'll list most of them here (you can find the full list at What Applets Can and Cannot Do):
Applets cannot access the local file system.
Applets cannot connect to or retrieve resources from a third party server.
Applets cannot load native libraries.
Applets cannot change the SecurityManager.
Applets cannot create a ClassLoader.
Applets cannot read certain system properties.
In summary, don't try to make changes to the user's desktop or the client's windows folder. Have them upload the file instead. Don't try to access .pngs or .json from external servers like google or yahoo either, probably because java can't guarantee them to be safe too. Neither can you load native libraries, so you might want to avoid those if you can, and finally you don't have access to some info in SecurityManager, ClassLoader or some System Props.
If your app violates one of these, Java is likely blocking your app from running. But it all depends on your implementation too. Make sure your browser doesn't block certain applet features (and that java supports your browser, make sure everything is enabled too) and try again.
Or, you can ignore all of that and try making your app privileged. Unfortunately I have very little experience with the process of making your app privileged, but from what I can hear, it'll give your applet a little more room to move in.

Using the IE/Chrome HTML-Renderer in Java OR storing files with JavaScript

I'm currently trying to write a little application (Which doesn't require internet access - So it really only is a local application.), which should be kept really simple. I thought about simply using HTML(+CSS) and a bit of JavaScript, since that would largely be sufficient, but I also need to have access to the filesystem in order to store my data in some file, which isn't really possible in javascript (Yes, I crawled through quite a few posts about JavaScript & FileSystem, but I didn't like any of the solutions.)
So I thought about another way to do it: There is some nice Library called HtmlUnit which would allow me to basically simulate my JavaScript, while having the Java FileAccess - But then I won't be able to render it.
So, two questions:
Is it possible to somewhat declare a JavaScript File as "local" and thus gaining file-system permissions?
Many applications (Games etc) internally use Internet Explorer. Is it possible to use IEs (Or even Chromes/Firefoxes/Whatevers) renderer in Java? I don't like any of the rendering-libraries I found until now - Or just simply be able to execute js+html code as a local application?
I tried out .HTAs, and I absolutly hate them. It's just so... old. Nothing is possible there. It would be awesome to get a simple html/js application looking like in chrome, but being a local application.
Q&A
Is it possible to somewhat declare a JavaScript File as "local" and thus gaining file-system permissions?
No, it is only possible through ActiveX / plugins (e.g. Java / browser addon).
Others may suggest that JavaScript has data storage or file system.
But they are not local file system access, and you cannot read or write real files with them.
Many applications (Games etc) internally use Internet Explorer. Is it possible to use IEs (Or even Chromes/Firefoxes/Whatevers) renderer in Java? I don't like any of the rendering-libraries I found until now - Or just simply be able to execute js+html code as a local application?
JavaFX's WebView use WebKit as renderer.
Webkit is not a full browser, so it has less feature, e.g. no localStorage, but you can replace most of them with Java code.
SWT Browser, as mentioned by another answer, also works as renderer but will make it difficult for you to package as single file, plus it depends on client to do install/update the browser.
I tried out .HTAs, and I absolutly hate them. It's just so... old. Nothing is possible there. It would be awesome to get a simple html/js application looking like in chrome, but being a local application.
It is possible to embed all resources into one HTML file using inline code and data uri.
Here is one of my projects that does it: [source files] [single file deployable].
Regardless, most browsers does not allow file write, as you no doubt already know, and Chrome is especially hostile against file access.
Advise
From my experience, the only feasible solutions are:
ActiveX HTML app
Native program, such as Java jar or .Net exe. (Or a jar packaged as exe)
Full blown web app with customised browser and tailor made launcher, e.g. in a usb stick / dvd / installer
I have done all of them, and I personally think Jar/Exe is the most balanced solution given your requirement.
Which is sad. If metro app were easily deployable like exe I'd advise that instead.
Is it possible to somewhat declare a JavaScript File as "local" and thus gaining file-system permissions?
Firefox extensions would have the necessary permissions to access the file system.
Is it possible to use IEs (Or even Chromes/Firefoxes/Whatevers) renderer in Java?
Yes, e.g. with the SWT Browser Widget or JavaFX WebView
I wonder if this will be enough for you (using HTML5 storage features):
function saveFile(localstorage) {
localstorage.root.getFile("info.txt", {create: true}, function(theFile) {
theFile.createWriter(function(theContent) {
var blob = new Blob(["Lorem Ipsum"], {type: "text/plain"});
theContent.write(blob);
});
});
}
Browsers will ask users for permissions to store files in local system.
Credit where credit is due

Change working dir in Java Webstart

Is there a way to change working dir for JVM when running Java Webstart?
When i use system.setProperties("user.dir", newDir) it sets it(system.getProperties() shows it does) but ignores it.
Is this a limitation in Java Webstart to always use the working dir where i started the jnlp file?
I am using all permissions in the jnlp file.
Please help!
EDIT: Whatever i do now, my webstart always uses user.dir to save files. Frustrating!
I've had this question in the past myself, but I've always found that, in the end, I didn't need it. Why do I say this?
Because your java web start app is not like an executable run from Program Files. It doesn't even exist on your computer like most programs (it is broken up into a bunch of different files and reassembled by the JVM). Therefore, you cannot say that the program has its own directory to do what it needs.
But it doesn't need to. Here's why:
Java has the Preferences API to help when you need to store data. The under-workings of the Preferences API is as mysterious as JWS, thus they are really a perfect fit. Either way, if you need to write things to a file, you should check this API to see if it can meet your needs.
If you need to write files for the user, then prompting them and allowing them to choose the location obviously means you won't use your current working directory to read/write files.
If you need to serialize objects, you should just create a program directory using the user.home resource as #AndrewThompson suggested. This will be "your" directory and is as good (in fact, better) than a directory in Program Files (if you're running on Windows, as an example).
In conclusion, in all cases (that I've come across), there's no need to change your current working directory. If you need your own folder, create one in user.home (because you won't run into file permissions issues there).
..all my settings file i use is created in the user.dir.
There is the mistake. Put them in a sub-directory of user.home & the problem is solved.
In the hypothesis you really really need to divert user.dir property for Java WebStart execution, here is the only option I have found: set this system environment variable (so system wide):
_JAVA_OPTIONS="-Duser.dir=C:\Temp"
But care about it, this option is read and applied to any JVM executions.
Why was it required in my context ? Because Java WebStart ClassLoader was looking for any single resource (class, properties...) in user profile before getting it from jar files in cache. As the user profile has been moved to a network storage, application start up became terribly slow. I am still investigating Java sources to understand (and avoid) this behavior. So my applications work perfectly without setting user.dir but that was the only work-around for the performance issue we got at the moment.
The recommended way to pass runtime parameters or user specific setting is through the jnlp argument
<application-desc main-class=".....">
<argument>user.home</argument>
..............

Is there a way to sandbox parts of a java process on Android?

I want to use an SDK in android, but I don't want that SDK to have any access to permissions that I haven't explicitly given it. On top of that, if the SDK throws an uncaught exception, I don't want it to bring down my entire application.
In C# there is the concept of an AppDomain where you can treat the code running inside of it like a sandbox, granting (or limiting) permissions, and only providing access to data that you explicitly want to share.
Is there anything that works like this in Java for the Android platform?
There are two questions here. The first one deals with handling exceptions in a piece of untrusted code; a carefully written try/catch block should take care of that, as long as the untrusted piece is pure Java. If native code is allowed, then nothing short of process level isolation would help. For running code in a separate process, read up on Android services; you can designate a service to run in a designated process. Then exceptions (the nonmanaged kind) won't bring down the main app. You'll just get a "service has died" exception.
A whole another issue is lowering the permission set. To the best of my knowledge, there's no way to lower the permission set within an app. Even a surrogate process won't help. If you ship a whole application (in the Android sense of the word) for wrapping and running custom code, that might help. But the logistics of app installation would get tricky. Google Market does not readily support the notion of app interdependence or prerequisites.
All the permissions you give to your app are the permissions that are allowed to otherwise it wont have permissions for almost nothing.
you set your permissions in your Manifest.xml otherwise than that you cannot set other kind of permissions.

Java application permissions

Does the java application permissions extends for created processes? i.e. if application hasn't permissions to create file and I'm running someprogram.exe from this application, then is it restricted too?
If no then how can I restrict created processes? Another thing I want to do is to restrict the memory used by subprocess. Please help
It's not absolute clear to me, what kind of permissions you're talking about.
The Java security settings are per application restrictions. They affect java code that runs inside one java virtual machine. If you call an executable, than that executable will not inherit those permissions.
Other permissions are per user permission. So if you don't have the permission to create a file in a certain folder, then the Java application that you started won't have the permission and any executable started from the java vm won't have permission too.
You can restrict the memory of the sub process just like any normal java app, for ex:
java -Xmx16m -XX:MaxPermSize=128m
On the other hand I believe the permissions are the same as the user that started the application, just like any *nix behaviour. When you spawn the new process you can probably change the user in witch that process is started but depends on implementation.
I don't have ref to this so I might be wrong but I don's see why this behaviour would be any different in any desktop app.

Categories