├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .editorconfig ├── .flake8 ├── .gitignore ├── .gitlab-ci.yml ├── .packit.yaml ├── .pylintrc ├── .travis.yml ├── BUGS.md ├── CHANGELOG.md ├── COPYING ├── HACKING.md ├── INSTALL.md ├── README.md ├── bolt.spec ├── boltd ├── bolt-auth.c ├── bolt-auth.h ├── bolt-bouncer.c ├── bolt-bouncer.h ├── bolt-config.c ├── bolt-config.h ├── bolt-daemon.c ├── bolt-device.c ├── bolt-device.h ├── bolt-domain.c ├── bolt-domain.h ├── bolt-exported.c ├── bolt-exported.h ├── bolt-guard.c ├── bolt-guard.h ├── bolt-journal.c ├── bolt-journal.h ├── bolt-key.c ├── bolt-key.h ├── bolt-log.c ├── bolt-log.h ├── bolt-manager.c ├── bolt-manager.h ├── bolt-power.c ├── bolt-power.h ├── bolt-reaper.c ├── bolt-reaper.h ├── bolt-store.c ├── bolt-store.h ├── bolt-sysfs.c ├── bolt-sysfs.h ├── bolt-udev.c ├── bolt-udev.h ├── bolt-watchdog.c └── bolt-watchdog.h ├── cli ├── bolt-client.c ├── bolt-client.h ├── bolt-device.c ├── bolt-device.h ├── bolt-domain.c ├── bolt-domain.h ├── bolt-power.c ├── bolt-power.h ├── bolt-proxy.c ├── bolt-proxy.h ├── boltctl-authorize.c ├── boltctl-cmds.h ├── boltctl-config.c ├── boltctl-domains.c ├── boltctl-enroll.c ├── boltctl-forget.c ├── boltctl-info.c ├── boltctl-list.c ├── boltctl-monitor.c ├── boltctl-power.c ├── boltctl-uidfmt.c ├── boltctl-uidfmt.h ├── boltctl.c └── boltctl.h ├── common ├── bolt-dbus.c ├── bolt-dbus.h ├── bolt-enums.c ├── bolt-enums.h ├── bolt-error.c ├── bolt-error.h ├── bolt-fs.c ├── bolt-fs.h ├── bolt-glue.c ├── bolt-glue.h ├── bolt-io.c ├── bolt-io.h ├── bolt-list.h ├── bolt-macros.h ├── bolt-names.c ├── bolt-names.h ├── bolt-rnd.c ├── bolt-rnd.h ├── bolt-str.c ├── bolt-str.h ├── bolt-term.c ├── bolt-term.h ├── bolt-time.c ├── bolt-time.h ├── bolt-unix.c ├── bolt-unix.h ├── bolt-wire.c ├── bolt-wire.h └── fix-coverity.h ├── config.h.in ├── contrib ├── Dockerfile-alpine ├── Dockerfile-arch ├── Dockerfile-coverity ├── Dockerfile-debian ├── Dockerfile-fedora ├── Dockerfile-ub1804 ├── PKGBUILD ├── bolt-mock ├── bolt.spec.in ├── cov-model.c ├── coverity.sh ├── docker-build.sh └── js │ ├── .jshintrc │ ├── client.js │ └── test.js ├── data ├── 90-bolt.rules ├── bolt.service.in ├── dbus.gresource.xml ├── org.freedesktop.bolt.conf ├── org.freedesktop.bolt.service.in └── org.freedesktop.bolt.xml ├── docs ├── boltctl.1.txt └── boltd.8.txt ├── meson.build ├── meson_options.txt ├── policy ├── org.freedesktop.bolt.policy.in └── org.freedesktop.bolt.rules.in ├── scripts ├── git-hooks.sh ├── git-hooks │ ├── pre-commit │ └── pre-push ├── meson-install.sh ├── uncrustify.cfg └── uncrustify.sh └── tests ├── bolt-test.c ├── bolt-test.h ├── example.bolt.xml ├── mock-sysfs.c ├── mock-sysfs.h ├── pycodestyle.cfg ├── test-auth.c ├── test-common.c ├── test-device.c ├── test-enums.h ├── test-exported.c ├── test-glue.c ├── test-guard.c ├── test-integration ├── test-journal.c ├── test-logging.c ├── test-power.c ├── test-reaper.c ├── test-self.c ├── test-store.c ├── test-sysfs.c ├── test-udev.c ├── test-unix.c ├── test-watchdog.c ├── test-wire.c └── tests.gresource.xml /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:latest 2 | RUN dnf install -y \ 3 | asciidoc \ 4 | bat \ 5 | clang-analyzer \ 6 | ccls \ 7 | codespell \ 8 | findutils \ 9 | fish \ 10 | fpaste \ 11 | gcc \ 12 | git \ 13 | glib2-devel \ 14 | glibc-langpack-en \ 15 | gtk-doc \ 16 | hostname \ 17 | ipython3 \ 18 | jq \ 19 | lcov \ 20 | libgudev-devel \ 21 | lsof \ 22 | make \ 23 | meson \ 24 | packit \ 25 | polkit-devel \ 26 | pylint \ 27 | python3 \ 28 | python3-autopep8 \ 29 | python3-dbus \ 30 | python3-dbusmock \ 31 | python3-devel \ 32 | python3-docutils \ 33 | python3-enchant \ 34 | python3-gobject \ 35 | python3-jsonschema \ 36 | python3-pip \ 37 | python3-pycodestyle \ 38 | python3-pylint \ 39 | python3-pytest \ 40 | python3-pyyaml \ 41 | redhat-rpm-config \ 42 | rpm-build \ 43 | rpmlint \ 44 | skopeo \ 45 | strace \ 46 | systemd-devel \ 47 | the_silver_searcher \ 48 | tree \ 49 | umockdev-devel \ 50 | uncrustify 51 | 52 | WORKDIR /workspaces/bolt 53 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bolt", 3 | "build": { 4 | "dockerfile": "Dockerfile", 5 | "context": "..", 6 | }, 7 | "mounts": [ 8 | "source=bold-share,target=/root/.local/share,type=volume" 9 | ], 10 | "runArgs": [ 11 | "--privileged" 12 | ], 13 | "settings": { 14 | "C_Cpp.autocomplete": "Disabled", 15 | "C_Cpp.formatting": "Disabled", 16 | "C_Cpp.errorSquiggles": "Disabled", 17 | "C_Cpp.intelliSenseEngine": "Disabled", 18 | "terminal.integrated.shell.linux": "/bin/fish", 19 | "python.pythonPath": "/usr/bin/python", 20 | "python.linting.enabled": true, 21 | "python.linting.pylintEnabled": true, 22 | "python.testing.unittestEnabled": false, 23 | "python.testing.nosetestsEnabled": false, 24 | "python.testing.pyTestEnabled": true, 25 | "python.testing.pyTestArgs": [ 26 | "test" 27 | ] 28 | }, 29 | "extensions": [ 30 | "asabil.meson", 31 | "editorconfig.editorconfig", 32 | "ccls-project.ccls", 33 | "laurenttreguier.rpm-spec", 34 | "ms-python.python", 35 | "ms-python.vscode-pylance", 36 | "ms-vscode.cpptools", 37 | "ms-vscode-remote.remote-containers", 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | charset = utf-8 8 | 9 | [*.{c,h}] 10 | indent_style = space 11 | indent_size = 2 12 | indent_brace_style = gnu 13 | 14 | [meson.build] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | [.md] 19 | indent_style = space 20 | indent_size = 2 21 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 120 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # files 3 | *~ 4 | *.log 5 | *.xz 6 | 7 | # directories 8 | build/ 9 | dist/ 10 | 11 | # coverity 12 | cov-int/ 13 | coverity/ 14 | 15 | # IDEs and related 16 | .ccls-cache/ 17 | .cquery_cached_index/ 18 | compile_commands.json 19 | .idea 20 | .gdb_history 21 | .vscode/ 22 | 23 | # emacs 24 | TAGS 25 | \#*\# 26 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: docker:latest 2 | 3 | services: 4 | - docker:dind 5 | 6 | .build-template: &build 7 | script: 8 | - docker build -t bolt-$OS -f ./contrib/Dockerfile-$OS . 9 | - mkdir build-$OS 10 | - docker run --cap-drop=dac_override -e -t -v `pwd`:/src -v `pwd`/build-$OS:/build bolt-$OS ./contrib/docker-build.sh 11 | artifacts: 12 | paths: 13 | - build-$OS/meson-logs 14 | expire_in: 1 week 15 | 16 | fedora: 17 | stage: build 18 | variables: 19 | OS: fedora 20 | <<: *build 21 | 22 | arch: 23 | stage: build 24 | allow_failure: true 25 | variables: 26 | OS: arch 27 | <<: *build 28 | 29 | alpine: 30 | stage: build 31 | variables: 32 | OS: alpine 33 | <<: *build 34 | 35 | coverity: 36 | stage: build 37 | only: 38 | refs: 39 | - schedules 40 | variables: 41 | - $COVERITY_TOKEN && $COVERITY_EMAIL 42 | script: 43 | - mkdir build-coverity 44 | - docker build --build-arg ORG=gicmo --build-arg PROJECT=bolt --build-arg TOKEN=$COVERITY_TOKEN -t bolt-coverity -f ./contrib/Dockerfile-coverity . 45 | - docker run --rm -e COVERITY_TOKEN=$COVERITY_TOKEN -e COVERITY_EMAIL=$COVERITY_EMAIL -t -v `pwd`:/src:Z -v `pwd`/build-coverity:/build:Z bolt-coverity ./contrib/coverity.sh 46 | artifacts: 47 | paths: 48 | - build-coverity/cov-int/build-log.txt 49 | expire_in: 1 week 50 | 51 | srpm_build: 52 | image: quay.io/packit/packit 53 | stage: build 54 | script: 55 | - packit srpm 56 | artifacts: 57 | paths: 58 | - "*.src.rpm" 59 | expire_in: 1 week 60 | -------------------------------------------------------------------------------- /.packit.yaml: -------------------------------------------------------------------------------- 1 | # https://packit.dev/docs/configuration/ 2 | 3 | specfile_path: bolt.spec 4 | 5 | synced_files: 6 | - bolt.spec 7 | - .packit.yaml 8 | 9 | upstream_package_name: bolt 10 | downstream_package_name: bolt 11 | 12 | copy_upstream_release_description: true 13 | 14 | actions: 15 | get-current-version: bash -c "git describe --tags --abbrev=0 | sed 's|v||'" 16 | 17 | jobs: 18 | - job: propose_downstream 19 | trigger: release 20 | dist_git_branches: 21 | - fedora-all 22 | - job: koji_build 23 | trigger: commit 24 | dist_git_branches: 25 | - fedora-all 26 | - job: bodhi_update 27 | trigger: commit 28 | dist_git_branches: 29 | - fedora-stable # rawhide updates are created automatically 30 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | disable=missing-docstring,invalid-name,duplicate-code,superfluous-parens,too-many-locals,attribute-defined-outside-init,too-many-arguments 3 | max-line-length=120 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: required 3 | dist: bionic 4 | 5 | services: 6 | - docker 7 | 8 | env: 9 | - OS=alpine 10 | - OS=debian 11 | - OS=arch 12 | - OS=fedora 13 | 14 | install: 15 | - docker build -t bolt-$OS -f ./contrib/Dockerfile-$OS . 16 | 17 | script: 18 | - mkdir build-$OS 19 | - sudo chown $(id -u):root build-$OS 20 | - docker run --cap-drop=dac_override -e -t -v `pwd`:/src -v `pwd`/build-$OS:/build bolt-$OS ./contrib/docker-build.sh 21 | -------------------------------------------------------------------------------- /BUGS.md: -------------------------------------------------------------------------------- 1 | Bugs 2 | ==== 3 | 4 | Bugs are tracked at [fd.o's gitlab][gitlab issues]. 5 | 6 | 7 | Debugging 8 | ========= 9 | 10 | The daemon can be run in verbose mode with the command line option `-v`. 11 | This should normally not be necessary, except when debugging the DBus 12 | layer of boltd (the verbose output is indeed very verbose). 13 | To replace the currently running daemon and run a new instance of it 14 | in the foreground, launch the daemon with `--replace`: 15 | 16 | boltd --replace 17 | 18 | 19 | [gitlab issues]: https://gitlab.freedesktop.org/bolt/bolt/issues 20 | -------------------------------------------------------------------------------- /HACKING.md: -------------------------------------------------------------------------------- 1 | Patches 2 | ======= 3 | 4 | Patches should be submitted in the form of merge requests at 5 | [gitlab][gitlab]. 6 | 7 | 8 | Coding style 9 | ============ 10 | 11 | The style is codified via the supplied `sscripts/uncrustify.cfg` config. 12 | It can be automatically formatted by the `uncrustify` target, i.e. by 13 | invoking `ninja -C uncrustify`. 14 | Make sure to format the source code before submitting pull requests. 15 | 16 | Testing 17 | ======= 18 | 19 | To run the test suite in verbose mode: 20 | 21 | meson test -C build --verbose 22 | 23 | To run `boltd` from within valgrind for the integration tests set the 24 | environment variable `VALGRIND`. A [suppression file][valgrind] can be 25 | specified via that variable as well (n.b. for meson the path must be 26 | relative to the build directory): 27 | 28 | VALGRIND=../bolt.supp meson test -C build --verbose 29 | 30 | Coverage 31 | -------- 32 | 33 | To analyze the current code coverage either `lcov` or `gcovr` need 34 | to be installed. Support must also be enabled during configure time: 35 | 36 | meson -Db_coverage=true 37 | 38 | This should enable the general `coverage` target as well as the 39 | `coverage-{text, html, xml}` targets: 40 | 41 | ninja -C coverage 42 | 43 | To manually invoke `gcovr` and exclude the `cli` directory use: 44 | 45 | gcovr -r -e cli -s 46 | 47 | 48 | Address Sanitizer 49 | ================= 50 | 51 | The Address Sanitizer can be used to detect memory errors, i.e. 52 | memory leaks and undefined behavior. Use `clang` for this, since 53 | there the needed library (`libasan`) is dynamically loaded, 54 | instead of pre-loaded via `LD_PRELOAD` when using `gcc`, which 55 | conflicts with our pre-load needed for `umockdev`. 56 | 57 | env CC=clang meson -Db_sanitize=address,undefined . 58 | ninja -C test 59 | 60 | NB: There might be a warning that `b_lundef` is needed as well. 61 | It seems to work just fine right now without it. 62 | 63 | 64 | Static analysis 65 | =============== 66 | 67 | The clang static analyzer can be run locally via: 68 | 69 | ninja -C scan-build 70 | 71 | Coverity 72 | -------- 73 | 74 | Bolt is registered with [coverity][coverity]. To submit a local build, 75 | execute the following commands (the `cov-build` [build tool][cov-build] 76 | must be in `PATH`) from the source directory: 77 | 78 | CC=gcc CXX=gcc meson -Dcoverity=true coverity 79 | cov-build --dir cov-int ninja -C coverity 80 | tar caf bolt.xz cov-int 81 | 82 | Upload the `bolt.xz` file to coverity for analysis. Fix defects. Profit. 83 | 84 | [gitlab]: https://gitlab.freedesktop.org/bolt/bolt 85 | [coverity]: https://scan.coverity.com/projects/bolt 86 | [cov-build]: https://scan.coverity.com/download 87 | [valgrind]: https://gist.github.com/gicmo/327dad149fcb386ac7f59e279b8ba322 88 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | BUILDING 2 | ======== 3 | 4 | The [meson][meson] build system is used to configure and compile bolt. 5 | 6 | 7 | meson build # configure bolt, use build as buildir 8 | ninja -C build # compile it 9 | ninja -C build test # run the tests 10 | 11 | 12 | NB: `boltd` comes with configuration files for dbus and PolicyKit that 13 | need to be installed to the proper locations. It is probably a good 14 | idea to manually specify them with the correct values for the current 15 | distribution. This can be done by passing the corresponding options 16 | to meson: 17 | 18 | --sysconfdir=/etc 19 | --localstatedir=/var 20 | --sharedstatedir=/var/lib 21 | 22 | 23 | [meson]: http://mesonbuild.com/ 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | bolt 2 | ==== 3 | 4 | Userspace system daemon to enable security levels for *Thunderbolt™* 5 | on GNU/Linux®. 6 | 7 | Introduction 8 | ------------ 9 | 10 | Thunderbolt™ is the brand name of a hardware interface developed by 11 | Intel® that allows the connection of external peripherals to a 12 | computer. 13 | 14 | Devices connected via Thunderbolt can be DMA masters and thus read 15 | system memory without interference of the operating system (or even 16 | the CPU). Version 3 of the interface introduced 5 different security 17 | levels, in order to mitigate the aforementioned security risk that 18 | connected devices pose to the system. The security level is set by the 19 | system firmware. 20 | 21 | The five security levels are: 22 | 23 | * `none`: Security disabled, all devices will fully functional 24 | on connect. 25 | * `dponly`: Only pass the display-port stream through to the 26 | connected device. 27 | * `user`: Connected devices need to be manually authorized by 28 | the user. 29 | * `secure`: As 'user', but also challenge the device with a secret 30 | key to verify its identity. 31 | * `usbonly`: One PCIe tunnel is created to a usb controller in a 32 | thunderbolt dock; no other downstream PCIe tunnels are 33 | authorized (needs 4.17 kernel and recent hardware). 34 | 35 | The Linux kernel, starting with version 4.13, provides an interface via 36 | sysfs that enables userspace query the security level, the status of 37 | connected devices and, most importantly, to authorize devices, if the 38 | security level demands it. 39 | 40 | boltd - the system daemon 41 | ------------------------- 42 | 43 | The core of bolt is a system daemon (`boltd`) that interfaces with 44 | sysfs and exposes devices via D-Bus to clients. It also has a database 45 | of previously authorized devices (and their keys) and will, depending 46 | on the policy set for the individual devices, automatically authorize 47 | newly connected devices without user interaction. The daemon supports 48 | syncing the devices database with the pre-boot access control list 49 | firmware feature. It also adapts its behavior when iommu support is 50 | detected. 51 | 52 | boltctl - command line client 53 | ----------------------------- 54 | The `boltctl` command line can be used to manage thunderbolt devices 55 | via `boltd`. It can list devices, monitor changes and initiate 56 | authorization of devices. 57 | 58 | 59 | Installation 60 | ============ 61 | 62 | The [meson][meson] build system is used to configure and compile bolt. 63 | 64 | 65 | meson build # configure bolt, use build as buildir 66 | ninja -C build # compile it 67 | ninja -C build test # run the tests 68 | 69 | See [INSTALL][install] for more information, [BUGS][bugs] for how to 70 | file issues and [HACKING][hacking] how to contribute. 71 | 72 | 73 | [meson]: http://mesonbuild.com/ 74 | [install]: INSTALL.md 75 | [bugs]: BUGS.md 76 | [hacking]: HACKING.md 77 | -------------------------------------------------------------------------------- /boltd/bolt-auth.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-enums.h" 24 | #include "bolt-key.h" 25 | 26 | #include 27 | 28 | G_BEGIN_DECLS 29 | 30 | /* forward decl because bolt-device.h include bolt-auth.h */ 31 | typedef struct _BoltDevice BoltDevice; 32 | 33 | #define BOLT_TYPE_AUTH bolt_auth_get_type () 34 | G_DECLARE_FINAL_TYPE (BoltAuth, bolt_auth, BOLT, AUTH, GObject); 35 | 36 | BoltAuth * bolt_auth_new (gpointer origin, 37 | BoltSecurity level, 38 | BoltKey *key); 39 | 40 | void bolt_auth_return_new_error (BoltAuth *auth, 41 | GQuark domain, 42 | gint code, 43 | const char *format, 44 | ...) G_GNUC_PRINTF (4, 5); 45 | 46 | void bolt_auth_return_error (BoltAuth *auth, 47 | GError **error); 48 | 49 | gboolean bolt_auth_check (BoltAuth *auth, 50 | GError **error); 51 | 52 | BoltDevice * bolt_auth_get_device (BoltAuth *auth); 53 | 54 | BoltSecurity bolt_auth_get_level (BoltAuth *auth); 55 | 56 | BoltKey * bolt_auth_get_key (BoltAuth *auth); 57 | 58 | BoltKeyState bolt_auth_get_keystate (BoltAuth *auth); 59 | 60 | gboolean bolt_auth_has_key (BoltAuth *auth); 61 | 62 | gpointer bolt_auth_get_origin (BoltAuth *auth); 63 | 64 | BoltPolicy bolt_auth_get_policy (BoltAuth *auth); 65 | 66 | void bolt_auth_set_policy (BoltAuth *auth, 67 | BoltPolicy policy); 68 | 69 | BoltStatus bolt_auth_to_status (BoltAuth *auth); 70 | 71 | BoltAuthFlags bolt_auth_to_flags (BoltAuth *auth, 72 | BoltAuthFlags *mask); 73 | 74 | 75 | G_END_DECLS 76 | -------------------------------------------------------------------------------- /boltd/bolt-bouncer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | #define BOLT_TYPE_BOUNCER bolt_bouncer_get_type () 28 | G_DECLARE_FINAL_TYPE (BoltBouncer, bolt_bouncer, BOLT, BOUNCER, GObject); 29 | 30 | BoltBouncer * bolt_bouncer_new (GCancellable *cancellable, 31 | GError **error); 32 | 33 | void bolt_bouncer_add_client (BoltBouncer *bnc, 34 | gpointer client); 35 | 36 | G_END_DECLS 37 | -------------------------------------------------------------------------------- /boltd/bolt-config.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-enums.h" 24 | #include "bolt-error.h" 25 | #include "bolt-names.h" 26 | 27 | #include "bolt-config.h" 28 | 29 | #define DAEMON_GROUP "config" 30 | #define CFG_VERSION 1 31 | 32 | #define DEFAULT_POLICY_KEY "DefaultPolicy" 33 | #define AUTH_MODE_KEY "AuthMode" 34 | 35 | const char * 36 | bolt_get_store_path (void) 37 | { 38 | const char *path; 39 | 40 | /* set by tools or the user directly */ 41 | path = g_getenv (BOLT_ENV_DBPATH); 42 | if (path != NULL) 43 | return path; 44 | 45 | /* set by systemd >= 240 to an absolute path 46 | * taking into account the StateDirectory 47 | * unit file setting */ 48 | path = g_getenv (BOLT_ENV_STATE_DIRECTORY); 49 | if (path != NULL) 50 | return path; 51 | 52 | /* set at compile time (config.h) */ 53 | return BOLT_DBDIR; 54 | } 55 | 56 | const char * 57 | bolt_get_runtime_directory (void) 58 | { 59 | const char *path; 60 | 61 | path = g_getenv (BOLT_ENV_RUNTIME_DIRECTORY); 62 | if (path) 63 | return path; 64 | 65 | return "/run/boltd"; 66 | } 67 | 68 | GKeyFile * 69 | bolt_config_user_init (void) 70 | { 71 | GKeyFile *cfg; 72 | 73 | cfg = g_key_file_new (); 74 | 75 | g_key_file_set_comment (cfg, NULL, NULL, 76 | " Generated by boltd - do not edit", 77 | NULL); 78 | 79 | g_key_file_set_uint64 (cfg, DAEMON_GROUP, "version", CFG_VERSION); 80 | 81 | return cfg; 82 | } 83 | 84 | BoltTri 85 | bolt_config_load_default_policy (GKeyFile *cfg, 86 | BoltPolicy *policy, 87 | GError **error) 88 | { 89 | g_autoptr(GError) err = NULL; 90 | g_autofree char *str = NULL; 91 | BoltPolicy p; 92 | 93 | g_return_val_if_fail (error == NULL || *error == NULL, TRI_NO); 94 | g_return_val_if_fail (policy != NULL, TRI_NO); 95 | 96 | if (cfg == NULL) 97 | return TRI_NO; 98 | 99 | str = g_key_file_get_string (cfg, DAEMON_GROUP, DEFAULT_POLICY_KEY, &err); 100 | if (str == NULL) 101 | { 102 | int res = bolt_err_notfound (err) ? TRI_NO : TRI_ERROR; 103 | 104 | if (res == TRI_ERROR) 105 | bolt_error_propagate (error, &err); 106 | 107 | return res; 108 | } 109 | 110 | p = bolt_policy_from_string (str); 111 | if (!bolt_policy_validate (p)) 112 | { 113 | g_set_error (error, BOLT_ERROR, BOLT_ERROR_CFG, 114 | "invalid policy: %s", str); 115 | return TRI_ERROR; 116 | } 117 | 118 | *policy = p; 119 | return TRI_YES; 120 | } 121 | 122 | BoltTri 123 | bolt_config_load_auth_mode (GKeyFile *cfg, 124 | BoltAuthMode *authmode, 125 | GError **error) 126 | { 127 | g_autoptr(GError) err = NULL; 128 | g_autofree char *str = NULL; 129 | guint flags = 0; 130 | gboolean ok; 131 | 132 | if (cfg == NULL) 133 | return TRI_NO; 134 | 135 | g_return_val_if_fail (error == NULL || *error == NULL, TRI_NO); 136 | 137 | str = g_key_file_get_string (cfg, DAEMON_GROUP, AUTH_MODE_KEY, &err); 138 | if (str == NULL) 139 | { 140 | int res = bolt_err_notfound (err) ? TRI_NO : TRI_ERROR; 141 | 142 | if (res == TRI_ERROR) 143 | bolt_error_propagate (error, &err); 144 | 145 | return res; 146 | } 147 | 148 | ok = bolt_flags_from_string (BOLT_TYPE_AUTH_MODE, str, &flags, error); 149 | if (!ok) 150 | return TRI_ERROR; 151 | 152 | if (authmode) 153 | *authmode = flags; 154 | 155 | return TRI_YES; 156 | } 157 | 158 | void 159 | bolt_config_set_auth_mode (GKeyFile *cfg, 160 | const char *authmode) 161 | { 162 | g_return_if_fail (cfg != NULL); 163 | 164 | g_key_file_set_string (cfg, DAEMON_GROUP, AUTH_MODE_KEY, authmode); 165 | } 166 | -------------------------------------------------------------------------------- /boltd/bolt-config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | #include "bolt-enums.h" 26 | 27 | G_BEGIN_DECLS 28 | 29 | /* well known paths */ 30 | const char * bolt_get_store_path (void); 31 | 32 | const char * bolt_get_runtime_directory (void); 33 | 34 | /* user and system configuration */ 35 | typedef enum BoltTri { 36 | 37 | TRI_ERROR = -1, 38 | TRI_NO = 0, 39 | TRI_YES = 1, 40 | 41 | } BoltTri; 42 | 43 | GKeyFile * bolt_config_user_init (void); 44 | 45 | 46 | BoltTri bolt_config_load_default_policy (GKeyFile *cfg, 47 | BoltPolicy *policy, 48 | GError **error); 49 | 50 | BoltTri bolt_config_load_auth_mode (GKeyFile *cfg, 51 | BoltAuthMode *authmode, 52 | GError **error); 53 | 54 | void bolt_config_set_auth_mode (GKeyFile *cfg, 55 | const char *authmode); 56 | 57 | G_END_DECLS 58 | -------------------------------------------------------------------------------- /boltd/bolt-device.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-auth.h" 24 | #include "bolt-enums.h" 25 | #include "bolt-exported.h" 26 | 27 | /* forward declaration */ 28 | struct udev_device; 29 | typedef struct _BoltDomain BoltDomain; 30 | 31 | G_BEGIN_DECLS 32 | 33 | #define BOLT_TYPE_DEVICE bolt_device_get_type () 34 | G_DECLARE_FINAL_TYPE (BoltDevice, bolt_device, BOLT, DEVICE, BoltExported); 35 | 36 | BoltDevice * bolt_device_new_for_udev (struct udev_device *udev, 37 | BoltDomain *domain, 38 | GError **error); 39 | 40 | const char * bolt_device_export (BoltDevice *device, 41 | GDBusConnection *connection, 42 | GError **error); 43 | 44 | void bolt_device_unexport (BoltDevice *device); 45 | 46 | BoltStatus bolt_device_connected (BoltDevice *dev, 47 | BoltDomain *domain, 48 | struct udev_device *udev); 49 | 50 | BoltStatus bolt_device_disconnected (BoltDevice *dev); 51 | 52 | gboolean bolt_device_is_connected (BoltDevice *device); 53 | 54 | gboolean bolt_device_is_authorized (BoltDevice *device); 55 | 56 | BoltStatus bolt_device_update_from_udev (BoltDevice *dev, 57 | struct udev_device *udev); 58 | 59 | void bolt_device_authorize (BoltDevice *dev, 60 | BoltAuth *auth, 61 | GAsyncReadyCallback callback, 62 | gpointer user_data); 63 | 64 | void bolt_device_authorize_idle (BoltDevice *dev, 65 | BoltAuth *auth, 66 | GAsyncReadyCallback callback, 67 | gpointer user_data); 68 | 69 | BoltDomain * bolt_device_get_domain (BoltDevice *dev); 70 | 71 | BoltKeyState bolt_device_get_keystate (BoltDevice *dev); 72 | 73 | const char * bolt_device_get_name (BoltDevice *dev); 74 | 75 | const char * bolt_device_get_object_path (BoltDevice *device); 76 | 77 | BoltPolicy bolt_device_get_policy (BoltDevice *dev); 78 | 79 | const char * bolt_device_get_uid (BoltDevice *dev); 80 | 81 | BoltSecurity bolt_device_get_security (BoltDevice *dev); 82 | 83 | gboolean bolt_device_get_stored (BoltDevice *dev); 84 | 85 | BoltStatus bolt_device_get_status (BoltDevice *dev); 86 | 87 | BoltAuthFlags bolt_device_get_authflags (BoltDevice *dev); 88 | 89 | const char * bolt_device_get_syspath (BoltDevice *dev); 90 | 91 | const char * bolt_device_get_vendor (BoltDevice *dev); 92 | 93 | BoltDeviceType bolt_device_get_device_type (BoltDevice *dev); 94 | 95 | gboolean bolt_device_is_host (BoltDevice *dev); 96 | 97 | const char * bolt_device_get_label (BoltDevice *dev); 98 | 99 | guint64 bolt_device_get_authtime (BoltDevice *dev); 100 | 101 | guint64 bolt_device_get_conntime (BoltDevice *dev); 102 | 103 | guint64 bolt_device_get_storetime (BoltDevice *dev); 104 | 105 | guint bolt_device_get_generation (BoltDevice *dev); 106 | 107 | gboolean bolt_device_has_iommu (BoltDevice *dev); 108 | 109 | gboolean bolt_device_has_key (BoltDevice *dev); 110 | 111 | gboolean bolt_device_supports_secure_mode (BoltDevice *dev); 112 | 113 | gboolean bolt_device_check_authflag (BoltDevice *dev, 114 | BoltAuthFlags flag); 115 | 116 | gboolean bolt_device_get_key_from_sysfs (BoltDevice *dev, 117 | BoltKey **key, 118 | GError **error); 119 | gboolean bolt_device_load_key (BoltDevice *dev, 120 | BoltKey **key, 121 | GError **error); 122 | 123 | /* bolt_domain_foreach helpers */ 124 | void bolt_bootacl_add (gpointer domain, 125 | gpointer device); 126 | 127 | void bolt_bootacl_del (gpointer domain, 128 | gpointer device); 129 | 130 | G_END_DECLS 131 | -------------------------------------------------------------------------------- /boltd/bolt-domain.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-enums.h" 24 | #include "bolt-exported.h" 25 | 26 | #include 27 | 28 | G_BEGIN_DECLS 29 | 30 | /* forward declaration */ 31 | struct udev_device; 32 | 33 | #define BOLT_TYPE_DOMAIN bolt_domain_get_type () 34 | G_DECLARE_FINAL_TYPE (BoltDomain, bolt_domain, BOLT, DOMAIN, BoltExported); 35 | 36 | BoltDomain * bolt_domain_new_for_udev (struct udev_device *udev, 37 | const char *uid, 38 | GError **error) G_GNUC_WARN_UNUSED_RESULT; 39 | 40 | const char * bolt_domain_get_uid (BoltDomain *domain); 41 | 42 | const char * bolt_domain_get_id (BoltDomain *domain); 43 | 44 | const char * bolt_domain_get_syspath (BoltDomain *domain); 45 | 46 | BoltSecurity bolt_domain_get_security (BoltDomain *domain); 47 | 48 | GStrv bolt_domain_get_bootacl (BoltDomain *domain); 49 | 50 | GStrv bolt_domain_dup_bootacl (BoltDomain *domain); 51 | 52 | gboolean bolt_domain_is_stored (BoltDomain *domain); 53 | 54 | gboolean bolt_domain_is_connected (BoltDomain *domain); 55 | 56 | gboolean bolt_domain_has_iommu (BoltDomain *domain); 57 | 58 | void bolt_domain_export (BoltDomain *domain, 59 | GDBusConnection *connection); 60 | 61 | void bolt_domain_connected (BoltDomain *domain, 62 | struct udev_device *udev); 63 | 64 | void bolt_domain_disconnected (BoltDomain *domain); 65 | 66 | void bolt_domain_update_from_udev (BoltDomain *domain, 67 | struct udev_device *udev); 68 | 69 | gboolean bolt_domain_can_delete (BoltDomain *domain, 70 | GError **error); 71 | 72 | /* boot acl related functions */ 73 | gboolean bolt_domain_supports_bootacl (BoltDomain *domain); 74 | 75 | guint bolt_domain_bootacl_slots (BoltDomain *domain, 76 | guint *n_free); 77 | 78 | gboolean bolt_domain_bootacl_contains (BoltDomain *domain, 79 | const char *uuid); 80 | 81 | const char ** bolt_domain_bootacl_get_used (BoltDomain *domain, 82 | guint *n_used); 83 | 84 | void bolt_domain_bootacl_allocate (BoltDomain *domain, 85 | GStrv acl, 86 | const char *uuid); 87 | gboolean bolt_domain_bootacl_set (BoltDomain *domain, 88 | GStrv acl, 89 | GError **error); 90 | 91 | gboolean bolt_domain_bootacl_add (BoltDomain *domain, 92 | const char *uuid, 93 | GError **error); 94 | 95 | gboolean bolt_domain_bootacl_del (BoltDomain *domain, 96 | const char *uuid, 97 | GError **error); 98 | /* domain list management */ 99 | BoltDomain * bolt_domain_insert (BoltDomain *list, 100 | BoltDomain *domain) G_GNUC_WARN_UNUSED_RESULT; 101 | 102 | BoltDomain * bolt_domain_remove (BoltDomain *list, 103 | BoltDomain *domain) G_GNUC_WARN_UNUSED_RESULT; 104 | 105 | BoltDomain * bolt_domain_next (BoltDomain *domain); 106 | 107 | BoltDomain * bolt_domain_prev (BoltDomain *domain); 108 | 109 | guint bolt_domain_count (BoltDomain *domain); 110 | 111 | void bolt_domain_foreach (BoltDomain *list, 112 | GFunc func, 113 | gpointer user_data); 114 | 115 | BoltDomain * bolt_domain_find_id (BoltDomain *list, 116 | const char *id, 117 | GError **error); 118 | 119 | void bolt_domain_clear (BoltDomain **list); 120 | 121 | 122 | G_END_DECLS 123 | -------------------------------------------------------------------------------- /boltd/bolt-exported.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | #include 26 | 27 | G_BEGIN_DECLS 28 | 29 | #define BOLT_TYPE_EXPORTED bolt_exported_get_type () 30 | 31 | G_DECLARE_DERIVABLE_TYPE (BoltExported, bolt_exported, BOLT, EXPORTED, GObject); 32 | 33 | typedef struct _BoltExportedClassPrivate BoltExportedClassPrivate; 34 | 35 | struct _BoltExportedClass 36 | { 37 | GObjectClass parent_class; 38 | 39 | /*< private >*/ 40 | BoltExportedClassPrivate *priv; 41 | 42 | /*< public >*/ 43 | 44 | /* Signals */ 45 | gboolean (*authorize_method) (BoltExported *exported, 46 | GDBusMethodInvocation *invocation, 47 | GError **error); 48 | 49 | gboolean (*authorize_property) (BoltExported *exported, 50 | const char *name, 51 | gboolean setting, 52 | GDBusMethodInvocation *invocation, 53 | GError **error); 54 | 55 | /* for the future */ 56 | gpointer padding[10]; 57 | }; 58 | 59 | typedef GVariant * (* BoltExportedMethodHandler) (BoltExported *obj, 60 | GVariant *params, 61 | GDBusMethodInvocation *inv, 62 | GError **error); 63 | 64 | typedef gboolean (* BoltExportedSetter) (BoltExported *obj, 65 | const char *name, 66 | const GValue *value, 67 | GError **error); 68 | 69 | /* class methods */ 70 | void bolt_exported_class_set_interface_name (BoltExportedClass *klass, 71 | const char *name); 72 | 73 | void bolt_exported_class_set_interface_info (BoltExportedClass *klass, 74 | const char *iface_name, 75 | const char *resource_name); 76 | 77 | void bolt_exported_class_set_object_path (BoltExportedClass *klass, 78 | const char *base_path); 79 | 80 | void bolt_exported_class_export_property (BoltExportedClass *klass, 81 | GParamSpec *spec); 82 | 83 | void bolt_exported_class_export_properties (BoltExportedClass *klass, 84 | guint start, 85 | guint n_pspecs, 86 | GParamSpec **specs); 87 | 88 | void bolt_exported_class_property_setter (BoltExportedClass *klass, 89 | GParamSpec *spec, 90 | BoltExportedSetter setter); 91 | 92 | void bolt_exported_class_property_wireconv (BoltExportedClass *klass, 93 | GParamSpec *spec, 94 | const char *custom_id, 95 | BoltConvToWire to_wire, 96 | BoltConvFromWire from_wire); 97 | 98 | void bolt_exported_class_export_method (BoltExportedClass *klass, 99 | const char *name, 100 | BoltExportedMethodHandler handler); 101 | 102 | /* instance methods */ 103 | gboolean bolt_exported_export (BoltExported *exported, 104 | GDBusConnection *connection, 105 | const char *object_path, 106 | GError **error); 107 | 108 | gboolean bolt_exported_unexport (BoltExported *exported); 109 | 110 | gboolean bolt_exported_is_exported (BoltExported *exported); 111 | 112 | GDBusConnection * bolt_exported_get_connection (BoltExported *exported); 113 | 114 | const char * bolt_exported_get_object_path (BoltExported *exported); 115 | 116 | gboolean bolt_exported_emit_signal (BoltExported *exported, 117 | const char *name, 118 | GVariant *parameters, 119 | GError **error); 120 | 121 | void bolt_exported_flush (BoltExported *exported); 122 | 123 | G_END_DECLS 124 | -------------------------------------------------------------------------------- /boltd/bolt-guard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2020 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-enums.h" 24 | #include "bolt-exported.h" 25 | 26 | #include 27 | 28 | G_BEGIN_DECLS 29 | 30 | #define BOLT_TYPE_GUARD bolt_guard_get_type () 31 | G_DECLARE_FINAL_TYPE (BoltGuard, bolt_guard, BOLT, GUARD, GObject); 32 | 33 | int bolt_guard_monitor (BoltGuard *guard, 34 | GError **error); 35 | 36 | const char * bolt_guard_get_id (BoltGuard *guard); 37 | 38 | const char * bolt_guard_get_who (BoltGuard *guard); 39 | 40 | guint bolt_guard_get_pid (BoltGuard *guard); 41 | 42 | const char * bolt_guard_get_path (BoltGuard *guard); 43 | 44 | const char * bolt_guard_get_fifo (BoltGuard *guard); 45 | 46 | GPtrArray * bolt_guard_recover (const char *statedir, 47 | GError **error); 48 | 49 | gboolean bolt_guard_save (BoltGuard *guard, 50 | GFile *guarddir, 51 | GError **error); 52 | 53 | BoltGuard * bolt_guard_load (const char *statedir, 54 | const char *name, 55 | GError **error); 56 | 57 | G_END_DECLS 58 | -------------------------------------------------------------------------------- /boltd/bolt-journal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | #include 26 | 27 | /* BoltJournal - database for devices, keys */ 28 | #define BOLT_TYPE_JOURNAL bolt_journal_get_type () 29 | G_DECLARE_FINAL_TYPE (BoltJournal, bolt_journal, BOLT, JOURNAL, GObject); 30 | 31 | typedef enum BoltJournalOp { 32 | BOLT_JOURNAL_FAILED = -1, 33 | BOLT_JOURNAL_UNCHANGED = '=', 34 | BOLT_JOURNAL_ADDED = '+', 35 | BOLT_JOURNAL_REMOVED = '-', 36 | } BoltJournalOp; 37 | 38 | typedef struct BoltJournalItem 39 | { 40 | char *id; 41 | BoltJournalOp op; 42 | guint64 ts; /* timestamp */ 43 | } BoltJournalItem; 44 | 45 | BoltJournal * bolt_journal_new (GFile *root, 46 | const char *name, 47 | GError **error); 48 | 49 | gboolean bolt_journal_is_fresh (BoltJournal *journal); 50 | 51 | gboolean bolt_journal_put (BoltJournal *journal, 52 | const char *id, 53 | BoltJournalOp op, 54 | GError **error); 55 | 56 | gboolean bolt_journal_put_diff (BoltJournal *journal, 57 | GHashTable *diff, 58 | GError **error); 59 | 60 | GPtrArray * bolt_journal_list (BoltJournal *journal, 61 | GError **error); 62 | 63 | gboolean bolt_journal_reset (BoltJournal *journal, 64 | GError **error); 65 | 66 | /* BoltJournalOp */ 67 | const char * bolt_journal_op_to_string (BoltJournalOp op); 68 | 69 | BoltJournalOp bolt_journal_op_from_string (const char *data, 70 | GError **error); 71 | /* BoltJournalItem */ 72 | void bolt_journal_item_free (BoltJournalItem *entry); 73 | -------------------------------------------------------------------------------- /boltd/bolt-key.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | #include "bolt-enums.h" 26 | 27 | G_BEGIN_DECLS 28 | 29 | /* BoltKey - represents a key to authorize devices with */ 30 | #define BOLT_TYPE_KEY bolt_key_get_type () 31 | G_DECLARE_FINAL_TYPE (BoltKey, bolt_key, BOLT, KEY, GObject); 32 | 33 | #define BOLT_KEY_BYTES 32 34 | #define BOLT_KEY_CHARS 64 35 | 36 | BoltKey * bolt_key_new (GError **error); 37 | 38 | gboolean bolt_key_write_to (BoltKey *key, 39 | int fd, 40 | BoltSecurity *level, 41 | GError **error); 42 | 43 | gboolean bolt_key_save_file (BoltKey *key, 44 | GFile *file, 45 | GError **error); 46 | 47 | BoltKey * bolt_key_load_file (GFile *file, 48 | GError **error); 49 | 50 | BoltKeyState bolt_key_get_state (BoltKey *key); 51 | 52 | G_END_DECLS 53 | -------------------------------------------------------------------------------- /boltd/bolt-manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-exported.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | #define BOLT_TYPE_MANAGER bolt_manager_get_type () 28 | G_DECLARE_FINAL_TYPE (BoltManager, bolt_manager, BOLT, MANAGER, BoltExported); 29 | 30 | gboolean bolt_manager_export (BoltManager *mgr, 31 | GDBusConnection *connection, 32 | GError **error); 33 | 34 | void bolt_manager_got_the_name (BoltManager *mgr); 35 | 36 | G_END_DECLS 37 | -------------------------------------------------------------------------------- /boltd/bolt-power.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-enums.h" 24 | #include "bolt-exported.h" 25 | #include "bolt-guard.h" 26 | #include "bolt-udev.h" 27 | 28 | #include 29 | 30 | G_BEGIN_DECLS 31 | 32 | /* forward declaration */ 33 | struct udev; 34 | 35 | /* BoltPower */ 36 | 37 | #define BOLT_TYPE_POWER bolt_power_get_type () 38 | G_DECLARE_FINAL_TYPE (BoltPower, bolt_power, BOLT, POWER, BoltExported); 39 | 40 | BoltPower * bolt_power_new (BoltUdev *udev); 41 | 42 | GFile * bolt_power_get_statedir (BoltPower *power); 43 | 44 | gboolean bolt_power_can_force (BoltPower *power); 45 | 46 | BoltPowerState bolt_power_get_state (BoltPower *power); 47 | 48 | BoltGuard * bolt_power_acquire_full (BoltPower *power, 49 | const char *who, 50 | pid_t pid, 51 | GError **error); 52 | 53 | BoltGuard * bolt_power_acquire (BoltPower *power, 54 | GError **error); 55 | 56 | GList * bolt_power_list_guards (BoltPower *power); 57 | 58 | G_END_DECLS 59 | -------------------------------------------------------------------------------- /boltd/bolt-reaper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2020 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | 26 | G_BEGIN_DECLS 27 | 28 | #define BOLT_TYPE_REAPER bolt_reaper_get_type () 29 | G_DECLARE_FINAL_TYPE (BoltReaper, bolt_reaper, BOLT, REAPER, GObject); 30 | 31 | BoltReaper * bolt_reaper_new (void); 32 | 33 | void bolt_reaper_add_pid (BoltReaper *reaper, 34 | guint pid, 35 | const char *name); 36 | 37 | gboolean bolt_reaper_del_pid (BoltReaper *reaper, 38 | guint pid); 39 | 40 | gboolean bolt_reaper_has_pid (BoltReaper *reaper, 41 | guint pid); 42 | 43 | G_END_DECLS 44 | -------------------------------------------------------------------------------- /boltd/bolt-sysfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-enums.h" 24 | 25 | #include "bolt-wire.h" 26 | 27 | #include 28 | 29 | struct udev; 30 | struct udev_device; 31 | 32 | G_BEGIN_DECLS 33 | 34 | /* Device identification */ 35 | typedef struct _BoltIdent BoltIdent; 36 | struct _BoltIdent 37 | { 38 | struct udev_device *udev; 39 | 40 | const char *name; 41 | const char *vendor; 42 | }; 43 | 44 | #define BOLT_IDENT_INIT {NULL, NULL, NULL} 45 | 46 | void bolt_ident_clear (BoltIdent *id); 47 | 48 | G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (BoltIdent, bolt_ident_clear); 49 | 50 | const char * bolt_sysfs_device_get_unique_id (struct udev_device *dev, 51 | GError **error); 52 | 53 | typedef enum BoltStatTime { 54 | BOLT_ST_ATIME, 55 | BOLT_ST_CTIME, 56 | BOLT_ST_MTIME 57 | } BoltStatTime; 58 | 59 | gint64 bolt_sysfs_device_get_time (struct udev_device *udev, 60 | BoltStatTime st); 61 | 62 | gboolean bolt_sysfs_device_is_domain (struct udev_device *udev, 63 | GError **error); 64 | 65 | struct udev_device * bolt_sysfs_domain_for_device (struct udev_device *udev, 66 | struct udev_device **host); 67 | 68 | BoltSecurity bolt_sysfs_security_for_device (struct udev_device *udev, 69 | GError **error); 70 | 71 | gboolean bolt_sysfs_device_ident (struct udev_device *udev, 72 | BoltIdent *id, 73 | GError **error); 74 | 75 | gboolean bolt_sysfs_host_ident (struct udev_device *udev, 76 | BoltIdent *id, 77 | GError **error); 78 | 79 | int bolt_sysfs_count_hosts (struct udev *udev, 80 | GError **error); 81 | 82 | gboolean bolt_sysfs_nhi_id_for_domain (struct udev_device *udev, 83 | guint32 *id, 84 | GError **error); 85 | 86 | typedef struct _BoltDevInfo 87 | { 88 | 89 | /* always included */ 90 | gint authorized; 91 | gssize keysize; 92 | gint boot; 93 | 94 | /* if 'full' is true the rest is valid */ 95 | gboolean full; 96 | gint64 ctim; 97 | const char *syspath; 98 | const char *parent; /* the uid */ 99 | guint generation; 100 | 101 | /* link speed, may be 0 if unknown */ 102 | BoltLinkSpeed linkspeed; 103 | 104 | } BoltDevInfo; 105 | 106 | gboolean bolt_sysfs_info_for_device (struct udev_device *udev, 107 | gboolean full, 108 | BoltDevInfo *info, 109 | GError **error); 110 | 111 | void bolt_sysfs_read_link_speed (struct udev_device *udev, 112 | BoltLinkSpeed *speed); 113 | 114 | gboolean bolt_sysfs_read_boot_acl (struct udev_device *udev, 115 | GStrv *out, 116 | GError **error); 117 | 118 | gboolean bolt_sysfs_write_boot_acl (const char *device, 119 | GStrv acl, 120 | GError **error); 121 | 122 | gboolean bolt_sysfs_read_iommu (struct udev_device *udev, 123 | gboolean *out, 124 | GError **error); 125 | 126 | /* NHI id related functions*/ 127 | gboolean bolt_nhi_uuid_is_stable (guint32 pci_id, 128 | gboolean *stability, 129 | GError **error); 130 | 131 | G_END_DECLS 132 | -------------------------------------------------------------------------------- /boltd/bolt-udev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | /* forward declaration */ 28 | struct udev; 29 | struct udev_device; 30 | struct udev_enumerate; 31 | 32 | /* BoltUdev - small udev abstraction */ 33 | #define BOLT_TYPE_UDEV bolt_udev_get_type () 34 | G_DECLARE_FINAL_TYPE (BoltUdev, bolt_udev, BOLT, UDEV, GObject); 35 | 36 | BoltUdev * bolt_udev_new (const char *name, 37 | const char * const *filter, 38 | GError **error); 39 | 40 | struct udev_enumerate * bolt_udev_new_enumerate (BoltUdev *udev, 41 | GError **error); 42 | 43 | struct udev_device * bolt_udev_device_new_from_syspath (BoltUdev *udev, 44 | const char *syspath, 45 | GError **error); 46 | 47 | /* thunderbolt specific helpers */ 48 | int bolt_udev_count_hosts (BoltUdev *udev, 49 | GError **error); 50 | 51 | gboolean bolt_udev_detect_force_power (BoltUdev *udev, 52 | char **path, 53 | GError **error); 54 | G_END_DECLS 55 | -------------------------------------------------------------------------------- /boltd/bolt-watchdog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | /* BoltWatchdog - Idle and status tracking */ 28 | 29 | #define BOLT_TYPE_WATCHDOG bolt_watchdog_get_type () 30 | G_DECLARE_FINAL_TYPE (BoltWatchdog, bolt_watchdog, BOLT, WATCHDOG, GObject); 31 | 32 | BoltWatchdog * bolt_watchdog_new (GError **error); 33 | 34 | G_END_DECLS 35 | -------------------------------------------------------------------------------- /cli/bolt-device.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-enums.h" 24 | #include "bolt-proxy.h" 25 | #include "bolt-wire.h" 26 | 27 | G_BEGIN_DECLS 28 | 29 | #define BOLT_TYPE_DEVICE bolt_device_get_type () 30 | G_DECLARE_FINAL_TYPE (BoltDevice, bolt_device, BOLT, DEVICE, BoltProxy); 31 | 32 | BoltDevice * bolt_device_new_for_object_path (GDBusConnection *bus, 33 | const char *path, 34 | GCancellable *cancellable, 35 | GError **error); 36 | 37 | gboolean bolt_device_authorize (BoltDevice *dev, 38 | BoltAuthCtrl flags, 39 | GCancellable *cancellable, 40 | GError **error); 41 | 42 | void bolt_device_authorize_async (BoltDevice *dev, 43 | BoltAuthCtrl flags, 44 | GCancellable *cancellable, 45 | GAsyncReadyCallback callback, 46 | gpointer user_data); 47 | 48 | gboolean bolt_device_authorize_finish (BoltDevice *dev, 49 | GAsyncResult *res, 50 | GError **error); 51 | 52 | /* getter */ 53 | const char * bolt_device_get_uid (BoltDevice *dev); 54 | 55 | const char * bolt_device_get_name (BoltDevice *dev); 56 | 57 | const char * bolt_device_get_vendor (BoltDevice *dev); 58 | 59 | guint bolt_device_get_generation (BoltDevice *dev); 60 | 61 | BoltDeviceType bolt_device_get_device_type (BoltDevice *dev); 62 | 63 | gboolean bolt_device_is_host (BoltDevice *dev); 64 | 65 | BoltStatus bolt_device_get_status (BoltDevice *dev); 66 | 67 | BoltAuthFlags bolt_device_get_authflags (BoltDevice *dev); 68 | 69 | const char * bolt_device_get_parent (BoltDevice *dev); 70 | 71 | const char * bolt_device_get_syspath (BoltDevice *dev); 72 | 73 | const char * bolt_device_get_domain (BoltDevice *dev); 74 | 75 | guint64 bolt_device_get_conntime (BoltDevice *dev); 76 | 77 | guint64 bolt_device_get_authtime (BoltDevice *dev); 78 | 79 | void bolt_device_get_linkspeed (BoltDevice *dev, 80 | BoltLinkSpeed *speed); 81 | 82 | gboolean bolt_device_is_stored (BoltDevice *dev); 83 | 84 | BoltPolicy bolt_device_get_policy (BoltDevice *dev); 85 | 86 | BoltKeyState bolt_device_get_keystate (BoltDevice *dev); 87 | 88 | guint64 bolt_device_get_storetime (BoltDevice *dev); 89 | 90 | const char * bolt_device_get_label (BoltDevice *dev); 91 | 92 | /* derived getter */ 93 | char * bolt_device_get_display_name (BoltDevice *dev); 94 | 95 | guint64 bolt_device_get_timestamp (BoltDevice *dev); 96 | 97 | G_END_DECLS 98 | -------------------------------------------------------------------------------- /cli/bolt-domain.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-enums.h" 24 | #include "bolt-proxy.h" 25 | 26 | G_BEGIN_DECLS 27 | 28 | #define BOLT_TYPE_DOMAIN bolt_domain_get_type () 29 | G_DECLARE_FINAL_TYPE (BoltDomain, bolt_domain, BOLT, DOMAIN, BoltProxy); 30 | 31 | 32 | BoltDomain * bolt_domain_new_for_object_path (GDBusConnection *bus, 33 | const char *path, 34 | GCancellable *cancellable, 35 | GError **error); 36 | /* getter */ 37 | const char * bolt_domain_get_uid (BoltDomain *domain); 38 | 39 | const char * bolt_domain_get_id (BoltDomain *domain); 40 | 41 | const char * bolt_domain_get_syspath (BoltDomain *domain); 42 | 43 | BoltSecurity bolt_domain_get_security (BoltDomain *domain); 44 | 45 | char ** bolt_domain_get_bootacl (BoltDomain *domain); 46 | 47 | gboolean bolt_domain_is_online (BoltDomain *domain); 48 | 49 | gboolean bolt_domain_has_iommu (BoltDomain *domain); 50 | 51 | G_END_DECLS 52 | -------------------------------------------------------------------------------- /cli/bolt-power.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-enums.h" 24 | #include "bolt-proxy.h" 25 | 26 | G_BEGIN_DECLS 27 | 28 | #define BOLT_TYPE_POWER bolt_power_get_type () 29 | G_DECLARE_FINAL_TYPE (BoltPower, bolt_power, BOLT, POWER, BoltProxy); 30 | 31 | 32 | BoltPower * bolt_power_new_for_object_path (GDBusConnection *bus, 33 | GCancellable *cancellable, 34 | GError **error); 35 | 36 | /* methods */ 37 | 38 | int bolt_power_force_power (BoltPower *power, 39 | GError **error); 40 | 41 | GPtrArray * bolt_power_list_guards (BoltPower *power, 42 | GCancellable *cancellable, 43 | GError **error); 44 | 45 | /* getter */ 46 | gboolean bolt_power_is_supported (BoltPower *power); 47 | 48 | BoltPowerState bolt_power_get_state (BoltPower *power); 49 | 50 | /* */ 51 | 52 | typedef struct BoltPowerGuard_ 53 | { 54 | char *id; 55 | char *who; 56 | guint pid; 57 | } BoltPowerGuard; 58 | 59 | void bolt_power_guard_free (BoltPowerGuard *guard); 60 | 61 | 62 | G_END_DECLS 63 | -------------------------------------------------------------------------------- /cli/boltctl-authorize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "boltctl-cmds.h" 24 | 25 | #include "bolt-error.h" 26 | #include "bolt-str.h" 27 | 28 | #include 29 | 30 | typedef struct AuthorizeAllData 31 | { 32 | GMainLoop *loop; 33 | gboolean done; 34 | gboolean res; 35 | 36 | GError **error; 37 | } AuthorizeAllData; 38 | 39 | static void 40 | authorize_all_done (GObject *source, 41 | GAsyncResult *res, 42 | gpointer user_data) 43 | { 44 | AuthorizeAllData *data = (AuthorizeAllData *) user_data; 45 | gboolean ok; 46 | 47 | ok = bolt_client_authorize_all_finish (BOLT_CLIENT (source), 48 | res, 49 | data->error); 50 | 51 | data->res = ok; 52 | data->done = TRUE; 53 | 54 | g_main_loop_quit (data->loop); 55 | } 56 | 57 | static gboolean 58 | authorize_all (BoltClient *client, 59 | const char *uid, 60 | BoltAuthCtrl flags, 61 | GError **error) 62 | { 63 | g_autoptr(BoltDevice) target = NULL; 64 | g_autoptr(GPtrArray) parents = NULL; 65 | g_autoptr(GPtrArray) uuids = NULL; 66 | g_autoptr(GMainLoop) loop = NULL; 67 | g_autoptr(GError) err = NULL; 68 | AuthorizeAllData data; 69 | 70 | target = bolt_client_get_device (client, 71 | uid, 72 | NULL, 73 | &err); 74 | 75 | if (target == NULL) 76 | { 77 | g_printerr ("Could not look up target: %s\n", 78 | err->message); 79 | return EXIT_FAILURE; 80 | } 81 | 82 | parents = bolt_client_list_parents (client, target, NULL, &err); 83 | if (parents == NULL) 84 | { 85 | g_printerr ("Could not look up parents: %s\n", 86 | err->message); 87 | return EXIT_FAILURE; 88 | } 89 | 90 | uuids = g_ptr_array_new_full (parents->len, NULL); 91 | 92 | /* reverse order, starting from the root! */ 93 | for (guint i = parents->len; i > 0; i--) 94 | { 95 | BoltDevice *dev = g_ptr_array_index (parents, i - 1); 96 | const char *id = bolt_device_get_uid (dev); 97 | BoltStatus status = bolt_device_get_status (dev); 98 | 99 | if (!bolt_status_is_pending (status)) 100 | continue; 101 | 102 | g_ptr_array_add (uuids, (gpointer) id); 103 | } 104 | 105 | /* the target itself */ 106 | g_ptr_array_add (uuids, (gpointer) uid); 107 | 108 | loop = g_main_loop_new (NULL, FALSE); 109 | data.loop = loop; 110 | data.done = FALSE; 111 | data.error = error; 112 | 113 | bolt_client_authorize_all_async (client, 114 | uuids, 115 | flags, 116 | NULL, 117 | authorize_all_done, 118 | &data); 119 | 120 | if (data.done == FALSE) 121 | g_main_loop_run (loop); 122 | 123 | return data.res; 124 | } 125 | 126 | 127 | int 128 | authorize (BoltClient *client, int argc, char **argv) 129 | { 130 | g_autoptr(GOptionContext) optctx = NULL; 131 | g_autoptr(BoltDevice) dev = NULL; 132 | g_autoptr(GError) error = NULL; 133 | BoltAuthCtrl flags = BOLT_AUTHCTRL_NONE; 134 | BoltStatus status; 135 | const char *uid; 136 | gboolean ok; 137 | gboolean first_time = FALSE; 138 | gboolean chain_arg = FALSE; 139 | GOptionEntry options[] = { 140 | { "first-time", 'F', 0, G_OPTION_ARG_NONE, &first_time, "Fail if device is already authorized", NULL }, 141 | { "chain", 0, 0, G_OPTION_ARG_NONE, &chain_arg, "Authorize parent devices if necessary" }, 142 | { NULL } 143 | }; 144 | 145 | optctx = g_option_context_new ("DEVICE - Authorize a device"); 146 | g_option_context_add_main_entries (optctx, options, NULL); 147 | 148 | if (!g_option_context_parse (optctx, &argc, &argv, &error)) 149 | return usage_error (error); 150 | 151 | if (argc < 2) 152 | return usage_error_need_arg ("DEVICE"); 153 | 154 | uid = argv[1]; 155 | 156 | dev = bolt_client_get_device (client, uid, NULL, &error); 157 | if (dev == NULL) 158 | { 159 | g_printerr ("%s\n", error->message); 160 | return EXIT_FAILURE; 161 | } 162 | 163 | status = bolt_device_get_status (dev); 164 | 165 | if (chain_arg) 166 | ok = authorize_all (client, uid, flags, &error); 167 | else 168 | ok = bolt_device_authorize (dev, flags, NULL, &error); 169 | 170 | if (!ok) 171 | { 172 | if (bolt_err_badstate (error) && 173 | bolt_status_is_authorized (status) && 174 | !first_time) 175 | ok = TRUE; 176 | else 177 | g_printerr ("Authorization error: %s\n", error->message); 178 | } 179 | 180 | return ok ? EXIT_SUCCESS : EXIT_FAILURE; 181 | } 182 | -------------------------------------------------------------------------------- /cli/boltctl-cmds.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "boltctl.h" 24 | 25 | G_BEGIN_DECLS 26 | 27 | typedef int (*BoltctlCommand) (BoltClient *client, 28 | int argc, 29 | char **argv); 30 | 31 | int authorize (BoltClient *client, 32 | int argc, 33 | char **argv); 34 | int config (BoltClient *client, 35 | int argc, 36 | char **argv); 37 | int enroll (BoltClient *client, 38 | int argc, 39 | char **argv); 40 | int forget (BoltClient *client, 41 | int argc, 42 | char **argv); 43 | int info (BoltClient *client, 44 | int argc, 45 | char **argv); 46 | int list_devices (BoltClient *client, 47 | int argc, 48 | char **argv); 49 | int list_domains (BoltClient *client, 50 | int argc, 51 | char **argv); 52 | int monitor (BoltClient *client, 53 | int argc, 54 | char **argv); 55 | int power (BoltClient *client, 56 | int argc, 57 | char **argv); 58 | 59 | G_END_DECLS 60 | -------------------------------------------------------------------------------- /cli/boltctl-domains.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "boltctl-cmds.h" 24 | #include "boltctl-uidfmt.h" 25 | 26 | #include "bolt-str.h" 27 | 28 | #include 29 | 30 | /* domain related commands */ 31 | static void 32 | print_domain (BoltDomain *domain, gboolean verbose) 33 | { 34 | g_auto(GStrv) bootacl = NULL; 35 | const char *tree_branch; 36 | const char *tree_right; 37 | const char *tree_cont; 38 | const char *tree_space; 39 | const char *uid; 40 | const char *name; 41 | const char *syspath; 42 | const char *security; 43 | BoltSecurity sl; 44 | gboolean online; 45 | gboolean iommu; 46 | 47 | tree_branch = bolt_glyph (TREE_BRANCH); 48 | tree_right = bolt_glyph (TREE_RIGHT); 49 | tree_cont = bolt_glyph (TREE_VERTICAL); 50 | tree_space = bolt_glyph (TREE_SPACE); 51 | 52 | uid = bolt_domain_get_uid (domain); 53 | name = bolt_domain_get_id (domain); 54 | sl = bolt_domain_get_security (domain); 55 | 56 | syspath = bolt_domain_get_syspath (domain); 57 | security = bolt_security_to_string (sl); 58 | bootacl = bolt_domain_get_bootacl (domain); 59 | online = syspath != NULL; 60 | 61 | if (online) 62 | { 63 | g_print (" %s%s%s ", 64 | bolt_color (ANSI_GREEN), 65 | bolt_glyph (BLACK_CIRCLE), 66 | bolt_color (ANSI_NORMAL)); 67 | } 68 | else 69 | { 70 | g_print (" %s ", bolt_glyph (WHITE_CIRCLE)); 71 | } 72 | 73 | g_print ("%s %s", (name ? : "domain"), format_uid (uid)); 74 | g_print ("\n"); 75 | 76 | if (verbose) 77 | g_print (" %s online: %s\n", tree_branch, bolt_yesno (online)); 78 | 79 | if (verbose && syspath != NULL) 80 | g_print (" %s syspath: %s\n", tree_branch, syspath); 81 | 82 | if (bootacl) 83 | { 84 | guint acl_max = g_strv_length ((char **) bootacl); 85 | guint used = 0; 86 | guint i; 87 | 88 | for (i = 0; i < acl_max; i++) 89 | if (!bolt_strzero (bootacl[i])) 90 | used++; 91 | 92 | g_print (" %s bootacl: %u/%u\n", tree_branch, used, acl_max); 93 | 94 | for (i = 0; i < acl_max; i++) 95 | { 96 | const char *tree_sym = used > 1 ? tree_branch : tree_right; 97 | 98 | if (bolt_strzero (bootacl[i])) 99 | continue; 100 | 101 | g_print (" %s %s[%u]", tree_cont, tree_sym, i); 102 | g_print (" %s\n", format_uid (bootacl[i])); 103 | used--; 104 | } 105 | } 106 | 107 | iommu = bolt_domain_has_iommu (domain); 108 | 109 | g_print (" %s security: ", tree_right); 110 | 111 | if (bolt_security_is_interactive (sl) && iommu) 112 | g_print ("iommu+%s", security); 113 | else if (bolt_security_allows_pcie (sl) && iommu) 114 | g_print ("iommu"); 115 | else 116 | g_print ("%s", security); 117 | 118 | g_print ("\n"); 119 | 120 | if (verbose) 121 | { 122 | g_print (" %s %s iommu: %s\n", tree_space, tree_branch, 123 | bolt_yesno (iommu)); 124 | 125 | g_print (" %s %s level: %s\n", tree_space, tree_right, 126 | security); 127 | 128 | } 129 | 130 | g_print ("\n"); 131 | } 132 | 133 | int 134 | list_domains (BoltClient *client, int argc, char **argv) 135 | { 136 | g_autoptr(GOptionContext) optctx = NULL; 137 | g_autoptr(GError) err = NULL; 138 | g_autoptr(GPtrArray) domains = NULL; 139 | gboolean details = FALSE; 140 | GOptionEntry options[] = { 141 | { "verbose", 'v', 0, G_OPTION_ARG_NONE, &details, "Show more details", NULL }, 142 | { NULL } 143 | }; 144 | 145 | optctx = g_option_context_new ("- List thunderbolt domains"); 146 | g_option_context_add_main_entries (optctx, options, NULL); 147 | 148 | if (!g_option_context_parse (optctx, &argc, &argv, &err)) 149 | return usage_error (err); 150 | 151 | domains = bolt_client_list_domains (client, NULL, &err); 152 | 153 | if (domains == NULL) 154 | { 155 | g_warning ("Could not list domains: %s", err->message); 156 | domains = g_ptr_array_new_with_free_func (g_object_unref); 157 | } 158 | 159 | for (guint i = 0; i < domains->len; i++) 160 | { 161 | BoltDomain *dom = g_ptr_array_index (domains, i); 162 | print_domain (dom, details); 163 | } 164 | 165 | return EXIT_SUCCESS; 166 | } 167 | -------------------------------------------------------------------------------- /cli/boltctl-enroll.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "boltctl-cmds.h" 24 | 25 | #include "bolt-str.h" 26 | 27 | #include 28 | 29 | typedef struct EnrollAllData 30 | { 31 | GMainLoop *loop; 32 | gboolean done; 33 | gboolean res; 34 | } EnrollAllData; 35 | 36 | static void 37 | enroll_all_done (GObject *source, 38 | GAsyncResult *res, 39 | gpointer user_data) 40 | { 41 | g_autoptr(GError) err = NULL; 42 | EnrollAllData *data = (EnrollAllData *) user_data; 43 | gboolean ok; 44 | 45 | ok = bolt_client_enroll_all_finish (BOLT_CLIENT (source), res, &err); 46 | 47 | if (!ok) 48 | g_printerr ("Could not enroll all devices: %s\n", err->message); 49 | 50 | data->done = TRUE; 51 | data->res = ok; 52 | g_main_loop_quit (data->loop); 53 | } 54 | 55 | static int 56 | enroll_all (BoltClient *client, 57 | const char *uid, 58 | BoltPolicy policy, 59 | BoltAuthCtrl flags) 60 | { 61 | g_autoptr(BoltDevice) target = NULL; 62 | g_autoptr(GPtrArray) parents = NULL; 63 | g_autoptr(GPtrArray) uuids = NULL; 64 | g_autoptr(GMainLoop) loop = NULL; 65 | g_autoptr(GError) err = NULL; 66 | EnrollAllData data; 67 | 68 | target = bolt_client_get_device (client, 69 | uid, 70 | NULL, 71 | &err); 72 | 73 | if (target == NULL) 74 | { 75 | g_printerr ("Could not look up target: %s\n", 76 | err->message); 77 | return EXIT_FAILURE; 78 | } 79 | 80 | parents = bolt_client_list_parents (client, target, NULL, &err); 81 | if (parents == NULL) 82 | { 83 | g_printerr ("Could not look up parents: %s\n", 84 | err->message); 85 | return EXIT_FAILURE; 86 | } 87 | 88 | uuids = g_ptr_array_new_full (parents->len, NULL); 89 | 90 | /* reverse order, starting from the root! */ 91 | for (guint i = parents->len; i > 0; i--) 92 | { 93 | BoltDevice *dev = g_ptr_array_index (parents, i - 1); 94 | const char *id = bolt_device_get_uid (dev); 95 | 96 | if (bolt_device_is_stored (dev) || 97 | bolt_device_is_host (dev)) 98 | continue; 99 | 100 | g_ptr_array_add (uuids, (gpointer) id); 101 | } 102 | 103 | /* the target itself */ 104 | g_ptr_array_add (uuids, (gpointer) uid); 105 | 106 | loop = g_main_loop_new (NULL, FALSE); 107 | data.loop = loop; 108 | data.done = FALSE; 109 | 110 | bolt_client_enroll_all_async (client, 111 | uuids, 112 | policy, 113 | flags, 114 | NULL, 115 | enroll_all_done, 116 | &data); 117 | 118 | if (data.done == FALSE) 119 | g_main_loop_run (loop); 120 | 121 | return data.res ? EXIT_SUCCESS : EXIT_FAILURE; 122 | } 123 | 124 | int 125 | enroll (BoltClient *client, int argc, char **argv) 126 | { 127 | g_autoptr(GOptionContext) optctx = NULL; 128 | g_autoptr(BoltDevice) dev = NULL; 129 | g_autoptr(GError) error = NULL; 130 | const char *uid; 131 | BoltPolicy policy = BOLT_POLICY_DEFAULT; 132 | BoltAuthCtrl flags = BOLT_AUTHCTRL_NONE; 133 | const char *policy_arg = "default"; 134 | gboolean chain_arg = FALSE; 135 | GOptionEntry options[] = { 136 | { "policy", 0, 0, G_OPTION_ARG_STRING, &policy_arg, "Policy for the device; one of {auto, manual, *default}", "POLICY" }, 137 | { "chain", 0, 0, G_OPTION_ARG_NONE, &chain_arg, "Authorize parent devices if necessary" }, 138 | { NULL } 139 | }; 140 | 141 | optctx = g_option_context_new ("DEVICE - Authorize and store a device in the database"); 142 | g_option_context_add_main_entries (optctx, options, NULL); 143 | 144 | if (!g_option_context_parse (optctx, &argc, &argv, &error)) 145 | return usage_error (error); 146 | 147 | if (argc < 2) 148 | return usage_error_need_arg ("DEVICE"); 149 | 150 | policy = bolt_policy_from_string (policy_arg); 151 | 152 | if (!bolt_policy_validate (policy)) 153 | { 154 | g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, 155 | "invalid policy '%s'", policy_arg); 156 | return usage_error (error); 157 | } 158 | 159 | uid = argv[1]; 160 | 161 | if (chain_arg) 162 | return enroll_all (client, uid, policy, flags); 163 | 164 | 165 | dev = bolt_client_enroll_device (client, uid, policy, flags, &error); 166 | if (dev == NULL) 167 | { 168 | g_printerr ("%s\n", error->message); 169 | return EXIT_FAILURE; 170 | } 171 | 172 | print_device (dev, TRUE); 173 | return EXIT_SUCCESS; 174 | } 175 | -------------------------------------------------------------------------------- /cli/boltctl-forget.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "boltctl-cmds.h" 24 | 25 | #include "bolt-str.h" 26 | 27 | #include 28 | 29 | int 30 | forget (BoltClient *client, int argc, char **argv) 31 | { 32 | g_autoptr(GOptionContext) optctx = NULL; 33 | g_autoptr(GError) error = NULL; 34 | const char *uid; 35 | gboolean ok, forget_all = FALSE; 36 | GOptionEntry options[] = { 37 | { "all", 'a', 0, G_OPTION_ARG_NONE, &forget_all, "Forget all devices", NULL }, 38 | { NULL } 39 | }; 40 | 41 | optctx = g_option_context_new ("DEVICE - Remove a device from the store"); 42 | g_option_context_add_main_entries (optctx, options, NULL); 43 | 44 | if (!g_option_context_parse (optctx, &argc, &argv, &error)) 45 | return usage_error (error); 46 | 47 | if (forget_all) 48 | { 49 | g_autoptr(GPtrArray) devices = NULL; 50 | 51 | ok = check_argc (argc, 0, 0, &error); 52 | if (!ok) 53 | return usage_error (error); 54 | 55 | devices = bolt_client_list_devices (client, NULL, &error); 56 | if (devices == NULL) 57 | { 58 | g_printerr ("Failed to list devices: %s", 59 | error->message); 60 | return EXIT_FAILURE; 61 | } 62 | 63 | for (guint i = 0; i < devices->len; i++) 64 | { 65 | BoltDevice *dev = g_ptr_array_index (devices, i); 66 | 67 | if (!bolt_device_is_stored (dev)) 68 | continue; 69 | 70 | uid = bolt_device_get_uid (dev); 71 | ok = bolt_client_forget_device (client, uid, &error); 72 | if (!ok) 73 | { 74 | g_printerr ("Failed to forget device: %s\n", error->message); 75 | return EXIT_FAILURE; 76 | } 77 | } 78 | } 79 | else 80 | { 81 | if (argc < 2) 82 | return usage_error_need_arg ("DEVICE"); 83 | uid = argv[1]; 84 | ok = bolt_client_forget_device (client, uid, &error); 85 | if (!ok) 86 | { 87 | g_printerr ("Failed to forget device: %s\n", error->message); 88 | return EXIT_FAILURE; 89 | } 90 | } 91 | 92 | return EXIT_SUCCESS; 93 | } 94 | -------------------------------------------------------------------------------- /cli/boltctl-info.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "boltctl-cmds.h" 24 | 25 | #include "bolt-str.h" 26 | 27 | #include 28 | 29 | int 30 | info (BoltClient *client, int argc, char **argv) 31 | { 32 | g_autoptr(GOptionContext) optctx = NULL; 33 | g_autoptr(BoltDevice) dev = NULL; 34 | g_autoptr(GError) error = NULL; 35 | const char *uid; 36 | 37 | optctx = g_option_context_new ("DEVICE - Show information about a device"); 38 | 39 | if (!g_option_context_parse (optctx, &argc, &argv, &error)) 40 | return usage_error (error); 41 | 42 | if (argc < 2) 43 | return usage_error_need_arg ("DEVICE"); 44 | 45 | uid = argv[1]; 46 | 47 | dev = bolt_client_get_device (client, uid, NULL, &error); 48 | if (dev == NULL) 49 | { 50 | g_printerr ("%s\n", error->message); 51 | return EXIT_FAILURE; 52 | } 53 | 54 | print_device (dev, TRUE); 55 | return EXIT_SUCCESS; 56 | } 57 | -------------------------------------------------------------------------------- /cli/boltctl-list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "boltctl-cmds.h" 24 | 25 | #include "bolt-str.h" 26 | 27 | #include 28 | 29 | int 30 | list_devices (BoltClient *client, int argc, char **argv) 31 | { 32 | g_autoptr(GOptionContext) optctx = NULL; 33 | g_autoptr(GError) error = NULL; 34 | g_autoptr(GPtrArray) devices = NULL; 35 | gboolean show_all = FALSE; 36 | GOptionEntry options[] = { 37 | { "all", 'a', 0, G_OPTION_ARG_NONE, &show_all, "Show all devices", NULL }, 38 | { NULL } 39 | }; 40 | 41 | optctx = g_option_context_new ("- List thunderbolt devices"); 42 | g_option_context_add_main_entries (optctx, options, NULL); 43 | 44 | if (!g_option_context_parse (optctx, &argc, &argv, &error)) 45 | return usage_error (error); 46 | 47 | devices = bolt_client_list_devices (client, NULL, &error); 48 | if (devices == NULL) 49 | { 50 | g_printerr ("Failed to list devices: %s", 51 | error->message); 52 | return EXIT_FAILURE; 53 | } 54 | 55 | bolt_devices_sort_by_syspath (devices, FALSE); 56 | for (guint i = 0; i < devices->len; i++) 57 | { 58 | BoltDevice *dev = g_ptr_array_index (devices, i); 59 | BoltDeviceType type; 60 | 61 | if (!show_all) 62 | { 63 | type = bolt_device_get_device_type (dev); 64 | if (type != BOLT_DEVICE_PERIPHERAL) 65 | continue; 66 | } 67 | 68 | print_device (dev, FALSE); 69 | } 70 | 71 | return EXIT_SUCCESS; 72 | } 73 | -------------------------------------------------------------------------------- /cli/boltctl-power.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "boltctl-cmds.h" 24 | 25 | #include "bolt-str.h" 26 | 27 | #include 28 | 29 | static gboolean 30 | quit_main_loop (gpointer user_data) 31 | { 32 | GMainLoop *loop = user_data; 33 | 34 | g_main_loop_quit (loop); 35 | return FALSE; 36 | } 37 | 38 | int 39 | power (BoltClient *client, int argc, char **argv) 40 | { 41 | g_autoptr(GOptionContext) optctx = NULL; 42 | g_autoptr(GMainLoop) main_loop = NULL; 43 | g_autoptr(BoltPower) power = NULL; 44 | g_autoptr(GError) error = NULL; 45 | BoltPowerState state; 46 | gboolean do_query = FALSE; 47 | int fd; 48 | double timeout = 0; 49 | GOptionEntry options[] = { 50 | { "query", 'q', 0, G_OPTION_ARG_NONE, &do_query, "Query the status", NULL }, 51 | { "timeout", 't', 0, G_OPTION_ARG_DOUBLE, &timeout, "Quit after N seconds", NULL }, 52 | { NULL } 53 | }; 54 | 55 | optctx = g_option_context_new ("- Force power configuration"); 56 | g_option_context_add_main_entries (optctx, options, NULL); 57 | 58 | if (!g_option_context_parse (optctx, &argc, &argv, &error)) 59 | return usage_error (error); 60 | 61 | power = bolt_client_new_power_client (client, NULL, &error); 62 | 63 | if (power == NULL) 64 | { 65 | g_warning ("Could get proxy for power interface: %s", 66 | error->message); 67 | return EXIT_FAILURE; 68 | } 69 | 70 | if (do_query) 71 | { 72 | g_autoptr(GPtrArray) guards = NULL; 73 | const char *tree_branch; 74 | const char *tree_right; 75 | const char *str; 76 | gboolean supported; 77 | 78 | supported = bolt_power_is_supported (power); 79 | g_print ("supported: %s\n", bolt_yesno (supported)); 80 | 81 | if (!supported) 82 | return EXIT_SUCCESS; 83 | 84 | state = bolt_power_get_state (power); 85 | str = bolt_power_state_to_string (state); 86 | g_print ("power state: %s\n", str); 87 | 88 | guards = bolt_power_list_guards (power, NULL, &error); 89 | 90 | if (guards == NULL) 91 | { 92 | g_warning ("Could not list guards: %s", error->message); 93 | return EXIT_FAILURE; 94 | } 95 | 96 | tree_branch = bolt_glyph (TREE_BRANCH); 97 | tree_right = bolt_glyph (TREE_RIGHT); 98 | 99 | g_print ("%u active power guards%s\n", guards->len, 100 | guards->len > 0 ? ":" : ""); 101 | 102 | for (guint i = 0; i < guards->len; i++) 103 | { 104 | BoltPowerGuard *g = g_ptr_array_index (guards, 0); 105 | g_print (" guard '%s'\n", g->id); 106 | g_print (" %s who: %s\n", tree_branch, g->who); 107 | g_print (" %s pid: %u\n", tree_right, g->pid); 108 | g_print ("\n"); 109 | } 110 | 111 | return EXIT_SUCCESS; 112 | } 113 | 114 | fd = bolt_power_force_power (power, &error); 115 | if (fd == -1) 116 | { 117 | g_warning ("Could force power controller: %s", error->message); 118 | return EXIT_SUCCESS; 119 | } 120 | 121 | g_print ("acquired power guard (%d)\n", fd); 122 | 123 | main_loop = g_main_loop_new (NULL, FALSE); 124 | 125 | if (timeout > 0.) 126 | { 127 | guint tout = (guint) timeout * 1000; 128 | g_timeout_add (tout, quit_main_loop, main_loop); 129 | } 130 | 131 | g_main_loop_run (main_loop); 132 | 133 | (void) close (fd); 134 | return EXIT_SUCCESS; 135 | } 136 | -------------------------------------------------------------------------------- /cli/boltctl-uidfmt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | /* how to format uuids */ 28 | typedef enum { 29 | BOLT_UID_FORMAT_FULL = 0, 30 | BOLT_UID_FORMAT_SHORT = 1, 31 | BOLT_UID_FORMAT_ALIAS = 2, 32 | BOLT_UID_FORMAT_LEN = 0xFF, 33 | 34 | } BoltUuidFormat; 35 | 36 | /* generic function */ 37 | char * bolt_uuid_format (const char *uuid, 38 | const char *salt, 39 | int fmt); 40 | 41 | int bolt_uuid_format_from_string (const char *str, 42 | GError **error); 43 | 44 | /* */ 45 | int format_uid_init (const char *str, 46 | GError **error); 47 | 48 | const char * format_uid (const char *uid); 49 | 50 | G_END_DECLS 51 | -------------------------------------------------------------------------------- /cli/boltctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-client.h" 24 | #include "bolt-term.h" 25 | 26 | G_BEGIN_DECLS 27 | 28 | typedef int (*run_t)(BoltClient *client, 29 | int argc, 30 | char **argv); 31 | 32 | typedef struct SubCommand 33 | { 34 | const char *name; 35 | run_t fn; 36 | const char *desc; 37 | } SubCommand; 38 | 39 | char * subcommands_make_summary (const SubCommand *cmds); 40 | const SubCommand * subcommands_find (const SubCommand *cmds, 41 | const char *cmdname, 42 | GError **error); 43 | int subcommand_run (const SubCommand *cmd, 44 | BoltClient *client, 45 | int argc, 46 | char **argv); 47 | 48 | gboolean check_argc (int argc, 49 | int lower, 50 | int upper, 51 | GError **error); 52 | 53 | int usage_error (GError *error); 54 | int usage_error_need_arg (const char *arg); 55 | int usage_error_too_many_args (void); 56 | int report_error (const char *prefix, 57 | GError *error); 58 | 59 | void print_device (BoltDevice *dev, 60 | gboolean verbose); 61 | 62 | G_END_DECLS 63 | -------------------------------------------------------------------------------- /common/bolt-dbus.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-dbus.h" 24 | #include "bolt-error.h" 25 | 26 | #include "bolt-dbus-resource.h" 27 | #include "bolt-str.h" 28 | 29 | static gpointer 30 | register_dbus_resources (gpointer data) 31 | { 32 | g_resources_register (bolt_dbus_get_resource ()); 33 | return NULL; 34 | } 35 | 36 | void 37 | bolt_dbus_ensure_resources (void) 38 | { 39 | static GOnce only_once = G_ONCE_INIT; 40 | 41 | g_once (&only_once, register_dbus_resources, NULL); 42 | } 43 | 44 | GDBusInterfaceInfo * 45 | bolt_dbus_interface_info_find (const char *interface_xml, 46 | const char *interface_name, 47 | GError **error) 48 | { 49 | g_autoptr(GDBusNodeInfo) node = NULL; 50 | GDBusInterfaceInfo **iter; 51 | GDBusInterfaceInfo *info = NULL; 52 | 53 | g_return_val_if_fail (interface_xml != NULL, NULL); 54 | g_return_val_if_fail (interface_name != NULL, NULL); 55 | 56 | node = g_dbus_node_info_new_for_xml (interface_xml, error); 57 | if (node == NULL) 58 | return NULL; 59 | 60 | for (iter = node->interfaces; iter && *iter; iter++) 61 | { 62 | GDBusInterfaceInfo *ii = *iter; 63 | if (bolt_streq (ii->name, interface_name)) 64 | { 65 | info = ii; 66 | break; 67 | } 68 | } 69 | 70 | if (info == NULL) 71 | { 72 | g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, 73 | "could not find interface with name '%s", 74 | interface_name); 75 | return NULL; 76 | } 77 | 78 | return g_dbus_interface_info_ref (info); 79 | } 80 | 81 | GDBusInterfaceInfo * 82 | bolt_dbus_interface_info_lookup (const char *resource_name, 83 | const char *interface_name, 84 | GError **error) 85 | { 86 | g_autoptr(GBytes) data = NULL; 87 | GDBusInterfaceInfo *info; 88 | const char *xml; 89 | 90 | g_return_val_if_fail (resource_name != NULL, NULL); 91 | g_return_val_if_fail (interface_name != NULL, NULL); 92 | 93 | data = g_resources_lookup_data (resource_name, 94 | G_RESOURCE_LOOKUP_FLAGS_NONE, 95 | error); 96 | 97 | if (data == NULL) 98 | return NULL; 99 | 100 | xml = g_bytes_get_data (data, NULL); 101 | info = bolt_dbus_interface_info_find (xml, interface_name, error); 102 | 103 | return info; 104 | } 105 | 106 | gboolean 107 | bolt_dbus_get_sender_pid (GDBusMethodInvocation *invocation, 108 | guint *pid, 109 | GError **error) 110 | { 111 | g_autoptr(GVariant) res = NULL; 112 | g_autoptr(GError) err = NULL; 113 | GDBusConnection *con; 114 | const char *sender; 115 | 116 | con = g_dbus_method_invocation_get_connection (invocation); 117 | sender = g_dbus_method_invocation_get_sender (invocation); 118 | 119 | res = g_dbus_connection_call_sync (con, 120 | "org.freedesktop.DBus", 121 | "/", 122 | "org.freedesktop.DBus", 123 | "GetConnectionUnixProcessID", 124 | g_variant_new ("(s)", sender), 125 | G_VARIANT_TYPE ("(u)"), 126 | G_DBUS_CALL_FLAGS_NONE, 127 | -1, NULL, 128 | &err); 129 | if (res == NULL) 130 | { 131 | g_set_error (error, BOLT_ERROR, BOLT_ERROR_FAILED, 132 | "could not get pid of caller: %s", 133 | err->message); 134 | return FALSE; 135 | } 136 | 137 | g_variant_get (res, "(u)", pid); 138 | 139 | return TRUE; 140 | } 141 | -------------------------------------------------------------------------------- /common/bolt-dbus.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | #pragma once 21 | 22 | #include 23 | 24 | G_BEGIN_DECLS 25 | 26 | void bolt_dbus_ensure_resources (void); 27 | 28 | GDBusInterfaceInfo * bolt_dbus_interface_info_find (const char *interface_xml, 29 | const char *interface_name, 30 | GError **error); 31 | 32 | GDBusInterfaceInfo * bolt_dbus_interface_info_lookup (const char *resource_name, 33 | const char *interface_name, 34 | GError **error); 35 | 36 | gboolean bolt_dbus_get_sender_pid (GDBusMethodInvocation *invocation, 37 | guint *pid, 38 | GError **error); 39 | G_END_DECLS 40 | -------------------------------------------------------------------------------- /common/bolt-error.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-error.h" 24 | 25 | #include "bolt-names.h" 26 | 27 | #include 28 | 29 | /** 30 | * SECTION:bolt-error 31 | * @Title: Error codes 32 | * 33 | */ 34 | 35 | static const GDBusErrorEntry bolt_error_entries[] = { 36 | {BOLT_ERROR_FAILED, BOLT_DBUS_NAME ".Error.Failed"}, 37 | {BOLT_ERROR_UDEV, BOLT_DBUS_NAME ".Error.UDev"}, 38 | {BOLT_ERROR_NOKEY, BOLT_DBUS_NAME ".Error.NoKey"}, 39 | {BOLT_ERROR_BADKEY, BOLT_DBUS_NAME ".Error.BadKey"}, 40 | {BOLT_ERROR_CFG, BOLT_DBUS_NAME ".Error.Cfg"}, 41 | {BOLT_ERROR_BADSTATE, BOLT_DBUS_NAME ".Error.BadState"}, 42 | {BOLT_ERROR_AUTHCHAIN, BOLT_DBUS_NAME ".Error.AuthChain"}, 43 | }; 44 | 45 | 46 | GQuark 47 | bolt_error_quark (void) 48 | { 49 | static volatile gsize quark_volatile = 0; 50 | 51 | g_dbus_error_register_error_domain ("bolt-error-quark", 52 | &quark_volatile, 53 | bolt_error_entries, 54 | G_N_ELEMENTS (bolt_error_entries)); 55 | return (GQuark) quark_volatile; 56 | } 57 | 58 | gboolean 59 | bolt_err_notfound (const GError *error) 60 | { 61 | return g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) || 62 | g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) || 63 | g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND) || 64 | g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); 65 | } 66 | 67 | gboolean 68 | bolt_err_exists (const GError *error) 69 | { 70 | return g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS) || 71 | g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_EXIST); 72 | } 73 | 74 | gboolean 75 | bolt_err_inval (const GError *error) 76 | { 77 | return g_error_matches (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); 78 | } 79 | 80 | gboolean 81 | bolt_err_cancelled (const GError *error) 82 | { 83 | return g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); 84 | } 85 | 86 | gboolean 87 | bolt_err_badstate (const GError *error) 88 | { 89 | return g_error_matches (error, BOLT_ERROR, BOLT_ERROR_BADSTATE); 90 | } 91 | 92 | gboolean 93 | bolt_err_nokey (const GError *error) 94 | { 95 | return g_error_matches (error, BOLT_ERROR, BOLT_ERROR_NOKEY); 96 | } 97 | 98 | gboolean 99 | bolt_error_propagate (GError **dest, 100 | GError **source) 101 | { 102 | GError *src; 103 | 104 | g_return_val_if_fail (source != NULL, FALSE); 105 | 106 | src = *source; 107 | 108 | if (src == NULL) 109 | return TRUE; 110 | 111 | g_propagate_error (dest, src); 112 | *source = NULL; 113 | 114 | return FALSE; 115 | } 116 | 117 | gboolean 118 | bolt_error_propagate_stripped (GError **dest, 119 | GError **source) 120 | { 121 | GError *src; 122 | 123 | g_return_val_if_fail (source != NULL, FALSE); 124 | 125 | src = *source; 126 | 127 | if (src == NULL) 128 | return TRUE; 129 | 130 | if (g_dbus_error_is_remote_error (src)) 131 | g_dbus_error_strip_remote_error (src); 132 | 133 | g_propagate_error (dest, g_steal_pointer (source)); 134 | return FALSE; 135 | } 136 | 137 | gboolean 138 | bolt_error_for_errno (GError **error, 139 | gint err_no, 140 | const char *format, 141 | ...) 142 | { 143 | va_list ap; 144 | int code; 145 | 146 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE); 147 | g_return_val_if_fail (format != NULL, FALSE); 148 | 149 | if (err_no == 0) 150 | return TRUE; 151 | 152 | if (error == NULL) 153 | return FALSE; 154 | 155 | code = g_io_error_from_errno (err_no); 156 | 157 | va_start (ap, format); 158 | *error = g_error_new_valist (G_IO_ERROR, code, format, ap); 159 | va_end (ap); 160 | 161 | return FALSE; 162 | } 163 | -------------------------------------------------------------------------------- /common/bolt-error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | /** 28 | * BoltError: 29 | * @BOLT_ERROR_FAILED: Generic error code 30 | * @BOLT_ERROR_UDEV: UDev error 31 | * @BOLT_ERROR_NOKEY: Key for authorization is missing 32 | * @BOLT_ERROR_BADKEY: The key is invalid 33 | * @BOLT_ERROR_CFG: Configuration is invalid 34 | * @BOLT_ERROR_BADSTATE: Device is in the wrong state 35 | * @BOLT_ERROR_AUTHCHAIN: Interrupted authorization chain 36 | * 37 | * Error codes used inside Bolt. 38 | */ 39 | typedef enum { 40 | BOLT_ERROR_FAILED = 0, 41 | BOLT_ERROR_UDEV, 42 | BOLT_ERROR_NOKEY, 43 | BOLT_ERROR_BADKEY, 44 | BOLT_ERROR_CFG, 45 | BOLT_ERROR_BADSTATE, 46 | BOLT_ERROR_AUTHCHAIN, 47 | } BoltError; 48 | 49 | 50 | GQuark bolt_error_quark (void); 51 | #define BOLT_ERROR (bolt_error_quark ()) 52 | 53 | /* helper function to check for certain error types */ 54 | gboolean bolt_err_notfound (const GError *error); 55 | gboolean bolt_err_exists (const GError *error); 56 | gboolean bolt_err_inval (const GError *error); 57 | gboolean bolt_err_cancelled (const GError *error); 58 | gboolean bolt_err_badstate (const GError *error); 59 | gboolean bolt_err_nokey (const GError *error); 60 | 61 | gboolean bolt_error_propagate (GError **dest, 62 | GError **source); 63 | gboolean bolt_error_propagate_stripped (GError **dest, 64 | GError **source); 65 | 66 | gboolean bolt_error_for_errno (GError **error, 67 | gint err_no, 68 | const char *format, 69 | ...) G_GNUC_PRINTF (3, 4); 70 | G_END_DECLS 71 | -------------------------------------------------------------------------------- /common/bolt-fs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-error.h" 24 | #include "bolt-io.h" 25 | #include "bolt-fs.h" 26 | 27 | #include 28 | #include 29 | 30 | gboolean 31 | bolt_fs_make_parent_dirs (GFile *target, 32 | GError **error) 33 | { 34 | g_autoptr(GError) err = NULL; 35 | g_autoptr(GFile) p = NULL; 36 | gboolean ok; 37 | 38 | g_return_val_if_fail (G_IS_FILE (target), FALSE); 39 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE); 40 | 41 | p = g_file_get_parent (target); 42 | 43 | ok = g_file_make_directory_with_parents (p, NULL, &err); 44 | if (!ok && !bolt_err_exists (err)) 45 | return bolt_error_propagate (error, &err); 46 | 47 | return TRUE; 48 | } 49 | 50 | static void 51 | cleanup_dir (DIR *d) 52 | { 53 | struct dirent *de = NULL; 54 | 55 | while ((de = readdir (d)) != NULL) 56 | { 57 | g_autoptr(GError) error = NULL; 58 | int uflag = 0; 59 | 60 | if (!g_strcmp0 (de->d_name, ".") || 61 | !g_strcmp0 (de->d_name, "..")) 62 | continue; 63 | 64 | if (de->d_type == DT_DIR) 65 | { 66 | DIR *cd; 67 | 68 | cd = bolt_opendir_at (dirfd (d), de->d_name, O_RDONLY, &error); 69 | if (cd == NULL) 70 | continue; 71 | 72 | cleanup_dir (cd); 73 | uflag = AT_REMOVEDIR; 74 | closedir (cd); 75 | } 76 | 77 | bolt_unlink_at (dirfd (d), de->d_name, uflag, NULL); 78 | } 79 | } 80 | 81 | gboolean 82 | bolt_fs_cleanup_dir (const char *target, 83 | GError **error) 84 | { 85 | DIR *d = NULL; 86 | 87 | g_return_val_if_fail (target != NULL, FALSE); 88 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE); 89 | 90 | d = bolt_opendir (target, error); 91 | if (d == NULL) 92 | return FALSE; 93 | 94 | cleanup_dir (d); 95 | (void) bolt_closedir (d, NULL); 96 | 97 | return bolt_rmdir (target, error); 98 | } 99 | 100 | #define TOUCH_FLAGS O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC 101 | 102 | static inline void 103 | timespec_set_from_uint64 (struct timespec *to, 104 | guint64 from) 105 | { 106 | if (from > 0) 107 | { 108 | to->tv_sec = (time_t) from; 109 | to->tv_nsec = 0; 110 | } 111 | else 112 | { 113 | to->tv_sec = 0; 114 | to->tv_nsec = UTIME_OMIT; 115 | } 116 | } 117 | 118 | gboolean 119 | bolt_fs_touch (GFile *target, 120 | guint64 atime, 121 | guint64 mtime, 122 | GError **error) 123 | { 124 | g_autofree char *path = NULL; 125 | struct timespec times[2]; 126 | gboolean ok; 127 | int fd; 128 | int r; 129 | 130 | g_return_val_if_fail (target != NULL, FALSE); 131 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE); 132 | 133 | path = g_file_get_path (target); 134 | 135 | fd = bolt_open (path, TOUCH_FLAGS, 0664, error); 136 | 137 | if (fd < 0) 138 | return FALSE; 139 | 140 | /* times[0] is the "last access time" (atime) */ 141 | timespec_set_from_uint64 (×[0], atime); 142 | 143 | /* times[1] is the "last modification time" (mtime). */ 144 | timespec_set_from_uint64 (×[1], mtime); 145 | 146 | r = futimens (fd, times); 147 | 148 | if (r == -1) 149 | { 150 | int errsave = errno; 151 | g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsave), 152 | "could not touch file: %s", g_strerror (errsave)); 153 | } 154 | 155 | ok = bolt_close (fd, error); 156 | 157 | return r != -1 && ok; 158 | } 159 | -------------------------------------------------------------------------------- /common/bolt-fs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bolt-error.h" 24 | 25 | #include 26 | 27 | G_BEGIN_DECLS 28 | 29 | gboolean bolt_fs_make_parent_dirs (GFile *target, 30 | GError **error); 31 | 32 | gboolean bolt_fs_cleanup_dir (const char *target, 33 | GError **error); 34 | 35 | gboolean bolt_fs_touch (GFile *target, 36 | guint64 atime, 37 | guint64 mtime, 38 | GError **error); 39 | 40 | G_END_DECLS 41 | -------------------------------------------------------------------------------- /common/bolt-glue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | 28 | GParamSpec * bolt_param_spec_override (GObjectClass *object_class, 29 | const char *name); 30 | 31 | gboolean bolt_str_parse_by_pspec (GParamSpec *spec, 32 | const char *str, 33 | GValue *val, 34 | GError **error); 35 | 36 | GPtrArray * bolt_properties_for_type (GType target); 37 | 38 | gboolean bolt_properties_find (GPtrArray *specs, 39 | const char *name, 40 | GParamSpec **spec, 41 | GError **error); 42 | 43 | /* wire protocol variant/value conversions */ 44 | typedef struct _BoltWireConv BoltWireConv; 45 | 46 | typedef GVariant * (*BoltConvToWire) (BoltWireConv *conv, 47 | const GValue *value, 48 | GError **error); 49 | 50 | typedef gboolean (*BoltConvFromWire) (BoltWireConv *conv, 51 | GVariant *wire, 52 | GValue *value, 53 | GError **error); 54 | 55 | BoltWireConv * bolt_wire_conv_ref (BoltWireConv *conv); 56 | 57 | void bolt_wire_conv_unref (BoltWireConv *conv); 58 | 59 | const GVariantType * bolt_wire_conv_get_wire_type (BoltWireConv *conv); 60 | 61 | const GParamSpec * bolt_wire_conv_get_prop_spec (BoltWireConv *conv); 62 | 63 | gboolean bolt_wire_conv_is_native (BoltWireConv *conv); 64 | 65 | const char * bolt_wire_conv_describe (BoltWireConv *conv); 66 | 67 | BoltWireConv * bolt_wire_conv_for (const GVariantType *wire_type, 68 | GParamSpec *prop_spec); 69 | 70 | BoltWireConv * bolt_wire_conv_custom (const GVariantType *wire_type, 71 | GParamSpec *prop_spec, 72 | const char *custom_id, 73 | BoltConvToWire to_wire, 74 | BoltConvFromWire from_wire); 75 | 76 | GVariant * bolt_wire_conv_to_wire (BoltWireConv *conv, 77 | const GValue *value, 78 | GError **error); 79 | 80 | gboolean bolt_wire_conv_from_wire (BoltWireConv *conv, 81 | GVariant *wire, 82 | GValue *value, 83 | GError **error); 84 | 85 | G_DEFINE_AUTOPTR_CLEANUP_FUNC (BoltWireConv, bolt_wire_conv_unref) 86 | 87 | #if !GLIB_CHECK_VERSION (2, 57, 1) 88 | G_DEFINE_AUTOPTR_CLEANUP_FUNC (GParamSpec, g_param_spec_unref) 89 | #endif 90 | 91 | G_END_DECLS 92 | -------------------------------------------------------------------------------- /common/bolt-list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | #include "bolt-macros.h" 26 | 27 | G_BEGIN_DECLS 28 | 29 | typedef struct BoltList_ BoltList; 30 | struct BoltList_ 31 | { 32 | BoltList *next; 33 | BoltList *prev; 34 | }; 35 | 36 | static inline void 37 | bolt_list_init (BoltList *node) 38 | { 39 | node->next = node; 40 | node->prev = node; 41 | } 42 | 43 | static inline void 44 | bolt_list_add_internal (BoltList *prev, BoltList *next, BoltList *node) 45 | { 46 | node->next = next; 47 | node->prev = prev; 48 | next->prev = node; 49 | prev->next = node; 50 | } 51 | 52 | static inline BoltList * 53 | bolt_list_add_before (BoltList *pos, BoltList *node) 54 | { 55 | if (pos == NULL) 56 | return node; 57 | 58 | bolt_list_add_internal (pos->prev, pos, node); 59 | 60 | return pos; 61 | } 62 | 63 | static inline BoltList * 64 | bolt_list_add_after (BoltList *pos, BoltList *node) 65 | { 66 | if (pos == NULL) 67 | return node; 68 | 69 | bolt_list_add_internal (pos, pos->next, node); 70 | 71 | return pos; 72 | } 73 | 74 | static inline void 75 | bolt_list_del_internal (BoltList *prev, BoltList *next) 76 | { 77 | prev->next = next; 78 | next->prev = prev; 79 | } 80 | 81 | #define bolt_list_entry(node, type, member) bolt_container_of (node, type, member) 82 | 83 | /* no head list */ 84 | static inline guint 85 | bolt_nhlist_len (BoltList *list) 86 | { 87 | BoltList *i = list; 88 | guint count = 0; 89 | 90 | if (list == NULL) 91 | return count; 92 | 93 | do 94 | { 95 | count++; 96 | i = i->next; 97 | } 98 | while (i != list); 99 | 100 | return count; 101 | } 102 | 103 | static inline BoltList * 104 | bolt_nhlist_del (BoltList *list, BoltList *node) 105 | { 106 | if (node == NULL || list == NULL) 107 | return list; 108 | 109 | bolt_list_del_internal (node->prev, node->next); 110 | 111 | if (node == list) 112 | { 113 | if (list->next == list) 114 | return NULL; 115 | else 116 | return list->next; 117 | } 118 | 119 | return list; 120 | } 121 | 122 | /* 123 | * Using a BoltList struct an iterator, where: 124 | * next the *current* node 125 | * prev the *head* of the list 126 | * 127 | * The following special conditions are encoded: 128 | * sym | next | prev | state 129 | * S | * | NULL | first iteration, initial state 130 | * E | NULL | * | end of iteration, final state 131 | */ 132 | static inline BoltList * 133 | bolt_nhlist_iter_init (BoltList *iter, BoltList *list) 134 | { 135 | iter->next = list; 136 | iter->prev = NULL; 137 | 138 | return iter; 139 | } 140 | 141 | #define bolt_nhlist_iter_head(iter_) ((iter_)->prev ? : (iter_)->next) 142 | #define bolt_nhlist_iter_node(iter_) ((iter_ != NULL) ? (iter_)->next : NULL) 143 | #define bolt_nhlist_iter_entry(iter_, type, member) \ 144 | bolt_container_of (bolt_nhlist_iter_node (iter_), type, member) 145 | 146 | static inline BoltList * 147 | bolt_nhlist_iter_next (BoltList *iter) 148 | { 149 | g_return_val_if_fail (iter != NULL, NULL); 150 | 151 | if (iter->next == NULL) /* E */ 152 | return NULL; 153 | 154 | if (iter->prev == NULL) /* S */ 155 | { 156 | iter->prev = iter->next; 157 | return iter->next; 158 | } 159 | 160 | iter->next = iter->next->next; 161 | 162 | if (iter->next == iter->prev) 163 | iter->next = NULL; 164 | 165 | return iter->next; 166 | } 167 | 168 | G_END_DECLS 169 | -------------------------------------------------------------------------------- /common/bolt-macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | G_BEGIN_DECLS 30 | 31 | #ifndef offsetof 32 | #define offsetof(type, member) ((size_t) &((type *) 0)->member) 33 | #endif 34 | 35 | #define bolt_container_of(ptr, type, member) \ 36 | ({const typeof (((type *) 0)->member) * p__ = (ptr); \ 37 | (type *) ((void *) ((char *) p__ - offsetof (type, member))); }) 38 | 39 | /* *INDENT-OFF* */ 40 | 41 | #define bolt_swap(a, b) G_STMT_START { \ 42 | typeof (a) t__ = (a); \ 43 | (a) = (b); \ 44 | (b) = t__; \ 45 | } G_STMT_END 46 | 47 | #define bolt_steal(ptr, none_value) ({ \ 48 | typeof (*(ptr)) t__ = *(ptr); \ 49 | *(ptr) = (none_value); \ 50 | t__; \ 51 | }) 52 | 53 | /* *INDENT-ON* */ 54 | 55 | #define bolt_cleanup(x) __attribute__((cleanup (x))) 56 | 57 | #if defined(__SANITIZE_ADDRESS__) 58 | # define HAVE_ASAN 1 59 | #elif defined(__has_feature) 60 | # if __has_feature (address_sanitizer) 61 | # define HAVE_ASAN 1 62 | # endif 63 | #endif 64 | #ifndef HAVE_ASAN 65 | # define HAVE_ASAN 0 66 | #endif 67 | 68 | G_END_DECLS 69 | -------------------------------------------------------------------------------- /common/bolt-names.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-names.h" 24 | 25 | /* Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_" */ 26 | #define DBUS_OPATH_VALID_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_" 27 | 28 | char * 29 | bolt_gen_object_path (const char *base, 30 | const char *oid) 31 | { 32 | g_autofree char *id = NULL; 33 | 34 | if (oid) 35 | { 36 | id = g_strdup (oid); 37 | g_strcanon (id, DBUS_OPATH_VALID_CHARS, '_'); 38 | } 39 | 40 | if (base && id) 41 | return g_build_path ("/", "/", base, id, NULL); 42 | else if (base) 43 | return g_build_path ("/", "/", base, NULL); 44 | else if (id) 45 | return g_build_path ("/", "/", id, NULL); 46 | 47 | return g_strdup ("/"); 48 | } 49 | -------------------------------------------------------------------------------- /common/bolt-names.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | /* D-Bus API revision (here for the lack of a better place) */ 28 | #define BOLT_DBUS_API_VERSION 1U 29 | 30 | /* logging */ 31 | 32 | #define BOLT_LOG_DOMAIN_UID "BOLT_DOMAIN_UID" 33 | #define BOLT_LOG_DOMAIN_NAME "BOLT_DOMAIN_NAME" 34 | 35 | #define BOLT_LOG_DEVICE_UID "BOLT_DEVICE_UID" 36 | #define BOLT_LOG_DEVICE_NAME "BOLT_DEVICE_NAME" 37 | #define BOLT_LOG_DEVICE_STATE "BOLT_DEVICE_STATE" 38 | 39 | #define BOLT_LOG_ERROR_DOMAIN "ERROR_DOMAIN" 40 | #define BOLT_LOG_ERROR_CODE "ERROR_CODE" 41 | #define BOLT_LOG_ERROR_MESSAGE "ERROR_MESSAGE" 42 | 43 | #define BOLT_LOG_TOPIC "BOLT_TOPIC" 44 | #define BOLT_LOG_VERSION "BOLT_VERSION" 45 | #define BOLT_LOG_CONTEXT "BOLT_LOG_CONTEXT" 46 | #define BOLT_LOG_BUG_MARK "BOLT_LOG_BUG" 47 | 48 | /* logging - message ids */ 49 | #define BOLT_LOG_MSG_IDLEN 33 50 | #define BOLT_LOG_MSG_ID_STARTUP "dd11929c788e48bdbb6276fb5f26b08a" 51 | 52 | 53 | /* dbus */ 54 | #define BOLT_DBUS_GRESOURCE_PATH "/bolt/org.freedesktop.bolt.xml" 55 | 56 | #define BOLT_DBUS_NAME "org.freedesktop.bolt" 57 | #define BOLT_DBUS_PATH "/org/freedesktop/bolt" 58 | #define BOLT_DBUS_PATH_DOMAINS BOLT_DBUS_PATH "/domains" 59 | #define BOLT_DBUS_PATH_DEVICES BOLT_DBUS_PATH "/devices" 60 | #define BOLT_DBUS_INTERFACE "org.freedesktop.bolt1.Manager" 61 | 62 | #define BOLT_DBUS_DEVICE_INTERFACE "org.freedesktop.bolt1.Device" 63 | #define BOLT_DBUS_DOMAIN_INTERFACE "org.freedesktop.bolt1.Domain" 64 | #define BOLT_DBUS_POWER_INTERFACE "org.freedesktop.bolt1.Power" 65 | 66 | /* sysfs */ 67 | #define BOLT_SYSFS_UNIQUE_ID "unique_id" 68 | 69 | #define BOLT_SYSFS_IOMMU "iommu_dma_protection" 70 | #define BOLT_SYSFS_GENERATION "generation" 71 | 72 | #define BOLT_SYSFS_RX_LANES "rx_lanes" 73 | #define BOLT_SYSFS_RX_SPEED "rx_speed" 74 | #define BOLT_SYSFS_TX_LANES "tx_lanes" 75 | #define BOLT_SYSFS_TX_SPEED "tx_speed" 76 | 77 | #define BOLT_SYSFS_DMI_ID "/sys/class/dmi/id" 78 | #define BOLT_SYSFS_DMI_SYS_VENDOR "sys_vendor" 79 | #define BOLT_SYSFS_DMI_PRODUCT_NAME "product_name" 80 | #define BOLT_SYSFS_DMI_PRODUCT_VERSION "product_version" 81 | 82 | /* environment variables */ 83 | #define BOLT_ENV_DBPATH "BOLT_DBPATH" 84 | #define BOLT_ENV_RUNTIME_DIRECTORY "RUNTIME_DIRECTORY" 85 | #define BOLT_ENV_STATE_DIRECTORY "STATE_DIRECTORY" 86 | 87 | #define BOLT_SD_WATCHDOG_USEC "WATCHDOG_USEC" 88 | #define BOLT_SD_NOTIFY_SOCKET "NOTIFY_SOCKET" 89 | 90 | /* other well known names */ 91 | #define INTEL_WMI_THUNDERBOLT_GUID "86CCFD48-205E-4A77-9C48-2021CBEDE341" 92 | 93 | /* helper functions */ 94 | 95 | char * bolt_gen_object_path (const char *path_base, 96 | const char *object_id); 97 | 98 | G_END_DECLS 99 | -------------------------------------------------------------------------------- /common/bolt-rnd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-io.h" 24 | #include "bolt-rnd.h" 25 | 26 | #include 27 | 28 | #include 29 | #include 30 | #if HAVE_FN_GETRANDOM 31 | #include 32 | # else 33 | # define GRND_NONBLOCK 0 34 | #endif 35 | 36 | int 37 | bolt_get_random_data (void *buf, gsize n) 38 | { 39 | gboolean ok; 40 | 41 | ok = bolt_random_getrandom (buf, n, GRND_NONBLOCK, NULL); 42 | if (ok) 43 | return BOLT_RNG_GETRANDOM; 44 | 45 | ok = bolt_random_urandom (buf, n); 46 | 47 | if (ok) 48 | return BOLT_RNG_URANDOM; 49 | 50 | bolt_random_prng (buf, n); 51 | return BOLT_RNG_PRNG; 52 | } 53 | 54 | /* specific implementations */ 55 | gboolean 56 | bolt_random_getrandom (void *buf, 57 | gsize n, 58 | unsigned flags, 59 | GError **error) 60 | { 61 | int r = -1; 62 | 63 | g_return_val_if_fail (buf != NULL, FALSE); 64 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE); 65 | 66 | #if HAVE_FN_GETRANDOM 67 | r = getrandom (buf, n, flags); 68 | #else 69 | errno = ENOSYS; 70 | #endif 71 | 72 | if (r < 0) 73 | { 74 | g_set_error (error, G_IO_ERROR, 75 | g_io_error_from_errno (errno), 76 | "failed to get random data: %s", 77 | g_strerror (errno)); 78 | return FALSE; 79 | } 80 | 81 | return TRUE; 82 | } 83 | 84 | gboolean 85 | bolt_random_urandom (void *buf, gsize n) 86 | { 87 | gboolean ok; 88 | int rndfd; 89 | gsize len; 90 | 91 | g_return_val_if_fail (buf != NULL, FALSE); 92 | 93 | rndfd = bolt_open ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY, 0, NULL); 94 | 95 | if (rndfd < 0) 96 | return FALSE; 97 | 98 | ok = bolt_read_all (rndfd, buf, n, &len, NULL); 99 | 100 | (void) close (rndfd); 101 | 102 | /* NB: according to the man page random(4), "when calling 103 | read(2) for the device /dev/urandom, reads of up to 256 104 | bytes will return as many bytes as are requested and will 105 | not be interrupted by a signal handler". 106 | */ 107 | return ok && len == n; 108 | } 109 | 110 | void 111 | bolt_random_prng (void *buf, gsize n) 112 | { 113 | char *ptr = buf; 114 | const gsize l = n % sizeof (guint32); 115 | const gsize k = n - l; 116 | 117 | if (buf == NULL || n == 0) 118 | return; 119 | 120 | for (gsize i = 0; i < k; i += sizeof (guint32)) 121 | { 122 | guint32 r = g_random_int (); 123 | memcpy (ptr + i, &r, sizeof (guint32)); 124 | } 125 | 126 | if (l > 0) 127 | { 128 | guint32 r = g_random_int (); 129 | memcpy (ptr + k, &r, l); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /common/bolt-rnd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | /* general function */ 28 | typedef enum { 29 | BOLT_RNG_ERROR = -1, 30 | BOLT_RNG_URANDOM = 1, 31 | BOLT_RNG_PRNG = 2, 32 | BOLT_RNG_GETRANDOM = 3, 33 | } BoltRng; 34 | 35 | BoltRng bolt_get_random_data (void *buf, 36 | gsize n); 37 | 38 | /* specific implementations */ 39 | gboolean bolt_random_getrandom (void *buf, 40 | gsize n, 41 | unsigned flags, 42 | GError **error); 43 | gboolean bolt_random_urandom (void *buf, 44 | gsize n); 45 | void bolt_random_prng (void *buf, 46 | gsize n); 47 | 48 | G_END_DECLS 49 | -------------------------------------------------------------------------------- /common/bolt-str.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | #include 25 | 26 | G_BEGIN_DECLS 27 | 28 | void bolt_erase_n (void *data, 29 | gsize n); 30 | void bolt_str_erase (char *str); 31 | void bolt_str_erase_clear (char **str); 32 | 33 | #define bolt_streq(s1, s2) (g_strcmp0 ((s1), (s2)) == 0) 34 | #define bolt_strcaseeq(s1, s2) (g_ascii_strcasecmp ((s1), (s2)) == 0) 35 | 36 | GStrv bolt_strv_from_ptr_array (GPtrArray **array); 37 | GStrv bolt_strv_make_n (guint size, 38 | const char *init); 39 | gsize bolt_strv_length (char * const *strv); 40 | guint bolt_gstrv_length0 (const GStrv strv); 41 | char ** bolt_strv_contains (GStrv haystack, 42 | const char *needle); 43 | gboolean bolt_strv_equal (const GStrv a, 44 | const GStrv b); 45 | 46 | GHashTable * bolt_strv_diff (const GStrv before, 47 | const GStrv after); 48 | 49 | char ** bolt_strv_rotate_left (char **strv); 50 | void bolt_strv_permute (char **strv); 51 | 52 | #define bolt_strv_isempty(strv) ((strv) == NULL || *(strv) == NULL) 53 | 54 | gboolean bolt_uuidv_check (const GStrv uuidv, 55 | gboolean empty_ok, 56 | GError **error); 57 | 58 | #define bolt_strzero(str) (str == NULL || *str == '\0') 59 | 60 | #define bolt_yesno(val) val ? "yes" : "no" 61 | #define bolt_okfail(val) (!!val) ? "ok" : "fail" 62 | 63 | char *bolt_strdup_validate (const char *string); 64 | 65 | char *bolt_strstrip (char *string); 66 | 67 | gboolean bolt_str_parse_as_int (const char *str, 68 | gint *ret, 69 | GError **error); 70 | 71 | gboolean bolt_str_parse_as_uint (const char *str, 72 | guint *ret, 73 | GError **error); 74 | 75 | gboolean bolt_str_parse_as_uint64 (const char *str, 76 | guint64 *ret, 77 | GError **error); 78 | 79 | gboolean bolt_str_parse_as_uint32 (const char *str, 80 | guint32 *ret, 81 | GError **error); 82 | 83 | gboolean bolt_str_parse_as_boolean (const char *str, 84 | gboolean *ret, 85 | GError **error); 86 | 87 | /* replacing string pointers, like g_set_object, g_set_error ... */ 88 | static inline gboolean 89 | bolt_set_str (char **target, char *str) 90 | { 91 | char *ptr; 92 | 93 | g_return_val_if_fail (target != NULL, FALSE); 94 | 95 | ptr = *target; 96 | 97 | if (ptr == str) 98 | return FALSE; 99 | 100 | g_free (ptr); 101 | *target = str; 102 | 103 | return TRUE; 104 | } 105 | 106 | #define bolt_set_strdup(target, str) \ 107 | bolt_set_str (target, g_strdup (str)) 108 | 109 | gboolean bolt_set_strdup_printf (char **target, 110 | const char *fmt, 111 | ...) G_GNUC_PRINTF (2, 3); 112 | 113 | gint bolt_comparefn_strcmp (gconstpointer a, 114 | gconstpointer b); 115 | 116 | G_END_DECLS 117 | -------------------------------------------------------------------------------- /common/bolt-term.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-str.h" 24 | #include "bolt-term.h" 25 | 26 | #include 27 | #include 28 | 29 | int 30 | bolt_is_fancy_terminal (void) 31 | { 32 | const char *val; 33 | 34 | if (!isatty (STDOUT_FILENO)) 35 | return 0; 36 | 37 | val = g_getenv ("TERM"); 38 | if (val && !g_ascii_strcasecmp (val, "dumb")) 39 | return 0; 40 | 41 | return 1; 42 | } 43 | 44 | const char * 45 | bolt_color (const char *color) 46 | { 47 | static gint on = -1; 48 | 49 | if (G_UNLIKELY (on == -1)) 50 | on = bolt_is_fancy_terminal (); 51 | 52 | return on ? color : ""; 53 | } 54 | 55 | /* borrowed from systemd */ 56 | static const char *const ansi_glphys[BOLT_GLYPH_LAST] = { 57 | [TREE_VERTICAL] = "| ", 58 | [TREE_BRANCH] = "|-", 59 | [TREE_RIGHT] = "`-", 60 | [TREE_SPACE] = " ", 61 | [WHITE_CIRCLE] = "o", 62 | [BLACK_CIRCLE] = "*", 63 | [ARROW] = "->", 64 | [MDASH] = "-", 65 | [ELLIPSIS] = "...", 66 | [WARNING_SIGN] = "!", 67 | }; 68 | 69 | static const char *const utf8_glphys[BOLT_GLYPH_LAST] = { 70 | [TREE_VERTICAL] = "\342\224\202 ", /* │ */ 71 | [TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */ 72 | [TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */ 73 | [TREE_SPACE] = " ", /* */ 74 | [WHITE_CIRCLE] = "\342\227\213", /* ○ */ 75 | [BLACK_CIRCLE] = "\342\227\217", /* ● */ 76 | [ARROW] = "\342\206\222", /* → */ 77 | [MDASH] = "\342\200\223", /* – */ 78 | [ELLIPSIS] = "\342\200\246", /* … */ 79 | [WARNING_SIGN] = "\342\232\240", /* ⚠ */ 80 | }; 81 | 82 | 83 | const char * 84 | bolt_glyph (BoltGlyph g) 85 | { 86 | static const char *const *glyph_table = NULL; 87 | 88 | g_return_val_if_fail (g < BOLT_GLYPH_LAST, "?"); 89 | 90 | /* TODO: check for utf-8 support */ 91 | if (G_UNLIKELY (glyph_table == NULL)) 92 | { 93 | if (bolt_is_fancy_terminal ()) 94 | glyph_table = utf8_glphys; 95 | else 96 | glyph_table = ansi_glphys; 97 | } 98 | 99 | return glyph_table[g]; 100 | } 101 | -------------------------------------------------------------------------------- /common/bolt-term.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | #include 25 | 26 | G_BEGIN_DECLS 27 | 28 | #define ANSI_NORMAL "\x1B[0m" 29 | #define ANSI_RED "\x1B[0;31m" 30 | #define ANSI_GREEN "\x1B[0;32m" 31 | #define ANSI_YELLOW "\x1B[0;33m" 32 | #define ANSI_BLUE "\x1B[0;34m" 33 | #define ANSI_HIGHLIGHT_BLACK "\x1B[0;1;30m" 34 | #define ANSI_HIGHLIGHT_RED "\x1B[0;1;31m" 35 | 36 | int bolt_is_fancy_terminal (void); 37 | 38 | const char * bolt_color (const char *color); 39 | 40 | typedef enum { 41 | TREE_VERTICAL, 42 | TREE_BRANCH, 43 | TREE_RIGHT, 44 | TREE_SPACE, 45 | 46 | BLACK_CIRCLE, 47 | WHITE_CIRCLE, 48 | 49 | ARROW, 50 | MDASH, 51 | ELLIPSIS, 52 | 53 | WARNING_SIGN, 54 | 55 | BOLT_GLYPH_LAST 56 | } BoltGlyph; 57 | 58 | const char * bolt_glyph (BoltGlyph g); 59 | 60 | G_END_DECLS 61 | -------------------------------------------------------------------------------- /common/bolt-time.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-time.h" 24 | 25 | char * 26 | bolt_epoch_format (guint64 seconds, const char *format) 27 | { 28 | g_autoptr(GDateTime) dt = NULL; 29 | 30 | g_return_val_if_fail (format != NULL, NULL); 31 | 32 | dt = g_date_time_new_from_unix_utc ((gint64) seconds); 33 | 34 | if (dt == NULL) 35 | return NULL; 36 | 37 | return g_date_time_format (dt, format); 38 | } 39 | 40 | guint64 41 | bolt_now_in_seconds (void) 42 | { 43 | gint64 now = g_get_real_time (); 44 | 45 | return (guint64) now / G_USEC_PER_SEC; 46 | } 47 | -------------------------------------------------------------------------------- /common/bolt-time.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | #define BOLT_MSEC_PER_SEC 1000LL /* number of milli-seconds (ms) in a second (s) */ 28 | #define BOLT_USEC_PER_MSEC 1000LL /* number of micro-seconds (µs) in a ms */ 29 | 30 | char * bolt_epoch_format (guint64 seconds, 31 | const char *format); 32 | 33 | guint64 bolt_now_in_seconds (void); 34 | 35 | G_END_DECLS 36 | -------------------------------------------------------------------------------- /common/bolt-unix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-unix.h" 24 | 25 | #include "bolt-error.h" 26 | #include "bolt-io.h" 27 | #include "bolt-names.h" 28 | #include "bolt-str.h" 29 | 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | gboolean 38 | bolt_pid_is_alive (pid_t pid) 39 | { 40 | gulong p = (gulong) pid; 41 | char path[256]; 42 | 43 | if (pid != 0) 44 | g_snprintf (path, sizeof (path), "/proc/%lu/stat", p); 45 | else 46 | g_snprintf (path, sizeof (path), "/proc/self/stat"); 47 | 48 | return g_file_test (path, G_FILE_TEST_EXISTS); 49 | } 50 | 51 | gboolean 52 | bolt_sd_notify_literal (const char *state, 53 | gboolean *sent, 54 | GError **error) 55 | { 56 | bolt_autoclose int fd = -1; 57 | struct sockaddr_un sau = {AF_UNIX, }; 58 | struct msghdr msghdr = { NULL, }; 59 | struct iovec iovec = { }; 60 | const char *env; 61 | socklen_t socklen; 62 | size_t len; 63 | ssize_t r; 64 | 65 | g_return_val_if_fail (state != NULL, FALSE); 66 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE); 67 | 68 | if (sent) 69 | *sent = FALSE; 70 | 71 | env = g_getenv (BOLT_SD_NOTIFY_SOCKET); 72 | 73 | if (env == NULL) 74 | return TRUE; 75 | 76 | len = strlen (env); 77 | 78 | if (len > sizeof (sau.sun_path) - 1) 79 | { 80 | g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, 81 | "unix domain socket path too long: %s", env); 82 | return FALSE; 83 | } 84 | 85 | socklen = offsetof (struct sockaddr_un, sun_path) + len; 86 | 87 | switch (*env) 88 | { 89 | case '@': 90 | /* abstract sockets have sun_path[0] set to '\0', 91 | * otherwise '\0' have no special meaning, i.e. 92 | * the address is not null-terminted */ 93 | memcpy (sau.sun_path + 1, env + 1, len); 94 | socklen += 1; /* the leading '\0' */ 95 | break; 96 | 97 | case '/': 98 | /* pathname: null-terminated filesystem path */ 99 | memcpy (sau.sun_path, env, len + 1); 100 | break; 101 | 102 | default: 103 | g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, 104 | "unsupported socket address: %s", env); 105 | return FALSE; 106 | } 107 | 108 | fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); 109 | if (fd < 0) 110 | return bolt_error_for_errno (error, errno, "failed to open socket %m"); 111 | 112 | iovec.iov_base = (void *) state; 113 | iovec.iov_len = strlen (state); 114 | 115 | msghdr.msg_iov = &iovec; 116 | msghdr.msg_iovlen = 1; 117 | msghdr.msg_name = &sau; 118 | msghdr.msg_namelen = socklen; 119 | 120 | r = sendmsg (fd, &msghdr, MSG_NOSIGNAL); 121 | 122 | if (sent) 123 | *sent = TRUE; 124 | 125 | if (r < 0) 126 | { 127 | bolt_error_for_errno (error, errno, "failed to send msg: %m"); 128 | return FALSE; 129 | } 130 | else if ((size_t) r != iovec.iov_len) 131 | { 132 | g_set_error (error, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE, 133 | "failed to send complete message: %s", env); 134 | return FALSE; 135 | } 136 | 137 | return TRUE; 138 | } 139 | 140 | int 141 | bolt_sd_watchdog_enabled (guint64 *timeout, 142 | GError **error) 143 | { 144 | const char *str; 145 | guint64 val = 0; 146 | gboolean ok; 147 | 148 | str = g_getenv (BOLT_SD_WATCHDOG_USEC); 149 | 150 | if (str == NULL) 151 | return 0; 152 | 153 | ok = bolt_str_parse_as_uint64 (str, &val, error); 154 | 155 | if (ok && (val == 0 || val == (guint64) - 1)) 156 | { 157 | g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, 158 | "invalid value '%" G_GUINT64_FORMAT "'", val); 159 | ok = FALSE; 160 | } 161 | 162 | if (!ok) 163 | g_prefix_error (error, "failed to parse WATCHDOG_USEC: "); 164 | else if (timeout) 165 | *timeout = val; 166 | 167 | return ok ? 1 : -1; 168 | } 169 | -------------------------------------------------------------------------------- /common/bolt-unix.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | #include 25 | 26 | G_BEGIN_DECLS 27 | 28 | gboolean bolt_pid_is_alive (pid_t pid); 29 | 30 | gboolean bolt_sd_notify_literal (const char *state, 31 | gboolean *sent, 32 | GError **error); 33 | 34 | int bolt_sd_watchdog_enabled (guint64 *timeout, 35 | GError **error); 36 | 37 | G_END_DECLS 38 | -------------------------------------------------------------------------------- /common/bolt-wire.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2020 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-wire.h" 24 | 25 | #include "bolt-error.h" 26 | 27 | #include 28 | 29 | G_DEFINE_BOXED_TYPE (BoltLinkSpeed, bolt_link_speed, bolt_link_speed_copy, g_free); 30 | 31 | BoltLinkSpeed * 32 | bolt_link_speed_copy (const BoltLinkSpeed *other) 33 | { 34 | BoltLinkSpeed *copy = g_new (BoltLinkSpeed, 1); 35 | 36 | *copy = *other; 37 | return copy; 38 | } 39 | 40 | gboolean 41 | bolt_link_speed_equal (const BoltLinkSpeed *a, 42 | const BoltLinkSpeed *b) 43 | { 44 | return 45 | a->rx.speed == b->rx.speed && 46 | a->rx.lanes == b->rx.lanes && 47 | a->tx.speed == b->tx.speed && 48 | a->tx.lanes == b->tx.lanes; 49 | } 50 | 51 | GVariant * 52 | bolt_link_speed_to_wire (BoltWireConv *conv, 53 | const GValue *value, 54 | GError **error) 55 | { 56 | GVariantBuilder builder; 57 | BoltLinkSpeed *link; 58 | 59 | 60 | link = g_value_get_boxed (value); 61 | 62 | g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{su}")); 63 | 64 | g_variant_builder_add (&builder, "{su}", "rx.speed", link->rx.speed); 65 | g_variant_builder_add (&builder, "{su}", "rx.lanes", link->rx.lanes); 66 | g_variant_builder_add (&builder, "{su}", "tx.speed", link->tx.speed); 67 | g_variant_builder_add (&builder, "{su}", "tx.lanes", link->tx.lanes); 68 | 69 | return g_variant_builder_end (&builder); 70 | } 71 | 72 | gboolean 73 | bolt_link_speed_from_wire (BoltWireConv *conv, 74 | GVariant *wire, 75 | GValue *value, 76 | GError **error) 77 | { 78 | BoltLinkSpeed link; 79 | gboolean ok; 80 | 81 | struct 82 | { 83 | const char *name; 84 | guint32 *target; 85 | } entries[] = { 86 | {"rx.speed", &link.rx.speed}, 87 | {"rx.lanes", &link.rx.lanes}, 88 | {"tx.speed", &link.tx.speed}, 89 | {"tx.lanes", &link.tx.lanes}, 90 | }; 91 | 92 | for (unsigned i = 0; i < G_N_ELEMENTS (entries); i++) 93 | { 94 | const char *name = entries[i].name; 95 | guint32 *target = entries[i].target; 96 | 97 | ok = g_variant_lookup (wire, name, "u", target); 98 | if (!ok) 99 | { 100 | g_set_error (error, BOLT_ERROR, BOLT_ERROR_FAILED, 101 | "Missing entry in LinkSpeed dict: %s", 102 | name); 103 | return FALSE; 104 | } 105 | } 106 | 107 | g_value_set_boxed (value, &link); 108 | 109 | return ok; 110 | } 111 | -------------------------------------------------------------------------------- /common/bolt-wire.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2020 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | #include 26 | 27 | G_BEGIN_DECLS 28 | 29 | typedef struct BoltLinkSpeed_ BoltLinkSpeed; 30 | 31 | struct BoltLinkSpeed_ 32 | { 33 | struct 34 | { 35 | struct 36 | { 37 | guint32 speed; 38 | guint32 lanes; 39 | } rx; 40 | 41 | struct 42 | { 43 | guint32 speed; 44 | guint32 lanes; 45 | } tx; 46 | }; 47 | }; 48 | 49 | GType bolt_link_speed_get_type (void); 50 | #define BOLT_TYPE_LINK_SPEED (bolt_link_speed_get_type ()) 51 | 52 | BoltLinkSpeed * bolt_link_speed_copy (const BoltLinkSpeed *ls); 53 | 54 | gboolean bolt_link_speed_equal (const BoltLinkSpeed *a, 55 | const BoltLinkSpeed *b); 56 | 57 | GVariant * bolt_link_speed_to_wire (BoltWireConv *conv, 58 | const GValue *value, 59 | GError **error); 60 | 61 | gboolean bolt_link_speed_from_wire (BoltWireConv *conv, 62 | GVariant *wire, 63 | GValue *value, 64 | GError **error); 65 | 66 | G_END_DECLS 67 | -------------------------------------------------------------------------------- /common/fix-coverity.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fix-coverity.h 3 | * Copyright 2017 Peter Jones 4 | * 5 | * Distributed under terms of the LGPL 2.1+ license. 6 | */ 7 | 8 | #ifndef FIX_COVERITY_H 9 | #define FIX_COVERITY_H 10 | 11 | #ifndef _GNU_SOURCE 12 | #define _GNU_SOURCE 13 | #endif 14 | 15 | #ifndef __COVERITY_GCC_VERSION_AT_LEAST 16 | #define __COVERITY_GCC_VERSION_AT_LEAST(x, y) 0 17 | #define FAKE__COVERITY_GCC_VERSION_AT_LEAST__ 18 | #endif /* __COVERITY_GCC_VERSION_AT_LEAST */ 19 | 20 | /* With gcc 7 on x86_64 (at least), coverity pretends to be GCC but 21 | * accidentally doesn't create all of the types GCC would. 22 | * 23 | * In glibc's headers, bits/floatn.h has: 24 | * 25 | * #if (defined __x86_64__ \ 26 | * ? __GNUC_PREREQ (4, 3) \ 27 | * : (defined __GNU__ ? __GNUC_PREREQ (4, 5) : __GNUC_PREREQ (4, 4))) 28 | * # define __HAVE_FLOAT128 1 29 | * #else 30 | * # define __HAVE_FLOAT128 0 31 | * #endif 32 | * 33 | * and stdlib.h has: 34 | * 35 | * #if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT) 36 | * slash* Likewise for the '_Float128' format *slash 37 | * extern _Float128 strtof128 (const char *__restrict __nptr, 38 | * char **__restrict __endptr) 39 | * __THROW __nonnull ((1)); 40 | * #endif 41 | * 42 | * Which then causes cov-emit to lose its shit: 43 | * 44 | * "/usr/include/stdlib.h", line 133: error #20: identifier "_Float128" is 45 | * undefined 46 | * extern _Float128 strtof128 (const char *__restrict __nptr, 47 | * ^ 48 | * "/usr/include/stdlib.h", line 190: error #20: identifier "_Float128" is 49 | * undefined 50 | * _Float128 __f) 51 | * ^ 52 | * "/usr/include/stdlib.h", line 236: error #20: identifier "_Float128" is 53 | * undefined 54 | * extern _Float128 strtof128_l (const char *__restrict __nptr, 55 | * ^ 56 | * 57 | * And then you'll notice something like this later on: 58 | * [WARNING] Emitted 0 C/C++ compilation units (0%) successfully 59 | * 60 | * 0 C/C++ compilation units (0%) are ready for analysis 61 | * For more details, please look at: 62 | * /home/pjones/devel/github.com/dbxtool/master/cov-int/build-log.txt 63 | * 64 | * You would think that if you're writing something that pretends to be 65 | * gcc, and you've got a "build a configuration by running shit through gcc 66 | * and looking at the output" stage (which they do), you would run "gcc -da 67 | * -fdump-tree-all -c -o foo.o foo.c" on an empty file and snarf up all the 68 | * types defined in the foo.c.001t.tu output. Apparently, they do not. 69 | * 70 | * Anyway, even just defining the type doesn't always work in the face of 71 | * how _Complex is defined, so we cheat a bit here. Be prepared to vomit. 72 | */ 73 | #ifdef __x86_64__ 74 | #if __COVERITY_GCC_VERSION_AT_LEAST (7, 0) 75 | #if 0 76 | typedef float _Float128 __attribute__((__mode__ (__TF__))); 77 | typedef __complex__ float __cfloat128 __attribute__((__mode__ (__TC__))); 78 | typedef _Complex float __cfloat128 __attribute__((__mode__ (__TC__))); 79 | #else 80 | #include 81 | #define __cplusplus 201103L 82 | #include 83 | #undef __cplusplus 84 | #endif 85 | #endif 86 | #endif 87 | 88 | #ifdef FAKE__COVERITY_GCC_VERSION_AT_LEAST__ 89 | #undef FAKE__COVERITY_GCC_VERSION_AT_LEAST 90 | #undef __COVERITY_GCC_VERSION_AT_LEAST 91 | #endif 92 | 93 | #endif /* !FIX_COVERITY_H */ 94 | // vim:fenc=utf-8:tw=75 95 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | /* naming and versioning */ 24 | #mesondefine PACKAGE_NAME 25 | #mesondefine PACKAGE_VERSION 26 | #mesondefine VERSION 27 | #mesondefine VERSION_MAJOR 28 | #mesondefine VERSION_MINOR 29 | 30 | /* directories */ 31 | #mesondefine DATADIR 32 | #mesondefine LOCALSTATEDIR 33 | #mesondefine BOLT_DBNAME 34 | #mesondefine BOLT_DBDIR 35 | #mesondefine DATADIR 36 | 37 | /* availability of features */ 38 | #mesondefine HAVE_FN_EXPLICIT_BZERO 39 | #mesondefine HAVE_FN_GETRANDOM 40 | #mesondefine HAVE_FN_COPY_FILE_RANGE 41 | #mesondefine HAVE_POLKIT_AUTOPTR 42 | 43 | /* constants */ 44 | #mesondefine _GNU_SOURCE 45 | 46 | /* fixup coverity build issues */ 47 | #mesondefine IS_COVERITY_BUILD 48 | #ifdef IS_COVERITY_BUILD 49 | #include "fix-coverity.h" 50 | #endif 51 | 52 | /* use structure logging f */ 53 | #define G_LOG_USE_STRUCTURED 1 54 | 55 | /* glib version checking */ 56 | #mesondefine GLIB_VERSION_MIN_REQUIRED 57 | #mesondefine GLIB_VERSION_MAX_ALLOWED 58 | -------------------------------------------------------------------------------- /contrib/Dockerfile-alpine: -------------------------------------------------------------------------------- 1 | ## -*- mode: dockerfile -*- 2 | FROM alpine:latest 3 | ENV LANG en_US.UTF-8 4 | ENV LANGUAGE en_US:en 5 | ENV LC_ALL en_US.UTF-8 6 | RUN apk add --no-cache bash dbus dbus-dev eudev-dev gcc glib-dev libc-dev meson ninja polkit-dev udev 7 | RUN mkdir /src /build 8 | WORKDIR /src 9 | -------------------------------------------------------------------------------- /contrib/Dockerfile-arch: -------------------------------------------------------------------------------- 1 | ## -*- mode: dockerfile -*- 2 | FROM archlinux/archlinux:base-devel 3 | ENV LANG en_US.UTF-8 4 | ENV LC_ALL en_US.UTF-8 5 | RUN pacman -Syu --noconfirm 6 | RUN pacman -S --noconfirm base-devel 7 | RUN pacman -S --noconfirm \ 8 | asciidoc \ 9 | dbus-glib \ 10 | git \ 11 | gobject-introspection \ 12 | gtk-doc \ 13 | meson \ 14 | perl-sgmls \ 15 | polkit \ 16 | python-dbus \ 17 | python-gobject \ 18 | python-pip \ 19 | umockdev \ 20 | valgrind 21 | 22 | RUN pip3 install python-dbusmock pylint==2.4.1 23 | 24 | RUN mkdir /src /build 25 | WORKDIR /src 26 | -------------------------------------------------------------------------------- /contrib/Dockerfile-coverity: -------------------------------------------------------------------------------- 1 | ## -*- mode: dockerfile -*- 2 | FROM fedora:34 3 | 4 | ENV LANG en_US.UTF-8 5 | ENV LANGUAGE en_US:en 6 | ENV LC_ALL en_US.UTF-8 7 | RUN dnf --enablerepo=updates-testing -y update 8 | RUN dnf --enablerepo=updates-testing -y install \ 9 | clang-analyzer \ 10 | codespell \ 11 | gcc \ 12 | git \ 13 | glib2-devel \ 14 | glibc-langpack-en \ 15 | gtk-doc \ 16 | lcov \ 17 | libgudev-devel \ 18 | meson-0.56.2-2.fc34 \ 19 | polkit-devel \ 20 | python3 \ 21 | python3-dbus \ 22 | python3-dbusmock \ 23 | python3-gobject \ 24 | rpm-build \ 25 | redhat-rpm-config \ 26 | systemd-devel \ 27 | umockdev-devel \ 28 | uncrustify \ 29 | wget 30 | 31 | ARG TOKEN 32 | ARG PROJECT 33 | ARG ORG 34 | 35 | ENV HOME "/root" 36 | 37 | WORKDIR "$HOME" 38 | RUN curl https://scan.coverity.com/download/linux64 \ 39 | --form project=${ORG}/${PROJECT} \ 40 | --form token=${TOKEN} \ 41 | -o coverity_tool.tgz && \ 42 | tar zxf coverity_tool.tgz \ 43 | && rm coverity_tool.tgz && \ 44 | mv cov-analysis-linux64-* cov-analysis-linux64 45 | 46 | ENV PATH "$PATH:$HOME/cov-analysis-linux64/bin" 47 | 48 | RUN mkdir /src /build 49 | WORKDIR /src 50 | -------------------------------------------------------------------------------- /contrib/Dockerfile-debian: -------------------------------------------------------------------------------- 1 | ## -*- mode: dockerfile -*- 2 | FROM debian:sid 3 | RUN apt-get update -q && apt-get install -y \ 4 | asciidoc \ 5 | git \ 6 | gobject-introspection \ 7 | libgirepository1.0-dev \ 8 | libpolkit-gobject-1-dev \ 9 | locales \ 10 | libudev-dev \ 11 | libumockdev-dev \ 12 | libsystemd-dev \ 13 | meson \ 14 | pkg-config \ 15 | policykit-1 \ 16 | python3-dbus \ 17 | python3-dbusmock \ 18 | udev \ 19 | umockdev \ 20 | systemd \ 21 | && rm -rf /var/lib/apt/lists/* 22 | 23 | RUN mkdir /src /build 24 | WORKDIR /src 25 | -------------------------------------------------------------------------------- /contrib/Dockerfile-fedora: -------------------------------------------------------------------------------- 1 | ## -*- mode: dockerfile -*- 2 | FROM fedora:34 3 | ENV LANG en_US.UTF-8 4 | ENV LANGUAGE en_US:en 5 | ENV LC_ALL en_US.UTF-8 6 | RUN dnf --enablerepo=updates-testing -y update 7 | RUN dnf --enablerepo=updates-testing -y install \ 8 | clang-analyzer \ 9 | codespell \ 10 | gcc \ 11 | git \ 12 | glib2-devel \ 13 | glibc-langpack-en \ 14 | gtk-doc \ 15 | lcov \ 16 | libgudev-devel \ 17 | meson-0.56.2-2.fc34 \ 18 | polkit-devel \ 19 | python3 \ 20 | python3-dbus \ 21 | python3-dbusmock \ 22 | python3-gobject \ 23 | rpm-build \ 24 | redhat-rpm-config \ 25 | systemd-devel \ 26 | umockdev-devel \ 27 | uncrustify 28 | 29 | RUN mkdir /src /build 30 | WORKDIR /src 31 | -------------------------------------------------------------------------------- /contrib/Dockerfile-ub1804: -------------------------------------------------------------------------------- 1 | ## -*- mode: dockerfile -*- 2 | FROM ubuntu:18.04 3 | ARG DEBIAN_FRONTEND=noninteractive 4 | RUN apt-get update -q && apt-get install -yy \ 5 | asciidoc \ 6 | git \ 7 | gobject-introspection \ 8 | libgirepository1.0-dev \ 9 | libpolkit-gobject-1-dev \ 10 | locales \ 11 | libudev-dev \ 12 | libumockdev-dev \ 13 | libsystemd-dev \ 14 | meson \ 15 | pkg-config \ 16 | policykit-1 \ 17 | python3-dbus \ 18 | python3-dbusmock \ 19 | udev \ 20 | umockdev \ 21 | systemd \ 22 | && rm -rf /var/lib/apt/lists/* 23 | 24 | RUN mkdir /src 25 | WORKDIR /src 26 | -------------------------------------------------------------------------------- /contrib/PKGBUILD: -------------------------------------------------------------------------------- 1 | pkgname=bolt-git 2 | pkgver=r271.6d86460 3 | pkgrel=1 4 | pkgdesc="Thunderbolt 3 security system daemon" 5 | arch=('i686' 'x86_64') 6 | url="https://github.com/gicmo/bolt" 7 | license=('LGPL') 8 | depends=('polkit' 'systemd') 9 | makedepends=('asciidoc' 'meson' 'git') 10 | checkdepends=('umockdev') 11 | conflicts=('bolt') 12 | provides=('bolt') 13 | source=(git+https://github.com/gicmo/bolt.git) 14 | md5sums=('SKIP') 15 | 16 | pkgver() { 17 | cd bolt 18 | printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" 19 | } 20 | 21 | build() { 22 | cd "${srcdir}" 23 | 24 | install -d build 25 | arch-meson bolt build 26 | ninja -v -C build 27 | } 28 | 29 | check() { 30 | cd "${srcdir}" 31 | ninja -C build test 32 | } 33 | 34 | package() { 35 | cd "${srcdir}" 36 | DESTDIR="${pkgdir}" ninja -C build install 37 | # Fixup mode to match polkit 38 | install -d -o root -g 102 -m 750 "${pkgdir}/usr/share/polkit-1/rules.d" 39 | } 40 | -------------------------------------------------------------------------------- /contrib/bolt.spec.in: -------------------------------------------------------------------------------- 1 | Name: bolt 2 | Version: @version@ 3 | Release: 0.@reltag@%{?dist} 4 | Summary: Thunderbolt device manager 5 | License: LGPLv2+ 6 | URL: https://gitlab.freedesktop.org/bolt/bolt 7 | Source0: %{url}/-/archive/%{version}/%{name}-%{version}.tar.xz 8 | 9 | BuildRequires: gcc 10 | BuildRequires: asciidoc 11 | BuildRequires: meson 12 | BuildRequires: libudev-devel 13 | BuildRequires: pkgconfig(gio-2.0) 14 | BuildRequires: pkgconfig(libudev) 15 | BuildRequires: pkgconfig(systemd) 16 | BuildRequires: pkgconfig(libsystemd) 17 | BuildRequires: polkit-devel 18 | BuildRequires: systemd 19 | %{?systemd_requires} 20 | 21 | # for the integration test (optional) 22 | %if 0%{?fedora} 23 | BuildRequires: pygobject3-devel 24 | BuildRequires: python3-dbus 25 | BuildRequires: python3-dbusmock 26 | BuildRequires: umockdev-devel 27 | %endif 28 | 29 | %description 30 | bolt is a system daemon to manage Thunderbolt devices via a D-BUS 31 | API. Thunderbolt 3 introduced different security modes that require 32 | devices to be authorized before they can be used. The D-Bus API can be 33 | used to list devices, enroll them (authorize and store them in the 34 | local database) and forget them again (remove previously enrolled 35 | devices). It also emits signals if new devices are connected (or 36 | removed). During enrollment devices can be set to be automatically 37 | authorized as soon as they are connected. A command line tool, called 38 | boltctl, can be used to control the daemon and perform all the above 39 | mentioned tasks. 40 | 41 | %package tests 42 | Summary: Integration tests, unit tests and bolt-mock test helper 43 | Requires: %{name}%{?_isa} = %{version}-%{release} 44 | License: LGPLv2+ 45 | 46 | %description tests 47 | Contains the unit tests suite, the integration tests and a bolt-mock 48 | helper that can be used to run the boltd daemon in a mock environment 49 | where thunderbolt domains and devices can be simulated. 50 | 51 | %prep 52 | %setup -q 53 | 54 | %build 55 | %meson -Ddb-name=@dbname@ -Dinstall-tests=true 56 | %meson_build 57 | 58 | %check 59 | %meson_test 60 | 61 | %install 62 | %meson_install 63 | 64 | %post 65 | %systemd_post %{name}.service 66 | 67 | %preun 68 | %systemd_preun %{name}.service 69 | 70 | %postun 71 | %systemd_postun_with_restart %{name}.service 72 | 73 | %files 74 | %license COPYING 75 | %doc README.md CHANGELOG.md BUGS.md INSTALL.md HACKING.md 76 | %{_bindir}/boltctl 77 | %{_libexecdir}/boltd 78 | %{_unitdir}/%{name}.service 79 | %{_udevrulesdir}/*-%{name}.rules 80 | %{_datadir}/dbus-1/system.d/org.freedesktop.bolt.conf 81 | %{_datadir}/dbus-1/interfaces/org.freedesktop.bolt.xml 82 | %{_datadir}/polkit-1/actions/org.freedesktop.bolt.policy 83 | %{_datadir}/polkit-1/rules.d/org.freedesktop.bolt.rules 84 | %{_datadir}/dbus-1/system-services/org.freedesktop.bolt.service 85 | %{_mandir}/man1/boltctl.1* 86 | %{_mandir}/man8/boltd.8* 87 | %ghost %dir @dbdir@ 88 | 89 | %files tests 90 | %{_libexecdir}/installed-tests/bolt 91 | %{_libexecdir}/installed-tests/bolt/* 92 | 93 | %changelog 94 | * @longdate@ Christian Kellner - @version@-@reltag@ 95 | - build from git sources. 96 | -------------------------------------------------------------------------------- /contrib/cov-model.c: -------------------------------------------------------------------------------- 1 | /* GLib types. */ 2 | typedef size_t gsize; 3 | typedef char gchar; 4 | typedef unsigned char guchar; 5 | typedef int gint; 6 | typedef unsigned long gulong; 7 | typedef unsigned int guint32; 8 | typedef void * gpointer; 9 | typedef unsigned int gboolean; 10 | 11 | 12 | void 13 | g_assertion_message_expr (const char *domain, 14 | const char *file, 15 | int line, 16 | const char *func, 17 | const char *expr) 18 | { 19 | __coverity_panic__ (); 20 | } 21 | 22 | #define g_critical(...) __coverity_panic__ (); 23 | 24 | /* Treat it as a memory sink to hide one-time allocation leaks. */ 25 | void 26 | (g_once_init_leave) (volatile void *location, 27 | gsize result) 28 | { 29 | __coverity_escape__ (result); 30 | } 31 | -------------------------------------------------------------------------------- /contrib/coverity.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | GIT_DESC=$(git describe) 6 | 7 | env 8 | 9 | # prepare 10 | export LC_ALL=C.UTF-8 11 | export PYTHONPATH="/usr/share/glib-2.0" 12 | 13 | rm -rf /build/* 14 | 15 | # info 16 | ls -la /build 17 | whoami 18 | 19 | # actual building 20 | export CC=clang CXX=clang 21 | meson -Dcoverity=true /build 22 | cov-build --dir /build/cov-int ninja -C /build 23 | pushd /build 24 | tar -caf coverity.xz cov-int 25 | popd 26 | 27 | if [[ -v COVERITY_TOKEN && -v COVERITY_EMAIL ]]; then 28 | 29 | curl --form "token=${COVERITY_TOKEN}" \ 30 | --form "email=${COVERITY_EMAIL}" \ 31 | --form "file=@/build/coverity.xz" \ 32 | --form "version=main" \ 33 | --form "description=${GIT_DESC}" \ 34 | https://scan.coverity.com/builds?project=gicmo%2Fbolt 35 | fi 36 | -------------------------------------------------------------------------------- /contrib/docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | # prepare 6 | export LC_ALL=C.UTF-8 7 | export PYTHONPATH="/usr/share/glib-2.0" 8 | 9 | rm -rf /build/* 10 | 11 | # info 12 | ls -la /build 13 | whoami 14 | 15 | # actual building 16 | meson -Dbuildtype=debug -Db_coverage=true -Dtests-speed=slow . /build 17 | ninja -C /build 18 | meson test -C /build --verbose 19 | 20 | if [[ -x "$(command -v lcov)" ]]; then 21 | ninja -C /build coverage 22 | fi 23 | 24 | if [[ -x "$(command -v scan-build)" ]]; then 25 | ninja -C /build scan-build 26 | 27 | if [[ -n "$(ls -A /build/meson-logs/scanbuild/)" ]]; then 28 | echo "Scan build log found, assuming defects exist" 29 | exit 1 30 | fi 31 | fi 32 | 33 | if [[ -x "$(command -v lcov)" ]]; then 34 | scripts/uncrustify.sh --check 35 | fi 36 | 37 | if [[ -x $(command -v pylint) ]]; then 38 | pylint tests/test-integration 39 | fi 40 | 41 | if [[ -x $(command -v codespell) ]]; then 42 | codespell -S .git -S build 43 | fi 44 | -------------------------------------------------------------------------------- /contrib/js/test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | const Gio = imports.gi.Gio; 22 | const GLib = imports.gi.GLib; 23 | const Lang = imports.lang; 24 | 25 | imports.searchPath.unshift('.'); 26 | const Bolt = imports.client; 27 | 28 | let gotParent = function (p, d, e) { 29 | if (e) { 30 | log(e); 31 | return; 32 | } 33 | 34 | if (!p) { 35 | print (' device: '+ d.Uid + ' -> no parent'); 36 | return; 37 | } 38 | 39 | print (' device: '+ d.Uid + ' -> parent: ' + p.Uid); 40 | 41 | }; 42 | 43 | let client = new Bolt.Client(function (client) { 44 | client.listDevices(function (devices, error) { 45 | if (error) { 46 | print ('error ' + error); 47 | return; 48 | } 49 | 50 | for (let i = 0; i < devices.length; i++) { 51 | let d = devices[i]; 52 | print(' ' + d.Uid + " " + d.Name); 53 | 54 | client.deviceGetParent(d, gotParent); 55 | } 56 | }); 57 | }); 58 | 59 | let loop = new GLib.MainLoop(null, false); 60 | loop.run(); 61 | -------------------------------------------------------------------------------- /data/90-bolt.rules: -------------------------------------------------------------------------------- 1 | # bolt udev rules 2 | # 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | # 5 | # Copyright © 2017 Red Hat, Inc 6 | # 7 | # Authors: 8 | # Christian J. Kellner 9 | # 10 | 11 | ACTION=="remove", GOTO="bolt_end" 12 | 13 | # start bolt service if we have a thunderbolt device connected 14 | SUBSYSTEM=="thunderbolt", TAG+="systemd", ENV{SYSTEMD_WANTS}+="bolt.service" 15 | 16 | LABEL="bolt_end" 17 | -------------------------------------------------------------------------------- /data/bolt.service.in: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Thunderbolt system service 3 | After=polkit.service 4 | Documentation=man:boltd(8) 5 | 6 | [Service] 7 | Type=dbus 8 | BusName=org.freedesktop.bolt 9 | ExecStart=@libexecdir@/boltd 10 | #Environment="G_MESSAGES_DEBUG=all" 11 | Restart=on-failure 12 | NotifyAccess=main 13 | WatchdogSec=3min 14 | 15 | MemoryDenyWriteExecute=yes 16 | PrivateTmp=yes 17 | ProtectControlGroups=yes 18 | ProtectHome=yes 19 | ProtectKernelModules=yes 20 | ProtectSystem=full 21 | RestrictAddressFamilies=AF_NETLINK AF_UNIX 22 | RestrictRealtime=yes 23 | ReadWritePaths=@dbdir@ 24 | SystemCallFilter=~@mount 25 | CapabilityBoundingSet=CAP_NET_ADMIN 26 | 27 | #directory management 28 | RuntimeDirectory=@dbname@ 29 | RuntimeDirectoryPreserve=yes 30 | StateDirectory=@dbname@ 31 | -------------------------------------------------------------------------------- /data/dbus.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | org.freedesktop.bolt.xml 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/org.freedesktop.bolt.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 20 | 21 | 23 | 24 | 25 | 27 | 28 | 30 | 31 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /data/org.freedesktop.bolt.service.in: -------------------------------------------------------------------------------- 1 | [D-BUS Service] 2 | Name=org.freedesktop.bolt 3 | Exec=@libexecdir@/boltd 4 | User=root 5 | SystemdService=bolt.service 6 | -------------------------------------------------------------------------------- /docs/boltd.8.txt: -------------------------------------------------------------------------------- 1 | boltd(8) 2 | ======== 3 | 4 | NAME 5 | ---- 6 | boltd - thunderbolt device managing system daemon 7 | 8 | SYNOPSIS 9 | -------- 10 | *boltd* ['OPTIONS'] 11 | 12 | DESCRIPTION 13 | ----------- 14 | boltd is the thunderbolt device manager daemon. Its goal is to enable 15 | the secure and convenient use of thunderbolt devices by using the 16 | security features of modern thunderbolt controllers. It provides the 17 | `org.freedesktop.bolt` name on the system bus. boltd is autostarted 18 | via systemd/udev if a thunderbolt device is connected. 19 | 20 | The thunderbolt I/O technology works by bridging PCIe between the 21 | controllers on each end of the connection, which in turn means that 22 | devices connected via Thunderbolt are ultimately connected via 23 | PCIe. Therefore thunderbolt can achieve very high connection speeds, 24 | fast enough to even drive external graphics cards. The downside is 25 | that it also makes certain attacks possible. To mitigate these 26 | security problems, the latest version -- known as Thunderbolt 3 -- 27 | supports different *security levels*: 28 | 29 | *none*:: 30 | No security. The behavior is identical to previous Thunderbolt 31 | versions. 32 | 33 | *dponly*:: 34 | No PCIe tunnels are created at all, but DisplayPort tunnels are allowed 35 | and will work. 36 | 37 | *user*:: 38 | Connected devices must be authorized by the user. Only then will the 39 | PCIe tunnels be activated. 40 | 41 | *secure*:: 42 | Basically the same as user mode, but additionally a key will be written 43 | to the device the first time the device is connected. This key will 44 | then be used to verify the identity of the connected device. 45 | 46 | *usbonly*:: 47 | One PCIe tunnel is created to a usb controller in a thunderbolt dock; 48 | no other downstream PCIe tunnels are authorized (needs 4.17 kernel and 49 | recent hardware). 50 | 51 | The primary task of *boltd* is to authorize thunderbolt peripherals if 52 | the security level is either `user` or `secure`. It provides a D-Bus 53 | API to list devices, enroll them (authorize and store them in the 54 | local database) and forget them again (remove previously enrolled 55 | devices). It also emits signals if new devices are connected (or 56 | removed). During enrollment devices can be set to be automatically 57 | authorized as soon as they are connected. A command line tool, called 58 | boltctl(1), can be used to control the daemon and perform all the 59 | above mentioned tasks. 60 | 61 | The pre-boot access control list (*BootACL*) feature is active when 62 | supported by the firmware and when 'boltd' is running on a new enough 63 | Linux kernel (>= 4.17). The 'BootACL' is a list of UUIDs, that can 64 | be written to the thunderbolt controller. If enabled in the BIOS, all 65 | devices in that list will be authorized by the firmware during 66 | pre-boot, which means these devices can be used in the BIOS setup and 67 | also during Linux early boot. NB: *no device verification* is done, 68 | even when the security level is set to 'secure' mode in the BIOS, i.e. 69 | the maximal effective security level for devices in the 'BootACL' is 70 | only 'user'. If 'BootACL' support is present, all new devices will be 71 | automatically added. Devices that are 'forgotten' (removed from 'boltd') 72 | will also be removed from the 'BootACL'. When a controller is offline, 73 | changes to the 'BootACL' will be written to a journal and synchronized 74 | back when the controller is online again. 75 | 76 | 'IOMMU' support: if the hardware and firmware support using the input–output 77 | memory management unit (IOMMU) to restrict direct memory access 78 | to certain safe regions, boltd will detect that feature and change its 79 | behavior: As long as iommu support is active, as indicated by the 80 | iommu_dma_protection sysfs attribute of the domain controller, new devices 81 | will be automatically enrolled with the 'iommu' policy and existing 82 | devices with 'iommu' (or 'auto') policy will be automatically authorized 83 | by boltd without any user interaction. When iommu is not active, devices 84 | that were enrolled with the 'iommu' policy will not be authorized 85 | automatically. The status of iommu support can be inspected by using 86 | *boltctl domains*. 87 | 88 | 89 | OPTIONS 90 | ------- 91 | 92 | *-h, --help*:: 93 | Prints a short help text and exits. 94 | 95 | *--version*:: 96 | Shows the version number and exits. 97 | 98 | *-r, --replace*:: 99 | Replace the currently running boltd instance. 100 | 101 | *--journal*:: 102 | Force logging to the journal. 103 | 104 | *-v, --verbose*:: 105 | Print debug output. 106 | 107 | 108 | ENVIRONMENT 109 | ----------- 110 | 111 | *`RUNTIME_DIRECTORY`*:: 112 | Specifies the path where the daemon stores data that only has 113 | to live as long as the current boot. Will be set automatically 114 | when started via systemd (>= 240). If not set the default path 115 | for runtime data is '/run/boltd'. 116 | 117 | *`STATE_DIRECTORY`*:: 118 | Specifies the path where the daemon stores device information, 119 | including the keys used for authorization. Overwrites the path 120 | that was set at compile time. Will be set automatically when 121 | started via systemd (>= 240). 122 | 123 | *`BOLT_DBPATH`*:: 124 | Same as `STATE_DIRECTORY` but takes precedence over that, if set. 125 | 126 | 127 | EXIT STATUS 128 | ----------- 129 | On success 0 is returned, a non-zero failure code otherwise. 130 | 131 | 132 | Author 133 | ------ 134 | Written by Christian Kellner . 135 | 136 | SEE ALSO 137 | -------- 138 | boltctl(1) 139 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('coverity', type: 'boolean', value: 'false', description: 'Whether or not to do a coverity build') 2 | option('db-path', type: 'string', description: 'DEPRECATED') 3 | option('db-name', type: 'string', value: 'boltd', description: 'Name for the device database') 4 | option('install-tests', type: 'boolean', value: 'false', description: 'Install the tests') 5 | option('man', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Build man pages') 6 | option('privileged-group', type: 'string', value: 'wheel', description: 'Name of privileged group') 7 | option('profiling', type: 'boolean', value: 'false', description: 'Build with profiling support') 8 | option('systemd', type: 'boolean', value: 'true', description: 'DEPRECATED') 9 | option('tests-speed', type: 'combo', choices: ['quick', 'slow'], value: 'quick', description : 'Which tests to run') 10 | -------------------------------------------------------------------------------- /policy/org.freedesktop.bolt.policy.in: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 13 | 14 | Thunderbolt System services 15 | https://github.com/gicmo/bolt 16 | thunderbolt-symbolic 17 | 18 | 19 | Enroll new thunderbolt devices 20 | Authentication is required to enroll thunderbolt devices 21 | thunderbolt-symbolic 22 | 23 | auth_admin 24 | auth_admin 25 | auth_admin_keep 26 | 27 | 28 | 29 | 30 | Authorize thunderbolt devices 31 | Authentication is required to authorize thunderbolt devices 32 | thunderbolt-symbolic 33 | 34 | auth_admin 35 | auth_admin 36 | auth_admin_keep 37 | 38 | 39 | 40 | 41 | Manage thunderbolt devices 42 | Authentication is required to manage thunderbolt devices 43 | thunderbolt-symbolic 44 | 45 | auth_admin 46 | auth_admin 47 | auth_admin_keep 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /policy/org.freedesktop.bolt.rules.in: -------------------------------------------------------------------------------- 1 | // -*- mode: js2 -*- 2 | polkit.addRule(function(action, subject) { 3 | if ((action.id === "org.freedesktop.bolt.enroll" || 4 | action.id === "org.freedesktop.bolt.authorize" || 5 | action.id === "org.freedesktop.bolt.manage") && 6 | subject.active === true && subject.local === true && 7 | subject.isInGroup("@privileged_group@")) { 8 | return polkit.Result.YES; 9 | } 10 | }); 11 | -------------------------------------------------------------------------------- /scripts/git-hooks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # git hooks management 4 | 5 | # global setup 6 | set -u 7 | SRCDIR=${MESON_SOURCE_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null 2>&1 && pwd)} 8 | HOOKDIR="$SRCDIR/scripts/git-hooks/" 9 | DESTDIR="$SRCDIR/.git/hooks" 10 | 11 | cd "$SRCDIR" 12 | declare -a HOOKS=() 13 | readarray -t HOOKS < <(find "$HOOKDIR" -maxdepth 1 -type f -exec basename {} \;) 14 | 15 | # helpers 16 | ensure_destdir () { 17 | if [ ! -d "$DESTDIR" ]; then 18 | echo "$DESTDIR does not exist" 19 | exit 2 20 | fi 21 | } 22 | 23 | # individual commands 24 | check () { 25 | ensure_destdir 26 | 27 | for hook in ${HOOKS[@]}; do 28 | echo -n "$hook " 29 | DEST="$DESTDIR/$hook" 30 | if [ -x "$DEST" ]; then 31 | echo "installed" 32 | else 33 | echo "missing" 34 | fi 35 | done 36 | } 37 | 38 | install () { 39 | ensure_destdir 40 | 41 | RESULT=0 42 | for hook in ${HOOKS[@]}; do 43 | DEST="$DESTDIR/$hook" 44 | if [ -x "$DEST" ]; then 45 | continue 46 | fi 47 | 48 | cp -p "$HOOKDIR/$hook" "$DEST" 49 | chmod a+x "$DEST" 50 | ((RESULT -= 1)) 51 | echo "Installed '$hook' hook" 52 | done 53 | exit $RESULT 54 | } 55 | 56 | uninstall () { 57 | ensure_destdir 58 | 59 | for hook in ${HOOKS[@]}; do 60 | DEST="$DESTDIR/$hook" 61 | if [ ! -x "$DEST" ]; then 62 | continue 63 | fi 64 | 65 | rm "$DEST" 66 | echo "Uninstalled '$hook' hook" 67 | done 68 | } 69 | 70 | # main 71 | 72 | usage_error () { 73 | echo "usage: $0 " 74 | exit 1 75 | } 76 | 77 | if [ "$#" -ne 1 ]; then 78 | usage_error 79 | fi 80 | 81 | case "$1" in 82 | check) 83 | check 84 | ;; 85 | install) 86 | install 87 | ;; 88 | uninstall) 89 | uninstall 90 | ;; 91 | *) 92 | usage_error 93 | ;; 94 | esac 95 | -------------------------------------------------------------------------------- /scripts/git-hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | 3 | exec 1>&2 4 | exec git diff-index --check --cached HEAD -- 5 | -------------------------------------------------------------------------------- /scripts/git-hooks/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Based on ".git/hooks/pre-push.sample" 3 | 4 | remote="$1" 5 | url="$2" # unused 6 | 7 | z40=0000000000000000000000000000000000000000 8 | 9 | while read local_ref local_sha remote_ref remote_sha 10 | do 11 | if [ "$local_sha" = $z40 ]; then 12 | # ignore deletes 13 | continue 14 | fi 15 | 16 | if [ "$remote_sha" = $z40 ]; then 17 | # new branch, examine new commits starting $remote 18 | remote_sha=$(git rev-parse "$remote") 19 | fi 20 | 21 | range="$remote_sha..$local_sha" 22 | 23 | # check for fixup! commit 24 | commit=`git rev-list -n 1 --grep '^fixup! ' "$range"` 25 | if [ -n "$commit" ]; then 26 | echo >&2 "'fixup!' commit in $local_ref, not pushing" 27 | exit 1 28 | fi 29 | 30 | done 31 | 32 | exit 0 33 | -------------------------------------------------------------------------------- /scripts/meson-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -z $MESON_INSTALL_PREFIX ]; then 4 | echo 'This is meant to be run by meson' 5 | exit 1 6 | fi 7 | 8 | BOLT_DBDIR=$1 9 | 10 | echo "Creating database dir: ${BOLT_DBDIR}" 11 | mkdir -p "${DESTDIR}/${BOLT_DBDIR}" 12 | -------------------------------------------------------------------------------- /scripts/uncrustify.cfg: -------------------------------------------------------------------------------- 1 | newlines lf 2 | 3 | input_tab_size 8 4 | output_tab_size 8 5 | 6 | string_escape_char 92 7 | string_escape_char2 0 8 | 9 | # indenting 10 | indent_columns 2 11 | indent_with_tabs 0 12 | indent_align_string True 13 | indent_brace 2 14 | indent_braces false 15 | indent_braces_no_func True 16 | indent_func_call_param false 17 | indent_func_def_param false 18 | indent_func_proto_param false 19 | indent_switch_case 0 20 | indent_case_brace 2 21 | indent_paren_close 1 22 | 23 | # spacing 24 | sp_arith Add 25 | sp_assign Add 26 | sp_enum_assign Add 27 | sp_bool Add 28 | sp_compare Add 29 | sp_inside_paren Remove 30 | sp_inside_fparens Remove 31 | sp_func_def_paren Force 32 | sp_func_proto_paren Force 33 | sp_paren_paren Remove 34 | sp_balance_nested_parens False 35 | sp_paren_brace Remove 36 | sp_before_square Remove 37 | sp_before_squares Remove 38 | sp_inside_square Remove 39 | sp_before_ptr_star Add 40 | sp_between_ptr_star Remove 41 | sp_after_comma Add 42 | sp_before_comma Remove 43 | sp_after_cast Add 44 | sp_sizeof_paren Add 45 | sp_not Remove 46 | sp_inv Remove 47 | sp_addr Remove 48 | sp_member Remove 49 | sp_deref Remove 50 | sp_sign Remove 51 | sp_incdec Remove 52 | sp_attribute_paren remove 53 | sp_macro Force 54 | sp_func_call_paren Force 55 | sp_func_call_user_paren Remove 56 | set func_call_user _ N_ C_ g_autoptr g_auto 57 | sp_brace_typedef add 58 | sp_cond_colon add 59 | sp_cond_question add 60 | sp_defined_paren remove 61 | 62 | # alignment 63 | align_keep_tabs False 64 | align_with_tabs False 65 | align_on_tabstop False 66 | align_number_right False 67 | align_func_params True 68 | align_var_def_span 0 69 | align_var_def_amp_style 1 70 | align_var_def_colon true 71 | align_enum_equ_span 0 72 | align_var_struct_span 2 73 | align_var_def_star_style 2 74 | align_var_def_amp_style 2 75 | align_typedef_span 2 76 | align_typedef_func 0 77 | align_typedef_star_style 2 78 | align_typedef_amp_style 2 79 | 80 | # newlines 81 | nl_assign_leave_one_liners True 82 | nl_enum_leave_one_liners False 83 | nl_func_leave_one_liners False 84 | nl_if_leave_one_liners False 85 | nl_end_of_file Add 86 | nl_assign_brace Remove 87 | nl_func_var_def_blk 1 88 | nl_fcall_brace Add 89 | nl_enum_brace Remove 90 | nl_struct_brace Force 91 | nl_union_brace Force 92 | nl_if_brace Force 93 | nl_brace_else Force 94 | nl_elseif_brace Force 95 | nl_else_brace Add 96 | nl_for_brace Force 97 | nl_while_brace Force 98 | nl_do_brace Force 99 | nl_brace_while Force 100 | nl_switch_brace Force 101 | nl_before_case True 102 | nl_after_case False 103 | nl_func_type_name Force 104 | nl_func_proto_type_name Remove 105 | nl_func_paren Remove 106 | nl_func_decl_start Remove 107 | nl_func_decl_args Force 108 | nl_func_decl_end Remove 109 | nl_fdef_brace Force 110 | nl_after_return False 111 | nl_define_macro False 112 | nl_create_if_one_liner False 113 | nl_create_for_one_liner False 114 | nl_create_while_one_liner False 115 | nl_after_semicolon True 116 | nl_multi_line_cond true 117 | 118 | # mod 119 | # I'd like these to be remove, but that removes brackets in if { if { foo } }, which i dislike 120 | # Not clear what to do about that... 121 | mod_full_brace_for Remove 122 | mod_full_brace_if Remove 123 | mod_full_brace_if_chain True 124 | mod_full_brace_while Remove 125 | mod_full_brace_do Remove 126 | mod_full_brace_nl 3 127 | mod_paren_on_return Remove 128 | 129 | # line splitting 130 | #code_width = 78 131 | ls_for_split_full True 132 | ls_func_split_full True 133 | 134 | # positioning 135 | pos_bool Trail 136 | pos_conditional Trail 137 | 138 | # custom keywords 139 | set FOR udev_list_entry_foreach 140 | -------------------------------------------------------------------------------- /scripts/uncrustify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | SRCROOT=`git rev-parse --show-toplevel` 3 | CFG="$SRCROOT/scripts/uncrustify.cfg" 4 | echo "srcroot: $SRCROOT" 5 | 6 | case "$1" in 7 | -c|--check) 8 | OPTS="--check" 9 | ;; 10 | 11 | *) 12 | OPTS="--replace --no-backup" 13 | ;; 14 | esac 15 | 16 | pushd "$SRCROOT" 17 | uncrustify -c "$CFG" $OPTS `git ls-tree --name-only -r HEAD | grep \\\.[ch]$ | grep -v gvdb | grep -v build/` 18 | RES=$? 19 | popd 20 | exit $RES 21 | -------------------------------------------------------------------------------- /tests/example.bolt.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/mock-sysfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | #include "bolt-enums.h" 27 | #include "bolt-wire.h" 28 | 29 | 30 | G_BEGIN_DECLS 31 | 32 | typedef struct MockDevId 33 | { 34 | 35 | gint vendor_id; 36 | const char *vendor_name; 37 | 38 | gint device_id; 39 | const char *device_name; 40 | 41 | const char *unique_id; 42 | 43 | } MockDevId; 44 | 45 | #define MOCK_TYPE_SYSFS mock_sysfs_get_type () 46 | G_DECLARE_FINAL_TYPE (MockSysfs, mock_sysfs, MOCK, SYSFS, GObject); 47 | 48 | MockSysfs * mock_sysfs_new (void); 49 | 50 | const char * mock_sysfs_force_power_add (MockSysfs *ms); 51 | 52 | gboolean mock_sysfs_force_power_remove (MockSysfs *ms); 53 | 54 | void mock_sysfs_force_power_load (MockSysfs *ms); 55 | 56 | void mock_sysfs_force_power_unload (MockSysfs *ms); 57 | 58 | char * mock_sysfs_force_power_read (MockSysfs *ms); 59 | 60 | gboolean mock_sysfs_force_power_enabled (MockSysfs *ms); 61 | 62 | const char * mock_sysfs_dmi_id_add (MockSysfs *ms, 63 | const char *sys_vendor, 64 | const char *product_name, 65 | const char *product_version); 66 | 67 | gboolean mock_sysfs_dmi_id_remove (MockSysfs *ms); 68 | 69 | const char * mock_sysfs_domain_add (MockSysfs *ms, 70 | BoltSecurity security, 71 | ...) G_GNUC_NULL_TERMINATED; 72 | 73 | const char * mock_sysfs_domain_get_syspath (MockSysfs *ms, 74 | const char *id); 75 | 76 | gboolean mock_sysfs_domain_remove (MockSysfs *ms, 77 | const char *id); 78 | 79 | GStrv mock_sysfs_domain_bootacl_get (MockSysfs *ms, 80 | const char *id, 81 | GError **error); 82 | 83 | gboolean mock_sysfs_domain_bootacl_set (MockSysfs *ms, 84 | const char *id, 85 | GStrv acl, 86 | GError **error); 87 | 88 | gboolean mock_syfs_domain_iommu_set (MockSysfs *ms, 89 | const char *id, 90 | const char *val, 91 | GError **error); 92 | 93 | const char * mock_sysfs_host_add (MockSysfs *ms, 94 | const char *domain, 95 | MockDevId *id); 96 | 97 | void mock_sysfs_host_remove (MockSysfs *ms, 98 | const char *host); 99 | 100 | const char * mock_sysfs_device_add (MockSysfs *ms, 101 | const char *parent, 102 | MockDevId *id, 103 | guint authorized, 104 | const char *key, 105 | gint boot, 106 | BoltLinkSpeed *link); 107 | 108 | const char * mock_sysfs_device_get_syspath (MockSysfs *ms, 109 | const char *id); 110 | 111 | const char * mock_sysfs_device_get_parent (MockSysfs *ms, 112 | const char *id); 113 | 114 | gboolean mock_sysfs_device_remove (MockSysfs *ms, 115 | const char *id); 116 | 117 | gboolean mock_sysfs_set_osrelease (MockSysfs *ms, 118 | const char *version); 119 | 120 | 121 | G_END_DECLS 122 | -------------------------------------------------------------------------------- /tests/pycodestyle.cfg: -------------------------------------------------------------------------------- 1 | [pycodestyle] 2 | max-line-length = 120 3 | -------------------------------------------------------------------------------- /tests/test-device.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-device.h" 24 | 25 | #include "bolt-dbus.h" 26 | #include "bolt-domain.h" 27 | #include "bolt-store.h" 28 | 29 | #include "bolt-error.h" 30 | 31 | #include 32 | 33 | typedef struct 34 | { 35 | int dummy; 36 | } TestDevice; 37 | 38 | static void 39 | test_device_basic (TestDevice *tt, gconstpointer user_data) 40 | { 41 | g_autoptr(BoltDevice) dev = NULL; 42 | g_autoptr(BoltDomain) dom = NULL; 43 | g_autoptr(BoltStore) store = NULL; 44 | g_autoptr(BoltKey) key = NULL; 45 | g_autoptr(GError) err = NULL; 46 | char uid[] = "fbc83890-e9bf-45e5-a777-b3728490989c"; 47 | BoltDeviceType devtype = BOLT_DEVICE_PERIPHERAL; 48 | BoltKeyState keystate; 49 | BoltSecurity sl; 50 | guint gen; 51 | gboolean ok; 52 | 53 | dev = g_object_new (BOLT_TYPE_DEVICE, 54 | "uid", uid, 55 | "name", "Laptop", 56 | "vendor", "GNOME.org", 57 | "type", BOLT_DEVICE_HOST, 58 | "status", BOLT_STATUS_DISCONNECTED, 59 | "generation", 3, 60 | NULL); 61 | 62 | g_assert_nonnull (dev); 63 | 64 | g_object_get (dev, 65 | "store", &store, 66 | "domain", &dom, 67 | "security", &sl, 68 | "generation", &gen, 69 | "type", &devtype, 70 | NULL); 71 | 72 | g_assert_null (store); 73 | g_assert_null (dom); 74 | 75 | g_assert_true (dom == bolt_device_get_domain (dev)); 76 | g_assert_cmpint (sl, ==, BOLT_SECURITY_UNKNOWN); 77 | g_assert_cmpint (gen, ==, 3); 78 | g_assert_cmpint (gen, ==, bolt_device_get_generation (dev)); 79 | g_assert_cmpint (devtype, ==, BOLT_DEVICE_HOST); 80 | g_assert_true (bolt_device_is_host (dev)); 81 | 82 | keystate = bolt_device_get_keystate (dev); 83 | g_assert_cmpint (keystate, ==, BOLT_KEY_MISSING); 84 | 85 | ok = bolt_device_get_key_from_sysfs (dev, &key, &err); 86 | g_assert_error (err, BOLT_ERROR, BOLT_ERROR_BADSTATE); 87 | g_assert_false (ok); 88 | } 89 | 90 | int 91 | main (int argc, char **argv) 92 | { 93 | setlocale (LC_ALL, ""); 94 | 95 | g_test_init (&argc, &argv, NULL); 96 | 97 | bolt_dbus_ensure_resources (); 98 | 99 | g_test_add ("/device/basic", 100 | TestDevice, 101 | NULL, 102 | NULL, 103 | test_device_basic, 104 | NULL); 105 | 106 | return g_test_run (); 107 | } 108 | -------------------------------------------------------------------------------- /tests/test-enums.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "test-enum-types.h" 24 | /** 25 | * BoltTestEnum 26 | * @BOLT_TEST_UNKNOWN: Unknown 27 | * @BOLT_TEST_ONE: One 28 | * @BOLT_TEST_TOW: Two 29 | * @BOLT_TEST_THRE: Three 30 | * 31 | * Test enumeration. 32 | */ 33 | typedef enum { 34 | 35 | BOLT_TEST_UNKNOWN = -1, 36 | BOLT_TEST_ONE, 37 | BOLT_TEST_TWO, 38 | BOLT_TEST_THREE 39 | 40 | } BoltTestEnum; 41 | 42 | 43 | /** 44 | * BoltTestFlags: 45 | * @BOLT_KITT_DISABLED: Flag for everthying is disabled. 46 | * @BOLT_KITT_ENABLED: Enabled flag. 47 | * @BOLT_KITT_SSPM: Super Pursuit Mode. 48 | * @BOLT_KITT_TURBO_BOOST: Turbo Boost. 49 | * @BOLT_KITT_SKI_MODE: Ski Mode. 50 | * 51 | * KITT features. 52 | */ 53 | typedef enum { /*< flags >*/ 54 | 55 | BOLT_KITT_DISABLED = 0, 56 | BOLT_KITT_ENABLED = 1, 57 | BOLT_KITT_SSPM = 1 << 1, 58 | BOLT_KITT_TURBO_BOOST = 1 << 2, 59 | BOLT_KITT_SKI_MODE = 1 << 3, 60 | 61 | BOLT_KITT_DEFAULT = BOLT_KITT_ENABLED | BOLT_KITT_SSPM, 62 | 63 | } BoltKittFlags; 64 | -------------------------------------------------------------------------------- /tests/test-reaper.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2020 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-reaper.h" 24 | 25 | #include "bolt-dbus.h" 26 | #include "bolt-unix.h" 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | 34 | typedef struct 35 | { 36 | int dummy; 37 | } TestReaper; 38 | 39 | static gboolean 40 | warn_quit_loop (gpointer user_data) 41 | { 42 | GMainLoop *loop = user_data; 43 | 44 | g_warning ("timeout reached"); 45 | g_main_loop_quit (loop); 46 | 47 | return G_SOURCE_REMOVE; 48 | } 49 | 50 | static void 51 | process_died (GObject *gobject, 52 | guint pid, 53 | const char *name, 54 | gpointer user_data) 55 | { 56 | 57 | GMainLoop *loop = user_data; 58 | 59 | g_debug ("%u (%s) died", pid, name); 60 | 61 | if (g_main_loop_is_running (loop)) 62 | g_main_loop_quit (loop); 63 | } 64 | 65 | /* */ 66 | 67 | static void 68 | test_reaper_object (TestReaper *tt, gconstpointer user) 69 | { 70 | g_autoptr(BoltReaper) reaper = NULL; 71 | guint timeout; 72 | gboolean found; 73 | 74 | reaper = g_object_new (BOLT_TYPE_REAPER, NULL); 75 | 76 | g_object_get (reaper, "timeout", &timeout, NULL); 77 | g_assert_cmpuint (timeout, >, 0); 78 | 79 | g_clear_object (&reaper); 80 | 81 | reaper = g_object_new (BOLT_TYPE_REAPER, "timeout", 10, NULL); 82 | g_object_get (reaper, "timeout", &timeout, NULL); 83 | g_assert_cmpuint (timeout, ==, 10); 84 | 85 | bolt_reaper_add_pid (reaper, 23, NULL); 86 | 87 | found = bolt_reaper_has_pid (reaper, 23); 88 | g_assert_true (found); 89 | 90 | found = bolt_reaper_del_pid (reaper, 23); 91 | g_assert_true (found); 92 | 93 | found = bolt_reaper_del_pid (reaper, 23); 94 | g_assert_false (found); 95 | } 96 | 97 | static void 98 | test_reaper_basic (TestReaper *tt, gconstpointer user) 99 | { 100 | g_autoptr(BoltReaper) reaper = NULL; 101 | g_autoptr(GMainLoop) loop = NULL; 102 | guint tid; 103 | pid_t pid; 104 | int r; 105 | 106 | pid = fork (); 107 | g_assert_cmpint (pid, !=, -1); 108 | 109 | if (pid == 0) 110 | /* child, do nothing but exit */ 111 | exit (0); 112 | 113 | g_assert_true (bolt_pid_is_alive (pid)); 114 | 115 | pid = waitpid (pid, &r, 0); 116 | g_assert_cmpint (pid, >, 0); 117 | g_assert_cmpint (r, ==, 0); 118 | 119 | loop = g_main_loop_new (NULL, FALSE); 120 | reaper = g_object_new (BOLT_TYPE_REAPER, 121 | "timeout", 500, 122 | NULL); 123 | g_assert_nonnull (reaper); 124 | 125 | bolt_reaper_add_pid (reaper, (pid_t) pid, "foo"); 126 | 127 | g_signal_connect (reaper, "process-died", 128 | G_CALLBACK (process_died), 129 | loop); 130 | 131 | tid = g_timeout_add_seconds (5, warn_quit_loop, loop); 132 | g_main_loop_run (loop); 133 | g_clear_handle_id (&tid, g_source_remove); 134 | 135 | } 136 | 137 | int 138 | main (int argc, char **argv) 139 | { 140 | setlocale (LC_ALL, ""); 141 | 142 | g_test_init (&argc, &argv, NULL); 143 | 144 | bolt_dbus_ensure_resources (); 145 | 146 | g_test_add ("/reaper/object", 147 | TestReaper, 148 | NULL, 149 | NULL, 150 | test_reaper_object, 151 | NULL); 152 | 153 | g_test_add ("/reaper/basic", 154 | TestReaper, 155 | NULL, 156 | NULL, 157 | test_reaper_basic, 158 | NULL); 159 | 160 | return g_test_run (); 161 | } 162 | -------------------------------------------------------------------------------- /tests/test-wire.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 Red Hat, Inc 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. If not, see . 16 | * 17 | * Authors: 18 | * Christian J. Kellner 19 | */ 20 | 21 | #include "config.h" 22 | 23 | #include "bolt-wire.h" 24 | 25 | #include "bolt-error.h" 26 | #include "test-enums.h" 27 | #include "bolt-test-resources.h" 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | typedef struct TestWire 36 | { 37 | int dummy; 38 | } TestWire; 39 | 40 | static void 41 | test_linkspeed_basic (TestWire *tt, gconstpointer data) 42 | { 43 | BoltLinkSpeed a = { 44 | .rx.speed = 10, 45 | .rx.lanes = 1, 46 | .tx.speed = 20, 47 | .tx.lanes = 2 48 | }; 49 | BoltLinkSpeed b = { 50 | .rx.speed = 20, 51 | .rx.lanes = 2, 52 | .tx.speed = 10, 53 | .tx.lanes = 1 54 | }; 55 | g_autofree BoltLinkSpeed *c = NULL; 56 | 57 | g_assert_false (bolt_link_speed_equal (&a, &b)); 58 | b = a; 59 | g_assert_true (bolt_link_speed_equal (&a, &b)); 60 | 61 | c = bolt_link_speed_copy (&a); 62 | g_assert_true (bolt_link_speed_equal (&a, c)); 63 | } 64 | 65 | int 66 | main (int argc, char **argv) 67 | { 68 | setlocale (LC_ALL, ""); 69 | 70 | g_test_init (&argc, &argv, NULL); 71 | 72 | g_test_add ("/common/linkseed/basic", 73 | TestWire, 74 | NULL, 75 | NULL, 76 | test_linkspeed_basic, 77 | NULL); 78 | 79 | return g_test_run (); 80 | } 81 | -------------------------------------------------------------------------------- /tests/tests.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | example.bolt.xml 5 | 6 | 7 | --------------------------------------------------------------------------------