Utility for Encrypting .Net App.Config Sections

by martin 18. July 2011 23:00

.Net ships with aspnet_regiis.exe for encrypting configuration sections in Web.Config files, but there seems to be no quick and dirty way to do this in non-web applications.  Sure, if you are packaging up software into an installation package, you can add your own custom installation action to encrypt a configuration section (see The Code Project : Implementing Protected Configuration With Windows Apps).  Or you can write code into your application to automatically encrypt a config section if it encounters it in an unencrypted state (see The Code Project : Encrypting the app.config File for Windows Forms Applications).  If you have IIS installed on the box, you can even rename your App.config to web.config and still use aspnet_regiis (see DotNetProfessional.com: Encrypt Sections of Web.config or App.config).  But what if you just want a quick way to encrypt a config section or two without all the fuss?  Or, better yet, what if you forget a password or some other important secret that is already encrypted in an app.config somewhere and you need to get it back.

 

Here is a simple little command line app that allows you to do app.config section encryption and decryption without having to write any addtional code (The .Net framework already takes care of decrypting these values automatically for us when we use them in our code).  Only this one small EXE is required and the standard MS .Net 2.0+ runtime dlls that are already installed on your system.

AppConfigSectionEncyptor.exe (7 kb)

Below are the "Usage" instructions that result from running the EXE without any parameters.  "-e" is for encrypt, "-u" is for unencrypt.

C:\>AppConfigSectionEncyptor.exe
Usage:  AppConfigSectionEncyptor.exe [-e|-u] [-d] file section

Examples:

        AppConfigSectionEncyptor -e c:\MyCode\MyApp.exe mySecureSection
        AppConfigSectionEncyptor -e -d c:\MyCode\MyApp.exe mySecureSection
        AppConfigSectionEncyptor -u c:\MyCode\MyApp.exe mySecureSection
Please note that 'file' is the path to the EXE, not the config file itself.
Please note that you need adaquate permissions to the keystore for this to work.

-d = use the DPAPIProtectedConfigurationProvider for encryption instead of the default RSAProtectedConfigurationProvider.

 

I hope that you find this useful, but as always, here is the disclaimer:

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 

Currently rated 1.7 by 56 people

  • Currently 1.696426/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

C# | Windows

Anonymous HTTP PUT with IIS 7

by martin 22. June 2009 21:32

From googling around in trying to get HTTP put enabled on IIS 7, I have concluded that turning on HTTP PUT verb support requires the installation of the WebDAV handler extension and that even then it only works in integrated authentication mode.  If this is not true, please let me know as I was forced to write my own put HTTP handler.  It actually turned out to be a lot easier than I thought it was going to be though.  Implementing IHttpHandler, I ended up just having to binaryread the request into a byte array and then use a binarywriter to write it to a file after validating the PhysicalPath of the request for user permissions and validating that the "pattern" is safe (ex. file extension, path).  I haven't tested the performance against the IIS 6 native solution, but it seems quite fast on today's server hardware.

 

Update May '11:  Here is some code to get you started:

 

Web.Config
  1. <appSettings>
  2.     <add key="BasePutPath" value="C:\PutUploadDir\" />
  3.     <add key="PutSecurityRegularExpression" value="^.+\\UPLOAD\\(\{[0-9A-F]{8}\-[0-9A-F]{4}\-[0-9A-F]{4}\-[0-9A-F]{4}\-[0-9A-F]{12}\})\\(.+\.DOC)$"/>
  4. </appSettings>

 

PutHandler.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Text.RegularExpressions;
  5. using System.Web;
  6. using System.Data.Sql;
  7. using System.Data;
  8. using System.Data.SqlClient;
  9. using System.IO;
  10. using System.Configuration;
  11. using System.Drawing;
  12. using System.Drawing.Imaging;
  13. using System.Drawing.Drawing2D;
  14. using log4net;
  15. using log4net.Config;
  16.  
  17. namespace IIS7Helper
  18. {
  19.     public class PutHandler : IHttpHandler
  20.     {
  21.         private static ILog log;
  22.         private static string strBasePutPath;
  23.         private static string strPutSecurityRegularExpression;
  24.  
  25.         static PutHandler()
  26.         {
  27.             log = LogManager.GetLogger(typeof(PutHandler));
  28.             strBasePutPath = ConfigurationManager.AppSettings["BasePutPath"];
  29.             strPutSecurityRegularExpression = ConfigurationManager.AppSettings["PutSecurityRegularExpression"];
  30.         }
  31.     
  32.  
  33.         public bool IsReusable
  34.         {
  35.             get { return true; }
  36.         }
  37.  
  38.         
  39.         public void ProcessRequest(HttpContext context)
  40.         {
  41.             try
  42.             {
  43.                 byte[] arrBytes = context.Request.BinaryRead(context.Request.ContentLength);
  44.                 string strLocation = context.Request.PhysicalPath.ToUpper();
  45.                 bool blnRequestSecure = false;   // trust no request by default
  46.  
  47.                 // sample url
  48.                 // https://xxx.yyy.com/Upload/{56DA31A8-15A8-4A0B-90F2-4A59909F5DCE}/MyFile.doc
  49.  
  50.                 string strDirName = string.Empty;
  51.                 string strFileName = string.Empty;
  52.                 string strPhysicalLocation = string.Empty;
  53.  
  54.                 Regex re = new Regex(strPutSecurityRegularExpression, RegexOptions.Singleline);
  55.                 Match m = re.Match(strLocation);
  56.                 if (m.Success)
  57.                 {
  58.                     strDirName = m.Groups[1].Captures[0].Value;
  59.                     strFileName = m.Groups[2].Captures[0].Value;
  60.  
  61.                     strPhysicalLocation = Path.Combine(strBasePutPath, strDirName);
  62.  
  63.                     if (Directory.Exists(strPhysicalLocation))
  64.                     {
  65.                         blnRequestSecure = true;
  66.                     }
  67.                     else
  68.                     {
  69.                         log.Error("Directory does not exist : " + strPhysicalLocation);
  70.                     }
  71.                 }
  72.                 else
  73.                 {
  74.                     log.Error("Security Alert : URL RegEx failed for " + strLocation);
  75.                 }
  76.                 strPhysicalLocation = Path.Combine(strPhysicalLocation, strFileName);
  77.                 if (blnRequestSecure)
  78.                 {
  79.                     log.Debug("About to write data to " + strPhysicalLocation);
  80.                     BinaryWriter bw = new BinaryWriter(new FileStream(strPhysicalLocation, FileMode.CreateNew));
  81.                     bw.Write(arrBytes);
  82.                     bw.Flush();
  83.                     bw.Close();
  84.                     bw = null;
  85.                     context.Response.StatusCode = 200;
  86.                     context.Response.Flush();
  87.                 }
  88.                 else
  89.                 {
  90.                     log.Error("Fall through due to either not matching regex or dir not existing. " );
  91.                     context.Response.StatusCode = 500;
  92.                     context.Response.Flush();
  93.                 }
  94.             }
  95.             catch (Exception ex)
  96.             {
  97.                 log.Error("An error occurred : " + ex.ToString());
  98.                 context.Response.StatusCode = 500;
  99.                 context.Response.Flush();
  100.             }
  101.         }     
  102.     }
  103. }

 

Currently rated 2.4 by 5 people

  • Currently 2.4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

ASP.Net | C# | Windows

Simple Web Application Stress Test Utility

by martin 19. June 2009 21:25

I was recently involved in migrating a web application from IIS 5 to IIS 7 on Server 2008.  One of the quintessential components to this app was originally written as a VC++ ISAPI server extension.  I've read many articles touting the efficiency of the integrated .Net pipeline in IIS 7, so I thought I would rewrite this legacy component in C# as an Http handler instead.  Once the code was written, I was looking for a way to test the speed of the old implementation versus the new.  To my surprise, there were very few free tools available to do this type of testing easily and quickly.  Microsoft offers two tools, Web Application Stress Tool and Web Capacity Analysis Tool.  Both were a complete disappointment for me.  WAST seems like it hasn't been updated or recompiled for years, and I couldn't even get it to install without errors on Windows 2008 x64.  WCAT installed, but it offers no GUI and seemed buggy.  So being the geek that I am, I wrote my own.

The tool that I wrote lets you enter multiple URLs to test and allows you to control the number of concurrent requests (threads) that attempt to retrieve the URLs.  You can also specify if you would like the URLs to be requested in a round-robin fashion or randomly.  Statistics are then displayed for all the requests, and per each URL.  Stats given include: the average number of bytes in response, the average round trip request-response time in milliseconds, requests per second, the total number of requests, and the total elapsed time.

This application was written in C# and it requires .Net 2.0+ or Mono 2.0+ to run.  It is available free of charge via the download link below, but if you find it useful, please feel free to donate a few bucks via the paypal link at the top right of this page.

 Download: SimpleMultiThreadedWebStressTester.exe (18.50 kb)



Currently rated 1.5 by 103 people

  • Currently 1.53398/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

C# | Linux | Mono | Windows

Service Oriented Programming and DSLs?

by martin 19. November 2008 22:20

I recently attended Dev Connections and was shown the benefits of decoupling business logic from aspects such as authentication, authorization, security, transaction support, threading model, instantiation model, encoding, and transport mechanism.  In Juval Lowy's Windows Communication Framework (WCF) seminar, I was exposed to the idea of our software tools and runtime environments evolving to allow us to utilize these functionalities in business application without even doing anything additional.  Juval reiterated that WCF is not just about web service and explained many of the benefits that you would get for using WCF even on an application that does not span CPUs.  These benefits include fault tolerance, fault screening (or formal fault contracts), contract first development, and the benefit of a thought out framework that provides separation of concerns for many aspects of enterprise software development.

At PDC at the end of October, Microsoft announced Azure, Oslo, and Dublin.  So Azure, or the "cloud", will let you deploy and run your production applications easily and supposedly allow them to dynamically scale up on-the-fly as demand warrants.  I heard this maybe being accomplished by dynamically spawning new virtualized servers from software and data that are stored in a massive partitioned and redundant sql server cluster (or I may have dreamt all this).  Oslo is the hybrid (both visual (Quadrant) and textual) programming environment for creating and using custom Domain Specific Languages (DSL) and Dublin is a SQL server based repository and runtime environment for the resulting Oslo DSL programs and data structures.  The DSLs are written in Mgrammer ("Mg") and the modeling language itself is just called "M".  There is a silverlight video from MS on http://modelsremixed.com/ that shows the history of "modeling", starting with prehistoric times.  In it, you will notice that one of the process models that they show is comprised of a component with the tiny logo that reads "Wcf" in its top left corner.

So that is a lot of new information to absorb.... but what does this all mean?  Will we all really be orchestrating business process workflows written in "vertical" DSLs?  Where does BPEL fit in?  Is this Microsoft's killer-app ESB?

http://msdn.microsoft.com/en-us/oslo/default.aspx

 

 

Currently rated 1.5 by 2 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

ASP.Net | C# | Windows

Say.exe - a simple command line text to speech program for Windows

by martin 24. October 2008 19:28

I remember back to the old days of my Commodore 64 .  Way back in the early eighties, I had a command line program to be able to have the computer say what you type on the command line.  I was very surprised that nothing like this is freely available on the net for windows.  Microsoft provides both the "MS Agent" COM api as well as the SAPI api, but no easy way to utilize either.

This is a real simple program that simple uses the MS SAPI api.  Simple run "Say.exe Hello world!" and have your computer say hello to the world.

Here is a link to a statically linked EXE:  SayStatic.exe

Here is a link to a dyncamically linked EXE (MSVCRT.dll version 8 / Visual Studio 2008 (9) ):  SayDynamic.exe

 

Here is a link to the source code.

Put it up on a publically accessible network share and use System Internal's psexec.exe (now owned by Microsoft) and have fun freaking folks out.

 

Currently rated 3.6 by 24 people

  • Currently 3.625001/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Windows

Single Button Mouse for Kids

by martin 3. October 2008 23:07

A while back, I looked around the internet for a simple one button mouse that my 3 year old could use to play the games on PBSKids.org.  I was surprised that there was no cheap mice like this available.  My kid was young and having a hard time clicking only the left mouse button, so I decided to write a small program that would allow me to easily switch so that all the mouse buttons functioned as the left mouse button.

Now I simply fire up one exe and then I can launch IE in kiosk mode (via "c:\Program Files\Internet Explorer\iexplore.exe" -k http://www.pbskids.org ) and I can walk away and let my kids have relatively safe fun playing games on the computer.

Here is a link to the program:  SingleButtonMouse.exe

When run, it will automatically go into single button mode and add a notification icon to your task bar (click on this to toggle back to multi button mode).  It has been tested to work in Windows 2000, XP, and 2008.  (It should work in Vista too.)

 

For those interested, the source code is available here.  It is written in C# (requires .Net 2.0 runtime) and uses windows api hooking.

Currently rated 5.0 by 6 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

C# | Windows

Welcome

Please contact me if you have a great idea for a project and need technical expertise in designing, developing, or integrating a custom software solution.

Recent Comments

Comment RSS