📄 obexdevice.cpp
字号:
// 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 + -