📄 pc_net_prog.cpp
字号:
BOOL fAllowAll = FALSE;
if(TRUE == RegAllowAll.Open(HKEY_LOCAL_MACHINE, L"Services\\SMBServer\\Shares")) {
fAllowAll = !(RegAllowAll.ValueDW(L"UseAuthentication", TRUE));
}
if(TRUE == fAllowAll) {
RETAILMSG(1, (L"SMBSRV: Even though this user didnt provide proper credentials we are letting in because of UseAuthentication reg setting"));
pMyConnection->SetGuest(FALSE);
} else {
TRACEMSG(ZONE_SECURITY, (L"SMBSRV COM_SESSION_SETUP_ANDX: access DENIED"));
dwRet = ERROR_CODE(STATUS_WRONG_PASSWORD);
goto Done;
}
}
}
{
StringConverter NativeOS;
StringConverter NativeLanman;
UINT uiNativeOS;
UINT uiNativeLanman;
UINT uiLeftInResponse = pResponse->uiDataSize - sizeof(SMB_COM_SESSION_SETUP_RESPONSE_NTLM);
BYTE *pEndOfResponse = (BYTE *)(pSessionResponse+1);
pSessionResponse->Action = 0;//(TRUE == fIsGuest?1:0);
pSessionResponse->ByteCount = 0;
NativeOS.append(L"Windows CE");
NativeLanman.append("Windows CE");
pNativeOS = NativeOS.NewSTRING(&uiNativeOS, pMyConnection->SupportsUnicode(pSMB->pInSMB));
pNativeLanman = NativeLanman.NewSTRING(&uiNativeLanman, pMyConnection->SupportsUnicode(pSMB->pInSMB));
if(NULL != pNativeOS && NULL != pNativeLanman) {
if((UINT)pEndOfResponse % 2) {
*pEndOfResponse = 0;
pEndOfResponse ++;
pSessionResponse->ByteCount ++;
uiLeftInResponse --;
}
memcpy(pEndOfResponse, pNativeOS, uiNativeOS);
pEndOfResponse += uiNativeOS;
pSessionResponse->ByteCount += uiNativeOS;
uiLeftInResponse -= uiNativeOS;
if((UINT)pEndOfResponse % 2) {
*pEndOfResponse = 0;
pEndOfResponse ++;
pSessionResponse->ByteCount ++;
uiLeftInResponse --;
}
memcpy(pEndOfResponse, pNativeLanman, uiNativeLanman);
pEndOfResponse += uiNativeLanman;
pSessionResponse->ByteCount += uiNativeLanman;
uiLeftInResponse -= uiNativeLanman;
} else {
ASSERT(FALSE);
goto Done;
}
dwRet = 0;
//
// Fill in word count -- subtract 3 for the WordCount byte and ByteCount(which doesnt count as a word)
pSessionResponse->ANDX.WordCount = (sizeof(SMB_COM_SESSION_SETUP_RESPONSE_NTLM)-3)/sizeof(WORD);
pSessionResponse->ANDX.AndXCommand = 0xFF; //assume we are the last command
pSessionResponse->ANDX.AndXReserved = 0;
pSessionResponse->ANDX.AndXOffset = 0;
*puiUsed = sizeof(SMB_COM_SESSION_SETUP_RESPONSE_NTLM) + pSessionResponse->ByteCount;
}
} else {
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_ACCESS_DENIED);
goto Done;
}
Done:
if(NULL != pNativeOS) {
LocalFree(pNativeOS);
}
if(NULL != pNativeLanman) {
LocalFree(pNativeLanman);
}
return dwRet;
}
BOOL AccessAllowAll()
{
CReg RegAllowAll;
BOOL fAllowAll = FALSE;
if(TRUE == RegAllowAll.Open(HKEY_LOCAL_MACHINE, L"Services\\SMBServer\\Shares")) {
fAllowAll = !(RegAllowAll.ValueDW(L"UseAuthentication", TRUE));
}
return fAllowAll;
}
DWORD SMB_Com_Session_Setup_ANDX_NTLM(SMB_PACKET *pSMB,
SMB_PROCESS_CMD *pRequest,
SMB_PROCESS_CMD *pResponse,
UINT *puiUsed)
{
DWORD dwRet = 0;
SMB_COM_SESSION_SETUP_REQUEST_EXTENDED_NTLM *pSessionRequest =
(SMB_COM_SESSION_SETUP_REQUEST_EXTENDED_NTLM *)pRequest->pDataPortion;
SMB_COM_SESSION_SETUP_RESPONSE_EXTENED_NTLM *pSessionResponse =
(SMB_COM_SESSION_SETUP_RESPONSE_EXTENED_NTLM *)pResponse->pDataPortion;
UINT uiLeftInResponse = 0;
BYTE *pEndOfResponse = NULL;
ce::smart_ptr<ActiveConnection> pMyConnection = NULL;
StringTokenizer SecurityTokens;
CtxtHandle newContextHandle;
SecBufferDesc secBufferDescIn;
SecBufferDesc secBufferDescOut;
SecBuffer secBufferIn;
SecBuffer secBufferOut;
ULONG ulContextAttrs;
TimeStamp TimeExpire;
SECURITY_STATUS secStatus;
BYTE PassedToken[1024];
BYTE *pPassedToken = PassedToken;
BYTE OutToken[1024];
BYTE *pOutToken = OutToken;
BYTE *pUnAlignedToken = NULL;
SecPkgInfo *pPackageInfo = NULL;
BOOL fIsGuest = FALSE;
BYTE *pNativeOS = NULL;
BYTE *pNativeLanman = NULL;
//
// Verify that we have enough data to satisfy requests
if(pRequest->uiDataSize <= sizeof(SMB_COM_SESSION_SETUP_REQUEST_EXTENDED_NTLM)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-COM_SESSION_SETUP_ANDX -- requst too large!!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto SendError;
}
if(pResponse->uiDataSize <= sizeof(SMB_COM_SESSION_SETUP_RESPONSE_EXTENED_NTLM)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-COM_SESSION_SETUP_ANDX -- response too large!!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto SendError;
}
uiLeftInResponse = pResponse->uiDataSize - sizeof(SMB_COM_SESSION_SETUP_RESPONSE_EXTENED_NTLM);
pEndOfResponse = (BYTE *)(pSessionResponse+1);
//
// Find our connection state
if(!(pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: COM_SESSION_SETUP_ANDX: -- cant find connection 0x%x!", pSMB->ulConnectionID));
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Put in any capabilities they support/want
if(0 != (pSMB->pInSMB->Flags2 & SMB_FLAGS2_UNICODE)) {
pMyConnection->SetUnicode(TRUE);
}
//
// Mark that we are using NT status codes
pResponse->pSMBHeader->Flags2 |= SMB_FLAGS2_NT_STATUS_CODE;
pSMB->pInSMB->Flags2 |= SMB_FLAGS2_NT_STATUS_CODE;
//
// Clean up the response
memset(pSessionResponse, 0, sizeof(SMB_COM_SESSION_SETUP_RESPONSE_EXTENED_NTLM));
// At the end we will find the security information
SecurityTokens.Reset((BYTE *)(pSessionRequest+1), pRequest->uiDataSize-sizeof(SMB_COM_SESSION_SETUP_REQUEST_EXTENDED_NTLM));
//
// If we couldnt find the auth information, we must create it out for ourselves
if(!pMyConnection->m_fContextSet) {
CredHandle CredHandle;
TimeStamp TimeStamp;
//
// Call into SSPI to get the credentials handle -- cache off the handle for
// use later
secStatus = AcquireCredentialsHandle(NULL,
L"Negotiate",
SECPKG_CRED_INBOUND,
NULL,
NULL,
NULL,
NULL,
&CredHandle,
&TimeStamp);
//
// On error
if(SEC_E_OK != secStatus) {
TRACEMSG(ZONE_ERROR, (L"SMBSRVR SessionSetup: error calling AcquireCredentialsHandle (%d)", secStatus));
goto SendError;
}
//
// Add the handle to our list
//
pMyConnection->m_Credentials = CredHandle;
pMyConnection->m_fContextSet = FALSE;
pMyConnection->SetGuest(TRUE);
IFDBG(pMyConnection->m_uiAcceptCalled = 0;);
//
// Context set must be false so we dont pass in a handle to ASC
ASSERT(FALSE == pMyConnection->m_fContextSet);
}
//
// At this point in SessionSetup it doesnt really matter if we just
// created the credentials handle or not... everything is the same to us
// we just pass blobs back and forth to SSPI
//
// Setup SecBufferDec for AcceptSecurityContext
if(FAILED(SecurityTokens.GetByteArray(&pUnAlignedToken, pSessionRequest->PasswordLength))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRVR SessionSetup: Error -- not enough data to get password blob!!"));
goto SendError;
}
if(pSessionRequest->PasswordLength > sizeof(PassedToken)) {
pPassedToken = new BYTE[pSessionRequest->PasswordLength];
if(NULL == pPassedToken) {
goto SendError;
}
}
//
// Query for maximum token size (for our out buffer)
if(SEC_E_OK != QuerySecurityPackageInfo(L"Negotiate", &pPackageInfo)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRVR SessionSetup: Error -- cant get max token size!!"));
goto SendError;
}
if(sizeof(OutToken) < pPackageInfo->cbMaxToken) {
pOutToken = new BYTE[pPackageInfo->cbMaxToken];
if(NULL == pOutToken) {
goto SendError;
}
}
//
// The memory must be aligned for NTLM to be happy
memcpy(pPassedToken, pUnAlignedToken, pSessionRequest->PasswordLength);
secBufferDescIn.ulVersion = SECBUFFER_VERSION;
secBufferDescIn.cBuffers = 1;
secBufferDescIn.pBuffers = &secBufferIn;
secBufferIn.cbBuffer = pSessionRequest->PasswordLength;
secBufferIn.BufferType = SECBUFFER_TOKEN;
secBufferIn.pvBuffer = pPassedToken;
secBufferDescOut.ulVersion = SECBUFFER_VERSION;
secBufferDescOut.cBuffers = 1;
secBufferDescOut.pBuffers = &secBufferOut;
secBufferOut.cbBuffer = pPackageInfo->cbMaxToken;
secBufferOut.BufferType = SECBUFFER_TOKEN;
secBufferOut.pvBuffer = pOutToken;
IFDBG(pMyConnection->m_uiAcceptCalled++;);
ASSERT(pMyConnection->m_uiAcceptCalled <= 2);
TRACEMSG(ZONE_SECURITY, (L"SMBSRV: ASC Handle: 0x%x Connection: %d MID: %d PID: %d", (UINT)&(pMyConnection->m_Credentials), pSMB->ulConnectionID, pSMB->pInSMB->Mid, pSMB->pInSMB->Pid));
secStatus = AcceptSecurityContext(&pMyConnection->m_Credentials,
pMyConnection->m_fContextSet?&pMyConnection->m_ContextHandle:NULL,
&secBufferDescIn,
ISC_REQ_MUTUAL_AUTH | ISC_REQ_FRAGMENT_TO_FIT | ISC_REQ_ALLOCATE_MEMORY | ASC_REQ_ALLOW_NULL_SESSION,
SECURITY_NATIVE_DREP,
&newContextHandle,
&secBufferDescOut,
&ulContextAttrs,
&TimeExpire);
ASSERT(pMyConnection->IsGuest());
if(SEC_E_OK == secStatus) {
BOOL fAllow = FALSE;
SecPkgContext_Names ctxName;
TRACEMSG(ZONE_SECURITY, (L"SMBSRVR Security: verified user with NTLM (doesnt mean they have permission.. but they are who they say they are!!"));
ASSERT(TRUE == pMyConnection->m_fContextSet);
pMyConnection->m_ContextHandle = newContextHandle;
if(SEC_E_OK != QueryContextAttributes(&pMyConnection->m_ContextHandle, SECPKG_ATTR_NAMES, &ctxName)) {
TRACEMSG(ZONE_SECURITY, (L"SMBSRVR Security: verified user with NTLM but couldnt get the user name! treating as guest"));
ASSERT(FALSE);
} else {
if(0 == wcscmp(L"", ctxName.sUserName)) {
pMyConnection->SetGuest(TRUE);
TRACEMSG(ZONE_SECURITY, (L" -- Authed Guest (NULL Session)"));
} else {
fAllow = TRUE;
pMyConnection->SetGuest(FALSE);
TRACEMSG(ZONE_SECURITY, (L" -- User: %s verified", ctxName.sUserName));
pMyConnection->SetUserName(ctxName.sUserName);
}
FreeContextBuffer(ctxName.sUserName);
}
ASSERT(TRUE == pMyConnection->m_fContextSet);
pMyConnection->m_fContextSet = FALSE;
FreeCredentialsHandle(&(pMyConnection->m_Credentials));
DeleteSecurityContext(&(pMyConnection->m_ContextHandle));
BOOL fAllowAll = AccessAllowAll();
//
// If we dont know who they are, reject them
if(!fAllow && !fAllowAll) {
TRACEMSG(ZONE_SECURITY, (L" -- User: REJECTED"));
goto SendError;
}
//
// If we are allowing universal access then do not
// set access level as guest
if(fAllowAll) {
pMyConnection->SetGuest(FALSE);
}
goto SendSuccess;
}
else if(SEC_I_CONTINUE_NEEDED == secStatus) {
//
// See if we should allow anyone in?
TRACEMSG(ZONE_SECURITY, (L"SMBSRVR Security: need continue -- sending back that in response!!"));
pMyConnection->m_ContextHandle = newContextHandle;
pMyConnection->m_fContextSet = TRUE;
goto SendContinue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -