summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2019-11-02 17:33:28 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2019-11-02 17:33:28 -0500
commitdd7559561a8a7f4fef7a4bb8b23e2894eca4594c (patch)
treea9feba9457e0d05eb6da967e3134f355e738e51f
parent8270ab3308f2522d0150e9040ea44883ce175e70 (diff)
downloadhorizon-dd7559561a8a7f4fef7a4bb8b23e2894eca4594c.tar.gz
horizon-dd7559561a8a7f4fef7a4bb8b23e2894eca4594c.tar.bz2
horizon-dd7559561a8a7f4fef7a4bb8b23e2894eca4594c.tar.xz
horizon-dd7559561a8a7f4fef7a4bb8b23e2894eca4594c.zip
hscript: Add download_file helper and implement SigningKey::execute0.1.0
-rw-r--r--hscript/CMakeLists.txt10
-rw-r--r--hscript/meta.cc47
-rw-r--r--hscript/script.cc27
-rw-r--r--hscript/util.cc61
-rw-r--r--hscript/util.hh25
5 files changed, 168 insertions, 2 deletions
diff --git a/hscript/CMakeLists.txt b/hscript/CMakeLists.txt
index e6e86b6..e7f54e9 100644
--- a/hscript/CMakeLists.txt
+++ b/hscript/CMakeLists.txt
@@ -1,3 +1,5 @@
+pkg_check_modules(CURL libcurl)
+
set(HSCRIPT_SOURCE
script.cc
disk.cc
@@ -5,6 +7,7 @@ set(HSCRIPT_SOURCE
meta.cc
network.cc
user.cc
+ util.cc
)
set(HSCRIPT_INCLUDE
@@ -14,6 +17,7 @@ set(HSCRIPT_INCLUDE
add_library(hscript ${HSCRIPT_SOURCE})
target_compile_features(hscript PRIVATE cxx_nullptr)
target_compile_features(hscript PUBLIC cxx_unicode_literals)
+
if("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
set_property(TARGET hscript PROPERTY CXX_STANDARD 17)
SET(FS_LIBRARY stdc++fs)
@@ -23,7 +27,13 @@ ELSE()
SET(FS_LIBRARY ${Boost_FILESYSTEM_LIBRARY})
add_definitions(-DFS_IS_BOOST)
ENDIF()
+
target_link_libraries(hscript ${BLKID_LIBRARIES} ${FS_LIBRARY} ${LIBUDEV_LIBRARIES} ${PARTED_LIBRARIES})
+IF(CURL_FOUND)
+ add_definitions(-DHAVE_LIBCURL)
+ target_link_libraries(hscript ${CURL_LIBRARIES})
+ENDIF(CURL_FOUND)
+
install(TARGETS hscript DESTINATION lib)
install(FILES ${HSCRIPT_INCLUDE} DESTINATION include/hscript)
diff --git a/hscript/meta.cc b/hscript/meta.cc
index d664992..1124988 100644
--- a/hscript/meta.cc
+++ b/hscript/meta.cc
@@ -20,6 +20,7 @@
#endif /* HAS_INSTALL_ENV */
#include <unistd.h> /* access - used by tz code even in RT env */
#include "meta.hh"
+#include "util.hh"
#include "util/output.hh"
using namespace Horizon::Keys;
@@ -511,6 +512,48 @@ bool SigningKey::validate(ScriptOptions) const {
return true;
}
-bool SigningKey::execute(ScriptOptions) const {
- return false;
+bool SigningKey::execute(ScriptOptions opts) const {
+ /* everything after the last / in the value is the filename */
+ const std::string name(_value.substr(_value.find_last_of('/') + 1));
+
+ const std::string target("/target/etc/apk/keys/" + name);
+
+ output_info("installfile:" + std::to_string(line),
+ "signingkey: trusting " + name + " for repository signing");
+
+ if(opts.test(Simulate)) {
+ std::cout << "mkdir -p /target/etc/apk/keys" << std::endl;
+ if(_value[0] == '/') {
+ std::cout << "cp " << _value << " " << target << std::endl;
+ } else {
+ std::cout << "curl -L -o " << target << " " << _value << std::endl;
+ }
+ return true;
+ }
+
+#ifdef HAS_INSTALL_ENV
+ error_code ec;
+ if(!fs::exists("/target/etc/apk/keys")) {
+ fs::create_directory("/target/etc/apk/keys", ec);
+ if(ec) {
+ output_error("installfile:" + std::to_string(line),
+ "signingkey: could not initialise target repository "
+ "keys directory", ec.message());
+ return false;
+ }
+ }
+
+ if(_value[0] == '/') {
+ fs::copy_file(_value, target, fs_overwrite, ec);
+ if(ec) {
+ output_error("installfile:" + std::to_string(line),
+ "signingkey: could not copy signing key to target",
+ ec.message());
+ return false;
+ }
+ } else {
+ return download_file(_value, target);
+ }
+#endif /* HAS_INSTALL_ENV */
+ return true;
}
diff --git a/hscript/script.cc b/hscript/script.cc
index 6eebae8..4ed52b7 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -712,6 +712,26 @@ bool add_default_repos(std::vector<std::unique_ptr<Keys::Repository>> &repos) {
}
+/*! Add the default repository keys to the signing key list.
+ * @param keys The list of repository keys.
+ * The list +keys+ will be modified with the default repository signing keys
+ * for Adélie Linux.
+ */
+bool add_default_repo_keys(std::vector<std::unique_ptr<Keys::SigningKey>> &keys) {
+ Keys::SigningKey *key = dynamic_cast<Keys::SigningKey *>(
+ Horizon::Keys::SigningKey::parseFromData(
+ "/etc/apk/keys/packages@adelielinux.org.pub", 0, nullptr, nullptr)
+ );
+ if(!key) {
+ output_error("internal", "failed to create default repository signing key");
+ return false;
+ }
+ std::unique_ptr<Keys::SigningKey> repo_key(key);
+ keys.push_back(std::move(repo_key));
+ return true;
+}
+
+
bool Script::validate() const {
int failures = 0;
std::set<std::string> seen_diskids, seen_labels, seen_parts, seen_pvs,
@@ -822,6 +842,13 @@ bool Script::validate() const {
"You may only specify up to 10 repositories.");
}
+ /* REQ: Script.signingkey */
+ if(this->internal->repo_keys.size() == 0) {
+ if(!add_default_repo_keys(this->internal->repo_keys)) {
+ return false;
+ }
+ }
+
/* REQ: Runner.Validate.signingkey */
for(auto &key : this->internal->repo_keys) {
if(!key->validate(this->opts)) {
diff --git a/hscript/util.cc b/hscript/util.cc
new file mode 100644
index 0000000..4a991c5
--- /dev/null
+++ b/hscript/util.cc
@@ -0,0 +1,61 @@
+/*
+ * util.cc - Implementation of useful utility routines
+ * libhscript, the HorizonScript library for
+ * Project Horizon
+ *
+ * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved.
+ * This code is licensed under the AGPL 3.0 license, as noted in the
+ * LICENSE-code file in the root directory of this repository.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+#include <string>
+#ifdef HAVE_LIBCURL
+# include <cstdio> /* fopen */
+# include <cstring> /* strerror */
+# include <curl/curl.h> /* curl_* */
+# include <errno.h> /* errno */
+#endif /* HAVE_LIBCURL */
+#include "util/output.hh"
+
+#ifdef HAVE_LIBCURL
+bool download_file(const std::string &url, const std::string &path) {
+ CURL *curl = curl_easy_init();
+ CURLcode result;
+ bool return_code = false;
+ char errbuf[CURL_ERROR_SIZE];
+ FILE *fp;
+
+ if(curl == nullptr) {
+ output_error("internal", "trouble initialising cURL library");
+ return false;
+ }
+
+ fp = fopen(path.c_str(), "w");
+ if(fp == nullptr) {
+ output_error("internal", "couldn't open " + path + " for writing",
+ strerror(errno));
+ curl_easy_cleanup(curl);
+ return false;
+ }
+
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
+
+ result = curl_easy_perform(curl);
+ if(result == CURLE_OK) {
+ return_code = true;
+ } else {
+ output_error("curl", "couldn't download file", errbuf);
+ }
+ curl_easy_cleanup(curl);
+ return return_code;
+}
+#else /* !HAVE_LIBCURL */
+bool download_file(const std::string &url, const std::string &path) {
+ output_error("internal", "can't download without linking to cURL");
+ return false;
+}
+#endif /* HAVE_LIBCURL */
diff --git a/hscript/util.hh b/hscript/util.hh
new file mode 100644
index 0000000..d350cd3
--- /dev/null
+++ b/hscript/util.hh
@@ -0,0 +1,25 @@
+/*
+ * util.cc - Definition of useful utility routines
+ * libhscript, the HorizonScript library for
+ * Project Horizon
+ *
+ * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved.
+ * This code is licensed under the AGPL 3.0 license, as noted in the
+ * LICENSE-code file in the root directory of this repository.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+#ifndef HSCRIPT_UTIL_HH
+#define HSCRIPT_UTIL_HH
+
+#include <string>
+
+/*! Download the contents of a URL to a path.
+ * @param url The URL to download.
+ * @param path The path in which to save the file.
+ * @returns true if successful download, false otherwise.
+ */
+bool download_file(const std::string &url, const std::string &path);
+
+#endif /* !HSCRIPT_UTIL_HH */