Architect Ryan

Thoughts from a .NET obsessed software architect and developer

nClam: A .NET library to virus scan

Posted on | May 19, 2011 | 7 Comments

Here is a very common scenario:  You have an ASP.NET website (WebForms or MVC).  It has a feature that accepts a file upload from your users.  Other visitors of your site are then able to download that file to their computer.

You might ask, is there a problem with this scenario?  Well, I would say, probably.  If a user uploads an infected file to your website, you will be essentially distributing that infected file to any of your other potential visitors.  That’s not good.  So what can you do?  Scan that upload with a virus scanner!

I’ve done a lot of research and unfortunately found that there are very few libraries for .NET which allow on-demand scanning.  There are a couple that have a $1k+/year price tag and while they might have good features, it seems extremely pricy for virus scanning some file uploads.   There is however, a really great open source antivirus engine called ClamAV.  It looks like in the past there have been some efforts of making a ClamAV client for .NET, however the projects I found seem years old and I could not find anything that worked out of the box.  So I went to work.

I had a prototype of nClam, a pure .NET client to ClamAV, ready in a few hours.  From there I polished up the code, added documentation, pushed it up to GitHub, and published a package to Nuget.

Using nClam is very easy.  It has one pre-requisite, a ClamAV server.  In the past, ClamAV was difficult to get running on Windows, but the team has done a lot of work on the Windows version and it’s able to install as a Windows Service right out of the box now.  Here are some quick steps to installing ClamAV:

  • Download the 32-bit or x64 version of ClamAV here: http://oss.netfarm.it/clamav/.
  • Extract the ClamAV binaries to C:\clamav
  • Create an empty folder called DB in C:\clamav
    image
  • From a command prompt in C:\clamav, run freshclam.exe (this will download the latest virus definitions)
    image
  • Install the ClamAV service by running: clamd –install
    image
  • Install the ClamAV Virus Updater service by running: freshclam –install
    image
  • Open up the Windows Services list and set the “ClamWin Free Antivirus Scanner Service” and the “ClamWin Free Antivirus Database Updater” to Startup Type: Automatic and start them.
    image
  • The ClamAV Server is now set up!

Once ClamAV is running, you can now on-demand scan anything from code using nClam.  Using nClam is easy!  First, get the nuget package nClam (or download it from github) and reference it in your project.  From there, instantiate a ClamClient object with the location of your server (which is probably localhost at this point) and the port it is running under (default is 3310) and call one of the Scan methods!  These methods return a ClamScanResult object, which has a handy enum which tells you if your scan was clean or a virus was detected.  Here is some sample code:

var clam = new ClamClient("localhost", 3310);
var scanResult = clam.ScanFileOnServer("C:\\test.txt");  //any file you would like!

switch (scanResult.Result)
{
    case ClamScanResults.Clean:
        Console.WriteLine("The file is clean!");
        break;
    case ClamScanResults.VirusDetected:
        Console.WriteLine("Virus Found!");
        Console.WriteLine("Virus name: {0}", scanResult.InfectedFiles.First().VirusName);
        break;
    case ClamScanResults.Error:
        Console.WriteLine("Woah an error occured! Error: {0}", scanResult.RawResult);
        break;
}

nClam is free and open source.  It is published under the very open Apache 2 license.  Here are some links to get nClam:

As always, I would love some feedback on this.  Feel free to post this to your blogs, tweet about it, and share it to any .NET developer.  Let’s make our applications more secure!

Websites With Shameful Password Policies

Posted on | May 8, 2011 | 2 Comments

Being a developer who has done a lot of work on the web, I can’t understand for the life of me why some sites restrict what characters you can use in a password.  A strong password will not only used mixed casing, but will have symbols and numbers as well.   For this reason, I have decided to make a list of websites in this blog post that I have encountered recently that prevent you from making a strong password.  Notice, some of these are major financial institutions where your security is arguably more important then other different types of websites.  I will keep updating this post with more as I encounter them.  Feel free to leave a comment with sites to add to the list, just make sure you give me their password policy so I can fill out the explanation column as well!

Website Explanation
BenefitAccess.com (Morgan Stanley) Passwords are case sensitive and must be between 6 and 16 characters long. Passwords must include a number, an upper case letter and a lower case letter. Passwords cannot contain spaces or symbols (such as # or *) .
CapitalOne.com “Your password must consist of 8-12 characters in length, containing at least one letter and one number, and may not include spaces or special characters.”
DiscoverCard.com “A password should be 5–10 characters, using letters and numbers but no spaces or special characters.”
Geico.com “Please use a password that is 8-16 characters (it must contain letters, at least one number and may include special characters ! @ # $ % ^ & * ( ) _ -)”  [Why not all special characters???]

.NET 4 Hidden Gem: System.Lazy

Posted on | April 27, 2010 | 5 Comments

I’ve been using .NET 4.0 at work since Beta 1. Yes, it’s been about a year+ now. Now that .NET 4 / VS2010 has RTM’ed, lots of developers are grabbing the new bits. Because of this, I’m going to make a series of posts about some new hidden gems (aka features I really like :-D ) in .NET 4.

One really cool new class in the BCL is System.Lazy. The beauty of this object is it allows you to define complex or potentially long running initialization code for an object and ensure it only executes once, which it handles automatically.  The lazy object allows you to write initialization code for an object, which is passed to it in as a Func<T>. Here’s a simple example of how to create a new Lazy object:

var lazy = new Lazy<string>(() => LongRunningMethodGetsString());

Lazy provides two properties, IsValueCreated and Value. You use IsValueCreated (which returns a bool) to determine if the object has been initialized. The Value property returns a type T, which returns the object that you create in your initializer code. When you first create a new Lazy object, IsValueCreated is false, until you call the Value property. Your initializer code only runs once, and the Lazy object will always return the result when you call Value.

I have a nice little pattern around the lazy object, which wraps a read-only property around a private lazy object. This makes it easier for consumers of your class to use a lazy object that you are using, by just returning T instead of Lazy<T>.

public class Awesomeness
{
    private Lazy<AwesomeObject> _ourAwesomeObject = new Lazy<AwesomeObject>(() =>
    {
        var awesomeObject = new AwesomeObject();
        //do stuff here to build your awesomeObject
        return awesomeObject;
    });

    public AwesomeObject OurAwesomeObject
    {
        get { return _ourAwesomeObject.Value; }
    }
}

One last word of advice when using Lazy: always make sure that your initializer does not throw an exception.  If it throws an exception (or an unhandled exception occurs), then any calls to the Value property will aways re-throw this exception.  In the case that your initializer could throw an exception, either wrap it in a try block, or just don’t use the Lazy object all together (perhaps by keeping a private field with the initialized value and checking to see if it is null).

Using Windows AppFabric Caching (Velocity) Beta 2 with .NET 4.0 RTM

Posted on | April 26, 2010 | No Comments

One of the awesome Microsoft tools that I’m fortunate to work with is Windows AppFabric Caching, codenamed Velocity.  It’s a distributed caching engine, not unlike MemCache.  I think overall it works really great in my application’s usage, and I also love how there is a Session plugin which is great for running under a farm.  My project has been using .NET 4.0 since Beta 1, so you could call us early adopters.  Last week when Visual Studio 2010 and .NET 4.0 RTMed, my entire team immediately upgraded.  Our entire code base worked as-is with no code changes (we upgraded from the .NET 4 RC).  The one thing I was surprised about was that the AppFabric Caching service did not start – in fact, it immediately failed.  I quickly posted on the MSDN Forums about this, here:  http://social.msdn.microsoft.com/Forums/en-US/velocity/thread/681a2283-a735-488a-aeeb-cdbcfd06d58c.

I received a not so awesome reply:

Beta2 works only with RC release of .Net 4/VSTS 2010. You’ll need to wait for the upcoming RC release which will work with .Net4 RTM.

With that said, I went off to figure out if I could make this work, despite Microsoft’s guidance, especially considering our code base upgraded with 0 changes.  It turns out there is a simple fix for the issue.  All you need to do is edit %windir%\System32\AppFabric\DistributedCacheService.exe.config and make these changes:

Replace

<supportedRuntime version="v4.0.30128" />

With:

<supportedRuntime version="v4.0.30319" />

With this one simple change, everything works great!

There is one other issue.  What if you need to install AppFabric Caching, with .NET 4.0 RTM installed?  Well, the answer is, you can’t.  You have to uninstall the .NET 4.0 RTM, install the .NET 4.0 RC, install AppFabric Caching, then uninstall the RC, and install the RTM.  Yes, this is a huge pain, but since the AppFabric installer is not an MSI, and has a dependency on the .NET 4.0 RC, I can see no other way to get around this.  At least it is *possible* to do this.

My Server is a WIMP

Posted on | April 25, 2010 | No Comments

So I just got WordPress pretty much all set up to my liking for this blog.  Dani, of daniweb.com fame, keeps asking me “So you do like LAMP?”.  Well, we put a second of thought into it, and the answer is NO, I don’t like LAMP – I like WIMP.

Windows
IIS
MySql
PHP

Well, I wouldn’t be proud of this by any stretch of the imagination, but WordPress is really great blog software.  And I always say – use the right tool for the job – so I guess that leaves me with WIMP.

My WIMP installation was really easy to setup, thanks to Microsoft’s sweet Web Platform Installer (grab it here: http://www.microsoft.com/web/downloads/platform.aspx)  All I did was check off PHP (and also Microsoft’s sweet Windows Cache Extension for PHP), hit Install, and presto – everything is installed and working without any other configuration changes.  If you’ve ever set up PHP on IIS before (which I unfortunately have) you’ll notice that I didn’t talk about unzipping some download into a random folder, registering ISAPIs or CGI’s with IIS, and changing an ini file!

So yes, this blog runs on PHP and MySQL.  But that’s just because WordPress rocks.  I have a bunch of plug-ins  installed and I’ve even customized some of the php code that they contain.  I’m not about to quit my romance with .NET, but it is a little bit of fun to write some other languages once in a while.

So there you have it, my webserver is a WIMP!  (It also has .NET on it, for the record!)

Console.WriteLine(“Hello, World!”)

Posted on | April 24, 2010 | 1 Comment

First post!  Hello everyone who is visiting this blog.  I’m Ryan Hoffman, and I’m a software architect focused on .NET solutions.  I’ve recently gotten into photography, and I’m posting lots of pictures to flickr.  I’m going to use this blog to share useful tips/ideas in development, and also just any other thoughts that I have!

  • About

    I'm a software architect, working for a non-profit. I love working with .NET, and I work primarily with C#. I'm one of those people that need to have the beta version of software installed - and have the latest gadgets in my pocket. For more about me, check out my about page.

    The postings on this site are my own and I am not speaking as a representative of my employer, any company or organization.
  • Tags

  • Archives

  • Meta