Ejemplo n.º 1
0
    def GetVolumeSize(self, 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.
      InvalidUUIDError: The UUID is formatted incorrectly.
    """
        if not util.UuidIsValid(uuid):
            raise storage.InvalidUUIDErrorError('Invalid UUID: ' + uuid)
        (volumes, containers) = self._GetAPFSVolumesAndContainers(uuid)

        num_bytes = 0
        for volume in volumes:
            if volume.get('APFSVolumeUUID') == uuid:
                num_bytes = (containers[0].get('CapacityFree') +
                             volume.get('CapacityInUse'))
                break

        if readable:
            return '%.2f GiB' % (num_bytes / (1 << 30))
        else:
            return num_bytes
Ejemplo n.º 2
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
Ejemplo n.º 3
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
Ejemplo n.º 4
0
def UnlockVolume(uuid, passphrase):
    """Unlock a core storage encrypted volume.

  Args:
    uuid: str, uuid of the volume to unlock.
    passphrase: str, passphrase to unlock the volume.
  Raises:
    CouldNotUnlockError: the volume cannot be unlocked.
    ValueError: The UUID is formatted incorrectly.
  """
    if not util.UuidIsValid(uuid):
        raise ValueError('Invalid UUID: ' + uuid)
    returncode, _, stderr = util.Exec(
        (DISKUTIL, 'corestorage', 'unlockVolume', uuid, '-stdinpassphrase'),
        stdin=passphrase)
    if returncode != 0 and not 'volume is not locked' in stderr:
        raise CouldNotUnlockError('Could not unlock volume (%s).' % returncode)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    def UnlockVolume(self, uuid, passphrase):
        """Unlock an APFS encrypted volume.

    Args:
      uuid: str, uuid of the volume to unlock.
      passphrase: str, passphrase to unlock the volume.
    Raises:
      CouldNotUnlockError: the volume cannot be unlocked.
      InvalidUUIDError: The UUID is formatted incorrectly.
    """
        if not util.UuidIsValid(uuid):
            raise storage.InvalidUUIDError('Invalid UUID: ' + uuid)
        returncode, _, stderr = util.Exec(
            (DISKUTIL, 'apfs', 'unlockVolume', uuid, '-stdinpassphrase'),
            stdin=passphrase)
        if (returncode != 0 and 'volume is not locked' not in stderr
                and 'is already unlocked' not in stderr):
            raise storage.CouldNotUnlockError('Could not unlock volume (%s).' %
                                              returncode)
Ejemplo n.º 7
0
def RevertVolume(uuid, passphrase):
    """Revert a core storage encrypted volume (to unencrypted state).

  Args:
    uuid: str, uuid of the volume to revert.
    passphrase: str, passphrase to unlock the volume.
  Raises:
    CouldNotRevertError: the volume was unlocked, but cannot be reverted.
    CouldNotUnlockError: the volume cannot be unlocked.
    ValueError: The UUID is formatted incorrectly.
  """
    if not util.UuidIsValid(uuid):
        raise ValueError('Invalid UUID: ' + uuid)
    UnlockVolume(uuid, passphrase)
    returncode, _, _ = util.Exec(
        (DISKUTIL, 'corestorage', 'revert', uuid, '-stdinpassphrase'),
        stdin=passphrase)
    if returncode != 0:
        raise CouldNotRevertError('Could not revert volume (%s).' % returncode)
Ejemplo n.º 8
0
    def RevertVolume(self, uuid, passphrase, passwd=''):
        """Disable encryption on an APFS system.

    Args:
      uuid: str, uuid of the volume to revert.
      passphrase: str, passphrase to unlock the volume.
      passwd: str, password for sudo
    Raises:
      CouldNotRevertError: the volume was unlocked, but cannot be reverted.
      CouldNotUnlockError: the volume cannot be unlocked.
      InvalidUUIDError: The UUID is formatted incorrectly.
    """
        if not util.UuidIsValid(uuid):
            raise storage.InvalidUUIDError('Invalid UUID: ' + uuid)
        self.UnlockVolume(uuid, passphrase)
        returncode, _, _ = util.Exec(('sudo', '-k', '-S', FDESETUP, 'disable'),
                                     stdin=passwd + '\n')

        if returncode != 0:
            raise storage.CouldNotRevertError(
                'Could not disable encryption (%s).' % (returncode))
Ejemplo n.º 9
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