class ASRClient(object):
    def __init__(self, payloadFile):
        self.s = PlistService(12345)
        self.size = os.path.getsize(payloadFile)
        self.packet_payload_size = 1450
        self.f = open(payloadFile, "rb")

    def initiate(self, msg):
        r = {
            "Checksum Chunk Size": 131072,
            "FEC Slice Stride": 40,
            "Packet Payload Size": self.packet_payload_size,
            "Packets Per FEC": 25,
            "Payload": {
                "Port": 1,
                "Size": self.size
            },
            "Stream ID": 1,
            "Version": 1
        }
        print "ASR: init"
        self.s.sendPlist(r)

    def handle_oob_request(self, msg):
        length = msg["OOB Length"]
        offset = msg["OOB Offset"]
        print "ASR: OOB request off=%d len=%d" % (offset, length)
        self.f.seek(offset)
        data = self.f.read(length)
        self.s.send_raw(data)

    def send_payload(self, msg):
        self.f.seek(0)
        i = self.size

        print "ASR: sending payload (%d bytes)" % self.size
        pbar = ProgressBar(self.size)
        pbar.start()
        while i < self.size:
            data = self.f.read(self.packet_payload_size)
            self.s.send_raw(data)
            i += len(data)
            pbar.update(i)
        pbar.finish()

    def work_loop(self):
        while True:
            msg = self.s.recvPlist()
            if not msg:
                break
            Command = msg["Command"]
            pprint(msg)

            if Command == "Initiate":
                self.initiate(msg)
            elif Command == "OOBData":
                self.handle_oob_request(msg)
            elif Command == "Payload":
                self.send_payload(msg)
Example #2
0
class ASRClient(object):
    def __init__(self, payloadFile):
        self.s = PlistService(12345)
        self.size = os.path.getsize(payloadFile)
        self.packet_payload_size = 1450
        self.f = open(payloadFile, "rb")

    def initiate(self, msg):
        r = {"Checksum Chunk Size": 131072,
             "FEC Slice Stride": 40,
             "Packet Payload Size": self.packet_payload_size,
             "Packets Per FEC": 25,
             "Payload": {"Port": 1, "Size": self.size},
             "Stream ID": 1,
             "Version": 1
             }
        print "ASR: init"
        self.s.sendPlist(r)

    def handle_oob_request(self, msg):
        length = msg["OOB Length"]
        offset = msg["OOB Offset"]
        print "ASR: OOB request off=%d len=%d" % (offset, length)
        self.f.seek(offset)
        data = self.f.read(length)
        self.s.send_raw(data)

    def send_payload(self, msg):
        self.f.seek(0)
        i = self.size

        print "ASR: sending payload (%d bytes)" % self.size
        pbar = ProgressBar(self.size)
        pbar.start()
        while i < self.size:
            data = self.f.read(self.packet_payload_size)
            self.s.send_raw(data)
            i += len(data)
            pbar.update(i)
        pbar.finish()

    def work_loop(self):
        while True:
            msg = self.s.recvPlist()
            if not msg:
                break
            Command = msg["Command"]
            pprint(msg)

            if Command == "Initiate":
                self.initiate(msg)
            elif Command == "OOBData":
                self.handle_oob_request(msg)
            elif Command == "Payload":
                self.send_payload(msg)
Example #3
0
class LockdownClient(object):
    def __init__(self, udid=None):
        self.paired = False
        self.SessionID = None
        self.c = PlistService(62078, udid)
        self.hostID = self.generate_hostID()
        self.paired = False
        self.label = "pyMobileDevice"

        assert self.queryType() == "com.apple.mobile.lockdown"

        self.udid = self.getValue("", "UniqueDeviceID")
        self.allValues = self.getValue("", "")
        self.UniqueChipID = self.allValues.get("UniqueChipID")
        self.DevicePublicKey = self.getValue("", "DevicePublicKey")
        self.identifier = self.udid
        if not self.identifier:
            if self.UniqueChipID:
                self.identifier = "%x" % self.UniqueChipID
            else:
                print "Could not get UDID or ECID, failing"
                raise

        if not self.validate_pairing():
            self.pair()
            if not self.validate_pairing():
                raise FatalPairingError
        self.paired = True
        return

    def queryType(self):
        self.c.sendPlist({"Request": "QueryType"})
        res = self.c.recvPlist()
        return res.get("Type")

    def generate_hostID(self):
        hostname = platform.node()
        hostid = uuid.uuid3(uuid.NAMESPACE_DNS, hostname)
        return str(hostid).upper()

    def enter_recovery(self):
        self.c.sendPlist({"Request": "EnterRecovery"})
        print self.c.recvPlist()

    def stop_session(self):
        if self.SessionID and self.c:
            self.c.sendPlist({"Label": self.label, "Request": "StopSession", "SessionID": self.SessionID})
            self.SessionID = None
            res = self.c.recvPlist()
            if not res or res.get("Result") != "Success":
                raise CannotStopSessionError
            return res

    def validate_pairing(self):
        pair_record = None
        certPem = None
        privateKeyPem = None

        if sys.platform == "win32":
            folder = os.environ["ALLUSERSPROFILE"] + "/Apple/Lockdown/"
        elif sys.platform == "darwin":
            folder = "/var/db/lockdown/"
        try:
            pair_record = plistlib.readPlist(folder + "%s.plist" % self.identifier)
        except:
            pair_record = None
        if pair_record:
            print "Using iTunes pair record: %s.plist" % self.identifier
            certPem = pair_record["HostCertificate"].data
            privateKeyPem = pair_record["HostPrivateKey"].data

        else:
            print "No iTunes pairing record found for device %s" % self.identifier
            print "Looking for pymobiledevice pairing record"
            record = readHomeFile(HOMEFOLDER, "%s.plist" % self.identifier)
            if record:
                pair_record = plistlib.readPlistFromString(record)
                print "Found pymobiledevice pairing record for device %s" % self.udid
                certPem = pair_record["HostCertificate"].data
                privateKeyPem = pair_record["HostPrivateKey"].data
            else:
                print "No  pymobiledevice pairing record found for device %s" % self.identifier
                return False

        ValidatePair = {"Label": self.label, "Request": "ValidatePair", "PairRecord": pair_record}
        self.c = PlistService(62078, self.udid)
        self.c.sendPlist(ValidatePair)
        r = self.c.recvPlist()
        if not r or r.has_key("Error"):
            pair_record = None
            print "ValidatePair fail", ValidatePair
            return False

        d = {"Label": self.label, "Request": "StartSession", "HostID": pair_record.get("HostID", self.hostID)}
        self.c.sendPlist(d)
        startsession = self.c.recvPlist()
        self.SessionID = startsession.get("SessionID")
        if startsession.get("EnableSessionSSL"):
            sslfile = self.identifier + "_ssl.txt"
            sslfile = writeHomeFile(HOMEFOLDER, sslfile, certPem + "\n" + privateKeyPem)
            self.c.ssl_start(sslfile, sslfile)

        self.paired = True
        return True

    def pair(self):
        self.DevicePublicKey = self.getValue("", "DevicePublicKey")
        if self.DevicePublicKey == "":
            print "Unable to retreive DevicePublicKey"
            return False

        print "Creating host key & certificate"
        certPem, privateKeyPem, DeviceCertificate = ca_do_everything(self.DevicePublicKey)

        pair_record = {
            "DevicePublicKey": plistlib.Data(self.DevicePublicKey),
            "DeviceCertificate": plistlib.Data(DeviceCertificate),
            "HostCertificate": plistlib.Data(certPem),
            "HostID": self.hostID,
            "RootCertificate": plistlib.Data(certPem),
            "SystemBUID": "30142955-444094379208051516",
        }

        pair = {"Label": self.label, "Request": "Pair", "PairRecord": pair_record}
        self.c = PlistService(62078, self.udid)
        self.c.sendPlist(pair)
        pair = self.c.recvPlist()

        if pair and pair.get("Result") == "Success" or pair.has_key("EscrowBag"):
            pair_record["HostPrivateKey"] = plistlib.Data(privateKeyPem)
            pair_record["EscrowBag"] = pair.get("EscrowBag")
            writeHomeFile(HOMEFOLDER, "%s.plist" % self.identifier, plistlib.writePlistToString(pair_record))
            self.paired = True
            return True

        elif pair and pair.get("Error") == "PasswordProtected":
            self.c.close()
            raise NotTrustedError

        else:
            self.c.close()
            raise PairingError

    def getValue(self, domain=None, key=None):

        req = {"Request": "GetValue", "Label": self.label}

        if domain:
            req["Domain"] = domain
        if key:
            req["Key"] = key

        self.c.sendPlist(req)
        res = self.c.recvPlist()
        if res:
            r = res.get("Value")
            if hasattr(r, "data"):
                return r.data
            return r

    def setValue(self, domain=None, key=None):

        req = {"Request": "SetValue", "Label": self.label}

        if domain:
            req["Domain"] = domain
        if key:
            req["Key"] = key

        self.c.sendPlist(req)
        res = self.c.recvPlist()
        print res
        return res

    def startService(self, name):
        if not self.paired:
            print "NotPaired"
            raise NotPairedError

        self.c.sendPlist({"Label": self.label, "Request": "StartService", "Service": name})
        StartService = self.c.recvPlist()
        if not StartService or StartService.get("Error"):
            print StartService
            raise StartServiceError
        return PlistService(StartService.get("Port"))
Example #4
0
class LockdownClient(object):
    def __init__(self,udid=None):
        self.SessionID = None
        self.c = None
        self.c = PlistService(62078,udid)
        self.hostID = self.generate_hostID()
        #print "HostID : ", self.hostID
        self.paired = False
        self.label = "pyMobileDevice"
        self.c.sendPlist({"Request":"QueryType"})
        res = self.c.recvPlist()
        assert res["Type"] == "com.apple.mobile.lockdown"
        self.udid = self.getValue("", "UniqueDeviceID")
        #print "Device Name : ", self.getValue("", "DeviceName")
        self.allValues = self.getValue("", "")
        self.UniqueChipID = self.allValues.get("UniqueChipID")
        #self.DevicePublicKey = ""
        self.DevicePublicKey =  self.getValue("", "DevicePublicKey")

        #pprint(self.allValues)
        #self.udid  = self.c.udid
        self.identifier = self.udid
        #if not self.identifier:
        #    if self.UniqueChipID:
        #        self.identifier = "%x" % self.UniqueChipID
        #    else:
        #        print "Could not get UDID or ECID, failing"
        #        raise
        if not self.validate_pairing():
            if not self.pair():
                return
            self.validate_pairing()

    def generate_hostID(self):
        #hostname = socket.gethostname()
        hostname = platform.node()
        hostid = uuid.uuid3(uuid.NAMESPACE_DNS, hostname)
        return str(hostid).upper()

        
    #def __del__(self):
    #    self.stop_session()
    #    if self.c :
    #        self.c.sendPlist({"Request": "Goodbye"})
    #        res = self.c.recvPlist()
    #        return res
    #    #if not res or res.get("Result") != "Success":
    #    #    print "Goodbye fail :", res
       
    def enter_recovery(self):
        self.c.sendPlist({"Request": "EnterRecovery"})
        print self.c.recvPlist()
    
    def stop_session(self):
        if self.SessionID and self.c:
            self.c.sendPlist({"Request": "StopSession", "SessionID": self.SessionID})
            self.SessionID = None
            res = self.c.recvPlist()
            return res
            #pprint(res)
            #if not res or res.get("Result") != "Success":
            #    print "StopSession fail :", res
                    
    def validate_pairing(self):
        pair_record = None
        certPem = None
        privateKeyPem = None
        
        record = readHomeFile(HOMEFOLDER, "%s.plist" % self.identifier)
        if record:
            pair_record = plistlib.readPlistFromString(record)
            certPem = pair_record["HostCertificate"].data
            privateKeyPem = pair_record["HostPrivateKey"].data
            print "Found pairing record for device %s" % self.udid
        else:
            print "No pairing record found for device %s" % self.identifier
            return
        if False:
            if sys.platform == "win32":
                folder = os.environ["ALLUSERSPROFILE"] + "/Apple/Lockdown/"
            elif sys.platform == "darwin":
                folder = "/var/db/lockdown/"
            pair_record = plistlib.readPlist(folder + "%s.plist" % self.identifier)
            print "Using iTunes pair record"
            
        ValidatePair = {"Request": "ValidatePair", "PairRecord": pair_record}
        self.c.sendPlist(ValidatePair)
        ValidatePair = self.c.recvPlist()
        if not ValidatePair or ValidatePair.has_key("Error"):
            pair_record =None
            print "ValidatePair fail", ValidatePair
            return False
        self.paired = True
        #print "Validate Pairing OK", ValidatePair
        d = {"Request": "StartSession", "HostID": pair_record.get("HostID", self.hostID)}
        self.c.sendPlist(d)
        startsession = self.c.recvPlist() 
        #print "Starting session",startsession
        self.SessionID = startsession.get("SessionID")
        if startsession.get("EnableSessionSSL"):
            sslfile = self.identifier + "_ssl.txt"
            sslfile = writeHomeFile(HOMEFOLDER, sslfile, certPem + "\n" + privateKeyPem)
            self.c.ssl_start(sslfile, sslfile)
            #print "SSL started"
            self.udid = self.getValue("", "UniqueDeviceID")
            self.allValues = self.getValue("", "")
            #print "UDID", self.udid
        return True

    def pair(self):
        self.DevicePublicKey =  self.getValue("", "DevicePublicKey")
        if self.DevicePublicKey == '':
            return
        print "Got device public key"
        print "Creating host key & certificate"
        certPem, privateKeyPem, DeviceCertificate = ca_do_everything(self.DevicePublicKey)

        pair_record = {"DevicePublicKey": plistlib.Data(self.DevicePublicKey),
                       "DeviceCertificate": plistlib.Data(DeviceCertificate),
                       "HostCertificate": plistlib.Data(certPem),
                       "HostID": self.hostID,
                       "RootCertificate": plistlib.Data(certPem),
                       "SystemBUID": "30142955-444094379208051516"
        }
        Pair = {"Request": "Pair", "PairRecord": pair_record}
        self.c.sendPlist(Pair)
        Pair = self.c.recvPlist()
        if Pair and  Pair.get("Result") == "Success" or Pair.has_key("EscrowBag"):
            #print "Pairing OK"
            pair_record["HostPrivateKey"] = plistlib.Data(privateKeyPem)
            if Pair.has_key("EscrowBag"):
                pair_record["EscrowBag"] = Pair["EscrowBag"]
            writeHomeFile(HOMEFOLDER, "%s.plist" % self.identifier, plistlib.writePlistToString(pair_record))
            return True
        print "Pairing error", Pair
        return False
    
    def getValue(self, domain=None, key=None):
        req = {"Request":"GetValue", "Label": self.label}
        
        if domain:
            req["Domain"] = domain
        if key:
            req["Key"] = key
        self.c.sendPlist(req)
        res = self.c.recvPlist()
        if res:
            r = res.get("Value")
            if hasattr(r, "data"):
                return r.data
            return r
        
    def startService(self, name):
        if not self.paired:
            print "Cannot startService %s, not paired" % name
            return
        self.c.sendPlist({"Request": "StartService", "Service": name})
        StartService = self.c.recvPlist()
        if not StartService:
            return
        if StartService.has_key("Error"):
            print StartService["Error"], name
            return
        #print StartService
        zz = PlistService(StartService["Port"])
        return zz
Example #5
0
class LockdownClient(object):
    def __init__(self, udid=None):
        self.paired = False
        self.SessionID = None
        self.c = PlistService(62078, udid)
        self.hostID = self.generate_hostID()
        self.paired = False
        self.label = "pyMobileDevice"

        assert self.queryType() == "com.apple.mobile.lockdown"

        self.udid = self.getValue("", "UniqueDeviceID")
        self.allValues = self.getValue("", "")
        self.UniqueChipID = self.allValues.get("UniqueChipID")
        self.DevicePublicKey = self.getValue("", "DevicePublicKey")
        self.identifier = self.udid
        if not self.identifier:
            if self.UniqueChipID:
                self.identifier = "%x" % self.UniqueChipID
            else:
                print "Could not get UDID or ECID, failing"
                raise

        if not self.validate_pairing():
            self.pair()
            if not self.validate_pairing():
                raise FatalPairingError
        self.paired = True
        return

    def queryType(self):
        self.c.sendPlist({"Request": "QueryType"})
        res = self.c.recvPlist()
        return res.get("Type")

    def generate_hostID(self):
        hostname = platform.node()
        hostid = uuid.uuid3(uuid.NAMESPACE_DNS, hostname)
        return str(hostid).upper()

    def enter_recovery(self):
        self.c.sendPlist({"Request": "EnterRecovery"})
        print self.c.recvPlist()

    def stop_session(self):
        if self.SessionID and self.c:
            self.c.sendPlist({
                "Label": self.label,
                "Request": "StopSession",
                "SessionID": self.SessionID
            })
            self.SessionID = None
            res = self.c.recvPlist()
            if not res or res.get("Result") != "Success":
                raise CannotStopSessionError
            return res

    def validate_pairing(self):
        pair_record = None
        certPem = None
        privateKeyPem = None

        if sys.platform == "win32":
            folder = os.environ["ALLUSERSPROFILE"] + "/Apple/Lockdown/"
        elif sys.platform == "darwin":
            folder = "/var/db/lockdown/"
        try:
            pair_record = plistlib.readPlist(folder +
                                             "%s.plist" % self.identifier)
        except:
            pair_record = None
        if pair_record:
            print "Using iTunes pair record: %s.plist" % self.identifier
            certPem = pair_record["HostCertificate"].data
            privateKeyPem = pair_record["HostPrivateKey"].data

        else:
            print "No iTunes pairing record found for device %s" % self.identifier
            print "Looking for pymobiledevice pairing record"
            record = readHomeFile(HOMEFOLDER, "%s.plist" % self.identifier)
            if record:
                pair_record = plistlib.readPlistFromString(record)
                print "Found pymobiledevice pairing record for device %s" % self.udid
                certPem = pair_record["HostCertificate"].data
                privateKeyPem = pair_record["HostPrivateKey"].data
            else:
                print "No  pymobiledevice pairing record found for device %s" % self.identifier
                return False

        ValidatePair = {
            "Label": self.label,
            "Request": "ValidatePair",
            "PairRecord": pair_record
        }
        self.c = PlistService(62078, self.udid)
        self.c.sendPlist(ValidatePair)
        r = self.c.recvPlist()
        if not r or r.has_key("Error"):
            pair_record = None
            print "ValidatePair fail", ValidatePair
            return False

        d = {
            "Label": self.label,
            "Request": "StartSession",
            "HostID": pair_record.get("HostID", self.hostID)
        }
        self.c.sendPlist(d)
        startsession = self.c.recvPlist()
        self.SessionID = startsession.get("SessionID")
        if startsession.get("EnableSessionSSL"):
            sslfile = self.identifier + "_ssl.txt"
            sslfile = writeHomeFile(HOMEFOLDER, sslfile,
                                    certPem + "\n" + privateKeyPem)
            self.c.ssl_start(sslfile, sslfile)

        self.paired = True
        return True

    def pair(self):
        self.DevicePublicKey = self.getValue("", "DevicePublicKey")
        if self.DevicePublicKey == '':
            print "Unable to retreive DevicePublicKey"
            return False

        print "Creating host key & certificate"
        certPem, privateKeyPem, DeviceCertificate = ca_do_everything(
            self.DevicePublicKey)

        pair_record = {
            "DevicePublicKey": plistlib.Data(self.DevicePublicKey),
            "DeviceCertificate": plistlib.Data(DeviceCertificate),
            "HostCertificate": plistlib.Data(certPem),
            "HostID": self.hostID,
            "RootCertificate": plistlib.Data(certPem),
            "SystemBUID": "30142955-444094379208051516"
        }

        pair = {
            "Label": self.label,
            "Request": "Pair",
            "PairRecord": pair_record
        }
        self.c = PlistService(62078, self.udid)
        self.c.sendPlist(pair)
        pair = self.c.recvPlist()

        if pair and pair.get("Result") == "Success" or pair.has_key(
                "EscrowBag"):
            pair_record["HostPrivateKey"] = plistlib.Data(privateKeyPem)
            pair_record["EscrowBag"] = pair.get("EscrowBag")
            writeHomeFile(HOMEFOLDER, "%s.plist" % self.identifier,
                          plistlib.writePlistToString(pair_record))
            self.paired = True
            return True

        elif pair and pair.get("Error") == "PasswordProtected":
            self.c.close()
            raise NotTrustedError

        else:
            self.c.close()
            raise PairingError

    def getValue(self, domain=None, key=None):

        req = {"Request": "GetValue", "Label": self.label}

        if domain:
            req["Domain"] = domain
        if key:
            req["Key"] = key

        self.c.sendPlist(req)
        res = self.c.recvPlist()
        if res:
            r = res.get("Value")
            if hasattr(r, "data"):
                return r.data
            return r

    def setValue(self, domain=None, key=None):

        req = {"Request": "SetValue", "Label": self.label}

        if domain:
            req["Domain"] = domain
        if key:
            req["Key"] = key

        self.c.sendPlist(req)
        res = self.c.recvPlist()
        print res
        return res

    def startService(self, name):
        if not self.paired:
            print "NotPaired"
            raise NotPairedError

        self.c.sendPlist({
            "Label": self.label,
            "Request": "StartService",
            "Service": name
        })
        StartService = self.c.recvPlist()
        if not StartService or StartService.get("Error"):
            print StartService
            raise StartServiceError
        return PlistService(StartService.get("Port"))
class LockdownClient(object):
    def __init__(self, udid=None):
        self.SessionID = None
        self.c = None
        self.c = PlistService(62078, udid)
        self.hostID = self.generate_hostID()
        #print "HostID : ", self.hostID
        self.paired = False
        self.label = "pyMobileDevice"
        self.c.sendPlist({"Request": "QueryType"})
        res = self.c.recvPlist()
        assert res["Type"] == "com.apple.mobile.lockdown"
        self.udid = self.getValue("", "UniqueDeviceID")
        #print "Device Name : ", self.getValue("", "DeviceName")
        self.allValues = self.getValue("", "")
        self.UniqueChipID = self.allValues.get("UniqueChipID")
        #self.DevicePublicKey = ""
        self.DevicePublicKey = self.getValue("", "DevicePublicKey")

        #pprint(self.allValues)
        #self.udid  = self.c.udid
        self.identifier = self.udid
        #if not self.identifier:
        #    if self.UniqueChipID:
        #        self.identifier = "%x" % self.UniqueChipID
        #    else:
        #        print "Could not get UDID or ECID, failing"
        #        raise
        if not self.validate_pairing():
            if not self.pair():
                return
            self.validate_pairing()

    def generate_hostID(self):
        #hostname = socket.gethostname()
        hostname = platform.node()
        hostid = uuid.uuid3(uuid.NAMESPACE_DNS, hostname)
        return str(hostid).upper()

    #def __del__(self):
    #    self.stop_session()
    #    if self.c :
    #        self.c.sendPlist({"Request": "Goodbye"})
    #        res = self.c.recvPlist()
    #        return res
    #    #if not res or res.get("Result") != "Success":
    #    #    print "Goodbye fail :", res

    def enter_recovery(self):
        self.c.sendPlist({"Request": "EnterRecovery"})
        print self.c.recvPlist()

    def stop_session(self):
        if self.SessionID and self.c:
            self.c.sendPlist({
                "Request": "StopSession",
                "SessionID": self.SessionID
            })
            self.SessionID = None
            res = self.c.recvPlist()
            return res
            #pprint(res)
            #if not res or res.get("Result") != "Success":
            #    print "StopSession fail :", res

    def validate_pairing(self):
        pair_record = None
        certPem = None
        privateKeyPem = None

        record = readHomeFile(HOMEFOLDER, "%s.plist" % self.identifier)
        if record:
            pair_record = plistlib.readPlistFromString(record)
            certPem = pair_record["HostCertificate"].data
            privateKeyPem = pair_record["HostPrivateKey"].data
            print "Found pairing record for device %s" % self.udid
        else:
            print "No pairing record found for device %s" % self.identifier
            return
        if False:
            if sys.platform == "win32":
                folder = os.environ["ALLUSERSPROFILE"] + "/Apple/Lockdown/"
            elif sys.platform == "darwin":
                folder = "/var/db/lockdown/"
            pair_record = plistlib.readPlist(folder +
                                             "%s.plist" % self.identifier)
            print "Using iTunes pair record"

        ValidatePair = {"Request": "ValidatePair", "PairRecord": pair_record}
        self.c.sendPlist(ValidatePair)
        ValidatePair = self.c.recvPlist()
        if not ValidatePair or ValidatePair.has_key("Error"):
            pair_record = None
            print "ValidatePair fail", ValidatePair
            return False
        self.paired = True
        #print "Validate Pairing OK", ValidatePair
        d = {
            "Request": "StartSession",
            "HostID": pair_record.get("HostID", self.hostID)
        }
        self.c.sendPlist(d)
        startsession = self.c.recvPlist()
        #print "Starting session",startsession
        self.SessionID = startsession.get("SessionID")
        if startsession.get("EnableSessionSSL"):
            sslfile = self.identifier + "_ssl.txt"
            sslfile = writeHomeFile(HOMEFOLDER, sslfile,
                                    certPem + "\n" + privateKeyPem)
            self.c.ssl_start(sslfile, sslfile)
            #print "SSL started"
            self.udid = self.getValue("", "UniqueDeviceID")
            self.allValues = self.getValue("", "")
            #print "UDID", self.udid
        return True

    def pair(self):
        self.DevicePublicKey = self.getValue("", "DevicePublicKey")
        if self.DevicePublicKey == '':
            return
        print "Got device public key"
        print "Creating host key & certificate"
        certPem, privateKeyPem, DeviceCertificate = ca_do_everything(
            self.DevicePublicKey)

        pair_record = {
            "DevicePublicKey": plistlib.Data(self.DevicePublicKey),
            "DeviceCertificate": plistlib.Data(DeviceCertificate),
            "HostCertificate": plistlib.Data(certPem),
            "HostID": self.hostID,
            "RootCertificate": plistlib.Data(certPem),
            "SystemBUID": "30142955-444094379208051516"
        }
        Pair = {"Request": "Pair", "PairRecord": pair_record}
        self.c.sendPlist(Pair)
        Pair = self.c.recvPlist()
        if Pair and Pair.get("Result") == "Success" or Pair.has_key(
                "EscrowBag"):
            #print "Pairing OK"
            pair_record["HostPrivateKey"] = plistlib.Data(privateKeyPem)
            if Pair.has_key("EscrowBag"):
                pair_record["EscrowBag"] = Pair["EscrowBag"]
            writeHomeFile(HOMEFOLDER, "%s.plist" % self.identifier,
                          plistlib.writePlistToString(pair_record))
            return True
        print "Pairing error", Pair
        return False

    def getValue(self, domain=None, key=None):
        req = {"Request": "GetValue", "Label": self.label}

        if domain:
            req["Domain"] = domain
        if key:
            req["Key"] = key
        self.c.sendPlist(req)
        res = self.c.recvPlist()
        if res:
            r = res.get("Value")
            if hasattr(r, "data"):
                return r.data
            return r

    def startService(self, name):
        if not self.paired:
            print "Cannot startService %s, not paired" % name
            return
        self.c.sendPlist({"Request": "StartService", "Service": name})
        StartService = self.c.recvPlist()
        if not StartService:
            return
        if StartService.has_key("Error"):
            print StartService["Error"], name
            return
        #print StartService
        zz = PlistService(StartService["Port"])
        return zz