📄 filesvr.cxx
字号:
pOT->ObexExecute (OBEX_RESP_RESPOND, pOT->uiTransactionId, &oc);
EnterCriticalSection (&g_cs);
return TRUE;
}
//
// If there is both a challenge and a response, see if everything checks
// out (do we accept them?)
//
else if (iAuthResponse >= 0 && iAuthChallenge >= 0)
{
SVSUTIL_ASSERT(!pNew);
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : Both CHALLENGE and RESPONSE found in packet! verifying them!\n"));
//
// get a pointer to the challenge
//
UINT uiChallengeSize = pOT->pObex->aPropVar[iAuthChallenge].caub.cuc;
BYTE *pTempChallenge = pOT->pObex->aPropVar[iAuthChallenge].caub.puc;
BYTE *pChallenge = NULL;
//find the nonce sent by the client
while(uiChallengeSize)
{
if(*pTempChallenge == 0 && *(pTempChallenge + 1) == 0x10)
{
pChallenge = pTempChallenge + 2;
break;
}
uiChallengeSize -= (*(pTempChallenge + 1)) + 2;
pTempChallenge += (*(pTempChallenge + 1)) + 2;
}
pTempChallenge = NULL;
//if there isnt a challenge, quit. its not using the MD5
// algorithm we are expecting
if(!pChallenge)
{
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : Client not using same request-digest that we expect\n"));
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
//
// Find the previous AuthList object (it should exist... if not, this is
// either a really broken client or they are trying to spoof us
//
AuthList *pAuthFound = NULL;
AuthList *pAuth = g_pAuthList;
//if there are no auth nodes, we have recieved a strange packet from the client.
if(!g_pAuthList)
{
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : op %d : NO CONNECTIONS EXIST! -- either they are trying to spoof us, or the client is broken!\n", pOT->pObex->uiOp));
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
//
// Do a scan weeding all authentications that have expired.
//
DWORD expireAfter = GetTickCount ();
AuthList *pDelPrev = NULL;
while(pAuth)
{
//since we insert on the beginning of the list, once we have hit
// one that has expired.... every one after that has expired too!
// note: since we do unsigned subtraction rollover on GetTickCount() is okay
if(expireAfter - pAuth->startTime > OBEX_TIMEOUT_AUTHENTICATIONS_AFTER_N_MILLISEC)
{
//
// Fix up the list (or remove the list if its on the head)
//
if(pDelPrev)
pDelPrev->pNext = NULL;
else
g_pAuthList = NULL;
//
// pAuth needs to be removed, as does everything behind it
//
while(pAuth)
{
AuthList *pDelMe = pAuth;
pAuth=pAuth->pNext;
SVSUTIL_ASSERT(expireAfter - pDelMe->startTime > OBEX_TIMEOUT_AUTHENTICATIONS_AFTER_N_MILLISEC);
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : removing expired authentication record\n"));
pOT->ObexFree (pDelMe);
}
break;
}
pDelPrev = pAuth;
pAuth=pAuth->pNext;
}
//
// Do the actual scan for our challenge...
// and remove it from the list (to be deleted later)
//
if(g_pAuthList)
{
pAuth = g_pAuthList;
if(0 == memcmp(pChallenge, g_pAuthList->challenge, 16))
{
pAuthFound = g_pAuthList;
g_pAuthList = g_pAuthList->pNext;
}
else
{
//check the remainder of the list
while (pAuth && pAuth->pNext)
{
if (0 == memcmp(pChallenge, pAuth->pNext->challenge, 16))
{
pAuthFound = pAuth->pNext;
pAuth->pNext = pAuth->pNext->pNext;
}
pAuth = pAuth->pNext;
}
}
}
// if we couldnt find the node, reject the packet
if (!pAuthFound)
{
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : op %d : connection not found! -- either they are trying to spoof us, or the client is broken!\n", pOT->pObex->uiOp));
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
//
// Create a new FileXFer connection
//
pNew = CreateNewFileXFerConnect(pOT);
if(!pNew)
{
pOT->ObexFree (pAuthFound);
return TRUE;
}
//
// Chain the connection into our list of ongoing connections
//
pNew->pNext = g_pConn;
g_pConn = pNew;
//
// Find the NONCE and REQUEST-DIGEST sent by the client, when(if) found
// put a pointer to it in pNonce
//
BYTE *pNonce = pChallenge; //already found it above! dont bother searching again
BYTE *pTemp = pOT->pObex->aPropVar[iAuthResponse].caub.puc;
BYTE *pRequestResponse = NULL;
UINT uiPackSize = pOT->pObex->aPropVar[iAuthResponse].caub.cuc;
//find the request-digest sent by the client
while(uiPackSize)
{
if(*pTemp == 0 && *(pTemp + 1) == 0x10)
{
pRequestResponse = pTemp + 2;
break;
}
uiPackSize -= (*(pTemp + 1)) + 2;
pTemp += (*(pTemp + 1)) + 2;
}
//if we couldnt find a NONCE or a requst response, return out
if(!pNonce || !pRequestResponse)
{
pOT->ObexFree (pAuthFound);
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : The packet sent to us was messed up. Most likely a client error!\n"));
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
WCHAR szPassword[_MAX_PATH];
//
// Fetch the password from the registry
if(FAILED(FetchPassword(szPassword, _MAX_PATH)))
{
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
//
// Verify their response to what we think it should be
//
BYTE bRequestDigest[18];
bRequestDigest[0] = 0x00;
bRequestDigest[1] = 0x10;
BYTE bExpectedResponse[16];
//do the check
if((ERROR_SUCCESS != MakeResponse (szPassword, pAuthFound->nonce + 2, bExpectedResponse)) ||
(0 != memcmp(bExpectedResponse, pRequestResponse, 16)) ||
(ERROR_SUCCESS != MakeResponse (szPassword, pNonce, bRequestDigest + 2)))
{
pOT->ObexFree (pAuthFound);
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : ERROR!!! invalid password!!!!!!!!!\n"));
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : Authenicated!\n"));
//
// Set the all-so-important authenticated flag!
//
pNew->fIsAuthenticated = TRUE;
//
// Add the request-digest to the reply packet
//
aPropID[oc.cProp] = OBEX_HID_AUTH_RESPONSE;
aPropVar[oc.cProp].caub.puc= bRequestDigest;
aPropVar[oc.cProp].caub.cuc = 18;
++oc.cProp;
oc.fFinal = TRUE;
oc.uiResp = OBEX_STAT_OK;
pOT->ObexFree (pAuthFound);
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_RESPOND, pOT->uiTransactionId, &oc);
EnterCriticalSection (&g_cs);
return TRUE;
}
//
// If we have a response and a challenge
//
else
{
//
// Create a new FileXFer connection
//
pNew = CreateNewFileXFerConnect(pOT);
if(!pNew)
{
return TRUE;
}
//
// Chain the connection into our list of ongoing connections
//
pNew->pNext = g_pConn;
g_pConn = pNew;
//
// If we are required to authenticate, reject the packet
//
if(fRequireAuthentication)
{
return HandlePacketAuthentication(pOT, pNew);
}
else
{
//
// Set the all-so-important authenticated flag (just to tell
// other functions that we've been authenticated)
//
pNew->fIsAuthenticated = TRUE;
// put in a connection ID
aPropID[oc.cProp] = OBEX_HID_CONNECTIONID;
aPropVar[oc.cProp].ui = pOT->uiConnectionId;
++oc.cProp;
oc.fFinal = TRUE;
oc.uiResp = OBEX_STAT_OK;
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_RESPOND, pOT->uiTransactionId, &oc);
EnterCriticalSection (&g_cs);
return TRUE;
}
}
}
/******************************************************************************/
/* HandlePacketAuthentication - this is just a utility function that could */
/* be located inside ServiceRequest. The reason its broken out is not */
/* ecause its reusable (just use it for GET/PUT) its because it */
/* is quite lengthy and would be included for GET's and PUT's */
/* */
/* RETURNS: TRUE if packet sent, FALSE if not */
/******************************************************************************/
static int HandlePacketAuthentication(ObexTransaction *pOT, FileXFer *pConn)
{
//
// If they havent been authenticated yet, we need to start the ball
// rolling on it. We will make up a challenge and respond to
// their request with UNAUTHORIZED
//
if(!pConn->fIsAuthenticated && !pConn->fNonceSet)
{
WCHAR szPassword[_MAX_PATH];
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] GET on 0x%08x -- we are NOT authenicated, so we do that now\n", pConn->uiConnectionId));
//
// Fetch the password from the registry
if(FAILED(FetchPassword(szPassword, _MAX_PATH)))
{
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : CANT FIND PASSWORD IN REGISTRY!\n"));
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
if(ERROR_SUCCESS != MakeNonce (szPassword, pConn->nonce + 2))
{
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
//
// Add the nonce to the reply packet
//
pConn->nonce[0] = 0x00;
pConn->nonce[1] = 0x10;
pConn->fNonceSet = TRUE;
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : Get -- using the following as challenge\n"));
IFDBG(svslog_DumpBuff (DEBUG_FTP_TRACE, pConn->nonce, 18));
//
// Build the reply packet (with CHALLENGE)
//
ObexCommand o;
unsigned int aPropId[1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -