SUMMARY ======= The FileServiceSecure sample demonstrates the use of a selected set of security features in the Web Services for Devices API. This sample is a modification to the FileService sample by adding security features into the sample. The two samples, FileService and FileServiceSecure, contains similar behaviour, but are not interoperable. The selected set of security features includes the following: - Server authentication over TLS using X509 certificates. The client authenticates the server using the server certificate thumbprint (certificate hash). - Client authentication using either a. NTLM/Negotiate http authentication scheme or b. X509 client certificate present in the current user store. The sample also includes the usage of the user token, which is a handle containing the credentials of the client, for which the service can use to impersonate that user and execute any of the code paths through that user. FILES ===== Supplied files -------------- ReadMe.txt This readme file FileServiceSecureContract\FileServiceSecure.wsdl FileServiceSecure Contract FileServiceSecureService\SecureService.cpp Secure Service Implementation FileServiceSecureService\SecureService.h Header for the Secure Service Implementation FileServiceSecureClient\SecureClient.cpp Secure Client Implementation FileServiceSecureClient\SecureClient.h Header for the Secure Client Implementation Generated configuration files ----------------------------- These files are generated automatically by WsdCodeGen.exe on FileServiceSecure.wsdl. The following commands were used to generate these config files: WsdCodeGen.exe /generateconfig:all /outputfile:CodeGen_All.config FileServiceSecure.wsdl WsdCodeGen.exe /generateconfig:client /outputfile:CodeGen_Client.config FileServiceSecure.wsdl WsdCodeGen.exe /generateconfig:Host /outputfile:CodeGen_Host.config FileServiceSecure.wsdl This sample only uses CodeGen_All.config, which includes configuration necessary to generate both the host and the client. The generations of the Client and Host config files are optional, but are ncluded in this sample for your reference. (* indicates the file in this sample has been modified from those generated by WsdCodeGen.exe) * FileServiceSecureContract\CodeGen_All.config Config file for this sample * FileServiceSecureContract\CodeGen_Client.config Client-side only config file * FileServiceSecureContract\CodeGen_Host.config Server-side only config file Generated header and source files --------------------------------- These files are generated automatically by WsdCodeGen.exe, but are included in the sample for reference. You may rebuild these files by running WsdCodeGen. The following command was used to generate these header and source files: WsdCodeGen.exe /generatecode CodeGen_All.config /gbc (* indicates the file in this sample has been modified from those generated by WsdCodeGen.exe) FileServiceSecureContract\FileServiceSecure.idl Interface file FileServiceSecureContract\[FileServiceSecure.h] Header file built from FileService.idl * FileServiceSecureContract\FileServiceSecureProxy.cpp Proxy class implementations * FileServiceSecureContract\FileServiceSecureProxy.h Proxy class definitions * FileServiceSecureContract\FileServiceSecureStub.cpp Stub function implementations FileServiceSecureContract\FileServiceSecureTypes.cpp Type definitions * FileServiceSecureContract\FileServiceSecureTypes.h Type declarations and structure definitions PLATFORMS SUPORTED ================== Windows Developer Preview BUILDING THE SERVER AND CLIENT APPLICATIONS =========================================== To build, type "msbuild FileServiceSecure.sln" on the command line in this directory, or open the supplied solutions file and build the solution in Visual Studio. RUNNING THE SERVER AND CLIENT APPLICATIONS ========================================== The client and service applications can run on the same computer or a different one. Please note that secure channel configurations are required prior to using the client and service applications. Refer to the following link: http://msdn.microsoft.com/en-us/library/aa823078(VS.85).aspx To run the service application: FileServiceSecureService.exe [-CertAuth] [-HttpAuth] [-CertOrHttpAuth] [] -CertAuth (WSD_SECURITY_SSL_NEGOTIATE_CLIENT_CERT) Requires the client to authenticate itself using a certificate-based credential. - HttpAuth (WSD_SECURITY_REQUIRE_HTTP_CLIENT_AUTH) (WSD_SECURITY_HTTP_AUTH_SCHEME_NEGOTIATE) Requires the client to authenticate itself using HTTP Authentication with a Negotiate scheme credential. - CertOrHttpAuth (WSD_SECURITY_REQUIRE_CLIENT_CERT_OR_HTTP_CLIENT_AUTH) (WSD_SECURITY_HTTP_AUTH_SCHEME_NEGOTIATE) Requires the client to authenticate itself using one of the following: - A certificate-based credential - A Negotiate scheme credential using HTTP Authentication The service will first use a certificate credential if present. If such a credential is not present, then the service will use a Negotiate scheme credential. Required. The root directory in which the service application will begin reading files from when requested by the client. The physcial or logical address that the service is to be hosted on. A physical address is either an HTTP or HTTPS address. A logical address is a URI address that is neither HTTP nor HTTPS such as urn:uuid:665e95e0-a4a8-11df-981c-0800200c9a66. At most one of -CertAuth, -HttpAuth and -CertOrHttpAuth is allowed. While the argument parser of the service application accepts more than one of these flags, the WSDAPI function WSDCreateDeviceHost2 will return E_INVALIDARG if more than one such flag is present. If -CertAuth, -HttpAuth or -CertOrHttpAuth is specified, then the is required, and must be an HTTPS address. If is an HTTPS address, then a server certificate must be present in the Local Machine Certificate Store whose CN exactly matches that of the device address. To run the client type: FileServiceSecureClient.exe [-SslHash ] [ [-CertAuth NULL] | [-CertAuth ] [-HttpAuth ] -SslHash (WSD_SECURITY_SSL_SERVER_CERT_VALIDATION) (WSDAPI_SSL_CERT_IGNORE_INVALID_CN) (WSDAPI_SSL_CERT_IGNORE_UNKNOWN_CA) Verifies the SSL server certificate upon establishing an SSL connection that the server certificate is the certificate that the client is expecting, identified by the thumbprint of the certificate (the certificate hash). : The certificate hash algorithm that generated the thumbprint. It must be one either MD5 or SHA1 as the Windows Cryptography APIs that handles the certificate validation only accepts these two hashing algorithms. : The thumbprint of the certificate. -CertAuth NULL (WSD_SECURITY_SSL_CERT_FOR_CLIENT_AUTH) Sends a NULL client certificate to the service. If the -CertAuth flag is specified (either with a NULL or non-NULL certificate), and if the service accepts a certificate-based credential (i.e. the parameters -CertAuth or -CertOrHttpAuth in FileServiceSecureService.exe), this suppresses WSDAPI from selecting a usable certificate from the Current User Certificate Store. If the -CertAuth flag is not specified, then if the service requests for a certificate, WSDAPI will attempt to iterate the Current User Certificate Store to find a usable certificate (for client authentication purpose) and will send the first usable certificate it finds to the service. -CertAuth (WSD_SECURITY_SSL_CERT_FOR_CLIENT_AUTH) Sends the specified client certificate to the service. The certificate is identified by its thumbprint, and is chosen from the Current User Certificate Store. : The thumbprint of the certificate. -HttpAuth (WSD_SECURITY_USE_HTTP_CLIENT_AUTH) Sends the Windows user credentials of the currently logged on user through HTTP Authentication using the selected scheme to the service. : An integer value where 1 - Use Negotiation Scheme 2 - Use NTLM Scheme 3 - Use either Negotiation Scheme, and if failed, NTLM Scheme. All other values will be rejected by the API. Required. The directory in which the client application will store the files retrieved from the service. Required. The physcial or logical address of the service in which the client wishes to connect. A client that fails to provide any form of acceptable credentials to a service that requests for them will be treated as an unauthenticated user by the service, which terminates the connection. LAYOUT OF CLASSES AND FUNCTIONS =============================== Service classes and functions ----------------------------- CFileServiceSecureService Implements the IFileServiceSecure interface, which matches the FileServiceSecure port type. This class acts like a COM object (i.e., has AddRef, Release, and QueryInterface methods) and also exposes the GetFile and GetFileList methods, which can be accessed across the wire. The CFileServiceService has one CFileChangeNotificationThread object, which automatically launches a thread to monitor for file system changes. This thread will call back into the CFileServiceSecureService object to issue events to clients. When GetFile is called on the CFileServiceSecureService object, it creates a CSendAttachmentThread object, which automatically launches a thread to write to an attachment. The thread will copy the contents of a file into the attachment and, when it is finished, will close the attachment and destroy itself. Both the GetFile and GetFileList methods will attempt to retrieve the user token from the event object. The user token is a handle that contains the credentials being sent by the client. This user token can be passed into the function ImpersonateLoggedOnUser so that any file and directory operations can be executed under that user. CFileChangeNotificationThread Starts and makes a blocking request for file change notifications. When a notification is received, this class packages up the results and sends an event to all subscribed clients. CSendAttachmentThread Opens a file and writes all data in the file into the supplied attachment object. When the file has been completely consumed, the object will close the attachment and then delete itself. The proper way to use this object is to instantiate one, call Start, and then discard the pointer to the object. It will be responsible for its own cleanup. Client classes and functions ---------------------------- CFileServiceSecureEventNotify Notification class that receives callbacks when a host sends a FileChange event to this client. This object is passed in as a parameter when the client subscribes to the FileChange event. CGetFileAsyncCallback Notification class that is used when the client calls the GetFile method on the service. This async callback object is passed in as a parameter to the BeginGetFile proxy method, and when the operation completes, the CGetFileAsyncCallback::AsyncOperationComplete method is called. This object is then responsible for retrieving the results of the GetFile call and saving them to a local file.