From bc6e9cb1651237cb9c1e48f3506bc32b74422721 Mon Sep 17 00:00:00 2001 From: Alexis He Date: Mon, 30 Aug 2021 19:18:40 +0200 Subject: [PATCH] Fix: zip top folder not necessarily reported as file entry Fix: pakset may not start with simutrans folder Fix: https calls --- .github/workflows/nightly-android.yml | 2 +- gui/pakinstaller.cc | 73 ++++++++++++++++++++------- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/.github/workflows/nightly-android.yml b/.github/workflows/nightly-android.yml index d4091eecb..ecb6eb362 100644 --- a/.github/workflows/nightly-android.yml +++ b/.github/workflows/nightly-android.yml @@ -74,7 +74,7 @@ jobs: - name: Checkout lib Android SDL by pelya (hard coded version) working-directory: /android-sdl run: | - git init && git remote add origin https://github.com/krosk/commandergenius.git && git fetch origin 0a516df844a2ffba02a81ecadd2849f957b38180 && git reset --hard FETCH_HEAD + git init && git remote add origin https://github.com/krosk/commandergenius.git && git fetch origin e5f69261a154cdc1d0a60d8c1e93ecd1973602ae && git reset --hard FETCH_HEAD - name: Setup licenses for Gradle working-directory: /android-sdl diff --git a/gui/pakinstaller.cc b/gui/pakinstaller.cc index c642b93a5..e2f894e38 100644 --- a/gui/pakinstaller.cc +++ b/gui/pakinstaller.cc @@ -94,6 +94,41 @@ bool pakinstaller_t::action_triggered(gui_action_creator_t*, value_t) #include #include + // linux/android specific, function to create folder makes use of opendir (linux system call) and mkdir (via system) +#include +#include + +static bool create_folder_if_required(const char* extracted_path) { + char extracted_folder_name[FILENAME_MAX]; + strcpy(extracted_folder_name, extracted_path); + char * last_occurence = strrchr(extracted_folder_name, '/'); + if (last_occurence != NULL) { + last_occurence[0] = '\0'; + } + else { + dbg->debug(__FUNCTION__, "Error searching for path? %s", extracted_folder_name); + return false; + } + + DIR* dir = opendir(extracted_folder_name); + if (dir) { + closedir(dir); + } + else if (ENOENT == errno) { + cbuffer_t param; + param.append("mkdir -p "); + param.append(extracted_folder_name); + const int retval = system( param ); + dbg->debug(__FUNCTION__, "- - Created folder %s, ret %d", extracted_folder_name, retval); + } + else { + dbg->debug(__FUNCTION__, "Error checking directory"); + return false; + } + + return true; +} + static void read_zip(const char* outfilename) { zip_t * zip_archive; int err; @@ -131,27 +166,19 @@ static void read_zip(const char* outfilename) { dbg->debug(__FUNCTION__, "unexpected content size in file %s (index %d) of zip_archive; is %d, should be %d: %s", st.name, idx, read_size, st.size); } else { - // example of path: - // simutrans/pak64.german/tool/check_passenger_stops/cursor.script_tool_check_pass.pak - // For android platform, the simutrans/ at the start must be removed. -#ifdef __ANDROID__ - const char* target_filename = st.name + 10; -#else - const char* target_filename = st.name; -#endif + // path may start with simutrans/, in which case it can be removed safely + bool start_with_simutrans = strncmp(st.name, "simutrans/", 10) == 0; + const char* target_filename = start_with_simutrans ? st.name + 10 : st.name; char extracted_path[FILENAME_MAX]; sprintf(extracted_path, "%s%s", env_t::data_dir, target_filename); - dbg->debug(__FUNCTION__, "- %s: %d", extracted_path, st.size); - if (st.size == 0) { // likely a directory - cbuffer_t param; - param.append("mkdir "); - param.append(extracted_path); - const int retval = system( param ); - dbg->debug(__FUNCTION__, "Creating folder %s, ret %d", extracted_path, retval); - } - else if(!std::ofstream(extracted_path).write(contents, st.size)) { + + if (!create_folder_if_required(extracted_path)) { + continue; + } + + if(st.size > 0 && !std::ofstream(extracted_path).write(contents, st.size)) { dbg->debug(__FUNCTION__, "Error writing file"); } } @@ -174,7 +201,17 @@ static CURLcode curl_download_file(CURL *curl, const char* target_file, const ch CURLcode res; curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + char cabundle_path[FILENAME_MAX]; + sprintf(cabundle_path, "%s%s", env_t::data_dir, "cacert.pem"); + FILE *cabundle_file; + if ((cabundle_file = fopen(cabundle_path, "r"))) { + fclose(cabundle_file); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); + curl_easy_setopt(curl, CURLOPT_CAINFO, cabundle_path); + } else { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + dbg->warning(__FUNCTION__, "ssl certificate authority bundle not found at %s; https calls will not be validated; this may be a security concern", cabundle_path); + } curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); -- 2.28.0.windows.1