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

📄 obexdevice.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        //  Fix up the ObexPacketData by pointing at the start of headers
        //     huh you ask? :)  the CONNECT response is like this
        //        byte0: response code
        //       byte1: connect response packet length
        //       byte2: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        //        byte3: OBEX version #
        //       byte4: flags
        //       byte5: max OBEX packet length
        //     byte6: ^^^^^^^^^^^^^^^^^^^^^^
        //  so we advance the packet by 7 bytes to account for this header stuff
        p->ppkt = pPacket;
        p->start = p->current = (pPacket + 7);
        p->length = uiPackSize - 7;    


        //
        //  if we've been denied access, we have to authenticate ourselves
        //
        fOkayToContinueWithoutAuthentication = FALSE;
        
        //
        //  pull out the challenge generated by the server and get a copy for ourselves
        //        
        while (! p->__EOF ()) 
        {
            if (p->IsA (OBEX_HID_AUTH_CHALLENGE))
            {  
                UCHAR *pTempServerChallenge = NULL;
                UCHAR *pServerChallenge = NULL;
                INT iTempServerChallenge;
                p->GetBytes(&pTempServerChallenge, &iTempServerChallenge);
                
                while(iTempServerChallenge)
                {
                    //decease the buffer by the size of this TAG/NAME/VALUE 
                    iTempServerChallenge -= (2 + *(pTempServerChallenge+1));

                    //
                    //  if the tag is 0x00, the size is 16 (the size of the
                    //    MD5 challenge, and the only option that could be set 
                    //      is READ/ONLY, we've got our challenge so stop looking
                    //
                    if(0x00 == *pTempServerChallenge && 
                       0x10 == *(pTempServerChallenge+1))
                      
                    {
                        pServerChallenge = pTempServerChallenge + 2;
                        fChallengeFound = TRUE;
                        break;    
                    }
                    else
                        pTempServerChallenge += (*(pTempServerChallenge+1) + 2);            
                }

                // 
                //  if we have actually got a valid looking challenge, cache it away
                //       into bServerChallenge
                if(pServerChallenge)
                {
                    memcpy(bServerChallenge, pServerChallenge, 16);    
                }
                else
                {
                    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSend() -- ERROR! challenge recieved, but was not a format we accept\n"));        
                    delete [] pPacket;
                    delete p;
                    return OBEX_E_CONNECTION_NOT_ACCEPTED;
                }
            }
            p->Next ();   
        }

        //
        //  If there wasnt a challenge, we cant continue on. (they denied us... they didnt challenge us?)
        //
        if(!fChallengeFound)
        {
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSend() -- ERROR! Unauthorized reply without challenge... most likely a server bug!\n"));        
            delete [] pPacket;
            delete p;
            return OBEX_E_CONNECTION_NOT_ACCEPTED;
        }

        //
        //  build up a response to the servers challenge and add it to the
        //    header collection
        //        
        BYTE bAuthResponse[18];

        bAuthResponse[0]=0;
        bAuthResponse[1]=16;

        hRes = MakeResponse (_pszPassToUse, bServerChallenge, bAuthResponse + 2);
        if (hRes != ERROR_SUCCESS)
            return E_FAIL;

        pHeaderCollection->AddByteArray(OBEX_HID_AUTH_RESPONSE, 18, bAuthResponse);

    
        //
        //  clear out the packet parser, delete the old packet, and RESend the CONNECT packet
        //    but this time its got an AUTHENICATION RESPONSE for the server 
        //    
        delete p;
        delete [] pPacket;
        pPacket = NULL;
        p = NULL;
        hRes = ObexSendRecv(pConnection, 
                            uiMaxPacket, 
                            (char)OBEX_OP_CONNECT, 
                            packet, 
                            4,        
                            pHeaderCollection, 
                            &pPacket, 
                            &uiPackSize);
        if(FAILED(hRes))
        {
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::Connect() -- error with ObexSendRecv!\n")); 
            return hRes;
        }


        //
        //  create a new parser, and double check the opcode
        //          
        p = new ObexParser(pPacket, uiPackSize);

        if (!p || p->Op() != (OBEX_STAT_OK | OBEX_OP_ISFINAL)) 
        {
            DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::Connect() -- error with ObexSendRecv - connection not accepted!\n")); 
            if(p) 
                delete p;
            delete [] pPacket;
            return OBEX_E_CONNECTION_NOT_ACCEPTED;
        }

        ((char *)(&wMaxLen))[0] = pPacket[5];
        ((char *)(&wMaxLen))[1] = pPacket[6];
        uiMaxPacket = htons(wMaxLen) - OBEX_AUTH_HEADER_SIZE; 
 
        if(uiMaxPacket > g_uiMaxFileChunk - OBEX_AUTH_HEADER_SIZE)
            uiMaxPacket = g_uiMaxFileChunk - OBEX_AUTH_HEADER_SIZE;

        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexConnect() -- GRANTED ACCESS access, setting max packet size to : %d\n",uiMaxPacket));        
     

        //
        //  Fix up the ObexPacketData by pointing at the start of headers
        //     huh you ask? :)  the CONNECT response is like this
        //        byte0: response code
        //       byte1: connect response packet length
        //       byte2: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        //        byte3: OBEX version #
        //       byte4: flags
        //       byte5: max OBEX packet length
        //     byte6: ^^^^^^^^^^^^^^^^^^^^^^
        //  so we advance the packet by 7 bytes to account for this header stuff
        p->ppkt = pPacket;
        p->start = p->current = (pPacket + 7);
        p->length = uiPackSize - 7;    
        
    }
    else
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::Connect() -- unrecognized response to CONNECT!\n"));        
        delete [] pPacket;
        delete p;
        return OBEX_E_CONNECTION_NOT_ACCEPTED;
    }


    //
    //  parse the headers and put them in the property bag
    //
    unsigned int uiCid = OBEX_INVALID_CONNECTION;
    PREFAST_ASSERT(p);
    while (! p->__EOF ()) 
    {
        if (p->IsA (OBEX_HID_CONNECTIONID)) {
            p->GetDWORD ((DWORD *)&uiConnectionId);
            pHeaderCollection->AddConnectionId(uiConnectionId);           
        }
        else if (p->IsA (OBEX_HID_AUTH_RESPONSE))
        {  
            UCHAR *pTempServerResponseToChallenge = NULL;
            UCHAR *pServerResponseToChallenge = NULL;
            INT iServerResponseToChallenge = 0;
            p->GetBytes(&pTempServerResponseToChallenge, &iServerResponseToChallenge);        
            PREFAST_ASSERT(pTempServerResponseToChallenge && iServerResponseToChallenge);
            
            while(iServerResponseToChallenge)
            {
                //decease the buffer by the size of this TAG/NAME/VALUE 
                iServerResponseToChallenge -= (2 + *(pTempServerResponseToChallenge+1));

                //
                //  if the tag is 0x00, the size is 16 (the size of the
                //    MD5 challenge, and the only option that could be set 
                //      is READ/ONLY, we've got our challenge so stop looking
                //
                if(0x00 == *pTempServerResponseToChallenge && 
                   0x10 == *(pTempServerResponseToChallenge+1))                                        
                {
                    pServerResponseToChallenge = pTempServerResponseToChallenge + 2;
                    break;
                }
                else
                    pTempServerResponseToChallenge += (*(pTempServerResponseToChallenge+1) + 2);            
            }
            pTempServerResponseToChallenge = NULL;
            
            //
            //  if we have a response to the challenge, generate a MD5 of what
            //    we are expecting and compare it to what was given
            //
            if(pServerResponseToChallenge)
            {                
                BYTE bResponseExpected[16];

                hRes = MakeResponse (_pszPassToUse, bMyNonce, bResponseExpected);
                
                if((hRes == ERROR_SUCCESS) && (0 == memcmp(bResponseExpected, pServerResponseToChallenge, 16)))
                {
                    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSend() -- VERIFIED identity!\n"));        
                    fHaveAuthentication = TRUE;
                }
                else
                {
                    DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSend() -- ERROR!!! invalid identity!\n"));           
                    fHaveAuthentication = FALSE;
                }
            }
            else
            {
                DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSend() -- ERROR! challenge recieved, but was not a format we accept\n"));        
                delete [] pPacket;
                return OBEX_E_CONNECTION_NOT_ACCEPTED;
            }
        }
        else if((p->Op() & OBEX_TYPE_MASK) == OBEX_TYPE_DWORD) 
        {
           ULONG val;
           p->GetDWORD(&val);
           pHeaderCollection->AddLong(p->Op(), val); 
        }
        else if((p->Op() & OBEX_TYPE_MASK) == OBEX_TYPE_BYTESEQ)
        {
            UCHAR *pBuf;
            INT ulBufSize;
            p->GetBytes(&pBuf, &ulBufSize);
            pHeaderCollection->AddByteArray((UCHAR)p->Op(), ulBufSize, pBuf);
        }
        else if((p->Op() & OBEX_TYPE_MASK) == OBEX_TYPE_UNICODE)
        {
            WCHAR *pBuf;  
            p->GetString(&pBuf);          
            pHeaderCollection->AddUnicodeString((UCHAR)p->Op(), pBuf);
        }

        else if((p->Op() & OBEX_TYPE_MASK) == OBEX_TYPE_BYTE)
        {
            BYTE byte;
            p->GetBYTE(&byte);
            pHeaderCollection->AddByte((UCHAR)p->Op(), byte);
        }

        p->Next ();
    }


    //
    //  delete our temporary storage and return
    //
    delete p;
    delete [] pPacket;

    if(!fOkayToContinueWithoutAuthentication && !fHaveAuthentication)
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSend() -- ERROR! we needed authentication, but it failed\n"));        
        return OBEX_E_CONNECTION_NOT_ACCEPTED;    
    }
    
    return S_OK;
}




/*****************************************************************************/
/*  CObexDevice::ObexSendRecvWithAuth -- our job is to do the same thing     */
/*     (send and receive 1 packet) as ObexSendRecv but in the event our      */
/*       request is denied because of authorization, we send our credientials  */
/*     and perform authorization (this function makes authorization          */
/*       transparent to SEND/RECV                                                 */
/*****************************************************************************/
HRESULT 
ObexSendRecvWithAuth(IObexTransportConnection *pConnection, 
                    UINT uiMaxPacket,
                    WCHAR *wcPassword, 
                    char cOpCode, 
                    char *additionalDta, 
                    UINT cAddnlDta, 
                    IHeaderCollection *pHeaderCollection, 
                    unsigned char **pNewPacket, 
                    ULONG *pSize)
{
    HRESULT hr = E_FAIL;    
    ObexParser *p = NULL;
    UINT uiPacketSize;
    UCHAR *pPacket;

    //first things first, send the packet out as-is
    hr = ObexSendRecv(pConnection, uiMaxPacket, cOpCode, additionalDta, cAddnlDta, pHeaderCollection, pNewPacket, pSize);

    if(FAILED(hr))
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecvWithAuth() -- ObexSendRecv failed!\n"));
        return hr;
    }


    pPacket = *pNewPacket;

    if(*pPacket != (OBEX_STAT_UNAUTHORIZED | OBEX_OP_ISFINAL) )
    {
       return hr;
    }


    if(wcPassword[0] == '\0')
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecvWithAuth() -- PASSWORD NOT SET and AUTHENTICATION REQUIRED!\n"));
        return OBEX_E_CONNECTION_NOT_ACCEPTED;
    }

    //
    //  Parse the return packet for its fields
    //    
    uiPacketSize = *pSize;
    p = new ObexParser(pPacket, *pSize);

    if(!p)
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecvWithAuth() -- ObexSendRecv failed!\n"));
        return hr;
    }


    //
    //  if the opcode is UNAUTHORIZED we need to handle
    //        this for the caller.  We do so by building 
    //        up a response and adding it to the property bag for them
    //        we then simply reissue their origional packet
    //       
    UCHAR *pServerChallenge = NULL;

    //
    //  Fix up the packet data by pointing at the start of headers
    //     huh you ask? :)  the CONNECT response is like this
    //        byte0: response code
    //       byte1: connect response packet length
    //       byte2: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    //  so we advance the packet by 3 bytes to account for this header stuff
    p->ppkt = pPacket;
    p->start = p->current = (pPacket + 3);
    p->length = uiPacketSize - 3;    

    
    //
    //  pull out the challenge generated by the server and get a copy for ourselves
    //        
    while (! p->__EOF ()) 
    {
        if (p->IsA (OBEX_HID_AUTH_CHALLENGE))
        {  
            UCHAR *pTempServerChallenge = NULL;                
            INT iTempServerChallenge;
            p->GetBytes(&pTempServerChallenge, &iTempServerChallenge);
            
            while(iTempServerChallenge)
            {
                //decease the buffer by the size of this TAG/NAME/VALUE 
                iTempServerChallenge -= (2 + *(pTempServerChallenge+1));

                //
                //  if the tag is 0x00, the size is 16 (the size of the
                //    MD5 challenge, and the only option that could be set 
                //      is READ/ONLY, we've got our challenge so stop looking
                //
                if(*pTempServerChallenge == 0x00 && 
                   *(pTempServerChallenge+1) == 0x10)
                {
                    pServerChallenge = pTempServerChallenge + 2;                        
                    break;    
                }
                else
                    pTempServerChallenge += (*(pTempServerChallenge+1) + 2);            
            }                
        }
        p->Next ();   
    }

    //
    //  If there wasnt a challenge, we cant continue on. (they denied us... they didnt challenge us?)
    //
    if(!pServerChallenge)
    {
        DEBUGMSG(OBEX_OBEXDEVICE_ZONE,(L"CObexDevice::ObexSendRecvWithAuth() -- ERROR! Unauthorized reply without challenge... most likely a server bug!\n"));        
        delete [] pPacket;
        delete p;
        return E_FAIL;
    }
        
    BYTE bAuthResponse[18];
    
    bAuthResponse[0]=0;
    bAuthResponse[1]=16;    

    HRESULT hRes = MakeResponse (wcPassword, pServerChallenge, bAuthResponse + 2);
    if (hRes != ERROR_SUCCESS)
        return hRes;

    pHeaderCollection->AddByteArray(OBEX_HID_AUTH_RESPONSE, 18, bAuthResponse);


    //
    //  clear out the packet parser, delete the old packet, and RESend the  packet
    //    but this time its got an AUTHENICATION RESPONSE for the server 
    //    
    delete p;
    delete [] pPacket;

⌨️ 快捷键说明

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