drop privileges if running elevated

make sure the Settings process is not running elevated otherwise the WebView control will fail to start
This commit is contained in:
Enrico Giordani 2019-10-03 18:42:18 +02:00 committed by Enrico Giordani
parent 25510b23e1
commit 298a8787d5
3 changed files with 75 additions and 2 deletions

View File

@ -3,7 +3,7 @@
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")
#include <strsafe.h>
#include <sddl.h>
std::optional<RECT> get_button_pos(HWND hwnd) {
RECT button;
@ -37,17 +37,21 @@ HWND get_filtered_active_window() {
static auto shell = GetShellWindow();
auto active_window = GetForegroundWindow();
active_window = GetAncestor(active_window, GA_ROOT);
if (active_window == desktop || active_window == shell) {
return nullptr;
}
auto window_styles = GetWindowLong(active_window, GWL_STYLE);
if ((window_styles & WS_CHILD) || (window_styles & WS_DISABLED)) {
return nullptr;
}
window_styles = GetWindowLong(active_window, GWL_EXSTYLE);
if ((window_styles & WS_EX_TOOLWINDOW) ||(window_styles & WS_EX_NOACTIVATE)) {
return nullptr;
}
char class_name[256] = "";
GetClassNameA(active_window, class_name, 256);
if (strcmp(class_name, "SysListView32") == 0 ||
@ -86,12 +90,14 @@ RECT keep_rect_inside_rect(const RECT& small_rect, const RECT& big_rect) {
result.left -= result.right-big_rect.right;
result.right -= result.right-big_rect.right;
}
if (result.left < big_rect.left) {
// move the rect right.
result.right += big_rect.left-result.left;
result.left += big_rect.left-result.left;
}
}
if ((result.bottom - result.top) > (big_rect.bottom - big_rect.top)) {
// small_rect is too big vertically. resize it.
result.bottom = big_rect.bottom;
@ -102,6 +108,7 @@ RECT keep_rect_inside_rect(const RECT& small_rect, const RECT& big_rect) {
result.top -= result.bottom-big_rect.bottom;
result.bottom -= result.bottom-big_rect.bottom;
}
if (result.top < big_rect.top) {
// move the rect down.
result.bottom += big_rect.top-result.top;
@ -148,19 +155,24 @@ void show_last_error_message(LPCWSTR lpszFunction, DWORD dw) {
WindowState get_window_state(HWND hwnd) {
WINDOWPLACEMENT placement;
placement.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(hwnd, &placement) == 0) {
return UNKNONW;
}
if (placement.showCmd == SW_MINIMIZE || placement.showCmd == SW_SHOWMINIMIZED || IsIconic(hwnd)) {
return MINIMIZED;
}
if (placement.showCmd == SW_MAXIMIZE || placement.showCmd == SW_SHOWMAXIMIZED) {
return MAXIMIZED;
}
auto rectp = get_window_pos(hwnd);
if (!rectp) {
return UNKNONW;
}
auto rect = *rectp;
MONITORINFO monitor;
monitor.cbSize = sizeof(MONITORINFO);
@ -170,11 +182,56 @@ WindowState get_window_state(HWND hwnd) {
bool bottom_left = monitor.rcWork.bottom == rect.bottom && monitor.rcWork.left == rect.left;
bool top_right = monitor.rcWork.top == rect.top && monitor.rcWork.right == rect.right;
bool bottom_right = monitor.rcWork.bottom == rect.bottom && monitor.rcWork.right == rect.right;
if (top_left && bottom_left) return SNAPED_LEFT;
if (top_left) return SNAPED_TOP_LEFT;
if (bottom_left) return SNAPED_BOTTOM_LEFT;
if (top_right && bottom_right) return SNAPED_RIGHT;
if (top_right) return SNAPED_TOP_RIGHT;
if (bottom_right) return SNAPED_BOTTOM_RIGHT;
return RESTORED;
}
bool is_process_elevated() {
HANDLE token = nullptr;
bool elevated = false;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
TOKEN_ELEVATION elevation;
DWORD size;
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size)) {
elevated = (elevation.TokenIsElevated != 0);
}
}
if (token) {
CloseHandle(token);
}
return elevated;
}
bool drop_elevated_privileges() {
HANDLE token = nullptr;
LPCTSTR lpszPrivilege = SE_SECURITY_NAME;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_DEFAULT | WRITE_OWNER, &token)) {
return false;
}
PSID medium_sid = NULL;
if (!::ConvertStringSidToSid(SDDL_ML_MEDIUM, &medium_sid)) {
return false;
}
TOKEN_MANDATORY_LABEL label = { 0 };
label.Label.Attributes = SE_GROUP_INTEGRITY;
label.Label.Sid = medium_sid;
DWORD size = (DWORD)sizeof(TOKEN_MANDATORY_LABEL) + ::GetLengthSid(medium_sid);
BOOL result = SetTokenInformation(token, TokenIntegrityLevel, &label, size);
LocalFree(medium_sid);
CloseHandle(token);
return result;
}

View File

@ -37,3 +37,9 @@ enum WindowState {
RESTORED
};
WindowState get_window_state(HWND hwnd);
// Returns true if the current process is running with elevated privileges
bool is_process_elevated();
// Drops the elevated privilages if present
bool drop_elevated_privileges();

View File

@ -6,6 +6,7 @@
#include <ShellScalingApi.h>
#include "resource.h"
#include <common/dpi_aware.h>
#include <common/common.h>
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "shcore.lib")
@ -424,12 +425,21 @@ void initialize_message_pipe() {
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) {
CoInitialize(nullptr);
if (is_process_elevated()) {
if (!drop_elevated_privileges()) {
MessageBox(NULL, L"Failed to drop admin privileges.\nPlease report the bug to https://github.com/microsoft/PowerToys/issues.", L"PowerToys Settings Error", MB_OK);
}
}
g_hinst = hInstance;
initialize_message_pipe();
register_classes(hInstance);
g_main_wnd = create_main_window(hInstance);
if (g_main_wnd == nullptr) {
MessageBox(NULL, L"Failed to create main window.\nPlease report the bug to https://github.com/microsoft/PowerToys/issues.", L"PowerToys Settings Error", MB_OK);
}
initialize_webview();
WINRT_VERIFY(ShowWindow(g_main_wnd, nShowCmd));
ShowWindow(g_main_wnd, nShowCmd);
// Main message loop.
MSG msg;