def createVideoWindow(self, media_player): videoWidget = QtGui.QMacCocoaViewContainer(None) self.videoLayout.addWidget(videoWidget) videoView = VLCVideoView.alloc().init() videoWidget.setCocoaView(sip.voidptr(objc.pyobjc_id(videoView))) media_player.set_nsobject(objc.pyobjc_id(videoView)) videoView.release()
def createVideoWindow(self,media_player): videoWidget = QtGui.QMacCocoaViewContainer(None) self.videoLayout.addWidget(videoWidget) videoView = VLCVideoView.alloc().init() videoWidget.setCocoaView(sip.voidptr(objc.pyobjc_id(videoView))) media_player.set_nsobject(objc.pyobjc_id(videoView)) videoView.release()
def do_prepare(self): """Prepare an item of content for display.""" window = VLCWindow.alloc().init() window.set_presentation_delegate(FadingPresentationDelegate()) self.set_window(window) self.vlc_view = AppKit.NSView.alloc().initWithFrame_( Foundation.NSZeroRect) self.vlc_instance = libvlc.Instance(b"vlc", b"--no-video-title-show") self.vlc_media = self.vlc_instance.media_new(self.uri) self.vlc_player = self.vlc_instance.media_player_new() self.vlc_player.set_media(self.vlc_media) self.vlc_player.set_nsobject(objc.pyobjc_id(self.vlc_view)) self.vlc_player.video_set_deinterlace(b"interlaced") # This doesn't really belong here... if ("layout_style" in self.params and self.params["layout_style"] == "x_y_width_height"): layout_delegate = XYWidthHeightLayoutDelegate( int(self.params["layout_x"]), int(self.params["layout_y"]), int(self.params["layout_width"]), int(self.params["layout_height"])) self.get_window().set_layout_delegate(layout_delegate) self.get_window().setContentView_(self.vlc_view) # Make the background black background_nscolour = AppKit.NSColor.\ colorWithCalibratedRed_green_blue_alpha_(0, 0, 0, 1) self.get_window().setBackgroundColor_(background_nscolour)
def SecStaticCodeCreateWithPath(cls, file_path): """Call Security Framework's SecStaticCodeCreateWithPath method. Args: file_path: fully qualified file path Returns: A SecStaticCodeRef wrapped with a CFTypeWrapper """ if isinstance(file_path, unicode): file_path = file_path.encode(encoding='utf-8', errors='ignore') # file_path as NSString file_path = Foundation.NSString.stringWithUTF8String_(file_path) # file_path with spaces escaped file_path = file_path.stringByAddingPercentEscapesUsingEncoding_(Foundation.NSUTF8StringEncoding).encode('utf-8') # init file_path as url path = Foundation.NSURL.URLWithString_(Foundation.NSString.stringWithUTF8String_(file_path)) # pointer for static code static_code = ctypes.c_void_p(0) # create static code from path and check result = cls.SEC_DLL.SecStaticCodeCreateWithPath(ctypes.c_void_p(objc.pyobjc_id(path)), cls.kSecCSDefaultFlags, ctypes.byref(static_code)) if cls.errSecSuccess != result: raise cls.SystemCallError('SecStaticCodeCreateWithPath', result) return cls.CFTypeWrapper(static_code)
def get_window_handle(self): if MAC: # Do not use self.winfo_id() on Mac, because of these issues: # 1. Window id sometimes has an invalid negative value (Issue #308). # 2. Even with valid window id it crashes during the call to NSView.setAutoresizingMask: # https://github.com/cztomczak/cefpython/issues/309#issuecomment-661094466 # # To fix it using PyObjC package to obtain window handle. If you change structure of windows then you # need to do modifications here as well. # # There is still one issue with this solution. Sometimes there is more than one window, for example when application # didn't close cleanly last time Python displays an NSAlert window asking whether to Reopen that window. In such # case app will crash and you will see in console: # > Fatal Python error: PyEval_RestoreThread: NULL tstate # > zsh: abort python tkinter_.py # Error messages related to this: https://github.com/cztomczak/cefpython/issues/441 # # There is yet another issue that might be related as well: # https://github.com/cztomczak/cefpython/issues/583 # noinspection PyUnresolvedReferences from AppKit import NSApp # noinspection PyUnresolvedReferences import objc logger.info("winfo_id={}".format(self.winfo_id())) # noinspection PyUnresolvedReferences content_view = objc.pyobjc_id(NSApp.windows()[-1].contentView()) logger.info("content_view={}".format(content_view)) return content_view elif self.winfo_id() > 0: return self.winfo_id() else: raise Exception("Couldn't obtain window handle")
def StringToCFString(string): # we'll need to convert our strings before use try: encoding = CoreFoundation.kCFStringEncodingASCII except AttributeError: encoding = 0x600 cfstring = CoreFoundation.CFStringCreateWithCString(None, string, encoding) return objc.pyobjc_id(cfstring.nsstring())
def get_window_handle(self): if self.winfo_id() > 0: return self.winfo_id() elif platform.system() == "Darwin": from AppKit import NSApp import objc return objc.pyobjc_id(NSApp.windows()[-1].contentView()) else: raise Exception("Couldn't obtain window handle")
def test_voidp_roundtrip(self): arr = objc.lookUpClass('NSArray').array() p = arr.__c_void_p__() self.assertIsInstance(p, ctypes.c_void_p) self.assertEqual(p.value, objc.pyobjc_id(arr)) v = objc.objc_object(c_void_p=p) self.assertIs(v, arr)
def test_voidp_using_ctypes(self): lib = ctypes.CDLL('/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation') func = lib.CFStringCreateWithCString func.restype = ctypes.c_void_p func.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int] kCFStringEncodingISOLatin1 = 0x0201 ct_obj = func(None, b"hello world", kCFStringEncodingISOLatin1) value = objc.objc_object(c_void_p=ct_obj) self.assertIsInstance(value, objc.pyobjc_unicode) self.assertEqual(objc.pyobjc_id(value.nsstring()), ct_obj)
def _get_application_hwnd(self) -> int: """ This finds the blender application window and collects the handler window ID Returns int: Handler Window ID """ # Check to ensure ns_window is set if self._ns_window is None: self._ns_window = self.__get_application_window() return objc.pyobjc_id(self._ns_window.contentView())
def test_voidp_using_ctypes(self): lib = ctypes.CDLL( '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation' ) func = lib.CFStringCreateWithCString func.restype = ctypes.c_void_p func.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int] kCFStringEncodingISOLatin1 = 0x0201 ct_obj = func(None, b"hello world", kCFStringEncodingISOLatin1) value = objc.objc_object(c_void_p=ct_obj) self.assertIsInstance(value, objc.pyobjc_unicode) self.assertEqual(objc.pyobjc_id(value.nsstring()), ct_obj)
def _load_client_cert_chain(_, name, *paths): """Load certs by SN from keychain rather than by path If multiple certs are found which contain the provided name, the one that has an exactly equivalent CN, and with the latest "not valid after" date will be chosen. Args: _ (keychain): Unused; here to support injecting into existing code. name (str): CN to match. paths: Any number of str paths, only the first of which will be used. Returns: CFMutableArray """ # Create an array to return trust_chain = CoreFoundation.CFArrayCreateMutable( CoreFoundation.kCFAllocatorDefault, 0, byref(CoreFoundation.kCFTypeArrayCallBacks),) query = { kSecClass: kSecClassIdentity, kSecMatchLimit: kSecMatchLimitAll, kSecMatchSubjectContains: name, kSecReturnRef: True, } error, results = SecItemCopyMatching(query, None) if error == errSecSuccess: candidates = [] for identity in results: error, cert_ref = SecIdentityCopyCertificate(identity, None) if error == errSecSuccess: cert_info, error = SecCertificateCopyValues(cert_ref, None, None) if error is None and _get_cn(cert_info) == name: not_valid_after = cert_info[kSecOIDX509V1ValidityNotAfter]['value'] candidates.append((not_valid_after, identity)) try: current_identity = sorted(candidates, key=itemgetter(0))[-1][1] CoreFoundation.CFArrayAppendValue(trust_chain, objc.pyobjc_id(current_identity)) except IndexError: # No candidates matched. pass return trust_chain
def get_window_handle(self): if self.winfo_id() > 0: return self.winfo_id() elif MAC: # On Mac window id is an invalid negative value (Issue #308). # This is kind of a dirty hack to get window handle using # PyObjC package. If you change structure of windows then you # need to do modifications here as well. # noinspection PyUnresolvedReferences from AppKit import NSApp # noinspection PyUnresolvedReferences import objc # Sometimes there is more than one window, when application # didn't close cleanly last time Python displays an NSAlert # window asking whether to Reopen that window. # noinspection PyUnresolvedReferences return objc.pyobjc_id(NSApp.windows()[-1].contentView()) else: raise Exception("Couldn't obtain window handle")
def StrToCFString(string): """Creates a CFString from a Python string. Inspired by Michael Lynn's power management wrapper: https://github.com/pudquick/pypmset/blob/master/pypmset.py Args: string: str, a regular Python string Returns: CFStringRef for CreatePowerAssertion() Raises: MissingImportsError: if CFStringCreateWithCString is missing """ if CFStringCreateWithCString and kCFStringEncodingASCII: return objc.pyobjc_id(CFStringCreateWithCString( None, string, kCFStringEncodingASCII).nsstring()) else: raise MissingImportsError( 'CFStringCreateWithCString or kCFStringEncodingASCII ' 'not imported successfully.')
def objc_setClass(obj, clazz): objAddr = objc.pyobjc_id(obj) # returns the addr and also ensures that it is an objc object assert objAddr != 0 import ctypes ctypes.pythonapi.objc_lookUpClass.restype = ctypes.c_void_p ctypes.pythonapi.objc_lookUpClass.argtypes = (ctypes.c_char_p,) className = clazz.__name__ # this should be correct I guess classAddr = ctypes.pythonapi.objc_lookUpClass(className) assert classAddr != 0 # Class object_setClass(id object, Class cls) ctypes.pythonapi.object_setClass.restype = ctypes.c_void_p ctypes.pythonapi.object_setClass.argtypes = (ctypes.c_void_p,ctypes.c_void_p) ctypes.pythonapi.object_setClass(objAddr, classAddr) obj.__class__ = clazz
def checkSignature(file, bundle=None): #global security framework 'handle' global securityFramework #global objcRuntime 'handle' global objcRuntime #return dictionary signingInfo = {} sigCheckFlags = kSecCSStrictValidate_kSecCSCheckAllArchitectures_kSecCSCheckNestedCode #status # ->just related to execution (e.g. API errors) status = not errSecSuccess #signed status of file signedStatus = None #flag indicating is from Apple isApple = False #list of authorities authorities = [] #load security framework if not securityFramework: #load and check securityFramework = ctypes.cdll.LoadLibrary(SECURITY_FRAMEWORK) if not securityFramework: #err msg logMessage(MODE_ERROR, 'could not load securityFramework') #bail return (status, None) #load objC runtime lib if not objcRuntime: #load and check objcRuntime = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc')) if not objcRuntime: #err msg logMessage(MODE_ERROR, 'could not load objcRuntime library') #bail return (status, None) #init objc_getClass function's return types objcRuntime.objc_getClass.restype = ctypes.c_void_p #init sel_registerName function's return types objcRuntime.sel_registerName.restype = ctypes.c_void_p #file as NSString file = Foundation.NSString.stringWithUTF8String_(file) #file with spaces escaped file = file.stringByAddingPercentEscapesUsingEncoding_( Foundation.NSUTF8StringEncoding).encode('utf-8') #init file as url path = Foundation.NSURL.URLWithString_( Foundation.NSString.stringWithUTF8String_(file)) #pointer for static code staticCode = ctypes.c_void_p(0) #create static code from path and check result = securityFramework.SecStaticCodeCreateWithPath( ctypes.c_void_p(objc.pyobjc_id(path)), kSecCSDefaultFlags, ctypes.byref(staticCode)) if errSecSuccess != result: #supress flag # ->for for non-r00t users want to supresss this error shouldSupress = False #when user isn't r00t and error is accessed denied # ->treat error as just an info warning (addresses issue of '/usr/sbin/cupsd') if (0 != os.geteuid()) and (result == kPOSIXErrorEACCES): #supress in non-verbose mode # ->overrides default behavior of MODE_WARN shouldSupress = True #dbg msg # ->note: uses log mode logMessage( MODE_ERROR, 'SecStaticCodeCreateWithPath(\'%s\') failed with %d' % (path, result), shouldSupress) #bail return (status, None) #check signature signedStatus = securityFramework.SecStaticCodeCheckValidityWithErrors( staticCode, sigCheckFlags, None, None) #make sure binary is signed # ->then, determine if signed by apple & always extract signing authorities if errSecSuccess == signedStatus: #set requirement string # ->check for 'signed by apple' requirementReference = "anchor apple" #get NSString class NSString = objcRuntime.objc_getClass('NSString') #init return type for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p ] #init key via 'stringWithUTF8String:' method requirementsString = objcRuntime.objc_msgSend( NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), requirementReference) #pointer for requirement requirement = ctypes.c_void_p(0) #first check if binary is signed by Apple # ->create sec requirement if errSecSuccess == securityFramework.SecRequirementCreateWithString( ctypes.c_void_p(requirementsString), kSecCSDefaultFlags, ctypes.byref(requirement)): #verify against requirement signature if errSecSuccess == securityFramework.SecStaticCodeCheckValidity( staticCode, sigCheckFlags, requirement): #signed by apple isApple = True #pointer for info dictionary information = ctypes.c_void_p(0) #get code signing info, including authorities and check result = securityFramework.SecCodeCopySigningInformation( staticCode, kSecCSSigningInformation, ctypes.byref(information)) #check result if errSecSuccess != result: #err msg logMessage( MODE_ERROR, 'SecCodeCopySigningInformation() failed with %d' % result) #bail return (status, None) #init return type for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p ] #init key via 'stringWithUTF8String:' method key = objcRuntime.objc_msgSend( NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), kSecCodeInfoCertificates) #init return type for 'objectForKey:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'objectForKey:' method objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p ] #get cert chain from dictionary # ->returns NSArray certChain = objcRuntime.objc_msgSend( information, objcRuntime.sel_registerName('objectForKey:'), key) #init return type for 'count:' method objcRuntime.objc_msgSend.restype = ctypes.c_uint #init arg types for 'count' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p] #get number of items in array count = objcRuntime.objc_msgSend(certChain, objcRuntime.sel_registerName('count')) #init pointer for cert name(s) certName = ctypes.c_char_p(0) #get all certs for index in range(count): #init return type for 'objectAtIndex:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'objectAtIndex:' method objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint ] #extract cert from array cert = objcRuntime.objc_msgSend( certChain, objcRuntime.sel_registerName('objectAtIndex:'), index) #get cert's common name and check result = securityFramework.SecCertificateCopyCommonName( ctypes.c_void_p(cert), ctypes.byref(certName)) if errSecSuccess != result: #just try next continue #init return type for 'UTF8String' method objcRuntime.objc_msgSend.restype = ctypes.c_char_p #init arg types for 'UTF8String' method objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p ] #extract cert name and append to list # ->this is the authority authorities.append( objcRuntime.objc_msgSend( certName, objcRuntime.sel_registerName('UTF8String'))) #TODO: CFRelease information #no errors # ->might be unsigned though status = errSecSuccess #save signed status signingInfo['status'] = signedStatus #save flag indicating file signed by apple signingInfo['isApple'] = isApple #save signing authorities signingInfo['authorities'] = authorities return (status, signingInfo)
def raw_ptr(pyobjc_string): return pyobjc_id(pyobjc_string.nsstring())
def checkSignature(file, bundle=None): SECURITY_FRAMEWORK = '/System/Library/Frameworks/Security.framework/Versions/Current/Security' kSecCSDefaultFlags = 0x0 kSecCSDoNotValidateResources = 0x4 kSecCSCheckAllArchitectures = 0x1 kSecCSCheckNestedCode = 0x8 kSecCSStrictValidate = 0x16 kSecCSStrictValidate_kSecCSCheckAllArchitectures = 0x17 kSecCSStrictValidate_kSecCSCheckAllArchitectures_kSecCSCheckNestedCode = 0x1f errSecSuccess = 0x0 SecCSSignatureOK = errSecSuccess errSecCSUnsigned = -67062 kPOSIXErrorEACCES = 100013 kSecCSSigningInformation = 0x2 kSecCodeInfoCertificates = 'certificates' #return dictionary signingInfo = {} sigCheckFlags = kSecCSStrictValidate_kSecCSCheckAllArchitectures_kSecCSCheckNestedCode securityFramework = ctypes.cdll.LoadLibrary(SECURITY_FRAMEWORK) objcRuntime = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc')) objcRuntime.objc_getClass.restype = ctypes.c_void_p objcRuntime.sel_registerName.restype = ctypes.c_void_p status = not errSecSuccess signedStatus = None isApple = False authorities = [] file = Foundation.NSString.stringWithString_(file) file = file.stringByAddingPercentEscapesUsingEncoding_( Foundation.NSUTF8StringEncoding).encode('utf-8') path = Foundation.NSURL.URLWithString_( Foundation.NSString.stringWithUTF8String_(file)) staticCode = ctypes.c_void_p(0) result = securityFramework.SecStaticCodeCreateWithPath( ctypes.c_void_p(objc.pyobjc_id(path)), kSecCSDefaultFlags, ctypes.byref(staticCode)) signedStatus = securityFramework.SecStaticCodeCheckValidityWithErrors( staticCode, sigCheckFlags, None, None) if errSecSuccess == signedStatus: requirementReference = "anchor apple" NSString = objcRuntime.objc_getClass('NSString') objcRuntime.objc_msgSend.restype = ctypes.c_void_p objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p ] requirementsString = objcRuntime.objc_msgSend( NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), requirementReference) requirement = ctypes.c_void_p(0) if errSecSuccess == securityFramework.SecRequirementCreateWithString( ctypes.c_void_p(requirementsString), kSecCSDefaultFlags, ctypes.byref(requirement)): if errSecSuccess == securityFramework.SecStaticCodeCheckValidity( staticCode, sigCheckFlags, requirement): isApple = True information = ctypes.c_void_p(0) result = securityFramework.SecCodeCopySigningInformation( staticCode, kSecCSSigningInformation, ctypes.byref(information)) objcRuntime.objc_msgSend.restype = ctypes.c_void_p objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p ] key = objcRuntime.objc_msgSend( NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), kSecCodeInfoCertificates) objcRuntime.objc_msgSend.restype = ctypes.c_void_p objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p ] certChain = objcRuntime.objc_msgSend( information, objcRuntime.sel_registerName('objectForKey:'), key) objcRuntime.objc_msgSend.restype = ctypes.c_uint objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p] count = objcRuntime.objc_msgSend(certChain, objcRuntime.sel_registerName('count')) certName = ctypes.c_char_p(0) for index in range(count): objcRuntime.objc_msgSend.restype = ctypes.c_void_p objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint ] cert = objcRuntime.objc_msgSend( certChain, objcRuntime.sel_registerName('objectAtIndex:'), index) result = securityFramework.SecCertificateCopyCommonName( ctypes.c_void_p(cert), ctypes.byref(certName)) if errSecSuccess != result: continue objcRuntime.objc_msgSend.restype = ctypes.c_char_p objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p ] authorities.append( objcRuntime.objc_msgSend( certName, objcRuntime.sel_registerName('UTF8String'))) status = errSecSuccess if signedStatus == 0: signingInfo['status'] = "signed" else: signingInfo['status'] = "unsigned" signingInfo['apple_binary'] = isApple signingInfo['Authority'] = authorities return (signingInfo)
if args in memo: return memo[args] else: memo[args] = function(*args) return memo[args] return wrapper @memoize def C(name): return objc_getClass(name) @memoize def S(name): return sel_registerName(name) def send(obj, sel, param=None): return objc_msgSend(obj, sel, param) temp_array = NSMutableArray.array() # get the raw pointer of the class object raw_temp_array = objc.pyobjc_id(temp_array) # Add the db_buffer pointer to the array result = send(raw_temp_array, S(b'addObject:'), db_buffer) # Get the object back from the other side! ctypes_o = temp_array[0]
def raw_ptr(self, pyobjc_string): return objc.pyobjc_id(pyobjc_string.nsstring())
def _rawPointer(pyobjc_string): """Returns a pointer to a CFString.""" return pyobjc_id(pyobjc_string.nsstring())
def checkSignature(file, bundle=None): #global security framework 'handle' global securityFramework #global objcRuntime 'handle' global objcRuntime #status # ->just related to execution (e.g. API errors) status = not errSecSuccess #signed status of file signedStatus = None #list of authorities authorities = [] #load security framework if not securityFramework: #load and check securityFramework = ctypes.cdll.LoadLibrary(SECURITY_FRAMEWORK) if not securityFramework: #err msg logMessage(MODE_ERROR, 'could not load securityFramework') #bail return (status, None, None) #load objC runtime lib if not objcRuntime: #load and check objcRuntime = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc')) if not objcRuntime: #err msg logMessage(MODE_ERROR, 'could not load objcRuntime library') #bail return (status, None, None) #init objc_getClass function's return types objcRuntime.objc_getClass.restype = ctypes.c_void_p #init sel_registerName function's return types objcRuntime.sel_registerName.restype = ctypes.c_void_p #file as NSString file = Foundation.NSString.stringWithUTF8String_(file) #file with spaces escaped file = file.stringByAddingPercentEscapesUsingEncoding_(Foundation.NSUTF8StringEncoding).encode('utf-8') #init file as url path = Foundation.NSURL.URLWithString_(Foundation.NSString.stringWithUTF8String_(file)) #pointer for static code staticCode = ctypes.c_void_p(0) #ctypes.c_uint64(0) #create static code from path and check result = securityFramework.SecStaticCodeCreateWithPath(ctypes.c_void_p(objc.pyobjc_id(path)), kSecCSDefaultFlags, ctypes.byref(staticCode)) if errSecSuccess != result: #error logMessage(MODE_ERROR, 'SecStaticCodeCreateWithPath() failed with %d' % result) #bail return (status, None, None) #checking the signature of a kext requires the use of a requirement string # ->initialize this based on bundle ID # see: checkKextSignature() in security.c (kext_tools) for details '''if bundle and isKext(bundle): #requirement reference # ->used for checking signature of kexts #requirementReference = None #requirement = None #wrap try: #load kext's plist kextPlist = loadPlist(os.path.join(bundle, 'Contents', 'Info.plist')) #extract bundle ID bundleID = kextPlist['CFBundleIdentifier'] #set requirement reference for Apple's kexts if bundleID.startswith(__kOSKextApplePrefix): #set requirementReference = "anchor apple" #set requirement reference for non-Apple's kexts else: #set requirementReference = "anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[field.1.2.840.113635.100.6.1.18]" #get NSString class NSString = objcRuntime.objc_getClass('NSString') #init return type for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] #init key via 'stringWithUTF8String:' method requirementsString = objcRuntime.objc_msgSend(NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), requirementReference) #print 'type of requirementsString' #print type(requirementsString) #pointer for requirement requirement = ctypes.c_void_p(0) #create sec requirement if errSecSuccess != securityFramework.SecRequirementCreateWithString(ctypes.c_void_p(requirementsString), kSecCSDefaultFlags, ctypes.byref(requirement)): #print 'ERROR' pass else: pass #print 'OK' # print 'ERRROR: SecRequirementCreateWithString()' #else: # print 'OK!!' #ignore exceptions except: #ignore pass ''' #print 'securityFramework.SecStaticCodeCheckValidity:', #print securityFramework.SecStaticCodeCheckValidity(staticCode, 1 << 30, None) #check signature signedStatus = securityFramework.SecStaticCodeCheckValidityWithErrors(staticCode, kSecCSDoNotValidateResources, None, None) #make sure binary is signed # ->then, extract signing authorities if errSecSuccess == signedStatus: #print 'File is signed!' #pointer for info dictionary information = ctypes.c_void_p(0) #get code signing info, including authorities and check result = securityFramework.SecCodeCopySigningInformation(staticCode, kSecCSSigningInformation, ctypes.byref(information)) if errSecSuccess != result: #err msg logMessage(MODE_ERROR, 'SecCodeCopySigningInformation() failed with %d' % result) #bail return (status, None, None) #get NSString class NSString = objcRuntime.objc_getClass('NSString') #init return type for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] #init key via 'stringWithUTF8String:' method key = objcRuntime.objc_msgSend(NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), kSecCodeInfoCertificates) #init return type for 'objectForKey:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'objectForKey:' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] #get cert chain from dictionary # ->returns NSArray certChain = objcRuntime.objc_msgSend(information, objcRuntime.sel_registerName('objectForKey:'), key) #init return type for 'count:' method objcRuntime.objc_msgSend.restype = ctypes.c_uint #init arg types for 'count' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p] #get number of items in array count = objcRuntime.objc_msgSend(certChain, objcRuntime.sel_registerName('count')) #init pointer for cert name(s) certName = ctypes.c_char_p(0) #get all certs for index in range(count): #init return type for 'objectAtIndex:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'objectAtIndex:' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint] #extract cert from array cert = objcRuntime.objc_msgSend(certChain, objcRuntime.sel_registerName('objectAtIndex:'), index) #get cert's common name and check result = securityFramework.SecCertificateCopyCommonName(ctypes.c_void_p(cert), ctypes.byref(certName)) if errSecSuccess != result: #just try next continue #init return type for 'UTF8String' method objcRuntime.objc_msgSend.restype = ctypes.c_char_p #init arg types for 'UTF8String' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p] #extract cert name and append to list # ->this is the authority authorities.append(objcRuntime.objc_msgSend(certName, objcRuntime.sel_registerName('UTF8String'))) #TODO: CFRelease information #no errors # ->might be unsigned though status = errSecSuccess return (status, signedStatus, authorities)
def StringToCFString(string): # we'll need to convert our strings before use return objc.pyobjc_id( CF.CFStringCreateWithCString(None, string, CF.kCFStringEncodingASCII).nsstring())
def checkSignature(file, bundle=None): #global security framework 'handle' global securityFramework #global objcRuntime 'handle' global objcRuntime #status # ->just related to execution (e.g. API errors) status = not errSecSuccess #signed status of file signedStatus = None #list of authorities authorities = [] #load security framework if not securityFramework: #load and check securityFramework = ctypes.cdll.LoadLibrary(SECURITY_FRAMEWORK) if not securityFramework: #err msg logMessage(MODE_ERROR, 'could not load securityFramework') #bail return (status, None, None) #load objC runtime lib if not objcRuntime: #load and check objcRuntime = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc')) if not objcRuntime: #err msg logMessage(MODE_ERROR, 'could not load objcRuntime library') #bail return (status, None, None) #init objc_getClass function's return types objcRuntime.objc_getClass.restype = ctypes.c_void_p #init sel_registerName function's return types objcRuntime.sel_registerName.restype = ctypes.c_void_p #file as NSString file = Foundation.NSString.stringWithUTF8String_(file) #file with spaces escaped file = file.stringByAddingPercentEscapesUsingEncoding_( Foundation.NSUTF8StringEncoding).encode('utf-8') #init file as url path = Foundation.NSURL.URLWithString_( Foundation.NSString.stringWithUTF8String_(file)) #pointer for static code staticCode = ctypes.c_void_p(0) #ctypes.c_uint64(0) #create static code from path and check result = securityFramework.SecStaticCodeCreateWithPath( ctypes.c_void_p(objc.pyobjc_id(path)), kSecCSDefaultFlags, ctypes.byref(staticCode)) if errSecSuccess != result: #error logMessage( MODE_ERROR, 'SecStaticCodeCreateWithPath(\'%s\') failed with %d' % (path, result)) #bail return (status, None, None) #checking the signature of a kext requires the use of a requirement string # ->initialize this based on bundle ID # see: checkKextSignature() in security.c (kext_tools) for details '''if bundle and isKext(bundle): #requirement reference # ->used for checking signature of kexts #requirementReference = None #requirement = None #wrap try: #load kext's plist kextPlist = loadPlist(os.path.join(bundle, 'Contents', 'Info.plist')) #extract bundle ID bundleID = kextPlist['CFBundleIdentifier'] #set requirement reference for Apple's kexts if bundleID.startswith(__kOSKextApplePrefix): #set requirementReference = "anchor apple" #set requirement reference for non-Apple's kexts else: #set requirementReference = "anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[field.1.2.840.113635.100.6.1.18]" #get NSString class NSString = objcRuntime.objc_getClass('NSString') #init return type for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] #init key via 'stringWithUTF8String:' method requirementsString = objcRuntime.objc_msgSend(NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), requirementReference) #print 'type of requirementsString' #print type(requirementsString) #pointer for requirement requirement = ctypes.c_void_p(0) #create sec requirement if errSecSuccess != securityFramework.SecRequirementCreateWithString(ctypes.c_void_p(requirementsString), kSecCSDefaultFlags, ctypes.byref(requirement)): #print 'ERROR' pass else: pass #print 'OK' # print 'ERRROR: SecRequirementCreateWithString()' #else: # print 'OK!!' #ignore exceptions except: #ignore pass ''' #print 'securityFramework.SecStaticCodeCheckValidity:', #print securityFramework.SecStaticCodeCheckValidity(staticCode, 1 << 30, None) #check signature signedStatus = securityFramework.SecStaticCodeCheckValidityWithErrors( staticCode, kSecCSDoNotValidateResources, None, None) #make sure binary is signed # ->then, extract signing authorities if errSecSuccess == signedStatus: #print 'File is signed!' #pointer for info dictionary information = ctypes.c_void_p(0) #get code signing info, including authorities and check result = securityFramework.SecCodeCopySigningInformation( staticCode, kSecCSSigningInformation, ctypes.byref(information)) if errSecSuccess != result: #err msg logMessage( MODE_ERROR, 'SecCodeCopySigningInformation() failed with %d' % result) #bail return (status, None, None) #get NSString class NSString = objcRuntime.objc_getClass('NSString') #init return type for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p ] #init key via 'stringWithUTF8String:' method key = objcRuntime.objc_msgSend( NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), kSecCodeInfoCertificates) #init return type for 'objectForKey:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'objectForKey:' method objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p ] #get cert chain from dictionary # ->returns NSArray certChain = objcRuntime.objc_msgSend( information, objcRuntime.sel_registerName('objectForKey:'), key) #init return type for 'count:' method objcRuntime.objc_msgSend.restype = ctypes.c_uint #init arg types for 'count' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p] #get number of items in array count = objcRuntime.objc_msgSend(certChain, objcRuntime.sel_registerName('count')) #init pointer for cert name(s) certName = ctypes.c_char_p(0) #get all certs for index in range(count): #init return type for 'objectAtIndex:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'objectAtIndex:' method objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint ] #extract cert from array cert = objcRuntime.objc_msgSend( certChain, objcRuntime.sel_registerName('objectAtIndex:'), index) #get cert's common name and check result = securityFramework.SecCertificateCopyCommonName( ctypes.c_void_p(cert), ctypes.byref(certName)) if errSecSuccess != result: #just try next continue #init return type for 'UTF8String' method objcRuntime.objc_msgSend.restype = ctypes.c_char_p #init arg types for 'UTF8String' method objcRuntime.objc_msgSend.argtypes = [ ctypes.c_void_p, ctypes.c_void_p ] #extract cert name and append to list # ->this is the authority authorities.append( objcRuntime.objc_msgSend( certName, objcRuntime.sel_registerName('UTF8String'))) #TODO: CFRelease information #no errors # ->might be unsigned though status = errSecSuccess return (status, signedStatus, authorities)
def set_string(event, s): buf = s.encode(native_utf16) CGEventKeyboardSetUnicodeString(objc.pyobjc_id(event), len(buf) / 2, buf)
def StringToCFString(string): # we'll need to convert our strings before use return objc.pyobjc_id( CoreFoundation.CFStringCreateWithCString( None, string, CoreFoundation.kCFStringEncodingASCII).nsstring())
def StringToCFString(string): # we'll need to convert our strings before use encoding = CoreFoundation.kCFStringEncodingASCII cfstring = CoreFoundation.CFStringCreateWithCString(None, string, encoding) return objc.pyobjc_id(cfstring.nsstring())
def raw_ptr(obj): '''Get pyobjc CFString raw pointer to pass it to IOKit functions via ctypes''' return pyobjc_id(obj.nsstring())
def checkSignature(file, bundle=None): #global security framework 'handle' global securityFramework #global objcRuntime 'handle' global objcRuntime #return dictionary signingInfo = {} sigCheckFlags = kSecCSStrictValidate_kSecCSCheckAllArchitectures_kSecCSCheckNestedCode #status # ->just related to execution (e.g. API errors) status = not errSecSuccess #signed status of file signedStatus = None #flag indicating is from Apple isApple = False #list of authorities authorities = [] #load security framework if not securityFramework: #load and check securityFramework = ctypes.cdll.LoadLibrary(SECURITY_FRAMEWORK) if not securityFramework: #err msg logMessage(MODE_ERROR, 'could not load securityFramework') #bail return (status, None) #load objC runtime lib if not objcRuntime: #load and check objcRuntime = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc')) if not objcRuntime: #err msg logMessage(MODE_ERROR, 'could not load objcRuntime library') #bail return (status, None) #init objc_getClass function's return types objcRuntime.objc_getClass.restype = ctypes.c_void_p #init sel_registerName function's return types objcRuntime.sel_registerName.restype = ctypes.c_void_p #file as NSString file = Foundation.NSString.stringWithUTF8String_(file) #file with spaces escaped file = file.stringByAddingPercentEscapesUsingEncoding_(Foundation.NSUTF8StringEncoding).encode('utf-8') #init file as url path = Foundation.NSURL.URLWithString_(Foundation.NSString.stringWithUTF8String_(file)) #pointer for static code staticCode = ctypes.c_void_p(0) #create static code from path and check result = securityFramework.SecStaticCodeCreateWithPath(ctypes.c_void_p(objc.pyobjc_id(path)), kSecCSDefaultFlags, ctypes.byref(staticCode)) if errSecSuccess != result: #supress flag # ->for for non-r00t users want to supresss this error shouldSupress = False #when user isn't r00t and error is accessed denied # ->treat error as just an info warning (addresses issue of '/usr/sbin/cupsd') if (0 != os.geteuid()) and (result == kPOSIXErrorEACCES): #supress in non-verbose mode # ->overrides default behavior of MODE_WARN shouldSupress = True #dbg msg # ->note: uses log mode logMessage(MODE_ERROR, 'SecStaticCodeCreateWithPath(\'%s\') failed with %d' % (path, result), shouldSupress) #bail return (status, None) #check signature signedStatus = securityFramework.SecStaticCodeCheckValidityWithErrors(staticCode, sigCheckFlags, None, None) #make sure binary is signed # ->then, determine if signed by apple & always extract signing authorities if errSecSuccess == signedStatus: #set requirement string # ->check for 'signed by apple' requirementReference = "anchor apple" #get NSString class NSString = objcRuntime.objc_getClass('NSString') #init return type for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] #init key via 'stringWithUTF8String:' method requirementsString = objcRuntime.objc_msgSend(NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), requirementReference) #pointer for requirement requirement = ctypes.c_void_p(0) #first check if binary is signed by Apple # ->create sec requirement if errSecSuccess == securityFramework.SecRequirementCreateWithString(ctypes.c_void_p(requirementsString), kSecCSDefaultFlags, ctypes.byref(requirement)): #verify against requirement signature if errSecSuccess == securityFramework.SecStaticCodeCheckValidity(staticCode, sigCheckFlags, requirement): #signed by apple isApple = True #pointer for info dictionary information = ctypes.c_void_p(0) #get code signing info, including authorities and check result = securityFramework.SecCodeCopySigningInformation(staticCode, kSecCSSigningInformation, ctypes.byref(information)) #check result if errSecSuccess != result: #err msg logMessage(MODE_ERROR, 'SecCodeCopySigningInformation() failed with %d' % result) #bail return (status, None) #init return type for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'stringWithUTF8String:' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] #init key via 'stringWithUTF8String:' method key = objcRuntime.objc_msgSend(NSString, objcRuntime.sel_registerName('stringWithUTF8String:'), kSecCodeInfoCertificates) #init return type for 'objectForKey:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'objectForKey:' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] #get cert chain from dictionary # ->returns NSArray certChain = objcRuntime.objc_msgSend(information, objcRuntime.sel_registerName('objectForKey:'), key) #init return type for 'count:' method objcRuntime.objc_msgSend.restype = ctypes.c_uint #init arg types for 'count' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p] #get number of items in array count = objcRuntime.objc_msgSend(certChain, objcRuntime.sel_registerName('count')) #init pointer for cert name(s) certName = ctypes.c_char_p(0) #get all certs for index in range(count): #init return type for 'objectAtIndex:' method objcRuntime.objc_msgSend.restype = ctypes.c_void_p #init arg types for 'objectAtIndex:' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint] #extract cert from array cert = objcRuntime.objc_msgSend(certChain, objcRuntime.sel_registerName('objectAtIndex:'), index) #get cert's common name and check result = securityFramework.SecCertificateCopyCommonName(ctypes.c_void_p(cert), ctypes.byref(certName)) if errSecSuccess != result: #just try next continue #init return type for 'UTF8String' method objcRuntime.objc_msgSend.restype = ctypes.c_char_p #init arg types for 'UTF8String' method objcRuntime.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p] #extract cert name and append to list # ->this is the authority authorities.append(objcRuntime.objc_msgSend(certName, objcRuntime.sel_registerName('UTF8String'))) #TODO: CFRelease information #no errors # ->might be unsigned though status = errSecSuccess #save signed status signingInfo['status'] = signedStatus #save flag indicating file signed by apple signingInfo['isApple'] = isApple #save signing authorities signingInfo['authorities'] = authorities return (status, signingInfo)
def addMatchingNotifications(self, matching, receiver): '''Rich IOServiceAddMatchingNotification_ wrapper Look up registered IOService objects that match a matching dictionary, and hooks notification requests to specially named methods on receiver. +------------------+-------------------------------+ |Method Name |Notification Type | +==================+===============================+ |`on_publish` |``kIOPublishNotification`` | +------------------+-------------------------------+ |`on_first_publish`|``kIOFirstPublishNotification``| +------------------+-------------------------------+ |`on_match` |``kIOMatchedNotification`` | +------------------+-------------------------------+ |`on_first_match` |``kIOFirstMatchNotification`` | +------------------+-------------------------------+ |`on_terminate` |``kIOTerminateNotification`` | +------------------+-------------------------------+ The method should expect a single argument, which will be an :class:`.IOIterator`. As a convenience, receiver can also implement methods whose names start with `on_path_` instead of `on_`. These methods will receiver a generator which yields path names for the relevant devices. Sample_ receiver implementation:: from CoreFoundation import * from IOKit import * port = IONotificationPort() matching = IOServiceMatching() matching[kUSBVendorID] = 0x0451 matching[kUSBProductID] = 0xf432 class Receiver(object): def on_path_match(self, paths): for path in paths: print '%s matched' % path def on_path_terminate(self, paths): for path in paths: print '%s terminated' % path receiver = Receiver() iterator = port.addMatchingNotifications(matching, receiver) source = port.getRunLoopSource() CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode) CFRunLoopRun() .. _IOServiceAddMatchingNotification: https://developer.apple.com/library/mac/#documentation/IOKit/Reference/IOKitLib_header_reference/Reference/reference.html#//apple_ref/doc/c_ref/IOServiceMatchingAddNotification .. _Sample: https://developer.apple.com/library/mac/#documentation/DeviceDrivers/Conceptual/USBBook/USBDeviceInterfaces/USBDevInterfaces.html ''' map = ( (kIOPublishNotification, 'on_publish', _notification), (kIOFirstPublishNotification, 'on_first_publish', _notification), (kIOMatchedNotification, 'on_match', _notification), (kIOFirstMatchNotification, 'on_first_match', _notification), (kIOTerminatedNotification, 'on_terminate', _notification), (kIOPublishNotification, 'on_path_publish', _path_notification), (kIOFirstPublishNotification, 'on_path_first_publish', _path_notification), (kIOMatchedNotification, 'on_path_match', _path_notification), (kIOFirstMatchNotification, 'on_path_first_match', _path_notification), (kIOTerminatedNotification, 'on_path_terminate', _path_notification), ) obj = self._obj matching_id = pyobjc_id(matching) iterators = {} for k, v, n in map: attr = getattr(receiver, v, None) if not attr: continue wrap = py_object(attr) setattr(receiver, k + '_ctype', wrap) # keep reference it = c_void_p() ret = _iokit.IOServiceAddMatchingNotification(obj, k, matching_id, n, wrap, byref(it)) if ret: raise IOException(ret) n(wrap, it) iterators[v] = it return iterators