Protecting your Connection String on Shared Hosting - c#

I am creating a website using MVC5 & EF6. I am also using a shared hosting to publish this website. Now the problem that I have is that my connection string at the moment is sitting in plain text in the web.config file. I am having a very hard time finding a "direct" answer on how I should deal with this.
I have come upon many articles such as this one. The article shows me how to encrypt the Connection Section of my web.config. So I tried following its example and encrypted the mail section it shows in that example. After I ran my code I noticed that my entire web.config file changed.
It use to be like this:
<system.net>
<mailSettings>
<smtp from="info#Site.com">
<network
host="mail.Site.com"
port="25"
userName="info#site.com"
password="password" />
</smtp>
</mailSettings>
</system.net>
and now it is like this:
<mailSettings>
<smtp configProtectionProvider="RsaProtectedConfigurationProvider">
<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>odapFFPDF1Fgsk2wyvbwVC4SNISqhWc9lXiAq+I/OW3wVVqBCPowxyen9M7c9+KUBkXmGSfaUVxDMlqutChv6g6VU8h4TWG3W6Tw/istjfw/UYrRsGguPiOqdvRsl9XLBmnS37v99+VX7FEA9TKb6ufC0a3Defp2MNpGTvTIR20=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>lHPPFRJAH2hIm/Ya+ABRMP5mo5rEYwL2aBJQ/DT4Q+1OZXaftutiddxxJZ4LSgw3pzi1QJpU8eOPwFVebvqFVA4cjs27l8Iqz50E/R/tBfS7e2oqdWTRsc8IFfE/xOIieMp22BuFsYEDbgnIbLdbHJnw+92zyt2lUlzJpW9epNpnb29sVQhtNJ9cPjAaYAaU</CipherValue>
</CipherData>
</EncryptedData>
</smtp>
</mailSettings>
My only problem right now is how do I read those values inside my code without having to decrypt and save the config file. I do not want to rewrite the webconfig file ever time I need to read the mail setting section or even the connection string section.
If I have a method like this:
public static string DecryptMailSettings()
{
var config = WebConfigurationManager.OpenWebConfiguration("~");
ConfigurationSection section = config.GetSection("system.net/mailSettings/smtp");
if (section.SectionInformation.IsProtected)
{
section.SectionInformation.UnprotectSection();
return section.???;
}
return "Nothing was read";
}
How do I get the value of lets say "host" from the example above.

From the documentation:
ASP.NET automatically decrypts the contents of the Web.config file when it processes the file. Therefore, no additional steps are required to decrypt the encrypted configuration settings for use by other ASP.NET features or to access the values in your code.
https://msdn.microsoft.com/en-us/library/dtkwfdky.aspx

I am suggesting that if the encryption/decryption is working fine, and it seems like that 'untangling' the Host Name is troublesome then just add a value to your web.config .
Like This:
<appSettings>
<add key="MAILHOST" value="mail.Site.com" /> ,
and then read that in your code.
Ex:
string HostName = ConfigurationManager.AppSettings["MAILHOST"].ToString();

Related

Web Config Password Encryption Problem in C# Application

<add name="connection" connectionString="Data Source=206.65.100.190,1433; Initial Catalog=dvsss; User ID=xxx; Password=234sdf;"
Please help for encrypted password in web config file
It is never a good idea to store the password because it allows all of the project's developers to view the password, and makes fixing the problem extremely difficult.If the account that is protected by the password is compromised, the owners of the system will be forced to choose between security and availability.
You can use the encryption tool available in aspnet_regiis:
aspnet_regiis -pef "connectionStrings" "c:\path\to\the\folder\containing\webconfig"
This will modify the web.config file with changes looking similar to this:
<connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider">
<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>A long cipher value</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>Another cipher value</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
Source: The ultimate guide to connection strings in web.config

How to send e-mails using NLog?

I'm using NLog, and I'm pretty new at logging. I created the log files but somehow I have a problem whit sending e-mails. I followed all instructions but couldn't make it.
Mail settings in configuration tags in web.config:
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory" from="some#some.org">
<network host="localhost"/>
<specifiedPickupDirectory pickupDirectoryLocation="d:\tmp\email"/>
</smtp>
</mailSettings>
</system.net>
And this is the target inside the nlog.config:
<target name="Mail" xsi:type="Mail" html="true" subject="Error Received"
body="${message}"
to="some1#some.com"
from="some#gmail.com"
encoding="UTF-8"
smtpUserName="some#some.com"
enableSsl="false"
smtpPassword="password"
smtpAuthentication="Basic"
smtpServer="smtp.some.com"
smtpPort="25" />
The rule I used:
<logger name="*" minlevel="Error" writeTo="Mail" />
And I called the logger like this:
Logger logger = LogManager.GetCurrentClassLogger();
try{ //something }
catch(Exception ex){ logger.Error(ex); }
And also I'm pretty confused about the places of the settings and configurations. Thank you.
The body is a layout format, not sure if it will process the ${message} tag. Change ${message] to a layout name that is in nlog.config or leave it off for the ${message}${newline} default.
You can turn on the Internal Debugging
Change the top XML parent to
<nlog internalLogFile="c:\log.txt" internalLogLevel="Trace">
This might give you an idea on the issue. Could be an authentication issue with the server or another issue.
Since you are specifying all the server information in the target, you don't need the web.config settings.
Not sure if it is fixed yet, but you should add a timeout="10000" to the target so it closes the connection.
There is a pretty good example in the NLog Wiki for GMail that works

"File being used by another process" error after modifying app.config

I am writing a simple reporting application that pulls data from a SQL database on an external server, and sends out HTML email messages based on said data.
The project builds and executes perfectly 99% of the time, with the exception being after I modify the app.config file. The very first build and run (in Visual Studio 2012 Pro) after modifying the app.config file yields the following error:
"The operation could not be completed. The process cannot access the file because it is being used by another process."
The build succeeds, but this error is generated immediately following build.
I have found several other users with a similar problem, and the solutions were varied. None had the same error for the same reason. A number of people attributed the error to a VS debugger issue.
Has anyone else experienced the same issue, or does anyone know what may cause this? Note that I get the same error in both Debug and Release. The same error is generated even if the connection string is not encrypted.
I have included the app.config file below, as well as all code that accesses config information.
Config File:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<appSettings>
<add key="minimum_days" value="40"/>
<add key="maximum_days" value="70"/>
</appSettings>
<connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider">
<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>......ciphertext...</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>...ciphertext...</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
</configuration>
Access Code:
private int min_threshold = Convert.ToInt32(ConfigurationManager.AppSettings.Get("minimum_days"));
private int max_threshold = Convert.ToInt32(ConfigurationManager.AppSettings.Get("maximum_days"));
private string connection_string = ConfigurationManager.ConnectionStrings["str1"].ConnectionString;

Modify SmtpSection in web.config in c# code in asp.net?

I have set up the following in my web.config to have multiple smtp settings defined:
<sectionGroup name="mailSettings">
<section name="smtp_1" type="System.Net.Configuration.SmtpSection" requirePermission="false"/>
<section name="smtp_2" type="System.Net.Configuration.SmtpSection" requirePermission="false"/>
</sectionGroup>
</configSections>
<mailSettings>
<smtp_1 deliveryMethod="Network" from="xxx#hotmail.com">
<network host="smtp.live.com" port="587" userName="xxx#hotmail.com" password="xxx" defaultCredentials="false"/>
</smtp_1>
<smtp_2 deliveryMethod="Network" from="yyy#gmail.com">
<network host="smtp.gmail.com" port="465" userName="yyy#gmail.com" password="yyy" defaultCredentials="false"/>
</smtp_2>
</mailSettings>
I have been able to retrieve any of the settings using code and I have set up a function to iterate through the config file and pull out each smtp setting and add to a dropdownlist.
The only thing that doesn't want to work is actually writing back to the web.config (either adding a new smtp or modifying an existing one). I have used the following C# code:
Configuration webConfig = WebConfigurationManager.OpenWebConfiguration("~");
SmtpSection smtpSection = (SmtpSection)ConfigurationManager.GetSection("mailSettings/smtp_1");
smtpSection.From = "zzz#hotmail.com";
smtpSection.Network.Port = 25;
smtpSection.Network.UserName = "xxx";
smtpSection.Network.Password = "xxx";
webConfig.Save();
But this returns the error:
The configuration is read only.
This code works perfectly fine, but of course it modifies the primary smtp settings in the system.net (where you cannot have multiple smtp settings).
System.Net.Configuration.MailSettingsSectionGroup mailSection = webConfig.GetSectionGroup("system.net/mailSettings") as System.Net.Configuration.MailSettingsSectionGroup;
mailSection.Smtp.From = "xxx#hotmail.com";
mailSection.Smtp.Network.Host = "smtp.live.com";
mailSection.Smtp.Network.Port = 25;
webConfig.Save();
Been racking my brain over this and can't seem to find the answer. Feels like it's going to be something so simple (or just not possible). If not, will probably need to encrypt settings and store in the DB.
Thanks! :)

What is ServicePointManager.FindServicePoint used for?

Can someone explain what ServicePointManager.FindServicePoint is intended to be used for? I have been writing some code to work with proxies in C#, and have seen indicators that it might be useful in this respect, but can't see why or how. How is this class (ServicePointManager) or method (ServicePointManager.FindServicePoint) supposed to be used (or when)?
Thanks.
The ServicePointManager.FindServicePoint(...) method will help you get the ServicePoint object that you've been specified in the configuration file.
Let's say, this is your configuration file:
<configuration>
<system.net>
<connectionManagement>
<add address="http://www.contoso.com" maxconnection="2" />
<add address="192.168.1.2" maxconnection="4" />
<add address="*" maxconnection="1" />
</connectionManagement>
</system.net>
</configuration>
This code would retrieve the "http://www.microsoft.com" ServicePoint:
ServicePoint sp1 = ServicePointManager.FindServicePoint(new Uri("http://www.microsoft.com"));
You can read all about it here.

Categories

Resources