Thursday, June 25, 2009

Local Machine - Registry & MAC Address

Recently, had a need to come up with a utility that deals with local machine info/settings, like getting name, MAC address, add/delete/get registry info. Wrote a handler (or utility) that does few things for me and here is a snippet that does the job.

One interesting thing out of it is to get MAC address and I know there are many ways people go about doing this; I chose to look for the first active network interface that has non zero in first 3 octets of the address. Well, the code isn't that complex and easy to look at - take a look:


using System;
using System.Net.NetworkInformation;
using Microsoft.Win32;

namespace MyCompany.MyProject
{
/// <summary>
/// Local Machine Handler
/// </summary>
public class LocalMachineHandler
{
public enum RegistryType
{
LocalMachine,
CurrentUser,
Users,
ClassesRoot,
CurrentConfig,
}

#region Private Properties
private static LocalMachineHandler _localMachineHandler = null;
#endregion Private Properties

#region Public Properties
/// <summary>
/// Singleton instance of LocalMachineHandler
/// </summary>
public static LocalMachineHandler Instance
{
get
{
if (_localMachineHandler == null)
_localMachineHandler = new LocalMachineHandler();
return _localMachineHandler;
}
}

/// <summary>
/// Gets currently loggedin User
/// </summary>
public string UserName
{
get
{
try { return System.Windows.Forms.SystemInformation.UserName; }
catch { return "All Users"; }
}
}

/// <summary>
/// Gets Computer Name
/// </summary>
public string ComputerName
{
get
{
try { return System.Windows.Forms.SystemInformation.ComputerName; }
catch { return ""; }
}
}

/// <summary>
/// Gets MAC Address of the computer
/// </summary>
public string MacAddress
{
get
{
string macAddress = "";
#region Logic to get MacAddress
try
{
IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();

if (nics != null && nics.Length > 0)
{
// All network interfaces
string firstFewOctets = "";
int octetCount = 0;
foreach (NetworkInterface adapter in nics)
{
macAddress = "";
firstFewOctets = "";
octetCount = 0;
IPInterfaceProperties properties = adapter.GetIPProperties();
// Look for the first interface that is up
if (adapter.OperationalStatus == OperationalStatus.Up)
{
// Get the physical address and format
PhysicalAddress address = adapter.GetPhysicalAddress();
byte[] bytes = address.GetAddressBytes();
for (int i = 0; i < bytes.Length; i++)
{
octetCount += 1;
// Get the first 3 octets and make sure they all are not 0
if (octetCount < 4)
firstFewOctets += string.Format("{0}", bytes[i].ToString("X2"));
// Get the physical address in hexadecimal.
macAddress += string.Format("{0}", bytes[i].ToString("X2"));
// Insert a hyphen after each byte, unless we are at the end of the address.
if (i != bytes.Length - 1)
{
macAddress += "-";
}
}
// make sure it's not all 0
if (firstFewOctets != null &&
firstFewOctets.Trim() != null &&
firstFewOctets.Trim().Length > 0 &&
firstFewOctets.Replace("0", "").Length > 0)
break;
}
}
}
}
catch { } // Nothing to catch, it's ok not to get a MAC address
#endregion Logic to get MacAddress
return macAddress;
}
}
#endregion Public Properties

#region Constructors
/// <summary>
/// Singleton - therefore prvate constructor
/// </summary>
private LocalMachineHandler() { }
#endregion Constructors

#region Public Methods

#region Registry methods

/// <summary>
/// Gets Registry value for the type
/// </summary>
/// <param name="registryType"></param>
/// <param name="keyPath"></param>
/// <param name="valueName"></param>
/// <returns></returns>
public string GetRegistryValue(RegistryType registryType, string keyPath, string valueName)
{
try
{
// Based on the type of registry, Open
RegistryKey registryKey = null;
switch (registryType)
{
case RegistryType.ClassesRoot:
registryKey = Registry.ClassesRoot.OpenSubKey(keyPath);
break;
case RegistryType.CurrentConfig:
registryKey = Registry.CurrentConfig.OpenSubKey(keyPath);
break;
case RegistryType.CurrentUser:
registryKey = Registry.CurrentUser.OpenSubKey(keyPath);
break;
case RegistryType.LocalMachine:
registryKey = Registry.LocalMachine.OpenSubKey(keyPath);
break;
case RegistryType.Users:
registryKey = Registry.Users.OpenSubKey(keyPath);
break;
default:
registryKey = Registry.LocalMachine.OpenSubKey(keyPath);
break;
}
return registryKey.GetValue(valueName).ToString();
}
catch { return ""; }
}

/// <summary>
/// Adds Registry value for the type
/// </summary>
/// <param name="registryType"></param>
/// <param name="keyPath"></param>
/// <param name="valueName"></param>
/// <param name="valueData"></param>
/// <returns></returns>
public bool AddRegistry(RegistryType registryType, string keyPath, string valueName, string valueData)
{
try
{
// Based on the type of registry, create
RegistryKey registryKey = null;
switch (registryType)
{
case RegistryType.ClassesRoot:
registryKey = Registry.ClassesRoot.CreateSubKey(keyPath);
break;
case RegistryType.CurrentConfig:
registryKey = Registry.CurrentConfig.CreateSubKey(keyPath);
break;
case RegistryType.CurrentUser:
registryKey = Registry.CurrentUser.CreateSubKey(keyPath);
break;
case RegistryType.LocalMachine:
registryKey = Registry.LocalMachine.CreateSubKey(keyPath);
break;
case RegistryType.Users:
registryKey = Registry.Users.CreateSubKey(keyPath);
break;
default:
registryKey = Registry.LocalMachine.CreateSubKey(keyPath);
break;
}
registryKey.SetValue(valueName, valueData);
return true;
}
catch { return false; }
}

/// <summary>
/// Deletes a registry path
/// </summary>
/// <param name="registryType"></param>
/// <param name="keyPath"></param>
/// <returns></returns>
public bool DeleteRegistry(RegistryType registryType, string keyPath)
{
try
{
// Based on the type of registry, Delete
switch (registryType)
{
case RegistryType.ClassesRoot:
Registry.ClassesRoot.DeleteSubKey(keyPath);
break;
case RegistryType.CurrentConfig:
Registry.CurrentConfig.DeleteSubKey(keyPath);
break;
case RegistryType.CurrentUser:
Registry.CurrentUser.DeleteSubKey(keyPath);
break;
case RegistryType.LocalMachine:
Registry.LocalMachine.DeleteSubKey(keyPath);
break;
case RegistryType.Users:
Registry.Users.DeleteSubKey(keyPath);
break;
default:
Registry.LocalMachine.DeleteSubKey(keyPath);
break;
}
return true;
}
catch { return false; }
}

#endregion Registry methods

#endregion Public Methods
}
}


Love coding!

Tuesday, June 16, 2009

One Way Hash - Credit Card storage?

In ecommerce it is very common for us to come across situations to deal with credit cards and when it must be stored, then the security of it. Recently, was dealing with design of a visa service (confidential) and had to address the storage of CC numbers under PCI guidelines. I would recommend to take a look at this interesting blog - PCI Integrity Corp. There's a lot of documentation, suggestions, issues, complaints, models... e.t.c one can go through. I would like to give my version here and why I chose to do so.

My model:
1. Use one way hash
2. Use salt (even if it's hard coded)
3. Do a minimum of 100 iterations
4. Use 512 encryption (on XP developer machine use SHA512Managed but on servers 2003 and above SHA512CryptoServiceProvider could be used as well)

Let me explain why I chose to use salt that is hard coded in the code. Yes, developers can see it and what's the point in not addressing the separation of responsibilities here... well, the rational is to prevent the external threats. Hashing without salt itself is acceptable under PCI and adding an internally known salt won't make it any worse but rather make it more secured for external threats. Enough said, take a look at a prototype code that can work for this model:


using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;

/// <summary>
/// HashManager
/// </summary>
public sealed class HashManager
{
private static readonly string _salt = "BD4332CF-EE54-4BB1-BCCF-BD7A0F0C7F1F";
private static readonly int _hashIterationsMax = 100;

private HashManager() { }

#region Public Methods
/// <summary>
/// Gets the salted hash value with predetermined iterations.
/// </summary>
/// <param name="unhashedData"></param>
/// <returns></returns>
public static string GetSaltedHash(string unhashedData)
{
string hashData = unhashedData;
for (int hashLimit = 0; hashLimit < _hashIterationsMax; hashLimit++)
hashData = GetHash(_salt + hashData);
return hashData;
}

/// <summary>
/// Verifies the hash
/// </summary>
/// <param name="unhashedData"></param>
/// <param name="hashedData"></param>
/// <returns></returns>
public static bool VerifyHash(string unhashedData, string hashedData)
{
string hashData = GetSaltedHash(unhashedData);
return hashedData.Equals(hashData);
}

#endregion Public Methods

#region Private Methods
/// <summary>
/// Gets the hash value of the data using SHA512Managed
/// </summary>
/// <param name="unhashedData"></param>
/// <returns></returns>
private static string GetHash(string unhashedData)
{
byte[] hashData = Encoding.UTF8.GetBytes(unhashedData);
// on server 2003 or higher, can use SHA512CryptoServiceProvider
SHA512Managed sha512Managed = new SHA512Managed();
hashData = sha512Managed.ComputeHash(hashData);
sha512Managed.Clear();
return Convert.ToBase64String(hashData);
}

#endregion Private Methods

}

Love coding!

Thursday, February 19, 2009

Mutex - A manager class to support both local and global scope

I think Mutex is one such object that I've seen few of us having difficulty or second opinions in usage. After all it does what it's supposed to do and as always I recommend everybody to read documentation to get a good understanding.

There are quite few interesting blogs that go on this topic and here I would like to show a manager class I use (even on terminal services) in my code. Notice that I'm prefixing Global in cases where I want it to be visible for all terminal server sessions; otherwise it's per user session (common usage). Take a look:


using System;
using System.Threading;

namespace myNameSpace
{
/// <summary>
/// MutexManager to support safe Mutex implementation
/// Be sure to check for IsMutexCreated
/// </summary>
public class MutexManager : IDisposable
{
#region Private Properties
private bool disposed = false;
private Mutex _Mutex;
#endregion Private Properties

#region Public Properties
public bool IsMutexCreated { get; private set; }
public bool HasException
{
get { return (ExceptionText != null && ExceptionText.Length > 0); }
}
public string ExceptionText { get; private set; }
#endregion Public Properties

/// <summary>
/// Instantiates the MutexManager with the WaitOne.
/// Check for IsMutexCreated to make sure whether to continue
/// </summary>
/// <param name="handleName">Unique name for each handler</param>
/// <param name="isGlobal">Set to true when using this for Terminal Services</param>
/// <param name="synchronizeRequest">Set to true when the request needs to be synchronized.</param>
public MutexManager(string handleName, bool isGlobal, bool synchronizeRequest)
{
try
{
IsMutexCreated = true;
bool isNewMutexCreated = false;
// Look for global
if (isGlobal)
handleName = @"Global\" + handleName;
//
_Mutex = new Mutex(false, handleName, out isNewMutexCreated);
//
IsMutexCreated = (isNewMutexCreated || synchronizeRequest);
if (IsMutexCreated)
isNewMutexCreated = _Mutex.WaitOne();
}
catch (UnauthorizedAccessException accessException)
{
IsMutexCreated = false;
ExceptionText = accessException.Message;
}
catch (AbandonedMutexException abandonedMutex)
{
IsMutexCreated = false;
ExceptionText = abandonedMutex.Message;
}
}

#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
try { _Mutex.ReleaseMutex(); }
catch { }
disposed = true;
}
}
~MutexManager()
{
Dispose(false);
}
#endregion IDisposable Members
}
}

When to consume, I then use it like:


using (MutexManager mutexManager =
new MutexManager("my unique handler name", true, false))
{
// Mutex has exception?
if (mutexManager.HasException)
log(mutexManager.ExceptionText);

// Not synchronizing the Mutex ==> check for whether to continue
if (!mutexManager.IsMutexCreated)
return;

// do work
}

Love coding!

Wednesday, February 18, 2009

Wizard Control in WinForms? A Trick by hiding Tabs.

Recently I stumbled upon a nifty trick to build a wizard control simulator (like Asp.Net wizard). Check this forum post to see how simple it is; thanks to the poster there. Taking the idea, I created a control class like this:


using System;
using System.Windows.Forms;

namespace MyProejctNameSpace
{
public class WizardControl : TabControl
{
protected override void WndProc(ref Message m)
{
// Hide tabs by trapping the TCM_ADJUSTRECT message
if (m.Msg == 0x1328 && !DesignMode) m.Result = (IntPtr)1;
else base.WndProc(ref m);
}
}
}

And I start using this in place of tab control and used SelectedIndex property to show each step (or tab) in the wizard simulator.
Love coding!

Tuesday, February 10, 2009

Oracle 10g client upgrade error - Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Last year when we were looking to upgrade Oracle client to 10.2 version (our databases were already 10g from a year before), ran into errors with XMLType columns. Anytime we read XMLType column, we get an exception "Attempted to read or write protected memory. This is often an indication that other memory is corrupt".

Strangely, this was not a problem on local machines but only on servers. Tried many simulations and trials, but with no success. This might be a valid error in cases like when the connection was closed/disposed before reading the XMLType data but in my test scenarios I made sure it was clean code and handles objects properly. Actually went too deep trying to diagnose the problem, even digging GAC.

Turns out in the end all we had to do is to apply 10g Release 2 (10.2.0.4) Patch Set 3 for Microsoft Windows (32-Bit). And things have been stable since that patch.

Love coding!

Cryptography - AesManaged

I wrote a cryptography class for one my projects in the past and it was built using RijndaelManaged Class. Few months back, revisited to upgrade it to a simpler yet better code block and that's when I looked into AesManaged Class. Just as I was getting ready to post my sample to this blog, I searched and found that Steve Sheldon had a wonderful blog about a simple example to implement AesManaged class in a blog titled Simple Cryptography Block. Thanks Steve!

Love coding!

Tuesday, January 20, 2009

WCF Client without app.config/web.config

We might be so used to having the config file options for the WCF client applications and it makes life so easy to handle. However, should we ever need to work with no config file scenario, like if we were to build an api kind of interface and expose properties instead of a config file, then we still could do it using code. It can get a little complex but to start let me give you a simple example.

Look at this code snippet that helps to get this idea:


EndpointAddress endpointAddress = new EndpointAddress("http://myServiceURL.com");
WSHttpBinding serviceBinding = new WSHttpBinding();
serviceBinding.ReceiveTimeout = new TimeSpan(0, 0, 120);
MyServiceClient myClient = new MyServiceClient(serviceBinding, endpointAddress);


Love coding!

Serialize using DataContractSerializer

In the past I had couple of posts about serialization - this and this. Recently, came across a need that required to serialize an object that is not public - wanted to serialize an internal class. This could be done using good old reflection techniques but thanks to 3.0/3.5 framework, the solution lies in using DataContractSerializer.

Let's get to the code - quite simple:


using System.Runtime.Serialization;

/// <summary>
/// Serialize using DataContractSerializer
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
internal string Serialize(Object obj)
{
StringBuilder serialXML = new StringBuilder();
DataContractSerializer dcSerializer = new DataContractSerializer(obj.GetType());
using (XmlWriter xWriter = XmlWriter.Create(serialXML))
{
dcSerializer.WriteObject(xWriter, obj);
xWriter.Flush();
return serialXML.ToString();
}
}


Love coding!

Monday, January 19, 2009

WCF Streaming - Couple of blogs to read

Recently I was building a WCF streaming service and came across couple of blogs that are very neat in explaining the basics. Take a look at those...

WCF Streaming: Upload files over HTTP
Transferring large files using WCF

Love coding!

Saturday, January 10, 2009

.Net Chart Control from Microsoft - Just when I needed

We might have used many chart controls over years and there are many good ones out there. But as just I was planning on upgrading one project to include advanced presentation parts, Microsoft comes up with free chart control! Check it out here and here.

Love coding!

Sunday, December 28, 2008

Windows Forms SetFocus to any control

Recently came across a developer need to have a utility that sets focus to a control anywhere on a windows form. Well, you might know about the Focus method of the controls but that might not navigate to the control in cases, say for example, when you have tab pages. So wrote this quick utility that takes the name of the control and a base control where to start the drill down (for most instances, you might want to give the base form here).

The code builds the list of controls recursively by finding the control and it's parents in parent-child hierarchy. Let's look at a simple code snippet for it:


namespace MyProject.ClientUtility
{
/// <summary>
/// Utility class for forms controls
/// </summary>
public class FormsUtility
{
private List<Control> _focusControlsList = new List<Control>();

public FormsUtility() { }

#region Set Focus to Control
/// <summary>
/// Set focus to a control based on the control name.
/// Pass base(parent) control to loop through all child controls.
/// </summary>
/// <param name="controlName"></param>
/// <param name="baseControl"></param>
/// <returns></returns>
public void SetFocusTo(string controlName, Control baseControl)
{
// Build the control list from parent to child order
BuildControlList(controlName, baseControl);
// Set focus in that order:
foreach (Control eachControl in _focusControlsList)
SetFocus(eachControl);
}

/// <summary>
/// Build the control list from Top-Down
/// </summary>
/// <param name="controlName"></param>
/// <param name="baseControl"></param>
/// <returns></returns>
private bool BuildControlList(string controlName, Control baseControl)
{
if (baseControl.Name == controlName)
{
_focusControlsList.Insert(0, baseControl);
return true;
}
foreach (Control eachControl in baseControl.Controls)
{
if (eachControl.Name == controlName)
{
_focusControlsList.Insert(0, eachControl);
return true;
}
if (eachControl.HasChildren)
{
// recursive...
if (BuildControlList(controlName, eachControl))
{
// going back to each parent to set focus
_focusControlsList.Insert(0, eachControl);
return true;
}
}
}
return false;
}

/// <summary>
/// Focus based on type of control
/// </summary>
/// <param name="controlToFocus"></param>
private void SetFocus(Control controlToFocus)
{
switch (controlToFocus.GetType().ToString())
{
case "System.Windows.Forms.TabPage":
// TabPage must be selected
((TabControl)((TabPage)controlToFocus).Parent).SelectedTab =
(TabPage)controlToFocus;
break;
default:
controlToFocus.Focus();
break;
}
}
#endregion
}
}

Love coding!

Wednesday, December 3, 2008

Toolbox Bitmap for Control - when icon not showing?

If you ever built any custom components, you might be familiar in creating toolbox bitmaps. To start with, take a look at this MSDN How To to get an idea of what I'm talking about. It's fairly simple and straightforward. However, I heard from quite few about having problems in getting this working. Most of them seem to have issues with assemblies and if you had made sure that's not the case then one more place I would suggest is going to the properties of the icon or bitmap itself in your project. Make sure that the Build Action is selected to as Embedded Resource before compiling your project.

Love coding!

Friday, November 7, 2008

How to track users when cookies are deleted? Super Cookies?

Ever wonder how some sites keep track of your visit even after clearing all the cookies and cache? Besides permanent cookies, which browsers can clear and also have an expiration, we can look into Flash based Local Shared Object model.

Take for instance Bank of America. According to their Privacy & Security statement they (also) use flash objects to remember your computer. Even when you delete your cookies, cache and temp files they can still recognize your user ID (when you opted to remember the computer) and bypass the security question. There are others that do similar techniques, like INGDirect and so on.

If you are wondering where the information is getting stored, then look under "C:\Documents and Settings\YourUSERID\Application Data\Macromedia\Flash Player\#SharedObjects". And to see how to set your preferences, check this article here.

While this is a neat technique to overcome ordinary user's cookie deletions, the technique is subject to concerns regarding how well it's being used to secure the data. Unlike cookies, flash cache is not something all the users are aware of. Hence before using this technique we need to ensure that the users are educated on risks if using a public machine and leaving a trail of flash cache.

Love coding!