diff -r cd501b96611d -r ece3df019add authenticationservices/authenticationserver/source/client/authclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/authenticationservices/authenticationserver/source/client/authclient.cpp Tue Nov 24 09:06:03 2009 +0200 @@ -0,0 +1,774 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* authclient - exported authentication client session implementation +* +*/ + + +/** + @file +*/ + +#include +#include +#include "authclient_impl.h" +#include "authrepository.h" + +namespace AuthServer +{ + +/** + Helper function for Authenticate. This allocates + a buffer to hold the externalized authentication expression. + + @param aExpr Expression to externalize. + @return Descriptor containing externalized expression. + The memory must be freed by the caller. + */ +HBufC8* ExternalizeExpressionL(const CAuthExpression* aExpr) + { + AuthServer::TSizeStream ss; + RWriteStream ws(&ss); + aExpr->ExternalizeL(ws); + + TInt len = ss.Size(); + HBufC8* buf = HBufC8::NewLC(len); + TPtr8 bufDes(buf->Des()); + + RDesWriteStream dws(bufDes); + aExpr->ExternalizeL(dws); + dws.CommitL(); + + CleanupStack::Pop(buf); + return buf; + } +} + +using namespace AuthServer; + + +/** + * Connect to the server, attempt to start it if it is not yet running + * + * @return KErrNone if successful or an error code + */ +EXPORT_C TInt RAuthClient::Connect() + { + const TUidType serverUid(KNullUid, KNullUid, KAuthServerSecureId); + + TInt err = RScsClientBase::Connect(AuthServer::KAuthServerName, TVersion(1, 0, 0), + AuthServer::KAuthServerImg, serverUid ); + return err; + } + +EXPORT_C RAuthClient::RAuthClient() : + RScsClientBase(), iAsyncResponseDecoder(0) + { + + } + + + +/** + Authenticate the current device holder using a specified combination of + authentication methods. The ownership of the heap allocated CIdentity + object is passed to the caller. Requesting a user specific key + requires ReadUserData capability. + + @capability None/ReadUserData + + @param aExpression An authentication expression specifying which + combination of methods to use to authenticate the device holder. + + @param aTimeout If an authentication has previously been performed + within this period then a cached identity is returned. + + @param aClientSpecificKey If this value is true then the key returned + by this server will be unique to the calling client. This is achieved + by combining the identity protection key with the client process UID. + If this value is set to false then the call requires ReadUserData. + + @param aWithString If this value is true then the identity object returned + by the server will contain the identities string. If this value is set to + true then the call requires ReadUserData. + + @return CIdentity object corresponding to the authenticated device + holder. It is possible for the identity to be 'unknown'. + + @leave KErrServerTerminated, if the server no longer present + @leave KErrServerBusy, if the request cannot be handled at this time. + @leave KErrNoMemory, if there is insufficient memory available. + @leave KErrPermissionDenied, if the caller has insufficient capabilities. + @leave ... One of the AuthServer error codes defined in + auth_srv_errs.h or one of the system-wide error codes. + **/ +EXPORT_C CIdentity* RAuthClient::AuthenticateL( + const CAuthExpression& aExpression, + TTimeIntervalSeconds aTimeout, + TBool aClientSpecificKey, + TBool aWithString) + { + TUid clientSid = {0}; + + CIdentity* identity = AuthenticateL(aExpression, aTimeout, + aClientSpecificKey, clientSid, + aWithString, KNullDesC()); + + return identity; + + } + + + +/** + Authenticate the current device holder using a specified combination of + authentication methods. The ownership of the heap allocated CIdentity + object is passed to the caller. Requesting a user specific key + requires ReadUserData capability. + + @capability None/ReadUserData + + @param aExpression An authentication expression specifying which + combination of methods to use to authenticate the device holder. + + @param aTimeout If an authentication has previously been performed + within this period then a cached identity is returned. + + @param aClientSpecificKey If this value is true then the key returned + by this server will be unique to the calling client. This is achieved + by combining the identity protection key with the client process UID. + If this value is set to false then the call requires ReadUserData. + + @param aWithString If this value is true then the identity object returned + by the server will contain the identities string. If this value is set to + true then the call requires ReadUserData. + + @param aIdentityResult The returned identity will be placed in this + parameter when the asynchronous request completes. + + @param aStatus The request status for this asynchronous request. + + @leave KErrServerTerminated, if the server no longer present + @leave KErrServerBusy, if the request cannot be handled at this time. + @leave KErrNoMemory, if there is insufficient memory available. + @leave KErrPermissionDenied, if the caller has insufficient capabilities. + @leave ... One of the AuthServer error codes defined in + auth_srv_errs.h or one of the system-wide error codes. + + **/ +EXPORT_C void RAuthClient::AuthenticateL( + const CAuthExpression& aExpression, + TTimeIntervalSeconds aTimeout, + TBool aClientSpecificKey, + TBool aWithString, + CIdentity*& aIdentityResult, + TRequestStatus& aStatus) + { + TUid clientSid = {0}; + AuthenticateL(aExpression, aTimeout, aClientSpecificKey, + clientSid, aWithString, KNullDesC(), + aIdentityResult, aStatus); + + } + + +/** + Authenticate the current device holder using a specified combination of + authentication methods. The ownership of the heap allocated CIdentity + object is passed to the caller. Requesting a user specific key requires + ReadUserData capability. + + @capability None/ReadUserData + + @param aAuthStrength Descriptor specifying the authentication strength, + which inturn maps to a combination of methods to be used to authenticate + the device holder. + + @param aTimeout If an authentication has previously been performed + within this period then a cached identity is returned. + + @param aClientSpecificKey If this value is true then the key returned + by this server will be unique to the calling client. This is achieved + by combining the identity protection key with the client process UID. + If this value is set to false then the call requires ReadUserData. + + @param aClientSid Sid of the client application from where the authentication + request originated and is used to generate protection key.This value is ignored + when aClientSpecificKey is set to false. If aClientSid is non-zero and is not + the calling application's sid, then the call requires ReadUserData. + + @param aWithString If this value is true then the identity object returned + by the server will contain the identities string. If this value is set to + true then the call requires ReadUserData. + + @param aClientMessage A displayable text string parameter for authentication + requests.It shall be passed to plug-ins to display to the users. + + @return the CIdentity object corresponding to the authenticated device + holder. It is possible for the identity to be 'unknown'. + + @leave KErrServerTerminated, if the server no longer present + @leave KErrServerBusy, if the request cannot be handled at this time. + @leave KErrNoMemory, if there is insufficient memory available. + @leave KErrPermissionDenied, if the caller has insufficient capabilities. + @leave ... One of the AuthServer error codes defined in + auth_srv_errs.h or one of the system-wide error codes. + + **/ + +EXPORT_C CIdentity* RAuthClient::AuthenticateL( + const CAuthExpression& aAuthExpression, + TTimeIntervalSeconds aTimeout, + TBool aClientSpecificKey, + TUid aClientSid, + TBool aWithString, + const TDesC& aClientMessage) + { + + //Create a flat buffer + CBufFlat* flatBuffer = CBufFlat::NewL(KDefaultBufferSize); + CleanupStack::PushL(flatBuffer); + + //Initialize the CAuthParams object + CAuthParams* params = CAuthParams::NewL(aTimeout, + aClientSpecificKey, + aClientSid, + aWithString, + aClientMessage); + CleanupStack::PushL(params); + //Externalize params + RBufWriteStream stream(*flatBuffer); + CleanupClosePushL(stream); + params->ExternalizeL(stream); + CleanupStack::PopAndDestroy(2, params); + + HBufC8* paramsBuffer = HBufC8::NewLC(flatBuffer->Size()); + TPtr8 paramsPtr(paramsBuffer->Des()); + flatBuffer->Read(0, paramsPtr, flatBuffer->Size()); + + //Externalize the expression + HBufC8* exprBuf = ExternalizeExpressionL(&aAuthExpression); + CleanupStack::PushL(exprBuf); + + // allocate buffer for identity result + HBufC8* identityResultbuf = HBufC8::NewLC(KDefaultBufferSize); + TPtr8 bufDes(identityResultbuf->Des()); + + TIpcArgs args(exprBuf, ¶msPtr, &bufDes); + User::LeaveIfError(CallSessionFunction(EAuthenticate, args)); + + + + RDesReadStream readStream(*identityResultbuf); + CIdentity* identity = CIdentity::InternalizeL(readStream); + + CleanupStack::PopAndDestroy(4,flatBuffer);//identityResultbuf, exprBuf, + //paramsBuffer, flatBuffer + return identity; + } + +/** + Authenticate the current device holder using a specified combination of + authentication methods. The ownership of the heap allocated CIdentity + object is passed to the caller. Requesting a user specific key requires + ReadUserData capability. + + @capability None/ReadUserData + + @param aAuthStrength Descriptor specifying the authentication strength, + which inturn maps to a combination of methods to be used to authenticate the device holder. + + @param aTimeout If an authentication has previously been performed + within this period then a cached identity is returned. + + @param aClientSpecificKey If this value is true then the key returned + by this server will be unique to the calling client. This is achieved + by combining the identity protection key with the client process UID. + If this value is set to false then the call requires ReadUserData. + + @param aClientSid Sid of the client application from where the authentication + request originated and is used to generate protection key.This value is ignored + when aClientSpecificKey is set to false. If aClientSid is non-zero and is not + the calling application's sid, then the call requires ReadUserData. + + @param aWithString If this value is true then the identity object returned + by the server will contain the identities string. If this value is set to + true then the call requires ReadUserData. + + @param aClientMessage A displayable text string parameter for authentication + requests.It shall be passed to plug-ins to display to the users. + + @param aIdentityResult The returned identity will be placed in this + parameter when the asynchronous request completes. + + @param aStatus The request status for this asynchronous request. + + @leave KErrServerTerminated, if the server no longer present + @leave KErrServerBusy, if the request cannot be handled at this time. + @leave KErrNoMemory, if there is insufficient memory available. + @leave KErrPermissionDenied, if the caller has insufficient capabilities. + @leave ... One of the AuthServer error codes defined in + auth_srv_errs.h or one of the system-wide error codes. + + **/ + +EXPORT_C void RAuthClient::AuthenticateL( + const CAuthExpression& aExpression, + TTimeIntervalSeconds aTimeout, + TBool aClientSpecificKey, + TUid aClientSid, + TBool aWithString, + const TDesC& aClientMessage, + CIdentity*& aIdentityResult, + TRequestStatus& aStatus + ) + { + + CheckAsyncDecoderL(); + iAsyncResponseDecoder->AuthenticateL(aExpression, + aTimeout, + aClientSpecificKey, + aClientSid, + aWithString, + aClientMessage, + aIdentityResult, + aStatus); + + + } + +/** + * creates the async decoder if it's not already been created. + */ +void RAuthClient::CheckAsyncDecoderL() + { + if (iAsyncResponseDecoder == 0) + { + iAsyncResponseDecoder = new (ELeave) CAsyncResponseDecoder(*this); + } + } + + + + +/** + * Retrieves all plugin descriptions. + * + * @param aPluginList will be filled with the full list of plugins available on the device. + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + **/ +EXPORT_C void RAuthClient::PluginsL(RPluginDescriptions& aPluginList) + { + HBufC8* buffer = SendReceiveBufferLC(EPlugins); + // create a stream based on the buffer + RDesReadStream stream(*buffer); + CleanupClosePushL(stream); + + // reassemble the array from the stream + InternalizePointerArrayL(aPluginList, stream); + + CleanupStack::PopAndDestroy(2, buffer);// buffer, stream + } + +/** + * @param aPluginList the list of active plugins available on the device. + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + **/ +EXPORT_C void RAuthClient::ActivePluginsL(RPluginDescriptions& aPluginList) + { + HBufC8* buffer = SendReceiveBufferLC(EActivePlugins); + // create a stream based on the buffer + RDesReadStream stream(*buffer); + CleanupClosePushL(stream); + + // reassemble the array from the stream + InternalizePointerArrayL(aPluginList, stream); + + CleanupStack::PopAndDestroy(2, buffer);// buffer, stream + } + +/** + * + * Retrieves plugin descriptions for plugins matching the specified + * type. + * + * @param aType the plugin type for which the method should return + * the list of plugins. + * + * @param aPluginList the list of plugins with the specified type available + * on the device. + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + * + * @see TAuthPluginType + **/ +EXPORT_C void RAuthClient::PluginsOfTypeL( + TAuthPluginType aType, + RPluginDescriptions& aPluginList) + { + TIpcArgs args(TIpcArgs::ENothing, aType); + HBufC8* buffer = SendReceiveBufferLC(EPluginsByType, args); + // create a stream based on the buffer + RDesReadStream stream(*buffer); + CleanupClosePushL(stream); + + // reassemble the array from the stream + InternalizePointerArrayL(aPluginList, stream); + + CleanupStack::PopAndDestroy(2, buffer);// buffer, stream + } + +/** + * Retrieves plugin descriptions for plugins matching the specified + * training status. + * + * @param aStatus the training status for which the method should + * return the list of plugins. + * + * @param aPluginList the list of plugins with the specified type available + * on the device. + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + * + * @see TAuthTrainingStatus + **/ +EXPORT_C void RAuthClient::PluginsWithTrainingStatusL( + TAuthTrainingStatus aStatus, + RPluginDescriptions& aPluginList) + { + TIpcArgs args(TIpcArgs::ENothing, aStatus); + HBufC8* buffer = SendReceiveBufferLC(EPluginsByTraining, args); + // create a stream based on the buffer + RDesReadStream stream(*buffer); + CleanupClosePushL(stream); + + // reassemble the array from the stream + InternalizePointerArrayL(aPluginList, stream); + + CleanupStack::PopAndDestroy(2, buffer);// buffer, stream + } + +/** + * @param aIdList populated with the list of identities known by the + * phone. + * + * @capability ReadDeviceData + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + * @leave KErrPermissionDenied, if the caller has insufficient capabilities. + **/ +EXPORT_C void RAuthClient::IdentitiesL(RIdentityIdArray& aIdList) + { + HBufC8* buffer = SendReceiveBufferLC(EIdentities); + // create a stream based on the buffer + RDesReadStream stream(*buffer); + CleanupClosePushL(stream); + + // reassemble the array from the stream + InternalizeArrayL(aIdList, stream); + + CleanupStack::PopAndDestroy(2, buffer);// buffer, stream + } + +/** + * @param aIdList populated with the list of identities and their strings + * known by the phone. + * + * @capability ReadDeviceData + * @capability ReadUserData + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + * @leave KErrPermissionDenied, if the caller has insufficient capabilities. + **/ +EXPORT_C void RAuthClient::IdentitiesWithStringL(RIdAndStringArray& aIdList) + { + HBufC8* buffer = SendReceiveBufferLC(EIdentitiesWithString); + // create a stream based on the buffer + RDesReadStream stream(*buffer); + CleanupClosePushL(stream); + + // reassemble the array from the stream + InternalizePointerArrayL(aIdList, stream); + + CleanupStack::PopAndDestroy(2, buffer);// buffer, stream + } + +/** + * @param aId the Id number of the identity for which to set the + * string. + * + * @param aId the identity who's string to set. + * @param aString the string to use + * + * @capability WriteUserData + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + * @leave KErrPermissionDenied, if the caller has insufficient capabilities. + * @leave KErrAuthServIdentityNotFound, if the id does not exist. + **/ +EXPORT_C void RAuthClient::SetIdentityStringL(TIdentityId aId, + const TDesC& aString) + { + TIpcArgs args(aId, &aString); + + User::LeaveIfError(CallSessionFunction(ESetIdentityString, args)); + } + +/** + * Deauthenticates the current user. This means that clients requesting an + * authentication will always cause a plug-in to be called regardless of + * any timeout value specified. + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + * + **/ +EXPORT_C void RAuthClient::DeauthenticateL() + { + User::LeaveIfError(CallSessionFunction(EDeauthenticate)); + } + +/** + * @param aId the Id number of the identity for which to return the + * string. + * + * @return the string associated with the specified identity. + * + * @capability ReadUserData + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + * @leave KErrPermissionDenied, if the caller has insufficient capabilities. + * @leave KErrAuthServIdentityNotFound, if the id does not exist. + **/ +EXPORT_C HBufC* RAuthClient::IdentityStringL(TIdentityId aId) + { + HBufC* buffer = HBufC::NewLC(KDefaultBufferSize); + TPtr ptr = buffer->Des(); + User::LeaveIfError(CallSessionFunction(EIdentityString, TIpcArgs(&ptr, aId))); + CleanupStack::Pop(buffer); + return buffer; + } + + +/** + */ +HBufC8* RAuthClient::SendReceiveBufferLC(TInt aMessage) + { + HBufC8* output = HBufC8::NewLC(KDefaultBufferSize); + + TPtr8 pOutput(output->Des()); + + TInt result = CallSessionFunction(aMessage, TIpcArgs(&pOutput)); + + if (result == KErrOverflow) + { + TInt sizeNeeded = 0; + TPckg sizeNeededPackage(sizeNeeded); + sizeNeededPackage.Copy(*output); + + // Re-allocate buffer after reclaiming memory + CleanupStack::PopAndDestroy(output); + output = HBufC8::NewLC(sizeNeeded); + + TPtr8 pResizedOutput(output->Des()); + + result=CallSessionFunction(aMessage, TIpcArgs(&pResizedOutput)); + } + User::LeaveIfError(result); + return output; + } + +/** + * aArgs[0] is set to the buffer to be sent/received + */ +HBufC8* RAuthClient::SendReceiveBufferLC( + TInt aMessage, + TIpcArgs& aArgs) + { + HBufC8* output = HBufC8::NewLC(KDefaultBufferSize); + + TPtr8 pOutput(output->Des()); + + aArgs.Set(0, &pOutput); + + TInt result = CallSessionFunction(aMessage, aArgs); + + if (result == KErrOverflow) + { + TInt sizeNeeded; + TPckg sizeNeededPackage(sizeNeeded); + sizeNeededPackage.Copy(*output); + + // Re-allocate buffer + CleanupStack::PopAndDestroy(output); + output = HBufC8::NewLC(sizeNeeded); + + TPtr8 pResizedOutput(output->Des()); + aArgs.Set(0, &pResizedOutput); + result=CallSessionFunction(aMessage, aArgs); + } + User::LeaveIfError(result); + return output; + } + +/** + * @param aPluginType the type of plugin for which to return the preferred + * plugin id + * + * @return the id of the preferred plugin for the specified type + * + * @leave KErrServerTerminated, if the server no longer present + * @leave KErrServerBusy, if the request cannot be handled at this time. + * @leave KErrNoMemory, if there is insufficient memory available. + * @leave KErrPermissionDenied, if the caller has insufficient capabilities. + **/ +EXPORT_C TPluginId RAuthClient::PreferredTypePluginL(TAuthPluginType aPluginType) + { + TPluginId id = KUnknownPluginId; + TPckg idPckg(id); + + User::LeaveIfError(CallSessionFunction(EGetAuthPreferences, TIpcArgs(aPluginType, &idPckg))); + + return id; + } + +/** + * Cancel any operation in progress. + * + * @return KErrNone, if the send operation is successful or no operation + * is in effect. + * @return KErrServerTerminated, if the server no longer present + * @return KErrServerBusy, if the request cannot be handled at this time. + * @return KErrNoMemory, if there is insufficient memory available. + **/ +EXPORT_C TUint RAuthClient::Cancel() + { + CallSessionFunction(ECancel); + if(iAsyncResponseDecoder) + { + iAsyncResponseDecoder->Cancel(); + } + + return KErrNone; + } + + +EXPORT_C void RAuthClient::Close() + { + delete iAsyncResponseDecoder; + iAsyncResponseDecoder = 0; + + RScsClientBase::Close(); + } + +/** + Lists the authentication aliases. + + @return An array of authentication strength aliases. + + @leave KErrServerTerminated, if the server no longer present + @leave KErrServerBusy, if the request cannot be handled at this time. + @leave KErrNoMemory, if there is insufficient memory available. + @leave KErrPermissionDenied, if the caller has insufficient capabilities. + **/ + +EXPORT_C void RAuthClient::ListAuthAliasesL(RPointerArray& aAuthAliasesList) + { + HBufC8* buffer = SendReceiveBufferLC(EListAuthAliases); + + // create a stream based on the buffer + RDesReadStream stream(*buffer); + CleanupClosePushL(stream); + + // reassemble the array from the stream + TInt strengthAliasCount = stream.ReadInt32L(); + for(TInt i = 0; i < strengthAliasCount; ++i) + { + HBufC* strengthAlias = HBufC::NewLC(stream, KMaxTInt); + aAuthAliasesList.AppendL(strengthAlias); + CleanupStack::Pop(strengthAlias); + } + + CleanupStack::PopAndDestroy(2, buffer);// buffer, stream + } + +/** + Returns a CAuthExpression object from a free form expression + which can be a combination of plugin Ids, plugin types and alias names. + This can be used for calling the authentication APIs. + + + @capability None + + @param aAuthString Descriptor specifying a free form expression + which can be a combination of plugin Ids, plugin types and alias names. + + + @return the CAuthExpression object which can be used to call the + authentication APIs. + + @leave KErrServerTerminated, if the server no longer present + @leave KErrServerBusy, if the request cannot be handled at this time. + @leave KErrNoMemory, if there is insufficient memory available. + @leave KErrPermissionDenied, if the caller has insufficient capabilities. + @leave ... One of the AuthServer error codes defined in + auth_srv_errs.h or one of the system-wide error codes. + + **/ + +EXPORT_C CAuthExpression* RAuthClient::CreateAuthExpressionL(const TDesC& aAuthString) const + { + CAuthExpression* authExpr(0); + + if(aAuthString == KNullDesC) + { + authExpr = AuthExpr(); + return authExpr; + } + HBufC* buffer = HBufC::NewLC(KDefaultBufferSize); + TPtr bufDes(buffer->Des()); + + // get the string in combination of plugin ID and plugin type. + User::LeaveIfError(CallSessionFunction(EResolveExpression, TIpcArgs(&bufDes, &aAuthString))); + + // create an auth expression from alias string. + authExpr = CAuthExpressionImpl::CreateAuthExprObjectL(*buffer); + CleanupStack::PopAndDestroy(buffer); + + return authExpr; + } + + + +