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

📄 auth.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		
	SEC_WINNT_AUTH_IDENTITY AuthIdentityClient = {
					    m_wszRemoteUser, wcslen(m_wszRemoteUser), 
						SECURITY_DOMAIN,SVSUTIL_CONSTSTRLEN(SECURITY_DOMAIN),
						wszPassword, wcslen(wszPassword), 
						0};		// dummy domain needed

	memset(&ServerState,0,sizeof(AUTH_STATE));
	memset(&ClientState,0,sizeof(AUTH_STATE));

	if (!g_pVars->m_hSecurityLib)
		myleave(368);

	// NTLM auth functions seem to expect that these buffer will be zeroed.
	pClientOutBuf = MyRgAllocZ(BYTE,g_pVars->m_cbMaxToken);		
	if (NULL == pClientOutBuf)
		myleave(370);

	pServerOutBuf = MyRgAllocZ(BYTE,g_pVars->m_cbMaxToken);		
	if (NULL == pServerOutBuf)
		myleave(371);

	ServerState.m_Stage = SEC_STATE_NO_INIT_CONTEXT;
	ClientState.m_Stage = SEC_STATE_NO_INIT_CONTEXT;

	cbClientBuf = cbServerBuf = g_pVars->m_cbMaxToken;

	//  Main loop that forges client and server talking.
	while (!fDone) {
		cbClientBuf = g_pVars->m_cbMaxToken;
		if (! SecurityClientContext(&AuthIdentityClient,&ClientState,pServerOutBuf,
								cbServerBuf, pClientOutBuf, &cbClientBuf))
		{
			myleave(372);
		}

		cbServerBuf = g_pVars->m_cbMaxToken;
		if (! SecurityServerContext(&AuthIdentityClient,&ServerState, pClientOutBuf,
							  cbClientBuf, pServerOutBuf, &cbServerBuf, &fDone,NTLM_PACKAGE_NAME))
		{
			myleave(373);
		}
	}

done:
	DEBUGMSG_ERR(ZONE_ERROR,(L"HTTPD: Unable to convert Basic Auth to NTLM Auth, err = %d\r\n",err));
	
	if (fDone) {
		GetUserAndGroupInfo(&ServerState);
		m_AuthLevelGranted = DeterminePermissionGranted(GetUserList(),AUTH_USER);
	}
	
	MyFree(pClientOutBuf);
	MyFree(pServerOutBuf);
	
	FreeSecContextHandles(&ServerState);
	FreeSecContextHandles(&ClientState);

	return fDone;
}

//  This calls the DC (or goes to registry in local case), either getting a
//  data blob to return to client or granting auth or denying.

BOOL SecurityServerContext(
			PSEC_WINNT_AUTH_IDENTITY pAuthIdentity,
			PAUTH_STATE pAS,		// security state info
			BYTE *pIn,
			DWORD cbIn,
			BYTE *pOut,
			DWORD *pcbOut,
			BOOL *pfDone,
			const TCHAR *szPackageName)
{
	SECURITY_STATUS	ss;
	TimeStamp		Lifetime;
	SecBufferDesc	OutBuffDesc;
	SecBuffer		OutSecBuff;
	SecBufferDesc	InBuffDesc;
	SecBuffer		InSecBuff;
	ULONG			ContextAttributes;

	
	if (SEC_STATE_NO_INIT_CONTEXT == pAS->m_Stage)  {
		ss = g_pVars->m_SecurityInterface.AcquireCredentialsHandle (
							NULL,	// principal
							(TCHAR *)szPackageName,
							SECPKG_CRED_INBOUND,
							NULL,	// LOGON id
						    pAuthIdentity,	
							NULL,	// get key fn
							NULL,	// get key arg
							&pAS->m_hcred,
							&Lifetime
							);
		if (SEC_SUCCESS (ss))
			pAS->m_fHaveCredHandle = TRUE;
		else {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: NTLM AcquireCreds failed: %X\n", ss));
			return(FALSE);
		}
	}

	// prepare output buffer
	//
	OutBuffDesc.ulVersion = 0;
	OutBuffDesc.cBuffers = 1;
	OutBuffDesc.pBuffers = &OutSecBuff;

	OutSecBuff.cbBuffer = *pcbOut;
	OutSecBuff.BufferType = SECBUFFER_TOKEN;
	OutSecBuff.pvBuffer = pOut;

	// prepare input buffer
	//
	InBuffDesc.ulVersion = 0;
	InBuffDesc.cBuffers = 1;
	InBuffDesc.pBuffers = &InSecBuff;

	InSecBuff.cbBuffer = cbIn;
	InSecBuff.BufferType = SECBUFFER_TOKEN;
	InSecBuff.pvBuffer = pIn;

	ss = g_pVars->m_SecurityInterface.AcceptSecurityContext (
						&pAS->m_hcred,
						(pAS->m_Stage == SEC_STATE_PROCESSING) ?  &pAS->m_hctxt : NULL,
						&InBuffDesc,
						0,	// context requirements
						SECURITY_NATIVE_DREP,
						&pAS->m_hctxt,
						&OutBuffDesc,
						&ContextAttributes,
						&Lifetime
						);
	if (!SEC_SUCCESS (ss))  {
		DEBUGMSG(ZONE_ERROR,(L"HTTPD: NTLM init context failed: %X\n", ss));
		return FALSE;
	}

	pAS->m_fHaveCtxtHandle = TRUE;

	// Complete token -- if applicable
	//
	if ((SEC_I_COMPLETE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss))  {
		if (g_pVars->m_SecurityInterface.CompleteAuthToken) {
			ss = g_pVars->m_SecurityInterface.CompleteAuthToken (&pAS->m_hctxt, &OutBuffDesc);
			if (!SEC_SUCCESS(ss))  {
				DEBUGMSG(ZONE_ERROR,(L"HTTPD:  NTLM complete failed: %X\n", ss));
				return FALSE;
			}
		}
		else {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Complete not supported.\n"));
			return FALSE;
		}
	}

	*pcbOut = OutSecBuff.cbBuffer;
	pAS->m_Stage = SEC_STATE_PROCESSING;

	*pfDone = !((SEC_I_CONTINUE_NEEDED == ss) ||
				(SEC_I_COMPLETE_AND_CONTINUE == ss));

	return TRUE;
}


//  Forges the client browser's part in NTLM communication if the browser
//  sent a Basic request.
BOOL SecurityClientContext(
			PSEC_WINNT_AUTH_IDENTITY pAuthIdentity,
			PAUTH_STATE pAS,		// NTLM state info
			BYTE *pIn,
			DWORD cbIn,
			BYTE *pOut,
			DWORD *pcbOut) 
{
	SECURITY_STATUS	ss;
	TimeStamp		Lifetime;
	SecBufferDesc	OutBuffDesc;
	SecBuffer		OutSecBuff;
	SecBufferDesc	InBuffDesc;
	SecBuffer		InSecBuff;
	ULONG			ContextAttributes;

	if (SEC_STATE_NO_INIT_CONTEXT == pAS->m_Stage)  {
		ss = g_pVars->m_SecurityInterface.AcquireCredentialsHandle (
							NULL,	// principal
							NTLM_PACKAGE_NAME,
							SECPKG_CRED_OUTBOUND,
							NULL,	// LOGON id
							pAuthIdentity,	// auth data
							NULL,	// get key fn
							NULL,	// get key arg
							&pAS->m_hcred,
							&Lifetime
							);
		if (SEC_SUCCESS (ss))
			pAS->m_fHaveCredHandle = TRUE;
		else {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: AcquireCreds failed: %X\n", ss));
			return(FALSE);
		}
	}

	// prepare output buffer
	//
	OutBuffDesc.ulVersion = 0;
	OutBuffDesc.cBuffers = 1;
	OutBuffDesc.pBuffers = &OutSecBuff;

	OutSecBuff.cbBuffer = *pcbOut;
	OutSecBuff.BufferType = SECBUFFER_TOKEN;
	OutSecBuff.pvBuffer = pOut;

	// prepare input buffer
	
	if (SEC_STATE_NO_INIT_CONTEXT != pAS->m_Stage)  {
		InBuffDesc.ulVersion = 0;
		InBuffDesc.cBuffers = 1;
		InBuffDesc.pBuffers = &InSecBuff;

		InSecBuff.cbBuffer = cbIn;
		InSecBuff.BufferType = SECBUFFER_TOKEN;
		InSecBuff.pvBuffer = pIn;
	}

	ss = g_pVars->m_SecurityInterface.InitializeSecurityContext (
						&pAS->m_hcred,
						(pAS->m_Stage == SEC_STATE_PROCESSING) ? &pAS->m_hctxt : NULL,
						NULL,  
						0,	// context requirements
						0,	// reserved1
						SECURITY_NATIVE_DREP,
						(pAS->m_Stage == SEC_STATE_PROCESSING) ?  &InBuffDesc : NULL,
						0,	// reserved2
						&pAS->m_hctxt,
						&OutBuffDesc,
						&ContextAttributes,
						&Lifetime
						);
	if (!SEC_SUCCESS (ss))  {
		DEBUGMSG(ZONE_ERROR,(L"HTTPD: init context failed: %X\n", ss));
		return FALSE;
	}

	pAS->m_fHaveCtxtHandle = TRUE;

	// Complete token -- if applicable
	//
	if ((SEC_I_COMPLETE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss))  {
		if (g_pVars->m_SecurityInterface.CompleteAuthToken) {
			ss = g_pVars->m_SecurityInterface.CompleteAuthToken (&pAS->m_hctxt, &OutBuffDesc);
			if (!SEC_SUCCESS(ss))  {
				DEBUGMSG(ZONE_ERROR,(L"HTTPD: complete failed: %X\n", ss));
				return FALSE;
			}
		}
		else {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Complete not supported.\n"));
			return FALSE;
		}
	}

	*pcbOut = OutSecBuff.cbBuffer;
	pAS->m_Stage = SEC_STATE_PROCESSING;

	return TRUE;
}


// Gets group and user info from NTLM structure after a user has retrieved info.
// Called after a user has been successfully authenticated with either BASIC or NTLM.
// See \winceos\comm\security\authhlp to see ACL algorithm function/description.
void CHttpRequest::GetUserAndGroupInfo(PAUTH_STATE pAuth)
{
	PWSTR wsz = NULL;
	SecPkgContext_Names pkgName;
	pkgName.sUserName = NULL;

#if defined(UNDER_CE)
	SecPkgContext_GroupNames ContextGroups;	
	ContextGroups.msGroupNames = NULL;
	int ccGroupNamesLen = 0; // null delimited string; wcslen won't work!
#endif	

	// If we're called from NTLM request (pAuth != NULL) then we need 
	// to get the user name if we don't have it.  On BASIC request, we
	// have m_wszRemoteUser name already.
	if ((NULL==m_wszRemoteUser) && ! SEC_SUCCESS(g_pVars->m_SecurityInterface.QueryContextAttributes(&(pAuth->m_hctxt),
	                   SECPKG_ATTR_NAMES, &pkgName)))
	{
		DEBUGMSG(ZONE_ERROR,(L"HTTPD: QueryContextAttributes failed, cannot determine user name!\r\n"));
		goto done; 	// If we can't get user name, don't bother continuing
	}

#if defined(UNDER_CE)
	g_pVars->m_SecurityInterface.QueryContextAttributes(&(pAuth->m_hctxt),SECPKG_ATTR_GROUP_NAMES,&ContextGroups);
	// Group list is returned to us a NULL delimited list.  Need to calculate len of this multi-string, wcslen() is out.
	if (ContextGroups.msGroupNames) {
		PWSTR szTrav = ContextGroups.msGroupNames;

		while (*szTrav) {
			szTrav += wcslen(szTrav)+1;
		}
		ccGroupNamesLen = szTrav - ContextGroups.msGroupNames + 1;
	}
#endif
		
	DEBUGMSG(ZONE_AUTH,(L"HTTPD: Admin Users = %s, pkgName.sUserName = %s, group name = %s\r\n",
	         m_pWebsite->m_wszAdminUsers,pkgName.sUserName,ContextGroups.msGroupNames));

done:
	if (pkgName.sUserName) {
		DEBUGCHK(m_wszRemoteUser == NULL);
		m_wszRemoteUser = MySzDupW(pkgName.sUserName);
		g_pVars->m_SecurityInterface.FreeContextBuffer(pkgName.sUserName);
	}
#if defined(UNDER_CE)
	DEBUGCHK(m_wszMemberOf == NULL);

	if (ContextGroups.msGroupNames && (ccGroupNamesLen >1)) {
		m_wszMemberOf = MySzAllocW(ccGroupNamesLen);
		if (m_wszMemberOf) {
			memcpy(m_wszMemberOf,ContextGroups.msGroupNames,ccGroupNamesLen*sizeof(WCHAR));
			DEBUGCHK(m_wszMemberOf[ccGroupNamesLen-1] == 0 && m_wszMemberOf[ccGroupNamesLen-2] == 0); // last 2 bytes should = 0.
		}
	}
	if (ContextGroups.msGroupNames)
		g_pVars->m_SecurityInterface.FreeContextBuffer(ContextGroups.msGroupNames);
#endif
}


AUTHLEVEL CHttpRequest::DeterminePermissionGranted(const WCHAR *wszUserList, AUTHLEVEL authDefault) {
	if (!m_wszRemoteUser) {
		DEBUGMSG(ZONE_AUTH,(L"HTTPD: DeterminePermissionGranted returns default level %d because there's no user\r\n",authDefault));
		return authDefault;
	}

	// Administrators always get admin access and access to the page, even if
	// they're barred in the VRoot list.  If there is a vroot list and we fail
	// the IsAccessAllowed test, we set the auth granted to 0 - this
	// will deny access.  If no VRoot user list is set, keep us at AUTH_USER.
	if (m_pWebsite->m_wszAdminUsers && IsAccessAllowed(m_wszRemoteUser,m_wszMemberOf,m_pWebsite->m_wszAdminUsers,FALSE)) {
		DEBUGMSG(ZONE_AUTH,(L"HTTPD: DeterminePermissionGranted returns AUTH_ADMIN because %s is in admin user list\r\n",m_wszRemoteUser));
		return AUTH_ADMIN;
	}
	else if (wszUserList && IsAccessAllowed(m_wszRemoteUser,m_wszMemberOf,(WCHAR*)wszUserList,FALSE)) {
		DEBUGMSG(ZONE_AUTH,(L"HTTPD: DeterminePermissionGranted returns AUTH_USER because %s is in user list\r\n",m_wszRemoteUser));
		return AUTH_USER;
	}
	else if (wszUserList) {
		DEBUGMSG(ZONE_AUTH,(L"HTTPD: DeterminePermissionGranted returns AUTH_PUBLIC because %s was not in user list\r\n",m_wszRemoteUser));
		return AUTH_PUBLIC;
	}
	else {
		DEBUGMSG(ZONE_AUTH,(L"HTTPD: DeterminePermissionGranted returns default level permission %d because not in Adminlist/userlist\r\n",authDefault));
		return authDefault;
	}
}


⌨️ 快捷键说明

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