Merge pull request #22066 from Faless/bundle_certs

Bundle SSL certs with the templates
This commit is contained in:
Rémi Verschelde 2018-09-16 01:22:47 +02:00 committed by GitHub
commit 7f5e653a22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 107 additions and 147 deletions

View file

@ -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(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(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(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 # Thirdparty libraries
opts.Add(BoolVariable('builtin_bullet', "Use the built-in Bullet library", True)) 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_enet', "Use the built-in ENet library", True))
opts.Add(BoolVariable('builtin_freetype', "Use the built-in FreeType 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)) opts.Add(BoolVariable('builtin_libogg', "Use the built-in libogg library", True))

View file

@ -93,6 +93,9 @@ if 'builtin_zstd' in env and env['builtin_zstd']:
# Godot's own sources # Godot's own sources
env.add_source_files(env.core_sources, "*.cpp") 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 # Make binders
env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run)) env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run))

View file

@ -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 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): def make_authors_header(target, source, env):

View file

@ -30,6 +30,8 @@
#include "stream_peer_ssl.h" #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/os/file_access.h"
#include "core/project_settings.h" #include "core/project_settings.h"
@ -42,13 +44,20 @@ StreamPeerSSL *StreamPeerSSL::create() {
StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL; StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL;
bool StreamPeerSSL::available = false; bool StreamPeerSSL::available = false;
bool StreamPeerSSL::initialize_certs = true;
void StreamPeerSSL::load_certs_from_memory(const PoolByteArray &p_memory) { void StreamPeerSSL::load_certs_from_memory(const PoolByteArray &p_memory) {
if (load_certs_func) if (load_certs_func)
load_certs_func(p_memory); 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() { bool StreamPeerSSL::is_available() {
return available; return available;
} }
@ -61,6 +70,25 @@ bool StreamPeerSSL::is_blocking_handshake_enabled() const {
return blocking_handshake; 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 StreamPeerSSL::get_project_cert_array() {
PoolByteArray out; 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")); ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
if (certs_path != "") { if (certs_path != "") {
// Use certs defined in project settings.
FileAccess *f = FileAccess::open(certs_path, FileAccess::READ); return get_cert_file_as_array(certs_path);
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
} }
#ifdef BUILTIN_CERTS_ENABLED
memdelete(f); 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 #ifdef DEBUG_ENABLED
print_verbose(vformat("Loaded certs from '%s'.", certs_path)); print_verbose("Loaded builtin certs");
#endif #endif
} }
} #endif
return out; return out;
} }

View file

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

View file

@ -61,10 +61,6 @@ if env['tools']:
env.Depends("#editor/doc_data_compressed.gen.h", docs) 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)) 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 import glob
path = env.Dir('.').abspath path = env.Dir('.').abspath

View file

@ -9,32 +9,6 @@ from platform_methods import subprocess_main
from compat import encode_utf8, byte_to_str, open_utf8, escape_string 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): def make_doc_header(target, source, env):
dst = target[0] dst = target[0]

View file

@ -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);
}

View file

@ -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

View file

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

View file

@ -30,6 +30,7 @@
#include "editor_settings.h" #include "editor_settings.h"
#include "core/io/certs_compressed.gen.h"
#include "core/io/compression.h" #include "core/io/compression.h"
#include "core/io/config_file.h" #include "core/io/config_file.h"
#include "core/io/file_access_memory.h" #include "core/io/file_access_memory.h"
@ -947,6 +948,10 @@ void EditorSettings::setup_network() {
_initial_set("network/debug/remote_port", port); _initial_set("network/debug/remote_port", port);
add_property_hint(PropertyInfo(Variant::INT, "network/debug/remote_port", PROPERTY_HINT_RANGE, "1,65535,1")); 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() { void EditorSettings::save() {

View file

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

View file

@ -73,6 +73,7 @@
#include "editor/doc/doc_data.h" #include "editor/doc/doc_data.h"
#include "editor/doc/doc_data_class_path.gen.h" #include "editor/doc/doc_data_class_path.gen.h"
#include "editor/editor_node.h" #include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/project_manager.h" #include "editor/project_manager.h"
#endif #endif
@ -756,7 +757,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (editor) { if (editor) {
packed_data->set_disabled(true); packed_data->set_disabled(true);
globals->set_disable_feature_overrides(true); globals->set_disable_feature_overrides(true);
StreamPeerSSL::initialize_certs = false; //will be initialized by editor
} }
#endif #endif
@ -1595,6 +1595,7 @@ bool Main::start() {
sml->set_use_font_oversampling(font_oversampling); sml->set_use_font_oversampling(font_oversampling);
} else { } else {
GLOBAL_DEF("display/window/stretch/mode", "disabled"); 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")); 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"); GLOBAL_DEF("display/window/stretch/aspect", "ignore");
@ -1654,6 +1655,10 @@ bool Main::start() {
} }
if (!project_manager && !editor) { // game 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 != "") { if (game_path != "") {
Node *scene = NULL; Node *scene = NULL;
Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path); Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path);
@ -1686,6 +1691,15 @@ bool Main::start() {
sml->get_root()->add_child(pmanager); sml->get_root()->add_child(pmanager);
OS::get_singleton()->set_context(OS::CONTEXT_PROJECTMAN); 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 #endif
} }

View file

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