Use PolicyKit to give my application access to restricted files - c#

I'm writing an application for Ubuntu, which allows you to customize the Unity 2D desktop environment.
Some settings, I can change using Dconf, which is user-specific. So if one user changes a setting, it only applies for that user.
For other settings, however, I need to edit text files which are located in /usr/share/unity-2d/, to which a normal user can't write. To solve this problem, I thought it was a good idea to have users run the application as root, which makes sure they have access to /usr/share/unity-2d/. Only, when the application is running as root, and one of the Dconf settings is changed, it gets changed in the root user's Dconf, so the changes don't apply to the actual user.
I need to find a solution to this problem, and my first realistic idea was to use PolicyKit. I need to make sure that my application runs as the current user (so not always as root), but that it does have access to /usr/share/unity-2d/ and the files inside it. I'm writing the application in C#, using the Mono framework. I don't really have any experience with PolicyKit, and to be honest this is my first attempt in making a serious Linux application.
My idea was PolicyKit, but if one of you has another (realistic) way to achieve this, that fine with me as well. If it comes down to using PolicyKit, I'd like to have a bit more information on how to do this, and what everything does, please. I know I can probably just run my application using pkexec, but I was actually thinking more among the lines of a button in my application to unlock the features which need access to that directory, which at that moment asks for a password to get writing access to the files in the folder. In this way, people who don't have special permissions on the system the application is running on, can still customize some basic settings.

Well, the obvious solution is to have two processes, one normal user app with the GUI, and something that runs as root that manipulates files as root.
E.g. as an analog "commandline only" issue would writing a file as root:
sudo echo Hello World >/root/hello.txt
Does not work because the redirection is done by the interactive shell and it does not have root's access.
The classical solution is to use two processes:
echo Hello World | sudo tee /root/hello.txt
Now the /root/hello.txt file is opened by tee which runs as root (via sudo), which is allowed.

Related

How do programs keep track of global settings (that are the same each time the program is executed)

So for example, when I load word, if I go to save a file, it will default to the same directory that I selected last time...Also, it keeps track of the last 10 (or whatever) .doc files you opened
how does it do this? Right now for a program I am writing (in C#), I just save a text document which holds these kinds of settings...is this bad practice??
If not, where should I put this text doc. Right now I am just using:
Path.GetDirectoryName(Application.ExecutablePath);
as the directory where this file is held...its fine before I publish the program, because it just uses one of the folders in the solution directory...
But after I publish it, the directory is really weird:
C:\users\me\AppData\Local\Apps\2.0\J6AAL16C.2QW.....
and it goes on....So is this like a directory created for this program when I install it?? is this where it SHOULD be getting saved?
Thanks!!
The Application Settings feature of .NET makes this pretty simple, really. In particular I wouldn't use the registry if I were you - it makes it harder for users to copy settings from machine to machine, etc.
It does get a bit weird if you try writing your own settings providers though - I've tried to understand the overall design a couple of times, and always got lost. For simple applications though, it's easy.

How to track directory opening

I'm not sure if the question's title makes sense, and I'm sorry if it doesn't; I didn't really know what to title it.. Anyway, is there a way to make your program track the viewing of a folder?
What I'm trying to achieve: Windows 7 Home Premium doesn't allow encryption. So, I made a folder inside my user directory, and set it to hidden. Although, you can easily find it by changing windows settings.. So, is there a way to make a program pull up a window if the user tries to access that certain folder?
I don't think you can detect the "opening" of a folder.
Instead, you may want to set a FileSystemWatcher to detect any file access to the files in that particular folder.
Hope this helps.
First of all, I have to wonder why you're not just setting an ACL on the directory to prevent access.
However, it sounds like you want to find when somebody is accessing a particular directory. To do this, you enable filesystem auditing, then set the audit ACL to generate audit entries for "List folder". This will cause entries to be generated in the Security Event Log whenever the directory is viewed.
Now you just have to write a program that watches the Security event log looking for entries indicating that somebody has listed the directory in question and take action as necessary.
Well, there is an article on code project describing how you can hook into windows system calls: http://www.codeproject.com/KB/system/hooksys.aspx - it's not simple though (and also not C#) and has the potential to screw with your system but if it might be a fun project to work on.
A simpler option would be: Use a 3rd party desktop encryption tool - not much programming involved here but it might do the job better than anything else.

Silverlight open file from server

I have task to give in my application possibility to open document that is located on server, but I dont know at all how to implement this.
Please give the main idea how can i do this?
If you are trying to open a file based on it's MIME extension and not prompt the user, you really can't do that in a Silverlight web application (for either case, MIME launching or opening a file without prompting the user). Silverlight isn't a "browser standard", and a lot of it's seemingly crippled features are done so out of the name of security, and a safer user experience. (You don't want a Silverlight app randomly reading files on your hard drive without you knowing about it and silently uploading them somewhere now, do you?)
I believe you can do whatever it is you're trying to do in Silverlight 4, but it requires elevated permissions (and consequently that it must be installed out of browser), and a little bit of COM hackery.
The elevated permissions do not give you direct access to files outside of the "My" Folders, so I don't think you are going to be able to do what you want if you want to preserve cross platform compatibility to the Mac.
However, if you don't care about that, you can do just about anything you want regarding file access by utilizing the Windows system COM objects (specifically the WScript.Shell and Scripting.FileSystemObject objects).
Here's and example.
Scroll to the section of COM Interoperability.

Why can't my C# app create files in Windows 7?

I have a C# app that creates a settings file for itself to store the current state of certain visual elements. This app works just fine on any machine that isn't running Windows 7, but on those machines we get an error that the settings file can't be created because the user doesn't have permission. Now, I could fix this issue by going to each computer, logging in as the administrator and giving the user read and write access on the program folder for the application that we've installed, but there has to be a better way.
It seems like in XP, you got write access on the folders you created by default, but that isn't the case anymore. Is there a setting I need in the setup package to make this work?
The point is that you shouldn't be storing settings files in the program folder. Microsoft have advised against this for a long time, but started making things stricter with Vista IIRC.
Use Environment.SpecialFolders.ApplicationData (etc) to find the most appropriate place to put settings. Or use the .NET settings infrastructure which does this automatically for you.
are you trying to create files in the installation folder? you should be using the user data folder for data and not the installation folders. Use the Environment.SpecialFolders.ApplicationData folder to get a folder you can write to.
You're probably running as an administrator on your non-Windows 7 machine which an write anywhere. Be sure to save any per user instance data in their AppData folder (roaming if it should follow them from computer to computer, or local if its a cache or local to taht machine only). If you need to share settings between users, use the C:\ProgramData folder with the appropriate permissions.
A program shouldn't try to store settings in its installation directory.
Be sure to use the SpecialFolders along with Environment.GetFolderPath to get the right locations needed. You should never hard code paths because they can be different between versions AND languages. (I know in the German version of XP it wasn't Program Files but Programme!)
this app works just fine on any machine that isn't running Windows 7
Wrong! It only works on those machines if you run as administrator. I think you'll find your program is broken on Windows XP as well if you try to run it on just about any business computer rather than a home computer.
Instead, this kind of information needs to go in one of the special Application Data folders.
This is a security flaw in your program because your program is writing information to the program directory (which is, and should be, protected.) If it's a situation of correcting the root cause, consider using the SpecialFolder enumeration or the static members on Application like like CommonAppDataPath to write your information to a more appropriate location.
Assuming the typical approach to writing a file via a path, this is a trivial fix and there's no good "expediency" reason to not correct the root cause. If you're not sure about how to manipulate the path, consider using Path.Combine(). It does it for you.
In general, you shouldn't be writing program data to any folder underneath Program Files (even if you created the folder). You should use the Environment.GetFolderPath(...) to figure out where to put your application specific data. You can pass in one of many enums defined here -- you probably want Environtment.SpecialFolder.CommonApplicationData
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
I do not see how any of this is an actaul answer. I need to be able to write a report and have it saved the users documents folder the same folder I used to read the xml files I am writing the report from.

Restrict a directory that can be used only through a .net Application

I have a windows Application that stores certain files in a directory. I would like to know if there is a way in .net that I can restrict users not to have access to that directly (by just going to that directory in windows, and grab files) so only my application can add/verify/delete a file in that directory.
Could you use the Isolated Storage in .Net? While, it isn't necessarily restricted away from your users it may be a lot harder to find.... (stores under the local settings\application data\isolated storage for the logged in user)
Via code you work with it by using / importing the System.Io.IsolatedStorage and then you can create directories, files, etc... normal.
You also don't have to keep track of the actual directory on the HD it's in as .Net manages this. Maybe a nice plus.
This is only possible if your application runs with different credentials than the user running the application.
By default all applications run with the credentials of the user who launched the process. This means the application has the same directory and file restrictions as the user. Without a different account, the application can only decrease it's ability to access the file system, not increase it.
Dealing with the file system is evil in general. Even if you could get the user to not play in that directory you still can't trust the results will be in the exact same state as you left them. It's possible for other users, physical disk corruption or any number of other things to corrupt your files.
The only way to sanely program the file system is to expect failure from the start and count yourself lucky when it actually works.
The application needs to run as a specific user - and that user will always have the same rights as your application. You can, potentially, make a service that runs as an administrator to prevent standard users from accessing a directory, but the administrator will still be able to change things in the directory.
I suggest you look for another approach for your problem. There are potentially alternatives - perhaps you should consider keeping some type of encrypted hash on the directory contents. That would at least allow you to verify that the contents have not been changed, although it won't prevent the change from occurring.
As others have mentioned, you need the application to act as a different user than the ones currently logged in. You should look into 'impersonation', here are some links that can get you started on getting your application to act as a different user when performing certain tasks:
http://csharptuning.blogspot.com/2007/06/impersonation-in-c.html
http://www.codeproject.com/KB/cs/cpimpersonation1.aspx
The easiest (although not secure in any way) method, would be to use a hidden folder, which the users know nothing about. so \servername\hiddenfiles$
A more secure alternative would be to change the credentials the program is using to access the folder. Is it necessary for them to access it as themselves?
An alternative would be to create a dummy account for each user, where they do not know the password. Make it relate to their windows login, so domain\myname becomes domain\mynamehidden. Then use this to connect to the directory.
This will ensure everything can be audited nicely too.
Look at FileSystemWatcher - it doesn't prevent from changes in directory, but allows to notify program about changes in dir.

Categories