diff options
Diffstat (limited to 'platform/windows/export')
-rw-r--r-- | platform/windows/export/export.cpp | 185 |
1 files changed, 183 insertions, 2 deletions
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 827daa2d58..3abb05b494 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -31,6 +31,7 @@ #include "core/os/file_access.h" #include "core/os/os.h" #include "editor/editor_export.h" +#include "editor/editor_node.h" #include "editor/editor_settings.h" #include "platform/windows/logo.gen.h" @@ -38,11 +39,22 @@ static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, class EditorExportPlatformWindows : public EditorExportPlatformPC { + Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path); + public: virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); + virtual Error sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); virtual void get_export_options(List<ExportOption> *r_options); }; +Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) { + if (p_preset->get("codesign/enable")) { + return _code_sign(p_preset, p_path); + } else { + return OK; + } +} + Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, p_path, p_flags); @@ -133,12 +145,28 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> OS::get_singleton()->execute(wine_path, args, true); #endif - return OK; + if (p_preset->get("codesign/enable") && err == OK) { + err = _code_sign(p_preset, p_path); + } + + return err; } void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) { EditorExportPlatformPC::get_export_options(r_options); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false)); +#ifdef WINDOWS_ENABLED + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA1 hash)"), 0)); +#endif + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray())); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), "")); @@ -149,11 +177,164 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), "")); } +Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path) { + List<String> args; + +#ifdef WINDOWS_ENABLED + String signtool_path = EditorSettings::get_singleton()->get("export/windows/signtool"); + if (signtool_path != String() && !FileAccess::exists(signtool_path)) { + ERR_PRINTS("Could not find signtool executable at " + signtool_path + ", aborting."); + return ERR_FILE_NOT_FOUND; + } + if (signtool_path == String()) { + signtool_path = "signtool"; // try to run signtool from PATH + } +#else + String signtool_path = EditorSettings::get_singleton()->get("export/windows/osslsigncode"); + if (signtool_path != String() && !FileAccess::exists(signtool_path)) { + ERR_PRINTS("Could not find osslsigncode executable at " + signtool_path + ", aborting."); + return ERR_FILE_NOT_FOUND; + } + if (signtool_path == String()) { + signtool_path = "osslsigncode"; // try to run signtool from PATH + } +#endif + + args.push_back("sign"); + + //identity +#ifdef WINDOWS_ENABLED + int id_type = p_preset->get("codesign/identity_type"); + if (id_type == 0) { //auto select + args.push_back("/a"); + } else if (id_type == 1) { //pkcs12 + if (p_preset->get("codesign/identity") != "") { + args.push_back("/f"); + args.push_back(p_preset->get("codesign/identity")); + } else { + EditorNode::add_io_error("codesign: no identity found"); + return FAILED; + } + } else if (id_type == 2) { //Windows certificate store + if (p_preset->get("codesign/identity") != "") { + args.push_back("/sha1"); + args.push_back(p_preset->get("codesign/identity")); + } else { + EditorNode::add_io_error("codesign: no identity found"); + return FAILED; + } + } else { + EditorNode::add_io_error("codesign: invalid identity type"); + return FAILED; + } +#else + if (p_preset->get("codesign/identity") != "") { + args.push_back("-pkcs12"); + args.push_back(p_preset->get("codesign/identity")); + } else { + EditorNode::add_io_error("codesign: no identity found"); + return FAILED; + } +#endif + + //password + if (p_preset->get("codesign/password") != "") { +#ifdef WINDOWS_ENABLED + args.push_back("/p"); +#else + args.push_back("-pass"); +#endif + args.push_back(p_preset->get("codesign/password")); + } + + //timestamp + if (p_preset->get("codesign/timestamp")) { + if (p_preset->get("codesign/timestamp_server") != "") { +#ifdef WINDOWS_ENABLED + args.push_back("/tr"); + args.push_back(p_preset->get("codesign/timestamp_server_url")); + args.push_back("/td"); + if ((int)p_preset->get("codesign/digest_algorithm") == 0) { + args.push_back("sha1"); + } else { + args.push_back("sha256"); + } +#else + args.push_back("-ts"); + args.push_back(p_preset->get("codesign/timestamp_server_url")); +#endif + } else { + EditorNode::add_io_error("codesign: invalid timestamp server"); + return FAILED; + } + } + + //digest +#ifdef WINDOWS_ENABLED + args.push_back("/fd"); +#else + args.push_back("-h"); +#endif + if ((int)p_preset->get("codesign/digest_algorithm") == 0) { + args.push_back("sha1"); + } else { + args.push_back("sha256"); + } + + //description + if (p_preset->get("codesign/description") != "") { +#ifdef WINDOWS_ENABLED + args.push_back("/d"); +#else + args.push_back("-n"); +#endif + args.push_back(p_preset->get("codesign/description")); + } + + //user options + PoolStringArray user_args = p_preset->get("codesign/custom_options"); + for (int i = 0; i < user_args.size(); i++) { + String user_arg = user_args[i].strip_edges(); + if (!user_arg.empty()) { + args.push_back(user_arg); + } + } + +#ifndef WINDOWS_ENABLED + args.push_back("-in"); +#endif + args.push_back(p_path); +#ifndef WINDOWS_ENABLED + args.push_back("-out"); + args.push_back(p_path); +#endif + + String str; + Error err = OS::get_singleton()->execute(signtool_path, args, true, NULL, &str, NULL, true); + ERR_FAIL_COND_V(err != OK, err); + + print_line("codesign (" + p_path + "): " + str); +#ifndef WINDOWS_ENABLED + if (str.find("SignTool Error") != -1) { +#else + if (str.find("Failed") != -1) { +#endif + return FAILED; + } + + return OK; +} + void register_windows_exporter() { EDITOR_DEF("export/windows/rcedit", ""); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/rcedit", PROPERTY_HINT_GLOBAL_FILE, "*.exe")); -#ifndef WINDOWS_ENABLED +#ifdef WINDOWS_ENABLED + EDITOR_DEF("export/windows/signtool", ""); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/signtool", PROPERTY_HINT_GLOBAL_FILE, "*.exe")); +#else + EDITOR_DEF("export/windows/osslsigncode", ""); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/osslsigncode", PROPERTY_HINT_GLOBAL_FILE)); // On non-Windows we need WINE to run rcedit EDITOR_DEF("export/windows/wine", ""); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/wine", PROPERTY_HINT_GLOBAL_FILE)); |