Forráskód Böngészése

Merge pull request #22066 from Faless/bundle_certs

Bundle SSL certs with the templates
Rémi Verschelde 7 éve
szülő
commit
7f5e653a22

+ 2 - 0
SConstruct

@@ -169,9 +169,11 @@ opts.Add(BoolVariable('progress', "Show a progress indicator during compilation"
 opts.Add(BoolVariable('dev', "If yes, alias for verbose=yes warnings=all", False))
 opts.Add(EnumVariable('macports_clang', "Build using Clang from MacPorts", 'no', ('no', '5.0', 'devel')))
 opts.Add(BoolVariable('no_editor_splash', "Don't use the custom splash screen for the editor", False))
+opts.Add('system_certs_path', "Use this path as SSL certificates default for editor (for package maintainers)", '')
 
 # Thirdparty libraries
 opts.Add(BoolVariable('builtin_bullet', "Use the built-in Bullet library", True))
+opts.Add(BoolVariable('builtin_certs', "Bundle default SSL certificates to be used if you don't specify an override in the project settings", True))
 opts.Add(BoolVariable('builtin_enet', "Use the built-in ENet library", True))
 opts.Add(BoolVariable('builtin_freetype', "Use the built-in FreeType library", True))
 opts.Add(BoolVariable('builtin_libogg', "Use the built-in libogg library", True))

+ 3 - 0
core/SCsub

@@ -93,6 +93,9 @@ if 'builtin_zstd' in env and env['builtin_zstd']:
 # Godot's own sources
 env.add_source_files(env.core_sources, "*.cpp")
 
+# Certificates
+env.Depends("#core/io/certs_compressed.gen.h", ["#thirdparty/certs/ca-certificates.crt", env.Value(env['builtin_certs']), env.Value(env['system_certs_path'])])
+env.CommandNoCache("#core/io/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(core_builders.make_certs_header))
 
 # Make binders
 env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run))

+ 34 - 1
core/core_builders.py

@@ -4,7 +4,40 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki
 
 """
 from platform_methods import subprocess_main
-from compat import iteritems, itervalues, open_utf8, escape_string
+from compat import iteritems, itervalues, open_utf8, escape_string, byte_to_str
+
+
+def make_certs_header(target, source, env):
+
+    src = source[0]
+    dst = target[0]
+    f = open(src, "rb")
+    g = open_utf8(dst, "w")
+    buf = f.read()
+    decomp_size = len(buf)
+    import zlib
+    buf = zlib.compress(buf)
+
+    g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+    g.write("#ifndef _CERTS_RAW_H\n")
+    g.write("#define _CERTS_RAW_H\n")
+
+    # System certs path. Editor will use them if defined. (for package maintainers)
+    path = env['system_certs_path']
+    g.write("#define _SYSTEM_CERTS_PATH \"%s\"\n" % str(path))
+    if env['builtin_certs']:
+        # Defined here and not in env so changing it does not trigger a full rebuild.
+        g.write("#define BUILTIN_CERTS_ENABLED\n")
+        g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
+        g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
+        g.write("static const unsigned char _certs_compressed[] = {\n")
+        for i in range(len(buf)):
+            g.write("\t" + byte_to_str(buf[i]) + ",\n")
+        g.write("};\n")
+    g.write("#endif")
+
+    g.close()
+    f.close()
 
 
 def make_authors_header(target, source, env):

+ 41 - 16
core/io/stream_peer_ssl.cpp

@@ -30,6 +30,8 @@
 
 #include "stream_peer_ssl.h"
 
+#include "core/io/certs_compressed.gen.h"
+#include "core/io/compression.h"
 #include "core/os/file_access.h"
 #include "core/project_settings.h"
 
@@ -42,13 +44,20 @@ StreamPeerSSL *StreamPeerSSL::create() {
 
 StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL;
 bool StreamPeerSSL::available = false;
-bool StreamPeerSSL::initialize_certs = true;
 
 void StreamPeerSSL::load_certs_from_memory(const PoolByteArray &p_memory) {
 	if (load_certs_func)
 		load_certs_func(p_memory);
 }
 
+void StreamPeerSSL::load_certs_from_file(String p_path) {
+	if (p_path != "") {
+		PoolByteArray certs = get_cert_file_as_array(p_path);
+		if (certs.size() > 0)
+			load_certs_func(certs);
+	}
+}
+
 bool StreamPeerSSL::is_available() {
 	return available;
 }
@@ -61,6 +70,25 @@ bool StreamPeerSSL::is_blocking_handshake_enabled() const {
 	return blocking_handshake;
 }
 
+PoolByteArray StreamPeerSSL::get_cert_file_as_array(String p_path) {
+
+	PoolByteArray out;
+	FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
+	if (f) {
+		int flen = f->get_len();
+		out.resize(flen + 1);
+		PoolByteArray::Write w = out.write();
+		f->get_buffer(w.ptr(), flen);
+		w[flen] = 0; // Make sure it ends with string terminator
+		memdelete(f);
+#ifdef DEBUG_ENABLED
+		print_verbose(vformat("Loaded certs from '%s'.", p_path));
+#endif
+	}
+
+	return out;
+}
+
 PoolByteArray StreamPeerSSL::get_project_cert_array() {
 
 	PoolByteArray out;
@@ -68,24 +96,21 @@ PoolByteArray StreamPeerSSL::get_project_cert_array() {
 	ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
 
 	if (certs_path != "") {
-
-		FileAccess *f = FileAccess::open(certs_path, FileAccess::READ);
-		if (f) {
-			int flen = f->get_len();
-			out.resize(flen + 1);
-			{
-				PoolByteArray::Write w = out.write();
-				f->get_buffer(w.ptr(), flen);
-				w[flen] = 0; //end f string
-			}
-
-			memdelete(f);
-
+		// Use certs defined in project settings.
+		return get_cert_file_as_array(certs_path);
+	}
+#ifdef BUILTIN_CERTS_ENABLED
+	else {
+		// Use builtin certs only if user did not override it in project settings.
+		out.resize(_certs_uncompressed_size + 1);
+		PoolByteArray::Write w = out.write();
+		Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
+		w[_certs_uncompressed_size] = 0; // Make sure it ends with string terminator
 #ifdef DEBUG_ENABLED
-			print_verbose(vformat("Loaded certs from '%s'.", certs_path));
+		print_verbose("Loaded builtin certs");
 #endif
-		}
 	}
+#endif
 
 	return out;
 }

+ 2 - 3
core/io/stream_peer_ssl.h

@@ -46,9 +46,6 @@ protected:
 	static LoadCertsFromMemory load_certs_func;
 	static bool available;
 
-	friend class Main;
-	static bool initialize_certs;
-
 	bool blocking_handshake;
 
 public:
@@ -72,7 +69,9 @@ public:
 
 	static StreamPeerSSL *create();
 
+	static PoolByteArray get_cert_file_as_array(String p_path);
 	static PoolByteArray get_project_cert_array();
+	static void load_certs_from_file(String p_path);
 	static void load_certs_from_memory(const PoolByteArray &p_memory);
 	static bool is_available();
 

+ 0 - 4
editor/SCsub

@@ -61,10 +61,6 @@ if env['tools']:
     env.Depends("#editor/doc_data_compressed.gen.h", docs)
     env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, run_in_subprocess(editor_builders.make_doc_header))
 
-    # Certificates
-    env.Depends("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt")
-    env.CommandNoCache("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(editor_builders.make_certs_header))
-
     import glob
 
     path = env.Dir('.').abspath

+ 0 - 26
editor/editor_builders.py

@@ -9,32 +9,6 @@ from platform_methods import subprocess_main
 from compat import encode_utf8, byte_to_str, open_utf8, escape_string
 
 
-def make_certs_header(target, source, env):
-
-    src = source[0]
-    dst = target[0]
-    f = open(src, "rb")
-    g = open_utf8(dst, "w")
-    buf = f.read()
-    decomp_size = len(buf)
-    import zlib
-    buf = zlib.compress(buf)
-
-    g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
-    g.write("#ifndef _CERTS_RAW_H\n")
-    g.write("#define _CERTS_RAW_H\n")
-    g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
-    g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
-    g.write("static const unsigned char _certs_compressed[] = {\n")
-    for i in range(len(buf)):
-        g.write("\t" + byte_to_str(buf[i]) + ",\n")
-    g.write("};\n")
-    g.write("#endif")
-
-    g.close()
-    f.close()
-
-
 def make_doc_header(target, source, env):
 
     dst = target[0]

+ 0 - 48
editor/editor_initialize_ssl.cpp

@@ -1,48 +0,0 @@
-/*************************************************************************/
-/*  editor_initialize_ssl.cpp                                            */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "editor_initialize_ssl.h"
-
-#include "certs_compressed.gen.h"
-#include "core/io/compression.h"
-#include "core/io/stream_peer_ssl.h"
-
-void editor_initialize_certificates() {
-
-	PoolByteArray data;
-	data.resize(_certs_uncompressed_size + 1);
-	{
-		PoolByteArray::Write w = data.write();
-		Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
-		w[_certs_uncompressed_size] = 0; //make sure it ends at zero
-	}
-
-	StreamPeerSSL::load_certs_from_memory(data);
-}

+ 0 - 36
editor/editor_initialize_ssl.h

@@ -1,36 +0,0 @@
-/*************************************************************************/
-/*  editor_initialize_ssl.h                                              */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef EDITOR_INITIALIZE_SSL_H
-#define EDITOR_INITIALIZE_SSL_H
-
-void editor_initialize_certificates();
-
-#endif // EDITOR_INITIALIZE_SSL_H

+ 0 - 2
editor/editor_node.cpp

@@ -54,7 +54,6 @@
 #include "editor/editor_audio_buses.h"
 #include "editor/editor_file_system.h"
 #include "editor/editor_help.h"
-#include "editor/editor_initialize_ssl.h"
 #include "editor/editor_properties.h"
 #include "editor/editor_settings.h"
 #include "editor/editor_themes.h"
@@ -4686,7 +4685,6 @@ EditorNode::EditorNode() {
 	SceneState::set_disable_placeholders(true);
 	ResourceLoader::clear_translation_remaps(); //no remaps using during editor
 	ResourceLoader::clear_path_remaps();
-	editor_initialize_certificates(); //for asset sharing
 
 	InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
 

+ 5 - 0
editor/editor_settings.cpp

@@ -30,6 +30,7 @@
 
 #include "editor_settings.h"
 
+#include "core/io/certs_compressed.gen.h"
 #include "core/io/compression.h"
 #include "core/io/config_file.h"
 #include "core/io/file_access_memory.h"
@@ -947,6 +948,10 @@ void EditorSettings::setup_network() {
 
 	_initial_set("network/debug/remote_port", port);
 	add_property_hint(PropertyInfo(Variant::INT, "network/debug/remote_port", PROPERTY_HINT_RANGE, "1,65535,1"));
+
+	// Editor SSL certificates override
+	_initial_set("network/ssl/editor_ssl_certificates", _SYSTEM_CERTS_PATH);
+	add_property_hint(PropertyInfo(Variant::STRING, "network/ssl/editor_ssl_certificates", PROPERTY_HINT_GLOBAL_FILE, "*.crt,*.pem"));
 }
 
 void EditorSettings::save() {

+ 0 - 3
editor/project_manager.cpp

@@ -41,7 +41,6 @@
 #include "core/translation.h"
 #include "core/version.h"
 #include "core/version_hash.gen.h"
-#include "editor_initialize_ssl.h"
 #include "editor_scale.h"
 #include "editor_settings.h"
 #include "editor_themes.h"
@@ -2059,8 +2058,6 @@ void ProjectListFilter::_bind_methods() {
 
 ProjectListFilter::ProjectListFilter() {
 
-	editor_initialize_certificates(); //for asset sharing
-
 	_current_filter = FILTER_NAME;
 
 	filter_option = memnew(OptionButton);

+ 15 - 1
main/main.cpp

@@ -73,6 +73,7 @@
 #include "editor/doc/doc_data.h"
 #include "editor/doc/doc_data_class_path.gen.h"
 #include "editor/editor_node.h"
+#include "editor/editor_settings.h"
 #include "editor/project_manager.h"
 #endif
 
@@ -756,7 +757,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 	if (editor) {
 		packed_data->set_disabled(true);
 		globals->set_disable_feature_overrides(true);
-		StreamPeerSSL::initialize_certs = false; //will be initialized by editor
 	}
 
 #endif
@@ -1595,6 +1595,7 @@ bool Main::start() {
 			sml->set_use_font_oversampling(font_oversampling);
 
 		} else {
+
 			GLOBAL_DEF("display/window/stretch/mode", "disabled");
 			ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
 			GLOBAL_DEF("display/window/stretch/aspect", "ignore");
@@ -1654,6 +1655,10 @@ bool Main::start() {
 		}
 
 		if (!project_manager && !editor) { // game
+
+			// Load SSL Certificates from Project Settings (or builtin)
+			StreamPeerSSL::load_certs_from_memory(StreamPeerSSL::get_project_cert_array());
+
 			if (game_path != "") {
 				Node *scene = NULL;
 				Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path);
@@ -1686,6 +1691,15 @@ bool Main::start() {
 			sml->get_root()->add_child(pmanager);
 			OS::get_singleton()->set_context(OS::CONTEXT_PROJECTMAN);
 		}
+
+		if (project_manager || editor) {
+			// Load SSL Certificates from Editor Settings (or builtin)
+			String certs = EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String();
+			if (certs != "")
+				StreamPeerSSL::load_certs_from_file(certs);
+			else
+				StreamPeerSSL::load_certs_from_memory(StreamPeerSSL::get_project_cert_array());
+		}
 #endif
 	}
 

+ 3 - 5
modules/mbedtls/stream_peer_mbed_tls.cpp

@@ -317,15 +317,13 @@ void StreamPeerMbedTLS::initialize_ssl() {
 	mbedtls_debug_set_threshold(1);
 #endif
 
-	PoolByteArray cert_array = StreamPeerSSL::get_project_cert_array();
-
-	if (cert_array.size() > 0)
-		_load_certs(cert_array);
-
 	available = true;
 }
 
 void StreamPeerMbedTLS::finalize_ssl() {
 
+	available = false;
+	_create = NULL;
+	load_certs_func = NULL;
 	mbedtls_x509_crt_free(&cacert);
 }