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]
        <files-directory>
        [<device-address>]
    
    -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.
    
    <files-directory>
        Required.  The root directory in which the service application will
        begin reading files from when requested by the client.
    
    <device-address>
        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
    <device-address> is required, and must be an HTTPS address.
    
    If <device-address> 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 <Algorithm> <Thumbprint>]
        [       [-CertAuth NULL]
            |   [-CertAuth <Thumbprint> ]
        [-HttpAuth <Scheme>]
        <files-directory>
        <device-address>
    
    -SslHash <Algorithm> <Thumbprint>
        (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).
        
        <Algorithm>: 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.
        
        <Thumbprint>: 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 <Thumbprint>
        (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.
        
        <Certificate Hash>: The thumbprint of the certificate.
    
    -HttpAuth <Scheme>
        (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.
        
        <Scheme>: 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.
    
    <files-directory>
        Required.  The directory in which the client application will
        store the files retrieved from the service.
    
    <device-address>
        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.
