From 8b9988b88dad0e75ffc05666f18b2387d809647c Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Fri, 7 Feb 2020 10:11:36 -0800 Subject: [PATCH] Added support for Firewall Filter modifications on Windows --- microscript/ILibDuktape_Polyfills.c | 9 ++ modules/win-firewall.js | 191 ++++++++++++++++++---------- 2 files changed, 134 insertions(+), 66 deletions(-) diff --git a/microscript/ILibDuktape_Polyfills.c b/microscript/ILibDuktape_Polyfills.c index 736dacd..35d4697 100644 --- a/microscript/ILibDuktape_Polyfills.c +++ b/microscript/ILibDuktape_Polyfills.c @@ -2052,6 +2052,15 @@ void ILibDuktape_Polyfills_JS_Init(duk_context *ctx) // win-dispatcher a helper to run JavaScript as a particular user. Refer to modules/win-dispatcher.js duk_peval_string_noresult(ctx, "addModule('win-dispatcher', Buffer.from('LyoKQ29weXJpZ2h0IDIwMTkgSW50ZWwgQ29ycG9yYXRpb24KCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwp5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQpkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLApXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZApsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKi8KCgpmdW5jdGlvbiBkaXNwYXRjaChvcHRpb25zKQp7CiAgICBpZiAoIW9wdGlvbnMgfHwgIW9wdGlvbnMubW9kdWxlcyB8fCAhb3B0aW9ucy5sYXVuY2ggfHwgIW9wdGlvbnMubGF1bmNoLm1vZHVsZSB8fCAhb3B0aW9ucy5sYXVuY2gubWV0aG9kIHx8ICFvcHRpb25zLmxhdW5jaC5hcmdzKSB7IHRocm93ICgnSW52YWxpZCBQYXJhbWV0ZXJzJyk7IH0KCiAgICB2YXIgaXBjSW50ZWdlcgogICAgdmFyIHJldCA9IHsgb3B0aW9uczogb3B0aW9ucyB9OwogICAgcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyLmNhbGwocmV0LCB0cnVlKS5jcmVhdGVFdmVudCgnY29ubmVjdGlvbicpOwoKICAgIHJldC5faXBjID0gcmVxdWlyZSgnbmV0JykuY3JlYXRlU2VydmVyKCk7IHJldC5faXBjLnBhcmVudCA9IHJldDsKICAgIHJldC5faXBjMiA9IHJlcXVpcmUoJ25ldCcpLmNyZWF0ZVNlcnZlcigpOyByZXQuX2lwYzIucGFyZW50ID0gcmV0OwogICAgcmV0Ll9pcGMub24oJ2Nsb3NlJywgZnVuY3Rpb24gKCkgeyB9KTsKICAgIHJldC5faXBjMi5vbignY2xvc2UnLCBmdW5jdGlvbiAoKSB7IH0pOwoKICAgIHdoaWxlICh0cnVlKQogICAgewogICAgICAgIGlwY0ludGVnZXIgPSByZXF1aXJlKCd0bHMnKS5nZW5lcmF0ZVJhbmRvbUludGVnZXIoJzEwMDAnLCAnOTk5OScpOwogICAgICAgIHJldC5faXBjUGF0aCA9ICdcXFxcLlxccGlwZVxcdGFza1JlZGlyZWN0aW9uLScgKyBpcGNJbnRlZ2VyOwogICAgICAgIAogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgcmV0Ll9pcGMubGlzdGVuKHsgcGF0aDogcmV0Ll9pcGNQYXRoLCB3cml0YWJsZUFsbDogdHJ1ZSB9KTsKICAgICAgICAgICAgcmV0Ll9pcGMyLmxpc3Rlbih7IHBhdGg6IHJldC5faXBjUGF0aCArICdDJywgd3JpdGFibGVBbGw6IHRydWUgfSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoeCkKICAgICAgICB7CiAgICAgICAgfQogICAgfQogICAgdmFyIHN0ciA9IEJ1ZmZlci5mcm9tKCJyZXF1aXJlKCd3aW4tY29uc29sZScpLmhpZGUoKTtyZXF1aXJlKCd3aW4tZGlzcGF0Y2hlcicpLmNvbm5lY3QoJyIgKyBpcGNJbnRlZ2VyICsgIicpOyIpLnRvU3RyaW5nKCdiYXNlNjQnKTsKICAgIHJldC5faXBjMi5vbmNlKCdjb25uZWN0aW9uJywgZnVuY3Rpb24gb25Db25uZWN0KHMpCiAgICB7DQogICAgICAgIHRoaXMucGFyZW50Ll9jb250cm9sID0gczsNCiAgICAgICAgdGhpcy5wYXJlbnQuX2NvbnRyb2wuX3BhcmVudCA9IHRoaXM7DQogICAgICAgIHRoaXMucGFyZW50Lmludm9rZSA9IGZ1bmN0aW9uIChtZXRob2QsIGFyZ3MpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBkLCBoID0gQnVmZmVyLmFsbG9jKDQpOwogICAgICAgICAgICBkID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoeyBjb21tYW5kOiAnaW52b2tlJywgdmFsdWU6IHsgbWV0aG9kOiBtZXRob2QsIGFyZ3M6IGFyZ3MgfSB9KSk7CiAgICAgICAgICAgIGgud3JpdGVVSW50MzJMRShkLmxlbmd0aCArIDQpOwogICAgICAgICAgICB0aGlzLl9jb250cm9sLndyaXRlKGgpOwogICAgICAgICAgICB0aGlzLl9jb250cm9sLndyaXRlKGQpOw0KICAgICAgICB9Ow0KICAgICAgICBzLm9uY2UoJ2VuZCcsIGZ1bmN0aW9uICgpIHsgdGhpcy5fcGFyZW50LmNsb3NlKCk7IH0pOw0KICAgIH0pOwogICAgcmV0Ll9pcGMub25jZSgnY29ubmVjdGlvbicsIGZ1bmN0aW9uIG9uQ29ubmVjdChzKQogICAgewogICAgICAgIHRoaXMucGFyZW50Ll9jbGllbnQgPSBzOwogICAgICAgIHRoaXMucGFyZW50Ll9jbGllbnQuX3BhcmVudCA9IHRoaXM7CiAgICAgICAgdmFyIGQsIGggPSBCdWZmZXIuYWxsb2MoNCk7CgogICAgICAgIGZvciAodmFyIG0gaW4gdGhpcy5wYXJlbnQub3B0aW9ucy5tb2R1bGVzKQogICAgICAgIHsKICAgICAgICAgICAgZCA9IEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KHsgY29tbWFuZDogJ2FkZE1vZHVsZScsIHZhbHVlOiB7IG5hbWU6IHRoaXMucGFyZW50Lm9wdGlvbnMubW9kdWxlc1ttXS5uYW1lLCBqczogdGhpcy5wYXJlbnQub3B0aW9ucy5tb2R1bGVzW21dLnNjcmlwdCB9IH0pKTsKICAgICAgICAgICAgaC53cml0ZVVJbnQzMkxFKGQubGVuZ3RoICsgNCk7CiAgICAgICAgICAgIHMud3JpdGUoaCk7CiAgICAgICAgICAgIHMud3JpdGUoZCk7CiAgICAgICAgfQoKICAgICAgICBkID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoeyBjb21tYW5kOiAnbGF1bmNoJywgdmFsdWU6IHsgbW9kdWxlOiB0aGlzLnBhcmVudC5vcHRpb25zLmxhdW5jaC5tb2R1bGUsIG1ldGhvZDogdGhpcy5wYXJlbnQub3B0aW9ucy5sYXVuY2gubWV0aG9kLCBhcmdzOiB0aGlzLnBhcmVudC5vcHRpb25zLmxhdW5jaC5hcmdzIH0gfSkpOwogICAgICAgIGgud3JpdGVVSW50MzJMRShkLmxlbmd0aCArIDQpOwogICAgICAgIHMud3JpdGUoaCk7CiAgICAgICAgcy53cml0ZShkKTsKICAgICAgICBzLm9uY2UoJ2VuZCcsIGZ1bmN0aW9uICgpIHsgdGhpcy5fcGFyZW50LmNsb3NlKCk7IH0pOwogICAgICAgIHRoaXMucGFyZW50LmVtaXQoJ2Nvbm5lY3Rpb24nLCBzKTsKICAgIH0pOwoKICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZShwcm9jZXNzLmVudlsnd2luZGlyJ10gKyAnXFxzeXN0ZW0zMlxcY21kLmV4ZScsIFsnY21kJ10pOwogICAgY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgfSk7CiAgICBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB9KTsKCiAgICBpZiAob3B0aW9ucy51c2VyKQogICAgewogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCdTQ0hUQVNLUyAvQ1JFQVRFIC9GIC9UTiBNZXNoVXNlclRhc2sgL1NDIE9OQ0UgL1NUIDAwOjAwIC9SVSAnICsgb3B0aW9ucy51c2VyICsgJyAvVFIgIicgKyBwcm9jZXNzLmV4ZWNQYXRoICsgJyAtYjY0ZXhlYyAnICsgc3RyICsgJyJcclxuJyk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5nZXRQcm9jZXNzT3duZXJOYW1lKHByb2Nlc3MucGlkKS50c2lkID09IDApCiAgICAgICAgew0KICAgICAgICAgICAgLy8gTG9jYWxTeXN0ZW0NCiAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCdTQ0hUQVNLUyAvQ1JFQVRFIC9GIC9UTiBNZXNoVXNlclRhc2sgL1NDIE9OQ0UgL1NUIDAwOjAwIC9SVSBTWVNURU0gL1RSICInICsgcHJvY2Vzcy5leGVjUGF0aCArICcgLWI2NGV4ZWMgJyArIHN0ciArICciXHJcbicpOw0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsNCiAgICAgICAgICAgIC8vIFJ1bm5pbmcgYXMgbG9nZ2VkIGluIHVzZXINCiAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCdTQ0hUQVNLUyAvQ1JFQVRFIC9GIC9UTiBNZXNoVXNlclRhc2sgL1NDIE9OQ0UgL1NUIDAwOjAwIC9UUiAiJyArIHByb2Nlc3MuZXhlY1BhdGggKyAnIC1iNjRleGVjICcgKyBzdHIgKyAnIlxyXG4nKTsNCiAgICAgICAgfQogICAgfQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ1NDSFRBU0tTIC9SVU4gL1ROIE1lc2hVc2VyVGFza1xyXG4nKTsKICAgIGNoaWxkLnN0ZGluLndyaXRlKCdTQ0hUQVNLUyAvREVMRVRFIC9GIC9UTiBNZXNoVXNlclRhc2tcclxuJyk7CiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZXhpdFxyXG4nKTsKICAgIGNoaWxkLndhaXRFeGl0KCk7CiAgICAKCiAgICByZXR1cm4gKHJldCk7Cn0KCmZ1bmN0aW9uIGNvbm5lY3QoaXBjKQp7CiAgICB2YXIgaXBjUGF0aCA9ICdcXFxcLlxccGlwZVxcdGFza1JlZGlyZWN0aW9uLScgKyBpcGM7CiAgICBnbG9iYWwuaXBjMkNsaWVudCA9IHJlcXVpcmUoJ25ldCcpLmNyZWF0ZUNvbm5lY3Rpb24oeyBwYXRoOiBpcGNQYXRoICsgJ0MnIH0sIGZ1bmN0aW9uICgpDQogICAgew0KICAgICAgICB0aGlzLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjTGVuID0gYy5yZWFkVUludDMyTEUoMCk7CiAgICAgICAgICAgIGlmIChjTGVuID4gYy5sZW5ndGgpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhpcy51bnNoaWZ0KGMpOwogICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGNtZCA9IEpTT04ucGFyc2UoYy5zbGljZSg0LCBjTGVuKS50b1N0cmluZygpKTsKICAgICAgICAgICAgc3dpdGNoIChjbWQuY29tbWFuZCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBjYXNlICdpbnZva2UnOgogICAgICAgICAgICAgICAgICAgIGdsb2JhbC5fcHJveHlTdHJlYW1bY21kLnZhbHVlLm1ldGhvZF0uYXBwbHkoZ2xvYmFsLl9wcm94eVN0cmVhbSwgY21kLnZhbHVlLmFyZ3MpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNMZW4gPCBjLmxlbmd0aCkgeyB0aGlzLnVuc2hpZnQoYy5zbGljZShjTGVuKSk7IH0NCiAgICAgICAgfSk7DQogICAgfSk7CiAgICBnbG9iYWwuaXBjQ2xpZW50ID0gcmVxdWlyZSgnbmV0JykuY3JlYXRlQ29ubmVjdGlvbih7IHBhdGg6IGlwY1BhdGggfSwgZnVuY3Rpb24gKCkKICAgIHsKICAgICAgICB0aGlzLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpCiAgICAgICAgewogICAgICAgICAgICB2YXIgY0xlbiA9IGMucmVhZFVJbnQzMkxFKDApOwogICAgICAgICAgICBpZiAoY0xlbiA+IGMubGVuZ3RoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLnVuc2hpZnQoYyk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBjbWQgPSBKU09OLnBhcnNlKGMuc2xpY2UoNCwgY0xlbikudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIHN3aXRjaCAoY21kLmNvbW1hbmQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgJ2FkZE1vZHVsZSc6CiAgICAgICAgICAgICAgICAgICAgYWRkTW9kdWxlKGNtZC52YWx1ZS5uYW1lLCBjbWQudmFsdWUuanMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnbGF1bmNoJzoKICAgICAgICAgICAgICAgICAgICB2YXIgb2JqID0gcmVxdWlyZShjbWQudmFsdWUubW9kdWxlKTsKICAgICAgICAgICAgICAgICAgICBnbG9iYWwuX3Byb3h5U3RyZWFtID0gb2JqW2NtZC52YWx1ZS5tZXRob2RdLmFwcGx5KG9iaiwgY21kLnZhbHVlLmFyZ3MpOwogICAgICAgICAgICAgICAgICAgIGdsb2JhbC5fcHJveHlTdHJlYW0ucGlwZSh0aGlzLCB7IGVuZDogZmFsc2UgfSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5waXBlKGdsb2JhbC5fcHJveHlTdHJlYW0sIHsgZW5kOiBmYWxzZSB9KTsKCiAgICAgICAgICAgICAgICAgICAgZ2xvYmFsLl9wcm94eVN0cmVhbS5vbignZW5kJywgZnVuY3Rpb24gKCkgeyBwcm9jZXNzLmV4aXQoKTsgfSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbignZW5kJywgZnVuY3Rpb24gKCkgeyBwcm9jZXNzLmV4aXQoKTsgfSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjTGVuIDwgYy5sZW5ndGgpIHsgdGhpcy51bnNoaWZ0KGMuc2xpY2UoY0xlbikpOyB9CiAgICAgICAgfSk7CiAgICB9KTsKfQoKbW9kdWxlLmV4cG9ydHMgPSB7IGRpc3BhdGNoOiBkaXNwYXRjaCwgY29ubmVjdDogY29ubmVjdCB9OwoK', 'base64').toString());"); + + // win-firewall is a helper to Modify Windows Firewall Filters. Refer to modules/win-firewall.js + char *_winfirewall = ILibMemory_Allocate(31788, 0, NULL, NULL); + memcpy_s(_winfirewall + 0, 18164, "LyoKQ29weXJpZ2h0IDIwMjAgSW50ZWwgQ29ycG9yYXRpb24KCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwp5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQpkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLApXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZApsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKi8KCnZhciBwcm9taXNlID0gcmVxdWlyZSgncHJvbWlzZScpOwp2YXIgd2lucmVnID0gcmVxdWlyZSgnd2luLXJlZ2lzdHJ5Jyk7CgpmdW5jdGlvbiBwYXJzZUNtZGxldE91dHB1dChkYXRhKQp7CiAgICB2YXIgdG91Y2hlZDsKICAgIHZhciByZXQgPSBbXTsKICAgIHZhciBjaHVua3MgPSBkYXRhLnRyaW0oKS5zcGxpdCgnXHJcblxyXG4nKTsKICAgIHZhciBsaW5lcywgeCwgb2JqOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaHVua3MubGVuZ3RoOyArK2kpCiAgICB7CiAgICAgICAgb2JqID0ge307IHRvdWNoZWQgPSBmYWxzZTsKICAgICAgICBsaW5lcyA9IGNodW5rc1tpXS5zcGxpdCgnXHJcbicpOwogICAgICAgIGZvciAoeCA9IDA7IHggPCBsaW5lcy5sZW5ndGg7ICsreCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBkID0gbGluZXNbeF0uaW5kZXhPZignOicpOwogICAgICAgICAgICB2YXIga2V5ID0gbGluZXNbeF0uc3Vic3RyaW5nKDAsIGQpLnRyaW0oKTsKICAgICAgICAgICAgdmFyIHZhbHVlID0gbGluZXNbeF0uc3Vic3RyaW5nKGQgKyAxKS50cmltKCk7CiAgICAgICAgICAgIGlmIChrZXkgIT0gIiIpIHsgb2JqW2tleV0gPSB2YWx1ZTsgdG91Y2hlZCA9IHRydWU7IH0KICAgICAgICB9CiAgICAgICAgaWYgKHRvdWNoZWQpIHsgcmV0LnB1c2gob2JqKTsgfQogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CmZ1bmN0aW9uIGZldGNoUG9ydEZpbHRlcnMocnVsZXMpCnsKICAgIHZhciBpOwogICAgaWYgKCFBcnJheS5pc0FycmF5KHJ1bGVzKSkKICAgIHsKICAgICAgICBydWxlcyA9IFtydWxlc107CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyArK2kpCiAgICB7CiAgICAgICAgZmlsdGVyID0gd2lucmVnLlF1ZXJ5S2V5KHdpbnJlZy5IS0VZLkxvY2FsTWFjaGluZSwgJ1NZU1RFTVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTaGFyZWRBY2Nlc3NcXFBhcmFtZXRlcnNcXEZpcmV3YWxsUG9saWN5XFxGaXJld2FsbFJ1bGVzJywgcnVsZXNbaV0uTmFtZSk7CiAgICAgICAgdG9rZW5zID0gZmlsdGVyLnNwbGl0KCd8Jyk7CiAgICAgICAgZm9yIChrID0gMDsgayA8IHRva2Vucy5sZW5ndGg7ICsraykKICAgICAgICB7CiAgICAgICAgICAgIGlmICgodG9rZW5YID0gdG9rZW5zW2tdLmluZGV4T2YoJz0nKSkgPiAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHRva2Vuc1trXS5zdWJzdHJpbmcoMCwgdG9rZW5YKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICdQcm90b2NvbCc6CiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVzW2ldLlByb3RvY29sID0gdG9rZW5zW2tdLnN1YnN0cmluZyh0b2tlblggKyAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnTFBvcnQnOgogICAgICAgICAgICAgICAgICAgICAgICBydWxlc1tpXS5Mb2NhbFBvcnQgPSB0b2tlbnNba10uc3Vic3RyaW5nKHRva2VuWCArIDEpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICdSUG9ydCc6CiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVzW2ldLlJlbW90ZVBvcnQgPSB0b2tlbnNba10uc3Vic3RyaW5nKHRva2VuWCArIDEpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICdBcHAnOgogICAgICAgICAgICAgICAgICAgICAgICBydWxlc1tpXS5Qcm9ncmFtID0gdG9rZW5zW2tdLnN1YnN0cmluZyh0b2tlblggKyAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCmZ1bmN0aW9uIGdldEZpcmV3YWxsUnVsZXMob3B0aW9ucykKewogICAgdmFyIHAgPSBuZXcgcHJvbWlzZShmdW5jdGlvbiAoYSwgcikgeyB0aGlzLl9yZXMgPSBhOyB0aGlzLl9yZWogPSByOyB9KTsKICAgIHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlci5jYWxsKHAsIHRydWUpCiAgICAgICAgLmNyZWF0ZUV2ZW50KCdmaXJld2FsbFJ1bGUnKTsKCiAgICB2YXIgcmV0VmFsID0gW10sIGZpbHRlciA9IFtdOwogICAgdmFyIGNvbW1hbmQgPSAnR2V0LU5ldEZpcmV3YWxsUnVsZSc7CiAgICBpZiAob3B0aW9ucy5wcm9ncmFtKSB7IGNvbW1hbmQgPSAnR2V0LU5ldEZpcmV3YWxsQXBwbGljYXRpb25GaWx0ZXIgLVByb2dyYW0gXFwiJyArIG9wdGlvbnMucHJvZ3JhbSArICdcXCIgfCAnICsgY29tbWFuZDsgfQoKICAgIGlmIChyZXF1aXJlKCdvcycpLmFyY2goKSA9PSAneDY0JykKICAgIHsKICAgICAgICBwLmNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKHByb2Nlc3MuZW52Wyd3aW5kaXInXSArICdcXFN5c3RlbTMyXFxXaW5kb3dzUG93ZXJTaGVsbFxcdjEuMFxccG93ZXJzaGVsbC5leGUnLCBbJy9DICInICsgY29tbWFuZCArICciJ10pOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHAuY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUocHJvY2Vzcy5lbnZbJ3dpbmRpciddICsgJ1xcU3lzdGVtMzJcXFdpbmRvd3NQb3dlclNoZWxsXFx2MS4wXFxwb3dlcnNoZWxsLmV4ZScsIFsnL0MgIicgKyBjb21tYW5kICsgJyInXSk7CiAgICB9CiAgICBwLm9wdGlvbnMgPSBvcHRpb25zOwogICAgcC5jaGlsZC5wYXJlbnQgPSBwOwogICAgcC5jaGlsZC5zdGRvdXQuc3RyID0gJyc7IHAuY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpCiAgICB7CiAgICAgICAgdmFyIGNvbW1hbmQ7CiAgICAgICAgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOwogICAgICAgIGlmKHRoaXMucGFyZW50LnBhcmVudC5saXN0ZW5lckNvdW50KCdmaXJld2FsbFJ1bGUnKT4wKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGk7CiAgICAgICAgICAgIGlmKChpPXRoaXMuc3RyLmluZGV4T2YoJ1xyXG5cclxuJykpPj0wKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgZmlsdGVyLCBrLCB0b2tlbnMsIHRva2VuWDsKICAgICAgICAgICAgICAgIHZhciBqID0gdGhpcy5zdHIuc3Vic3RyaW5nKDAsIGkpOwogICAgICAgICAgICAgICAgdGhpcy5zdHIgPSB0aGlzLnN0ci5zdWJzdHJpbmcoaSArIDQpOwoKICAgICAgICAgICAgICAgIGogPSBwYXJzZUNtZGxldE91dHB1dChqKTsKICAgICAgICAgICAgICAgIGZldGNoUG9ydEZpbHRlcnMoaik7CgogICAgICAgICAgICAgICAgZm9yKGk9MDtpPGoubGVuZ3RoOysraSkKICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LnBhcmVudC5lbWl0KCdmaXJld2FsbFJ1bGUnLCBqW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwogICAgcC5jaGlsZC5zdGRlcnIuc3RyID0gJyc7IHAuY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsKCiAgICBwLmNoaWxkLm9uKCdleGl0JywgZnVuY3Rpb24gKCkKICAgIHsKICAgICAgICB2YXIgY29tbWFuZCwgaSwgaiwgY2hpbGQsIGZpbHRlcjsKICAgICAgICBpZiAodGhpcy5zdGRlcnIuc3RyLnRyaW0oKSAhPSAiIikgeyB0aGlzLnBhcmVudC5fcmVqKHRoaXMuc3RkZXJyLnN0ci50cmltKCkpOyByZXR1cm47IH0KCiAgICAgICAgaWYgKHRoaXMucGFyZW50Lmxpc3RlbmVyQ291bnQoJ2ZpcmV3YWxsUnVsZScpID4gMCkKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMucGFyZW50Ll9yZXMoKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdmFyIG9iakFyciA9IHBhcnNlQ21kbGV0T3V0cHV0KHRoaXMuc3Rkb3V0LnN0cik7CiAgICAgICAgZmV0Y2hQb3J0RmlsdGVycyhvYmpBcnIpOwogICAgICAgIHRoaXMucGFyZW50Ll9yZXMob2JqQXJyKTsKICAgIH0pOwoKICAgIHJldHVybiAocCk7Cn0KCgpmdW5jdGlvbiBkaXNhYmxlRmlyZXdhbGxSdWxlcyhvcHRpb25zKQp7CiAgICB2YXIgcmV0ID0gbmV3IHByb21pc2UoZnVuY3Rpb24gKGEsIHIpIHsgdGhpcy5fcmVzID0gYTsgdGhpcy5fcmVqID0gcjsgfSk7CiAgICB2YXIgY29tbWFuZCA9ICdEaXNhYmxlLU5ldEZpcmV3YWxsUnVsZSc7CgogICAgaWYgKG9wdGlvbnMucHJvZ3JhbSkNCiAgICB7DQogICAgICAgIGNvbW1hbmQgPSAnR2V0LU5ldEZpcmV3YWxsQXBwbGljYXRpb25GaWx0ZXIgLVByb2dyYW0gXFwiJyArIG9wdGlvbnMucHJvZ3JhbSArICdcXCIgfCAnICsgY29tbWFuZDsNCiAgICB9CiAgICBlbHNlDQogICAgew0KICAgICAgICB2YXIga2V5LCB2YWx1ZTsNCiAgICAgICAgZm9yIChrZXkgaW4gb3B0aW9ucykNCiAgICAgICAgew0KICAgICAgICAgICAgdmFsdWUgPSBvcHRpb25zW2tleV07DQogICAgICAgICAgICBpZiAodmFsdWUuaW5kZXhPZignICcpID49IDApIHsgdmFsdWUgPSAnXFwiJyArIG9wdGlvbnNba2V5XSArICdcXCInOyB9DQogICAgICAgICAgICBjb21tYW5kICs9ICgnLScgKyBrZXkgKyAnICcgKyB2YWx1ZSk7DQogICAgICAgIH0NCiAgICB9CgogICAgaWYgKHJlcXVpcmUoJ29zJykuYXJjaCgpID09ICd4NjQnKQogICAgewogICAgICAgIHJldC5jaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZShwcm9jZXNzLmVudlsnd2luZGlyJ10gKyAnXFxTeXN0ZW0zMlxcV2luZG93c1Bvd2VyU2hlbGxcXHYxLjBcXHBvd2Vyc2hlbGwuZXhlJywgWycvQyAiJyArIGNvbW1hbmQgKyAnIiddKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXQuY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUocHJvY2Vzcy5lbnZbJ3dpbmRpciddICsgJ1xcU3lzdGVtMzJcXFdpbmRvd3NQb3dlclNoZWxsXFx2MS4wXFxwb3dlcnNoZWxsLmV4ZScsIFsnL0MgIicgKyBjb21tYW5kICsgJyInXSk7CiAgICB9CgogICAgcmV0LmNoaWxkLnJldCA9IHJldDsKICAgIHJldC5jaGlsZC5zdGRvdXQuc3RyID0gJyc7IHJldC5jaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOwogICAgcmV0LmNoaWxkLnN0ZGVyci5zdHIgPSAnJzsgcmV0LmNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7CiAgICByZXQuY2hpbGQub24oJ2V4aXQnLCBmdW5jdGlvbiAoKQ0KICAgIHsNCiAgICAgICAgaWYgKHRoaXMuc3RkZXJyLnN0ciAhPSAnJykNCiAgICAgICAgew0KICAgICAgICAgICAgdGhpcy5yZXQuX3Jlaih0aGlzLnN0ZGVyci5zdHIudHJpbSgpKTsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlDQogICAgICAgIHsNCiAgICAgICAgICAgIHRoaXMucmV0Ll9yZXMoKTsNCiAgICAgICAgfQ0KICAgIH0pOwoKICAgIHJldHVybiAocmV0KTsKfQoKZnVuY3Rpb24gZW5hYmxlRmlyZXdhbGxSdWxlcyhvcHRpb25zKQp7CiAgICB2YXIgcmV0ID0gbmV3IHByb21pc2UoZnVuY3Rpb24gKGEsIHIpIHsgdGhpcy5fcmVzID0gYTsgdGhpcy5fcmVqID0gcjsgfSk7CgogICAgdmFyIGNvbW1hbmQgPSAnRW5hYmxlLU5ldEZpcmV3YWxsUnVsZSc7CiAgICBpZiAob3B0aW9ucy5wcm9ncmFtKQ0KICAgIHsNCiAgICAgICAgY29tbWFuZCA9ICdHZXQtTmV0RmlyZXdhbGxBcHBsaWNhdGlvbkZpbHRlciAtUHJvZ3JhbSBcXCInICsgb3B0aW9ucy5wcm9ncmFtICsgJ1xcIiB8ICcgKyBjb21tYW5kOw0KICAgIH0KICAgIGVsc2UNCiAgICB7DQogICAgICAgIHZhciBrZXksIHZhbHVlOw0KICAgICAgICBmb3IgKGtleSBpbiBvcHRpb25zKQ0KICAgICAgICB7DQogICAgICAgICAgICB2YWx1ZSA9IG9wdGlvbnNba2V5XTsNCiAgICAgICAgICAgIGlmICh2YWx1ZS5pbmRleE9mKCcgJykgPj0gMCkgeyB2YWx1ZSA9ICdcXCInICsgb3B0aW9uc1trZXldICsgJ1xcIic7IH0NCiAgICAgICAgICAgIGNvbW1hbmQgKz0gKCctJyArIGtleSArICcgJyArIHZhbHVlKTsNCiAgICAgICAgfQ0KICAgIH0KCiAgICBpZiAocmVxdWlyZSgnb3MnKS5hcmNoKCkgPT0gJ3g2NCcpCiAgICB7CiAgICAgICAgcmV0LmNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKHByb2Nlc3MuZW52Wyd3aW5kaXInXSArICdcXFN5c3RlbTMyXFxXaW5kb3dzUG93ZXJTaGVsbFxcdjEuMFxccG93ZXJzaGVsbC5leGUnLCBbJy9DICInICsgY29tbWFuZCArICciJ10pOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldC5jaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZShwcm9jZXNzLmVudlsnd2luZGlyJ10gKyAnXFxTeXN0ZW0zMlxcV2luZG93c1Bvd2VyU2hlbGxcXHYxLjBcXHBvd2Vyc2hlbGwuZXhlJywgWycvQyAiJyArIGNvbW1hbmQgKyAnIiddKTsKICAgIH0KCiAgICByZXQuY2hpbGQucmV0ID0gcmV0OwogICAgcmV0LmNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgcmV0LmNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7CiAgICByZXQuY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyByZXQuY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsKICAgIHJldC5jaGlsZC5vbignZXhpdCcsIGZ1bmN0aW9uICgpCiAgICB7DQogICAgICAgIGlmKHRoaXMuc3RkZXJyLnN0ciAhPSAnJykNCiAgICAgICAgew0KICAgICAgICAgICAgdGhpcy5yZXQuX3Jlaih0aGlzLnN0ZGVyci5zdHIudHJpbSgpKTsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlDQogICAgICAgIHsNCiAgICAgICAgICAgIHRoaXMucmV0Ll9yZXMoKTsNCiAgICAgICAgfQ0KICAgIH0pOwoKICAgIHJldHVybiAocmV0KTsKfQoKCmZ1bmN0aW9uIHZlcmlmeVZhbHVlcyhvcHRpb25zSW5wdXQsIGtleU5hbWUsIGtleVZhbHVlcywgZGVmYXVsdFZhbHVlKQp7CiAgICB2YXIgaSwgaiwgdG1wLCBvazsKICAgIGZvciAodmFyIGtleSBpbiBvcHRpb25zSW5wdXQpCiAgICB7CiAgICAgICAgaWYoa2V5TmFtZS50b0xvd2VyQ2FzZSgpID09IGtleS50b0xvd2VyQ2FzZSgpKQogICAgICAgIHsKICAgICAgICAgICAgdG1wID0gb3B0aW9uc0lucHV0W2tleV07CiAgICAgICAgICAgIGRlbGV0ZSBvcHRpb25zSW5wdXRba2V5XTsKCiAgICAgICAgICAgIGlmIChrZXlWYWx1ZXMgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgb3B0aW9uc0lucHV0W2tleU5hbWVdID0gdG1wOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRtcCE9bnVsbCkgeyB0bXAgPSB0bXAudG9TdHJpbmcoKS5zcGxpdCgnLCcpOyB9CiAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgdG1wLmxlbmd0aDsgKytqKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG9rID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpPTA7aTxrZXlWYWx1ZXMubGVuZ3RoOysraSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlWYWx1ZXNbaV0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpID09IHRtcFtqXS50b1N0cmluZygpLnRyaW0oKS50b0xvd2VyQ2FzZSgpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zSW5wdXRba2V5TmFtZV0gPSAob3B0aW9uc0lucHV0W2tleU5hbWVdID09IG51bGwgPyBrZXlWYWx1ZXNbaV0gOiAob3B0aW9uc0lucHV0W2tleU5hbWVdICsgJywgJyArIGtleVZhbHVlc1tpXSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2sgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCFvaykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICgnSW52YWxpZCB2YWx1ZSBmb3IgWycgKyBrZXlOYW1lICsgJ106ICcgKyB0bXBbal0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChvcHRpb25zSW5wdXRba2V5TmFtZV0gIT0gbnVsbCkgeyByZXR1cm47IH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyBJZiB3ZSBnb3QgaGVyZSwgdGhlbiB0aGUga2V5IGRvZXNuJ3QgZXhpc3QuLi4gQ2hlY2sgdG8gc2VlIGlmIHdlIG5lZWQgdG8gcHV0IGluIGEgZGVmYXVsdCB2YWx1ZQogICAgaWYoZGVmYXVsdFZhbHVlICE9IG51bGwpCiAgICB7CiAgICAgICAgb3B0aW9uc0lucHV0W2tleU5hbWVdID0gZGVmYXVsdFZhbHVlOwogICAgfQp9CgpmdW5jdGlvbiBjb252ZXJ0T3B0aW9ucyhvcHRpb25zKQp7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ0FjdGlvbicsIFsnTm90Q29uZmlndXJlZCcsICdBbGxvdycsICdCbG9jayddKTsKICAgIHZlcmlmeVZhbHVlcyhvcHRpb25zLCAnQXV0aGVudGljYXRpb24nLCBbJ05vdFJlcXVpcmVkJywgJ1JlcXVpcmVkJywgJ05vRW5jYXAnXSk7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ0Rlc2NyaXB0aW9uJyk7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ0RpcmVjdGlvbicsIFsnSW5ib3VuZCcsICdPdXRib3VuZCddKTsKICAgIHZlcmlmeVZhbHVlcyhvcHRpb25zLCAnRGlzcGxheU5hbWUnKTsKICAgIHZlcmlmeVZhbHVlcyhvcHRpb25zLCAnRHluYW1pY1RhcmdldCcsIFsnQW55JywgJ1Byb3hpbWl0eUFwcHMnLCAnUHJveGltaXR5U2hhcmluZycsICdXaWZpRGlyZWN0UHJpbnRpbmcnLCAnV2lmaURpcmVjdERpc3BsYXknLCAnV2lmaURpcmVjdERldmljZXMnXSwgJ0FueScpOwogICAgdmVyaWZ5VmFsdWVzKG9wdGlvbnMsICdFZGdlVHJhdmVyc2FsUG9saWN5JywgWydCbG9jaycsICdBbGxvdycsICdEZWZlclRvVXNlcicsICdEZWZlclRvQXBwJ10pOwogICAgdmVyaWZ5VmFsdWVzKG9wdGlvbnMsICdFbmFibGVkJywgWydUcnVlJywgJ0ZhbHNlJ10sICdUcnVlJyk7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ0VuY3J5cHRpb24nLCBbJ05vdFJlcXVpcmVkJywgJ1JlcXVpcmVkJywgJ0R5bmFtaWMnXSk7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ0ludGVyZmFjZVR5cGUnLCBbJ0FueScsICdXaXJlZCcsICdXaXJlbGVzcycsICdSZW1vdGVBY2Nlc3NdJ10sICdBbnknKTsKICAgIHZlcmlmeVZhbHVlcyhvcHRpb25zLCAnTG9jYWxBZGRyZXNzJyk7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ0xvY2FsT25seU1hcHBpbmcnLCBbJ1RydWUnLCAnRmFsc2UnXSk7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ0xvY2FsUG9ydCcpOwogICAgdmVyaWZ5VmFsdWVzKG9wdGlvbnMsICdMb2NhbFVzZXInKTsKICAgIHZlcmlmeVZhbHVlcyhvcHRpb25zLCAnTG9vc2VTb3VyY2VNYXBwaW5nJywgWydUcnVlJywgJ0ZhbHNlJ10pOwogICAgdmVyaWZ5VmFsdWVzKG9wdGlvbnMsICdOYW1lJyk7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ092ZXJyaWRlQmxvY2tSdWxlcycsIFsnVHJ1ZScsICdGYWxzZSddKTsKICAgIHZlcmlmeVZhbHVlcyhvcHRpb25zLCAnT3duZXInKTsKICAgIHZlcmlmeVZhbHVlcyhvcHRpb25zLCAnUGFja2FnZScpOwogICAgdmVyaWZ5VmFsdWVzKG9wdGlvbnMsICdQbGF0Zm9ybScpOwogICAgdmVyaWZ5VmFsdWVzKG9wdGlvbnMsICdQb2xpY3lTdG9yZScpOwogICAgdmVyaWZ5VmFsdWVzKG9wdGlvbnMsICdQcm9maWxlJywgWydBbnknLCAnRG9tYWluJywgJ1ByaXZhdGUnLCAnUHVibGljJywgJ05vdEFwcGxpY2FibGUnXSwgJ0FueScpOwogICAgdmVyaWZ5VmFsdWVzKG9wdGlvbnMsICdQcm9ncmFtJyk7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ1Byb3RvY29sJyk7CiAgICB2ZXJpZnlWYWx1ZXMob3B0aW9ucywgJ1JlbW90ZUFkZHJlc3MnKTsKICAgIHZlcmlmeVZhbHVlcyhvcHRpb25zLCAnUmVtb3RlTWFjaGluZScpOwogICAgdmVyaWZ5VmFsdWVzKG9wdGlvbnMsICdSZW1vdGVQb3J0Jyk7CiAgICAKICAgIHJldHVybiAob3B0aW9ucyk7Cn0KCmZ1bmN0aW9uIHJlbW92ZUZpcmV3YWxsUnVsZShvcHRpb25zKQ0Kew0KICAgIGlmICh0eXBlb2YgKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7IG9wdGlvbnMgPSB7IE5hbWU6IG9wdGlvbnMgfTsgfQ0KICAgIHZhciByZXQgPSBuZXcgcHJvbWlzZShmdW5jdGlvbiAoYSwgcikgeyB0aGlzLl9yZXMgPSBhOyB0aGlzLl9yZWogPSByOyB9KTsKDQogICAgdmFyIGNvbW1hbmQgPSAnUmVtb3ZlLU5ldEZpcmV3YWxsUnVsZSc7CiAgICBpZiAob3B0aW9ucy5wcm9ncmFtKQogICAgew0KICAgICAgICBjb21tYW5kID0gJ0dldC1OZXRGaXJld2FsbEFwcGxpY2F0aW9uRmlsdGVyIC1Qcm9ncmFtIFxcIicgKyBvcHRpb25zLnByb2dyYW0gKyAnXFwiIHwgJyArIGNvbW1hbmQ7DQogICAgfQogICAgZWxzZQogICAgew0KICAgICAgICB2YXIga2V5LCB2YWx1ZTsNCiAgICAgICAgZm9yKGtleSBpbiBvcHRpb25zKQ0KICAgICAgICB7DQogICAgICAgICAgICB2YWx1ZSA9IG9wdGlvbnNba2V5XTsNCiAgICAgICAgICAgIGlmICh2YWx1ZS5pbmRleE9mKCcgJykgPj0gMCkgeyB2YWx1ZSA9ICdcXCInICsgb3B0aW9uc1trZXldICsgJ1xcIic7IH0NCiAgICAgICAgICAgIGNvbW1hbmQgKz0gKCctJyArIGtleSArICcgJyArIHZhbHVlKTsNCiAgICAgICAgfQ0KICAgIH0KCiAgICBpZiAocmVxdWlyZSgnb3MnKS5hcmNoKCkgPT0gJ3g2NCcpDQogICAgew0KICAgICAgICByZXQuY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUocHJvY2Vzcy5lbnZbJ3dpbmRpciddICsgJ1xcU3lzdGVtMzJcXFdpbmRvd3NQb3dlclNoZWxsXFx2MS4wXFxwb3dlcnNoZWxsLmV4ZScsIFsnL0MgIicgKyBjb21tYW5kICsgJyInXSk7DQogICAgfQogICAgZWxzZQ0KICAgIHsNCiAgICAgICAgcmV0LmNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKHByb2Nlc3MuZW52Wyd3aW5kaXInXSArICdcXFN5c3RlbTMyXFxXaW5kb3dzUG93ZXJTaGVsbFxcdjEuMFxccG93ZXJzaGVsbC5leGUnLCBbJy9DICInICsgY29tbWFuZCArICciJ10pOw0KICAgIH0KCiAgICByZXQuY2hpbGQucmV0ID0gcmV0OwogICAgcmV0LmNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgcmV0LmNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7CiAgICByZXQuY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyByZXQuY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygp", 16000); + memcpy_s(_winfirewall + 16000, 2164, "OyB9KTsKICAgIHJldC5jaGlsZC5vbignZXhpdCcsIGZ1bmN0aW9uICgpCiAgICB7DQogICAgICAgIGlmKHRoaXMuc3RkZXJyLnN0ciAhPSAnJykNCiAgICAgICAgew0KICAgICAgICAgICAgdGhpcy5yZXQuX3Jlaih0aGlzLnN0ZGVyci5zdHIudHJpbSgpKTsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlDQogICAgICAgIHsNCiAgICAgICAgICAgIHRoaXMucmV0Ll9yZXMoKTsNCiAgICAgICAgfQ0KICAgIH0pOwogICAgcmV0dXJuIChyZXQpOw0KfQoKZnVuY3Rpb24gYWRkRmlyZXdhbGxSdWxlKG9wdGlvbnMpCnsKICAgIHZhciBjb21tYW5kID0gJ05ldy1OZXRGaXJld2FsbFJ1bGUnOwogICAgdmFyIHZhbCA9IGNvbnZlcnRPcHRpb25zKG9wdGlvbnMpOwogICAgdmFyIGtleTsKCiAgICBmb3IgKGtleSBpbiB2YWwpCiAgICB7CiAgICAgICAgaWYgKHZhbFtrZXldLnRvU3RyaW5nKCkuaW5kZXhPZignICcpID49IDApCiAgICAgICAgewogICAgICAgICAgICBjb21tYW5kICs9ICgnIC0nICsga2V5ICsgJyBcXCInICsgdmFsW2tleV0gKyAnXFwiJyk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGNvbW1hbmQgKz0gKCcgLScgKyBrZXkgKyAnICcgKyB2YWxba2V5XSArICcnKTsKICAgICAgICB9CiAgICB9CgogICAgdmFyIGNoaWxkOwogICAgaWYgKHJlcXVpcmUoJ29zJykuYXJjaCgpID09ICd4NjQnKQogICAgewogICAgICAgIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKHByb2Nlc3MuZW52Wyd3aW5kaXInXSArICdcXFN5c3RlbTMyXFxXaW5kb3dzUG93ZXJTaGVsbFxcdjEuMFxccG93ZXJzaGVsbC5leGUnLCBbJy9DICInICsgY29tbWFuZCArICciJ10pOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKHByb2Nlc3MuZW52Wyd3aW5kaXInXSArICdcXFN5c3RlbTMyXFxXaW5kb3dzUG93ZXJTaGVsbFxcdjEuMFxccG93ZXJzaGVsbC5leGUnLCBbJy9DICInICsgY29tbWFuZCArICciJ10pOwogICAgfQoKICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsKICAgIGNoaWxkLnN0ZGVyci5zdHIgPSAnJzsgY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsKICAgIGNoaWxkLndhaXRFeGl0KCk7CgogICAgaWYoY2hpbGQuc3RkZXJyLnN0ci50cmltKCkgIT0gJycpCiAgICB7CiAgICAgICAgdGhyb3cgKGNoaWxkLnN0ZGVyci5zdHIudHJpbSgpKTsKICAgIH0KfQoKCm1vZHVsZS5leHBvcnRzID0KICAgIHsKICAgICAgICBnZXRGaXJld2FsbFJ1bGVzOiBnZXRGaXJld2FsbFJ1bGVzLAogICAgICAgIGRpc2FibGVGaXJld2FsbFJ1bGVzOiBkaXNhYmxlRmlyZXdhbGxSdWxlcywKICAgICAgICBlbmFibGVGaXJld2FsbFJ1bGVzOiBlbmFibGVGaXJld2FsbFJ1bGVzLAogICAgICAgIGFkZEZpcmV3YWxsUnVsZTogYWRkRmlyZXdhbGxSdWxlLAogICAgICAgIHJlbW92ZUZpcmV3YWxsUnVsZTogcmVtb3ZlRmlyZXdhbGxSdWxlCiAgICB9Owo=", 2164); + ILibBase64DecodeEx((unsigned char*)_winfirewall, 18164, (unsigned char*)_winfirewall + 18164); + duk_push_global_object(ctx); duk_get_prop_string(ctx, -1, "addModule"); duk_swap_top(ctx, -2); duk_push_string(ctx, "win-firewall"); duk_push_string(ctx, _winfirewall + 18164); + duk_pcall_method(ctx, 2); duk_pop(ctx); + free(_winfirewall); #endif #ifdef _FREEBSD diff --git a/modules/win-firewall.js b/modules/win-firewall.js index 436ecb8..6cd2f35 100644 --- a/modules/win-firewall.js +++ b/modules/win-firewall.js @@ -141,80 +141,94 @@ function getFirewallRules(options) function disableFirewallRules(options) { var ret = new promise(function (a, r) { this._res = a; this._rej = r; }); - var p = getFirewallRules(options).on('firewallRule', function (r) { if (this._count == null) { this._count = 0; } ++this._count; }); - p.options = options; - p.ret = ret; - p.then(function (a) + var command = 'Disable-NetFirewallRule'; + + if (options.program) { - if(this._count > 0) + command = 'Get-NetFirewallApplicationFilter -Program \\"' + options.program + '\\" | ' + command; + } + else + { + var key, value; + for (key in options) { - var command = 'Disable-NetFirewallRule'; - if (this.options.program) { command = 'Get-NetFirewallApplicationFilter -Program \\"' + this.options.program + '\\" | ' + command; } - - var child; - if (require('os').arch() == 'x64') - { - child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); - } - else - { - child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); - } - - child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); - child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); }); - child.waitExit(); - - if (child.stderr.str.trim() != "") - { - this.ret._rej(child.stderr.str.trim()); - } - else - { - this.ret._res(); - } + value = options[key]; + if (value.indexOf(' ') >= 0) { value = '\\"' + options[key] + '\\"'; } + command += ('-' + key + ' ' + value); } - }, function (e) { this.ret._rej(e); }); + } + + if (require('os').arch() == 'x64') + { + ret.child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); + } + else + { + ret.child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); + } + + ret.child.ret = ret; + ret.child.stdout.str = ''; ret.child.stdout.on('data', function (c) { this.str += c.toString(); }); + ret.child.stderr.str = ''; ret.child.stderr.on('data', function (c) { this.str += c.toString(); }); + ret.child.on('exit', function () + { + if (this.stderr.str != '') + { + this.ret._rej(this.stderr.str.trim()); + } + else + { + this.ret._res(); + } + }); + return (ret); } function enableFirewallRules(options) { var ret = new promise(function (a, r) { this._res = a; this._rej = r; }); - var p = getFirewallRules(options).on('firewallRule', function (r) { if (this._count == null) { this._count = 0; } ++this._count; }); - p.options = options; - p.ret = ret; - p.then(function (a) + + var command = 'Enable-NetFirewallRule'; + if (options.program) { - if (this._count > 0) + command = 'Get-NetFirewallApplicationFilter -Program \\"' + options.program + '\\" | ' + command; + } + else + { + var key, value; + for (key in options) { - var command = 'Enable-NetFirewallRule'; - if (this.options.program) { command = 'Get-NetFirewallApplicationFilter -Program \\"' + this.options.program + '\\" | ' + command; } - - var child; - if (require('os').arch() == 'x64') - { - child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); - } - else - { - child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); - } - - child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); - child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); }); - child.waitExit(); - - if (child.stderr.str.trim() != "") - { - this.ret._rej(child.stderr.str.trim()); - } - else - { - this.ret._res(); - } + value = options[key]; + if (value.indexOf(' ') >= 0) { value = '\\"' + options[key] + '\\"'; } + command += ('-' + key + ' ' + value); } - }, function (e) { this.ret._rej(e); }); + } + + if (require('os').arch() == 'x64') + { + ret.child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); + } + else + { + ret.child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); + } + + ret.child.ret = ret; + ret.child.stdout.str = ''; ret.child.stdout.on('data', function (c) { this.str += c.toString(); }); + ret.child.stderr.str = ''; ret.child.stderr.on('data', function (c) { this.str += c.toString(); }); + ret.child.on('exit', function () + { + if(this.stderr.str != '') + { + this.ret._rej(this.stderr.str.trim()); + } + else + { + this.ret._res(); + } + }); + return (ret); } @@ -299,12 +313,58 @@ function convertOptions(options) return (options); } +function removeFirewallRule(options) +{ + if (typeof (options) == 'string') { options = { Name: options }; } + var ret = new promise(function (a, r) { this._res = a; this._rej = r; }); + + var command = 'Remove-NetFirewallRule'; + if (options.program) + { + command = 'Get-NetFirewallApplicationFilter -Program \\"' + options.program + '\\" | ' + command; + } + else + { + var key, value; + for(key in options) + { + value = options[key]; + if (value.indexOf(' ') >= 0) { value = '\\"' + options[key] + '\\"'; } + command += ('-' + key + ' ' + value); + } + } + + if (require('os').arch() == 'x64') + { + ret.child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); + } + else + { + ret.child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); + } + + ret.child.ret = ret; + ret.child.stdout.str = ''; ret.child.stdout.on('data', function (c) { this.str += c.toString(); }); + ret.child.stderr.str = ''; ret.child.stderr.on('data', function (c) { this.str += c.toString(); }); + ret.child.on('exit', function () + { + if(this.stderr.str != '') + { + this.ret._rej(this.stderr.str.trim()); + } + else + { + this.ret._res(); + } + }); + return (ret); +} + function addFirewallRule(options) { var command = 'New-NetFirewallRule'; var val = convertOptions(options); var key; - console.log(JSON.stringify(val, null, 1)); for (key in val) { @@ -318,9 +378,7 @@ function addFirewallRule(options) } } - console.log(command); var child; - if (require('os').arch() == 'x64') { child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['/C "' + command + '"']); @@ -346,5 +404,6 @@ module.exports = getFirewallRules: getFirewallRules, disableFirewallRules: disableFirewallRules, enableFirewallRules: enableFirewallRules, - addFirewallRule: addFirewallRule + addFirewallRule: addFirewallRule, + removeFirewallRule: removeFirewallRule };