From 22e4c0b2bfea51c9f48d0d84e527ffe4c8eb0e25 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sun, 13 Oct 2019 18:25:49 +0300 Subject: Improve meson.build files - meson should now properly create OpenSSL signing key and hexdump before trying to compile plugin loader --- lib/about/aboutdialog.cpp | 1 - lib/about/meson.build | 4 +-- lib/configuration/meson.build | 5 ++-- lib/pluginloader/meson.build | 21 ++++++++------- linux/makepkg/PKGBUILD | 23 +++-------------- meson.build | 47 +++++++++++++--------------------- meson_options.txt | 5 ++++ src/browser.cpp | 2 +- src/meson.build | 4 +-- tools/config.py | 20 --------------- tools/hexdump.py | 35 ------------------------- tools/ssl-keygen.py | 59 +++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 102 insertions(+), 124 deletions(-) delete mode 100755 tools/config.py delete mode 100755 tools/hexdump.py create mode 100755 tools/ssl-keygen.py diff --git a/lib/about/aboutdialog.cpp b/lib/about/aboutdialog.cpp index 452d16f..1ca493e 100644 --- a/lib/about/aboutdialog.cpp +++ b/lib/about/aboutdialog.cpp @@ -9,7 +9,6 @@ #include "aboutdialog.h" #include "ui_aboutdialog.h" #include -#include "config.h" // compiler // clang also defines __GNUC__, so we need to check for clang first diff --git a/lib/about/meson.build b/lib/about/meson.build index e6228c4..531355d 100644 --- a/lib/about/meson.build +++ b/lib/about/meson.build @@ -7,6 +7,6 @@ about_moc = mod_qt5.preprocess( dep_about = declare_dependency( include_directories: include_directories('.'), link_with: static_library('about', - ['aboutdialog.cpp', 'aboutplugin.cpp', about_moc], - dependencies: [dep_qt5, dep_genheaders]) + ['aboutdialog.cpp', 'aboutplugin.cpp', about_moc, version_h], + dependencies: [dep_qt5]) ) diff --git a/lib/configuration/meson.build b/lib/configuration/meson.build index 7234bf0..57bafbc 100644 --- a/lib/configuration/meson.build +++ b/lib/configuration/meson.build @@ -1,14 +1,13 @@ -configuration_inc = include_directories('.') configuration_moc = mod_qt5.preprocess( moc_headers: ['configuration.h'], dependencies: dep_qt5 ) configuration_lib = static_library('configuration', ['commandline.cpp', 'configuration.cpp', configuration_moc], - dependencies: [dep_boost, dep_qt5, dep_genheaders] + dependencies: [dep_boost, dep_qt5, autogen_config] ) dep_configuration = declare_dependency( - include_directories: configuration_inc, + include_directories: include_directories('.'), link_with: configuration_lib ) diff --git a/lib/pluginloader/meson.build b/lib/pluginloader/meson.build index 9334f24..1b68c8c 100644 --- a/lib/pluginloader/meson.build +++ b/lib/pluginloader/meson.build @@ -1,15 +1,14 @@ -dep_openssl = dependency('openssl') +python = import('python') +python3 = python.find_installation('python3') -openssl_exe = find_program('openssl', required: true) -sh = find_program('sh') -hexdump = meson.source_root() / 'tools/hexdump.py' +private_pem = meson.build_root() / get_option('ssl_private_pem') +public_pem = meson.build_root() / get_option('ssl_public_pem') -publickey = custom_target('publicKey.h', +publicKey_h = custom_target('publicKey_h', output: 'publicKey.h', - build_by_default: true, - command: [sh, '-c', - openssl_exe.path() + ' genrsa -out privateKey.pem 4096; ' + openssl_exe.path() + ' rsa -in privateKey.pem -pubout -out publicKey.pem; python3 ' + hexdump + ' --name=publicKey_pem publicKey.pem --output=@OUTPUT@' - ] + command: [python3, meson.source_root() / 'tools/ssl-keygen.py', + '--private=' + private_pem, '--public=' + public_pem, + '--output=@OUTPUT@', '--array-name=publicKey_pem'] ) pluginloader_moc = mod_qt5.preprocess( @@ -20,8 +19,8 @@ pluginloader_moc = mod_qt5.preprocess( dep_pluginloader = declare_dependency( include_directories: include_directories('.'), link_with: static_library('plugin', - ['pluginloader.cpp', pluginloader_moc], + ['pluginloader.cpp', pluginloader_moc, publicKey_h], include_directories: include_directories('.'), - dependencies: [dep_qt5, dep_openssl, dep_genheaders]) + dependencies: [dep_qt5]) ) diff --git a/linux/makepkg/PKGBUILD b/linux/makepkg/PKGBUILD index cd63cef..9a4d13a 100644 --- a/linux/makepkg/PKGBUILD +++ b/linux/makepkg/PKGBUILD @@ -6,7 +6,7 @@ pkgdesc='Yet another no-frills browser' pkgver=r0 pkgrel=1 -url="https://neueland.iserlohn-fortress.net/smolbote" +url="https://neueland.iserlohn-fortress.net/gitea/smolbote" install="smolbote.install" arch=('x86_64') @@ -17,7 +17,7 @@ optdepends=('firejail: launch a sandboxed instance') makedepends=('git' 'meson' 'boost' 'python-kconfiglib' 'openssl' 'qt5-tools' 'scdoc' 'spdlog') # this is the central repository -source=("git+https://neueland.iserlohn-fortress.net/gitea/aeon/smolbote.git" +source=("git+https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote.git" "git+https://github.com/itay-grudev/SingleApplication.git") sha512sums=('SKIP' @@ -32,9 +32,7 @@ sha512sums=('SKIP' #_menuconfig= # Enable plugin signing: -# - generate a 4096-bit RSA key and embed the public key into the binary -# - apply the plugin signing patch to the config, enabling PluginLoader::verify -# - sign the plugins with the private key, and install the signatures +# meson/ninja will generate the privateKey.pem and publicKey.pem in the $builddir # Because this embeds the public key into the executable, enabling this option will break reproducible builds. _signPlugins= @@ -44,19 +42,6 @@ prepare() { git submodule init git config submodule.3rd-party/SingleApplication/SingleApplication.git.url $srcdir/SingleApplication git submodule update 3rd-party/SingleApplication/SingleApplication.git - - if [ -n $_signPlugins ]; then - msg "Creating OpenSSL signing key" - mkdir $srcdir/signing - cd $srcdir/signing - # generate rsa keypair - openssl genrsa -out privateKey.pem 4096 - msg2 "Keypair written to $srcdir/signing/privateKey.pem." - - openssl rsa -in privateKey.pem -pubout -out publicKey.pem - python3 $srcdir/smolbote/tools/hexdump.py --name='publicKey_pem' publicKey.pem --output=$srcdir/smolbote/src/plugin/publicKey.h - msg2 "Public key exported to $srcdir/signing/publicKey.pem." - fi } pkgver() { @@ -104,7 +89,7 @@ package() { if [ -n $_signPlugins ]; then msg "Signing plugins" for so in $pkgdir/usr/local/lib/smolbote/plugins/*.so; do - openssl dgst -sha256 -sign $srcdir/signing/privateKey.pem -out $so.sig $so + openssl dgst -sha256 -sign $srcdir/build/privateKey.pem -out $so.sig $so # If the sigs were in another location, use #install -m644 -t $pkgdir/usr/local/lib/smolbote/plugins $so.sig done diff --git a/meson.build b/meson.build index 5798c49..6412730 100644 --- a/meson.build +++ b/meson.build @@ -2,7 +2,23 @@ project('smolbote', 'cpp', version: '0.1.0', default_options: ['cpp_std=c++17', 'strip=true', 'warning_level=3'], license: 'GPL3', - meson_version: '>=0.49.0' + meson_version: '>=0.51.2' +) + +kconfig = import('unstable-kconfig') +cdata = configuration_data(kconfig.load(host_machine.system() + '/.config')) +config_h = configure_file(output: 'config.h', configuration: cdata) + +version_h = vcs_tag( + command: [find_program('git').path(), 'describe', '--long', '--abbrev=40'], + #fallback: defaults to meson.project_version(), + input: 'include/version.h.in', + output: 'version.h' +) + +autogen_config = declare_dependency( + include_directories: include_directories('.'), + sources: [config_h] ) # add -DQT_NO_DEBUG to non-debug builds @@ -27,9 +43,6 @@ add_project_arguments(cxx.get_supported_arguments([ mod_qt5 = import('qt5') dep_qt5 = dependency('qt5', modules: ['Core', 'Network', 'Widgets', 'WebEngineWidgets', 'Concurrent']) -mod_python = import('python') -python3 = mod_python.find_installation('python3') - dep_boost = dependency('boost', modules: ['program_options']) dep_spdlog = dependency('spdlog', fallback: ['spdlog', 'spdlog_dep'], version: '>=1.3.1') @@ -48,37 +61,11 @@ optional_deps += declare_dependency(compile_args: '-DPLASMA', ) endif -if get_option('Python').enabled() -optional_deps += declare_dependency(compile_args: '-DPYTHON', - dependencies: [ meson.get_compiler('cpp').find_library('linenoise'), - python3.dependency('python', version: '>=3.0.0')]) - subdir('src/cli') -endif - dep_gtest = dependency('gtest', required: get_option('testing')) # Generate config header include = include_directories('include') -git = find_program('git').path() - -dep_genheaders = declare_dependency( - include_directories: include_directories('.'), - sources: [ - vcs_tag( - command: [git, 'describe', '--long', '--abbrev=40'], - #fallback: defaults to meson.project_version(), - input: 'include/version.h.in', - output: 'version.h' - ), - custom_target('configheader', - input: ['tools/config.py', 'Kconfig', host_machine.system() + '/.config'], - output: 'config.h', - command: [python3, '@INPUT0@', '--kconfig=@INPUT1@', '--dotconfig=@INPUT2@', '--generate=@OUTPUT@'], - build_by_default: true - )] -) - interfaces_moc = mod_qt5.preprocess( moc_headers: 'include/profileinterface.h', dependencies: dep_qt5 diff --git a/meson_options.txt b/meson_options.txt index 2615eaa..5f56ec2 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -2,6 +2,11 @@ option('poiName', description: 'Executable name', type: 'string', value: 'poi') option('firejail', description: 'firejail executable name', type: 'string', value: '/usr/bin/firejail') +# Build options +option('signPlugins', description: 'Generate OpenSSL signing key', type: 'feature', value: 'auto') +option('ssl_private_pem', description: 'OpenSSL private key path', type: 'string', value: 'privateKey.pem') +option('ssl_public_pem', description: 'OpenSSL public key path', type: 'string', value: 'publicKey.pem') + # Install options option('manpage', description: 'Generate and install manpage', type: 'feature', value: 'auto') option('translations', description: 'Generate and install translations', type: 'feature', value: 'auto') diff --git a/src/browser.cpp b/src/browser.cpp index e11a1da..0b076ca 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -118,7 +118,7 @@ QPair Browser::loadProfile(const QString &id, bool isOffTheR if(h.length() == 2) interceptor->addHttpHeader(h.at(0).toLatin1(), h.at(1).toLatin1()); } - profile->setRequestInterceptor(interceptor); + profile->setUrlRequestInterceptor(interceptor); spdlog::info("Added profile: {}{}", qUtf8Printable(_id), profile->isOffTheRecord() ? " (otr)" : ""); return QPair(_id, profile); diff --git a/src/meson.build b/src/meson.build index 8660534..ea866b9 100644 --- a/src/meson.build +++ b/src/meson.build @@ -13,10 +13,10 @@ poi_moc = mod_qt5.preprocess( poi = executable(get_option('poiName'), install: true, cpp_args: ['-DQAPPLICATION_CLASS=QApplication'], - dependencies: [dep_qt5, dep_boost, dep_spdlog, dep_SingleApplication, dep_genheaders, optional_deps, + dependencies: [dep_qt5, dep_boost, dep_spdlog, dep_SingleApplication, optional_deps, dep_about, dep_addressbar, dep_bookmarks, dep_configuration, dep_downloads, dep_pluginloader, dep_urlfilter, dep_webprofile], include_directories: [include], - sources: ['main.cpp', 'builtins.cpp', 'crashhandler.cpp', poi_moc, + sources: ['main.cpp', 'builtins.cpp', 'crashhandler.cpp', poi_moc, version_h, 'browser.cpp', 'util.cpp', 'util.h', diff --git a/tools/config.py b/tools/config.py deleted file mode 100755 index 11de99c..0000000 --- a/tools/config.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python3 - -import os -import argparse -import subprocess - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--kconfig", metavar="Kconfig", nargs="?", default="Kconfig", help="Top-level Kconfig file (default: Kconfig)") - parser.add_argument("--dotconfig", metavar="dotconfig", nargs="?", default=".config", help=".config") - parser.add_argument("--generate", metavar="config_header", nargs="?", default="config.h", help="Generate config file") - - args = parser.parse_args() - - # set srctree, otherwise includes don't work - os.environ["srctree"] = os.path.dirname(os.path.realpath(args.kconfig)) - os.environ["KCONFIG_CONFIG"] = os.path.realpath(args.dotconfig) - - subprocess.run(["genconfig", os.path.realpath(args.kconfig), "--header-path=" + args.generate], check=True) - diff --git a/tools/hexdump.py b/tools/hexdump.py deleted file mode 100755 index c0ed2a3..0000000 --- a/tools/hexdump.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import sys -from functools import partial - -parser = argparse.ArgumentParser(description='Convert a file to C array') -parser.add_argument('input', type=str, help='Input file') -parser.add_argument('--output', type=argparse.FileType('wt'), default=sys.stdout, help='Output file') -parser.add_argument('--array-type', type=str, default='const unsigned char', help='Array type') -parser.add_argument('--length-type', type=str, default='const unsigned int', help='Length type') -parser.add_argument('--name', type=str, default='a', help='Array name') - -args=parser.parse_args() - -print("{} {}[] = {{".format(args.array_type, args.name), file=args.output) - -n = 0 - -with open(args.input, "rb") as in_file: - for c in iter(partial(in_file.read, 1), b''): - if n % 16 == 0: - print(" ", end='', file=args.output) - - print("0x%02X," % ord(c), end='', file=args.output) - - n += 1 - if n % 16 == 0: - print("", file=args.output) - else: - print(" ", end='', file=args.output) - -print("\n};", file=args.output) -print("{} {}_len = {};".format(args.length_type, args.name, n), file=args.output) - diff --git a/tools/ssl-keygen.py b/tools/ssl-keygen.py new file mode 100755 index 0000000..555b379 --- /dev/null +++ b/tools/ssl-keygen.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +import argparse +import sys +import os.path +import subprocess +from functools import partial + +def generate_private_key(out_pem='privateKey.pem'): + subprocess.run(['openssl', 'genrsa', '-out', out_pem, '4096'], check=True) + +def generate_public_key(in_pem='privateKey.pem', out_pem='publicKey.pem'): + subprocess.run(['openssl', 'rsa', '-in', in_pem, '-pubout', '-out', out_pem], check=True) + +def hexdump(array_type, array_name, length_type, in_pem, out_h): + n = 0 + + print("// Autogenerated hex dump of OpenSSL public key, do not edit", file=out_h) + print("{} {}[] = {{".format(array_type, array_name), file=out_h) + + for line in iter(partial(in_pem.read, 16), b''): + l = list(line) + for n, i in enumerate(l): + l[n] = '0x{:02X}'.format(i) + + print(" {},".format(", ".join(l)), file=out_h) + + n += 1 + + print("};", file=out_h) + print("{} {}_len = {};".format(length_type, array_name, n), file=out_h) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Generate OpenSSL key and hexdump') + + parser.add_argument('--private', default='privateKey.pem', type=str, help='Private key input') + parser.add_argument('--public', default='publicKey.pem', type=str, help='Public key input') + + parser.add_argument('--output', type=argparse.FileType('wt'), default=sys.stdout, help='Output file') + + parser.add_argument('--array-type', type=str, default='const unsigned char', help='Array type') + parser.add_argument('--length-type', type=str, default='const unsigned int', help='Length type') + parser.add_argument('--array-name', type=str, default='a', help='Array name') + + args=parser.parse_args() + + # check if public key exists + if not os.path.isfile(args.public): + # if there is no private key, generate one + if not os.path.isfile(args.private): + generate_private_key(args.private) + + # export public key from private + generate_public_key(args.private, args.public) + + with open(args.public, "rb") as public_pem: + hexdump(args.array_type, args.array_name, args.length_type, public_pem, args.output) + + -- cgit v1.2.1