#!/usr/bin/python
# Copyright 2011-2014 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Image installer for Google Fiber CPE devices."""

__author__ = 'dgentry@google.com (Denton Gentry)'

import os
import re
import StringIO
import struct
import subprocess
import sys
import tarfile
import zlib
from Crypto.Hash import SHA512
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
import options


optspec = """
ginstall -p <partition>
ginstall -p <partition> -t <tarfile> [options...]
ginstall -p <partition> -k <kernel> -r <rootfs> [options...]
--
t,tar=        tar archive containing kernel and rootfs
k,kernel=     kernel image filename to install
r,rootfs=     rootfs UBI image filename to install
skiploader    skip installing bootloader (dev-only)
loader=       bootloader file to install
loadersig=    bootloader signature filename
manifest=     manifest file
drm=          drm blob filename to install
p,partition=  partition to install to (primary, secondary, or other)
q,quiet       suppress unnecessary output
skiploadersig suppress checking the loader signature
uloader=      microloader file to install
"""


# unit tests can override these with fake versions
BUFSIZE = 64 * 1024
ETCPLATFORM = '/etc/platform'
ETCVERSION = '/etc/version'
SECUREBOOT = '/tmp/gpio/ledcontrol/secure_boot'
HNVRAM = 'hnvram'
MTD_PREFIX = '/dev/mtd'
SYSCLASSMTD = '/sys/class/mtd'
MMCBLK = '/dev/mmcblk0'
PROC_CMDLINE = '/proc/cmdline'
PROC_MTD = '/proc/mtd'
SGDISK = 'sgdisk'
SIGNINGKEY = '/etc/gfiber_public.der'
GZIP_HEADER = '\x1f\x8b\x08'  # encoded as string to ignore endianness


# Verbosity of output
quiet = False

default_manifest_v2 = {
    'installer_version': '2',
    'platforms': ['GFHD100', 'GFMS100'],
    'image_type': 'unlocked'
}

default_manifest_files = {
    'installer_version': '2',
    'image_type': 'unlocked'
}


class Fatal(Exception):
  """An exception that we print as just an error, with no backtrace."""
  pass


def Verify(f, s, k):
  key = RSA.importKey(k)
  h = SHA512.new(f.read())
  v = PKCS1_v1_5.new(key)
  return v.verify(h, s.read())


def Log(s, *args):
  sys.stdout.flush()
  if args:
    sys.stderr.write(s % args)
  else:
    sys.stderr.write(str(s))


def VerbosePrint(s, *args):
  if not quiet:
    Log(s, *args)


def GetPlatform():
  return open(ETCPLATFORM).read().strip()


def GetVersion():
  return open(ETCVERSION).read().strip()


def SetBootPartition(partition):
  VerbosePrint('Setting boot partition to kernel%d\n', partition)
  cmd = [HNVRAM, '-q', '-w', 'ACTIVATED_KERNEL_NAME=kernel%d' % partition]
  return subprocess.call(cmd)


def GetBootedPartition():
  """Get the role of partition where the running system is booted from.

  Returns:
    0 or 1 for rootfs0 and rootfs1, or None if not booted from flash.
  """
  try:
    with open(PROC_CMDLINE) as f:
      cmdline = f.read().strip()
  except IOError:
    return None
  for arg in cmdline.split(' '):
    if arg.startswith('root='):
      partition = arg.split('=')[1]
      if partition == 'rootfs0':
        return 0
      elif partition == 'rootfs1':
        return 1
  return None


def PickFreeUbi():
  for i in range(32):
    if not os.path.exists('/dev/ubi%d' % i):
      return i
  raise Fatal('no free /dev/ubi devices found')


def GetMtdDevForNameOrNone(partname):
  """Find the mtd# for a named partition.

  In /proc/mtd we have:

  dev:    size   erasesize  name
  mtd0: 00200000 00010000 "cfe"
  mtd1: 00200000 00010000 "reserve0"
  mtd2: 10000000 00100000 "kernel0"
  mtd3: 10000000 00100000 "kernel1"

  Args:
    partname: the partition to find. For example, "kernel0"

  Returns:
    The mtd device, for example "mtd2"
  """
  quotedname = '"%s"' % partname
  # read the whole file at once to avoid race conditions in case it changes
  data = open(PROC_MTD).read().split('\n')
  for line in data:
    fields = line.strip().split()
    if len(fields) >= 4 and fields[3] == quotedname:
      assert fields[0].startswith('mtd')
      assert fields[0].endswith(':')
      return '%s%d' % (MTD_PREFIX, int(fields[0][3:-1]))
  return None  # no match


def IsMtdNand(mtddevname):
  mtddevname = re.sub(r'^' + MTD_PREFIX, 'mtd', mtddevname)
  path = SYSCLASSMTD + '/{0}/type'.format(mtddevname)
  data = open(path).read()
  return 'nand' in data


def GetMtdDevForName(partname):
  """Like GetMtdDevForNameOrNone, but raises an exception on failure."""
  mtd = GetMtdDevForNameOrNone(partname)
  if not mtd:
    raise KeyError(partname)
  return mtd


def GetMtdDevForNameList(names):
  """Find the first mtd partition with any of the given names.

  Args:
    names: List of partition names.

  Returns:
    The mtd of the first name to match, or None of there is no match.
  """
  for name in names:
    mtd = GetMtdDevForNameOrNone(name)
    if mtd: return mtd
  raise KeyError(names)


def GetGptPartitionForName(name):
  """Find the mmcmlk0p# for a named partition.

  From sgdisk -p we have:

  Number  Start (sector)    End (sector)  Size       Code  Name
     1           34816         1083391   512.0 MiB   0700  image0
     2         1083392         2131967   512.0 MiB   0700  image1
     3         2131968         2263039   64.0 MiB    0700  emergency
     4         2263040         2525183   128.0 MiB   8300  config
     5         2525184         6719487   2.0 GiB     8300  user
  """
  cmd = [SGDISK, '-p', MMCBLK]
  devnull = open('/dev/null', 'w')
  try:
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=devnull)
  except OSError:
    return None  # no sgdisk, must not be a platform that supports it
  mmcpart = None
  for line in p.stdout:
    fields = line.strip().split()
    if len(fields) == 7 and fields[6] == name:
      mmcpart = MMCBLK + 'p' + fields[0]
  p.wait()
  return mmcpart


def IsDeviceNoSigning():
  """Returns true if the platform does not handle a kernel header prepended."""
  return False


# TODO(apenwarr): instead of re-reading the source file, use a checksum.
#  This will be especially important later when we want to avoid ever reading
#  the input file twice, so we can stream it from stdin.
def IsIdentical(description, srcfile, dstfile):
  """Compare srcfile and dstfile. Return true if contents are identical."""
  VerbosePrint('Verifying %s.\n', description)
  sbuf = srcfile.read(BUFSIZE)
  dbuf = dstfile.read(len(sbuf))
  if not sbuf:
    raise IOError('IsIdentical: srcfile is empty?')
  if not dbuf:
    raise IOError('IsIdentical: dstfile is empty?')
  while sbuf and dbuf:
    if sbuf != dbuf:
      return False
    sbuf = srcfile.read(BUFSIZE)
    dbuf = dstfile.read(len(sbuf))
    VerbosePrint('.')
  VerbosePrint('\n')
  return True


def GetFileSize(f):
  """Return size of a file like object."""
  current = f.tell()
  f.seek(0, os.SEEK_END)
  size = f.tell()
  f.seek(current, os.SEEK_SET)
  return size


def SilentCmd(name, *args):
  """Wrapper for program calls that doesn't print or check errors."""
  null = open('/dev/null', 'w')
  cmd = [name] + list(args)
  subprocess.call(cmd, stderr=null)


def Cmd(name, *args):
  """Wrapper for program calls."""
  cmd = [name] + list(args)
  VerbosePrint('%s\n' % cmd)
  rc = subprocess.call(cmd)
  if rc != 0:
    raise IOError('Error: %r' % (cmd,))


def EraseMtd(mtddevname):
  """Erase an mtd partition."""
  VerbosePrint('Erasing flash partition %r\n', mtddevname)
  cmd = ['flash_erase', '--quiet', mtddevname, '0', '0']
  return subprocess.call(cmd)


def Nandwrite(f, mtddevname):
  """Write file to NAND flash using nandwrite."""
  cmd = ['nandwrite', '--quiet', '--markbad', mtddevname]
  VerbosePrint('%s\n' % cmd)
  p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
  written = WriteToFile(f, p.stdin)
  p.stdin.close()
  p.wait()
  return written


def Pad(data, bufsize):
  if len(data) < bufsize:
    return data + '\xff' * (bufsize - len(data))
  else:
    return data


def WriteToFile(srcfile, dstfile):
  """Copy all bytes from srcfile to dstfile."""
  buf = srcfile.read(BUFSIZE)
  totsize = 0
  while buf:
    totsize += len(buf)
    dstfile.write(Pad(buf, BUFSIZE))
    buf = srcfile.read(BUFSIZE)
    VerbosePrint('.')
  dstfile.flush()
  VerbosePrint('\n')
  return totsize


def _CopyAndVerify(description, inf, outf):
  """Copy data from file object inf to file object outf, then verify it."""
  start = inf.tell()
  written = WriteToFile(inf, outf)
  inf.seek(start, os.SEEK_SET)
  outf.seek(0, os.SEEK_SET)
  if not IsIdentical(description, inf, outf):
    raise IOError('Read-after-write verification failed')
  return written


def _CopyAndVerifyNand(f, mtddevname):
  """Copy data from file object f to NAND flash mtddevname, then verify it."""
  start = f.tell()
  VerbosePrint('Writing to NAND partition %r\n', mtddevname)
  written = Nandwrite(f, mtddevname)
  f.seek(start, os.SEEK_SET)
  cmd = ['nanddump', '--bb=skipbad', '--length=%d' % written, '--quiet', mtddevname]
  VerbosePrint('%s\n' % cmd)
  p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
  if not IsIdentical(mtddevname, f, p.stdout):
    raise IOError('Read-after-write verification failed')
  while p.stdout.read(BUFSIZE):
    pass
  p.wait()


def InstallToMtd(f, mtddevname):
  """Write an image to an mtd device."""
  if EraseMtd(mtddevname):
    raise IOError('Flash erase failed.')
  VerbosePrint('Writing to mtd partition %r\n', mtddevname)
  # TODO(danielmentz): _CopyAndVerifyNand is based on the external tool
  # nandwrite which can handle bad erase blocks i.e. it skips them. The
  # bootloader (CFE) on the bruno platform (CPE 1.0) cannot handle bad blocks
  # at the moment so let's keep on using _CopyAndVerify on this platform.
  # _CopyAndVerify will throw an exception during the verification step which
  # is more desirable than installing a bad kernel image and depending on CFE
  # to fall back to the other kernel partition.
  if IsMtdNand(mtddevname) and GetPlatform().startswith('GFRG2'):
    return _CopyAndVerifyNand(f, mtddevname)
  else:
    return _CopyAndVerify(mtddevname, f, open(mtddevname, 'r+b'))


def InstallToFile(f, outfilename):
  """Write the file-like object f to file named outfilename."""
  VerbosePrint('Writing to raw file %r\n', outfilename)
  return _CopyAndVerify(outfilename, f, open(outfilename, 'w+b'))


def InstallRawFileToUbi(f, mtddevname):
  """Write an image without its own ubi header to a ubi device.

  Args:
    f: a file-like object holding the image to be installed.
    mtddevname: the device filename of the mtd partition to install to.
    ubino: the ubi device number to use.

  Raises:
    IOError: when ubi format fails

  Returns:
    number of bytes written.
  """
  ubino = PickFreeUbi()
  SilentCmd('ubidetach', '-p', mtddevname)
  Cmd('ubiformat', '-y', '-q', mtddevname)
  Cmd('ubiattach', '-p', mtddevname, '-d', str(ubino))
  try:
    Cmd('ubimkvol', '-N', 'rootfs-prep', '-m', '/dev/ubi%d' % ubino)
    newmtd = GetMtdDevForName('rootfs-prep')
    siz = InstallToMtd(f, newmtd)
    Cmd('ubirename', '/dev/ubi%d' % ubino, 'rootfs-prep', 'rootfs')
  finally:
    SilentCmd('ubidetach', '-d', str(ubino))
  return siz


def WriteDrm(opt):
  """Write DRM Keyboxes."""
  Log('DO NOT INTERRUPT OR POWER CYCLE, or you will lose drm capability.\n')
  drm = open(opt.drm, 'rb')
  mtddevname = GetMtdDevForName('drmregion0')
  VerbosePrint('Writing drm to %r\n', mtddevname)
  InstallToMtd(drm, mtddevname)

  drm.seek(0)
  mtddevname = GetMtdDevForName('drmregion1')
  VerbosePrint('Writing drm to %r\n', mtddevname)
  InstallToMtd(drm, mtddevname)


def GetKey():
  """Return the key to check file signatures."""
  try:
    return open(SIGNINGKEY).read()
  except IOError, e:
    raise Fatal(e)


def ParseManifest(f):
  """Parse a ginstall image manifest.
  Example:
    installer_version: 99
    image_type: fake
    platforms: [ GFHD100, GFMS100 ]
  Args:
    f: a file-like object for the manifest file
  Returns:
    a dict of the fields in the manifest.
  """
  result = {}
  for line in f:
    fields = line.split(':', 1)
    if len(fields) == 2:
      key = fields[0].strip()
      val = fields[1].strip()
      if val.startswith('['):  # [ GFHD100, GFMS100 ]
        val = re.sub(r'[\[\],\s]', r' ', val).split()
      result[key] = val
  return result


def CheckPlatform(manifest):
  platform = GetPlatform()
  platforms = manifest['platforms']
  for p in platforms:
    if p.lower() == platform.lower():
      return True
  raise Fatal('Package supports %r, but this device is %r'
              % (platforms, platform))


def CheckManifestVersion(img):
  v = img.ManifestVersion()
  if v >= 2 and v <= 4:
    return True
  else:
    raise Fatal('Incompatible manifest version: "%s"' % v)

def ParseVersionString(ver):
  """
  Extract major and minor revision number from version string.

  Args:
    ver: Version string
  Returns:
    A tuple (major, minor) or None if string cannot be parsed. Return 0 for
    minor if minor revision number cannot be parsed.

  Example:
    'abc-<x>.<y>junk' -> (x,y)
    'gfrg200-39-pre1-60-g2841888-da' -> (39,0)
    'gfrg200-38.6a3-ap' -> (38.6)
    'gfrg200-38-pre2-125-g403f9a3-da' -> (38,0)
  """
  m = re.match(r'[^-]+-(\d+)(?:\.(\d+))?', ver)
  if not m:
    return None
  return (int(m.group(1)), int(m.group(2)) if m.group(2) else 0)


def CheckVersion(manifest):
  minimum_version = manifest.get('minimum_version')
  if not minimum_version: return True
  our_version = GetVersion()
  min_version = ParseVersionString(minimum_version)
  if not min_version:
    raise Fatal('Cannot parse minimum_version field "%s" in manifest' %
        minimum_version)
  if ParseVersionString(our_version) >= min_version:
    return True
  raise Fatal('Package requires minimum version %s, but we are running %s'
              % (minimum_version, our_version))


def CheckMisc(img):
  """
  Miscellaneous sanity checks.
  """
  if (GetPlatform() == 'GFHD200' and BroadcomDeviceIsSecure() and
          (ParseVersionString(img.GetVersion()) < (38, 11) or
           img.GetVersion().startswith('gftv200-39-pre0') or
           img.GetVersion().startswith('gftv200-39-pre1') )):
      raise Fatal('Refusing to install gftv200-38.10 and before, and gftv200-39-pre1 and before.')
  return True


class FileImage(object):
  """A system image packaged as separate kernel, rootfs and loader files."""

  def __init__(self, kernelfile, rootfs, loader, loadersig, manifest, uloader):
    self.kernelfile = kernelfile
    self.rootfs = rootfs
    self.loader = loader
    self.loadersig = loadersig
    self.uloader = uloader
    if manifest:
      self.manifest = ParseManifest(open(manifest))
    else:
      self.manifest = default_manifest_files.copy()
      self.manifest['platforms'] = [GetPlatform()]

  def ManifestVersion(self):
    return int(self.manifest['installer_version'])

  def GetVersion(self):
    return None

  def GetLoader(self):
    if self.loader:
      try:
        return open(self.loader, 'rb')
      except IOError, e:
        raise Fatal(e)
    else:
      return None

  def GetUloader(self):
    if self.uloader:
      try:
        return open(self.uloader, 'rb')
      except IOError, e:
        raise Fatal(e)
    else:
      return None

  def GetKernel(self):
    if self.kernelfile:
      try:
        return open(self.kernelfile, 'rb')
      except IOError, e:
        raise Fatal(e)
    else:
      return None

  def GetRootFs(self):
    if self.rootfs:
      try:
        return open(self.rootfs, 'rb')
      except IOError, e:
        raise Fatal(e)
    else:
      return None

  def GetLoaderSig(self):
    if self.loadersig:
      try:
        return open(self.loadersig, 'rb')
      except IOError, e:
        raise Fatal(e)
    else:
      return None


class TarImage(object):
  """A system image packaged as a tar file."""

  def __init__(self, tarfilename):
    self.tarfilename = tarfilename
    self.tar_f = tarfile.open(name=tarfilename)
    fnames = self.tar_f.getnames()
    self.rootfs = None

    for fname in fnames:
      if fname.startswith('rootfs.'):
        self.rootfs = fname
        break

    f = None
    for m in ['MANIFEST', 'manifest']:
      try:
        f = self.tar_f.extractfile(m)
        break
      except KeyError:
        pass
    if not f:
      # No manifest; it must be an old-style installer.
      # Generate an auto-manifest compatible with older files.
      self.manifest = default_manifest_v2.copy()
      try:
        self.manifest['version'] = (
            self.tar_f.extractfile('version').read(4096).strip())
      except KeyError:
        pass
    else:
      self.manifest = ParseManifest(f)

  def ManifestVersion(self):
    return int(self.manifest['installer_version'])

  def GetVersion(self):
    try:
      return self.manifest['version']
    except KeyError:
      raise Fatal('Fatal: image file has no version field')

  def GetKernel(self):
    # TV boxes use a raw vmlinu* file, the gflt* install a uImage to
    # the kernel partition.
    if self.ManifestVersion() > 2:
      kernel_names = ['kernel.img']
    else:
      kernel_names = ['vmlinuz', 'vmlinux', 'uImage']
    for name in kernel_names:
      try:
        return self.tar_f.extractfile(name)
      except KeyError:
        pass
    return None

  def GetRootFs(self):
    if not self.rootfs:
      return None
    try:
      return self.tar_f.extractfile(self.rootfs)
    except KeyError:
      return None

  def GetLoader(self):
    try:
      filename = 'loader.img' if self.ManifestVersion() > 2 else 'loader.bin'
      return self.tar_f.extractfile(filename)
    except KeyError:
      return None

  def GetLoaderSig(self):
    try:
      return self.tar_f.extractfile('loader.sig')
    except KeyError:
      return None

  def GetUloader(self):
    try:
      # Image versions prior to v3 never included a uloader.
      return self.tar_f.extractfile('uloader.img')
    except KeyError:
      return None


def WriteLoaderToMtd(loader, loader_start, mtd, description):
  is_loader_current = False
  with open(mtd, 'rb') as mtdfile:
    VerbosePrint('Checking if the %s is up to date.\n', description)
    loader.seek(loader_start)
    is_loader_current = IsIdentical(description, loader, mtdfile)
  if is_loader_current:
    VerbosePrint('The %s is the latest.\n', description)
  else:
    loader.seek(loader_start, os.SEEK_SET)
    Log('DO NOT INTERRUPT OR POWER CYCLE, or you will brick the unit.\n')
    VerbosePrint('Writing to %r\n', mtd)
    InstallToMtd(loader, mtd)


def main():
  global quiet  # gpylint: disable-msg=global-statement
  o = options.Options(optspec)
  opt, unused_flags, unused_extra = o.parse(sys.argv[1:])

  if not (opt.drm or opt.kernel or opt.rootfs or opt.loader or opt.tar or
          opt.partition):
    o.fatal('Expected at least one of -p, -k, -r, -t, --loader, or --drm')

  quiet = opt.quiet

  if opt.drm:
    WriteDrm(opt)

  if (opt.kernel or opt.rootfs or opt.tar) and not opt.partition:
    # default to the safe option if not given
    opt.partition = 'other'

  if opt.partition == 'other':
    boot = GetBootedPartition()
    assert boot in [None, 0, 1]
    if boot is None:
      # Policy decision: if we're booted from NFS, install to secondary
      partition = 1
    else:
      partition = boot ^ 1
  elif opt.partition in ['primary', 0]:
    partition = 0
  elif opt.partition in ['secondary', 1]:
    partition = 1
  elif opt.partition:
    o.fatal('--partition must be one of: primary, secondary, other')
  elif opt.tar or opt.kernel or opt.rootfs:
    o.fatal('A --partition option must be provided with -k, -r, or -t')
  else:
    partition = None

  if opt.tar or opt.kernel or opt.rootfs or opt.loader:
    key = GetKey()
    if opt.tar:
      img = TarImage(opt.tar)
      if opt.kernel or opt.rootfs or opt.loader or opt.loadersig:
        o.fatal('--tar option is incompatible with -k, -r, '
                '--loader and --loadersig')
    else:
      img = FileImage(opt.kernel, opt.rootfs, opt.loader, opt.loadersig,
                      opt.manifest, opt.uloader)

    # old software versions are incompatible with this version of ginstall.
    # In particular, we want to leave out versions that:
    #  - don't support 1GB NAND layout.
    #  - use pre-ubinized files instead of raw rootfs images.
    ver = img.GetVersion()
    if ver and (
        ver.startswith('bruno-') or
        (ver.startswith('gfibertv-') and ver < 'gfibertv-24')):
      raise Fatal('%r is too old: aborting.\n' % ver)

    manifest = img.manifest
    CheckPlatform(manifest)
    CheckManifestVersion(img)
    CheckVersion(manifest)
    CheckMisc(img)

    rootfs = img.GetRootFs()
    if rootfs:
      partition_name = 'rootfs%d' % partition
      mtd = GetMtdDevForNameOrNone(partition_name)
      gpt = GetGptPartitionForName(partition_name)
      if mtd:
        Log('Installing raw rootfs image to ubi partition %r\n' % mtd)
        VerbosePrint('Writing raw rootfs to %r\n', mtd)
        InstallRawFileToUbi(rootfs, mtd)
      elif gpt:
        VerbosePrint('Writing raw rootfs to %r\n', gpt)
        InstallToFile(rootfs, gpt)
      else:
        raise Fatal('no partition named %r is available' % partition_name)

    kern = img.GetKernel()
    if kern:
      if IsDeviceNoSigning():
        buf = kern.read(4100)
        if buf[0:3] != GZIP_HEADER and buf[4096:4099] == GZIP_HEADER:
          VerbosePrint('Incompatible device: removing kernel signing.\n')
          kern.seek(4096)
        elif buf[0:3] == GZIP_HEADER:
          kern.seek(0)
        else:
          raise Fatal('Incompatible device: unrecognized kernel format')
      partition_name = 'kernel%d' % partition
      mtd = GetMtdDevForNameOrNone(partition_name)
      gpt = GetGptPartitionForName(partition_name)
      if mtd:
        VerbosePrint('Writing kernel to %r\n' % mtd)
        InstallToMtd(kern, mtd)
      elif gpt:
        VerbosePrint('Writing kernel to %r\n' % gpt)
        InstallToFile(kern, gpt)
      else:
        raise Fatal('no partition named %r is available' % partition_name)

    loader = img.GetLoader()
    if loader:
      loader_start = loader.tell()
      if opt.skiploader:
        VerbosePrint('Skipping loader installation.\n')
      else:
        # TODO(jnewlin): Temporary hackage.  v3 of ginstall will have a
        # signature over the entire file as opposed to just on the loader and
        # we can drop this loader signature.  For now allow a command line
        # opt to disable signature checking.
        if not opt.skiploadersig:
          loadersig = img.GetLoaderSig()
          if not loadersig:
            raise Fatal('Loader signature file is missing; try --loadersig')
          if not Verify(loader, loadersig, key):
            raise Fatal('Loader signing check failed.')
        installed = False
        for i in ['cfe', 'loader', 'loader0', 'loader1']:
          mtd = GetMtdDevForNameOrNone(i)
          if mtd:
            WriteLoaderToMtd(loader, loader_start, mtd, 'loader')
            installed = True
        if not installed:
          raise Fatal('no loader partition is available')

    uloader = img.GetUloader()
    if uloader:
      uloader_start = uloader.tell()
      if opt.skiploader:
        VerbosePrint('Skipping uloader installation.\n')
      else:
        mtd = GetMtdDevForNameOrNone('uloader')
        if mtd:
          uloader_signed = UloaderSigned(uloader)
          device_secure = C2kDeviceIsSecure(mtd)
          if uloader_signed and not device_secure:
            VerbosePrint('Signed uloader but unsecure box; stripping sig.\n')
            uloader, uloader_start = StripUloader(uloader, uloader_start)
          elif not uloader_signed and device_secure:
            raise Fatal('Unable to install unsigned uloader on secure device.')
          WriteLoaderToMtd(uloader, uloader_start, mtd, 'uloader')

  if partition is not None:
    SetBootPartition(partition)

  return 0


def BroadcomDeviceIsSecure():
  """Determines whether a Broadcom device is secure."""
  return os.path.isfile(SECUREBOOT)


def C2kDeviceIsSecure(uloader_mtddevname):
  """Determines whether a Mindspeed C2k device verifies uloader signature.

  Currently this is done by examining the currently installed uloader.

  Args:
    uloader_mtddevname: Name of the mtd device containing the installed uloader

  Returns:
    True if the device is insecure, False otherwise
  """
  # TODO(smcgruer): Also check the OTP, raise exception if they differ.

  with open(uloader_mtddevname, 'r+b') as installed_uloader:
    return UloaderSigned(installed_uloader)


def UloaderSigned(uloader_file):
  """Determines if the given uloader file is signed or unsigned.

  The file's current location will be saved and restored when the
  function exits.

  Args:
    uloader_file: A file object containing the uloader to be checked.

  Returns:
    True if the passed uloader is signed, false otherwise.
  """

  current_loc = uloader_file.tell()

  # The simplest check for a signed uloader is to examine byte 16 (zero-indexed)
  # of the header, which indicates the key type.

  uloader_file.seek(0)
  header = uloader_file.read(20)
  uloader_file.seek(current_loc)

  return header[16] == '\x02'


def StripUloader(uloader, uloader_start):
  """Strips a signed uLoader, allowing it to be installed on an insecure device.

  IMPORTANT: This method will close the given uloader file. A new, memory-backed
  file is returned in its place.

  Args:
    uloader: A signed uloader file.
    uloader_start: The start offset of the given uLoader file.

  Returns:
    A tuple (uloader, uloader_start), containing the stripped uloader file and
    its start position.
  """

  uloader.seek(uloader_start)
  uloader_data = uloader.read()
  uloader.close()

  # The signed header includes 24 bytes of metadata and a 256 byte hash.
  header = list(uloader_data[:280])

  # Magic number and timestamp.
  new_header = header[:8]

  # CRC (initialized to 0s), embedded key length, and key type.
  new_header += '\x00' * 12

  # Image length.
  new_header += header[20:24]

  # Padding.
  new_header += '\x00' * 32

  # Calculate a CRC for the new header.
  new_header_string = ''.join(new_header)
  crc = zlib.crc32(new_header_string) & 0xFFFFFFFF
  new_header[8:12] = struct.pack('<I', crc)

  new_uloader = StringIO.StringIO()
  new_uloader.write(''.join(new_header))
  new_uloader.write(uloader_data[280:])
  new_uloader.seek(0)

  return new_uloader, new_uloader.tell()


if __name__ == '__main__':
  try:
    try:
      p = subprocess.Popen(['psback'], stdout=subprocess.PIPE)
      psback = p.stdout.readline().strip()
      p.wait()
      p = subprocess.Popen(['logos', 'ginstall'], stdin=subprocess.PIPE)
      p.stdin.write('args: %r\ncalled by: %s\n' % (sys.argv, psback))
      p.stdin.close()
      p.wait()
    except OSError:
      Log('W: psback/logos unavailable for tracing.\n')
    sys.exit(main())
  except Fatal, e:
    Log('%s\n', e)
    sys.exit(1)
