#============================================================================
#Name : iadinfo.py
#Part of : Helium
#Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
#All rights reserved.
#This component and the accompanying materials are made available
#under the terms of the License "Eclipse Public License v1.0"
#which accompanies this distribution, and is available
#at the URL "http://www.eclipse.org/legal/epl-v10.html".
#
#Initial Contributors:
#Nokia Corporation - initial contribution.
#
#Contributors:
#
#Description:
#===============================================================================
import optparse
import sys, os
import struct
import zlib
import pdb
PyASN1Availabe = True
try :
from pyasn1.codec.der import decoder
from pyasn1.type import univ, base
except :
PyASN1Availabe = False
def _findItem(item, itemParent, index, objectIdentifier) :
if isinstance(item, base.AbstractSimpleAsn1Item) :
if item == objectIdentifier :
return itemParent[index + 1]
else:
for i in range(len(item)) :
found = _findItem(item[i], item, i, objectIdentifier)
if found:
return found
def findItem(decodedCert, objectIdentifier) :
return _findItem(decodedCert, None, 0, objectIdentifier)
class CertificateOrganization :
def __init__(self) :
pass
def parse(self, decodedCert) :
self.commonName = findItem(decodedCert, (2, 5, 4, 3))
self.countryCode = findItem(decodedCert, (2, 5, 4, 6))
self.locality = findItem(decodedCert, (2, 5, 4, 7))
self.state = findItem(decodedCert, (2, 5, 4, 8))
self.street = findItem(decodedCert, (2, 5, 4, 9))
self.organization = findItem(decodedCert, (2, 5, 4, 10))
def readableStr(self) :
buf = ""
if self.commonName :
buf += self.commonName.prettyPrint() + "\n"
if self.countryCode :
buf += self.countryCode.prettyPrint() + "\n"
if self.locality :
buf += self.locality.prettyPrint() + "\n"
if self.state :
buf += self.state.prettyPrint() + "\n"
if self.street :
buf += self.street.prettyPrint() + "\n"
if self.organization :
buf += self.organization.prettyPrint()
return buf
class CertificateInfo :
def __init__(self) :
pass
def parse(self, decodedCert) :
self.issuer = CertificateOrganization()
self.issuer.parse(decodedCert[0][3])
self.signer = CertificateOrganization()
self.signer.parse(decodedCert[0][5])
def readableStr(self) :
buf = "Signer:\n " + "\n ".join(self.signer.readableStr().split('\n')) + "\n"
buf += "Issuer:\n " + "\n ".join(self.issuer.readableStr().split('\n')) + "\n"
return buf
class SISFileHeader :
def __init__(self) :
self.uid1 = 0
self.uid2 = 0
self.uid3 = 0
self.uidChecksum = 0
class SISField :
def __init__(self) :
self.type = 0
self.length = None
self.subFields = []
def readFieldLength(self, fileReader) :
length = fileReader.readBytesAsUint(4)
if length & 0x80000000 > 0 :
length = length << 32
length |= fileReader.readBytesAsUint(4)
return length
def findField(self, fieldType, startIndex=0) :
result = None
index = startIndex
for field in self.subFields[startIndex:] :
if field.type == fieldType :
result = field
break
++ index
return (result, index)
def readableStr(self) :
return ""
def traverse(self, handler, depth=0) :
handler.handleField(self, depth)
for field in self.subFields :
field.traverse(handler, depth + 1)
class SISUnsupportedField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fileReader.readPlainBytes(self.length)
class SISStringField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.data = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
buf = fileReader.readPlainBytes(self.length)
self.data = u""
while len(buf) > 0 :
temp = buf[:2]
buf = buf[2:]
self.data += unichr(ord(temp[0]) | ord(temp[1]) << 8)
def readableStr(self) :
return self.data
class SISArrayField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
type = fileReader.readBytesAsInt(4)
l = self.length - 4
while l > 0 :
field = SISFieldTypes[type]()
field.type = type
field.initFromFile(fileReader)
self.subFields.append(field)
l -= field.length + 4 # field length + the length field
padding = fileReader.skipPadding()
l -= padding
class SISCompressedField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.algorithm = None
self.uncompressedDataSize = None
self.data = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.algorithm = fileReader.readBytesAsUint(4)
self.uncompressedDataSize = fileReader.readBytesAsUint(8)
data = fileReader.readPlainBytes(self.length - 4 - 8)
if self.algorithm == 0 :
self.data = data
elif self.algorithm == 1 :
self.data = zlib.decompress(data)
class SISVersionField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.version = (- 1, - 1, - 1)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
major = fileReader.readBytesAsInt(4)
minor = fileReader.readBytesAsInt(4)
build = fileReader.readBytesAsInt(4)
self.version = (major, minor, build)
def readableStr(self) :
return str(self.version)
class SISVersionRangeField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.fromVersion = None
self.toVersion = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.fromVersion = fieldParser.parseField(fileReader)
if self.length - fieldParser.lastReadBytes > 0 :
self.toVersion = fieldParser.parseField(fileReader)
class SISDateField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.year = None
self.month = None
self.day = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.year = fileReader.readBytesAsUint(2)
self.month = fileReader.readBytesAsUint(1)
self.day = fileReader.readBytesAsUint(1)
def readableStr(self) :
return str(self.year) + "." + str(self.month) + "." + str(self.day)
class SISTimeField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.hours = None
self.minutes = None
self.seconds = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.hours = fileReader.readBytesAsUint(1)
self.minutes = fileReader.readBytesAsUint(1)
self.seconds = fileReader.readBytesAsUint(1)
def readableStr(self) :
return str(self.hours) + ":" + str(self.minutes) + ":" + str(self.seconds)
class SISDateTimeField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.date = None
self.time = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.date = fieldParser.parseField(fileReader)
self.time = fieldParser.parseField(fileReader)
class SISUidField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.uid = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.uid = fileReader.readBytesAsUint(4)
def readableStr(self) :
return hex(self.uid)
class SISLanguageField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.language = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.language = fileReader.readBytesAsUint(4)
def readableStr(self) :
return str(self.language)
class SISContentsField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
field = fieldParser.parseField(fileReader)
while field :
if field.type == 3 : # compressed<conroller>
bufferReader = SISBufferReader(field.data)
field = fieldParser.parseField(bufferReader)
self.subFields.append(field)
field = fieldParser.parseField(fileReader)
class SISControllerField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
bufferReader = SISBufferReader(fileReader.readPlainBytes(self.length))
field = fieldParser.parseField(bufferReader)
while field :
self.subFields.append(field)
field = fieldParser.parseField(bufferReader)
class SISInfoField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.installType = None
self.installFlags = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # UID
self.subFields.append(fieldParser.parseField(fileReader)) # Vendor name unique
self.subFields.append(fieldParser.parseField(fileReader)) # names
self.subFields.append(fieldParser.parseField(fileReader)) # vendor names
self.subFields.append(fieldParser.parseField(fileReader)) # version
self.subFields.append(fieldParser.parseField(fileReader)) # creation time
self.installType = fileReader.readBytesAsUint(1)
self.installFlags = fileReader.readBytesAsUint(1)
class SISSupportedLanguagesField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # languages
class SISSupportedOptionsField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # options
class SISPrerequisitiesField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # target devices
self.subFields.append(fieldParser.parseField(fileReader)) # dependencies
class SISDependencyField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # UID
field = fieldParser.parseField(fileReader)
# Version range field is optional
if field.type == VersionRangeField :
self.subFields.append(field) # version range
self.subFields.append(fieldParser.parseField(fileReader)) # dependency names
else :
self.subFields.append(field) # dependency names
class SISPropertiesField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # properties
class SISPropertyField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.key = None
self.value = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.key = fileReader.readBytesAsInt(4)
self.value = fileReader.readBytesAsInt(4)
# There is a type for this field, but there is no definition of the field contents
class SISSignaturesField(SISUnsupportedField) :
pass
class SISCertificateChainField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # certificate data
class SISLogoField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # logo file
class SISFileDescriptionField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.operation = None
self.operationOptions = None
self.compressedLength = None
self.uncompressedLength = None
self.fileIndex = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader))
self.subFields.append(fieldParser.parseField(fileReader))
field = fieldParser.parseField(fileReader)
self.subFields.append(field)
if field.type == 41 : # read field was capabilities ==> there is one more field left
self.subFields.append(fieldParser.parseField(fileReader))
self.operation = fileReader.readBytesAsUint(4)
self.operationOptions = fileReader.readBytesAsUint(4)
self.compressedLength = fileReader.readBytesAsUint(8)
self.uncompressedLength = fileReader.readBytesAsUint(8)
self.fileIndex = fileReader.readBytesAsUint(4)
def readableStr(self) :
return "index: " + str(self.fileIndex)
class SISHashField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.algorithm = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.algorithm = fileReader.readBytesAsUint(4)
self.subFields.append(fieldParser.parseField(fileReader)) # logo file
class SISIfField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # expression
self.subFields.append(fieldParser.parseField(fileReader)) # install block
self.subFields.append(fieldParser.parseField(fileReader)) # else ifs
class SISElseIfField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # expression
self.subFields.append(fieldParser.parseField(fileReader)) # install block
class SISInstallBlockField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.files = None
self.embeddedSISFiles = None
self.ifBlocks = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader))
self.subFields.append(fieldParser.parseField(fileReader))
self.subFields.append(fieldParser.parseField(fileReader))
class SISExpressionField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.operator = None
self.integerValue = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.operator = fileReader.readBytesAsUint(4)
self.integerValue = fileReader.readBytesAsInt(4)
if self.operator == 10 or self.operator == 13 :
self.subFields.append(fieldParser.parseField(fileReader))
if self.operator == 1 or self.operator == 2 or self.operator == 3 or self.operator == 4 or self.operator == 5 or self.operator == 6 or self.operator == 7 or self.operator == 8 or self.operator == 11 or self.operator == 12 :
self.subFields.append(fieldParser.parseField(fileReader))
if not (self.operator == 13 or self.operator == 14 or self.operator == 15 or self.operator == 16 or self.operator == 10) :
self.subFields.append(fieldParser.parseField(fileReader))
class SISDataField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # data units
class SISDataUnitField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # file data
class SISFileDataField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # raw file data
class SISSupportedOptionField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # names
class SISControllerChecksumField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.checksum = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.checksum = fileReader.readBytesAsUint(2)
class SISDataChecksumField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.checksum = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.checksum = fileReader.readBytesAsUint(2)
class SISSignatureField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # signature algorithm
self.subFields.append(fieldParser.parseField(fileReader)) # signature data
class SISBlobField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.data = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.data = fileReader.readPlainBytes(self.length)
class SISSignatureAlgorithmField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # algorithm identifier
class SISSignatureCertificateChainField(SISField) :
def __init__(self) :
SISField.__init__(self)
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # signatures
self.subFields.append(fieldParser.parseField(fileReader)) # certificate chain
class SISDataIndexField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.dataIndex = None
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.dataIndex = fileReader.readBytesAsUint(4)
class SISCapabilitiesField(SISField) :
def __init__(self) :
SISField.__init__(self)
self.capabilities = 0
self.readableCaps = []
def initFromFile(self, fileReader) :
self.length = self.readFieldLength(fileReader)
self.capabilities = fileReader.readBytesAsUint(self.length)
for i in range(20) :
if (self.capabilities >> i) & 0x01 :
self.readableCaps.append(CapabilityNames[i])
def readableStr(self) :
return " ".join(self.readableCaps)
SISFieldTypes = {
1 : SISStringField,
2 : SISArrayField,
3 : SISCompressedField,
4 : SISVersionField,
5 : SISVersionRangeField,
6 : SISDateField,
7 : SISTimeField,
8 : SISDateTimeField,
9 : SISUidField,
10 : SISUnsupportedField,
11 : SISLanguageField,
12 : SISContentsField,
13 : SISControllerField,
14 : SISInfoField,
15 : SISSupportedLanguagesField,
16 : SISSupportedOptionsField,
17 : SISPrerequisitiesField,
18 : SISDependencyField,
19 : SISPropertiesField,
20 : SISPropertyField,
21 : SISSignaturesField,
22 : SISCertificateChainField,
23 : SISLogoField,
24 : SISFileDescriptionField,
25 : SISHashField,
26 : SISIfField,
27 : SISElseIfField,
28 : SISInstallBlockField,
29 : SISExpressionField,
30 : SISDataField,
31 : SISDataUnitField,
32 : SISFileDataField,
33 : SISSupportedOptionField,
34 : SISControllerChecksumField,
35 : SISDataChecksumField,
36 : SISSignatureField,
37 : SISBlobField,
38 : SISSignatureAlgorithmField,
39 : SISSignatureCertificateChainField,
40 : SISDataIndexField,
41 : SISCapabilitiesField
}
[StringField,
ArrayField,
CompressedField,
VersionField,
VersionRangeField,
DateField,
TimeField,
DateTimeField,
UidField,
UnusedField,
LanguageField,
ContentsField,
ControllerField,
InfoField,
SupportedLanguagesField,
SupportedOptionsField,
PrerequisitiesField,
DependencyField,
PropertiesField,
PropertyField,
SignaturesField,
CertificateChainField,
LogoField,
FileDescriptionField,
HashField,
IfField,
ElseIfField,
InstallBlockField,
ExpressionField,
DataField,
DataUnitField,
FileDataField,
SupportedOptionField,
ControllerChecksumField,
DataChecksumField,
SignatureField,
BlobField,
SignatureAlgorithmField,
SignatureCertificateChainField,
DataIndexField,
CapabilitiesField] = range(1, 42)
FieldNames = {
0 : "ROOT",
StringField : "StringField",
ArrayField : "ArrayField",
CompressedField : "CompressedField",
VersionField : "VersionField",
VersionRangeField : "VersionRangeField",
DateField : "DateField",
TimeField : "TimeField",
DateTimeField : "DateTimeField",
UidField : "UidField",
UnusedField : "UnusedField",
LanguageField : "LanguageField",
ContentsField : "ContentsField",
ControllerField : "ControllerField",
InfoField : "InfoField",
SupportedLanguagesField : "SupportedLanguagesField",
SupportedOptionsField : "SupportedOptionsField",
PrerequisitiesField : "PrerequisitiesField",
DependencyField : "DependencyField",
PropertiesField : "PropertiesField",
PropertyField : "PropertyField",
SignaturesField : "SignaturesField",
CertificateChainField : "CertificateChainField",
LogoField : "LogoField",
FileDescriptionField : "FileDescriptionField",
HashField : "HashField",
IfField : "IfField",
ElseIfField : "ElseIfField",
InstallBlockField : "InstallBlockField",
ExpressionField : "ExpressionField",
DataField : "DataField",
DataUnitField : "DataUnitField",
FileDataField : "FileDataField",
SupportedOptionField : "SupportedOptionField",
ControllerChecksumField : "ControllerChecksumField",
DataChecksumField : "DataChecksumField",
SignatureField : "SignatureField",
BlobField : "BlobField",
SignatureAlgorithmField : "SignatureAlgorithmField",
SignatureCertificateChainField : "SignatureCertificateChainField",
DataIndexField : "DataIndexField",
CapabilitiesField : "CapabilitiesField"
}
CapabilityNames = {
0 : "TCB",
1 : "CommDD",
2 : "PowerMgmt",
3 : "MultimediaDD",
4 : "ReadDeviceData",
5 : "WriteDeviceData",
6 : "DRM",
7 : "TrustedUI",
8 : "ProtServ",
9 : "DiskAdmin",
10 : "NetworkControl",
11 : "AllFiles",
12 : "SwEvent",
13 : "NetworkServices",
14 : "LocalServices",
15 : "ReadUserData",
16 : "WriteUserData",
17 : "Location",
18 : "SurroundingsDD",
19 : "UserEnvironment"
}
InstallTypes = {
0: "SA",
1: "SP",
2: "PU",
3: "PA",
4: "PP"
}
class SISReader :
def __init__(self) :
self.bytesRead = 0
def readUnsignedBytes(self, numBytes) :
buf = self.readPlainBytes(numBytes)
if len(buf) < numBytes :
return []
format = ""
for i in range(numBytes) :
format += "B"
return struct.unpack(format, buf)
def readSignedBytes(self, numBytes) :
buf = self.readPlainBytes(numBytes)
if len(buf) < numBytes :
return []
format = ""
for i in range(numBytes) :
format += "b"
return struct.unpack(format, buf)
def readBytesAsUint(self, numBytes) :
result = 0
bytes = self.readUnsignedBytes(numBytes)
if len(bytes) == numBytes :
for i in range(numBytes) :
result |= bytes[i] << (i * 8)
return result
def readBytesAsInt(self, numBytes) :
result = 0
bytes = self.readSignedBytes(numBytes)
if len(bytes) == numBytes :
for i in range(numBytes) :
result |= bytes[i] << (i * 8)
return result
def skipPadding(self) :
result = 0
if self.bytesRead % 4 != 0 :
paddingLength = 4 - self.bytesRead % 4
self.readPlainBytes(paddingLength)
result = paddingLength
return result
def readPlainBytes(self, numBytes) :
pass
class SISFileReader(SISReader) :
def __init__(self, inStream) :
SISReader.__init__(self)
self.inStream = inStream
self.eof = False
self.bytesRead = 0
def readPlainBytes(self, numBytes) :
if self.eof :
return ""
if numBytes == 0 :
return ""
buf = ""
buf = self.inStream.read(numBytes)
if len(buf) < numBytes :
self.eof = True
return ""
self.bytesRead += numBytes
return buf
def isEof(self) :
return self.eof
class SISBufferReader(SISReader) :
def __init__(self, buffer) :
self.buffer = buffer
self.bytesRead = 0
def readPlainBytes(self, numBytes) :
if self.isEof() :
return ""
if numBytes == 0 :
return ""
result = self.buffer[self.bytesRead:self.bytesRead + numBytes]
self.bytesRead += numBytes
return result
def isEof(self) :
return self.bytesRead >= len(self.buffer)
class SISFieldParser :
def __init__(self) :
self.lastReadBytes = 0
def parseField(self, fileReader) :
"""Reads the next field from the fileReader stream and returns it"""
field = None
self.lastReadBytes = 0
type = fileReader.readBytesAsUint(4)
self.lastReadBytes += 4
if type != 0 :
field = SISFieldTypes[type]()
field.type = type
field.initFromFile(fileReader)
self.lastReadBytes += field.length + 4 # Field length + length field
self.lastReadBytes += fileReader.skipPadding()
return field
class SISInfo(SISField) :
def __init__(self) :
SISField.__init__(self)
self.fin = None
self.fileHeader = SISFileHeader()
def parse(self, filename) :
fin = open(filename, 'rb')
fileReader = SISFileReader(fin)
self.parseHeader(fileReader)
self.parseSISFields(fileReader)
def parseHeader(self, fileReader) :
self.fileHeader.uid1 = fileReader.readBytesAsUint(4)
self.fileHeader.uid2 = fileReader.readBytesAsUint(4)
self.fileHeader.uid3 = fileReader.readBytesAsUint(4)
self.fileHeader.uidChecksum = fileReader.readBytesAsUint(4)
def parseSISFields(self, fileReader) :
parser = SISFieldParser()
while not fileReader.isEof() :
self.subFields.append(parser.parseField(fileReader))
class Handler :
def __init__(self) :
self.files = []
self.fileDatas = []
self.signatureCertificateChains = []
def handleField(self, field, depth) :
if field.type == FileDescriptionField :
self.files.append(field)
elif field.type == FileDataField :
self.fileDatas.append(field)
elif field.type == SignatureCertificateChainField :
self.signatureCertificateChains.append(field)
def execute(self, options) :
for f in self.files :
if options.info :
buf = " " + f.findField(StringField)[0].readableStr()
caps = f.findField(CapabilitiesField)[0]
if caps :
buf += " [" + " ".join(f.findField(CapabilitiesField)[0].readableCaps) + "]"
print buf
if options.extract :
parts = f.findField(StringField)[0].readableStr().split("\\")
if len(parts[len(parts) - 1]) > 0 :
path = os.path.abspath(options.extract)
path += os.sep + os.sep.join(parts[1: - 1])
if not os.path.exists(path) :
os.makedirs(path)
newFile = file(path + os.sep + parts[len(parts) - 1], "wb")
newFile.write(self.fileDatas[f.fileIndex].findField(CompressedField)[0].data)
newFile.close()
for s in self.signatureCertificateChains :
if options.certificate:
buf = s.findField(CertificateChainField)[0].subFields[0].data
print "Certificate chain:"
i = 1
while len(buf) > 0 :
print " Certificate " + str(i) + ":"
i += 1
decoded = decoder.decode(buf)
cer = CertificateInfo()
cer.parse(decoded[0])
readableStr = cer.readableStr()
print " " + "\n ".join(readableStr.split('\n'))
buf = decoded[1]
class ContentPrinter :
def __init__(self) :
pass
def handleField(self, field, depth) :
buf = ""
for i in range(depth) :
buf += " "
buf += FieldNames[field.type] + " "
if len(field.readableStr()) > 0 :
buf += field.readableStr()
print buf
class IADHandler :
def __init__(self) :
self.packageVersion = (0, 0, 0)
self.packageUid = 0
self.vendorName = ""
self.packageNames = []
self.packageNamesFields = []
self.languages = []
self.platformDependencies = []
self.packageDependencies = []
self.installType = 0
self.installFlags = 0
def handleDependency(self, field) :
dep = [0, - 1, - 1, - 1, - 1, - 1, - 1]
dep[0] = field.subFields[0].uid
if field.subFields[1] and field.subFields[1].type == VersionRangeField :
r = field.subFields[1]
if r.fromVersion != None :
dep[1] = r.fromVersion.version[0]
dep[2] = r.fromVersion.version[1]
dep[3] = r.fromVersion.version[2]
if r.toVersion != None :
dep[4] = r.toVersion.version[0]
dep[5] = r.toVersion.version[1]
dep[6] = r.toVersion.version[2]
return dep
def handleField(self, field, depth) :
if field.type == InfoField :
self.packageVersion = field.subFields[4].version
self.packageVersionField = field.subFields[4]
self.packageUid = field.subFields[0].uid
self.packageUidField = field.subFields[0]
self.vendorName = field.subFields[1].data
self.vendorNameField = field.subFields[1]
self.installType = field.installType
self.installFlags = field.installFlags
for name in field.subFields[2].subFields :
self.packageNames.append(name.data)
elif field.type == LanguageField :
self.languages.append(field.language)
elif field.type == PrerequisitiesField :
for f in field.subFields[0].subFields :
dependency = self.handleDependency(f)
self.platformDependencies.append(dependency)
for f in field.subFields[1].subFields :
dependency = self.handleDependency(f)
self.packageDependencies.append(dependency)
def getInfo (self, fileName) :
sisInfo = SISInfo()
sisInfo.parse(fileName)
handler = IADHandler()
sisInfo.traverse(handler)
info = "<sisinfo>\n" \
+ " <uid>" + hex(handler.packageUid) + "</uid>\n" \
+ " <vendor>" + handler.vendorName + "</vendor>\n" \
+ " <version>" \
+ "<major>" + repr(handler.packageVersion[0]) + "</major>" \
+ "<minor>" + repr(handler.packageVersion[1]) + "</minor>" \
+ "<build>" + repr(handler.packageVersion[2]) + "</build>" \
+ "</version>\n" \
+ " <type>" + InstallTypes[self.installType] + "</type>\n"
for num, name in enumerate(handler.packageNames) :
info += " <name language='" + repr(handler.languages[num]) + "'>" + name + "</name>\n"
for language in handler.languages :
info += " <language>" + repr(language) + "</language>\n"
for platDep in handler.platformDependencies :
info += " <platform_dependency><uid>" + hex(platDep[0]) + "</uid>\n"
info += " <from>" \
+ "<major>" + repr(platDep[1]) + "</major>" \
+ "<minor>" + repr(platDep[2]) + "</minor>"
# info += "<build>" + repr(platDep[3]) + "</build>"
info += "</from>\n <to>" \
+ "<major>" + repr(platDep[4]) + "</major>" \
+ "<minor>" + repr(platDep[5]) + "</minor>"
# info += "<build>" + repr(platDep[6]) + "</build>"
info += "</to>\n" \
+ " </platform_dependency>\n"
for packageDep in handler.packageDependencies :
info += " <package_dependency><uid>" + hex(packageDep[0]) + "</uid>\n"
info += " <from>" \
+ "<major>" + repr(packageDep[1]) + "</major>" \
+ "<minor>" + repr(packageDep[2]) + "</minor>"
# info += "<build>" + repr(packageDep[3]) + "</build>"
info += "</from>\n <to>" \
+ "<major>" + repr(packageDep[4]) + "</major>" \
+ "<minor>" + repr(packageDep[5]) + "</minor>"
# info += "<build>" + repr(packageDep[6]) + "</build>"
info += "</to>\n" \
+ " </package_dependency>\n"
info += "</sisinfo>\n"
return info
if __name__ == "__main__" :
handler = IADHandler()
print (handler.getInfo (sys.argv[1]))