24

Windows Vista

Sample Credential Providers Overview

24

Contents

Terms of Use 2

Release Notes 3

SampleCredentialProvider 3

The SampleCredentialProvider Codebase 4

Project Structure 4

Common Tasks For Extending SampleCredentialProvider 5

Tips & Tricks 7

Automating The Deployment Process 7

Developing With CredUI 7

Debugging LogonUI 8

If Your System Becomes Unstable 9

SampleCredUICredentialProvider 10

SampleAllControlsCredentialProvider 10

SampleHardwareEventCredentialProvider 11

SampleWrapExistingCredentialProvider 13

Default Tiles 15

Wrapping Existing Credential Providers 15

Credential Provider Architecture 17

Summary 17

Questions 17

Appendix A – Frequently Asked Questions 18

Terms of Use

This code and information is provided "as is" without warranty of any kind, either expressed or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

Information in this document, including URL and other Internet Web site references, is subject to change without notice. Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

Copyright (c) 2006 Microsoft Corporation. All rights reserved.

Microsoft, Windows Vista, Windows XP, and Visual Studio are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.
Introduction

In this document, we’ll take a look at some custom Windows Vista credential provider samples. Specifically, we’ll cover the following topics:

1.  Understanding the base SampleCredentialProvider codebase.

2.  Common tasks for extending the base SampleCredentialProvider codebase.

3.  SampleCredUICredentialProvider, which supports CredUI.

4.  SampleAllControlsCredentialProvider, which exposes each possible UI control.

5.  SampleHardwareEventCredentialProvider, which supports asynchronous events.

6.  SampleWrapExistingCredentialProvider, which wraps the default username/password credential provider in Windows Vista.

Release Notes

This is the third release of the samples. The first release targeted the February CTP. The second release targeted Beta2 and added additional samples. This third release updates those samples for RTM.

Changes include

·  Fixing unlock. Post-Beta2, Windows Vista changed to require a KerbWorkstationUnlockLogon message type to unlock the machine and a KerbInteractiveLogon message type to log on to the machine. Previously it would accept a KerbInteractiveLogon message type for both logon and unlock. The samples have been updated accordingly. [v3.0]

·  Using CredProtect to encrypt the password when the credentials are serialized. [v3.0]

·  Updating the project settings to support Visual C++ Express. [v3.0]

·  Updating the SampleCredUICredentialProvider to handle additional Credui scenarios such as proper handling of CREDUIWIN_PACK_32_WOW [v3.0]

·  Fixed some issues in SampleWrapExistingCredentialProvider. Any callbacks into ICredentialProviderCredentialEvents would fail because it was confused about which credprov was which. Among other symptoms, this caused change expired password to fail. The solution is to have the wrapper credprov provide an ICredentialProviderCredentialEvents. [v3.0]

·  Overview now includes FAQ (Appendix A) [v3.0]

SampleCredentialProvider

Out of the box, SampleCredentialProvider provides a DLL project that exposes the two COM interfaces required to develop a credential provider: ICredentialProvider and ICredentialProviderCredential. ICredentialProvider exposes the functionality to enumerate available credentials, and ICredentialProviderCredential exposes the functionality required for each specific credential during the authentication process.

The SampleCredentialProvider Codebase

The SampleCredentialProvider project provides a working baseline credential provider. This sample is hardcoded to expose two accounts: Administrator and Guest. The following screenshot shows what this might look like on a domain joined machine.

Project Structure

The SampleCredentialProvider project includes a small set of files, each with their own purpose:

File[s] / Purpose
common.h / Describes the UI and layout of the credentials. Edit this file to change the number and type of UI elements in each credential tile.
CSampleCredential.h/.cpp / Defines the behavior of a credential tile. Edit these files to change the way a tile responds to user input.
CSampleProvider.h/.cpp / Defines the behavior of the credential provider, which typically manages one or more CSampleCredentials. Edit this file to change the way credentials are enumerated.
dll.h/.cpp, samplecredentialprovider.def / Fulfills baseline support for COM server and DLL requirements. You shouldn’t need to edit these files.
guid.h/.cpp / Defines the provider’s GUID. You’ll need to edit guid.h to reference your unique GUID.
helpers.h/.cpp / Provides utility methods for working with UNICODE strings and auth packages. You shouldn’t need to edit these files.
Register.reg, Unregister.reg / Registers and unregisters the sample credential provider, respectively. You’ll need to edit these files to use the GUID from guid.h wherever a GUID appears. You’ll also need to edit the Register.reg file to reflect the name of your object (the first two registry keys) and the name of the DLL (the third registry key).
resource.h, resources.rc / Manages provider resources, such as the tile image. Edit these files if you want to add more resources, such as images, to the credential provider.
tileimage.bmp / The image to display on the credential tile. Edit this file (or add different images) to change the image that appears in the tile.

Common Tasks For Extending SampleCredentialProvider

Since SampleCredentialProvider provides a great baseline for developing custom providers, it is recommended that you customize it to meet your needs, rather than starting from scratch. The following steps will walk you through the process of customizing the SampleCredentialProvider project that is common to all extensions.

We’ll use “MyCredentialProvider” as the new project name, so be sure to change it to reflect the name you want to use. We’re also not going to rename any of the folders or files to reflect the name unless it is required to build successfully, so this may be something you choose to do once you’re comfortable with the codebase.

Please note that these samples are intended to be run against the RTM version of Windows Vista. They should be compiled against the RTM version of the Windows Vista SDK.

1.  Set up Visual Studio 2005 in Tools | Options to use the executables, includes, and libs from the SDK instead of the ones shipped with VS. For more info on how to do this, see ReleaseNotes.Htm in the root of the SDK directory.

2.  In the SampleCredentialProvider folder, double-click the SampleCredentialProvider.sln to open it in Visual Studio 2005.

3.  In the Solution Explorer, right-click the SampleCredentialProvider project node and select Rename. Change the name to “MyCredentialProvider” and press Enter to lock in.

4.  In the Solution Explorer, right-click the MyCredentialProvider project node and select Properties. This will launch the MyCredentialProvider Property Pages dialog.

5.  In the left tree view, select the Configuration Properties | C/C++ node.

6.  Make sure the path to your Vista SDK include directory is included in Additional Include Directories. On a default install it ends up at “C:\Program Files\Microsoft SDKs\Windows\v1.0\Include”.

7.  In the left tree view, select the Configuration Properties | Linker node to display the general properties of the linker configuration.

8.  Make sure the path to your Vista SDK library directory is included in Additional Library Directories. On a default install it ends up at “C:\Program Files\Microsoft SDKs\Windows\v1.0\Lib".

9.  Press OK to dismiss the dialog.

10. Open samplecredentialprovider.def. Change “SAMPLECREDENTIALPROVIDER.DLL” to “MYCREDENTIALPROVIDER.DLL”. Save samplecredentialprovider.def.

11. Open guid.h. Replace the GUID in DEFINE_GUID with a unique one. You can generate a unique GUID from Tools | Create GUID. Be sure to remember it for later. Save guid.h.

12. Open Register.reg in notepad or Visual Studio (do not execute it in Explorer). Replace the GUIDs in each registry key with the one created in the last step. Also change “sampleprovider” to “MyCredentialProvider” as well as "SampleCredentialProvider.dll" to "MyCredentialProvider.dll". Save Register.reg.

13. Open Unregister.reg in notepad or Visual Studio (do not execute it in Explorer). Replace the GUID in the registry key with the one used in the Register.reg. Save Unregister.reg.

14. Select Build | Build Solution. If there are any build errors, review the steps above.

15. Copy the freshly built MyCredentialProvider.dll to the System32 directory of the test machine.

16. Copy Register.reg to the test machine and run it from Explorer to register the credential provider.

17. From the Start Menu, select the option to switch users.

18. The login screen should now have an extra Administrator and Guest account. If all you see is one large tile, click Switch User to see the list of tiles.

19. You should be able to log in using the newly created Administrator account tile. The Guest account may or may not be enabled due to the security settings of your system.

20. If you want to remove the sample, copy Unregister.reg to the test machine and run it to unregister the credential provider.

Tips & Tricks

The following are some tips & tricks that can help you during the development cycle. These are useful to keep in mind when reviewing the other samples covered later in this document.

Automating The Deployment Process

If you are developing on a test machine to begin with, you can automate the DLL deployment process of by adding a Post-Build Event that automatically copies the output DLL to the System32 directory. For example, you can go to the Configuration Properties | Build Events | Post-Build Event tab of the project’s Property Pages dialog and set the following for Command Line:

copy "$(OutDir)\$(ProjectName).dll" %systemroot%\system32 /Y

However, be careful when performing a second build since the Post-Build Event only occurs after a successful build, and Visual C++ will skip the build process if the binaries are already up-to-date.

Developing With CredUI

Although you may not want to support the CredUI scenario in your final credential provider, you may wish to use it during development and debugging if you are developing on the test machine. Since the CredUI scenario runs from a normal desktop session, you’ll be able to attach the Visual Studio debugger to it at runtime, drastically simplifying the process of development and testing.

To do this:

1.  Create a new Win32 console project in Visual Studio.

2.  Update the main function of your new project to make a call to CredUIPromptForWindowsCredentials, such as:

#include "stdafx.h"

#include <windows.h>

#include <WinCred.h>

int _tmain(int argc, _TCHAR* argv[])

{

BOOL save = false;

DWORD authPackage = 0;

LPVOID authBuffer;

ULONG authBufferSize = 0;

CREDUI_INFO credUiInfo;

credUiInfo.pszCaptionText = TEXT("My caption");

credUiInfo.pszMessageText = TEXT("My message");

credUiInfo.cbSize = sizeof(credUiInfo);

credUiInfo.hbmBanner = NULL;

credUiInfo.hwndParent = NULL;

CredUIPromptForWindowsCredentials(&(credUiInfo), 0, &(authPackage),

NULL, 0, &authBuffer, &authBufferSize, &(save), 0);

}

3.  Update the project to link against CredUI.lib. You may need to update your “Additional Include Directories” and “Additional Library Directories” to point to the Windows Vista SDK from the project’s property pages dialog.

4.  Add your credential provider project to the solution.

5.  Build the credential provider and make sure the latest version is deployed to the System32 directory and is registered as a credential provider.

6.  Set breakpoints, etc, and then run the console app in debug mode. Your breakpoints should get hit as appropriate after CredUIPromptForWindowsCredentials is called from the console app.

Debugging LogonUI

In short: hook up kd between your test machine and your debugging machine and then pipe ntsd over kd for logonUI. There’s a fair amount of info on how to do this on the web (although not specifically for logonUI). But here’s some basic pointers.

1.  Install the debugger package (http://www.microsoft.com/whdc/devtools/debugging/default.mspx)

2.  Get kd set up between the two computers (for more info look on the web or MSDN)

a.  Hook up your debug cable

b.  On the debugee machine, run something like the following (change command line arguments as necessary)

i.  Bcdedit –debug on

ii. Bcdedit –dbgsettings serial debugport:1 baudrate:115200

c.  Reboot debuggee

d.  On debugger machine, run something like

i.  Kd.exe –r –k com:port=com1,baud=115200

3.  Copy symbols that you will need locally to the box since NTSD won’t have access to the network

4.  Create a key named logonui.exe under HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options

5.  In the logonui.exe key, create a string value named Debugger

a.  Populate that value with the path to ntsd.exe on your machine, for example C:\debuggers\ntsd.exe -d -gG -y <path to local symbols> (space between –y and path required)

b.  –d pipes the NTSD output to KD

c.  –g ignores the initial startup breakpoint in the process (if you want the process to break instantly when first executed to set BPs, do not set the small g)

d.  –G ignores the termination breakpoint, so the process will exit quietly

e.  –y sets the local symbol path on the debugee for NTSD

6.  Breaking in when a .DLL loads (not required, but good to know if needed)

a.  Follow all of the steps above for the executable that loads the .dll, but do not set the small g flag, then when the process starts, NTSD will break in

b.  Type sxeld <dll name>

c.  Then g the debugger and NTSD will break in on load of that dll and you can set breakpoints, etc.

If Your System Becomes Unstable

During the process of credential provider development, there is a good possibility that you might mess up the credential providers, possibly even crashing LogonUI.

Don’t Panic.

Typically, you can reboot Windows in safe mode (repeatedly tap F8 during early boot for the menu to do this). From safe mode you should be able to log in using the normal password provider, at which point you can unregister the offending credential provider.