/*+----------------------------------------------------------------------- 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. Copyright (C) 1992 - 2000. Microsoft Corporation. All rights reserved. File: stubs.c Contents: user-mode stubs for security API ------------------------------------------------------------------------*/ #define _NO_KSECDD_IMPORT_ #include "sampssp.h" SecurityFunctionTableW SecTableW = {SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION, EnumerateSecurityPackagesW, NULL, AcquireCredentialsHandleW, FreeCredentialsHandle, NULL, // LogonUser InitializeSecurityContextW, AcceptSecurityContext, CompleteAuthToken, DeleteSecurityContext, ApplyControlToken, QueryContextAttributesW, ImpersonateSecurityContext, RevertSecurityContext, MakeSignature, VerifySignature, FreeContextBuffer, QuerySecurityPackageInfoW }; PSEC_CONTEXT ContextList; PCREDENTIAL CredentialList; ULONG NextId; TimeStamp Forever = {0x7fffffff,0xfffffff}; TimeStamp Never = {0,0}; //+------------------------------------------------------------------------- // // Function: LocateContext // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- PSEC_CONTEXT LocateContext(ULONG ContextId) { PSEC_CONTEXT TestContext; EnterCriticalSection(&DllCritSect); TestContext = ContextList; while (TestContext != NULL) { if (TestContext->ContextId == ContextId) { break; } TestContext = TestContext->Next; } LeaveCriticalSection(&DllCritSect); return(TestContext); } //+------------------------------------------------------------------------- // // Function: DeleteContext // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- BOOLEAN DeleteContext(ULONG ContextId) { PSEC_CONTEXT TestContext, LastContext; EnterCriticalSection(&DllCritSect); TestContext = ContextList; LastContext = NULL; while (TestContext != NULL) { if (TestContext->ContextId == ContextId) { break; } LastContext = TestContext; TestContext = TestContext->Next; } if (TestContext != NULL) { if (LastContext != NULL) { LastContext->Next = TestContext->Next; } else { assert(ContextList == TestContext); ContextList = TestContext->Next; } LocalFree(TestContext); } LeaveCriticalSection(&DllCritSect); return( TestContext == NULL ? FALSE : TRUE ); } //+------------------------------------------------------------------------- // // Function: AddContext // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- VOID AddContext(PSEC_CONTEXT Context) { EnterCriticalSection(&DllCritSect); Context->Next = ContextList; ContextList = Context; LeaveCriticalSection(&DllCritSect); } //+------------------------------------------------------------------------- // // Function: InitSecurityInterfaceW // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- PCREDENTIAL LocateCredential(ULONG CredentialId) { PCREDENTIAL TestCredential; EnterCriticalSection(&DllCritSect); TestCredential = CredentialList; while (TestCredential != NULL) { if (TestCredential->CredentialId == CredentialId) { break; } TestCredential = TestCredential->Next; } LeaveCriticalSection(&DllCritSect); return(TestCredential); } BOOLEAN DeleteCredential(ULONG CredentialId) { PCREDENTIAL TestCredential, LastCredential; EnterCriticalSection(&DllCritSect); TestCredential = CredentialList; LastCredential = NULL; while (TestCredential != NULL) { if (TestCredential->CredentialId == CredentialId) { break; } LastCredential = TestCredential; TestCredential = TestCredential->Next; } if (TestCredential != NULL) { if (LastCredential != NULL) { LastCredential->Next = TestCredential->Next; } else { assert(CredentialList == TestCredential); CredentialList = TestCredential->Next; } LocalFree(TestCredential); } LeaveCriticalSection(&DllCritSect); return( TestCredential == NULL ? FALSE : TRUE ); } VOID AddCredential(PCREDENTIAL Credential) { EnterCriticalSection(&DllCritSect); Credential->Next = CredentialList; CredentialList = Credential; LeaveCriticalSection(&DllCritSect); } ULONG GetNewId() { ULONG NewId; EnterCriticalSection(&DllCritSect); NewId = NextId; NextId ++; LeaveCriticalSection(&DllCritSect); return(NewId); } PSecBuffer LocateBuffer(PSecBufferDesc Buffer, ULONG MinimumSize) { ULONG Index; if (Buffer == NULL) { return(NULL); } for (Index = 0; Index < Buffer->cBuffers ; Index++) { if (((Buffer->pBuffers[Index].BufferType) & ~SECBUFFER_ATTRMASK) == SECBUFFER_TOKEN) { // // Do size checking // if (Buffer->pBuffers[Index].cbBuffer < MinimumSize) { return(NULL); } return(&Buffer->pBuffers[Index]); } } return(NULL); } PSecBuffer LocateSecBuffer(PSecBufferDesc Buffer) { return(LocateBuffer(Buffer, sizeof(MESSAGE))); } PSecBuffer LocateSigBuffer(PSecBufferDesc Buffer) { return(LocateBuffer(Buffer, sizeof(SIGNATURE))); } //+------------------------------------------------------------------------- // // Function: InitSecurityInterfaceW // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- PSecurityFunctionTableW SEC_ENTRY InitSecurityInterfaceW(VOID) { InitializeCriticalSection( &DllCritSect ); return(&SecTableW); } //+------------------------------------------------------------------------- // // Function: AcquireCredentialsHandleW // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW( LPWSTR pszPrincipal, // Name of principal LPWSTR pszPackageName, // Name of package unsigned long fCredentialUse, // Flags indicating use void SEC_FAR * pvLogonId, // Pointer to logon ID void SEC_FAR * pAuthData, // Package specific data SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func void SEC_FAR * pvGetKeyArgument, // Value to pass to GetKey() PCredHandle phCredential, // (out) Cred Handle PTimeStamp ptsExpiry // (out) Lifetime (optional) ) { PCREDENTIAL NewCredential = NULL; if ((fCredentialUse & (SECPKG_CRED_BOTH)) == 0) { return(SEC_E_UNKNOWN_CREDENTIALS); } NewCredential = (PCREDENTIAL) LocalAlloc(0,sizeof(CREDENTIAL)); if (NewCredential == NULL) { return(SEC_E_INSUFFICIENT_MEMORY); } NewCredential->CredentialId = GetNewId(); NewCredential->Use = fCredentialUse; NewCredential->AuthData = (ULONG *)pAuthData; phCredential->dwUpper = NewCredential->CredentialId; *ptsExpiry = Forever; AddCredential(NewCredential); return(SEC_E_OK); } //+------------------------------------------------------------------------- // // Function: FreeCredentialsHandle // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY FreeCredentialsHandle( PCredHandle phCredential // Handle to free ) { if (DeleteCredential(phCredential->dwUpper)) { return(SEC_E_OK); } else { return(SEC_E_UNKNOWN_CREDENTIALS); } } //+------------------------------------------------------------------------- // // Function: InitializeSecurityContextW // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY InitializeSecurityContextW( PCredHandle phCredential, // Cred to base context PCtxtHandle phContext, // Existing context (OPT) LPWSTR pszTargetName, // Name of target unsigned long fContextReq, // Context Requirements unsigned long Reserved1, // Reserved, MBZ unsigned long TargetDataRep, // Data rep of target PSecBufferDesc pInput, // Input Buffers unsigned long Reserved2, // Reserved, MBZ PCtxtHandle phNewContext, // (out) New Context handle PSecBufferDesc pOutput, // (inout) Output Buffers unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs PTimeStamp ptsExpiry // (out) Life span (OPT) ) { PCREDENTIAL Credential = NULL; PSEC_CONTEXT Context = NULL; PMESSAGE Message = NULL; PSecBuffer OutputBuffer; PSecBuffer InputBuffer; MESSAGE SampleMessage; if (fContextReq & ISC_REQ_ALLOCATE_MEMORY) { return(SEC_E_INSUFFICIENT_MEMORY); } OutputBuffer = LocateSecBuffer(pOutput); if (OutputBuffer == NULL) { return(SEC_E_INVALID_TOKEN); } if (phContext == NULL) { Credential = LocateCredential(phCredential->dwUpper); if (Credential == NULL) { return(SEC_E_UNKNOWN_CREDENTIALS); } if ((Credential->Use & SECPKG_CRED_OUTBOUND) == 0) { return(SEC_E_UNKNOWN_CREDENTIALS); } } // // If the context is NULL, create a new one. // if (phContext == NULL) { Context = (PSEC_CONTEXT) LocalAlloc(0,sizeof(SEC_CONTEXT)); if (Context == NULL) { return(SEC_E_INSUFFICIENT_MEMORY); } Context->ContextId = GetNewId(); phNewContext->dwUpper = Context->ContextId; Context->CredentialId = phCredential->dwUpper; Context->State = FirstInit; Context->Nonce = 0; Context->ContextFlags = fContextReq; *pfContextAttr = fContextReq; *ptsExpiry = Forever; // // Build an output token. // Message = (PMESSAGE) OutputBuffer->pvBuffer; Message->MessageType = Negotiate; memset(Message->Buffer,'x',MESSAGE_SIZE); OutputBuffer->cbBuffer = sizeof(MESSAGE); AddContext(Context); return(SEC_I_CONTINUE_NEEDED); } else { // // This is the second call. Lookup the old context. // Context = LocateContext(phContext->dwUpper); if (Context == NULL) { return(SEC_E_INVALID_HANDLE); } if ((Context->State != FirstInit) && (Context->State != SecondInit)) { return(SEC_E_INVALID_HANDLE); } // // Build the new output message // if (Context->State == FirstInit) { // // Check that the input message is what we expected. // InputBuffer = LocateSecBuffer(pInput); if (InputBuffer == NULL) { return(SEC_E_INVALID_TOKEN); } Message = (PMESSAGE) InputBuffer->pvBuffer; SampleMessage.MessageType = Challenge; memset(SampleMessage.Buffer, 'y', MESSAGE_SIZE); if (memcmp(&SampleMessage,Message,MESSAGE_SIZE) != 0) { return(SEC_E_INVALID_TOKEN); } Message = (PMESSAGE) OutputBuffer->pvBuffer; Message->MessageType = ChallengeResponse; memset(Message->Buffer,'z',MESSAGE_SIZE); } else { Message = (PMESSAGE) OutputBuffer->pvBuffer; Message->MessageType = ReAuthenticate; memset(Message->Buffer,'q',MESSAGE_SIZE); } OutputBuffer->cbBuffer = sizeof(MESSAGE); Context->State = SecondInit; return(SEC_E_OK); } } //+------------------------------------------- ------------------------------ // // Function: AcceptSecurityContext // // Synopsis: Allows a remotely initiated security context between the // application and a remote peer to be established. To complete // the establishment of context one or more reply tokens may be // required from remote peer. // This function is the server counterpart to the // InitializeSecurityContext API. The ContextAttributes is a bit // mask representing various context level functions such as // delegation, mutual authentication, confidentiality, replay // detection and sequence detection. This API is used by the // server side. When a request comes in, the server uses the // ContextReqFlags parameter to specify what it requires of the // session. In this fashion, a server can specify that clients // must be capable of using a confidential or integrity checked // session, and fail clients that can't meet that demand. // Alternatively, a server can require nothing, and whatever the // client can provide or requires is returned in the // pfContextAttributes parameter. For a package that supports 3 // leg mutual authentication, the calling sequence would be: // Client provides a token, server calls Accept the first time, // generating a reply token. The client uses this in a second // call to InitializeSecurityContext, and generates a final token. // This token is then used in the final call to Accept to complete // the session. Another example would be the LAN Manager/NT // authentication style. The client connects to negotiate a // protocol. The server calls Accept to set up a context and // generate a challenge to the client. The client calls // InitializeSecurityContext and creates a response. The server // then calls Accept the final time to allow the package to verify // the response is appropriate for the challenge. // // Effects: // // // Arguments: [phCredential] - Handle to the credentials to be used to // create the context. // // [phContext] - Handle to the partially formed context, if // this is a second call (see above) or NULL if this is the first call. // // [pInput] - Pointer to the input token. In the first call // this token can either be NULL or may contain // security package specific information. // // [fContextReq] - Requirements of the context, package specific. See // the ASC_REQ_xxx defines in SSPI.H. // // [TargetDataRep] - Long indicating the data representation (byte // ordering, etc) on the target. The constant // SECURITY_NATIVE_DREP may be supplied by the // transport indicating that the native format // is in use. // // [phNewContext] - New context handle. If this is a second // call, this can be same as OldContextHandle. // // [pOutput] - Buffer to receive the output token. // // [pfContextAttr] - Attributes of the context established. See // the ASC_RET_xxx defines in SSPI.H // // [ptsExpiry] - Expiration time of the context. // // Requires: // // Returns: STATUS_SUCCESS - Message handled // SEC_I_CALLBACK_NEEDED - Caller should call again later // SEC_E_NO_SPM - Security Support Provider is not running // SEC_E_INVALID_TOKEN - Token improperly formatted // SEC_E_INVALID_HANDLE - Credential/Context Handle is invalid // SEC_E_BUFFER_TOO_SMALL- Buffer for output token isn't big enough // SEC_E_LOGON_DENIED - User is no allowed to logon to this server // SEC_E_INSUFFICIENT_MEMORY - Not enough memory // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY AcceptSecurityContext( PCredHandle phCredential, // Cred to base context PCtxtHandle phContext, // Existing context (OPT) PSecBufferDesc pInput, // Input buffer unsigned long fContextReq, // Context Requirements unsigned long TargetDataRep, // Target Data Rep PCtxtHandle phNewContext, // (out) New context handle PSecBufferDesc pOutput, // (inout) Output buffers unsigned long SEC_FAR * pfContextAttr, // (out) Context attributes PTimeStamp ptsExpiry // (out) Life span (OPT) ) { PCREDENTIAL Credential = NULL; PSEC_CONTEXT Context = NULL; PMESSAGE Message = NULL; PSecBuffer OutputBuffer; PSecBuffer InputBuffer; MESSAGE SampleMessage; if (fContextReq & ISC_REQ_ALLOCATE_MEMORY) { return(SEC_E_INSUFFICIENT_MEMORY); } InputBuffer = LocateSecBuffer(pInput); if (InputBuffer == NULL) { return(SEC_E_INVALID_TOKEN); } if (phContext == NULL) { Credential = LocateCredential(phCredential->dwUpper); if (Credential == NULL) { return(SEC_E_UNKNOWN_CREDENTIALS); } if ((Credential->Use & SECPKG_CRED_INBOUND) == 0) { return(SEC_E_UNKNOWN_CREDENTIALS); } } // // If the context is NULL, create a new one. // if (phContext == NULL) { // // Make sure the output buffer exists. // OutputBuffer = LocateSecBuffer(pOutput); if (OutputBuffer == NULL) { return(SEC_E_INVALID_TOKEN); } // // Check that the input message is what we expected. // Message = (PMESSAGE) InputBuffer->pvBuffer; SampleMessage.MessageType = Negotiate; memset(SampleMessage.Buffer, 'x', MESSAGE_SIZE); if (memcmp(&SampleMessage,Message,MESSAGE_SIZE) != 0) { return(SEC_E_INVALID_TOKEN); } // // Build a new context. // Context = (PSEC_CONTEXT) LocalAlloc(0,sizeof(SEC_CONTEXT)); if (Context == NULL) { return(SEC_E_INSUFFICIENT_MEMORY); } Context->ContextId = GetNewId(); phNewContext->dwUpper = Context->ContextId; Context->CredentialId = phCredential->dwUpper; Context->State = FirstAccept; Context->Nonce = 0; Context->ContextFlags = fContextReq; *pfContextAttr = fContextReq; *ptsExpiry = Forever; // // Build an output token. // Message = (PMESSAGE) OutputBuffer->pvBuffer; Message->MessageType = Challenge; memset(Message->Buffer,'y',MESSAGE_SIZE); OutputBuffer->cbBuffer = sizeof(MESSAGE); AddContext(Context); return(SEC_I_CONTINUE_NEEDED); } else { // // This is the second call. Lookup the old context. // Context = LocateContext(phContext->dwUpper); if (Context == NULL) { return(SEC_E_INVALID_HANDLE); } if ((Context->State != FirstAccept) && (Context->State != SecondAccept)) { return(SEC_E_INVALID_HANDLE); } Message = (PMESSAGE) InputBuffer->pvBuffer; // // Check that the input message is what we expected. // if (Context->State == FirstAccept) { SampleMessage.MessageType = ChallengeResponse; memset(SampleMessage.Buffer, 'z', MESSAGE_SIZE); } else { SampleMessage.MessageType = ReAuthenticate; memset(SampleMessage.Buffer, 'q', MESSAGE_SIZE); } if (memcmp(&SampleMessage,Message,MESSAGE_SIZE) != 0) { return(SEC_E_INVALID_TOKEN); } Context->State = SecondAccept; return(SEC_E_OK); } } //+------------------------------------------------------------------------- // // Function: DeleteSecurityContext // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY DeleteSecurityContext( PCtxtHandle phContext // Context to delete ) { if (DeleteContext(phContext->dwUpper)) { return(SEC_E_OK); } else { return(SEC_E_INVALID_HANDLE); } } //+------------------------------------------------------------------------- // // Function: ApplyControlToken // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY ApplyControlToken( PCtxtHandle phContext, // Context to modify PSecBufferDesc pInput // Input token to apply ) { return(SEC_E_UNSUPPORTED_FUNCTION); } //+------------------------------------------------------------------------- // // Function: EnumerateSecurityPackagesW // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW( unsigned long SEC_FAR * pcPackages, // Receives num. packages PSecPkgInfoW SEC_FAR * ppPackageInfo // Receives array of info ) { SECURITY_STATUS SecStatus; SecStatus = QuerySecurityPackageInfoW( PACKAGE_NAME, ppPackageInfo ); if (SecStatus == SEC_E_OK) { *pcPackages = 1; } return(SecStatus); } //+------------------------------------------------------------------------- // // Function: QuerySecurityPackageInfoW // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoW( LPWSTR pszPackageName, // Name of package PSecPkgInfoW SEC_FAR * ppPackageInfo // Receives package info ) { PSecPkgInfoW PackageInfo; ULONG PackageInfoSize; PUCHAR Where; if (_wcsicmp(pszPackageName, PACKAGE_NAME)) { return(SEC_E_SECPKG_NOT_FOUND); } PackageInfoSize = sizeof(SecPkgInfoW) + (wcslen(PACKAGE_NAME) + 1 + wcslen(PACKAGE_COMMENT) + 1) * sizeof(WCHAR); PackageInfo = (PSecPkgInfoW) LocalAlloc(0,PackageInfoSize); if (PackageInfo == NULL) { return(SEC_E_INSUFFICIENT_MEMORY); } PackageInfo->fCapabilities = PACKAGE_CAPABILITIES; PackageInfo->wVersion = PACKAGE_VERSION; PackageInfo->wRPCID = PACKAGE_RPCID; PackageInfo->cbMaxToken = PACKAGE_MAXTOKEN; Where = (PUCHAR) (PackageInfo + 1); PackageInfo->Name = (LPWSTR) Where; Where += (wcslen(PACKAGE_NAME) + 1) * sizeof(WCHAR); RtlCopyMemory(PackageInfo->Name, PACKAGE_NAME, sizeof(PACKAGE_NAME)); PackageInfo->Comment = (LPWSTR) Where; Where += (wcslen(PACKAGE_COMMENT) + 1) * sizeof(WCHAR); RtlCopyMemory(PackageInfo->Comment, PACKAGE_COMMENT, sizeof(PACKAGE_COMMENT)); assert(Where - (PBYTE) PackageInfo == (LONG) PackageInfoSize); *ppPackageInfo = PackageInfo; return(SEC_E_OK); } //+------------------------------------------------------------------------- // // Function: FreeContextBuffer // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY FreeContextBuffer( void SEC_FAR * pvContextBuffer ) { LocalFree(pvContextBuffer); return(SEC_E_OK); } //+------------------------------------------------------------------------- // // Function: CompleteAuthToken // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY CompleteAuthToken( PCtxtHandle phContext, // Context to complete PSecBufferDesc pToken // Token to complete ) { return(SEC_E_OK); } //+------------------------------------------------------------------------- // // Function: ImpersonateSecurityContext // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY ImpersonateSecurityContext( PCtxtHandle phContext // Context to impersonate ) { return(SEC_E_OK); } //+------------------------------------------------------------------------- // // Function: RevertSecurityContext // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY RevertSecurityContext( PCtxtHandle phContext // Context from which to re ) { return(SEC_E_OK); } //+------------------------------------------------------------------------- // // Function: QueryContextAttributes // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY QueryContextAttributesW( PCtxtHandle phContext, // Context to query unsigned long ulAttribute, // Attribute to query void SEC_FAR * pBuffer // Buffer for attributes ) { PSEC_CONTEXT Context; PSecPkgContext_Sizes ContextSizes; PSecPkgContext_NamesW ContextNames; PSecPkgContext_Lifespan ContextLifespan; PSecPkgContext_DceInfo ContextDceInfo; Context = LocateContext(phContext->dwUpper); if (Context == NULL) { return(SEC_E_INVALID_HANDLE); } switch(ulAttribute) { case SECPKG_ATTR_SIZES: ContextSizes = (PSecPkgContext_Sizes) pBuffer; ContextSizes->cbMaxSignature = PACKAGE_SIGNATURE_SIZE; if ((Context->ContextFlags & ISC_REQ_CONFIDENTIALITY) != 0) { ContextSizes->cbSecurityTrailer = PACKAGE_SIGNATURE_SIZE; ContextSizes->cbBlockSize = 1; } else { ContextSizes->cbSecurityTrailer = 0; ContextSizes->cbBlockSize = 0; } ContextSizes->cbMaxToken = PACKAGE_MAXTOKEN; break; case SECPKG_ATTR_NAMES: ContextNames = (PSecPkgContext_Names) pBuffer; ContextNames->sUserName = (LPWSTR) LocalAlloc(0, sizeof(L"dummy user")); if (ContextNames->sUserName == NULL) { return(SEC_E_INSUFFICIENT_MEMORY); } RtlCopyMemory(ContextNames->sUserName, L"dummy user", sizeof(L"dummy user")); break; case SECPKG_ATTR_LIFESPAN: ContextLifespan = (PSecPkgContext_Lifespan) pBuffer; ContextLifespan->tsStart = Never; ContextLifespan->tsExpiry = Forever; break; case SECPKG_ATTR_DCE_INFO: ContextDceInfo = (PSecPkgContext_DceInfo) pBuffer; ContextDceInfo->AuthzSvc = 0; ContextDceInfo->pPac = (PVOID) LocalAlloc(0,sizeof(L"dummy user")); if (ContextDceInfo->pPac == NULL) { return(SEC_E_INSUFFICIENT_MEMORY); } RtlCopyMemory((LPWSTR) ContextDceInfo->pPac, L"dummy user", sizeof(L"dummy user")); break; default: return(SEC_E_INVALID_TOKEN); } return(SEC_E_OK); } #if 0 //+------------------------------------------------------------------------- // // Function: QueryCredentialsAttributes // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesW( PCredHandle phCredentials, // Credentials to query unsigned long ulAttribute, // Attribute to query void SEC_FAR * pBuffer // Buffer for attributes ) { return( pspPackages[phCredentials->dwLower].pftTableW->QueryCredentialsAttributesW( phCredentials, ulAttribute, pBuffer ) ); } #endif //+------------------------------------------------------------------------- // // Function: MakeSignature // // Synopsis: // // Effects: // // Arguments: [phContext] -- context to use // [fQOP] -- quality of protection to use // [pMessage] -- message // [MessageSeqNo] -- sequence number of message // // Requires: // // Returns: // // Notes: // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY MakeSignature( PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { PSEC_CONTEXT Context; PSecBuffer SignatureBuffer; PSIGNATURE Signature; Context = LocateContext(phContext->dwUpper); if (Context == NULL) { return(SEC_E_INVALID_HANDLE); } SignatureBuffer = LocateSigBuffer(pMessage); if (SignatureBuffer == NULL) { return(SEC_E_INVALID_TOKEN); } Signature = (PSIGNATURE) SignatureBuffer->pvBuffer; Signature->MessageId = Context->Nonce++; Signature->Tag = PACKAGE_SIGNATURE_TAG; SignatureBuffer->cbBuffer = sizeof(SIGNATURE); return(SEC_E_OK); } //+------------------------------------------------------------------------- // // Function: VerifySignature // // Synopsis: // // Effects: // // Arguments: [phContext] -- Context performing the unseal // [pMessage] -- Message to verify // [MessageSeqNo] -- Sequence number of this message // [pfQOPUsed] -- quality of protection used // // Requires: // // Returns: // // Notes: // //-------------------------------------------------------------------------- SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, ULONG * pfQOP) { PSEC_CONTEXT Context; PSecBuffer SignatureBuffer; PSIGNATURE Signature; Context = LocateContext(phContext->dwUpper); if (Context == NULL) { return(SEC_E_INVALID_HANDLE); } SignatureBuffer = LocateSigBuffer(pMessage); if (SignatureBuffer == NULL) { return(SEC_E_INVALID_TOKEN); } Signature = (PSIGNATURE) SignatureBuffer->pvBuffer; if (Signature->Tag != PACKAGE_SIGNATURE_TAG) { return(SEC_E_MESSAGE_ALTERED); } if (Signature->MessageId != Context->Nonce++) { Context->State = Idle; return(SEC_E_OUT_OF_SEQUENCE); } return(SEC_E_OK); }