3

The web application I'm working on uses log4net for logging. A requirement of the project is that the connections strings should be encrypted. How do I tell log4net to use the decrypted value?

For example:

 <log4net>
    <root>
      <level value="Debug"/>
      <appender-ref ref="AdoNetAppender"/>
    </root>
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <bufferSize value="1"/>
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      <connectionString value="encryptedconnectionstringhere=="/>

Is there a way to accomplish this?

quakkels
  • 11,676
  • 24
  • 92
  • 149

2 Answers2

7

When implementing drumboog's answer, I ran into stackoverflow exceptions due to an infinitely recursive method call. This is essentially what I ended up using.

public class CustomAdoNetAppender : AdoNetAppender
{
    private string _connectionString;
    protected override string ResolveConnectionString(out string connectionStringContext)
    {
        if(string.IsNullOrEmpty(_connectionString))
        {
            var decrypt = new MyDecyptionLib();
            _connectionString = decrypt.MyDecryptionFunction(ConfigurationManager.AppSettings["Connection"]);
        }

        connectionStringContext = _connectionString;
        return connectionStringContext;
    }

}

...and in the log4net config section

<appender name="AdoNetAppender" type="My.Name.Space.To.CustomAdoNetAppender">
quakkels
  • 11,676
  • 24
  • 92
  • 149
  • 1
    Yes, I suppose `ResolveConnectionString` would introduce unwanted recursion... it should have called `base.ResolveConnectionString` instead so that it would call back to the parent implementation (I've updated the answer for future viewers). The only reason you would need this over what you have is if you supplied the connection string name in your appender settings instead of the actual connection string. AdoNetAppender resolves the actual connection string based on several configuration attributes. In your case, this may not necessary. – Glen Hughes Jul 26 '12 at 16:56
4

Aside from writing a custom appender, you could encrypt the entire configuration section:

http://msdn.microsoft.com/en-us/library/zhhddkxy.aspx

Programmatically encrypting a config-file in .NET

Edit:

log4net is open source, so you can also try looking through their code and customizing their appender to fit your needs... maybe something like this:

public class DecryptConnectionStringAdoNetAppender : AdoNetAppender
{
    protected override string ResolveConnectionString(out string connectionStringContext)
    {
        string result = base.ResolveConnectionString(out connectionStringContext);
        if (String.IsNullOrEmpty(result))
        {
            return result;
        }
        else
        {
            Decrypt(result);
        }
    }

    private string Decrypt(string encryptedValue)
    {
        // Your code goes here.
    }
}

Then update the type attribute of the appender element in the config file:

<appender name="AdoNetAppender" type="Your.Namespace.DecryptConnectionStringAdoNetAppender">
Community
  • 1
  • 1
Glen Hughes
  • 4,712
  • 2
  • 20
  • 25
  • Interesting. We're really only concerned about the connection string. The team has already written utilities to encrypt/decrypt strings. Would I be able to use those processes in a custom appender? – quakkels Jul 25 '12 at 22:07
  • After looking through the log4net code... it looks like there might be a better option. Please see my update above. – Glen Hughes Jul 25 '12 at 22:41
  • Wow. Thank you very much for such a detailed answer. I will try this out in the morning. +1. – quakkels Jul 25 '12 at 22:42