Browse Source

Improve meson.build files

- meson should now properly create OpenSSL signing key and hexdump
before trying to compile plugin loader
master
Aqua-sama 2 months ago
parent
commit
22e4c0b2bf
Signed by: Aqua-sama <aqua@iserlohn-fortress.net> GPG Key ID: 81A99984EABC02D1
12 changed files with 102 additions and 124 deletions
  1. +0
    -1
      lib/about/aboutdialog.cpp
  2. +2
    -2
      lib/about/meson.build
  3. +2
    -3
      lib/configuration/meson.build
  4. +10
    -11
      lib/pluginloader/meson.build
  5. +4
    -19
      linux/makepkg/PKGBUILD
  6. +17
    -30
      meson.build
  7. +5
    -0
      meson_options.txt
  8. +1
    -1
      src/browser.cpp
  9. +2
    -2
      src/meson.build
  10. +0
    -20
      tools/config.py
  11. +0
    -35
      tools/hexdump.py
  12. +59
    -0
      tools/ssl-keygen.py

+ 0
- 1
lib/about/aboutdialog.cpp View File

@@ -9,7 +9,6 @@
#include "aboutdialog.h"
#include "ui_aboutdialog.h"
#include <version.h>
#include "config.h"

// compiler
// clang also defines __GNUC__, so we need to check for clang first

+ 2
- 2
lib/about/meson.build View File

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

+ 2
- 3
lib/configuration/meson.build View File

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

+ 10
- 11
lib/pluginloader/meson.build View File

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


+ 4
- 19
linux/makepkg/PKGBUILD View File

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

+ 17
- 30
meson.build View File

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

+ 5
- 0
meson_options.txt View File

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

+ 1
- 1
src/browser.cpp View File

@@ -118,7 +118,7 @@ QPair<QString, Profile *> 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<QString, WebProfile *>(_id, profile);

+ 2
- 2
src/meson.build View File

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


+ 0
- 20
tools/config.py View File

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


+ 0
- 35
tools/hexdump.py View File

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


+ 59
- 0
tools/ssl-keygen.py View File

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



Loading…
Cancel
Save