
#include"TokenHelper.h"



void DumpTokenPrivileges(HANDLE processToken) {

	// Let's first get the structure size

	DWORD structSize = GetTokenInformationLen(processToken, TokenPrivileges);

	// Lets get'em privileges :) 

	DWORD structSize2;   // should come out of the API with same value as structSize2
	PTOKEN_PRIVILEGES processTokenPrivs;

	processTokenPrivs = (PTOKEN_PRIVILEGES)malloc(structSize);

	if (!GetTokenInformation(processToken, TokenPrivileges, processTokenPrivs, structSize, &structSize2)) {

		ErrorDetails(_T("GetTokenInformation()"), true);
	}

	// Now let us iterate through and dump all privileges

	bool seDebugAvailable = false;
	TCHAR privName[MAX_PRIV_LEN];
	DWORD privNameSize = sizeof(privName);

	_tprintf(_T("\n********************Dumping Privileges********************\n\n"));

	_tprintf(_T("#   Status        Privilege-Name\n\n"));

	for (DWORD x = 0; x < processTokenPrivs->PrivilegeCount; x++) {

		privNameSize = sizeof(privName);

		if (!LookupPrivilegeName(NULL, &processTokenPrivs->Privileges[x].Luid, privName, &privNameSize)) {

			ErrorDetails(_T("LookupPrivilegeName:"), false);
			_tprintf(_T("Required size: %d\n"), privNameSize);
		}
		else {

			if (processTokenPrivs->Privileges[x].Attributes & SE_PRIVILEGE_ENABLED) {

				_tprintf(_T("%3d. Enabled       %s [+]\n"), x+1, privName);
			}
			else {
				_tprintf(_T("%3d. Disabled      %s [-]\n"), x+1, privName);
			}

		}


	}

	_tprintf(_T("\n**********************************************************\n"));

	free(processTokenPrivs);

}



void DumpTokenUser(HANDLE processToken) {

	DWORD infoLen = GetTokenInformationLen(processToken, TokenUser);
	DWORD returnLen;

	PTOKEN_USER tokenUserInfo = (PTOKEN_USER)malloc(infoLen);

	if (!GetTokenInformation(processToken, TokenUser, (LPVOID)tokenUserInfo, infoLen, &returnLen)) {

		ErrorDetails(_T("GetTokenInformation: TokenUser: "), FALSE);
		return;
	}

	_tprintf(_T("\n********************Dumping Token User********************\n\n"));

	PrintSidDetails(tokenUserInfo->User.Sid);

	_tprintf(_T("\n**********************************************************\n\n"));

	free(tokenUserInfo);
}


void DumpTokenGroups(HANDLE processToken) {

	DWORD infoLen = GetTokenInformationLen(processToken, TokenGroups);
	DWORD returnLen;

	PTOKEN_GROUPS tokenGroupsInfo = (PTOKEN_GROUPS)malloc(infoLen);

	if (!GetTokenInformation(processToken, TokenGroups, (LPVOID)tokenGroupsInfo, infoLen, &returnLen)) {

		ErrorDetails(_T("GetTokenInformation: TokenGroups: "), FALSE);
		return;
	}


	_tprintf(_T("\n********************Dumping Token Groups********************\n\n"));

	for (DWORD x = 0; x < tokenGroupsInfo->GroupCount; x++) {

		PrintSidDetails(tokenGroupsInfo->Groups[x].Sid);
		_tprintf(_T("\n"));

	}


	_tprintf(_T("\n**********************************************************\n\n"));

	free(tokenGroupsInfo);
}



void DumpTokenOwner(HANDLE processToken) {

	DWORD infoLen = GetTokenInformationLen(processToken, TokenOwner);
	DWORD returnLen;

	PTOKEN_OWNER tokenOwnerInfo = (PTOKEN_OWNER)malloc(infoLen);

	if (!GetTokenInformation(processToken, TokenOwner, (LPVOID)tokenOwnerInfo, infoLen, &returnLen)) {

		ErrorDetails(_T("GetTokenInformation: TokenOwner: "), FALSE);
		return;
	}

	
	_tprintf(_T("\n********************Dumping Token Owner********************\n\n"));

	PrintSidDetails(tokenOwnerInfo->Owner);

	_tprintf(_T("\n**********************************************************\n\n"));

	free(tokenOwnerInfo);
}


void DumpTokenPrimaryGroup(HANDLE processToken) {

	DWORD infoLen = GetTokenInformationLen(processToken, TokenPrimaryGroup);
	DWORD returnLen;

	PTOKEN_PRIMARY_GROUP tokenPrimaryGroupInfo = (PTOKEN_PRIMARY_GROUP)malloc(infoLen);

	if (!GetTokenInformation(processToken, TokenPrimaryGroup, (LPVOID)tokenPrimaryGroupInfo, infoLen, &returnLen)) {

		ErrorDetails(_T("GetTokenInformation: TokenPrimaryGroup: "), FALSE);
		return;
	}


	_tprintf(_T("\n********************Dumping Token Primary Group********************\n\n"));

	PrintSidDetails(tokenPrimaryGroupInfo->PrimaryGroup);

	_tprintf(_T("\n**********************************************************\n\n"));


	free(tokenPrimaryGroupInfo);
}


void DumpTokenSource(HANDLE processToken) {

	DWORD returnLen;

	PTOKEN_SOURCE tokenSourceInfo = (PTOKEN_SOURCE)malloc(sizeof(TOKEN_SOURCE));

	_tprintf(_T("\n********************Dumping Token Source********************\n\n"));

	if (!GetTokenInformation(processToken, TokenSource, (LPVOID)tokenSourceInfo, sizeof(TOKEN_SOURCE), &returnLen)) {

		ErrorDetails(_T("GetTokenInformation: TokenSource: "), FALSE);
		return;
	}


	_tprintf(_T("Token Source: "));

	for (DWORD m = 0; m < 8; m++) {

		if (tokenSourceInfo->SourceName[m]) {
			_tprintf(_T("%c"), tokenSourceInfo->SourceName[m]);
		}
	}
	_tprintf(_T("\n"));


	_tprintf(_T("\n**********************************************************\n\n"));


	free(tokenSourceInfo);
}


void DumpTokenType(HANDLE processToken) {

	DWORD returnLen;

	PTOKEN_TYPE tokenTypeInfo = (PTOKEN_TYPE)malloc(sizeof(TOKEN_TYPE));

	_tprintf(_T("\n********************Dumping Token Type********************\n\n"));

	if (!GetTokenInformation(processToken, TokenType, (LPVOID)tokenTypeInfo, sizeof(TOKEN_TYPE), &returnLen)) {

		ErrorDetails(_T("GetTokenInformation: TokenType: "), FALSE);
		return;
	}


	_tprintf(_T("Token Type: "));

	if (*tokenTypeInfo == TokenPrimary) {
	
		_tprintf(_T("TokenPrimary\n"));
	}
	else {
		_tprintf(_T("TokenImpersonation"));

		// Let's find the type of Impersonation
		PSECURITY_IMPERSONATION_LEVEL tokenImpersonationLevel = (PSECURITY_IMPERSONATION_LEVEL)malloc(sizeof(SECURITY_IMPERSONATION_LEVEL));
		if (!GetTokenInformation(processToken, TokenImpersonationLevel, (LPVOID)tokenImpersonationLevel, sizeof(TOKEN_TYPE), &returnLen)) {

			ErrorDetails(_T("GetTokenInformation: TokenImpersonationLevel: "), FALSE);
		}
		else {
			switch (*tokenImpersonationLevel) {

					case SecurityAnonymous:
						_tprintf(_T("Impersonation Level: SecurityAnonymous\n"));
						break;

					case SecurityIdentification:
						_tprintf(_T("Impersonation Level: SecurityIdentification\n"));
						break;

					case SecurityImpersonation:
						_tprintf(_T("Impersonation Level: SecurityImpersonation\n"));
						break;

					case SecurityDelegation:
						_tprintf(_T("Impersonation Level: SecurityDelegation\n"));
						break;

			}
		}
	}

	_tprintf(_T("\n**********************************************************\n\n"));


	free(tokenTypeInfo);


}


void DumpTokenElevation(HANDLE processToken) {

	DWORD returnLen;

	PTOKEN_ELEVATION tokenElevationInfo = (PTOKEN_ELEVATION)malloc(sizeof(TOKEN_ELEVATION));

	_tprintf(_T("\n********************Dumping Token Elevation********************\n\n"));

	if (!GetTokenInformation(processToken, TokenElevation, (LPVOID)tokenElevationInfo, sizeof(TOKEN_ELEVATION), &returnLen)) {

		ErrorDetails(_T("GetTokenInformation: TokenElevation: "), FALSE);
		return;
	}

	if (tokenElevationInfo->TokenIsElevated) {

		_tprintf(_T("Token is Elevated: TRUE\n"));
	}
	else {
		_tprintf(_T("Token is Elevated: FALSE\n"));
	}

	_tprintf(_T("\n**********************************************************\n\n"));

	free(tokenElevationInfo);
}