コード例 #1
0
 def testGetCoreStorageStateEnabled(self):
     self.mox.StubOutWithMock(util, 'GetPlistFromExec')
     pl = plistlib.readPlistFromString(CORE_STORAGE_PLIST_LIST_ENABLED)
     pl2 = plistlib.readPlistFromString(CORE_STORAGE_PLIST_LVF_INFO_ENABLED)
     util.GetPlistFromExec(mox.In(DISKUTIL)).AndReturn(pl)
     util.GetPlistFromExec(mox.In(DISKUTIL)).AndReturn(pl2)
     self.mox.ReplayAll()
     self.assertEquals(corestorage.GetState(), corestorage.State.enabled)
     self.mox.VerifyAll()
コード例 #2
0
def GetStateAndVolumeIds():
    """Determine the state of core storage and the volume IDs (if any).

  In the case that core storage is enabled, it is required that every present
  volume is encrypted, to return "encrypted" status (i.e. the entire drive is
  encrypted, for all present drives).  Otherwise only "enabled" status is
  returned.

  Returns:
    tuple: (State, [list; str encrypted UUIDs], [list; str unencrypted UUIDs])
  Raises:
    Error: there was a problem getting the corestorage list, or family info.
  """
    try:
        cs_plist = util.GetPlistFromExec(
            (DISKUTIL, 'corestorage', 'list', '-plist'))
    except util.ExecError:
        logging.exception(
            'GetStateAndVolumeIds() failed to get corestorage list.')
        raise Error

    state = State.none
    volume_ids = []
    encrypted_volume_ids = []

    groups = cs_plist.get('CoreStorageLogicalVolumeGroups', [])
    if groups:
        state = State.enabled
    for group in groups:
        for family in group.get('CoreStorageLogicalVolumeFamilies', []):
            family_id = family['CoreStorageUUID']
            if not util.UuidIsValid(family_id):
                continue
            try:
                info_plist = util.GetPlistFromExec(
                    (DISKUTIL, 'corestorage', 'info', '-plist', family_id))
            except util.ExecError:
                logging.exception(
                    'GetStateAndVolumeIds() failed to get corestorage family info: %s',
                    family_id)
                raise Error
            enc = info_plist.get(
                'CoreStorageLogicalVolumeFamilyEncryptionType', '')

            for volume in family['CoreStorageLogicalVolumes']:
                volume_id = volume['CoreStorageUUID']
                if enc == 'AES-XTS':
                    encrypted_volume_ids.append(volume_id)
                else:
                    volume_ids.append(volume_id)
    if encrypted_volume_ids and not volume_ids:
        state = State.encrypted
    return state, encrypted_volume_ids, volume_ids
コード例 #3
0
 def testGetCoreStorageStateFailed(self):
     self.mox.StubOutWithMock(util, 'GetPlistFromExec')
     pl = plistlib.readPlistFromString(CORE_STORAGE_PLIST_LIST_ENABLED)
     pl2 = plistlib.readPlistFromString(CORE_STORAGE_PLIST_LVF_INFO_ENABLED)
     pl3 = plistlib.readPlistFromString(CORE_STORAGE_PLIST_LV_INFO)
     pl3['CoreStorageLogicalVolumeConversionState'] = 'Failed'
     util.GetPlistFromExec(mox.In(DISKUTIL)).AndReturn(pl)
     util.GetPlistFromExec(mox.In(DISKUTIL)).AndReturn(pl2)
     util.GetPlistFromExec(mox.In(DISKUTIL)).AndReturn(pl3)
     self.mox.ReplayAll()
     self.assertEquals(corestorage.GetState(), corestorage.State.FAILED)
     self.mox.VerifyAll()
コード例 #4
0
 def testGetRecoveryPartition(self):
     self.mox.StubOutWithMock(util, 'GetPlistFromExec')
     pl = plistlib.readPlistFromString(DISKUTIL_LIST_PLIST)
     util.GetPlistFromExec(mox.In(DISKUTIL)).AndReturn(pl)
     self.mox.ReplayAll()
     self.assertEquals(corestorage.GetRecoveryPartition(), '/dev/disk0s3')
     self.mox.VerifyAll()
コード例 #5
0
 def testGetRecoveryPartitionWhenDiskutilFail(self):
     self.mox.StubOutWithMock(util, 'GetPlistFromExec')
     util.GetPlistFromExec(mox.In(DISKUTIL)).AndRaise(
         corestorage.util.ExecError)
     self.mox.ReplayAll()
     self.assertEquals(corestorage.GetRecoveryPartition(), None)
     self.mox.VerifyAll()
コード例 #6
0
 def testGetCoreStorageStateNone(self):
     self.mox.StubOutWithMock(util, 'GetPlistFromExec')
     pl = plistlib.readPlistFromString(CORE_STORAGE_PLIST_LIST_EMPTY)
     util.GetPlistFromExec(mox.In(DISKUTIL)).AndReturn(pl)
     self.mox.ReplayAll()
     self.assertEquals(corestorage.GetState(), corestorage.State.NONE)
     self.mox.VerifyAll()
コード例 #7
0
def UpdateEscrowPassphrase(password):
    """Change the FileVault2 recovery key.

  Under CoreStorage, the current recovery key could be used as the password to
  fdesetup, but this does not work with APFS.  Since the user password works in
  both cases and we already require it for sudo, we simply default to that.

  Args:
    password: the user password.
  Returns:
    The new recovery key.
  """
    command = ('sudo', '-k', '-S', FDESETUP_PATH, 'changerecovery',
               '-personal', '-outputplist', '-inputplist')

    stdin = plistlib.writePlistToString({'Password': password})
    if os.getuid() != 0:
        stdin = '%s\n%s' % (password, stdin)

    try:
        result_plist = util.GetPlistFromExec(command, stdin=stdin)
    except util.ExecError as e:
        logging.error(e.stderr)
        raise Error(e.message)

    recovery_key = result_plist.get('RecoveryKey')
    return recovery_key
コード例 #8
0
def GetVolumeSize(uuid, readable=True):
    """Return the size of the volume with the given UUID.

  Args:
    uuid: str, ID of the volume in question
    readable: Optional boolean, default true: return a human-readable string
      when true, otherwise int number of bytes.

  Returns:
    str or int, see "readable" arg.
  Raises:
    Error: there was a problem getting volume info.
    ValueError: The UUID is formatted incorrectly.
  """
    if not util.UuidIsValid(uuid):
        raise ValueError('Invalid UUID: ' + uuid)
    try:
        plist = util.GetPlistFromExec(
            (DISKUTIL, 'corestorage', 'info', '-plist', uuid))
    except util.ExecError:
        logging.exception('GetVolumeSize() failed to get volume info: %s',
                          uuid)
        raise Error

    num_bytes = plist['CoreStorageLogicalVolumeSize']
    if readable:
        return '%.2f GiB' % (num_bytes / (1 << 30))
    else:
        return num_bytes
コード例 #9
0
ファイル: glue.py プロジェクト: tristansgray/cauliflowervest
def GetFilesystemType():
    try:
        plist = util.GetPlistFromExec((DISKUTIL, 'info', '-plist', '/'))
    except util.ExecError:
        logging.error('FilesystemType lookup failed.  Defaulting to hfs')
        return 'hfs'
    fstype = plist.get('FilesystemType', None)
    return fstype
コード例 #10
0
ファイル: apfs.py プロジェクト: optionalg/cauliflowervest
 def GetPrimaryVolumeUUID(self):
     """Returns string UUID of the boot volume (/), or None if error."""
     cmd = [DISKUTIL, 'info', '-plist', '/']
     try:
         plist = util.GetPlistFromExec(cmd)
     except util.ExecError:
         return None
     return plist.get('VolumeUUID')
コード例 #11
0
def IsBootVolumeEncrypted():
    """Returns True if the boot volume (/) is encrypted, False otherwise."""
    try:
        csinfo_plist = util.GetPlistFromExec(
            (DISKUTIL, 'cs', 'info', '-plist', '/'))
    except util.ExecError:
        return False  # Non-zero return means / volume isn't a CoreStorage volume.

    lvf_uuid = csinfo_plist.get('MemberOfCoreStorageLogicalVolumeFamily')
    if lvf_uuid:
        try:
            lvf_info_plist = util.GetPlistFromExec(
                (DISKUTIL, 'cs', 'info', '-plist', lvf_uuid))
        except util.ExecError:
            return False  # Couldn't get info on Logical Volume Family UUID.
        return lvf_info_plist.get(
            'CoreStorageLogicalVolumeFamilyEncryptionType') == 'AES-XTS'

    return False
コード例 #12
0
    def testGetPlistFromExec(self):
        self.mox.StubOutWithMock(util, 'Exec')
        self.mox.StubOutWithMock(util.plistlib, 'readPlistFromString')

        util.Exec('cmd', stdin='stdin').AndReturn((0, 'stdout', 'stderr'))
        util.plistlib.readPlistFromString('stdout').AndReturn('plist')

        self.mox.ReplayAll()
        self.assertEqual('plist', util.GetPlistFromExec('cmd', stdin='stdin'))
        self.mox.VerifyAll()
コード例 #13
0
ファイル: glue.py プロジェクト: smusa/cauliflowervest
    def EnableEncryption(self):
        """Enable full disk encryption.

    Returns:
      A 2-tuple containing the encrypted volume's UUID, and the recovery token.
    """
        try:
            result_plist = util.GetPlistFromExec(self._GetCommand(),
                                                 stdin=self._GetStdin())
        except util.ExecError as e:
            self._HandleFailure(e)
        return self._HandleResult(result_plist)
コード例 #14
0
ファイル: glue.py プロジェクト: tristansgray/cauliflowervest
def UpdateEscrowPassphrase(password, passphrase):
    """Change recovery passphrase."""
    command = ('sudo', '-k', '-S', FDESETUP_PATH, 'changerecovery',
               '-personal', '-outputplist', '-inputplist')

    stdin = plistlib.writePlistToString({'Password': passphrase})
    if os.getuid() != 0:
        stdin = '%s\n%s' % (password, stdin)

    try:
        result_plist = util.GetPlistFromExec(command, stdin=stdin)
    except util.ExecError as e:
        logging.error(e.stderr)
        raise Error(e.message)

    recovery_key = result_plist.get('RecoveryKey')
    return recovery_key
コード例 #15
0
ファイル: apfs.py プロジェクト: optionalg/cauliflowervest
    def _GetAPFSVolumesAndContainers(self, uuid=None, disk=None):
        """Returns a tuple of volumes and containers from apfs list -plist.

    Args:
      uuid: str, optional, APFSVolume uuid. If no uuid is provided, this
            function returns a diskutil apfs list plist..
      disk: str, optional, name of the disk to look at.
    Returns:
      A dict of diskutil cs info/list -plist output.
    Raises:
      Error: The given uuid was invalid or there was a diskutil error.
    """
        if uuid:
            if not util.UuidIsValid(uuid):
                raise storage.Error

        if disk or not self._containers:
            cmd = [DISKUTIL, 'apfs', 'list', '-plist']
            if disk:
                cmd.append(disk)
            try:
                plist = util.GetPlistFromExec(cmd)
            except util.ExecError:
                return ([], [])
            containers = plist.get('Containers', [])
            if containers:
                volumes = containers[0].get('Volumes', [])
            else:
                volumes = []

            if not disk:  # save the full list for future lookups
                self._containers = containers
                self._volumes = volumes
        else:
            containers = self._containers
            volumes = self._volumes

        if uuid:
            uuid_volumes = []
            for volume in volumes:
                if volume.get('APFSVolumeUUID') == uuid:
                    uuid_volumes.append(volume)
            return (uuid_volumes, containers)
        else:
            return (volumes, containers)
コード例 #16
0
def GetRecoveryPartition():
    """Determine the location of the recovery partition.

  Returns:
    str, like "/dev/disk0s3" where the recovery partition is, OR
    None, if no recovery partition exists or cannot be detected.
  """
    try:
        disklist_plist = util.GetPlistFromExec((DISKUTIL, 'list', '-plist'))
    except util.ExecError:
        logging.exception(
            'GetRecoveryPartition() failed to get partition list.')
        return

    alldisks = disklist_plist.get('AllDisksAndPartitions', [])
    for disk in alldisks:
        partitions = disk.get('Partitions', [])
        for partition in partitions:
            if partition.get('VolumeName') == 'Recovery HD':
                return '/dev/%s' % partition['DeviceIdentifier']
コード例 #17
0
def GetCoreStoragePlist(uuid=None):
    """Returns a dict of diskutil cs info plist for a given str CoreStorage uuid.

  Args:
    uuid: str, optional, CoreStorage uuid. If no uuid is provided, this function
          returns a diskutil cs list plist..
  Returns:
    A dict of diskutil cs info/list -plist output.
  Raises:
    Error: The given uuid was invalid or there was a diskutil error.
  """
    if uuid:
        if not util.UuidIsValid(uuid):
            raise Error
        cmd = [DISKUTIL, 'corestorage', 'info', '-plist', uuid]
    else:
        cmd = [DISKUTIL, 'corestorage', 'list', '-plist']
    try:
        return util.GetPlistFromExec(cmd)
    except util.ExecError:
        raise Error
コード例 #18
0
    """Base class for all errors raised by options."""


def ApplyEncryption(fvclient, username, password):
    """Turn encryption on."""

    # Supply entropy to the system before csfde uses /dev/random.
    try:
        entropy = util.RetrieveEntropy()
        util.SupplyEntropy(entropy)
    except util.EntropyError, e:
        raise Error('Entropy operations failed: %s' % str(e))

    root_disk = util.GetRootDisk()
    try:
        csfde_plist = util.GetPlistFromExec(
            (CSFDE_PATH, root_disk, username, '-'), stdin=password)
    except util.ExecError, e:
        if e.returncode == CSFDE_RETURN_AUTH_FAIL:
            raise InputError(
                'Authentication problem with local account.  Drive NOT encrypted.'
            )
        elif e.returncode != 0:
            logging.error('csfde failed with stderr:\n%s', e.stderr)
            raise Error('Problem running csfde (exit status = %d)' %
                        e.returncode)
        else:
            logging.exception('Problem running csfde.')
            raise Error('Problem running csfde', e)
    fvclient.SetOwner(username)

    return GetEncryptionResults(csfde_plist)
コード例 #19
0
ファイル: util_test.py プロジェクト: kelvin55/cauliflowervest
    def testGetPlistFromExec(self, exec_mock, read_plist_mock):
        self.assertEqual('plist', util.GetPlistFromExec('cmd', stdin='stdin'))

        exec_mock.assert_called_once_with('cmd', stdin='stdin')
        read_plist_mock.assert_called_once_with('stdout')