How can you mount a device using just java? - java

Okay, I realize this might not be possible ...
I have a device that runs linux, and it will likely not have a user interface that is visible. It will have a USB port that is open ... I want to be able to write java to allow the overall system to detect when a device is plugged into the USB port and then mount the device.
I know how to do this from a command line, but it requires "sudo" to fork a new process with elevated privilege to perform the task. I don't know how to write a java program that can get around (yes, I want to get around) the security protection of mount.
runtime.exec() doesn't really do what I am hoping to accomplish. Is this a "can't be done in Java" problem?
I'm hoping to do this without resorting to external executable code.

You can't get around the security protection of mount. The protection is not in mount. The protection is in the kernel.
If by chance you find a way and publish it, it will get removed.
If you have control of the OS you are running on, you can add the option user to the mountpoint in /etc/fstab. After doing so, "mount /path" and "umount /path" work from runtime.exec() without elevation. mount and umount are setuid-root to allow this to work.

File mounts are controlled by the host operating system. So controlling mounts is done through system calls. You seem to be using a Unix operating system, so that means the system call interface is C. So you could use JNI to call a small C function that makes the system call needed.
But all such matters are system dependent, and privileged operations. So that approach creates portability and security problems. So you might do better to reconsider why your program itself must do this, rather than letting a control component (such as systemd) do it for you.

Related

Check if my Java application was started from Network

I have to check whether someone started my Java application over the network or not, so that I can shut down the application if it was started from another machine.
The solution has to work on Windows and Linux.
I guess interpreting the current working directory might be a starting point, but I have no idea with Java-class; provide me the feature I need.
Why? If it's for security reasons then you probably are out-of-luck. If the attacker can create a process on your machine, then (s)he will be able to create a process with whatever environmental properties your program checks to decide whether the "user" is remote or local.
If it's for security reasons, then you should be trying to prevent the attacker from communicating with the machine at all.
If it's for some other purpose, then you haven't really provided enough information. What kind of "application?" How does a local user normally start it? How would a remote user try to start it? etc.

Bootable program

I'm a front end developer that's looking to get into some other languages such as Java or C++. I have an idea for a program and was just looking for an answer to something. What I would like to do is build a program and boot directly to that program. For example I have an old computer and I wipe the hard drive clean. So they is nothing currently on it. Not even an OS. I want to build a program that I can install to the hard drive that will boot straight into the program once started. Would this be considered an OS?
No you don't. Unless you want to spend many years, writing drivers for your graphics card, harddisk controller, usb controller, dma controller and all the other hardware your computer have.
What you want is a minimal operation system, which include just the kernel, and a runtime library and which start your program and nothing else on startup. A minimal Linux such as linux from scratch or bsd would be a good starting point.
First of all you need to decide your your program needs what. I mean should operate in Protected mode or the routine you have is tiny, so it is enough to run before entering protected mode (i.e. in real mode).
Here you can do three things
Modify bootloader to jump the execution to your code . Then Your code can resume normal os initialization.
Modify your os kernel early initialization code So that it executes your code before entering protected mode
I think your code will not be harmed if a bit of os portion is running. So you can write your routine before full kernel initialization.
Now note that for the later two point you need to modify your kernel, which is not easy (not even always possible)
Now the problem in first approach: Nothing will be ready for you, not even a regular c library or divice drivers , so you have to write every raw bit of code by hand which is crude.
This is off course not possible in java. Because the jvm will not be ready for you.
Now practically: there are lot of tiny os available, use one of them and modify as per your need. use this link to get a complete list of what is available for you.
First, Java is right out. You cannot possibly do this in Java without enormous amounts of tool-building. Java is not suited for this task at all.
You can do it in C++ or C. The search terms you are looking for is operating system development. This would probably not technically be considered developing an Operating System since it wouldn't run other programs, but the information about how to get through the boot-up procedure and establish a minimal environment are going to be most easily found in the category of operating system development. Some reasonable starting resources for that can be found at the OS Dev Wiki.
Alternately, you could take an existing small open-source OS and modify what it does after the boot-up sequence completes. If your program is intending to do anything more than just use the keyboard and the screen in text mode, there need to be device drivers. Thus, depending on the project, changing an existing OS may be the easiest route because you won't need to write your own device drivers for any devices you want to use.
Java can't run without Environment. If you want to run you program on you machine without OS, Java is a wrong choice.
C++ program can run without OS, but it's difficult to write a bootable program in C++.
If you want to write your own bootable program, you should use assembly for boot and load function, with some knowledge to use hardware in low level.
You have to have an operating system, so your program would be the operating system (or you would have to use another one and write it for that). It's certainly possible in C++, but it's not really possible to write an operating system in java.
Unless you want write something in (for example) Open Firmware and Forth or say a ROM BASIC. You'll probably qualify as a boot loader. Your application may qualify as an operating system. In my opinion, and a modern context, it entirely depends on how much functionality it provides to hosted applications. I'm not sure that something like FreeDOS would be considered an operating system (no pre-emptive task scheduling or GUI for example) given modern computers (I don't care to argue the point either way).

Grant permission to word with a protected file

I need to programmatically edit, write or delete protected files. In Windows, if i do it manually, it asks for permission and in Unix systems i need "sudo".
How can I ask in Java for higher privileges during execution?
If your program requires high level access it is best to advise the user that they need to run it as root / a privileged account in order to work.
Otherwise the best option is to start a new 'proxy process' that is initialised using "sudo" and then a program doing what you want, eg "sudo cp File1 File2" that will perform your dirty work for you.
Unfortunately this is not cross platform and requires the users password.
There is simply no way you can just bump the JVM to a higher user during execution as this would pose a huge security risk.
md_5
Because Java works using a virtual machine, you can't just start (for example) another thread in an elevated mode. Instead, you'll need to launch an entirely new VM, which you won't be able to connect to.
I'd look into ways of executing a separate Java process which can run with elevated permissions. You can still use the same code, but have it be a main method.
You won't be able to just raise your privillages.
I might be entirely wrong, and am happy to be shown otherwise.

Reliable non-network IPC in Java

Is there a reliable, cross-platform way to do IPC (between two JVMs running on the same host) in Java (J2SE) that doesn't rely on the network stack?
To be more specific, I have a server application that I'd like to provide a small "monitoring" GUI app for. The monitor app would simply talk to the server process and display simple status information. The server app has a web interface for most of its interaction, but sometimes things go wrong (port conflict, user forgot password) that require a local control app.
In the past I've done this by having the server listen on 127.0.01 on a specific port and the client communicates that way. However, this isn't as reliable as I'd like. Certain things can make this not work (Windows's network stack can be bizarre with VPN adapters, MediaSense, laptops lid closing/power saving modes). You can imagine the user's confusion when the tool they use to diagnose the server doesn't even think the server is running.
Named Pipes seem plausible, but Java doesn't seem to have an API for them unless I'm mistaken. Ideas? Third party libraries that support this? My performance requirements are obviously extremely lax in case that helps.
One of my specialties is really low-tech solutions. Especially if your performance requirements aren't critical:
The low-low tech alternative to named pipes is named FILES. Think yourself up a protocol where one app writes a file and another reads it. If need be, you can do semaphoring between them.
Remember that a rename is pretty much an atomic operation, so you could calmly write a file in some process and then make it magically appear in its entirety by renaming/moving it from somewhere that wasn't previously visible.
You can poll for data by checking for appearance of a file (in a loop with a SLEEP in it), and you can signal completion by deleting the file.
An added benefit is that you can debug your app using the DIR command :)
Depending on how much data you need to pass between the server and the diagnostic tool you could:
go low-tech and have a background thread check a file in the file system; fetch commands from it; write ouput into a second to be picked up by the diagnostic tool.
build a component that manages an input/output queue in shared memory connecting to it via JNI.
Consider JMX. I do not know if any of the Windows JVM's allow JMX over shared memory.
Does Windows even have named pipes? I was going to suggest it. You'd just have to use an exec() to create it.
Map a read_write byte buffer into memory from a FileChannel. Write status information into the byte buffer, then call force() to get it written out. On the monitor side, open up the same file and map it into memory too. Poll it periodically to find out the status.

In a Java thread running as root, how can we apply Unix rights specific to a logged-in user?

We have a Java program run as root on Unix, that therefore can read for example the content of the folders /home/user1 and /home/user2. However, if the Unix user "user1" is logged in in our application, he should not be able to access "/home/user2" data.
We would like to use directly the Unix rights and not recreate all the permissions in our application !
So, could we...
try to change the UID of our
program depending on the user logged
in ? Sounds difficult, and each file
access is in different threads so
the UID would be different on each
thread of our program...
use JNI to read permissions of
"/home/user2"...And then determine
if user1 has sufficient permissions
on "/home/user2" ? (how ?).
Use SecurityManager!
Put current unix user id into ThreadLocal
Create your own SecurityManager that checks unix user permissions on checkRead() and checkWrite()
System.setSecurityManager(new MySecurityManager())
Enjoy
Update
There is no, of course, standard library to read unix file permissions. It's not WORA.
But I have tried briefly to find a ready to use library, and found this one:
http://jan.newmarch.name/java/posix/ It uses JNI, but you don't need to write your own JNI code, which is a big relief. :) I'm sure there must also be others.
Class Stat from there gives you all required access information:
http://jan.newmarch.name/java/posix/posix.Stat.html
Update 2
As folks mentioned, this approach fails to check for "non-standard" unix security features, such as ACL or Posix Capabilities (may be; not sure if they apply to files). But if the goal of being totally in sync with host OS security is set, then we even more need to use SecurityManager, because it's a JVM-wide protection mechanism! Yes, we can start a child SUID-process to verify the permissions (and keep it running, talking to it via pipe running while the user is logged in), but we need to do so from SecurityManager!
The simplest and most portable way would be to spawn a child process, have it exec a wrapper written in C which changes the UID, drops all the privileges (be careful, writting a wrapper to do that is tricky - it is as hard as writing a setuid wrapper), and execs another java instance to which you talk via RMI. That java instance would do all the filesystem manipulation on behalf of the user.
For single-threaded Linux programs, you could instead use setfsuid()/setfsgid(), but that is not an option for portable or multithreaded programs.
if you only want the app to be allowed to read files by user1 i strongly suggest the app runs as user1.
If everything else fails, you can run a shellscript from java and parse the result.
Described for example here
For those who were wondering, it's apparently not possible to do this by calling setuid with JNI for each independent thread. setuid affects the whole process, not just the thread that invoked it.
Should you want to call setuid within a single-threaded Java program there's a good example at http://www2.sys-con.com/itsg/virtualcd/Java/archives/0510/Silverman/index.html.
Another option would be to invert the approach: instead of the code running as root most of the time and either changing the user ID or somehow checking the permissions whenever it has to use some restricted resource, run as the user most of the time and talk to a smaller daemon running as root when it needs to do something only root can do. This also has the added benefit of reducing the attack surface.
Of course, you then have to authenticate the connection from the process running as the user to the process running as root.
I am also having the exact problem as Mikael, and got to this page looking for answers.
None of the answers are 100% satisfactionary for me. So I am thinking of 4 alternatives:
Use a Linux group that has access to all the users. Run a single Java app under that group. This Java app can communicate to the 'root' app using whatever means.
Potentially, it can be "hotel"-ed. e.g. 1 "hotel" (app with group permissions) per 100 users (or as appropriate). So if you have 10,000 users you need 100 hotels, which is quite manageable.
Spawn a JVM for each child app under its own user ID. This is like calling a script, but rather than using stdin/stdio/stderr, use any communication protocol. In my case, I'm using XMPP and IO Data (which, since it's already in use by other components, it doesn't matter "where" aka which JVM it runs).
Create a Super-Server 'root' app. This can be part of the original 'root' app or a separate service dedicated to service management.
The Super-Server is responsible for handling incoming requests (i.e. it practically becomes a reverse proxy) for the user-specific sub-apps, and launching the real child apps (if they're not running already), and passing messages back and forth between the client and the child app(s).
Additionally, the child apps can be pooled (or even "passivated", if there's such thing), much in the way Java EE EJB Container does it. So even if there are 10,000 users and (potentially) 10,000 child apps servicing, the maximum number of child apps running are capped. Idle apps are shut down to make room for others.
Same as #3 but rather than creating a proprietary service management mechanism, integrate with Upstart (or the service management framework in the underlying OS). i.e. there is a 'root' service that can control Upstart. Upstart can start, stop, restart, can query the status of the child services, just like it can control mysqld, Apache, etc.
For me, now, the quickest and simplest to implement would be #1. However, my ideal solution would be #4, but it will take time and testing whether it works well. (the concept itself borrows from inetd/xinetd and EJB, so I think it's pretty sound fundamentally)

Categories

Resources