VBoxCredProv.cpp revision d2236df2116a3cbe8b17c567f4a9c2281733a956
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// PARTICULAR PURPOSE.
//
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
//
// Modifications (c) 2009 Sun Microsystems, Inc.
//
#include <credentialprovider.h>
#include <VBox/VBoxGuestLib.h>
#include "VBoxCredProv.h"
#include "VBoxCredential.h"
#include "guid.h"
VBoxCredProv::VBoxCredProv(void):
m_cRef(1),
m_fGotCredentials(false)
{
if (RT_FAILURE(rc))
rc = VbglR3Init();
if (RT_FAILURE(rc))
if (l == 1) /* First instance? */
{
LogRel(("VBoxCredProv: DLL instance created: %ld\n", l));
}
else
{
Log(("VBoxCredProv: DLL instance %ld created.\n", l));
}
}
VBoxCredProv::~VBoxCredProv(void)
{
{
}
{
delete m_pPoller;
}
Log(("VBoxCredProv: DLL instance unloaded.\n"));
VbglR3Term();
DllRelease();
}
/* SetUsageScenario is the provider's cue that it's going to be asked for tiles
* in a subsequent call. This call happens after the user pressed CTRL+ALT+DEL
* and we need to handle the CPUS_LOGON event. */
{
/* Decide which scenarios to support here. Returning E_NOTIMPL simply tells the caller
* that we're not designed for that scenario. */
switch (m_cpUS)
{
case CPUS_LOGON:
case CPUS_UNLOCK_WORKSTATION:
{
m_pPoller = new VBoxCredPoller();
if (false == m_pPoller->Initialize(this))
Log(("VBoxCredProv::SetUsageScenario: Could not initialize credentials poller thread!\n"));
}
{
m_pCred = new VBoxCredential();
/* All stuff allocated? */
{
}
else
{
hr = E_OUTOFMEMORY;
Log(("VBoxCredProv::SetUsageScenario: Out of memory!\n"));
}
}
else
{
/* All set up already! */
}
/* If we did fail -> cleanup */
{
{
}
}
break;
case CPUS_CREDUI:
case CPUS_CHANGE_PASSWORD:
break;
default:
hr = E_INVALIDARG;
break;
}
Log(("VBoxCredProv::SetUsageScenario returned 0x%08x (CPUS: %d, Flags: %ld)\n", hr, cpus, dwFlags));
return hr;
}
// SetSerialization takes the kind of buffer that you would normally return to LogonUI for
// an authentication attempt. It's the opposite of ICredentialProviderCredential::GetSerialization.
// GetSerialization is implement by a credential and serializes that credential. Instead,
// SetSerialization takes the serialization and uses it to create a credential.
//
// SetSerialization is called for two main scenarios. The first scenario is in the credui case
// where it is prepopulating a tile with credentials that the user chose to store in the OS.
// The second situation is in a remote logon case where the remote client may wish to
// prepopulate a tile with a username, or in some cases, completely populate the tile and
// use it to logon without showing any UI.
//
STDMETHODIMP VBoxCredProv::SetSerialization(const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpcs)
{
return E_NOTIMPL;
}
/* Called by LogonUI to give you a callback. Providers often use the callback if they
* some event would cause them to need to change the set of tiles (visible UI elements)
* that they enumerated. */
{
Log(("VBoxCredProv::Advise\n"));
if (m_pCredProvEvents != NULL)
/* Save advice context for later use when binding to
certain ICredentialProviderEvents events. */
return S_OK;
}
/* Called by LogonUI when the ICredentialProviderEvents callback is no longer valid. */
{
Log(("VBoxCredProv::UnAdvise\n"));
if (m_pCredProvEvents != NULL)
{
}
return S_OK;
}
// Called by LogonUI to determine the number of fields in your tiles. This
// does mean that all your tiles must have the same number of fields.
// This number must include both visible and invisible fields. If you want a tile
// to have different fields from the other tiles you enumerate for a given usage
// using the field descriptors.
{
return S_OK;
}
// Gets the field descriptor for a particular field
{
/* Verify dwIndex is a valid field */
if ( dwIndex < SFI_NUM_FIELDS
&& ppcpfd)
{
}
else
{
hr = E_INVALIDARG;
}
Log(("VBoxCredProv::GetFieldDescriptorAt: hr=0x%08x, index=%ld, ppcpfd=%p\n",
return hr;
}
// Sets pdwCount to the number of tiles that we wish to show at this time.
// Sets pdwDefault to the index of the tile which should be used as the default.
//
// The default tile is the tile which will be shown in the zoomed view by default. If
// more than one provider specifies a default tile the behavior is the last used cred
// prov gets to specify the default tile to be displayed
//
// If *pbAutoLogonWithDefault is TRUE, LogonUI will immediately call GetSerialization
// on the credential you've specified as the default and will submit that credential
// for authentication without showing any further UI.
{
bool fGotCredentials = false;
if ( m_pPoller
&& m_pCred)
{
}
if (fGotCredentials)
{
*pdwDefault = 0; /* The credential we provide is *always* at index 0! */
}
else
{
*pdwCount = 0;
}
Log(("VBoxCredProv::GetCredentialCount: *pdwCount=%ld, *pdwDefault=%ld, *pbAutoLogonWithDefault=%s\n",
return S_OK;
}
// Returns the credential at the index specified by dwIndex. This function is called by logonUI to enumerate
// the tiles.
{
{
Log(("VBoxCredProv::GetCredentialAt: No credentials available.\n"));
return E_INVALIDARG;
}
/* Validate parameters (we only have one credential) */
if( dwIndex == 0
&& ppcpc)
{
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
/* Creates our provider. This happens *before* CTRL-ALT-DEL was pressed! */
{
if (pProvider)
{
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
/* Do a credential re-enumeration if we got the event to do so. */
const char *pszPw,
const char *pszDomain)
{
Log(("VBoxCredProv::OnCredentialsProvided\n"));
if (m_pCredProvEvents != NULL)
}