I am working on an application with Spring.Net and Windows forms. I would like to prevent users to change the Spring configuration file, something like setting the configuration file as readonly. I read the Spring.Net documentation and I found nothing, I looked on visual studio's side but I did not find how to set a file as Readonly. The only thing I found is to encrypt the app.config file, it is working but it does not prevent user changes.
Do you have any idea?
Really preventing a change will be hard to impossible...
BUT usually it should be enough to be able to recognize whether it has been changed... to achieve this you basically need to implement some variation of the following scheme:
Create a hash of the file (together with a salt)
Store that value in your app.config
In your application read the file and recalculate that hash (with the same hash)
IF that value matches what is in your app.config all is fine, otherwise it has been changed and you need to take the appropriate action
To take the above a step further:
You could embed a copy of the file as an "embedded resource" into your application (EXE/DLL) and replace the file on disk on startup with the content of that resource - this way you make sure that the file is always what your application expects.
DISCLAIMER: the above scheme won't stop a really determined "attacker/hacker...".
Related
I want to get and set some application settings hidden for the user. In this case these are two tokens and two tokens that are being altered by the application. But still all four them are a secret to the application user.
I found two ways on MSDN and this forum.
Use a .config file. -> this sounds okay and I can change some values in it. But I see still a plain text file after publish.
Use the settings in the project properties. -> should it be? I read warnings about that this not so secure after all.
A lot of sites describe a web server solution while I just want to have a desktop solution.
Btw. It is not a commercial product, I am making a hobby project to learn more from C#.net.
If these files need to be altered by the application, you will need to persist these outside of the application so that the new settings will be loaded next time the app starts.
For this, you can always create a config (or settings) file and hide it in the System.IO.IsolatedStorage files for the assembly. This is still editable by the user, but its a bit of a pain to find - plus this will transfer over with roaming profiles so that the settings are used cross machine.
Something simple to help you start out:
IsolatedStorage.IsolatedStorageFile storage = IsolatedStorage.IsolatedStorageFile.GetUserStoreForAssembly();
string subdirectory = "SomeDirectory";
storage.CreateFile(System.IO.Path.Combine(subdirectory, "settings.config"));
Does the * existence* of the setting need to be kept secret, or just its value?
If the latter, I'd suggest encrypting the value you save to the .config file.
I'm wondering if there is a way to create settings in a config file for individual programmers. The situation I'm encountering is that there are some programmers who want settings turned on and several that want them turned off. Our config files are in SVN source control, so using a shared config file means we are always overwriting each others settings. We are doing this for an ASP.NET web application project. My initial thoughts would be to create a config file outside of source control, but how do I make it so that each programmer has his own copy?
Here is some further clarification. We have a link in the main web.config file that points to an environment-based file (e.g. file used for dev, staging and live).
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings configSource="EnvironmentConfigs\appSettings.config" />
...
</configuration>
Inside the appSettings.config file, we have settings for dev, staging and live. What I'd like to do is create another config file called user.config and have the individual programmer settings staored there (not in source control of course). What do I need to do in order to have visual studio read from this new file?
The settings file does not need to be versioned in SVN, or each developer can select their settings file to not be overwritten or committed. See the SVN settings file, it could even be added as a global ignore.
Each developer can set up their own build congifuration in Visual Studio. This build configuration should be linked to a build script, which replaces sections of the Web.Config/App.Config/*.Config files specifically as the developer wants.
This way, when they want to make changes to the config files to suit themselves, they should change the replacements in the build script rather than changing the config file directly.
This article covers some of the points i've mentioned: http://www.diaryofaninja.com/blog/2010/05/09/automated-site-deployments-with-teamcity-deployment-projects-amp-svn
Remove the config file from source control and set the svn:ignore property on it. Then it won't be committed. Then, also create another file, like, Production.web.config, that has the production values in it, so you still keep those around too.
That's what I do!
Don't commit config file changes unless they are new settings that to be sent to everyone.
Otherwise, checkout, edit, and leave it checked out. You'll know if someone else has added/modified the file when you get latest version. At which time you merge your settings with their changes, but leave it checked out on your machine.
We do not store application configuration files in source control. Instead, in source control, we store a configuration file template, usually named something like web.config.template. Each developer has their own 'values' file, usually named web.config.values-bem for instance. Each developer also sets up a post-commit hook which takes the template file, and processes it, replacing 'variables' with their values from the specified values file.
For instance, my config values file has the following definition in it:
DB_SERVER=.\SQLEXPRESS
In the web.config.template file, this exists:
connectionString="server=#DB_SERVER#[DEV1];Persist Security Info=True;Password=#DB_PW#;User ID=#DB_USER#;database=#DB_NAME#;Enlist=false;Max Pool Size=100" />
So when the process runs (a python script), it replaces all instances of #DB_SERVER# with the setting I have in my values file. The template script allows for default values to be specified right in the template as well, so you can make changes to the template file and not break other developers' environments (usually). (The default values are next to the variable, in square brackets.)
This solution allows each developer to have their own settings, but still have a web.config.template file that's versioned, and each developer avoids 'inflicting' configuration changes on other developers.
This works well for us. If you want to use the same scheme, you can check out the code for it on my github: https://github.com/bmontgomery/FileReplace. I can help you with the hook scripts as well if you're interested in that.
So I recently updated my application to support a new feature. In the past if the configuration file was deleted by the user it wasn't a big deal. This new feature requires it to exist, and one of the requirements is that, the file exists in the application's installation directory.
I have notice when the file is deleted ( depending on variables I have not figured out ) I get a .NET notification that the configuration file is missing or corrupt. Currently my program then crashes ( I still have to figure out how to duplicate this behavior ) which is the reason for this question.
I am familar with ConfigurationManager. I am having trouble writting the file once the default values are loaded. Forcing a Save for some reason does not seem to recreate the file, at least not in the installation directory, which is a requirement.
I am looking for guidence on how to handle this corner case in an elegant manner. I would post code, honestly its just all failed attempts, which while my attempts do generate a file the contents are not the settings I am looking for.
I am willing to post anything that might be able to help.
Stop using the built-in config support and just use write/read to a file called something.exe.config using the standard XML classes and if that gets deleted, just re-create it from values hard-coded in the executable.
The config file support is supposed to make things easier, if you need to do stuff where it makes things difficult, don't use it.
Something like
var wcfm = new WebConfigurationFileMap();
Configuration newConfig = WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
newConfig.Save();
doesn't work?
You dont. Under normal conditions the program can not write into it's install directory - this is a standard windows security issue and the reason why app application data should reside ni external (from the exe's point) driectories.
If an admin deletes the config file, crash, ask for reinstall. There is nothing you can RELIABLY do, as you can not assume you can write into the folder at runtime. A message followed by an event log entry is the best approach here. Users are not supposed to delete parts of the application.
I've seen this solution proposed, but doesn't seem to work for me:
Configuration oConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
oConfig.AppSettings.Settings["PreferenceToRemember"].Value = “NewValue”;
oConfig.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
It successfully changes the value in memory, but does not save it back to the config file.
I'm trying to do this in a Wpf app, if that makes any difference.
Or is there a preferred way to save user settings to a file?
If your app is installed in \Program Files\ then it may not have permissions to write to the file. Generally, app.config files are modified by hand (in my experience, at least). If you want to persist user preferences, you should look into a .settings file as these are created in the %appdata% (or %localappdata%) directory, which is under the user's directory.
My guess is that using OpenExeConfiguration does not actually open the associated file. For example, you could be running from a XAP, where there would still be a .exe.config inside the .xap, but it doesn't map to an actual file on the filesystem.
You could probably check this by seeing if oConfig.HasFile is true or not.
If my guess is correct, then you'll need to use the OpenExeConfiguration(string) overload; the sample on the MSDN page has a reasonable way to get the right filename, although my first instinct was instead to try System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase.
I know it is a good idea to store configuration data in app.config (e.g. database connection strings) instead of hardcoing it, even if I am writing an application just for myself. But is there a way to update the configuration data stored in app.config from the program that is using it?
If you use the Settings for the project, you can mark each setting as either application or user.
If they're set as user, they will be stored per-user and when you call the Save method it will be updated in the config for that user.
Code project has a really detailed article on saving all types of settings.
app.config isn't what you want to use for user-tweakable data, as it'll be stored somewhere in Program Files (which the user shouldn't have write permissions to). Instead, settings marked with a UserScopedSettingAttribute will end up in a user-scoped .config file somewhere in %LocalAppData%.
I found the best way to learn this stuff was to mess with the Visual Studio "Settings" tab (on your project's property pages), then look at the code that it generates and look in %LocalAppData% to see the file that it generates.