Einleitung

Der Inhalt dieses Dokument wendet sich an Architekten und .NET Entwickler.

Moderne Windows-Betriebssysteme überwachen den Zustand des Computers in Hinblick auf relevante Sicherheitseinstellungen. Diese Einstellungen sind auch von eigenen Anwendungen über eine Programmierschnittstelle nutzbar.

Die Verwendung dieser API’s wird an Hand einer lauffähigen VisualStudio 2010 Lösung demonstriert. Die Lösung und dieser Guide als Worddokument kann unter http://code.msdn.microsoft.com/AccessingWindowsSecu heruntergeladen werden.

 

Technische Voraussetzungen

Visual Studio 2010

C#

Windows Vista oder Windows 7

 

Einführung in das Szenario

Die Sicherheit von Rechnern spielt heute eine grosse Rolle für verschiedene Anwendungen. Weiterhin gibt es in modernen Betriebssystemen API’s und Funktionalitäten, die den Sicherheitsstatus eines Computers überwachen. Wenn man zu Beispiel ein Programm schreibt, welches nur auf einem Rechner mit Virenscanner und Firewall laufen soll, kann man die vorhandenen API’s nutzen, um die notwendigen Prüfungen durchzuführen.

Erste Schritte in Richtung dieser Betriebssystem Erweiterung für eine erhöhte Computersicherheit wurden schon im Betriebssystem Windows XP mit dem „Security Center“ und einer Firewall (Windows XP SP2) eingebaut. Seit diesen Anfängen wurden diese Funktionen in den Folgebetriebssystem ständig erweitert und verbessert.

In Windows Vista wurde unter anderen der „User Account Control“ Sicherheitsmechanismus eingefürt.

In Windows 7 heisst die Überwachungsanwendung „Action Center“ und kann so zum Beispiel aus dem Control Panel gestartet werden. Sie dient sowohl der Überwachung und Steuerung von Sicherheitsfunktionen als auch zur Administration von allgemeinen Wartungsfunktionen.

clip_image002

Abbildung 1 - Windows Action Center

Aus dem Action Center können folgende sicherheitsrelevante Funktionen beobachtet und bei ausreichenden Berechtigungen verändert/konfiguriert werden:

  • Netzwerk firewall
  • Windows Update
  • Virus protection
  • Spyware and unwanted software protection
  • Internet security settings
  • User Account Control
  • Network Access Protection

 

Die Beispielanwendung und der Code

Bei der Beispielanwendung handelt es sich um ein WPF .NET 4.0 Projekt, dass in der Programmiersprache C# implementiert wurde. Bei der Implementierung der Anwendung wurden Fehlerbehandlung etc. vernachlässig und auf das Kernthema fokussiert.

Die Anwendung enthält ein sehr einfaches WPF Fenster, dass die Ein- und Ausgabe realisiert.

Der wichtigste Bestandteil im C# Projekt ist die Klasse Win32. Der Name der Klasse ist bewusst gewählt, da die Klasse im Wesentlichen den Zugriff auf Funktionen des Win32 API kapselt. Die Funktionen und Enumerationen, die der C# Code abbildet und verwendet sind in der MSDN Library unter http://msdn.microsoft.com/en-us/library/ee213469(v=VS.85).aspx beschrieben.

Es handelt sich um 3 C-Funktionen und 2 Enumerationen:

[Flags]
public enum WSC_SECURITY_PROVIDER : int
{
    WSC_SECURITY_PROVIDER_FIREWALL = 1,
    WSC_SECURITY_PROVIDER_AUTOUPDATE_SETTINGS = 2,
    WSC_SECURITY_PROVIDER_ANTIVIRUS = 4,
    WSC_SECURITY_PROVIDER_ANTISPYWARE = 8,
    WSC_SECURITY_PROVIDER_INTERNET_SETTINGS = 16,
    WSC_SECURITY_PROVIDER_USER_ACCOUNT_CONTROL = 32,
    WSC_SECURITY_PROVIDER_SERVICE = 64,
    WSC_SECURITY_PROVIDER_NONE = 0,
    WSC_SECURITY_PROVIDER_ALL = WSC_SECURITY_PROVIDER_FIREWALL | WSC_SECURITY_PROVIDER_AUTOUPDATE_SETTINGS | WSC_SECURITY_PROVIDER_ANTIVIRUS |
    WSC_SECURITY_PROVIDER_ANTISPYWARE | WSC_SECURITY_PROVIDER_INTERNET_SETTINGS | WSC_SECURITY_PROVIDER_USER_ACCOUNT_CONTROL |
    WSC_SECURITY_PROVIDER_SERVICE | WSC_SECURITY_PROVIDER_NONE
}

[Flags]
public enum WSC_SECURITY_PROVIDER_HEALTH : int
{
    WSC_SECURITY_PROVIDER_HEALTH_GOOD, // Green pillar in English locales
    WSC_SECURITY_PROVIDER_HEALTH_NOTMONITORED, // Yellow pillar in English locales
    WSC_SECURITY_PROVIDER_HEALTH_POOR,  // Red pillar in English locales
    WSC_SECURITY_PROVIDER_HEALTH_SNOOZE, // Yellow pillar in English locales
    WSC_SECURITY_PROVIDER_HEALTH_UNKNOWN
}

[DllImport("wscapi.dll")]
public static extern int WscGetSecurityProviderHealth(int inValue, ref int outValue);

[DllImport("wscapi.dll")]
public static extern int WscUnRegisterChanges(IntPtr hRegistrationHandle);

[DllImport("wscapi.dll")]
public static extern int WscRegisterForChanges(IntPtr Reserved, out IntPtr phCallbackRegistration, WscChangedNotification lpCallbackAddress, IntPtr pContext);



Das API ist sehr einfach. Die Methode WscGetSecurityProviderHealth fragt, den Status eines Providers ab, z.B. Firewall, Useraccount Control, ... . So kann man sich einen Überblick über den Status eines einzelnen sicherheitsrelevanten Subsystems schaffen. Die Methoden WscRegisterForChanges registriert einen Handler, der aufgerufen wird, wenn sich der Status eines Security Subsystems ändert. In dem implementierten Beispiel wird ein Handler in C# Code aufgerufen, der die Anzeige aktualisiert.

Mit der Methode WscUnRegisterChanges kann ein registrierter Handler wieder abgemeldet werden.

Weiterhin sind in der Klasse Win32, diese nativen API’s gekapselt, um den Zugriff auf die Funktionen komfortabler zu gestalten und die Int-Werte des nativen API’s in C# Enumeration-Werte zu mappen.

public static WSC_SECURITY_PROVIDER_HEALTH GetSecurityProviderHealth(WSC_SECURITY_PROVIDER inputValue)
{
    int inValue = (int)inputValue;
    int outValue = -1;

    int result = Win32.WscGetSecurityProviderHealth(inValue, ref outValue);

    foreach (WSC_SECURITY_PROVIDER_HEALTH wsph in Enum.GetValues(typeof(WSC_SECURITY_PROVIDER_HEALTH)))
        if ((int)wsph == outValue) return wsph;

    return WSC_SECURITY_PROVIDER_HEALTH.WSC_SECURITY_PROVIDER_HEALTH_UNKNOWN;
}

private static GCHandle gHandle;
private static IntPtr regHandler;

public static void RegisterForWscChange(ref WscChangedNotification handler)
{
    if (gHandle.IsAllocated)
    {
        throw new ApplicationException("Change handler already registered!");
    }
    else
    {
        gHandle = GCHandle.Alloc(handler);

        int result = WscRegisterForChanges(IntPtr.Zero, out regHandler, handler, IntPtr.Zero);
    }
}

public static void UnRegisterForWscChange()
{
    if (gHandle.IsAllocated)
    {
        WscUnRegisterChanges(regHandler);
        gHandle.Free();
    }
}

public static void ScStatusChangedHandler(IntPtr param)
{
    try
    {
        System.Diagnostics.Trace.WriteLine(Win32.GetSecurityProviderHealth(WSC_SECURITY_PROVIDER.WSC_SECURITY_PROVIDER_FIREWALL));
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

public static List<ComputerStatus> GetComputerStatus()
{
    List<ComputerStatus> status = new List<ComputerStatus>();

    Array a = Enum.GetValues(typeof(WSC_SECURITY_PROVIDER));
    foreach (WSC_SECURITY_PROVIDER sp in a)
    {
        if (sp != WSC_SECURITY_PROVIDER.WSC_SECURITY_PROVIDER_NONE && sp != WSC_SECURITY_PROVIDER.WSC_SECURITY_PROVIDER_ALL)
        {
            WSC_SECURITY_PROVIDER_HEALTH spStatus = GetSecurityProviderHealth(sp);
            status.Add(new ComputerStatus() { Category = sp.ToString().Replace("WSC_SECURITY_PROVIDER_", ""), Status = spStatus.ToString() });
        }
    }

    return status;
}

Im Code der Klasse MainWindow.cs wird die einfache Verwendung der Klasse Win32 demonstriert. Mit 7 Zeilen von Code kann die Funktionalität der Demoanwendung realisiert werden. Das Userinterface der einfachen Anwendung sieht wie folgt aus.

clip_image004

Abbildung 2 - Userinterface der Demoanwendung

 

Zusammenfassung

Mit dem Windows Security Center API lassen sich schnell und unkompliziert Anwendungen implementieren, die den Sicherheitszustand eines Computers beachten bzw. auf Zustandsänderungen der Sicherheitseinstellungen reagieren können.

Das API ist auf den Plattformen Windows Vista und Windows 7 verfügbar. Unter Windows Server fehlt die notwendige WSCAPI.DLL.