def checkRemovableDrives(self): drives = {} p = subprocess.Popen(["system_profiler", "SPUSBDataType", "-xml"], stdout=subprocess.PIPE) plist = plistlib.loads(p.communicate()[0]) p.wait() for dev in self._findInTree(plist, "Mass Storage Device"): if "removable_media" in dev and dev["removable_media"] == "yes" and "volumes" in dev and len(dev["volumes"]) > 0: for vol in dev["volumes"]: if "mount_point" in vol: volume = vol["mount_point"] drives[volume] = os.path.basename(volume) p = subprocess.Popen(["system_profiler", "SPCardReaderDataType", "-xml"], stdout=subprocess.PIPE) plist = plistlib.loads(p.communicate()[0]) p.wait() for entry in plist: if "_items" in entry: for item in entry["_items"]: for dev in item["_items"]: if "removable_media" in dev and dev["removable_media"] == "yes" and "volumes" in dev and len(dev["volumes"]) > 0: for vol in dev["volumes"]: if "mount_point" in vol: volume = vol["mount_point"] drives[volume] = os.path.basename(volume) return drives
def checkRemovableDrives(self): drives = {} p = subprocess.Popen(["system_profiler", "SPUSBDataType", "-xml"], stdout = subprocess.PIPE) plist = plistlib.loads(p.communicate()[0]) result = self._recursiveSearch(plist, "removable_media") p = subprocess.Popen(["system_profiler", "SPCardReaderDataType", "-xml"], stdout=subprocess.PIPE) plist = plistlib.loads(p.communicate()[0]) result.extend(self._recursiveSearch(plist, "removable_media")) for drive in result: # Ignore everything not explicitly marked as removable if drive["removable_media"] != "yes": continue # Ignore any removable device that does not have an actual volume if "volumes" not in drive or not drive["volumes"]: continue for volume in drive["volumes"]: if not "mount_point" in volume: continue mount_point = volume["mount_point"] if "_name" in volume: drive_name = volume["_name"] else: drive_name = os.path.basename(mount_point) drives[mount_point] = drive_name return drives
def test_v1_plist(): create_app_and_keys() data = {'app_id': 'com.mplewis.myapp', 'format': 'plist'} c = Client() resp = post_json(c, '/api/v1/', data) resp.status_code.should.eql(200) resp['Content-Type'].should.eql('application/x-plist') plistlib.loads(resp.content).should.eql(expected_keys)
def test_appleformattingfromliteral(self): self.maxDiff = None for fmt in ALL_FORMATS: with self.subTest(fmt=fmt): pl = self._create(fmt=fmt) pl2 = plistlib.loads(TESTDATA[fmt], fmt=fmt) self.assertEqual(dict(pl), dict(pl2), "generated data was not identical to Apple's output") pl2 = plistlib.loads(TESTDATA[fmt]) self.assertEqual(dict(pl), dict(pl2), "generated data was not identical to Apple's output")
def test_nondictroot(self): for fmt in ALL_FORMATS: with self.subTest(fmt=fmt): test1 = "abc" test2 = [1, 2, 3, "abc"] result1 = plistlib.loads(plistlib.dumps(test1, fmt=fmt)) result2 = plistlib.loads(plistlib.dumps(test2, fmt=fmt)) self.assertEqual(test1, result1) self.assertEqual(test2, result2)
def test_invalid_binary(self): for data in [ # too short data b'', # too large offset_table_offset and nonstandard offset_size b'\x00\x08' b'\x00\x00\x00\x00\x00\x00\x03\x01' b'\x00\x00\x00\x00\x00\x00\x00\x01' b'\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x2a', # integer overflow in offset_table_offset b'\x00\x08' b'\x00\x00\x00\x00\x00\x00\x01\x01' b'\x00\x00\x00\x00\x00\x00\x00\x01' b'\x00\x00\x00\x00\x00\x00\x00\x00' b'\xff\xff\xff\xff\xff\xff\xff\xff', # offset_size = 0 b'\x00\x08' b'\x00\x00\x00\x00\x00\x00\x00\x01' b'\x00\x00\x00\x00\x00\x00\x00\x01' b'\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x09', # ref_size = 0 b'\xa1\x01\x00\x08\x0a' b'\x00\x00\x00\x00\x00\x00\x01\x00' b'\x00\x00\x00\x00\x00\x00\x00\x02' b'\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x0b', # integer overflow in offset b'\x00\xff\xff\xff\xff\xff\xff\xff\xff' b'\x00\x00\x00\x00\x00\x00\x08\x01' b'\x00\x00\x00\x00\x00\x00\x00\x01' b'\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x09', # invalid ASCII b'\x51\xff\x08' b'\x00\x00\x00\x00\x00\x00\x01\x01' b'\x00\x00\x00\x00\x00\x00\x00\x01' b'\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x0a', # invalid UTF-16 b'\x61\xd8\x00\x08' b'\x00\x00\x00\x00\x00\x00\x01\x01' b'\x00\x00\x00\x00\x00\x00\x00\x01' b'\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x0b', ]: with self.assertRaises(plistlib.InvalidFileException): plistlib.loads(b'bplist00' + data, fmt=plistlib.FMT_BINARY)
def test_skipkeys(self): pl = {42: "aNumber", "snake": "aWord"} for fmt in ALL_FORMATS: with self.subTest(fmt=fmt): data = plistlib.dumps(pl, fmt=fmt, skipkeys=True, sort_keys=False) pl2 = plistlib.loads(data) self.assertEqual(pl2, {"snake": "aWord"}) fp = BytesIO() plistlib.dump(pl, fp, fmt=fmt, skipkeys=True, sort_keys=False) data = fp.getvalue() pl2 = plistlib.loads(fp.getvalue()) self.assertEqual(pl2, {"snake": "aWord"})
def read_property_list(*lines): """Portable front end to plistlib.readPlistFromString() or loads().""" import plistlib text = '\n'.join(lines) if sys.version_info.major == 2: return plistlib.readPlistFromString(text) #pylint: disable=no-member return plistlib.loads(text.encode())
def filtered_profiles(team=None, app_id=None, type=None): profile_dicts = {} filtered = [] for profile_path in local_profiles(): plist_string = plist_from_profile(profile_path) plist_dict = plistlib.loads(plist_string) profile_dicts[profile_path] = plist_dict profiles = list(profile_dicts.keys()) if team is None: filtered = profiles else: for profile in profiles: profile_dict = profile_dicts[profile] if profile_dict["ApplicationIdentifierPrefix"][0] == team: filtered.append(profile) if app_id is not None: profiles = filtered filtered = [] for profile in profiles: profile_dict = profile_dicts[profile] prof_app_id = profile_dict["Entitlements"]["application-identifier"] prof_app_id = prof_app_id.replace(profile_dict["ApplicationIdentifierPrefix"][0]+".", "") if prof_app_id == app_id: filtered.append(profile) # return dict[name]->file prof_name_dict = {} for profile in filtered: prof_dict = profile_dicts[profile] prof_name_dict[prof_dict["Name"]] = profile return prof_name_dict
def plist_as_dict(self): """Makes the network request and returns data""" if self.data: return self.data purl = urlparse(self.url) if purl.scheme == "https": conn = http.HTTPSConnection(purl.hostname, purl.port) else: conn = http.HTTPConnection(purl.hostname, purl.port) conn.request(self.method, purl.path, self.body, self.headers) response = conn.getresponse() data = response.read() try: self.data = plistlib.loads(data) except ExpatError: self.data = None if response.status != 200: print("Request %s returned code %d" % (self.url, response.status)) return None return self.data
def com_google_fonts_check_ftxvalidator(font): """Checking with ftxvalidator.""" import plistlib try: import subprocess ftx_cmd = [ "ftxvalidator", "-t", "all", # execute all checks font ] ftx_output = subprocess.check_output(ftx_cmd, stderr=subprocess.STDOUT) ftx_data = plistlib.loads(ftx_output) # we accept kATSFontTestSeverityInformation # and kATSFontTestSeverityMinorError if 'kATSFontTestSeverityFatalError' \ not in ftx_data['kATSFontTestResultKey']: yield PASS, "ftxvalidator passed this file" else: ftx_cmd = [ "ftxvalidator", "-T", # Human-readable output "-r", # Generate a full report "-t", "all", # execute all checks font ] ftx_output = subprocess.check_output(ftx_cmd, stderr=subprocess.STDOUT) yield FAIL, f"ftxvalidator output follows:\n\n{ftx_output}\n" except subprocess.CalledProcessError as e: yield ERROR, ("ftxvalidator returned an error code. Output follows:" "\n\n{}\n").format(e.output.decode('utf-8')) except OSError: yield ERROR, "ftxvalidator is not available!"
def test_int(self): for pl in [ 0, 2 ** 8 - 1, 2 ** 8, 2 ** 16 - 1, 2 ** 16, 2 ** 32 - 1, 2 ** 32, 2 ** 63 - 1, 2 ** 64 - 1, 1, -2 ** 63, ]: for fmt in ALL_FORMATS: with self.subTest(pl=pl, fmt=fmt): data = plistlib.dumps(pl, fmt=fmt) pl2 = plistlib.loads(data) self.assertIsInstance(pl2, int) self.assertEqual(pl, pl2) data2 = plistlib.dumps(pl2, fmt=fmt) self.assertEqual(data, data2) for fmt in ALL_FORMATS: for pl in (2 ** 64 + 1, 2 ** 127 - 1, -2 ** 64, -2 ** 127): with self.subTest(pl=pl, fmt=fmt): self.assertRaises(OverflowError, plistlib.dumps, pl, fmt=fmt)
def test_appleformatting(self): for use_builtin_types in (True, False): for fmt in ALL_FORMATS: with self.subTest(fmt=fmt, use_builtin_types=use_builtin_types): pl = plistlib.loads(TESTDATA[fmt], use_builtin_types=use_builtin_types) data = plistlib.dumps(pl, fmt=fmt) self.assertEqual(data, TESTDATA[fmt], "generated data was not identical to Apple's output")
def test_large_timestamp(self): # Issue #26709: 32-bit timestamp out of range for ts in -2 ** 31 - 1, 2 ** 31: with self.subTest(ts=ts): d = datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(seconds=ts) data = plistlib.dumps(d, fmt=plistlib.FMT_BINARY) self.assertEqual(plistlib.loads(data), d)
def _call_ipptool(self, request): with tempfile.NamedTemporaryFile(delete=False) as temp_file: temp_file.write(bytes(request, encoding='utf-8')) process = subprocess.Popen([self.config['ipptool_path'], self.authenticated_uri, '-X', temp_file.name], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) future = [] timer = threading.Timer(self.config['timeout'], self.timeout_handler, (process, future)) timer.start() try: stdout, stderr = process.communicate() finally: os.unlink(temp_file.name) timer.cancel() if future: raise TimeoutError if PY3: result = plistlib.loads(stdout) else: result = plistlib.readPlistFromString(stdout) try: return result['Tests'][0] except (IndexError, KeyError): logger = logging.getLogger(__name__) logger.error('ipptool command failed: {} {}'.format(stdout, stderr)) raise
def status(job_label, runas=None): ''' Return the status for a service, returns a bool whether the service is running. CLI Example: .. code-block:: bash salt '*' service.status <service label> ''' service = _service_by_name(job_label) lookup_name = service['plist']['Label'] if service else job_label launchctl_data = _get_launchctl_data(lookup_name, runas=runas) if launchctl_data: if BEFORE_YOSEMITE: if six.PY3: return 'PID' in plistlib.loads(launchctl_data) else: return 'PID' in dict(plistlib.readPlistFromString(launchctl_data)) else: pattern = '"PID" = [0-9]+;' return True if re.search(pattern, launchctl_data) else False else: return False
def test_cycles(self): # recursive list a = [] a.append(a) b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY)) self.assertIs(b[0], b) # recursive tuple a = ([],) a[0].append(a) b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY)) self.assertIs(b[0][0], b) # recursive dict a = {} a['x'] = a b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY)) self.assertIs(b['x'], b)
def test_bytes(self): pl = self._create() data = plistlib.dumps(pl) pl2 = plistlib.loads(data) self.assertEqual(dict(pl), dict(pl2)) data2 = plistlib.dumps(pl2) self.assertEqual(data, data2)
def readPlist(pathOrFile): """Raises NotBinaryPlistException, InvalidPlistException""" didOpen = False result = None if isinstance(pathOrFile, (six.binary_type, six.text_type)): pathOrFile = open(pathOrFile, 'rb') didOpen = True try: reader = PlistReader(pathOrFile) result = reader.parse() except NotBinaryPlistException as e: try: pathOrFile.seek(0) result = None if hasattr(plistlib, 'loads'): contents = None if isinstance(pathOrFile, (six.binary_type, six.text_type)): with open(pathOrFile, 'rb') as f: contents = f.read() else: contents = pathOrFile.read() result = plistlib.loads(contents) else: result = plistlib.readPlist(pathOrFile) result = wrapDataObject(result, for_binary=True) except Exception as e: raise InvalidPlistException(e) finally: if didOpen: pathOrFile.close() return result
def _machine_id(): """ for informational purposes, try to get a machine unique id thing """ if platform.isLinux(): try: # why this? see: http://0pointer.de/blog/projects/ids.html with open('/var/lib/dbus/machine-id', 'r') as f: return f.read().strip() except: # Non-dbus using Linux, get a hostname return socket.gethostname() elif platform.isMacOSX(): # Get the serial number of the platform import plistlib plist_data = subprocess.check_output(["ioreg", "-rd1", "-c", "IOPlatformExpertDevice", "-a"]) if six.PY2: # Only API on 2.7 return plistlib.readPlistFromString(plist_data)[0]["IOPlatformSerialNumber"] else: # New, non-deprecated 3.4+ API return plistlib.loads(plist_data)[0]["IOPlatformSerialNumber"] else: # Something else, just get a hostname return socket.gethostname()
def _plist_from_popen(popen): out, _ = popen.communicate() if not out: return [] try: return loads(out) except ExpatError: return []
def test_bytes(self): pl = self._create() data = plistlib.dumps(pl) pl2 = plistlib.loads(data) self.assertNotIsInstance(pl, plistlib._InternalDict) self.assertEqual(dict(pl), dict(pl2)) data2 = plistlib.dumps(pl2) self.assertEqual(data, data2)
def device_in_profile(udid): try: profile = subprocess.check_output(['security', 'cms', '-D', '-i', PROVISIONING_PROFILE]) plist = plistlib.loads(profile) return udid in plist['ProvisionedDevices'] except subprocess.CalledProcessError: return False
def test_dict_members(self): pl = {"first": {"a": 1}, "second": {"a": 1}, "third": {"b": 2}} for fmt in ALL_FORMATS: with self.subTest(fmt=fmt): data = plistlib.dumps(pl, fmt=fmt) pl2 = plistlib.loads(data) self.assertEqual(pl2, {"first": {"a": 1}, "second": {"a": 1}, "third": {"b": 2}}) self.assertIsNot(pl2["first"], pl2["second"])
def update(self, view): if not self.need_update: return self.need_update = False content = self.color_scheme.content() current_colors = set("#%s" % c.upper() for c in re.findall(r'\b%s([a-fA-F0-9]{8})\b' % self.prefix, content)) bg_col = self.get_background_col(view) rules = [] if not re.search(r'\b%sgutter\b' % self.prefix, content): rules.append({ "scope": "%sgutter" % self.prefix, "background": "#000000", "foreground": "#ffffff", }) for col, name in self.colors.items(): if col not in current_colors: fg_col = self.get_inv_col(bg_col, col) rules.append({ "scope": name, "background": col, "foreground": fg_col, }) if rules: try: # For sublime-color-scheme m = re.search(r'([\t ]*)"rules":\s*\[[\r\n]*', content) if m: json_rules = json.dumps({"rules": rules}, indent=m.group(1)) json_rules = '\n'.join(map(str.rstrip, json_rules.split('\n')[2:-2])) + ',\n' content = content[:m.end()] + json_rules + content[m.end():] write_package(self.color_scheme.path, content) log.debug("Updated sublime-color-scheme") return # for tmTheme if re.match(r'\s*<(?:\?xml|!DOCTYPE|plist)\b', content): plist_content = plistlib.loads(content.encode('utf-8')) plist_content['settings'].extend({ "scope": r['scope'], "settings": { "foreground": r['foreground'], "background": r['background'], } } for r in rules) content = plistlib.dumps(plist_content).decode('utf-8') write_package(self.color_scheme.path, content) log.debug("Updated tmTheme") return log.error("Not Updated: Schema format not recognized") except Exception as e: import traceback; traceback.print_exc(); log.error("Not Updated: %r" % e)
def get_provisioning_profile_id(): try: profile = subprocess.check_output(['security', 'cms', '-D', '-i', PROVISIONING_PROFILE], stderr=subprocess.STDOUT) plist = plistlib.loads(profile) return plist['UUID'] except subprocess.CalledProcessError: return None
def __init__(self, metadata_blob): metadata = plistlib.loads(metadata_blob) # The current version has a 1-element array at toplevel. # Future versions will have a dictionary at toplevel. if isinstance(metadata, list) and len(metadata) == 1: metadata = metadata[0] assert isinstance(metadata, dict) self.metadata = metadata self.secrets = None
def getpacket(self): resp, tag, payload = BinaryProtocol.getpacket(self) if resp != self.TYPE_PLIST: raise MuxError("Received non-plist type %d"%resp) if PY3: payload = plistlib.loads(payload) else: payload = plistlib.readPlistFromString(payload) return payload['MessageType'], tag, payload
def test_dataobject_deprecated(self): in_data = { 'key': plistlib.Data(b'hello') } out_data = { 'key': b'hello' } buf = plistlib.dumps(in_data) cur = plistlib.loads(buf) self.assertEqual(cur, out_data) self.assertNotEqual(cur, in_data) cur = plistlib.loads(buf, use_builtin_types=False) self.assertNotEqual(cur, out_data) self.assertEqual(cur, in_data) with self.assertWarns(DeprecationWarning): cur = plistlib.readPlistFromBytes(buf) self.assertNotEqual(cur, out_data) self.assertEqual(cur, in_data)
def get_usb_drives(): """Enumerate USB Drives attached to Mac""" plist_byte_object = (subprocess.Popen(["system_profiler", "SPUSBDataType", "-xml"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate())[0] plist_object = plistlib.loads(plist_byte_object) valid_usb_drives = traverse_plist(plist_object, 0, [], []) return valid_usb_drives
] notarizeStapler = [ "xcrun", "stapler", "staple", existingDmgLocation ] print("notarizing app") notarisationRequestUUID = None with tempfile.TemporaryFile(mode='w+b') as stdoutFile: popen = subprocess.Popen(notarize, stdout=stdoutFile) popen.wait() stdoutFile.seek(0) data = stdoutFile.read() data = plistlib.loads(data) if "notarization-upload" in data: notarisationRequestUUID = data["notarization-upload"].get("RequestUUID") print("notarisation Request UUID:", notarisationRequestUUID) if "product-errors" in data: print("\n".join([e["message"] for e in data["product-errors"]])) print("done notarizing app") notarisationSucces = False if notarisationRequestUUID: print("getting notarization info") notarizeInfo = [ "xcrun", "altool", "--notarization-info", notarisationRequestUUID,
def wait_for_results(uuids, config): """Waits for results from the notarization service. This iterates the list of UUIDs and checks the status of each one. For each successful result, the function yields to the caller. If a request failed, this raises a NotarizationError. If no requests are ready, this operation blocks and retries until a result is ready. After a certain amount of time, the operation will time out with a NotarizationError if no results are produced. Args: uuids: List of UUIDs to check for results. The list must not be empty. config: The |config.CodeSignConfig| object. Yields: The UUID of a successful notarization request. """ assert len(uuids) wait_set = set(uuids) sleep_time_seconds = 5 total_sleep_time_seconds = 0 while len(wait_set) > 0: for uuid in list(wait_set): try: command = [ 'xcrun', 'altool', '--notarization-info', uuid, '--username', config.notary_user, '--password', config.notary_password, '--output-format', 'xml' ] if config.notary_asc_provider is not None: command.extend( ['--asc-provider', config.notary_asc_provider]) output = commands.run_command_output(command) except subprocess.CalledProcessError as e: # A notarization request might report as "not found" immediately # after submission, which causes altool to exit non-zero. Check # for this case and parse the XML output to ensure that the # error code refers to the not-found state. The UUID is known- # good since it was a result of submit(), so loop to wait for # it to show up. if e.returncode == 239: plist = plistlib.loads(e.output) if plist['product-errors'][0]['code'] == 1519: continue raise e plist = plistlib.loads(output) info = plist['notarization-info'] status = info['Status'] if status == 'in progress': continue elif status == 'success': print('Successfully notarized request {}. Log file: {}'.format( uuid, info[_LOG_FILE_URL])) wait_set.remove(uuid) yield uuid else: print('Failed to notarize request {}. Log file: {}. Output:\n{}' .format(uuid, info[_LOG_FILE_URL], output)) raise NotarizationError( 'Notarization request {} failed with status: "{}". ' 'Log file: {}.'.format(uuid, status, info[_LOG_FILE_URL])) if len(wait_set) > 0: # Do not wait more than 30 minutes for all the operations to # complete. if total_sleep_time_seconds < 30 * 60: # No results were available, so wait and try again in some # number of seconds. Do not wait more than 1 minute for any # iteration. time.sleep(sleep_time_seconds) total_sleep_time_seconds += sleep_time_seconds sleep_time_seconds = min(sleep_time_seconds * 2, 60) else: raise NotarizationError( 'Timed out waiting for notarization requests: {}'.format( uuids))
def do_cat(self, p): data = self.afc.get_file_contents(self.curdir + "/" + p) if data and p.endswith(".plist"): pprint(plistlib.loads(data)) else: print(data)
def test_indentation_dict(self): data = {'1': {'2': {'3': {'4': {'5': {'6': {'7': {'8': {'9': b'aaaaaa'}}}}}}}}} self.assertEqual(plistlib.loads(plistlib.dumps(data)), data)
def read(self): size, = struct.unpack('>L', self.pipe.read(4)) response = self.pipe.read_all(size) return plistlib.loads(response)
def test_invalid_binary(self): for name, data in INVALID_BINARY_PLISTS: with self.subTest(name): with self.assertRaises(plistlib.InvalidFileException): plistlib.loads(b'bplist00' + data, fmt=plistlib.FMT_BINARY)
def dump(self, file_obj: BinaryIO) -> None: # type: ignore binary = plistlib.dumps( # todo: change dumps to binary and remove this plistlib.loads(self.dumps().encode('utf-8')), # type: ignore fmt=plistlib.FMT_BINARY, ) file_obj.write(binary)
def test_indentation_dict_mix(self): data = {'1': {'2': [{'3': [[[[[{'test': b'aaaaaa'}]]]]]}]}} self.assertEqual(plistlib.loads(plistlib.dumps(data)), data)
def test_indentation_array(self): data = [[[[[[[[{'test': b'aaaaaa'}]]]]]]]] self.assertEqual(plistlib.loads(plistlib.dumps(data)), data)
def ota_authenticate(): """Over-The-Air Profile Delivery Phase 3 and 4. This endpoint represents the OTA Phase 3 and 4, "/profile" endpoint as specified in apples document "Over-The-Air Profile Delivery". There are two types of requests made here: - The first request is signed by the iPhone Device CA and contains the challenge in the `Profile Service` payload, we respond with the SCEP detail. - The second request is signed by the issued SCEP certificate. We should respond with an enrollment profile. It also contains the same device attributes sent in the previous step, but this time they are authenticated by our SCEP CA. Examples: Signed plist given in the first request:: { 'CHALLENGE': '<CHALLENGE FROM PROFILE HERE>', 'IMEI': 'empty if macOS', 'MEID': 'empty if macOS', 'NotOnConsole': False, 'PRODUCT': 'MacPro6,1', 'SERIAL': 'C020000000000', 'UDID': '00000000-0000-0000-0000-000000000000', 'UserID': '00000000-0000-0000-0000-000000000000', 'UserLongName': 'Joe User', 'UserShortName': 'juser', 'VERSION': '16F73' } See Also: - `Over-the-Air Profile Delivery and Configuration <https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009505-CH1-SW1>`_. """ signed_data = g.signed_data signers = g.signers # TODO: This should Validate to iPhone Device CA but we can't because: # http://www.openradar.me/31423312 device_attributes = plistlib.loads(signed_data) current_app.logger.debug(device_attributes) try: org = db.session.query(Organization).one() except NoResultFound: abort( 500, 'No organization is configured, cannot generate enrollment profile.' ) except MultipleResultsFound: abort(500, 'Multiple organizations, backup your database and start again') # TODO: Behold, the stupidest thing ever just to get this working, theres no way this should be prod: # Phase 4 does not send a challenge but phase 3 does if 'CHALLENGE' in device_attributes: # Reply SCEP profile = Profile( identifier=org.payload_prefix + '.ota.phase3', uuid=uuid4(), display_name='Commandment OTA SCEP Enrollment', description= 'Retrieves a SCEP Certificate to complete OTA Enrollment', organization=org.name, version=1, scope=PayloadScope.System, ) scep_payload = scep_payload_from_configuration() profile.payloads.append(scep_payload) else: profile = generate_enroll_profile() # profile = generate_enroll_profile() schema = profile_schema.ProfileSchema() result = schema.dump(profile) plist_data = dumps_none(result.data, skipkeys=True) return plist_data, 200, {'Content-Type': PROFILE_CONTENT_TYPE}
def test_export_firmware_extended_macos(C): """ Check, whether the firmware file is exported correctly, and in correct size. Apparently, the auto-remounting side effect of the v0.46 change, is disturbing the export process. Unmounting the UV just before the export gives the device 20/20 success rate. Test case for issue https://github.com/Nitrokey/nitrokey-app/issues/399 """ skip_if_device_version_lower_than({'S': 43}) skip_if_not_macos( 'macOS specific test, due to the mount path and command.') import pexpect from time import sleep import os from os.path import exists as exist import plistlib usb_devices = pexpect.run('system_profiler -xml SPUSBDataType') assert b'Nitrokey' in usb_devices, 'No Nitrokey devices connected' usb_devices_parsed = plistlib.loads(usb_devices) assert isinstance(usb_devices_parsed, list), 'usb_devices_parsed has unexpected type' # Try to get all USB devices try: devices = usb_devices_parsed[0]['_items'][0]['_items'] except KeyError: devices = None assert devices is not None, 'could not list USB devices' device_item = None for item in devices: if '_items' in item: # Fix for macOS 10.13.6, Python 3.6.2 item = item['_items'][0] if 'manufacturer' in item and item['manufacturer'] == 'Nitrokey': device_item = item # Try to get first volume of USB device try: volume = device_item['Media'][0]['volumes'][0] except (KeyError, TypeError): volume = None assert volume is not None, 'could not determine volume' assert 'bsd_name' in volume, 'could not get BSD style device name' device = '/dev/' + volume['bsd_name'] pexpect.run(f'diskutil mount {device}') sleep(3) assert 'mount_point' in volume, 'could not get mount point' firmware_abs_path = volume['mount_point'] + '/firmware.bin' checks = 0 print('path: {}, device: {}'.format(firmware_abs_path, device)) checks_add = 0 if exist(firmware_abs_path): os.remove(firmware_abs_path) assert not exist(firmware_abs_path) ATTEMPTS = 20 for i in range(ATTEMPTS): # if umount is disabled, success rate is 3/10, enabled: 10/10 pexpect.run(f'diskutil unmount {device}') assert C.NK_export_firmware( DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK pexpect.run(f'diskutil mount {device}') sleep(1) firmware_file_exist = exist(firmware_abs_path) if firmware_file_exist: checks += 1 getsize = os.path.getsize(firmware_abs_path) print('Firmware file exist, size: {}'.format(getsize)) checks_add += 1 if getsize >= 100 * 1024 else 0 # checks_add += 1 if os.path.getsize(firmware_abs_path) == 256*1024 else 0 os.remove(firmware_abs_path) assert not exist(firmware_abs_path) print('CHECK {} ; CHECK ADDITIONAL {}'.format(checks, checks_add)) assert checks == ATTEMPTS assert checks_add == checks
def read_plist(p: Path) -> dict: escaped = "".join( (chr(ord(char) + OFFSET) if ord(char) in BAD_CODES else char) for char in p.read_text()) return plistlib.loads(escaped.encode("utf-8"))
def parse_plist(catalog_data): if sys.version_info > (3, 0): root = plistlib.loads(catalog_data) else: root = plistlib.readPlistFromString(catalog_data) return root
def profile_plist_for_args(args): pnargs = [CLT_BINARY] pnargs.extend(args) pnargs.extend(["-O", "-"]) out = subprocess.check_output(pnargs) return plistlib.loads(out)
def getpacket(self): resp, tag, payload = super().getpacket() if resp != self.TYPE_PLIST: raise MuxError('Received non-plist type %d' % resp) payload = plistlib.loads(payload) return payload.get('MessageType', ''), tag, payload
def plist(self): import plistlib return plistlib.loads(self.content)
def ParseFileObject(self, parser_mediator, file_object): """Parses a plist file-like object. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. file_object (dfvfs.FileIO): a file-like object. Raises: UnableToParseFile: when the file cannot be parsed. """ filename = parser_mediator.GetFilename() file_size = file_object.get_size() if file_size <= 0: raise errors.UnableToParseFile( 'File size: {0:d} bytes is less equal 0.'.format(file_size)) if file_size > self._MAXIMUM_PLIST_FILE_SIZE: raise errors.UnableToParseFile( 'File size: {0:d} bytes is larger than 50 MB.'.format( file_size)) plist_data = file_object.read() has_leading_whitespace = False is_binary_plist = plist_data.startswith(b'bplist0') if not is_binary_plist: byte_order_mark_size, encoding = self._CheckByteOrderMark( plist_data) xml_signature = '<?xml '.encode(encoding) is_xml = plist_data[byte_order_mark_size:].startswith( xml_signature) if not is_xml: # Preserve the byte-order-mark for plistlib. plist_data = b''.join([ plist_data[:byte_order_mark_size], plist_data[byte_order_mark_size:].lstrip() ]) is_xml = plist_data[byte_order_mark_size:].startswith( xml_signature) has_leading_whitespace = is_xml if is_xml: plist_footer = '</plist>'.encode(encoding) plist_data = plist_data.rstrip() if not plist_data.endswith(plist_footer): raise errors.UnableToParseFile( 'Unable to parse XML plist with error: missing plist XML root ' 'element.') try: top_level_object = plistlib.loads(plist_data) except (AttributeError, binascii.Error, expat.ExpatError, plistlib.InvalidFileException) as exception: raise errors.UnableToParseFile( 'Unable to parse plist with error: {0!s}'.format(exception)) except (LookupError, ValueError) as exception: # LookupError will be raised in cases where the plist is an XML file # that contains an unsupported encoding. # ValueError will be raised in cases where the plist is an XML file # that contains an unsupported date and time value. parser_mediator.ProduceExtractionWarning( 'unable to parse XML plist with error: {0!s}'.format( exception)) return if not top_level_object: # Do not produce an extraction warning for a binary plist without a top # level object. if not is_binary_plist: parser_mediator.ProduceExtractionWarning(( 'unable to parse XML plist file with error: missing top level ' 'object')) return if has_leading_whitespace: parser_mediator.ProduceExtractionWarning( 'XML plist file with leading whitespace') filename_lower_case = filename.lower() try: top_level_keys = set(top_level_object.keys()) except AttributeError as exception: raise errors.UnableToParseFile( 'Unable to parse top level keys of: {0:s} with error: {1!s}.'. format(filename, exception)) found_matching_plugin = False for plugin in self._plugins: if parser_mediator.abort: break if not plugin.PLIST_PATH_FILTERS: path_filter_match = True else: path_filter_match = False for path_filter in plugin.PLIST_PATH_FILTERS: if path_filter.Match(filename_lower_case): path_filter_match = True file_entry = parser_mediator.GetFileEntry() display_name = parser_mediator.GetDisplayName(file_entry) if (not path_filter_match or not top_level_keys.issuperset(plugin.PLIST_KEYS)): logger.debug( 'Skipped parsing file: {0:s} with plugin: {1:s}'.format( display_name, plugin.NAME)) continue logger.debug('Parsing file: {0:s} with plugin: {1:s}'.format( display_name, plugin.NAME)) try: plugin.UpdateChainAndProcess(parser_mediator, top_level=top_level_object) found_matching_plugin = True except Exception as exception: # pylint: disable=broad-except parser_mediator.ProduceExtractionWarning( ('plugin: {0:s} unable to parse plist file with error: ' '{1!s}').format(plugin.NAME, exception)) if not found_matching_plugin and self._default_plugin: self._default_plugin.UpdateChainAndProcess( parser_mediator, top_level=top_level_object)
def post(self, request, *args, **kwargs): # Verify payload signature, extract signed payload try: certificates, payload = verify_signed_payload(request.read()) except ValueError: self.abort("posted data is not signed") # find out which CA signed the certificate used to sign the payload # if iPhone CA: phase 2 # if SCEP CA: phase 3 # if unknown: phase 2 # TODO: verify. seen with self signed cert in 10.13 beta in VMWare. for certificate_i_cn, certificate_bytes, signing_certificate in certificates: if verify_apple_iphone_device_ca_issuer_openssl(certificate_bytes): phase = 2 break elif verify_zentral_scep_ca_issuer_openssl(certificate_bytes): phase = 3 break else: self.post_event( "warning", reason="unknown signing certificate issuer '{}'".format( certificate_i_cn)) phase = 2 payload = plistlib.loads(payload) self.serial_number = payload["SERIAL"] self.udid = payload["UDID"] if phase == 2: # Verify the challenge challenge = payload.get("CHALLENGE") if not challenge: self.abort("missing challenge", phase=phase) try: es_request = verify_enrollment_secret("ota_enrollment", challenge, self.user_agent, self.ip, self.serial_number, self.udid) except EnrollmentSecretVerificationFailed as e: self.abort("secret verification failed: '{}'".format( e.err_msg), phase=phase) # Start an OTA enrollment session ota_enrollment_session = OTAEnrollmentSession.objects.create_from_ota_enrollment( es_request.enrollment_secret.ota_enrollment, self.serial_number, self.udid) payload = build_ota_scep_payload(ota_enrollment_session) filename = "zentral_ota_scep" elif phase == 3: # get the serial number from the DN of the payload signing certificate serial_number = signing_certificate.subject.get_attributes_for_oid( NameOID.SERIAL_NUMBER)[0].value if self.serial_number != serial_number: self.abort( "signing certificate DN serial number != payload serial number", phase=phase) # get the ota enrollment session from the DN of the payload signing certificate cn = signing_certificate.subject.get_attributes_for_oid( NameOID.COMMON_NAME)[0].value _, ota_enrollment_session_secret = cn.split("$") try: ota_enrollment_session = ( OTAEnrollmentSession.objects.select_for_update( ).select_related("ota_enrollment", "enrollment_secret__meta_business_unit"). get(enrollment_secret__secret=ota_enrollment_session_secret )) except OTAEnrollmentSession.DoesNotExist: self.abort( "could not find ota enrollment session from payload signing certificate", phase=phase) # verify and update ota enrollment session status try: ota_enrollment_session.set_phase3_status() except OTAEnrollmentSessionStatusError: self.abort("ota enrollment session has wrong status", phase=phase) # verify DN mbu ota_enrollment_session_mbu = ota_enrollment_session.enrollment_secret.meta_business_unit o = signing_certificate.subject.get_attributes_for_oid( NameOID.ORGANIZATION_NAME)[0] if int(o.value.split("$")[-1]) != ota_enrollment_session_mbu.pk: self.abort("DN mbu doesn't match ota enrollment session mbu", phase=phase) # Get the MDM push certificate push_certificate = ota_enrollment_session_mbu.metabusinessunitpushcertificate.push_certificate payload = build_mdm_payload(ota_enrollment_session, push_certificate) filename = "zentral_mdm" self.post_event("success", phase=phase) return build_payload_response(sign_payload_openssl(payload), filename) return HttpResponse()
def getpacket(self): resp, tag, payload = BinaryProtocol.getpacket(self) if resp != self.TYPE_PLIST: raise MuxError("Received non-plist type %d" % resp) payload = plistlib.loads(payload) return payload['MessageType'], tag, payload
def readPlistFromString(s): return loads(s, fmt=FMT_XML)
def plist_from_bytes(byte_content): try: return plistlib.loads(byte_content) except AttributeError: return plistlib.readPlistFromString(byte_content)
async def __ipa_parse(file_path: str): """ 解析ipa包 :param file_path: ipa路径 :return: PackageParse """ ipa_file = ZipFile(file_path) # 解析info.plist路径 ns = [ n for n in ipa_file.namelist() if Regex.IPAInfoPlistPath.match(n) ] if not ns: log.warning('parse info.plist failure: {}'.format(file_path)) return plist_path = ns[-1] # 解析plist plist_data = ipa_file.read(plist_path) plist_file = plistlib.loads(plist_data) # 解析icon'CFBundleIconFiles' (4400546488) if plist_file.get('CFBundleIconFiles'): icon_name = plist_file['CFBundleIconFiles'][-1] else: if plist_file.get('CFBundleIcons'): icon_dict = plist_file['CFBundleIcons'] elif plist_file.get('CFBundleIcons'): icon_dict = plist_file['CFBundleIcons~ipad'] else: log.warning('parse icon failure: {}'.format(file_path)) return icon_name = icon_dict['CFBundlePrimaryIcon']['CFBundleIconFiles'][ -1] log.debug('parse icon name: {}'.format(icon_name)) # 获取icon路径 re_icon_name_end = '(@\dx)\.png' if not icon_name.endswith( '.png') else '' re_icon_name = re.compile('([^/]+/){{2}}{}{}'.format( icon_name, re_icon_name_end)) ns = [n for n in ipa_file.namelist() if re_icon_name.match(n)] if not ns: log.warning('read icon failure: {}'.format(file_path)) return icon_path = ns[-1] log.debug('parse icon path: {}'.format(icon_path)) # 版本号 version_number = plist_file['CFBundleShortVersionString'] # build号 build_number = plist_file['CFBundleVersion'] # 包名 package_name = plist_file['CFBundleIdentifier'] # app名称 app_name = plist_file['CFBundleDisplayName'] if plist_file.get( 'CFBundleDisplayName') else plist_file['CFBundleName'] log.debug('app: {}, V{} build {}, package: {}'.format( app_name, version_number, build_number, package_name)) return PackageParse(ipa_file, AppType.iOS, package_name, app_name, icon_path, version_number, build_number)
def read_plist(s): if sys.version_info.major == 3: return plistlib.loads(s) else: return plistlib.readPlistFromString(s)
for plist in plist_files: # For each file, decode the plist and get data inside the <hash data> xml key #print("Parsing file {}".format(plist)) with open(os.path.join(path, plist), 'rb') as f: parsed_data = plistlib.load(f) if not parsed_data: print("[-]Parsed data seems to be empty for file {}".format( os.path.join(path, plist))) continue if 'ShadowHashData' in parsed_data: account = plist.split('.plist')[0] print("Found ShadowHashData for account: {}".format(account)) shadow_data = plistlib.loads(parsed_data['ShadowHashData'][0]) #print(shadow_data) # Extract data related to keys: entropy, iterations and salt if 'SALTED-SHA512-PBKDF2' in shadow_data: iterations = shadow_data['SALTED-SHA512-PBKDF2']['iterations'] salt = shadow_data['SALTED-SHA512-PBKDF2']['salt'] entropy = shadow_data['SALTED-SHA512-PBKDF2']['entropy'] if not (iterations and salt and entropy): print("[-]Something is wrong, checkout logs") continue salt = salt.hex() entropy = entropy.hex() res[account] = [iterations, salt, entropy] else: print(
def test_parse_file_reads_plist(self, _mock_file): """Parsing a PList file should produce a dictionary.""" fake_prefs = Preferences() value = fake_prefs._parse_json_or_plist_file("fake_filepath") self.assertEqual(value, plistlib.loads(TEST_PLIST_PREFS))
def make_mobileconfig_from_payload( self, payload_path, payload_identifier, mobileconfig_name, organization, description, mobileconfig_uuid, ): """create a mobileconfig file using a payload file""" # import plist as text and replace any substitutable keys with open(payload_path, "rb") as file: payload_text = file.read() # substitute user-assignable keys (requires decode to string) payload_text = self.substitute_assignable_keys((payload_text.decode()), xml_escape=True) # now convert to data (requires encode back to bytes...) mcx_preferences = plistlib.loads(str.encode(payload_text)) self.output("Preferences contents:", verbose_level=2) self.output(mcx_preferences, verbose_level=2) # generate a random UUID for the payload payload_uuid = str(uuid.uuid4()) # add the other keys required in the payload payload_contents = { "PayloadDisplayName": "Custom Settings", "PayloadIdentifier": payload_uuid, "PayloadOrganization": "JAMF Software", "PayloadType": "com.apple.ManagedClient.preferences", "PayloadUUID": payload_uuid, "PayloadVersion": 1, "PayloadContent": { payload_identifier: { "Forced": [{ "mcx_preference_settings": mcx_preferences }] } }, } self.output("Payload contents:", verbose_level=2) self.output(payload_contents, verbose_level=2) # now write the mobileconfig file mobileconfig_data = { "PayloadDescription": description, "PayloadDisplayName": mobileconfig_name, "PayloadOrganization": organization, "PayloadRemovalDisallowed": True, "PayloadScope": "System", "PayloadType": "Configuration", "PayloadVersion": 1, "PayloadIdentifier": mobileconfig_uuid, "PayloadUUID": mobileconfig_uuid, "PayloadContent": [payload_contents], } self.output("Converting config data to plist") mobileconfig_plist = plistlib.dumps(mobileconfig_data) self.output("Mobileconfig contents:", verbose_level=2) self.output(mobileconfig_plist.decode("UTF-8"), verbose_level=2) return mobileconfig_plist
def test_non_bmp_characters(self): pl = {'python': '\U0001f40d'} for fmt in ALL_FORMATS: with self.subTest(fmt=fmt): data = plistlib.dumps(pl, fmt=fmt) self.assertEqual(plistlib.loads(data), pl)
def plist_from_bytes(byte_content): if _PY3: return plistlib.loads(byte_content) else: return plistlib.readPlistFromString(byte_content)
def test_xml_plist_with_entity_decl(self): with self.assertRaisesRegex( plistlib.InvalidFileException, "XML entity declarations are not supported"): plistlib.loads(XML_PLIST_WITH_ENTITY, fmt=plistlib.FMT_XML)
def build_kext(self): empty_controllers = [c for c in self.controllers_historical if not any(p["selected"] for p in c["ports"])] response = None if empty_controllers: empty_menu = utils.TUIMenu( "Selection Validation", "Select an option: ", in_between=["The following controllers have no enabled ports:", ""] + [controller["name"] for controller in empty_controllers] + ["Select whether to ignore these controllers and exclude them from the map, or disable all ports on these controllers."], add_quit=False, return_number=True, ) empty_menu.add_menu_option("Ignore", key="I") empty_menu.add_menu_option("Disable", key="D") response = empty_menu.start() model_identifier = None if self.settings["use_native"]: if platform.system() == "Darwin": model_identifier = plistlib.loads(subprocess.run("system_profiler -detailLevel mini -xml SPHardwareDataType".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.strip())[ 0 ]["_items"][0]["machine_model"] else: model_menu = utils.TUIOnlyPrint( "Enter Model Identifier", "Enter the model identifier: ", [ "You are seeing this as you have selected to use AppleUSBHostController. Model identifier autodetection is unavailable as you are not on macOS.", "Please enter the model identifier of the target system below. You can find it in System Information or with 'system_profiler -detailLevel mini SPHardwareDataType'.", ], ).start() model_identifier = model_menu.strip() ignore = response == "I" template = plistlib.load((shared.resource_dir / Path("Info.plist")).open("rb")) menu = utils.TUIMenu("Building USBMap", "Select an option: ") menu.head() print("Generating Info.plist...") for controller in self.controllers_historical: if not any(i["selected"] for i in controller["ports"]) and ignore: continue # FIXME: ensure unique if controller["identifiers"].get("acpi_path"): if self.check_unique(lambda c: c["identifiers"]["acpi_path"].rpartition(".")[2], lambda c: "acpi_path" in c["identifiers"], controller): personality_name: str = controller["identifiers"]["acpi_path"].rpartition(".")[2] else: personality_name: str = controller["identifiers"]["acpi_path"][1:] # Strip leading \ elif controller["identifiers"].get("bdf"): personality_name: str = ":".join([str(i) for i in controller["identifiers"]["bdf"]]) else: personality_name: str = controller["name"] if self.settings["use_native"]: personality = { "CFBundleIdentifier": "com.apple.driver.AppleUSBHostMergeProperties", "IOClass": "AppleUSBHostMergeProperties", "IOProviderClass": "AppleUSBHostController", "IOParentMatch": self.choose_matching_key(controller), "model": model_identifier, } else: personality = { "CFBundleIdentifier": "com.dhinakg.USBToolBox.kext", "IOClass": "USBToolBox", "IOProviderClass": "IOPCIDevice", "IOMatchCategory": "USBToolBox", } | self.choose_matching_key( controller ) # type: ignore personality["IOProviderMergeProperties"] = {"ports": {}, "port-count": None} port_name_index = {} highest_index = 0 for port in controller["ports"]: if not port["selected"]: continue if port["index"] > highest_index: highest_index = port["index"] if controller["class"] == shared.USBControllerTypes.XHCI and port["class"] == shared.USBDeviceSpeeds.SuperSpeed: prefix = "SS" elif controller["class"] == shared.USBControllerTypes.XHCI and port["class"] == shared.USBDeviceSpeeds.HighSpeed: prefix = "HS" else: prefix = "PRT" port_index = port_name_index.setdefault(prefix, 1) port_name = prefix + str(port_index).zfill(4 - len(prefix)) port_name_index[prefix] += 1 personality["IOProviderMergeProperties"]["ports"][port_name] = { "port": binascii.a2b_hex(hexswap(hex(port["index"])[2:].zfill(8))), "UsbConnector": port["type"] or port["guessed"], } if self.settings["add_comments_to_map"] and port["comment"]: personality["IOProviderMergeProperties"]["ports"][port_name]["#comment"] = port["comment"] personality["IOProviderMergeProperties"]["port-count"] = binascii.a2b_hex(hexswap(hex(highest_index)[2:].zfill(8))) template["IOKitPersonalities"][personality_name] = personality if not self.settings["use_native"]: template["OSBundleLibraries"] = {"com.dhinakg.USBToolBox.kext": "1.0.0"} write_path = shared.current_dir / (Path("USBMap.kext") if self.settings["use_native"] else Path("UTBMap.kext")) if write_path.exists(): print("Removing existing kext...") shutil.rmtree(write_path) print("Writing kext and Info.plist...") (write_path / Path("Contents")).mkdir(parents=True) plistlib.dump(template, (write_path / Path("Contents/Info.plist")).open("wb"), sort_keys=True) print(f"Done. Saved to {write_path.resolve()}.\n") menu.print_options() menu.select() return True