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

📄 pc_net_prog.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    DWORD dwRet;
    UINT uiDialectIdx = 0;

    //make sure they (the client) arent trying to blow our buffers
    if(usRemaining > (pRequest->uiDataSize - sizeof(SMB_COM_NEGOTIATE_CLIENT_REQUEST))) {
        ASSERT(FALSE);
        TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: NEGOTIATE -- invalid sizes from client"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }

    //parse out dialects (NOTE: we only support NTLM 0.12)
    while(usRemaining) {
        UINT uiStringLen=0;

        if(0 == usRemaining || 0x02 != *pDialects) {
            dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
            goto Done;
        }
        pDialects++; usRemaining--;

        while(uiStringLen <= usRemaining && 0!=pDialects[uiStringLen])
            uiStringLen ++;

        if(0 != pDialects[uiStringLen]) {
            TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: NEGOTIATE -- couldnt find Dialect"));
            dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
            goto Done;
        }
        uiStringLen ++; //null

        if(0 == strcmp((char *)pDialects, "NT LM 0.12")) {
            fHaveNTLM = TRUE;
            uiNTLMIdx = uiDialectIdx;
        }

        usRemaining -= uiStringLen;
        pDialects += uiStringLen;
        uiDialectIdx ++;
    }

    // The ordering of which dialect we choose is important -- chose them in order of
    //    age (if ever there are more dialects -- right now there we only have
    //    NTLM 0.12
    if(fHaveNTLM && -1 != uiDialectIdx) {
        SYSTEMTIME SysTime;
        FILETIME   FileTime;

        SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM *pNegPortion =
           (SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM *)pResponse->pDataPortion;

        if(NULL == pResponse->pDataPortion || pResponse->uiDataSize < sizeof(SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM)) {
            TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: NTLM -- not enough data for dialect"));
            dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
            goto Done;
        }

        //
        // Get the current time, and convert to FILETIME
        GetLocalTime(&SysTime);

        if(0 == SystemTimeToFileTime(&SysTime, &FileTime)) {
          TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: Cant convert SysTime to Filetime"));
          ASSERT(FALSE);
          dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
          goto Done;
        }

        pNegPortion->inner.WordCount = (sizeof(SMB_COM_NEGOTIATE_SERVER_RESPONSE)-1)/sizeof(WORD);
        pNegPortion->inner.DialectIndex = uiNTLMIdx;
        pNegPortion->inner.SecurityMode = 3;//bit 0 = share level security, bit 1 = encrypt passwords
//        pNegPortion->inner.SecurityMode = 2;//bit 0 = share level security, bit 1 = encrypt passwords
        pNegPortion->inner.MaxMpxCount = 50;
        pNegPortion->inner.MaxCountVCs = 1;
        pNegPortion->inner.MaxTransmitBufferSize = SMB_Globals::MAX_PACKET_SIZE;
        pNegPortion->inner.MaxRawSize = SMB_Globals::MAX_PACKET_SIZE;
        pNegPortion->inner.SessionKey = 0;
        pNegPortion->inner.Capabilities = 0;
//       pNegPortion->inner.Capabilities |= CAP_RAW_MODE;
//       pNegPortion->inner.Capabilities |= CAP_MPX_MODE;
        pNegPortion->inner.Capabilities |= CAP_NT_FIND;
        pNegPortion->inner.Capabilities |= CAP_LARGE_FILES;
        pNegPortion->inner.Capabilities |= CAP_NT_SMBS;
        pNegPortion->inner.Capabilities |= CAP_UNICODE;
        pNegPortion->inner.Capabilities |= CAP_LEVEL_II_OPLOCKS;
        pNegPortion->inner.Capabilities |= CAP_STATUS32;


        //<--CAP_EXTENDED_SECURITY put in only if they put extended security in their flags2 field
        TRACEMSG(ZONE_SMB, (L"SMBSRV--NEGOTIATE Caps set to: 0x%x", pNegPortion->inner.Capabilities));


        pNegPortion->inner.SystemTimeLow = FileTime.dwLowDateTime;
        pNegPortion->inner.SystemTimeHigh = FileTime.dwHighDateTime;
        pNegPortion->inner.ServerTimeZone = (USHORT)GetTimeZoneBias();

        pNegPortion->inner.EncryptionKeyLength = 0;
        pNegPortion->ByteCount = 0;

        //
        // LM passwords
        if(!(SMB_FLAGS2_EXTENDED_SECURITY  & pSMB->pInSMB->Flags2)) {
            pNegPortion->inner.EncryptionKeyLength = 8;
            if(0 == CeGenRandom(8, pNegPortion->Blob)) {
                ASSERT(FALSE);
                memset(pNegPortion->Blob, 0, 8);
            }
            if(FAILED(SMB_Globals::g_pConnectionManager->AddChallenge(pSMB->ulConnectionID, pNegPortion->Blob))) {
                ASSERT(FALSE);
            }

            *puiUsed = sizeof(SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM) - 16 + 8; //remove BLOB and add key
            pNegPortion->ByteCount += 8;
        } else {
            BYTE *pBuffer = pNegPortion->Blob;

            pNegPortion->inner.Capabilities |= CAP_EXTENDED_SECURITY;
            ASSERT(16 == sizeof(SMB_Globals::g_ServerGUID));
            memcpy(pBuffer, SMB_Globals::g_ServerGUID, sizeof(SMB_Globals::g_ServerGUID));
            pNegPortion->ByteCount += sizeof(SMB_Globals::g_ServerGUID);
            pBuffer += sizeof(SMB_Globals::g_ServerGUID);
            *puiUsed = sizeof(SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM) - 16 + 16; //remove BLOB and add GUID


            //
            // Copy in a security blob
            CredHandle hNegSecurityHandle;
            TimeStamp ts;
            if(SEC_E_OK != AcquireCredentialsHandle(NULL, L"Negotiate", SECPKG_CRED_INBOUND,NULL,NULL,NULL,NULL,&hNegSecurityHandle, &ts)) {
                 TRACEMSG(ZONE_ERROR, (L"SMBSRV-NEGOTITAE: couldnt get cred handle"));
                 ASSERT(FALSE);
            }

            ULONG Attributes;
            SecBufferDesc OutputToken;
            TimeStamp Expiry;
            SecBuffer OutputBuffer;
            CtxtHandle HandleOut;

            OutputToken.pBuffers = &OutputBuffer;
            OutputToken.cBuffers = 1;
            OutputToken.ulVersion = 0;
            OutputBuffer.pvBuffer = 0;
            OutputBuffer.cbBuffer = 0;
            OutputBuffer.BufferType = SECBUFFER_TOKEN;

            if(SEC_I_CONTINUE_NEEDED == AcceptSecurityContext(&hNegSecurityHandle,
                                                   NULL,NULL,
                                                   ISC_REQ_MUTUAL_AUTH | ISC_REQ_FRAGMENT_TO_FIT | ISC_REQ_ALLOCATE_MEMORY | ASC_REQ_ALLOW_NULL_SESSION,
                                                   SECURITY_NATIVE_DREP,
                                                   &HandleOut, &OutputToken, &Attributes, &Expiry)) {

                memcpy(pBuffer, OutputBuffer.pvBuffer, OutputBuffer.cbBuffer);
                pNegPortion->ByteCount += (USHORT)OutputBuffer.cbBuffer;
                *puiUsed += OutputBuffer.cbBuffer;
                FreeContextBuffer(OutputBuffer.pvBuffer);
                DeleteSecurityContext(&HandleOut);
            }
            FreeCredentialsHandle(&hNegSecurityHandle);

        }
    }
    else {
        TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: we dont have any dialects in common"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }
    dwRet = 0;
    Done:
        return dwRet;
}



DWORD SMB_TRANS_API_ShareEnum(SMB_PACKET *pSMB,
                               SMB_PROCESS_CMD *_pRawRequest,
                               SMB_PROCESS_CMD *_pRawResponse,
                               UINT *puiUsed,
                               StringTokenizer &RequestTokenizer)
{
    DWORD dwRet;
    WORD wLevel;
    WORD wRecvBufferSize;
    UINT uiNumShares = 0;
    CHAR *pAPIParam = NULL;
    CHAR *pAPIData = NULL;
    ce::smart_ptr<ActiveConnection> pMyConnection = NULL;

    SMB_COM_TRANSACTION_CLIENT_REQUEST *pRequest = (SMB_COM_TRANSACTION_CLIENT_REQUEST *)_pRawRequest->pDataPortion;
    SMB_COM_TRANSACTION_SERVER_RESPONSE *pResponse = (SMB_COM_TRANSACTION_SERVER_RESPONSE *)_pRawResponse->pDataPortion;

    if(FAILED(RequestTokenizer.GetString(&pAPIParam))) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_TRANS_API_ShareEnum -- Error fetching apiParams! from params!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }
    if(FAILED(RequestTokenizer.GetString(&pAPIData))) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_TRANS_API_ShareEnum -- Error fetching smpParams! from params!"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }

    TRACEMSG(ZONE_SMB, (L"...processing SMB_TRANS_API_ShareEnum"));
    //
    // Special to ShareEnum are two WORD's  -- level and recv buffer size
    if(FAILED(RequestTokenizer.GetWORD(&wLevel))) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- error getting Level from params on API"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }
    if(FAILED(RequestTokenizer.GetWORD(&wRecvBufferSize))) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- error getting Level from params on API"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }

    //
    // Find our connection state
    if(!(pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB))) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum: -- cant find connection 0x%x!", pSMB->ulConnectionID));
        ASSERT(FALSE);
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }

    //
    // Verify the param/data/level to make sure they are what we expected
    if((0 != strcmp("WrLeh", (CHAR *)pAPIParam)) ||
        (0 != strcmp("B13BWz", (CHAR *)pAPIData)) ||
        (1 != wLevel))
    {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- invalid apiparam for api"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }
    ASSERT(0 == RequestTokenizer.RemainingSize());

    //
    // Make sure we have more space than they do
    if(wRecvBufferSize > _pRawResponse->uiDataSize) {
        wRecvBufferSize = _pRawResponse->uiDataSize - sizeof(SMB_COM_TRANSACTION_SERVER_RESPONSE);
    }
    {
    //make 3 pointers... like this (main body plus params)
    //[SMB][TRANS_RESPONSE][[TRANS_PARAM_HEADER][SMB_SHARE_INFO * uiNumVisibleShares][sz-strings]]
    //   the pointers will point to a PARAM header, the array of SMB_SHARE_INFO's,
    //   and the other to the sz-strings
    RAPIBuilder RAPI((BYTE *)(pResponse+1), wRecvBufferSize, pRequest->MaxParameterCount, pRequest->MaxDataCount);
    SMB_RAP_RESPONSE_PARAM_HEADER *pParamHeader;
    SMB_SHARE_INFO_1              *pFirstShareInfo = NULL;
    UINT uiIdx = 0xFFFFFFFF;

    //BUGBUG: when we dont have enough memory we need to report back to the client!
    if(FAILED(RAPI.ReserveParams(sizeof(SMB_RAP_RESPONSE_PARAM_HEADER), (BYTE**)&pParamHeader))) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- not enough memory in request"));
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }

    //
    // We wont be alligned if we dont make a gap
    while(0 != ((UINT)RAPI.DataPtr() % sizeof(DWORD)))
        RAPI.MakeParamByteGap(1);

    //
    // Build a RAPI response with our share information
    for(UINT i=0; i<SMB_Globals::g_pShareManager->NumShares(); i++) {
        SMB_SHARE_INFO_1      *pShareInfo;
        Share *pShare = SMB_Globals::g_pShareManager->SearchForShare(i);
        HRESULT hr;
        if(!pShare || pShare->IsHidden() || FAILED(pShare->AllowUser(pMyConnection->UserName(),SEC_READ)))
            continue;

        if(uiIdx == 0xFFFFFFFF)
            uiNumShares = 1;
        else
            uiNumShares ++;

        const CHAR *pRemark = pShare->GetRemark();
        UINT uiRemarkLen = (NULL == pRemark)?1:(strlen(pRemark) + 1);
        CHAR *pUnbasedRemark;

        //
        // Reserve enough memory for our share info
        //BUGBUG: report back that we dont have enough memory!!
        hr = RAPI.ReserveBlock(sizeof(SMB_SHARE_INFO_1), (BYTE**)&pShareInfo);
        if(SUCCEEDED(hr))
            hr = RAPI.ReserveFloatBlock(uiRemarkLen, &uiIdx);
        if(SUCCEEDED(hr))
            hr = RAPI.MapFloatToFixed(uiIdx, (BYTE **)&pUnbasedRemark);
        if(FAILED(hr)) {
            TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- not enough memory in request"));
            dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
            goto Done;
        }

        //
        // Keep track of the first shareInfo structure
        if(NULL == pFirstShareInfo)
            pFirstShareInfo = pShareInfo;

        //
        // Write in the remark
        if(uiRemarkLen == 1)
            *pUnbasedRemark = (CHAR)0x00;
        else
            memcpy(pUnbasedRemark, pRemark, uiRemarkLen);

        //
        // Populate the share blob
        UINT uiShareNameLen = strlen(pShare->GetShareNameSZ()) + 1;
        pShareInfo->Type = pShare->GetShareType();
        pShareInfo->Remark = pUnbasedRemark; //note: this is not rebased yet!! we have to do that after coalesce()
        pShareInfo->Pad = 0;
        memset(pShareInfo->Netname, 0, sizeof(pShareInfo->Netname));
        memcpy(pShareInfo->Netname, pShare->GetShareNameSZ(), uiShareNameLen);
            ASSERT(pShareInfo->Type <= 3);

    }

    //
    //  Coalesce and rebase pointers
    if(FAILED(RAPI.Coalesce())) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- internal error with coalesce()!!"));
        ASSERT(FALSE);
        dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
        goto Done;
    }

    //
    // Rebase
    if(uiIdx != 0xFFFFFFFF) {
        SMB_SHARE_INFO_1      *pShareTemp = pFirstShareInfo;

⌨️ 快捷键说明

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