LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhd2F5IGxpa2UgYSBtYWRtYW4gYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAic2V0dXAuaCIKCiNpZm5kZWYgQ1VSTF9ESVNBQkxFX0ZUUAojaWZkZWYgSEFWRV9LUkI0CgojaW5jbHVkZSAic2VjdXJpdHkuaCIKI2luY2x1ZGUgImJhc2U2NC5oIgojaW5jbHVkZSA8c3RkbGliLmg+CiNpZmRlZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxrcmIuaD4KI2luY2x1ZGUgPGRlcy5oPgoKI2lmZGVmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPiAvKiBmb3IgZ2V0cGlkKCkgKi8KI2VuZGlmCgojaW5jbHVkZSAiZnRwLmgiCiNpbmNsdWRlICJzZW5kZi5oIgojaW5jbHVkZSAia3JiNC5oIgojaW5jbHVkZSAiY3VybF9tZW1vcnkuaCIKCiNpZiBkZWZpbmVkKEhBVkVfSU5FVF9OVE9BX1IpICYmICFkZWZpbmVkKEhBVkVfSU5FVF9OVE9BX1JfREVDTCkKI2luY2x1ZGUgImluZXRfbnRvYV9yLmgiCiNlbmRpZgoKLyogVGhlIGxhc3QgI2luY2x1ZGUgZmlsZSBzaG91bGQgYmU6ICovCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgoKI2RlZmluZSBMT0NBTF9BRERSICgmY29ubi0+bG9jYWxfYWRkcikKI2RlZmluZSBSRU1PVEVfQUREUiBjb25uLT5pcF9hZGRyLT5haV9hZGRyCiNkZWZpbmUgbXljdGxhZGRyIExPQ0FMX0FERFIKI2RlZmluZSBoaXNjdGxhZGRyIFJFTU9URV9BRERSCgpzdHJ1Y3Qga3JiNF9kYXRhIHsKICBkZXNfY2Jsb2NrIGtleTsKICBkZXNfa2V5X3NjaGVkdWxlIHNjaGVkdWxlOwogIGNoYXIgbmFtZVtBTkFNRV9TWl07CiAgY2hhciBpbnN0YW5jZVtJTlNUX1NaXTsKICBjaGFyIHJlYWxtW1JFQUxNX1NaXTsKfTsKCiNpZm5kZWYgSEFWRV9TVFJMQ1BZCi8qIGlmIGl0IGV2ZXIgZ29lcyBub24tc3RhdGljLCBtYWtlIGl0IEN1cmxfIHByZWZpeGVkISAqLwpzdGF0aWMgc2l6ZV90CnN0cmxjcHkgKGNoYXIgKmRzdCwgY29uc3QgY2hhciAqc3JjLCBzaXplX3QgZHN0X3N6KQp7CiAgc2l6ZV90IG47CiAgY2hhciAqcDsKCiAgZm9yIChwID0gZHN0LCBuID0gMDsKICAgICAgIG4gKyAxIDwgZHN0X3N6ICYmICpzcmMgIT0gJ1wwJzsKICAgICAgICsrcCwgKytzcmMsICsrbikKICAgICpwID0gKnNyYzsKICAqcCA9ICdcMCc7CiAgaWYgKCpzcmMgPT0gJ1wwJykKICAgIHJldHVybiBuOwogIGVsc2UKICAgIHJldHVybiBuICsgc3RybGVuIChzcmMpOwp9CiNlbHNlCnNpemVfdCBzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeik7CiNlbmRpZgoKc3RhdGljIGludAprcmI0X2NoZWNrX3Byb3Qodm9pZCAqYXBwX2RhdGEsIGludCBsZXZlbCkKewogIGFwcF9kYXRhID0gTlVMTDsgLyogcHJldmVudCBjb21waWxlciB3YXJuaW5nICovCiAgaWYobGV2ZWwgPT0gcHJvdF9jb25maWRlbnRpYWwpCiAgICByZXR1cm4gLTE7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKa3JiNF9kZWNvZGUodm9pZCAqYXBwX2RhdGEsIHZvaWQgKmJ1ZiwgaW50IGxlbiwgaW50IGxldmVsLAogICAgICAgICAgICBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBNU0dfREFUIG07CiAgaW50IGU7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwoKICBpZihsZXZlbCA9PSBwcm90X3NhZmUpCiAgICBlID0ga3JiX3JkX3NhZmUoYnVmLCBsZW4sICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLCAmbSk7CiAgZWxzZQogICAgZSA9IGtyYl9yZF9wcml2KGJ1ZiwgbGVuLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIsCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICBpZihlKSB7CiAgICBzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YSA9IGNvbm4tPmRhdGE7CiAgICBpbmZvZihkYXRhLCAia3JiNF9kZWNvZGU6ICVzXG4iLCBrcmJfZ2V0X2Vycl90ZXh0KGUpKTsKICAgIHJldHVybiAtMTsKICB9CiAgbWVtbW92ZShidWYsIG0uYXBwX2RhdGEsIG0uYXBwX2xlbmd0aCk7CiAgcmV0dXJuIG0uYXBwX2xlbmd0aDsKfQoKc3RhdGljIGludAprcmI0X292ZXJoZWFkKHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwsIGludCBsZW4pCnsKICAvKiBubyBhcmd1bWVudHMgYXJlIHVzZWQsIGp1c3QgaW5pdCB0aGVtIHRvIHByZXZlbnQgY29tcGlsZXIgd2FybmluZ3MgKi8KICBhcHBfZGF0YSA9IE5VTEw7CiAgbGV2ZWwgPSAwOwogIGxlbiA9IDA7CiAgcmV0dXJuIDMxOwp9CgpzdGF0aWMgaW50CmtyYjRfZW5jb2RlKHZvaWQgKmFwcF9kYXRhLCB2b2lkICpmcm9tLCBpbnQgbGVuZ3RoLCBpbnQgbGV2ZWwsIHZvaWQgKip0bywKICAgICAgICAgICAgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwogICp0byA9IG1hbGxvYyhsZW5ndGggKyAzMSk7CiAgaWYobGV2ZWwgPT0gcHJvdF9zYWZlKQogICAgcmV0dXJuIGtyYl9ta19zYWZlKGZyb20sICp0bywgbGVuZ3RoLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUik7CiAgZWxzZSBpZihsZXZlbCA9PSBwcm90X3ByaXZhdGUpCiAgICByZXR1cm4ga3JiX21rX3ByaXYoZnJvbSwgKnRvLCBsZW5ndGgsIGQtPnNjaGVkdWxlLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUik7CiAgZWxzZQogICAgcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50Cm1rX2F1dGgoc3RydWN0IGtyYjRfZGF0YSAqZCwgS1RFWFQgYWRhdCwKICAgICAgICBjb25zdCBjaGFyICpzZXJ2aWNlLCBjaGFyICpob3N0LCBpbnQgY2hlY2tzdW0pCnsKICBpbnQgcmV0OwogIENSRURFTlRJQUxTIGNyZWQ7CiAgY2hhciBzbmFtZVtTTkFNRV9TWl0sIGluc3RbSU5TVF9TWl0sIHJlYWxtW1JFQUxNX1NaXTsKCiAgc3RybGNweShzbmFtZSwgc2VydmljZSwgc2l6ZW9mKHNuYW1lKSk7CiAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgcmV0ID0ga3JiX21rX3JlcShhZGF0LCBzbmFtZSwgaW5zdCwgcmVhbG0sIGNoZWNrc3VtKTsKICBpZihyZXQpCiAgICByZXR1cm4gcmV0OwogIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICBzdHJsY3B5KHJlYWxtLCBrcmJfcmVhbG1vZmhvc3QoaG9zdCksIHNpemVvZihyZWFsbSkpOwogIHJldCA9IGtyYl9nZXRfY3JlZChzbmFtZSwgaW5zdCwgcmVhbG0sICZjcmVkKTsKICBtZW1tb3ZlKCZkLT5rZXksICZjcmVkLnNlc3Npb24sIHNpemVvZihkZXNfY2Jsb2NrKSk7CiAgZGVzX2tleV9zY2hlZCgmZC0+a2V5LCBkLT5zY2hlZHVsZSk7CiAgbWVtc2V0KCZjcmVkLCAwLCBzaXplb2YoY3JlZCkpOwogIHJldHVybiByZXQ7Cn0KCiNpZmRlZiBIQVZFX0tSQl9HRVRfT1VSX0lQX0ZPUl9SRUFMTQppbnQga3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKGNoYXIgKiwgc3RydWN0IGluX2FkZHIgKik7CiNlbmRpZgoKc3RhdGljIGludAprcmI0X2F1dGgodm9pZCAqYXBwX2RhdGEsIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGludCByZXQ7CiAgY2hhciAqcDsKICBpbnQgbGVuOwogIEtURVhUX1NUIGFkYXQ7CiAgTVNHX0RBVCBtc2dfZGF0YTsKICBpbnQgY2hlY2tzdW07CiAgdV9pbnQzMl90IGNzOwogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICBjaGFyICpob3N0ID0gY29ubi0+aG9zdC5uYW1lOwogIHNzaXplX3QgbnJlYWQ7CiAgaW50IGwgPSBzaXplb2YoY29ubi0+bG9jYWxfYWRkcik7CiAgc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGEgPSBjb25uLT5kYXRhOwogIENVUkxjb2RlIHJlc3VsdDsKCiAgaWYoZ2V0c29ja25hbWUoY29ubi0+c29ja1tGSVJTVFNPQ0tFVF0sCiAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkciAqKUxPQ0FMX0FERFIsICZsKSA8IDApCiAgICBwZXJyb3IoImdldHNvY2tuYW1lKCkiKTsKCiAgY2hlY2tzdW0gPSBnZXRwaWQoKTsKICByZXQgPSBta19hdXRoKGQsICZhZGF0LCAiZnRwIiwgaG9zdCwgY2hlY2tzdW0pOwogIGlmKHJldCA9PSBLRENfUFJfVU5LTk9XTikKICAgIHJldCA9IG1rX2F1dGgoZCwgJmFkYXQsICJyY21kIiwgaG9zdCwgY2hlY2tzdW0pOwogIGlmKHJldCkgewogICAgQ3VybF9pbmZvZihkYXRhLCAiJXNcbiIsIGtyYl9nZXRfZXJyX3RleHQocmV0KSk7CiAgICByZXR1cm4gQVVUSF9DT05USU5VRTsKICB9CgojaWZkZWYgSEFWRV9LUkJfR0VUX09VUl9JUF9GT1JfUkVBTE0KICBpZiAoa3JiX2dldF9jb25maWdfYm9vbCgibmF0X2luX3VzZSIpKSB7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gKmxvY2FsYWRkciAgPSAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUjsKICAgIHN0cnVjdCBpbl9hZGRyIG5hdEFkZHI7CgogICAgaWYgKGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShrcmJfcmVhbG1vZmhvc3QoaG9zdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZuYXRBZGRyKSAhPSBLU1VDQ0VTUwogICAgICAgICYmIGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShOVUxMLCAmbmF0QWRkcikgIT0gS1NVQ0NFU1MpCiAgICAgIEN1cmxfaW5mb2YoZGF0YSwgIkNhbid0IGdldCBhZGRyZXNzIGZvciByZWFsbSAlc1xuIiwKICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoaG9zdCkpOwogICAgZWxzZSB7CiAgICAgIGlmIChuYXRBZGRyLnNfYWRkciAhPSBsb2NhbGFkZHItPnNpbl9hZGRyLnNfYWRkcikgewojaWZkZWYgSEFWRV9JTkVUX05UT0FfUgogICAgICAgIGNoYXIgbnRvYV9idWZbNjRdOwogICAgICAgIGNoYXIgKmlwID0gKGNoYXIgKilpbmV0X250b2FfcihuYXRBZGRyLCBudG9hX2J1Ziwgc2l6ZW9mKG50b2FfYnVmKSk7CiNlbHNlCiAgICAgICAgY2hhciAqaXAgPSAoY2hhciAqKWluZXRfbnRvYShuYXRBZGRyKTsKI2VuZGlmCiAgICAgICAgQ3VybF9pbmZvZihkYXRhLCAiVXNpbmcgTkFUIElQIGFkZHJlc3MgKCVzKSBmb3Iga2VyYmVyb3MgNFxuIiwgaXApOwogICAgICAgIGxvY2FsYWRkci0+c2luX2FkZHIgPSBuYXRBZGRyOwogICAgICB9CiAgICB9CiAgfQojZW5kaWYKCiAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKChjaGFyICopYWRhdC5kYXQsIGFkYXQubGVuZ3RoLCAmcCkgPCAxKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJPdXQgb2YgbWVtb3J5IGJhc2U2NC1lbmNvZGluZyIpOwogICAgcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgfQoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJBREFUICVzIiwgcCk7CgogIGZyZWUocCk7CgogIGlmKHJlc3VsdCkKICAgIHJldHVybiAtMjsKCiAgaWYoQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sIE5VTEwpKQogICAgcmV0dXJuIC0xOwoKICBpZihkYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzInKXsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIlNlcnZlciBkaWRuJ3QgYWNjZXB0IGF1dGggZGF0YSIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQoKICBwID0gc3Ryc3RyKGRhdGEtPnN0YXRlLmJ1ZmZlciwgIkFEQVQ9Iik7CiAgaWYoIXApIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIlJlbW90ZSBob3N0IGRpZG4ndCBzZW5kIGFkYXQgcmVwbHkiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBwICs9IDU7CiAgbGVuID0gQ3VybF9iYXNlNjRfZGVjb2RlKHAsIChjaGFyICopYWRhdC5kYXQpOwogIGlmKGxlbiA8IDApIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIkZhaWxlZCB0byBkZWNvZGUgYmFzZTY0IGZyb20gc2VydmVyIik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgYWRhdC5sZW5ndGggPSBsZW47CiAgcmV0ID0ga3JiX3JkX3NhZmUoYWRhdC5kYXQsIGFkYXQubGVuZ3RoLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKiloaXNjdGxhZGRyLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilteWN0bGFkZHIsICZtc2dfZGF0YSk7CiAgaWYocmV0KSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJFcnJvciByZWFkaW5nIHJlcGx5IGZyb20gc2VydmVyOiAlcyIsCiAgICAgICAgICAgICAgIGtyYl9nZXRfZXJyX3RleHQocmV0KSk7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAga3JiX2dldF9pbnQobXNnX2RhdGEuYXBwX2RhdGEsICZjcywgNCwgMCk7CiAgaWYoY3MgLSBjaGVja3N1bSAhPSAxKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJCYWQgY2hlY2tzdW0gcmV0dXJuZWQgZnJvbSBzZXJ2ZXIiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICByZXR1cm4gQVVUSF9PSzsKfQoKc3RydWN0IEN1cmxfc2VjX2NsaWVudF9tZWNoIEN1cmxfa3JiNF9jbGllbnRfbWVjaCA9IHsKICAgICJLRVJCRVJPU19WNCIsCiAgICBzaXplb2Yoc3RydWN0IGtyYjRfZGF0YSksCiAgICBOVUxMLCAvKiBpbml0ICovCiAgICBrcmI0X2F1dGgsCiAgICBOVUxMLCAvKiBlbmQgKi8KICAgIGtyYjRfY2hlY2tfcHJvdCwKICAgIGtyYjRfb3ZlcmhlYWQsCiAgICBrcmI0X2VuY29kZSwKICAgIGtyYjRfZGVjb2RlCn07CgpDVVJMY29kZSBDdXJsX2tyYl9rYXV0aChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBkZXNfY2Jsb2NrIGtleTsKICBkZXNfa2V5X3NjaGVkdWxlIHNjaGVkdWxlOwogIEtURVhUX1NUIHRrdCwgdGt0Y29weTsKICBjaGFyICpuYW1lOwogIGNoYXIgKnA7CiAgY2hhciBwYXNzd2RbMTAwXTsKICBpbnQgdG1wOwogIHNzaXplX3QgbnJlYWQ7CiAgaW50IHNhdmU7CiAgQ1VSTGNvZGUgcmVzdWx0OwoKICBzYXZlID0gQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHByb3RfcHJpdmF0ZSk7CgogIHJlc3VsdCA9IEN1cmxfZnRwc2VuZGYoY29ubiwgIlNJVEUgS0FVVEggJXMiLCBjb25uLT51c2VyKTsKCiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKCiAgcmVzdWx0ID0gQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sIE5VTEwpOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIGlmKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMycpewogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQoKICBwID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlQ9Iik7CiAgaWYoIXApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkJhZCByZXBseSBmcm9tIHNlcnZlciIpOwogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQoKICBwICs9IDI7CiAgdG1wID0gQ3VybF9iYXNlNjRfZGVjb2RlKHAsIChjaGFyICopdGt0LmRhdCk7CiAgaWYodG1wIDwgMCkgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIGRlY29kZSBiYXNlNjQgaW4gcmVwbHkuXG4iKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KICB0a3QubGVuZ3RoID0gdG1wOwogIHRrdGNvcHkubGVuZ3RoID0gdGt0Lmxlbmd0aDsKCiAgcCA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJQPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJCYWQgcmVwbHkgZnJvbSBzZXJ2ZXIiKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KICBuYW1lID0gcCArIDI7CiAgZm9yKDsgKnAgJiYgKnAgIT0gJyAnICYmICpwICE9ICdccicgJiYgKnAgIT0gJ1xuJzsgcCsrKTsKICAqcCA9IDA7CgogIGRlc19zdHJpbmdfdG9fa2V5IChjb25uLT5wYXNzd2QsICZrZXkpOwogIGRlc19rZXlfc2NoZWQoJmtleSwgc2NoZWR1bGUpOwoKICBkZXNfcGNiY19lbmNyeXB0KCh2b2lkICopdGt0LmRhdCwgKHZvaWQgKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgIHRrdC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogIGlmIChzdHJjbXAgKChjaGFyKil0a3Rjb3B5LmRhdCArIDgsCiAgICAgICAgICAgICAgS1JCX1RJQ0tFVF9HUkFOVElOR19USUNLRVQpICE9IDApIHsKICAgIGFmc19zdHJpbmdfdG9fa2V5KHBhc3N3ZCwKICAgICAgICAgICAgICAgICAgICAgIGtyYl9yZWFsbW9maG9zdChjb25uLT5ob3N0Lm5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgJmtleSk7CiAgICBkZXNfa2V5X3NjaGVkKCZrZXksIHNjaGVkdWxlKTsKICAgIGRlc19wY2JjX2VuY3J5cHQoKHZvaWQgKil0a3QuZGF0LCAodm9pZCAqKXRrdGNvcHkuZGF0LAogICAgICAgICAgICAgICAgICAgICB0a3QubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogIH0KICBtZW1zZXQoa2V5LCAwLCBzaXplb2Yoa2V5KSk7CiAgbWVtc2V0KHNjaGVkdWxlLCAwLCBzaXplb2Yoc2NoZWR1bGUpKTsKICBtZW1zZXQocGFzc3dkLCAwLCBzaXplb2YocGFzc3dkKSk7CiAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKChjaGFyICopdGt0Y29weS5kYXQsIHRrdGNvcHkubGVuZ3RoLCAmcCkgPCAxKSB7CiAgICBmYWlsZihjb25uLT5kYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmcuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfT1VUX09GX01FTU9SWTsKICB9CiAgbWVtc2V0ICh0a3Rjb3B5LmRhdCwgMCwgdGt0Y29weS5sZW5ndGgpOwoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzICVzIiwgbmFtZSwgcCk7CiAgZnJlZShwKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICByZXN1bHQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgTlVMTCk7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CgogIHJldHVybiBDVVJMRV9PSzsKfQoKI2VuZGlmIC8qIEhBVkVfS1JCNCAqLwojZW5kaWYgLyogQ1VSTF9ESVNBQkxFX0ZUUCAqLwo=