⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 krnlapi.cxx

📁 安全支持提供器接口(SSPI)源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//        STATUS_INVALID_HANDLE -- Credential/Context Handle is invalid
//        STATUS_UNSUPPORTED_FUNCTION -- Function code is not supported
//
//  Notes:
//
//--------------------------------------------------------------------------


NTSTATUS NTAPI
NtLmQueryContextAttributes(
    IN ULONG_PTR KernelContextHandle,
    IN ULONG Attribute,
    IN OUT PVOID Buffer
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    PSecPkgContext_NamesW ContextNames = NULL;
    PSecPkgContext_DceInfo ContextDceInfo = NULL;
    PSecPkgContext_SessionKey ContextSessionKeyInfo = NULL;
    PSecPkgContext_Sizes ContextSizes = NULL;
    PSecPkgContext_Flags ContextFlags = NULL;
    PSecPkgContext_PasswordExpiry PasswordExpires;
    PSecPkgContext_UserFlags UserFlags;
    PSecPkgContext_PackageInfo PackageInfo = NULL;
    PNTLM_KERNEL_CONTEXT pContext = NULL;
    unsigned int Length = 0;

    MAYBE_PAGED_CODE();

    DebugLog(( DEB_TRACE, "Entering NtLmQueryContextAttributes\n" ));



    Status = NtlmReferenceContext( KernelContextHandle, FALSE );

    if ( NT_SUCCESS( Status ) )
    {
        pContext = (PNTLM_KERNEL_CONTEXT) KernelContextHandle ;
    } else {

        //
        // for PACKAGE_INFO or NEGOTIATION_INFO, don't require a completed
        // context.
        //

        if( (Attribute != SECPKG_ATTR_PACKAGE_INFO) &&
            (Attribute != SECPKG_ATTR_NEGOTIATION_INFO)
            )
        {
            DebugLog(( DEB_ERROR,
            "Bad kernel context 0x%lx\n", KernelContextHandle));
            goto CleanUp_NoDeref;
        }

        Status = STATUS_SUCCESS;
    }

    //
    // Handle each of the various queried attributes
    //

    switch ( Attribute ) {
    case SECPKG_ATTR_SIZES:

        ContextSizes = (PSecPkgContext_Sizes) Buffer;
        ContextSizes->cbMaxToken = NTLMSP_MAX_TOKEN_SIZE;

        if (pContext->NegotiateFlags & (NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
                                       NTLMSSP_NEGOTIATE_SIGN |
                                       NTLMSSP_NEGOTIATE_SEAL) ) {
            ContextSizes->cbMaxSignature = NTLMSSP_MESSAGE_SIGNATURE_SIZE;
        } else {
            ContextSizes->cbMaxSignature = 0;
        }

        if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_SEAL) {
            ContextSizes->cbBlockSize = 1;
            ContextSizes->cbSecurityTrailer = NTLMSSP_MESSAGE_SIGNATURE_SIZE;
        }
        else
        {
            ContextSizes->cbBlockSize = 0;
            ContextSizes->cbSecurityTrailer = 0;
        }

        break;

    //
    // No one uses the function so don't go to the overhead of maintaining
    // the username in the context structure.
    //

    case SECPKG_ATTR_DCE_INFO:

        ContextDceInfo = (PSecPkgContext_DceInfo) Buffer;

        if (ContextDceInfo == NULL)
        {
            DebugLog(( DEB_ERROR, "Null buffer SECPKG_ATTR_DCE_INFO.\n" ));
            Status = STATUS_INVALID_PARAMETER;
            goto Cleanup;
        }

        if (pContext->ContextNames)
        {
            Length = wcslen(pContext->ContextNames);
        }

        ContextDceInfo->pPac = (LPWSTR) LsaKernelFunctions->AllocateHeap(
                 (Length + 1) * sizeof(WCHAR));

        if (ContextDceInfo->pPac != NULL)
        {
            RtlCopyMemory(
                ContextDceInfo->pPac,
                pContext->ContextNames,
                Length * sizeof(WCHAR));

            LPWSTR Temp =  (LPWSTR)ContextDceInfo->pPac;
            Temp[Length] = L'\0';
        }
        else
        {
            DebugLog(( DEB_ERROR, "Bad Context->pPac in SECPKG_ATTR_DCE_INFO.\n" ));
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto Cleanup;
        }
        ContextDceInfo->AuthzSvc = 0;

        break;

    case SECPKG_ATTR_NAMES:

        ContextNames = (PSecPkgContext_Names) Buffer;

        if (ContextNames == NULL)
        {
            DebugLog(( DEB_ERROR, "Null buffer SECPKG_ATTR_NAMES.\n" ));
            Status = STATUS_INVALID_PARAMETER;
            goto Cleanup;
        }

        if (pContext->ContextNames)
        {
            Length = wcslen(pContext->ContextNames);
            DebugLog(( DEB_TRACE, "NtLmQueryContextAttributes: ContextNames length is 0x%lx\n", Length));
        }

        ContextNames->sUserName = (LPWSTR) LsaKernelFunctions->AllocateHeap(
                 (Length + 1) * sizeof(WCHAR));

        if (ContextNames->sUserName != NULL)
        {
            RtlCopyMemory(
                ContextNames->sUserName,
                pContext->ContextNames,
                Length * sizeof(WCHAR));

            ContextNames->sUserName[Length] = L'\0';
        }
        else
        {
            DebugLog(( DEB_ERROR, "Bad Context->sUserName in SECPKG_ATTR_NAMES.\n" ));
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto Cleanup;
        }

        break;

    case SECPKG_ATTR_SESSION_KEY:
       ContextSessionKeyInfo = (PSecPkgContext_SessionKey) Buffer;
       ContextSessionKeyInfo->SessionKeyLength = MSV1_0_USER_SESSION_KEY_LENGTH;
       ContextSessionKeyInfo->SessionKey =
           (PUCHAR) LsaKernelFunctions->AllocateHeap(
               ContextSessionKeyInfo->SessionKeyLength);
       if (ContextSessionKeyInfo->SessionKey != NULL)
       {
           RtlCopyMemory(
               ContextSessionKeyInfo->SessionKey,
               pContext->SessionKey,
               MSV1_0_USER_SESSION_KEY_LENGTH);
       }
       else
       {
           Status = STATUS_INSUFFICIENT_RESOURCES;
       }

       break;

    case SECPKG_ATTR_PASSWORD_EXPIRY:
        PasswordExpires = (PSecPkgContext_PasswordExpiry) Buffer;
        if(pContext->PasswordExpiry.QuadPart != 0) {
            PasswordExpires->tsPasswordExpires = pContext->PasswordExpiry;
        } else {
            Status = SEC_E_UNSUPPORTED_FUNCTION;
        }
        break;

    case SECPKG_ATTR_USER_FLAGS:
        UserFlags = (PSecPkgContext_UserFlags) Buffer;
        UserFlags->UserFlags = pContext->UserFlags;
        break;

    case SECPKG_ATTR_FLAGS:
    {
        BOOLEAN Client = (pContext->ClientTokenHandle == 0);
        ULONG Flags = 0;

        //
        // BUGBUG: this doesn't return the complete flags
        //
        ContextFlags = (PSecPkgContext_Flags) Buffer;
        ContextFlags->Flags = 0;

        if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_SEAL) {
            if( Client )
            {
                Flags |= ISC_RET_CONFIDENTIALITY;
            } else {
                Flags |= ASC_RET_CONFIDENTIALITY;
            }
        }

        if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_SIGN) {
            if( Client )
            {
                Flags |= ISC_RET_SEQUENCE_DETECT | ISC_RET_REPLAY_DETECT | ISC_RET_INTEGRITY;
            } else {
                Flags |= ASC_RET_SEQUENCE_DETECT | ASC_RET_REPLAY_DETECT | ASC_RET_INTEGRITY;
            }
        }

        if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_NULL_SESSION) {
            if( Client )
            {
                Flags |= ISC_RET_NULL_SESSION;
            } else {
                Flags |= ASC_RET_NULL_SESSION;
            }
        }

        if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_DATAGRAM) {
            if( Client )
            {
                Flags |= ISC_RET_DATAGRAM;
            } else {
                Flags |= ASC_RET_DATAGRAM;
            }
        }

        if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_IDENTIFY) {
            if( Client )
            {
                Flags |= ISC_RET_IDENTIFY;
            } else {
                Flags |= ASC_RET_IDENTIFY;
            }
        }

        ContextFlags->Flags |= Flags;

        break;
    }

    case SECPKG_ATTR_PACKAGE_INFO:
    case SECPKG_ATTR_NEGOTIATION_INFO:
        //
        // Return the information about this package. This is useful for
        // callers who used SPNEGO and don't know what package they got.
        //

        PackageInfo = (PSecPkgContext_PackageInfo) Buffer;

        PackageInfo->PackageInfo = (PSecPkgInfoW) LsaKernelFunctions->AllocateHeap(
                                                    sizeof(SecPkgInfoW) +
                                                    sizeof(NTLMSP_NAME) +
                                                    sizeof(NTLMSP_COMMENT)
                                                    );

        if (PackageInfo->PackageInfo == NULL)
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto Cleanup;
        }
        PackageInfo->PackageInfo->Name = (LPWSTR) (PackageInfo->PackageInfo + 1);
        PackageInfo->PackageInfo->Comment = (LPWSTR) ((((PCHAR) PackageInfo->PackageInfo->Name)) + sizeof(NTLMSP_NAME));
        wcscpy(
            PackageInfo->PackageInfo->Name,
            NTLMSP_NAME
            );

        wcscpy(
            PackageInfo->PackageInfo->Comment,
            NTLMSP_COMMENT
            );
        PackageInfo->PackageInfo->wVersion      = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION;
        PackageInfo->PackageInfo->wRPCID        = NTLMSP_RPCID;
        PackageInfo->PackageInfo->fCapabilities = NTLMSP_CAPS;
        PackageInfo->PackageInfo->cbMaxToken    = NTLMSP_MAX_TOKEN_SIZE;

        if ( Attribute == SECPKG_ATTR_NEGOTIATION_INFO )
        {
            PSecPkgContext_NegotiationInfo NegInfo ;

            NegInfo = (PSecPkgContext_NegotiationInfo) PackageInfo ;
            if( pContext ) {
                NegInfo->NegotiationState = SECPKG_NEGOTIATION_COMPLETE ;
            } else {
                NegInfo->NegotiationState = 0;
            }
        }
        break;

    case SECPKG_ATTR_LIFESPAN:
    default:

        Status = STATUS_NOT_SUPPORTED;
        break;
    }

Cleanup:

    if (!NT_SUCCESS(Status)) {

        switch ( Attribute) {

          case SECPKG_ATTR_NAMES:

              if (ContextNames && ContextNames->sUserName)
              {
                  LsaKernelFunctions->FreeHeap(ContextNames->sUserName);
                  ContextNames->sUserName = NULL;
              }
          break;

          case SECPKG_ATTR_DCE_INFO:

              if (ContextDceInfo && ContextDceInfo->pPac)
              {
                  LsaKernelFunctions->FreeHeap(ContextDceInfo->pPac);
                  ContextDceInfo->pPac = NULL;
              }
          break;

          case SECPKG_ATTR_SESSION_KEY:

              if(ContextSessionKeyInfo && ContextSessionKeyInfo->SessionKey)
              {
                  LsaKernelFunctions->FreeHeap(ContextSessionKeyInfo->SessionKey);
                  ContextSessionKeyInfo->SessionKey = NULL;
              }
          break;

          case SECPKG_ATTR_NEGOTIATION_INFO:

              if(PackageInfo && PackageInfo->PackageInfo)
              {
                  LsaKernelFunctions->FreeHeap(PackageInfo->PackageInfo);
                  PackageInfo->PackageInfo = NULL;
              }
          break;

        }
    }

    if( pContext ) {
        NtlmDerefContext( pContext );
    }

CleanUp_NoDeref:
    DebugLog(( DEB_TRACE, "Leaving NtLmQueryContextAttributes 0x%lx\n", Status ));
    return Status;
}



//+-------------------------------------------------------------------------
//
//  Function:   NtLmCompleteToken
//
//  Synopsis:   Completes a context
//
//  Effects:
//
//  Arguments:
//
//  Requires:
//
//  Returns:
//
//  Notes:
//
//
//--------------------------------------------------------------------------
NTSTATUS NTAPI
NtLmCompleteToken(
    IN ULONG_PTR ContextHandle,
    IN PSecBufferDesc InputBuffer
    )
{
    UNREFERENCED_PARAMETER (ContextHandle);
    UNREFERENCED_PARAMETER (InputBuffer);
    PAGED_CODE();
    DebugLog(( DEB_TRACE, "Entering NtLmCompleteToken\n" ));
    DebugLog(( DEB_TRACE, "Leaving NtLmCompleteToken\n" ));
    return(STATUS_NOT_SUPPORTED);
}

//+-------------------------------------------------------------------------
//
//  Function:   NtLmMakePackedContext
//
//  Synopsis:   Maps a context to the caller's address space
//
//  Effects:
//
//  Arguments:  Context - The context to map
//              MappedContext - Set to TRUE on success
//              ContextData - Receives a buffer in the caller's address space
//                      with the mapped context.
//
//  Requires:
//
//  Returns:
//
//  Notes:
//
//
//--------------------------------------------------------------------------


NTSTATUS
NtLmMakePackedContext(
    IN PNTLM_KERNEL_CONTEXT Context,
    OUT PBOOLEAN MappedContext,
    OUT PSecBuffer ContextData,
    IN ULONG Flags
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    PNTLM_KERNEL_CONTEXT PackedContext = NULL;
    ULONG ContextSize, ContextNameSize = 0;

    PAGED_CODE();

    // ExAcquireResourceExclusiveLite(&NtLmKernelContextLock, TRUE);

    if (Context->ContextNames)
    {
        ContextNameSize = wcslen(Context->ContextNames);
    }

    // ExReleaseResource(&NtLmKernelContextLock);

    ContextSize =  sizeof(NTLM_KERNEL_CONTEXT) +
                

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -