Merge pull request from 21pages/mac

mac admin auth
This commit is contained in:
RustDesk 2023-02-27 09:21:01 +08:00 committed by GitHub
commit 6048efe02b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 37 deletions

@ -1,6 +1,9 @@
#import <AVFoundation/AVFoundation.h>
#import <AppKit/AppKit.h>
#import <IOKit/hidsystem/IOHIDLib.h>
#include <Security/Authorization.h>
#include <Security/AuthorizationTags.h>
// https://github.com/codebytere/node-mac-permissions/blob/main/permissions.mm
@ -35,6 +38,33 @@ extern "C" bool InputMonitoringAuthStatus(bool prompt) {
return false;
}
extern "C" bool MacCheckAdminAuthorization() {
AuthorizationRef authRef;
OSStatus status;
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
kAuthorizationFlagDefaults, &authRef);
if (status != errAuthorizationSuccess) {
printf("Failed to create AuthorizationRef\n");
return false;
}
AuthorizationItem authItem = {kAuthorizationRightExecute, 0, NULL, 0};
AuthorizationRights authRights = {1, &authItem};
AuthorizationFlags flags = kAuthorizationFlagDefaults |
kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagPreAuthorize |
kAuthorizationFlagExtendRights;
status = AuthorizationCopyRights(authRef, &authRights, kAuthorizationEmptyEnvironment, flags, NULL);
if (status != errAuthorizationSuccess) {
printf("Failed to authorize\n");
return false;
}
AuthorizationFree(authRef, kAuthorizationFlagDefaults);
return true;
}
extern "C" float BackingScaleFactor() {
NSScreen* s = [NSScreen mainScreen];
if (s) return [s backingScaleFactor];
@ -44,6 +74,33 @@ extern "C" float BackingScaleFactor() {
// https://github.com/jhford/screenresolution/blob/master/cg_utils.c
// https://github.com/jdoupe/screenres/blob/master/setgetscreen.m
size_t bitDepth(CGDisplayModeRef mode) {
size_t depth = 0;
// Deprecated, same display same bpp?
// https://stackoverflow.com/questions/8210824/how-to-avoid-cgdisplaymodecopypixelencoding-to-get-bpp
// https://github.com/libsdl-org/SDL/pull/6628
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
// my numerical representation for kIO16BitFloatPixels and kIO32bitFloatPixels
// are made up and possibly non-sensical
if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO32BitFloatPixels), kCFCompareCaseInsensitive)) {
depth = 96;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO64BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 64;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO16BitFloatPixels), kCFCompareCaseInsensitive)) {
depth = 48;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 32;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO30BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 30;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 16;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive)) {
depth = 8;
}
CFRelease(pixelEncoding);
return depth;
}
extern "C" bool MacGetModeNum(CGDirectDisplayID display, uint32_t *numModes) {
CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
if (allModes == NULL) {
@ -55,16 +112,28 @@ extern "C" bool MacGetModeNum(CGDirectDisplayID display, uint32_t *numModes) {
}
extern "C" bool MacGetModes(CGDirectDisplayID display, uint32_t *widths, uint32_t *heights, uint32_t max, uint32_t *numModes) {
CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
if (allModes == NULL) {
CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display);
if (currentMode == NULL) {
return false;
}
*numModes = CFArrayGetCount(allModes);
for (uint32_t i = 0; i < *numModes && i < max; i++) {
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
widths[i] = (uint32_t)CGDisplayModeGetWidth(mode);
heights[i] = (uint32_t)CGDisplayModeGetHeight(mode);
CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
if (allModes == NULL) {
CGDisplayModeRelease(currentMode);
return false;
}
uint32_t allModeCount = CFArrayGetCount(allModes);
uint32_t realNum = 0;
for (uint32_t i = 0; i < allModeCount && realNum < max; i++) {
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
if (CGDisplayModeGetRefreshRate(currentMode) == CGDisplayModeGetRefreshRate(mode) &&
bitDepth(currentMode) == bitDepth(mode)) {
widths[realNum] = (uint32_t)CGDisplayModeGetWidth(mode);
heights[realNum] = (uint32_t)CGDisplayModeGetHeight(mode);
realNum++;
}
}
*numModes = realNum;
CGDisplayModeRelease(currentMode);
CFRelease(allModes);
return true;
}
@ -80,31 +149,8 @@ extern "C" bool MacGetMode(CGDirectDisplayID display, uint32_t *width, uint32_t
return true;
}
size_t bitDepth(CGDisplayModeRef mode) {
size_t depth = 0;
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
// my numerical representation for kIO16BitFloatPixels and kIO32bitFloatPixels
// are made up and possibly non-sensical
if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO32BitFloatPixels), kCFCompareCaseInsensitive)) {
depth = 96;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO64BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 64;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO16BitFloatPixels), kCFCompareCaseInsensitive)) {
depth = 48;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 32;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO30BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 30;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 16;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive)) {
depth = 8;
}
CFRelease(pixelEncoding);
return depth;
}
bool setDisplayToMode(CGDirectDisplayID display, CGDisplayModeRef mode) {
static bool setDisplayToMode(CGDirectDisplayID display, CGDisplayModeRef mode) {
CGError rc;
CGDisplayConfigRef config;
rc = CGBeginDisplayConfiguration(&config);
@ -122,7 +168,6 @@ bool setDisplayToMode(CGDirectDisplayID display, CGDisplayModeRef mode) {
return true;
}
extern "C" bool MacSetMode(CGDirectDisplayID display, uint32_t width, uint32_t height)
{
bool ret = false;
@ -140,8 +185,8 @@ extern "C" bool MacSetMode(CGDirectDisplayID display, uint32_t width, uint32_t h
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
if (width == CGDisplayModeGetWidth(mode) &&
height == CGDisplayModeGetHeight(mode) &&
bitDepth(currentMode) == bitDepth(mode) &&
CGDisplayModeGetRefreshRate(currentMode) == CGDisplayModeGetRefreshRate(mode)) {
CGDisplayModeGetRefreshRate(currentMode) == CGDisplayModeGetRefreshRate(mode) &&
bitDepth(currentMode) == bitDepth(mode)) {
ret = setDisplayToMode(display, mode);
break;
}

@ -34,6 +34,7 @@ extern "C" {
static kAXTrustedCheckOptionPrompt: CFStringRef;
fn AXIsProcessTrustedWithOptions(options: CFDictionaryRef) -> BOOL;
fn InputMonitoringAuthStatus(_: BOOL) -> BOOL;
fn MacCheckAdminAuthorization() -> BOOL;
fn MacGetModeNum(display: u32, numModes: *mut u32) -> BOOL;
fn MacGetModes(
display: u32,
@ -665,3 +666,10 @@ pub fn change_resolution(name: &str, width: usize, height: usize) -> ResultType<
}
Ok(())
}
pub fn check_super_user_permission() -> ResultType<bool> {
unsafe {
Ok(MacCheckAdminAuthorization() == YES)
}
}

@ -707,10 +707,10 @@ pub fn is_root() -> bool {
pub fn check_super_user_permission() -> bool {
#[cfg(feature = "flatpak")]
return true;
#[cfg(any(windows, target_os = "linux"))]
#[cfg(any(windows, target_os = "linux", target_os = "macos"))]
return crate::platform::check_super_user_permission().unwrap_or(false);
#[cfg(not(any(windows, target_os = "linux")))]
true
#[cfg(not(any(windows, target_os = "linux", target_os = "macos")))]
return true;
}
#[allow(dead_code)]