Allow system certs file to be used by Editor.

Note, it will only used by the Editor, not when running the game.
This allows package maintainer to compile Godot to use system installed
certificates when accessing the AssetLib.
This commit is contained in:
Fabio Alessandrelli 2018-09-15 14:45:54 +02:00
parent d2b38aabec
commit 0e56377e96
8 changed files with 59 additions and 23 deletions

View file

@ -169,6 +169,7 @@ 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))

View file

@ -94,7 +94,7 @@ if 'builtin_zstd' in env and env['builtin_zstd']:
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.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

View file

@ -21,6 +21,10 @@ def make_certs_header(target, source, env):
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")

View file

@ -44,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;
}
@ -63,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;
@ -71,18 +97,7 @@ PoolByteArray StreamPeerSSL::get_project_cert_array() {
if (certs_path != "") {
// Use certs defined in project settings.
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; // Make sure it ends with string terminator
memdelete(f);
#ifdef DEBUG_ENABLED
print_verbose(vformat("Loaded certs from '%s'.", certs_path));
#endif
}
return get_cert_file_as_array(certs_path);
}
#ifdef BUILTIN_CERTS_ENABLED
else {

View file

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

View file

@ -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() {

View file

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

View file

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