Authenticating Gtk App to Run with Root Permissions

Authenticating GTK app to run with root permissions

The old way, simple but now being phased out, is GKSu. Here is the discussion on GKSu's future.

The new way is to use PolicyKit. I'm not quite sure how this works but I think you need to launch your app using the pkexec command.

UPDATE:

Looking at the example code on http://hal.freedesktop.org/docs/polkit/polkit-apps.html, it seems that you can use PolicyKit to obtain authorization for certain actions which are described by .policy files in /usr/share/polkit-1/actions. The action for executing a program as another user is org.freedesktop.policykit.exec. I can't seem to find an action for directly accessing block devices, but I have to admit, the PolicyKit documentation breaks my brain too.

So, perhaps the simplest course of action for you is to separate your disk-mangling code that requires privileges into a command-line utility, and run that from your GUI application using g_spawn_[a]sync() with pkexec. That way you wouldn't have to bother with requesting actions and that sort of thing. It's probably bad practice anyway to run your whole GUI application as root.

Another suggestion is to ask the author of PolicyKit (David Zeuthen) directly. Or try posting your question to the gtk-app-devel list.

Give root privileges to a PyGtk app

If you want cleaner integration with the OS, I would recommend you try using PolicyKit.

There are various ways to interact with it:

  1. Using DBus. You can find a nice example here.
  2. Using the Polkit module through GObject instrospection. Here's an example for this.

In both cases you would need to install a specific action configuration for your application on /usr/share/polkit-1/actions (or use an already existing one, like exec).

It probably will take you a little more of effort to implement it this way, but in my opinion is cleaner than a subprocess and makes to a better integration with the OS and the Desktop Enviroment (e.g. the password request dialog is provided by the DE).

Deploying an app with root privileges

The recommended Apple way to do what you want is as follows:

  • factor out the stuff that requires privileged operation into a separate executable (that's the stuff that uses libpcap for you).
  • when the application needs to start the privileged exe, it creates an authorization reference and checks the user can authorize (known as pre-authorization) and passes an external reference to the authorization to the privileged exe.
  • when it first starts, the privileged exe gains authorization again before attempting to do the privileged stuff.

For the above to work, the privileged exe has to be installed as owned by root with the setuid bit set. You can either do this with package maker or you can create what Apple terms a self repairing helper tool. This is a tool that checks if it is running as root and if not calls itself via AuthorizationExecuteWithPrivileges to repair its setuid bit and ownership. Then it does the authorization for the operation and performs the operation.

If you use the self repairing tool, you can bundle it in with your application and use a drag and drop installation process.

I strongly advise you to read the whole of the Authorization Programming Guide. It talks about all this stuff in more detail and includes some example code.

GTK+ How to ask for super user with prompt

You could check the gksu page on live gnome, or if you want to use the policy kit framework you can google for sample programs (e.g. like this one).

Another way, more straightforward, would require the creation of a group (which would allow users to access /dev/mmcblk0) and ask root to add specific allowed users to this group.

How can I ensure that a Rust executable is run with root permissions on Linux?

What I've found (and what is used in libcryptsetup-rs) is this:

use nix::unistd::Uid;

fn main() {
if !Uid::effective().is_root() {
panic!("You must run this executable with root permissions");
}
}

Whether to panic!, println!, or exit is up to the programmer to decide.

Have my GTK application started on startup on Linux

Create a .desktop file of your application, and put it to /etc/xdg/autostart/ for each user, or to $HOME/.config/autostart/ for current user.

If you want to load that application as root for general users, you may choose to use gksu or other tools to authorize priviledge.

Alternatively, you can see how network-manager is designed. It inits network-manager module as a init-script when system starts, and loads nm-applet, which is GUI for ordinary user, when a user session loads. Thus, network-manager can be managed on all the desktop environment (like Gnome, KDEE, xfce...) by desktop users.

Run a service with Root privileges or adding permissions with root

This is far from trivial but should work when the apps you want to monitor use sqlite databases or, more generically, write messages to a file when they arrive.

You will indeed need to have root access to the device as this violates the android security system:

Write a native process which runs as a daemon using the NDK and spawn it once after boot as root. You have now 3 major problems to solve:

How to find out if something changed?

This is the easy part. You would need to utilize the Linux inotify interface which should be accessible on every Android phone as the SDK has a FileObserver since API 1, so you are on the safe side here.

Another interesting approach may be to catch the C2DM messages. I have found a NDK class called BroadcastReceiver, so the NDK may be able to catch them. But I personally wouldn't do that as it feels wrong to steal intents. Also you would have to redistribute them or let them travel to real recipient, so I will not describe this in detail here. It may work, but it may be harder and should only be a fallback.

So, when you have solved this, the next problem arises:

How to read the changes in a safe way?

You have a problem, a big one, here. The file doesn't belong to the client, and the client doesn't even have the permission to know where it is (normally). So the monitored app is not aware of the client and will act like the file is exclusively owned only by itself. If they use some plain old textfile to write messages to you have to find out a way to read from it safely as it may be overwritten or extended at any time. But you may be lucky when they use sqlite, according to this it's totally valid to have more than one simultaneous reader, just only one writer. We are in the specs, everything fine again. When you have now read out the new data, more problems to solve:

How to get the new data back into the main app?

You should do only the bare minimum in this C/C++ program because it runs as root. You should also protect your app users from security breaches, so please write the program with this in mind. I have no real idea for this could work really good, but here are some thoughts:

  • Write the collected data into your own sqlite database (easy in C/C++ and Java),
  • Write the collected data into a plain file (not recommended at all, pain in the rear),
  • Send an Intent which contains the new data (maybe not that easy in C/C++, but easy in Java)
  • Use sockets/pipes/..., just every RPC mechanism you could imagine which is brought to you by Linux (same as the file, don't do it)

As stated in the text above, please be careful when you write this daemon as it is a potential security hazard. It may be hard to do this when you have no knowledge about C/C++ at all, even if you have written simple programs this should be a non trivial task.

On my search through the web I have found the NDK C++ classes I mentioned above. It can be found at Google code. I have neither experience with the NDK nor the C++ wrapper but it may be worth a look when you plan to write this.



Related Topics



Leave a reply



Submit