📄 filesvr.cxx
字号:
DWORD dwSize = sizeof(DWORD);
DWORD dwType = 0;
//
// Do the fetch
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"CanWrite" , NULL, &dwType, (LPBYTE)&fCanWrite, &dwSize)) ||
(dwType != REG_DWORD)) {
fCanWrite = FALSE;
}
}
else
return fCanWrite;
RegCloseKey (hk);
return fCanWrite;
}
HRESULT FetchPassword(WCHAR *pPwd, UINT uiSize)
{
HKEY hk;
HRESULT hr = E_FAIL;
if(!pPwd || !uiSize)
return hr;
//
// Fetch the password from the registry
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, OBEX_FTP_BASE_REG, 0, KEY_READ, &hk))
{
DWORD dwSize = uiSize;
DWORD dwType = 0;
//get the size of the password
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"Password" , NULL, &dwType, (LPBYTE)pPwd, &dwSize)) ||
(dwType != REG_SZ))
goto Done;
hr = S_OK;
}
else
return E_FAIL;
Done:
RegCloseKey (hk);
return hr;
}
FileXFer *
CreateNewFileXFerConnect(ObexTransaction *pOT)
{
//
// Create file transfer object (contains directory/file progress etc)
//
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : createing FileXFer state\n"));
FileXFer *pNew = (FileXFer *)pOT->ObexAlloc(sizeof(FileXFer));
if (! pNew)
{
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : OBEX_OP_CONNECT OOM\n"));
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return 0;
}
//
// initilize the object
//
memset (pNew, 0, sizeof (*pNew));
pNew->op = NONE;
pNew->hFile = INVALID_HANDLE_VALUE;
pNew->szCurDir[0] = L'\0';
pNew->uiConnectionId = pOT->uiConnectionId;
pNew->uiPacketLimit = pOT->pObex->sPktData.ConnectRequestResponse.maxlen;
pNew->fIsAuthenticated = FALSE;
pNew->fNonceSet = FALSE;
pNew->fNameHeaderFound = FALSE;
pNew->fDir = FALSE;
if (pNew->uiPacketLimit < 255)
pNew->uiPacketLimit = 255;
//
// get the base directory out of the registry
//
pNew->szBaseDir[0] = L'\0';
HKEY hk;
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, OBEX_FTP_BASE_REG, 0, KEY_READ, &hk)) {
DWORD dwSize = sizeof(pNew->szBaseDir);
DWORD dwType = 0;
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"BaseDir", NULL, &dwType, (LPBYTE)pNew->szBaseDir, &dwSize)) ||
(dwType != REG_SZ) || (dwSize >= sizeof(pNew->szBaseDir)))
pNew->szBaseDir[0] = L'\0';
RegCloseKey (hk);
}
//
// If we are in the root directory, okay... if not, create the directory
//
if ((pNew->szBaseDir[0] == '\\') && (pNew->szBaseDir[1] == '\0'))
{
pNew->szBaseDir[0] = '\0';
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : OBEX_OP_CONNECT BaseDirectory \\ all system visible!\n"));
}
else
{
if (pNew->szBaseDir[0] == '\0')
wcscpy (pNew->szBaseDir, OBEX_FTP_BASE_DIR);
//
// NOTE: okay for CanWrite() to be false here... this overrides security
// sice the directory being made is pulled from the registry with no
// user data
CreateDirectory (pNew->szBaseDir, NULL);
DWORD dwAttr = GetFileAttributes (pNew->szBaseDir);
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : OBEX_OP_CONNECT BaseDirectory %s, GetFileAttributes = 0x%08x\n", pNew->szBaseDir, dwAttr));
if (dwAttr == 0xffffffff) {
pOT->ObexFree (pNew);
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : OBEX_OP_CONNECT base dir does not exist\n"));
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return 0;
}
}
return pNew;
}
//
// Handle a CONNECT packet and the authentication
// associated with it
//
static int ServiceConnectPacket(ObexTransaction *pOT)
{
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : OBEX_OP_CONNECT 0x%08x pkt max %d\n", pOT->uiConnectionId, pOT->pObex->sPktData.ConnectRequestResponse.maxlen));
FileXFer *pNew = NULL;
//
// Seek out TARGET, WHO, and AUTHENTICATE headers
//
int iWho = -1;
int iTarget = -1;
int iAuthChallenge = -1;
int iAuthResponse = -1;
for (int i = 0 ; ((iTarget == -1) || (iWho == -1) || (iAuthChallenge == -1)) &&
(i < (int)pOT->pObex->cProp) ; ++i) {
if (pOT->pObex->aPropID[i] == OBEX_HID_TARGET)
iTarget = i;
else if (pOT->pObex->aPropID[i] == OBEX_HID_WHO)
iWho = i;
else if (pOT->pObex->aPropID[i] == OBEX_HID_AUTH_CHALLENGE)
iAuthChallenge = i;
else if (pOT->pObex->aPropID[i] == OBEX_HID_AUTH_RESPONSE)
iAuthResponse = i;
}
//
// Build up a response packet
//
ObexCommand oc;
unsigned int aPropID[4];
ObexVariant aPropVar[4];
memset (&oc, 0, sizeof(oc));
oc.uiOp = pOT->pObex->uiOp;
oc.cProp = 0;
oc.aPropID = aPropID;
oc.aPropVar = aPropVar;
oc.sPktData.ConnectRequestResponse.version = 0x10;
oc.sPktData.ConnectRequestResponse.maxlen = OBEX_FTP_MAXPACKET;
//
// Add the connection ID to the connection
//
if(iAuthResponse >= 0)
{
aPropID[oc.cProp] = OBEX_HID_CONNECTIONID;
aPropVar[oc.cProp].ui = pOT->uiConnectionId;
++oc.cProp;
}
//
// If there is a target, add it to the packet
//
if (iTarget >= 0)
{
aPropID[oc.cProp] = OBEX_HID_WHO;
aPropVar[oc.cProp].caub = pOT->pObex->aPropVar[iTarget].caub;
++oc.cProp;
}
//
// Add the TARGET
//
if (iWho >= 0) {
aPropID[oc.cProp] = OBEX_HID_TARGET;
aPropVar[oc.cProp].caub = pOT->pObex->aPropVar[iWho].caub;
++oc.cProp;
}
BOOL fRequireAuthentication = TRUE;
//
// ask the registry if its okay to work without authentication
//
HKEY hk;
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, OBEX_FTP_BASE_REG, 0, KEY_READ, &hk))
{
DWORD dwType = 0;
DWORD dwValue;
DWORD dwSize = sizeof(dwValue);
//query for the value
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"Authenticate", NULL, &dwType, (LPBYTE)&dwValue, &dwSize)) &&
dwType == REG_DWORD &&
dwValue == 0)
{
IFDBG(svslog_DebugOut (DEBUG_FTP_TRACE, L"[OBEX-FTP] ServiceRequest : according to registry, its okay not to authenticate!\n"));
fRequireAuthentication = FALSE;
}
RegCloseKey (hk);
}
//
// request authentication from the lower level transport (if required by reg -- default on)
//
DWORD dwRequireTransportAuth = 1;
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, OBEX_FTP_BASE_REG, 0, KEY_READ, &hk))
{
DWORD dwType = 0;
DWORD dwSize = sizeof(dwRequireTransportAuth);
//query for the value
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"TransportAuthenticate", NULL, &dwType, (LPBYTE)&dwRequireTransportAuth, &dwSize)) &&
dwType == REG_DWORD)
{
dwRequireTransportAuth = 1;
}
RegCloseKey (hk);
}
if(1 == dwRequireTransportAuth)
{
UINT uiStatus;
LeaveCriticalSection (&g_cs);
HRESULT hrAuthRet = pOT->ObexAuthRequest (pOT->uiTransactionId, &uiStatus);
EnterCriticalSection (&g_cs);
//return values from ObexAuthRequest
// 0 == FAILED (transport supports auth)
// 1 == SUCCESS
// 2 == NOT_SUPPORTED (transport doesnt support auth)
if(FAILED(hrAuthRet) || 0 == uiStatus)
{
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
}
//
// If we have a challenge and no response
//
if(-1 == iAuthResponse && iAuthChallenge >= 0)
{
//find the NONCE sent by the client as a challenge to us
UINT uiChallengeSize = pOT->pObex->aPropVar[iAuthChallenge].caub.cuc;
BYTE *pTempChallenge = pOT->pObex->aPropVar[iAuthChallenge].caub.puc;
BYTE *pChallenge = NULL;
WCHAR szPassword[_MAX_PATH];
//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;
}
//
// Create a new authentication node init it, and chain it in
//
AuthList *pNewAuth = (AuthList *)pOT->ObexAlloc(sizeof(AuthList));
//reject since we are out of memory
if(!pNewAuth)
{
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
pNewAuth->pNext = g_pAuthList;
pNewAuth->startTime = GetTickCount ();
memcpy(pNewAuth->challenge, pChallenge, 16);
g_pAuthList = pNewAuth;
//
// 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;
}
//
// Using the password and the current system time, build a nonce
//
HRESULT hAuthRes = MakeNonce (szPassword, ((BYTE *)pNewAuth->nonce)+2);
if(hAuthRes != ERROR_SUCCESS)
{
LeaveCriticalSection (&g_cs);
pOT->ObexExecute (OBEX_RESP_REJECT, pOT->uiTransactionId, NULL);
EnterCriticalSection (&g_cs);
return TRUE;
}
//
// Add the nonce to the reply packet
//
pNewAuth->nonce[0] = 0x00;
pNewAuth->nonce[1] = 0x10;
aPropID[oc.cProp] = OBEX_HID_AUTH_CHALLENGE;
aPropVar[oc.cProp].caub.puc= pNewAuth->nonce;
aPropVar[oc.cProp].caub.cuc = 18;
++oc.cProp;
oc.fFinal = TRUE;
oc.uiResp = OBEX_STAT_UNAUTHORIZED;
//
// Send off the packet
//
LeaveCriticalSection (&g_cs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -