So, it's a little unconventional, but I'm basically producing a Java App which I need to have access the /etc/hosts file.
This file obviously cannot be edited without root privs. The program is for parents so they can disable their kids from viewing certain sites. How can I make this root access happen?
I have read somewhere that I might be able to open the application as root inside of MacOSX's terminal line, but the reason I'm doing this program in Java is so I can distribute it to some of my close friends who are not computer savy, and they can easily run it.
Is there anyway I can request root privs at the beginning of the app?
You can let the user start the app with superuser privilges using the sudo command.
sudo your-app
The user must be allowed to use superuser privileges. He willl be prompted for his password before executing the command. Look around this site for more infos about sudo.
Note: Another possibility would be using the SUID bits directly. This is not very clever, because anyone starting the app would have superuser privileges. `sudo`` is the wrapper of choice for granting access for exactly that reason.
I assume that you use a unix-based system.
You can ask the users to make the program be owned by root and put the SUID bit on it (chmod 4555 on the file for example).
This way any user can launch it and the program will be executed with root privileges and will be easy to use.
Correction: Apparently you can't apply the SUID a java program according to this link (it is barely the same for scripts).
Just do a wrapper in C instead with the SUID bit:
#include <unistd.h>
int main(){
system("java main");
return 0; }
For more details concerning the SUID bit check this out.
Related
Working with Unix server... My requirement is to read the name of the file that is there at /a/b/c/node01/d.ear location on a Unix server and I have do the same through a java program. The problem is that the directory a is a restricted directory and is accessible only to certain users. On the Unix side, I first issue a become command like become a, then supply the password and then using cd command, I reach the d.ear directory and then get to see the name of the file.
How do I do all of this via a Java program?
I don't mind if my Java program calls a shell script that accesses the restricted directory and then reach d.ear and fetch the name of the file and returns the same to the java program. Do we have a way of doing this? Maybe issuing the become command inside the script which is called from the Java program and the password which is asked after become command is supplied as a parameter while calling the script???
Is this approach doable? I am very new to Unix commands and JSch library. Kindly provide the code or any other alternate solutions...
Thanks!!!
As I have suggested you already, your become command seems to behave the same way (from an interface/API point of view) as common *nix su or sudo.
So, use the same solution as for those. There are many questions on Stack Overflow covering use of su/sudo with JSch.
There's even an official JSch example Sudo.java:
http://www.jcraft.com/jsch/examples/Sudo.java.html
In short:
Execute become command
Feed a password to its input
Assuming the become starts a new shell (as su or sudo do), you feed the commands to be executed in the elevated environment to become input (the same was as the password).
I need to create a persistent storage in my Java app so all users can access it. So I was studying about java.util.prefs.Preferences and using systemRoot() works fine to me on Windows, saving data at Register.
But I'm really facing some problems on Linux (Ubuntu). I want to use a directory that other of our apps already uses: /usr/share/.
So, I'm trying to redirect systemRoot default directory to /usr/share at runtime. Here's my code:
System.setProperty("java -Djava.util.prefs.systemRoot", "/usr/share/myfolder");
Preferences pref = Preferences.systemRoot().node("/usr/share/myfolder");
According to this site, I have to create .systemPrefs folder before execute this command line and its implicit that systemRoot() will use it.
When I execute my program, I get the following WARNING:
java.util.prefs.FileSystemPreferences syncWorld
WARNING Couldn't flush system prefs: java.util.prefs.BackingStoreException: /etc/.java/.systemPrefs/usr create failed.
So I'm assuming that System.setProperty isn't working. Any suggestion?
Thanks in advance!
This is a really pesky issue Java running on *nix based servers.
I was able to solve it by using the following vm args:
-Djava.util.prefs.userRoot=/opt/apache-tomcat-7.0.50/uprefs -Djava.util.prefs.systemRoot=/opt/apache-tomcat-7.0.50/sprefs
One important note though on the systemRoot path is to create a sub-folder within it named .systemPrefs or it will not work.
Also, don't forget to chown -R these directories to the user running the java application (in my case it was tomcat).
Bimalesh suggested that instead of
System.setProperty("java -Djava.util.prefs.systemRoot", "/usr/share/myfolder"), that you say
System.setProperty("-Djava.util.prefs.systemRoot", "/usr/share/myfolder").
But the name of the property that you are trying to set is java.util.prefs.systemRoot, and not -Djava.util.prefs.systemRoot, so you should do
System.setProperty("java.util.prefs.systemRoot", "/usr/share/myfolder");
If that doesn't work, try adding the "-D" switch to the command line that starts your program. That is where
java -D... should go. The command would start with
java -Djava.util.prefs.systemRoot=/usr/share/myfolder
In a Linux system, the System root preference node will be under /etc. This is due to history, and is a standard that is regulated by the Linux Standard Base. Any non-system preferences can go in other locations, but it is a violation of the design of the operating system to have system preference go elsewhere.
Odds are your define is ineffective in a Linux system because it fails to start at /etc. Apparently something in the Java code defers to the specification of the operating system over your decision to re-base the preference root.
Typically such files are protected against modification by not being world (or even most user) writeable. This means that for users to have access to Preferences, they should go under
Preferences.userRoot()
Which will place them in hidden directories just off their home directory (where they will have modification privileges).
If your want any user to read any other user's preferences (the description sounds like you might) then you will need to have an installer that runs as a sufficiently authorized user (typically root) to make the required directory under /etc and change it's permissions to be world writeable.
Typically files under /etc are not world writable as users changing other's user's setting is then possible, and considered a type of security breach of the user's expected environment. For example, a careless employee (or a disgruntled one) could wipe out all other user's preferences in one stroke.
I am developing a java web application that needs to pass shell scripts to putty after user authentication. putty.exe should launch only if authentication is successful and if the script has begun running successfully.
Also, since different users might have installed putty in different locations on their systems. Is there any way to launch putty.exe without requiring the user to manually configure the path. Or is it possible to programmatically find the path and launch putty?
I will start by saying not having the user add putty to the path is most easily solved by creating a configuration file for each user, where one of the parameters will be the location of the putty executable. Properly handling this with default values and a dialogue box if putty can't be opened would be simple and familiar to most users.
Two simple situations could completely mess with how you do a search for the executable: the user renames the putty executable or the user has multiple versions of putty.
To avoid getting stumped by the first situation you are going to have to ask for the new name and somehow save it in a config.
To avoid getting stumped by the second you are going to have to ask for the version of putty they want, store that version, and somehow do version checking if all you want to do is look for putty.exe (maybe you have a file of the checksum for each version).
This is just as, if not more annoying to the user (and definitely more annoying to you) than just asking them to point to the executable. There are more ways that things could go wrong, as well.
Basically, it is possible to search for the executable but it would not save anyone any trouble and would only make more for you. Having the user configure the path is not very tricky, but if you want to avoid it then the easiest thing is to have per-user configuration files with the putty path saved in it by your program.
One way is by editing the PATH system variable of the user machines and add the full path of the Putty.exe location.
Another solution is to create a link that points to Putty.exe in a default folder in every user machine, so Java could access to this link w/o problems.
A third solution could be to ship the Putty.exe with your application installer. Putty.exe doesn't need custom DLLs to work (at least I haven't needed one yet).
Theoritically it is possible if you search through every directory on user's computer to find putty.exe. But practically, you should required the file to be put in some familiar directories or use an environment variable.
I agree with people above. Also in your application you can provide ability to user set putty.exe full path and store them in cookies.
I'd like to get the list of running processes using a java applet running in a browser. My understanding is that, as long as the applet is signed, it will be able to get this information. Is this accurate? Is this possible with an unsigned applet? Finally, are there any FOS applets available that I could take a look at?
Thanks.
An applet needs to be signed whenever it want to access/execute local system resources. This includes executing Runtime#exec() or ProcessBuilder which is required to be able to get a list of running processes.
You can find here a basic example how to get that list in Windows. I'd suggest to check if (System.getProperty("os.name").startsWith("win")) before continuing with that.
Porting the given example into an applet isn't that hard, just let the class extend JApplet and execute the whole code from inside AccessController#doPrivileged().
As to signing the applet, you can either sign it manually, the enduser would only face a security warning with a confirmation whether to execute it or not, or you can let it sign by a 3rd party company for some $$$, e.g. VeriSign, this way the enduser won't face the security warning. Not signing it will cause the applet not be able to run at all.
You'll have to execute OS-specific commands (through Runtime.getRuntime().exec), like tasklist.exe for windows and ps for unix-like systems.
As for security measures, I'm pretty sure it's impossible in standard 'sandbox', but 'privileged' applet can do it.
I've put together a basic applet where the user selects a file from their hard drive, it reads the first line of this file and passes that off to JavaScript for some additional preprocessing, and then when you click a button it tries to upload that file through an HTTP POST request. I found a very basic open source applet for uploading files that I copied and modified for this last bit.
The trouble is, though, it doesn't quite work. It seems like it's running fine, but then I run into two snags related to permissions. The messages in the Java Console say that the applet had access denied errors on the following two permissions:
java.lang.RuntimePermission setFactory
java.io.FilePermission read
I find this strange, because I thought I had granted permission to the applet already when I built it with the "self-signed" option checked in NetBeans, and then clicked to confirm the little security pop-up in the browser.
Also, the part that I coded myself, where it reads the file and passes the first line on to JavaScript works fine. This is a pretty clear indicator that the applet is able to read from the local file system! The trouble doesn't start until I actually try to start the upload. One thing to note, I suppose, is that the upload process seems to run in a new thread, whereas the rest of it all runs in the main class without creating threads.
I am a total novice to Java and know very little about threads in Java; do I need to pass the permissions onto this new thread somehow? Or something to that effect?
Thanks in advance.
You probably need to ask the security manager (code, not administrator) for permission to do a privileged operation. For various reasons, it's not generally a good thing for an applet to be able to open a local file, so it's guarded pretty heavily.
The basic key is to call AccessController.doPrivileged() and there's a good little tutorial on it at the Java Ranch FAQ.
I had a similar problem which took forever to solve. It turns out applet methods called from JavaScript have no permissions, even if you explicitly grant them in a policy file.
This workaround worked for me (adding commands to a queue which the applet loops through):
http://blog.carrythezero.com/?p=5
Make sure you understand the dangers here: Anyone can modify JavaScript on a page and change what's getting fed into the applet. In my case I know the code is never going on a webserver, and the class is unsigned so it will fail unless in the specific location granted by my policy file.
It's probably because the JavaScript is unsigned. I strongly suggest not signing code, particularly if you don't know what you are doing. From 6u10 (not on Mac yet) applets can use JNLP including the FileOpenService, so you don't have to sign.