mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 22:47:50 +00:00
file_vault: GUI control for encrypted virtual FS's
Warning! The current version of the file vault is not thought for productive use but for mere demonstrational purpose! Please refrain from storing sensitive data with it! The File Vault component implements a graphical frontend for setting up and controlling encrypted virtual file systems using the Consistent Block Encrypter (CBE) for encryption and snapshot management. For more details see 'repos/gems/src/app/file_vault/README'. Fixes #4032
This commit is contained in:
parent
3e375e4315
commit
870c5c7a81
1
repos/gems/recipes/pkg/file_vault/README
Normal file
1
repos/gems/recipes/pkg/file_vault/README
Normal file
@ -0,0 +1 @@
|
||||
See repos/gems/src/app/file_vault/README.
|
19
repos/gems/recipes/pkg/file_vault/archives
Normal file
19
repos/gems/recipes/pkg/file_vault/archives
Normal file
@ -0,0 +1,19 @@
|
||||
_/src/init
|
||||
_/src/libc
|
||||
_/src/libpng
|
||||
_/src/zlib
|
||||
_/src/fs_query
|
||||
_/src/menu_view
|
||||
_/src/cbe
|
||||
_/src/spark
|
||||
_/src/libsparkcrypto
|
||||
_/src/vfs_block
|
||||
_/src/vfs_jitterentropy
|
||||
_/src/vfs
|
||||
_/src/openssl
|
||||
_/src/fs_tool
|
||||
_/src/fs_utils
|
||||
_/src/posix
|
||||
_/src/rump
|
||||
_/src/sandbox
|
||||
_/src/file_vault
|
1
repos/gems/recipes/pkg/file_vault/hash
Normal file
1
repos/gems/recipes/pkg/file_vault/hash
Normal file
@ -0,0 +1 @@
|
||||
2021-04-26-a 405015723954822d3672b119d82e96262fe6763c
|
105
repos/gems/recipes/pkg/file_vault/runtime
Normal file
105
repos/gems/recipes/pkg/file_vault/runtime
Normal file
@ -0,0 +1,105 @@
|
||||
<runtime ram="220M" caps="2200" binary="init">
|
||||
|
||||
<provides>
|
||||
<file_system/>
|
||||
</provides>
|
||||
|
||||
<requires>
|
||||
<file_system label="data" writeable="yes"/>
|
||||
<file_system label="trust_anchor" writeable="yes"/>
|
||||
<file_system label="fonts" writeable="no"/>
|
||||
<rm/>
|
||||
<gui/>
|
||||
<timer/>
|
||||
</requires>
|
||||
|
||||
<content>
|
||||
<rom label="init"/>
|
||||
<rom label="ld.lib.so"/>
|
||||
<rom label="libc.lib.so"/>
|
||||
<rom label="libm.lib.so"/>
|
||||
<rom label="libpng.lib.so"/>
|
||||
<rom label="zlib.lib.so"/>
|
||||
<rom label="fs_query"/>
|
||||
<rom label="menu_view"/>
|
||||
<rom label="vfs"/>
|
||||
<rom label="vfs.lib.so"/>
|
||||
<rom label="vfs_block"/>
|
||||
<rom label="vfs_jitterentropy.lib.so"/>
|
||||
<rom label="vfs_cbe.lib.so"/>
|
||||
<rom label="vfs_cbe_crypto_aes_cbc.lib.so"/>
|
||||
<rom label="vfs_cbe_trust_anchor.lib.so"/>
|
||||
<rom label="cbe_cxx.lib.so"/>
|
||||
<rom label="cbe_init_cxx.lib.so"/>
|
||||
<rom label="cbe_init"/>
|
||||
<rom label="cbe_init_trust_anchor"/>
|
||||
<rom label="libcrypto.lib.so"/>
|
||||
<rom label="rump.lib.so"/>
|
||||
<rom label="vfs_rump.lib.so"/>
|
||||
<rom label="rump_fs.lib.so"/>
|
||||
<rom label="sandbox.lib.so"/>
|
||||
<rom label="libsparkcrypto.lib.so"/>
|
||||
<rom label="spark.lib.so"/>
|
||||
<rom label="fs_tool"/>
|
||||
<rom label="mke2fs"/>
|
||||
<rom label="resize2fs"/>
|
||||
<rom label="posix.lib.so"/>
|
||||
<rom label="file_vault"/>
|
||||
<rom label="file_vault-sync_to_cbe_vfs_init"/>
|
||||
<rom label="file_vault-truncate_file"/>
|
||||
<rom label="menu_view_styles.tar"/>
|
||||
</content>
|
||||
|
||||
<config>
|
||||
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="Gui"/>
|
||||
<service name="Timer"/>
|
||||
<service name="File_system"/>
|
||||
</parent-provides>
|
||||
|
||||
<service name="File_system">
|
||||
<default-policy>
|
||||
<child name="file_vault"/>
|
||||
</default-policy>
|
||||
</service>
|
||||
|
||||
<start name="file_vault" caps="2000">
|
||||
<resource name="RAM" quantum="200M"/>
|
||||
<provides>
|
||||
<service name="File_system"/>
|
||||
</provides>
|
||||
<config>
|
||||
<vfs>
|
||||
<dir name="cbe">
|
||||
<fs label="cbe"/>
|
||||
</dir>
|
||||
</vfs>
|
||||
</config>
|
||||
<route>
|
||||
<service name="File_system" label="cbe_trust_anchor_vfs -> storage_dir"> <parent label="trust_anchor"/> </service>
|
||||
<service name="File_system" label="vfs_block -> "> <parent label="data"/> </service>
|
||||
<service name="File_system" label="cbe"> <parent label="data"/> </service>
|
||||
<service name="File_system" label="fs_query -> "> <parent label="data"/> </service>
|
||||
<service name="File_system" label="image_fs_query -> "> <parent label="data"/> </service>
|
||||
<service name="File_system" label="cbe_vfs -> cbe_fs"> <parent label="data"/> </service>
|
||||
<service name="File_system" label="truncate_file -> cbe"> <parent label="data"/> </service>
|
||||
<service name="File_system" label="menu_view -> fonts"> <parent label="fonts"/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Gui"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="RM"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
</config>
|
||||
|
||||
</runtime>
|
3
repos/gems/recipes/src/file_vault/content.mk
Normal file
3
repos/gems/recipes/src/file_vault/content.mk
Normal file
@ -0,0 +1,3 @@
|
||||
SRC_DIR := src/app/file_vault
|
||||
|
||||
include $(GENODE_DIR)/repos/base/recipes/src/content.inc
|
1
repos/gems/recipes/src/file_vault/hash
Normal file
1
repos/gems/recipes/src/file_vault/hash
Normal file
@ -0,0 +1 @@
|
||||
2021-04-26-a f1ce555a3cd5070870e541aab731d5b8aa7ed30b
|
11
repos/gems/recipes/src/file_vault/used_apis
Normal file
11
repos/gems/recipes/src/file_vault/used_apis
Normal file
@ -0,0 +1,11 @@
|
||||
base
|
||||
os
|
||||
cbe
|
||||
vfs
|
||||
report_session
|
||||
gui_session
|
||||
input_session
|
||||
framebuffer_session
|
||||
posix
|
||||
libc
|
||||
sandbox
|
300
repos/gems/run/file_vault.run
Normal file
300
repos/gems/run/file_vault.run
Normal file
@ -0,0 +1,300 @@
|
||||
assert_spec x86_64
|
||||
|
||||
build { app/file_vault }
|
||||
|
||||
create_boot_directory
|
||||
|
||||
append archives "
|
||||
[depot_user]/src/[base_src]
|
||||
[depot_user]/pkg/[drivers_interactive_pkg]
|
||||
[depot_user]/pkg/fonts_fs
|
||||
[depot_user]/src/init
|
||||
[depot_user]/src/nitpicker
|
||||
[depot_user]/src/libc
|
||||
[depot_user]/src/libpng
|
||||
[depot_user]/src/zlib
|
||||
[depot_user]/src/fs_query
|
||||
[depot_user]/src/menu_view
|
||||
[depot_user]/src/cbe
|
||||
[depot_user]/src/spark
|
||||
[depot_user]/src/libsparkcrypto
|
||||
[depot_user]/src/vfs_block
|
||||
[depot_user]/src/vfs_jitterentropy
|
||||
[depot_user]/src/vfs
|
||||
[depot_user]/src/openssl
|
||||
[depot_user]/src/fs_tool
|
||||
[depot_user]/src/fs_utils
|
||||
[depot_user]/src/posix
|
||||
[depot_user]/src/rump
|
||||
[depot_user]/src/sandbox
|
||||
"
|
||||
|
||||
append_if [have_board linux] archives [depot_user]/src/lx_fs
|
||||
|
||||
import_from_depot $archives
|
||||
|
||||
append config {
|
||||
|
||||
<config>
|
||||
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="LOG"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="PD"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
</parent-provides>
|
||||
|
||||
<start name="timer" caps="100">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
<route>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="drivers" caps="1500" managing_system="yes">
|
||||
<resource name="RAM" quantum="64M"/>
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Capture"> <child name="nitpicker"/> </service>
|
||||
<service name="Event"> <child name="nitpicker"/> </service>
|
||||
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="RM"> <parent/> </service>
|
||||
<service name="IO_MEM"> <parent/> </service>
|
||||
<service name="IO_PORT"> <parent/> </service>
|
||||
<service name="IRQ"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="nitpicker" caps="100">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides>
|
||||
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
|
||||
</provides>
|
||||
<config focus="rom">
|
||||
<capture/> <event/>
|
||||
<background color="#123456"/>
|
||||
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
|
||||
<domain name="default" layer="3" content="client" label="no" hover="always" />
|
||||
<domain name="second" layer="2" xpos="200" ypos="300" content="client" label="no" hover="always" />
|
||||
|
||||
<policy label_prefix="pointer" domain="pointer"/>
|
||||
<policy label_prefix="text_area.2" domain="second"/>
|
||||
<default-policy domain="default"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Timer"> <child name="timer" /> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="pointer" caps="100">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<route>
|
||||
<service name="Gui"> <child name="nitpicker" /> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
}
|
||||
if {[have_board linux]} {
|
||||
|
||||
append config {
|
||||
|
||||
<start name="data_fs" caps="200" ld="no">
|
||||
<binary name="lx_fs"/>
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides>
|
||||
<service name="File_system"/>
|
||||
</provides>
|
||||
<config>
|
||||
<policy label="file_vault -> data"
|
||||
root="/file_vault_dir/data"
|
||||
writeable="yes"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="trust_anchor_fs" caps="200" ld="no">
|
||||
<binary name="lx_fs"/>
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides>
|
||||
<service name="File_system"/>
|
||||
</provides>
|
||||
<config>
|
||||
<policy label="file_vault -> trust_anchor"
|
||||
root="/file_vault_dir/trust_anchor"
|
||||
writeable="yes"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
append config {
|
||||
|
||||
<start name="data_fs" caps="2000">
|
||||
<binary name="vfs"/>
|
||||
<resource name="RAM" quantum="200M"/>
|
||||
<provides><service name="File_system"/></provides>
|
||||
<config>
|
||||
<vfs>
|
||||
<dir name="data">
|
||||
<ram/>
|
||||
</dir>
|
||||
</vfs>
|
||||
<policy label="file_vault -> data" root="/data" writeable="yes"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="trust_anchor_fs" caps="100">
|
||||
<binary name="vfs"/>
|
||||
<resource name="RAM" quantum="5M"/>
|
||||
<provides><service name="File_system"/></provides>
|
||||
<config>
|
||||
<vfs>
|
||||
<dir name="trust_anchor">
|
||||
<ram/>
|
||||
</dir>
|
||||
</vfs>
|
||||
<policy label="file_vault -> trust_anchor" root="/trust_anchor" writeable="yes"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
}
|
||||
}
|
||||
append config {
|
||||
|
||||
<start name="fonts_fs" caps="150">
|
||||
<binary name="vfs"/>
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides>
|
||||
<service name="File_system"/>
|
||||
</provides>
|
||||
<config>
|
||||
<vfs>
|
||||
<rom name="Vera.ttf"/>
|
||||
<rom name="VeraMono.ttf"/>
|
||||
<dir name="fonts">
|
||||
<dir name="title">
|
||||
<ttf name="regular" path="/Vera.ttf" size_px="18" cache="256K"/>
|
||||
</dir>
|
||||
<dir name="text">
|
||||
<ttf name="regular" path="/Vera.ttf" size_px="14" cache="256K"/>
|
||||
</dir>
|
||||
<dir name="annotation">
|
||||
<ttf name="regular" path="/Vera.ttf" size_px="11" cache="256K"/>
|
||||
</dir>
|
||||
<dir name="monospace">
|
||||
<ttf name="regular" path="/VeraMono.ttf" size_px="14" cache="256K"/>
|
||||
</dir>
|
||||
</dir>
|
||||
</vfs>
|
||||
|
||||
<policy label="file_vault -> fonts" root="/fonts" />
|
||||
</config>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="fonts_fs.config"/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="file_vault" caps="2000">
|
||||
<resource name="RAM" quantum="200M"/>
|
||||
<config>
|
||||
<vfs>
|
||||
<dir name="cbe">
|
||||
<fs label="cbe"/>
|
||||
</dir>
|
||||
</vfs>
|
||||
</config>
|
||||
<route>
|
||||
<service name="File_system" label="cbe_trust_anchor_vfs -> storage_dir"> <child name="trust_anchor_fs" label="file_vault -> trust_anchor"/> </service>
|
||||
<service name="File_system" label="vfs_block -> "> <child name="data_fs" label="file_vault -> data"/> </service>
|
||||
<service name="File_system" label="cbe"> <child name="data_fs" label="file_vault -> data"/> </service>
|
||||
<service name="File_system" label="fs_query -> "> <child name="data_fs" label="file_vault -> data"/> </service>
|
||||
<service name="File_system" label="image_fs_query -> "> <child name="data_fs" label="file_vault -> data"/> </service>
|
||||
<service name="File_system" label="cbe_vfs -> cbe_fs"> <child name="data_fs" label="file_vault -> data"/> </service>
|
||||
<service name="File_system" label="truncate_file -> cbe"> <child name="data_fs" label="file_vault -> data"/> </service>
|
||||
<service name="File_system" label="menu_view -> fonts"> <child name="fonts_fs" label="file_vault -> fonts"/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Gui"> <child name="nitpicker"/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="RM"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
set fd [open [run_dir]/genode/focus w]
|
||||
puts $fd "<focus label=\"file_vault -> \"/>"
|
||||
close $fd
|
||||
|
||||
if {[have_board linux]} {
|
||||
exec mkdir -p bin/file_vault_dir/data
|
||||
exec mkdir -p bin/file_vault_dir/trust_anchor
|
||||
}
|
||||
|
||||
append boot_modules {
|
||||
file_vault
|
||||
file_vault-sync_to_cbe_vfs_init
|
||||
file_vault-truncate_file
|
||||
}
|
||||
|
||||
append qemu_args " -display gtk "
|
||||
|
||||
append_if [have_board linux] boot_modules file_vault_dir
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
run_genode_until forever
|
149
repos/gems/src/app/file_vault/README
Normal file
149
repos/gems/src/app/file_vault/README
Normal file
@ -0,0 +1,149 @@
|
||||
The file vault
|
||||
Martin Stein
|
||||
|
||||
Warning
|
||||
~~~~~~~
|
||||
|
||||
The current version of the file vault is not thought for productive use but
|
||||
for mere demonstrational purpose! Please refrain from storing sensitive data
|
||||
with it!
|
||||
|
||||
|
||||
Brief
|
||||
~~~~~
|
||||
|
||||
The file vault is a graphical front end for creating and controlling a virtual
|
||||
encrypted block device using Genodes Consistent Block Encrypter (CBE). The
|
||||
vault also takes care of creating and managing a Trust Anchor for securing
|
||||
the block device and formatting the block device with the ext2 file system
|
||||
which is then provided to clients through Genodes File System service.
|
||||
|
||||
|
||||
Internal structure
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The file vault uses the Sandbox library to spawn child components according to
|
||||
its needs. It starts, closes or adapts children by re-writing the Sandbox
|
||||
configuration and listens to the Sandbox state report in order to wait for a
|
||||
specific child to finish or recognize resource requests.
|
||||
|
||||
One child that is always present is an instance of the Menu View component used
|
||||
by the vault to display its dialog window. The user input however is received
|
||||
and handled by the vault itself, which, if necessary, then adapts the
|
||||
graphical output accordingly by re-writing the Menu View configuration. In
|
||||
order to correlate input events to GUI changes, the vault always keeps track
|
||||
of the currently hovered GUI element by listening to the hover report of the
|
||||
Menu View child.
|
||||
|
||||
Whenever possible, the vault doesn't access the back end file systems itself
|
||||
but instead spawns helper components like fs_tool or fs_query. This allows the
|
||||
vault to remain simple and protected against problems during file system
|
||||
access.
|
||||
|
||||
In general, the implementation of the file vault tries to set the focus on
|
||||
state-driven decisions. The internal state machine of the vault is divided
|
||||
into 4 major steps: Setup, Startup, Controls, and Shutdown.
|
||||
|
||||
Setup means creating a new Trust Anchor and CBE device as well as formatting
|
||||
the CBE device. Startup means bringing up an already existing Trust Anchor
|
||||
and CBE device for use. Controls means showing the main window that allows
|
||||
manipulating a running CBE device (snapshot management, rekeying, resizing).
|
||||
Consequently, the Controls step follows after a successful Setup or Startup
|
||||
step. From the Controls step, the user can trigger a transition to the Shutdown
|
||||
step. Shutdown means gracefully terminating the use of a running CBE device and
|
||||
closing the file vault.
|
||||
|
||||
Each of these major steps is subdivided into smaller steps. For instance, the
|
||||
startup consists of requesting the user to input the device passphrase,
|
||||
unlocking the trust anchor, and starting the CBE device driver. Examining all
|
||||
minor steps would be to much in the context of this document but the class
|
||||
_File_vault::Main::State_ in _gems/src/app/file_vault/main.cc_ lists them in
|
||||
very descriptive way.
|
||||
|
||||
When the vault is started, it will first try to read the initial state from
|
||||
the _/file_vault/state_ file in the back-end file system. There are basically
|
||||
only two results to this: If the file doesn't exist, the Setup step is startet.
|
||||
If the file exists, however, it's expected to yield the initial state of the
|
||||
Startup step indicating that the Setup step has already been done on this back
|
||||
end during a former run of the file vault.
|
||||
|
||||
Once the CBE device is up and running, the file vault enters the Controls
|
||||
step. This step has several sub-states, for instance the states of rekeying or
|
||||
creating a snapshot (_File_vault::Main::Rekeying_state_,
|
||||
_File_vault::Main::Create_snapshot_state_, ...). This is because each of these
|
||||
operations can be executed independent from each other and in parallel. In
|
||||
order to execute the operations, the vault accesses the VFS control interface
|
||||
of the CBE (the CBE VFS plugin) spawned in a dedicated VFS server child.
|
||||
|
||||
Like with the back-end file systems, the vault doesn't access the CBE VFS
|
||||
itself when executing a device operation. It rather spawns an fs_tool instance
|
||||
to write to the file that starts the operation and an fs_query instance to
|
||||
watch the file that provides the operation progress.
|
||||
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The file vault should always have the following configuration:
|
||||
|
||||
! <config>
|
||||
! <vfs>
|
||||
! <dir name="cbe">
|
||||
! <fs label="cbe"/>
|
||||
! </dir>
|
||||
! </vfs>
|
||||
! </config>
|
||||
|
||||
The vault doesn't consider any further user configuration.
|
||||
|
||||
|
||||
Provided service and session requests
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The vault provides a File System service to the ext2 file system once a CBE
|
||||
device was successfully created and formatted respectively unlocked. Besides
|
||||
the common Genode environment sessions, the vault requests one File System
|
||||
session to a fonts file system, one File System session for the back-end
|
||||
storage of the Trust Anchor, several File System session for the file system
|
||||
that holds the CBE image file and the persistent vault data, one Gui session,
|
||||
several timer sessions and an RM session for the Rump kernel it spawns.
|
||||
|
||||
|
||||
Further resources
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The _gems/run/file_vault.run_ provides an example on how to manually integrate
|
||||
the file vault. It can also be used for analyzing and developing the vault -
|
||||
when targeting native Linux execution even with a persistent storage back-end.
|
||||
The file vault was also packaged in _gems/recipes/pkg/file_vault_ and can be
|
||||
deployed in Sculpt via _+ -> depot -> mstein -> Tools -> File Vault_.
|
||||
|
||||
|
||||
Open issues
|
||||
~~~~~~~~~~~
|
||||
|
||||
* The vault should show the percantage of used and free blocks in the CBE trees
|
||||
in order to enable the user to resize or sync to prevent an out-of-resource
|
||||
situation.
|
||||
* Although the Trust Anchor data (private key and superblock hash) can
|
||||
already be stored on a separate device like an USB stick it still has to be
|
||||
exposed to the system (device driver, file system driver, file vault)
|
||||
during operation as the file vault yet can't access "real" Trust-Anchor
|
||||
interfaces like OpenPGP-Smartcard.
|
||||
* While some device controls (rekeying, resizing, ...) can be controlled via
|
||||
the vault only in a serial way (the button only shows up again as soon as
|
||||
the operation is done) creating and discarding snapshots is controlled in a
|
||||
fire-and-forget fashion (the button immediately shows up again). This is
|
||||
because the CBE VFS yet doesn't fully propagate the completely asynchronous
|
||||
way of handling requests of the CBE.
|
||||
* The creation of the CBE image file is done yet in serial inside the vault
|
||||
itself which causes the GUI to hang till the image creation is done.
|
||||
* Shrinking the client FS or the journaling buffer is not yet supported.
|
||||
* Creating, discarding, and accessing snapshots isn't supported by now in the
|
||||
file vault, although the underlying CBE and its VFS plugin have full support.
|
||||
* The CBE might run into a ressource limit when writing block data or replacing
|
||||
the block encryption key. This is because it doesn't take care yet whether
|
||||
its Free Tree has enough free blocks left for finishing an operation. It will
|
||||
just through an exception in the middle of the operation. This won't affect
|
||||
the integrity of the vault on disk but might lead to the loss of cached
|
||||
block data.
|
58
repos/gems/src/app/file_vault/capacity.cc
Normal file
58
repos/gems/src/app/file_vault/capacity.cc
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* \brief Printable byte capacity
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2018-04-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* local includes */
|
||||
#include <capacity.h>
|
||||
|
||||
|
||||
/**************
|
||||
** Capacity_**
|
||||
**************/
|
||||
|
||||
void File_vault::Capacity::print(Output &out) const
|
||||
{
|
||||
static constexpr uint64_t KB = 1024;
|
||||
static constexpr uint64_t MB = 1024 * KB;
|
||||
static constexpr uint64_t GB = 1024 * MB;
|
||||
|
||||
Text const text {
|
||||
(_value >= GB) ? Text((float)_value/GB, " GiB") :
|
||||
(_value >= MB) ? Text((float)_value/MB, " MiB") :
|
||||
(_value >= KB) ? Text((float)_value/KB, " KiB") :
|
||||
Text(_value, " bytes") };
|
||||
|
||||
Genode::print(out, text);
|
||||
}
|
||||
|
||||
|
||||
File_vault::Capacity::Capacity(uint64_t value)
|
||||
:
|
||||
_value { value }
|
||||
{ }
|
||||
|
||||
|
||||
/*********************
|
||||
** Capacity_string **
|
||||
*********************/
|
||||
|
||||
File_vault::Capacity_string::Capacity_string(uint64_t value)
|
||||
:
|
||||
Capacity::Text { Capacity { value } }
|
||||
{ }
|
||||
|
||||
|
||||
File_vault::Capacity_string::operator char const *()
|
||||
{
|
||||
return Capacity::Text::string();
|
||||
}
|
51
repos/gems/src/app/file_vault/capacity.h
Normal file
51
repos/gems/src/app/file_vault/capacity.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* \brief Printable byte capacity
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2018-04-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _CAPACITY_H_
|
||||
#define _CAPACITY_H_
|
||||
|
||||
/* local includes */
|
||||
#include <types.h>
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
class Capacity;
|
||||
class Capacity_string;
|
||||
}
|
||||
|
||||
class File_vault::Capacity
|
||||
{
|
||||
private:
|
||||
|
||||
uint64_t const _value;
|
||||
|
||||
public:
|
||||
|
||||
using Text = String<64>;
|
||||
|
||||
Capacity(uint64_t value);
|
||||
|
||||
void print(Output &out) const;
|
||||
};
|
||||
|
||||
class File_vault::Capacity_string : public Capacity::Text
|
||||
{
|
||||
public:
|
||||
|
||||
Capacity_string(uint64_t value);
|
||||
|
||||
operator char const *();
|
||||
};
|
||||
|
||||
#endif /* _CAPACITY_H_ */
|
70
repos/gems/src/app/file_vault/child_exit_state.h
Normal file
70
repos/gems/src/app/file_vault/child_exit_state.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* \brief Utility for querying the child-exit state from init's state report
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2021-03-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _CHILD_EXIT_STATE_H_
|
||||
#define _CHILD_EXIT_STATE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/xml_node.h>
|
||||
|
||||
/* local includes */
|
||||
#include <types.h>
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
class Child_exit_state;
|
||||
}
|
||||
|
||||
class File_vault::Child_exit_state
|
||||
{
|
||||
public:
|
||||
|
||||
typedef String<128> Name;
|
||||
typedef String<16> Version;
|
||||
|
||||
private:
|
||||
|
||||
bool _exists = false;
|
||||
bool _exited = false;
|
||||
bool _responsive = true;
|
||||
int _code = 0;
|
||||
Version _version { };
|
||||
|
||||
public:
|
||||
|
||||
Child_exit_state(Xml_node init_state, Name const &name)
|
||||
{
|
||||
init_state.for_each_sub_node("child", [&] (Xml_node child) {
|
||||
if (child.attribute_value("name", Name()) == name) {
|
||||
_exists = true;
|
||||
_version = child.attribute_value("version", Version());
|
||||
|
||||
if (child.has_attribute("exited")) {
|
||||
_exited = true;
|
||||
_code = child.attribute_value("exited", 0L);
|
||||
}
|
||||
|
||||
_responsive = (child.attribute_value("skipped_heartbeats", 0U) <= 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool exists() const { return _exists ; }
|
||||
bool exited() const { return _exited ; }
|
||||
bool responsive() const { return _responsive ; }
|
||||
int code() const { return _code ; }
|
||||
Version version() const { return _version ; }
|
||||
};
|
||||
|
||||
#endif /* _CHILD_EXIT_STATE_H_ */
|
147
repos/gems/src/app/file_vault/child_state.h
Normal file
147
repos/gems/src/app/file_vault/child_state.h
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* \brief Runtime state of a child hosted in the runtime subsystem
|
||||
* \author Martin Stein
|
||||
* \author Norman Feske
|
||||
* \date 2021-02-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _CHILD_STATE_H_
|
||||
#define _CHILD_STATE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/xml_node.h>
|
||||
#include <util/noncopyable.h>
|
||||
#include <util/string.h>
|
||||
#include <base/registry.h>
|
||||
#include <base/quota_guard.h>
|
||||
|
||||
/* local includes */
|
||||
#include <types.h>
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
class Child_state;
|
||||
}
|
||||
|
||||
class File_vault::Child_state : Noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
using Start_name = String<128>;
|
||||
using Binary_name = String<128>;
|
||||
using Registry_element = Registry<Child_state>::Element;
|
||||
|
||||
struct Version
|
||||
{
|
||||
unsigned value;
|
||||
};
|
||||
|
||||
Registry_element _registry_element;
|
||||
Start_name const _start_name;
|
||||
Binary_name const _binary_name;
|
||||
Ram_quota const _initial_ram_quota;
|
||||
Cap_quota const _initial_cap_quota;
|
||||
Ram_quota _ram_quota { _initial_ram_quota };
|
||||
Cap_quota _cap_quota { _initial_cap_quota };
|
||||
Version _version { 0 };
|
||||
|
||||
public:
|
||||
|
||||
Child_state(Registry<Child_state> ®istry,
|
||||
Start_name const &start_name,
|
||||
Binary_name const &binary_name,
|
||||
Ram_quota ram_quota,
|
||||
Cap_quota cap_quota)
|
||||
:
|
||||
_registry_element { registry, *this },
|
||||
_start_name { start_name },
|
||||
_binary_name { binary_name },
|
||||
_initial_ram_quota { ram_quota },
|
||||
_initial_cap_quota { cap_quota }
|
||||
{ }
|
||||
|
||||
Child_state(Registry<Child_state> ®istry,
|
||||
Start_name const &start_name,
|
||||
Ram_quota ram_quota,
|
||||
Cap_quota cap_quota)
|
||||
:
|
||||
_registry_element { registry, *this },
|
||||
_start_name { start_name },
|
||||
_binary_name { start_name },
|
||||
_initial_ram_quota { ram_quota },
|
||||
_initial_cap_quota { cap_quota }
|
||||
{ }
|
||||
|
||||
void trigger_restart()
|
||||
{
|
||||
_version.value++;
|
||||
_ram_quota = _initial_ram_quota;
|
||||
_cap_quota = _initial_cap_quota;
|
||||
}
|
||||
|
||||
void gen_start_node_version(Xml_generator &xml) const
|
||||
{
|
||||
if (_version.value)
|
||||
xml.attribute("version", _version.value);
|
||||
}
|
||||
|
||||
template <typename GEN_CONTENT>
|
||||
void gen_start_node(Xml_generator &xml,
|
||||
GEN_CONTENT const &gen_content) const
|
||||
{
|
||||
xml.node("start", [&] () {
|
||||
xml.attribute("name", _start_name);
|
||||
xml.attribute("caps", _cap_quota.value);
|
||||
gen_start_node_version(xml);
|
||||
|
||||
if (_start_name != _binary_name) {
|
||||
xml.node("binary", [&] () {
|
||||
xml.attribute("name", _binary_name);
|
||||
});
|
||||
}
|
||||
xml.node("resource", [&] () {
|
||||
xml.attribute("name", "RAM");
|
||||
Number_of_bytes const bytes(_ram_quota.value);
|
||||
xml.attribute("quantum", String<64>(bytes)); });
|
||||
|
||||
gen_content();
|
||||
});
|
||||
}
|
||||
|
||||
bool apply_child_state_report(Xml_node const &child)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (child.attribute_value("name", Start_name()) != _start_name)
|
||||
return false;
|
||||
|
||||
if (child.has_sub_node("ram") &&
|
||||
child.sub_node("ram").has_attribute("requested"))
|
||||
{
|
||||
_ram_quota.value *= 2;
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (child.has_sub_node("caps") &&
|
||||
child.sub_node("caps").has_attribute("requested"))
|
||||
{
|
||||
_cap_quota.value += 100;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Ram_quota ram_quota() const { return _ram_quota; }
|
||||
|
||||
Start_name start_name() const { return _start_name; }
|
||||
};
|
||||
|
||||
#endif /* _CHILD_STATE_H_ */
|
64
repos/gems/src/app/file_vault/const_pointer.h
Normal file
64
repos/gems/src/app/file_vault/const_pointer.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* \brief Pointer of const object safe against null dereferencing
|
||||
* \author Martin Stein
|
||||
* \date 2021-04-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _CONST_POINTER_H_
|
||||
#define _CONST_POINTER_H_
|
||||
|
||||
/* local includes */
|
||||
#include <types.h>
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
template <typename T>
|
||||
class Const_pointer;
|
||||
}
|
||||
|
||||
|
||||
template <typename OBJECT_TYPE>
|
||||
class File_vault::Const_pointer
|
||||
{
|
||||
private:
|
||||
|
||||
OBJECT_TYPE const *_object;
|
||||
|
||||
public:
|
||||
|
||||
struct Invalid : Genode::Exception { };
|
||||
|
||||
Const_pointer() : _object { nullptr } { }
|
||||
|
||||
Const_pointer(OBJECT_TYPE const &object) : _object { &object } { }
|
||||
|
||||
OBJECT_TYPE const &object() const
|
||||
{
|
||||
if (_object == nullptr)
|
||||
throw Invalid();
|
||||
|
||||
return *_object;
|
||||
}
|
||||
|
||||
bool valid() const { return _object != nullptr; }
|
||||
|
||||
bool operator != (Const_pointer const &other) const
|
||||
{
|
||||
if (valid() != other.valid()) {
|
||||
return true;
|
||||
}
|
||||
if (valid()) {
|
||||
return _object != other._object;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _CONST_POINTER_H_ */
|
194
repos/gems/src/app/file_vault/dynamic_array.h
Normal file
194
repos/gems/src/app/file_vault/dynamic_array.h
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* \brief Dynamically growing array
|
||||
* \author Norman Feske
|
||||
* \date 2020-01-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _DYNAMIC_ARRAY_H_
|
||||
#define _DYNAMIC_ARRAY_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator.h>
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
template <typename>
|
||||
struct Dynamic_array;
|
||||
}
|
||||
|
||||
|
||||
template <typename ET>
|
||||
struct File_vault::Dynamic_array
|
||||
{
|
||||
public:
|
||||
|
||||
struct Index { unsigned value; };
|
||||
|
||||
private:
|
||||
|
||||
Allocator &_alloc;
|
||||
|
||||
using Element = Constructible<ET>;
|
||||
|
||||
Element *_array = nullptr;
|
||||
|
||||
unsigned _capacity = 0;
|
||||
unsigned _upper_bound = 0; /* index after last used element */
|
||||
|
||||
bool _index_valid(Index at) const
|
||||
{
|
||||
return (at.value < _upper_bound) && _array[at.value].constructed();
|
||||
}
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Dynamic_array(Dynamic_array const &other);
|
||||
void operator = (Dynamic_array const &);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Moving constructor
|
||||
*/
|
||||
Dynamic_array(Dynamic_array &other)
|
||||
:
|
||||
_alloc(other._alloc), _array(other._array),
|
||||
_capacity(other._capacity), _upper_bound(other._upper_bound)
|
||||
{
|
||||
other._array = nullptr;
|
||||
other._capacity = 0;
|
||||
other._upper_bound = 0;
|
||||
}
|
||||
|
||||
Dynamic_array(Allocator &alloc) : _alloc(alloc) { }
|
||||
|
||||
~Dynamic_array()
|
||||
{
|
||||
if (!_array)
|
||||
return;
|
||||
|
||||
clear();
|
||||
|
||||
_alloc.free(_array, _capacity*sizeof(Element));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
if (_upper_bound > 0)
|
||||
for (unsigned i = _upper_bound; i > 0; i--)
|
||||
destruct(Index{i - 1});
|
||||
}
|
||||
|
||||
template <typename... ARGS>
|
||||
void insert(Index at, ARGS &&... args)
|
||||
{
|
||||
/* grow array if index exceeds current capacity or if it's full */
|
||||
if (at.value >= _capacity || _upper_bound == _capacity) {
|
||||
|
||||
size_t const new_capacity =
|
||||
2 * max(_capacity, max(8U, at.value));
|
||||
|
||||
Element *new_array = nullptr;
|
||||
try {
|
||||
(void)_alloc.alloc(sizeof(Element)*new_capacity, &new_array);
|
||||
|
||||
for (unsigned i = 0; i < new_capacity; i++)
|
||||
construct_at<Element>(&new_array[i]);
|
||||
}
|
||||
catch (... /* Out_of_ram, Out_of_caps */ ) { throw; }
|
||||
|
||||
if (_array) {
|
||||
for (unsigned i = 0; i < _upper_bound; i++)
|
||||
new_array[i].construct(*_array[i]);
|
||||
|
||||
_alloc.free(_array, sizeof(Element)*_capacity);
|
||||
}
|
||||
|
||||
_array = new_array;
|
||||
_capacity = new_capacity;
|
||||
}
|
||||
|
||||
/* make room for new element */
|
||||
if (_upper_bound > 0)
|
||||
for (unsigned i = _upper_bound; i > at.value; i--)
|
||||
_array[i].construct(*_array[i - 1]);
|
||||
|
||||
_array[at.value].construct(args...);
|
||||
|
||||
_upper_bound = max(at.value + 1, _upper_bound + 1);
|
||||
}
|
||||
|
||||
template <typename... ARGS>
|
||||
void append(ARGS &&... args) { insert(Index{_upper_bound}, args...); }
|
||||
|
||||
bool exists(Index at) const { return _index_valid(at); }
|
||||
|
||||
Index upper_bound() const { return Index { _upper_bound }; }
|
||||
|
||||
void destruct(Index at)
|
||||
{
|
||||
if (!_index_valid(at))
|
||||
return;
|
||||
|
||||
_array[at.value].destruct();
|
||||
|
||||
if (_upper_bound > 0)
|
||||
for (unsigned i = at.value; i < _upper_bound - 1; i++)
|
||||
_array[i].construct(*_array[i + 1]);
|
||||
|
||||
_upper_bound--;
|
||||
_array[_upper_bound].destruct();
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void apply(Index at, FN const &fn)
|
||||
{
|
||||
if (_index_valid(at))
|
||||
fn(*_array[at.value]);
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void apply(Index at, FN const &fn) const
|
||||
{
|
||||
if (_index_valid(at))
|
||||
fn(*_array[at.value]);
|
||||
}
|
||||
|
||||
struct Range { Index at; unsigned length; };
|
||||
|
||||
template <typename FN>
|
||||
void for_each(Range range, FN const &fn) const
|
||||
{
|
||||
unsigned const first = range.at.value;
|
||||
unsigned const limit = min(_upper_bound, first + range.length);
|
||||
|
||||
for (unsigned i = first; i < limit; i++)
|
||||
if (_array[i].constructed())
|
||||
fn(Index{i}, *_array[i]);
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void for_each(FN const &fn) const
|
||||
{
|
||||
for_each(Range { .at = { 0U }, .length = ~0U }, fn);
|
||||
}
|
||||
|
||||
void print(Output &out) const
|
||||
{
|
||||
for (unsigned i = 0; i < _upper_bound; i++)
|
||||
if (_array[i].constructed())
|
||||
Genode::print(out, *_array[i]);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _DYNAMIC_ARRAY_H_ */
|
28
repos/gems/src/app/file_vault/gui_input_event_handler.h
Normal file
28
repos/gems/src/app/file_vault/gui_input_event_handler.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* \brief Interface for handling input events
|
||||
* \author Norman Feske
|
||||
* \date 2018-05-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _GUI_INPUT_EVENT_HANDLER_H_
|
||||
#define _GUI_INPUT_EVENT_HANDLER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/interface.h>
|
||||
#include <input/event.h>
|
||||
|
||||
namespace Gui { struct Input_event_handler; }
|
||||
|
||||
struct Gui::Input_event_handler : Genode::Interface
|
||||
{
|
||||
virtual void handle_input_event(Input::Event const &) = 0;
|
||||
};
|
||||
|
||||
#endif /* _GUI_INPUT_EVENT_HANDLER_H_ */
|
122
repos/gems/src/app/file_vault/gui_session_component.h
Normal file
122
repos/gems/src/app/file_vault/gui_session_component.h
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* \brief GUI wrapper for monitoring the user input of GUI components
|
||||
* \author Norman Feske
|
||||
* \date 2020-01-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _GUI_SESSION_COMPONENT_H_
|
||||
#define _GUI_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/component.h>
|
||||
#include <base/session_object.h>
|
||||
#include <gui_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include <gui_input_event_handler.h>
|
||||
|
||||
namespace Gui {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Session_component;
|
||||
}
|
||||
|
||||
|
||||
struct Gui::Session_component : Session_object<Gui::Session>
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
Input_event_handler &_event_handler;
|
||||
|
||||
Gui::Connection _connection;
|
||||
|
||||
Input::Session_component _input_component { _env, _env.ram() };
|
||||
|
||||
Signal_handler<Session_component> _input_handler {
|
||||
_env.ep(), *this, &Session_component::_handle_input };
|
||||
|
||||
void _handle_input()
|
||||
{
|
||||
_connection.input()->for_each_event([&] (Input::Event ev) {
|
||||
|
||||
/* handle event locally within the sculpt manager */
|
||||
_event_handler.handle_input_event(ev);
|
||||
|
||||
_input_component.submit(ev);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename... ARGS>
|
||||
Session_component(Env &env, Input_event_handler &event_handler, ARGS &&... args)
|
||||
:
|
||||
Session_object(args...),
|
||||
_env(env), _event_handler(event_handler),
|
||||
_connection(env, _label.string())
|
||||
{
|
||||
_connection.input()->sigh(_input_handler);
|
||||
_env.ep().manage(_input_component);
|
||||
_input_component.event_queue().enabled(true);
|
||||
}
|
||||
|
||||
~Session_component() { _env.ep().dissolve(_input_component); }
|
||||
|
||||
void upgrade(Session::Resources const &resources)
|
||||
{
|
||||
_connection.upgrade(resources);
|
||||
}
|
||||
|
||||
Framebuffer::Session_capability framebuffer_session() override {
|
||||
return _connection.framebuffer_session(); }
|
||||
|
||||
Input::Session_capability input_session() override {
|
||||
return _input_component.cap(); }
|
||||
|
||||
View_handle create_view(View_handle parent) override {
|
||||
return _connection.create_view(parent); }
|
||||
|
||||
void destroy_view(View_handle view) override {
|
||||
_connection.destroy_view(view); }
|
||||
|
||||
View_handle view_handle(View_capability view_cap, View_handle handle) override {
|
||||
return _connection.view_handle(view_cap, handle); }
|
||||
|
||||
View_capability view_capability(View_handle view) override {
|
||||
return _connection.view_capability(view); }
|
||||
|
||||
void release_view_handle(View_handle view) override {
|
||||
_connection.release_view_handle(view); }
|
||||
|
||||
Dataspace_capability command_dataspace() override {
|
||||
return _connection.command_dataspace(); }
|
||||
|
||||
void execute() override {
|
||||
_connection.execute(); }
|
||||
|
||||
Framebuffer::Mode mode() override {
|
||||
return _connection.mode(); }
|
||||
|
||||
void mode_sigh(Signal_context_capability sigh) override {
|
||||
_connection.mode_sigh(sigh); }
|
||||
|
||||
void buffer(Framebuffer::Mode mode, bool use_alpha) override
|
||||
{
|
||||
/*
|
||||
* Do not call 'Connection::buffer' to avoid paying session quota
|
||||
* from our own budget.
|
||||
*/
|
||||
_connection.Client::buffer(mode, use_alpha);
|
||||
}
|
||||
|
||||
void focus(Capability<Gui::Session> session) override {
|
||||
_connection.focus(session); }
|
||||
};
|
||||
|
||||
#endif /* _GUI_SESSION_COMPONENT_H_ */
|
261
repos/gems/src/app/file_vault/input.h
Normal file
261
repos/gems/src/app/file_vault/input.h
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* \brief Text buffer for a passphrase
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2021-03-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _INPUT_H_
|
||||
#define _INPUT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/output.h>
|
||||
#include <util/utf8.h>
|
||||
#include <base/buffered_output.h>
|
||||
|
||||
/* local includes */
|
||||
#include <types.h>
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
class Input_single_line;
|
||||
class Input_passphrase;
|
||||
class Input_number_of_bytes;
|
||||
class Input_number_of_blocks;
|
||||
}
|
||||
|
||||
|
||||
class File_vault::Input_single_line
|
||||
{
|
||||
public:
|
||||
|
||||
enum { MAX_LENGTH = 64 };
|
||||
|
||||
protected:
|
||||
|
||||
Codepoint _characters[MAX_LENGTH] { };
|
||||
|
||||
unsigned _length = 0;
|
||||
|
||||
void _print_characters(Output &out) const
|
||||
{
|
||||
/*
|
||||
* FIXME This was copied from gems/src/server/terminal/main.cc
|
||||
*/
|
||||
|
||||
struct Utf8 { char b0, b1, b2, b3, b4; };
|
||||
|
||||
auto utf8_from_codepoint = [] (unsigned c) {
|
||||
|
||||
/* extract 'n' bits 'at' bit position of value 'c' */
|
||||
auto bits = [c] (unsigned at, unsigned n) {
|
||||
return (c >> at) & ((1 << n) - 1); };
|
||||
|
||||
return (c < 2<<7) ? Utf8 { char(bits( 0, 7)), 0, 0, 0, 0 }
|
||||
: (c < 2<<11) ? Utf8 { char(bits( 6, 5) | 0xc0),
|
||||
char(bits( 0, 6) | 0x80), 0, 0, 0 }
|
||||
: (c < 2<<16) ? Utf8 { char(bits(12, 4) | 0xe0),
|
||||
char(bits( 6, 6) | 0x80),
|
||||
char(bits( 0, 6) | 0x80), 0, 0 }
|
||||
: (c < 2<<21) ? Utf8 { char(bits(18, 3) | 0xf0),
|
||||
char(bits(12, 6) | 0x80),
|
||||
char(bits( 6, 6) | 0x80),
|
||||
char(bits( 0, 6) | 0x80), 0 }
|
||||
: Utf8 { };
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < _length; i++) {
|
||||
|
||||
Utf8 const utf8 = utf8_from_codepoint(_characters[i].value);
|
||||
|
||||
auto _print = [&] (char c) {
|
||||
if (c)
|
||||
Genode::print(out, Char(c)); };
|
||||
|
||||
_print(utf8.b0); _print(utf8.b1); _print(utf8.b2);
|
||||
_print(utf8.b3); _print(utf8.b4);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void append_character(Codepoint c)
|
||||
{
|
||||
if (_length < MAX_LENGTH) {
|
||||
_characters[_length] = c;
|
||||
_length++;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_last_character()
|
||||
{
|
||||
if (_length > 0) {
|
||||
_length--;
|
||||
_characters[_length].value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool equals(Input_single_line const &other) const
|
||||
{
|
||||
if (other._length != _length) {
|
||||
return false;
|
||||
}
|
||||
if (memcmp(other._characters, _characters, _length) != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned length() const { return _length; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
class File_vault::Input_passphrase : public Input_single_line
|
||||
{
|
||||
private:
|
||||
|
||||
bool _hide { true };
|
||||
|
||||
void _print_bullets(Output &out) const
|
||||
{
|
||||
char const bullet_utf8[4] {
|
||||
(char)0xe2, (char)0x80, (char)0xa2, 0 };
|
||||
|
||||
for (unsigned i = 0; i < _length; i++)
|
||||
Genode::print(out, bullet_utf8);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
bool suitable() const
|
||||
{
|
||||
return _length >= 8;
|
||||
}
|
||||
|
||||
char const *not_suitable_text() const
|
||||
{
|
||||
return "Must have at least 8 characters!";
|
||||
}
|
||||
|
||||
void print(Output &out) const
|
||||
{
|
||||
if (_hide) {
|
||||
_print_bullets(out);
|
||||
} else {
|
||||
_print_characters(out);
|
||||
}
|
||||
}
|
||||
|
||||
void hide(bool value)
|
||||
{
|
||||
_hide = value;
|
||||
}
|
||||
|
||||
bool hide() const
|
||||
{
|
||||
return _hide;
|
||||
}
|
||||
|
||||
bool appendable_character(Codepoint code)
|
||||
{
|
||||
if (!code.valid()) {
|
||||
return false;
|
||||
}
|
||||
bool const is_printable {
|
||||
code.value >= 0x20 && code.value < 0xf000 };
|
||||
|
||||
return is_printable;
|
||||
}
|
||||
|
||||
String<MAX_LENGTH * 3> plaintext() const
|
||||
{
|
||||
String<MAX_LENGTH * 3> result { };
|
||||
|
||||
auto write = [&] (char const *str)
|
||||
{
|
||||
result = Cstring(str, strlen(str));
|
||||
};
|
||||
Buffered_output<MAX_LENGTH * 3, decltype(write)> output(write);
|
||||
|
||||
_print_characters(output);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class File_vault::Input_number_of_bytes : public Input_single_line
|
||||
{
|
||||
public:
|
||||
|
||||
void print(Output &out) const
|
||||
{
|
||||
_print_characters(out);
|
||||
}
|
||||
|
||||
size_t value() const
|
||||
{
|
||||
String<32> const str { *this };
|
||||
Number_of_bytes result { 0 };
|
||||
ascii_to(str.string(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool appendable_character(Codepoint code)
|
||||
{
|
||||
if (!code.valid()) {
|
||||
return false;
|
||||
}
|
||||
bool const is_number {
|
||||
code.value >= 48 && code.value <= 57 };
|
||||
|
||||
bool const is_unit_prefix {
|
||||
code.value == 71 || code.value == 75 || code.value == 77 };
|
||||
|
||||
return is_number || is_unit_prefix;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class File_vault::Input_number_of_blocks : public Input_single_line
|
||||
{
|
||||
public:
|
||||
|
||||
void print(Output &out) const
|
||||
{
|
||||
_print_characters(out);
|
||||
}
|
||||
|
||||
unsigned long to_unsigned_long() const
|
||||
{
|
||||
String<32> const str { *this };
|
||||
unsigned long result { 0 };
|
||||
ascii_to(str.string(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_nr_greater_than_zero() const
|
||||
{
|
||||
return (size_t)to_unsigned_long() > 0;
|
||||
}
|
||||
|
||||
bool appendable_character(Codepoint code)
|
||||
{
|
||||
if (!code.valid()) {
|
||||
return false;
|
||||
}
|
||||
bool const is_number {
|
||||
code.value >= 48 && code.value <= 57 };
|
||||
|
||||
return is_number;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INPUT_H_ */
|
4098
repos/gems/src/app/file_vault/main.cc
Normal file
4098
repos/gems/src/app/file_vault/main.cc
Normal file
File diff suppressed because it is too large
Load Diff
389
repos/gems/src/app/file_vault/menu_view_dialog.cc
Normal file
389
repos/gems/src/app/file_vault/menu_view_dialog.cc
Normal file
@ -0,0 +1,389 @@
|
||||
/*
|
||||
* \brief Local utilities for the menu view dialog
|
||||
* \author Martin Stein
|
||||
* \date 2021-02-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* local includes */
|
||||
#include <menu_view_dialog.h>
|
||||
#include <capacity.h>
|
||||
|
||||
using namespace File_vault;
|
||||
|
||||
|
||||
void File_vault::gen_normal_font_attribute(Xml_generator &xml)
|
||||
{
|
||||
xml.attribute("font", "text/regular");
|
||||
}
|
||||
|
||||
|
||||
void File_vault::gen_frame_title(Xml_generator &xml,
|
||||
char const *name,
|
||||
unsigned long min_width)
|
||||
{
|
||||
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", name);
|
||||
xml.attribute("west", "yes");
|
||||
xml.attribute("north", "yes");
|
||||
|
||||
xml.node("label", [&] () {
|
||||
xml.attribute("text", "" );
|
||||
xml.attribute("min_ex", min_width);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void File_vault::gen_info_frame(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *info,
|
||||
unsigned long min_width)
|
||||
{
|
||||
gen_main_frame(xml, name, min_width, [&] (Xml_generator &xml) {
|
||||
|
||||
gen_centered_info_line(xml, "info", info);
|
||||
gen_info_line(xml, "pad_1", "");
|
||||
});
|
||||
}
|
||||
|
||||
void File_vault::gen_action_button_at_bottom(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *label,
|
||||
bool hovered,
|
||||
bool selected)
|
||||
{
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", name);
|
||||
xml.attribute("east", "yes");
|
||||
xml.attribute("west", "yes");
|
||||
xml.attribute("south", "yes");
|
||||
|
||||
xml.node("button", [&] () {
|
||||
|
||||
if (hovered) {
|
||||
xml.attribute("hovered", "yes");
|
||||
}
|
||||
if (selected) {
|
||||
xml.attribute("selected", "yes");
|
||||
}
|
||||
|
||||
xml.node("float", [&] () {
|
||||
|
||||
xml.node("label", [&] () {
|
||||
gen_normal_font_attribute(xml);
|
||||
xml.attribute("text", label);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void File_vault::gen_action_button_at_bottom(Xml_generator &xml,
|
||||
char const *label,
|
||||
bool hovered,
|
||||
bool selected)
|
||||
{
|
||||
gen_action_button_at_bottom(xml, label, label, hovered, selected);
|
||||
}
|
||||
|
||||
void File_vault::gen_action_button(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *label,
|
||||
bool hovered,
|
||||
bool selected,
|
||||
size_t min_ex)
|
||||
{
|
||||
xml.node("button", [&] () {
|
||||
xml.attribute("name", name);
|
||||
|
||||
if (hovered) {
|
||||
xml.attribute("hovered", "yes");
|
||||
}
|
||||
if (selected) {
|
||||
xml.attribute("selected", "yes");
|
||||
}
|
||||
xml.node("label", [&] () {
|
||||
|
||||
if (min_ex != 0) {
|
||||
xml.attribute("min_ex", min_ex);
|
||||
}
|
||||
xml.attribute("text", label);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void File_vault::gen_text_input(Xml_generator &xml,
|
||||
char const *name,
|
||||
String<256> const &text,
|
||||
bool selected)
|
||||
{
|
||||
String<256> const padded_text { " ", text };
|
||||
|
||||
xml.node("frame", [&] () {
|
||||
xml.attribute("name", name);
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("west", "yes");
|
||||
xml.node("label", [&] () {
|
||||
gen_normal_font_attribute(xml);
|
||||
xml.attribute("text", padded_text);
|
||||
|
||||
if (selected) {
|
||||
xml.node("cursor", [&] () {
|
||||
xml.attribute("at", padded_text.length() - 1 );
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
File_vault::
|
||||
gen_input_passphrase(Xml_generator &xml,
|
||||
size_t max_width,
|
||||
Input_passphrase const &passphrase,
|
||||
bool input_selected,
|
||||
bool show_hide_button_hovered,
|
||||
bool show_hide_button_selected)
|
||||
{
|
||||
char const *show_hide_button_label;
|
||||
size_t cursor_at;
|
||||
if (passphrase.hide()) {
|
||||
|
||||
show_hide_button_label = "Show";
|
||||
cursor_at = passphrase.length() + 1;
|
||||
|
||||
} else {
|
||||
|
||||
show_hide_button_label = "Hide";
|
||||
cursor_at = passphrase.length() + 1;
|
||||
}
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", "Passphrase Label");
|
||||
xml.attribute("west", "yes");
|
||||
|
||||
xml.node("label", [&] () {
|
||||
gen_normal_font_attribute(xml);
|
||||
xml.attribute("text", " Passphrase: ");
|
||||
});
|
||||
});
|
||||
xml.node("hbox", [&] () {
|
||||
|
||||
String<256> const padded_text { " ", passphrase, " " };
|
||||
xml.node("frame", [&] () {
|
||||
xml.attribute("name", "Passphrase");
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("west", "yes");
|
||||
xml.node("label", [&] () {
|
||||
xml.attribute("min_ex", max_width - 11);
|
||||
gen_normal_font_attribute(xml);
|
||||
xml.attribute("text", padded_text);
|
||||
|
||||
|
||||
if (input_selected) {
|
||||
xml.node("cursor", [&] () {
|
||||
xml.attribute("at", cursor_at );
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", "1");
|
||||
xml.attribute("east", "yes");
|
||||
|
||||
gen_action_button(
|
||||
xml, "Show Hide", show_hide_button_label,
|
||||
show_hide_button_hovered, show_hide_button_selected, 5);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void File_vault::gen_titled_text_input(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *title,
|
||||
String<256> const &text,
|
||||
bool selected)
|
||||
{
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", String<64> { name, "_label" });
|
||||
xml.attribute("west", "yes");
|
||||
|
||||
xml.node("label", [&] () {
|
||||
gen_normal_font_attribute(xml);
|
||||
xml.attribute("text", String<64> { " ", title, ": " });
|
||||
});
|
||||
});
|
||||
gen_text_input(xml, name, text, selected);
|
||||
}
|
||||
|
||||
void File_vault::gen_empty_line(Xml_generator &xml,
|
||||
char const *name,
|
||||
size_t min_width)
|
||||
{
|
||||
xml.node("label", [&] () {
|
||||
xml.attribute("name", name);
|
||||
xml.attribute("min_ex", min_width);
|
||||
xml.attribute("text", "");
|
||||
});
|
||||
}
|
||||
|
||||
void File_vault::gen_info_line(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *text)
|
||||
{
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", name);
|
||||
xml.attribute("west", "yes");
|
||||
xml.node("label", [&] () {
|
||||
gen_normal_font_attribute(xml);
|
||||
xml.attribute("text", String<256> { " ", text, " "});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void File_vault::gen_centered_info_line(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *text)
|
||||
{
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", name);
|
||||
xml.node("label", [&] () {
|
||||
gen_normal_font_attribute(xml);
|
||||
xml.attribute("text", String<256> { " ", text, " "});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void File_vault::gen_multiple_choice_entry(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *text,
|
||||
bool hovered,
|
||||
bool selected)
|
||||
{
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", name);
|
||||
xml.attribute("west", "yes");
|
||||
|
||||
xml.node("hbox", [&] () {
|
||||
|
||||
xml.node("button", [&] () {
|
||||
if (selected) {
|
||||
xml.attribute("selected", "yes");
|
||||
}
|
||||
if (hovered) {
|
||||
xml.attribute("hovered", "yes");
|
||||
}
|
||||
xml.attribute("style", "radio");
|
||||
|
||||
xml.node("hbox", [&] () { });
|
||||
});
|
||||
xml.node("label", [&] () {
|
||||
gen_normal_font_attribute(xml);
|
||||
xml.attribute("text", String<64> { " ", text });
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void File_vault::gen_menu_title(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *label,
|
||||
char const *label_annex,
|
||||
bool hovered,
|
||||
bool selected)
|
||||
{
|
||||
xml.node("hbox", [&] () {
|
||||
xml.attribute("name", name);
|
||||
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", "0");
|
||||
xml.attribute("west", "yes");
|
||||
|
||||
xml.node("hbox", [&] () {
|
||||
|
||||
xml.node("button", [&] () {
|
||||
if (selected) {
|
||||
xml.attribute("style", "back");
|
||||
xml.attribute("selected", "yes");
|
||||
} else {
|
||||
xml.attribute("style", "radio");
|
||||
}
|
||||
if (hovered) {
|
||||
xml.attribute("hovered", "yes");
|
||||
}
|
||||
xml.attribute("hovered", "no");
|
||||
|
||||
xml.node("hbox", [&] () { });
|
||||
});
|
||||
xml.node("label", [&] () {
|
||||
if (selected) {
|
||||
xml.attribute("font", "title/regular");
|
||||
}
|
||||
xml.attribute("text", String<64> { " ", label });
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", "2");
|
||||
xml.attribute("east", "yes");
|
||||
|
||||
xml.node("label", [&] () {
|
||||
xml.attribute("font", "title/regular");
|
||||
xml.attribute(
|
||||
"text", label_annex);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void File_vault::gen_closed_menu(Xml_generator &xml,
|
||||
char const *label,
|
||||
char const *label_annex,
|
||||
bool hovered)
|
||||
{
|
||||
xml.node("vbox", [&] () {
|
||||
xml.attribute("name", label);
|
||||
|
||||
gen_menu_title(xml, "Enter", label, label_annex, hovered, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void File_vault::gen_global_controls(Xml_generator &xml,
|
||||
size_t min_width,
|
||||
size_t cbe_image_size,
|
||||
size_t client_fs_size,
|
||||
size_t nr_of_clients,
|
||||
bool shut_down_button_hovered,
|
||||
bool shut_down_button_selected)
|
||||
{
|
||||
gen_empty_line(xml, "Status 0", min_width);
|
||||
gen_centered_info_line(xml, "Status 1",
|
||||
String<256> {
|
||||
" Image: ",
|
||||
Capacity_string { cbe_image_size },
|
||||
", Client FS: ",
|
||||
Capacity_string { client_fs_size },
|
||||
", Clients: ",
|
||||
nr_of_clients
|
||||
}.string()
|
||||
);
|
||||
|
||||
gen_empty_line(xml, "Status 3", 0);
|
||||
|
||||
xml.node("hbox", [&] () {
|
||||
gen_action_button(
|
||||
xml, "Shut down", "Shut down",
|
||||
shut_down_button_hovered,
|
||||
shut_down_button_selected);
|
||||
});
|
||||
}
|
181
repos/gems/src/app/file_vault/menu_view_dialog.h
Normal file
181
repos/gems/src/app/file_vault/menu_view_dialog.h
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* \brief Local utilities for the menu view dialog
|
||||
* \author Martin Stein
|
||||
* \date 2021-02-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _MENU_VIEW_DIALOG_H_
|
||||
#define _MENU_VIEW_DIALOG_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/xml_generator.h>
|
||||
|
||||
/* local includes */
|
||||
#include <types.h>
|
||||
#include <input.h>
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
void gen_normal_font_attribute(Xml_generator &xml);
|
||||
|
||||
void gen_frame_title(Xml_generator &xml,
|
||||
char const *name,
|
||||
unsigned long min_width);
|
||||
|
||||
template <typename GEN_FRAME_CONTENT>
|
||||
void gen_main_frame(Xml_generator &xml,
|
||||
char const *name,
|
||||
unsigned long min_width,
|
||||
GEN_FRAME_CONTENT const &gen_frame_content)
|
||||
{
|
||||
xml.node("frame", [&] () {
|
||||
xml.attribute("name", name);
|
||||
|
||||
xml.node("vbox", [&] () {
|
||||
|
||||
gen_frame_title(xml, "title", min_width);
|
||||
gen_frame_content(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
template <typename GEN_FRAME_CONTENT>
|
||||
void gen_controls_frame(Xml_generator &xml,
|
||||
char const *name,
|
||||
GEN_FRAME_CONTENT const &gen_frame_content)
|
||||
{
|
||||
xml.node("frame", [&] () {
|
||||
xml.attribute("name", name);
|
||||
|
||||
xml.node("vbox", [&] () {
|
||||
|
||||
gen_frame_content(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
template <typename GEN_FRAME_CONTENT>
|
||||
void gen_untitled_frame(Xml_generator &xml,
|
||||
char const *name,
|
||||
GEN_FRAME_CONTENT const &gen_frame_content)
|
||||
{
|
||||
xml.node("frame", [&] () {
|
||||
xml.attribute("name", name);
|
||||
|
||||
xml.node("float", [&] () {
|
||||
xml.attribute("name", "xxx");
|
||||
xml.attribute("east", "yes");
|
||||
xml.attribute("west", "yes");
|
||||
xml.attribute("north", "yes");
|
||||
|
||||
xml.node("vbox", [&] () {
|
||||
|
||||
gen_frame_content(xml);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_info_frame(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *info,
|
||||
unsigned long min_width);
|
||||
|
||||
void gen_action_button_at_bottom(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *label,
|
||||
bool hovered,
|
||||
bool selected);
|
||||
|
||||
void gen_action_button_at_bottom(Xml_generator &xml,
|
||||
char const *label,
|
||||
bool hovered,
|
||||
bool selected);
|
||||
|
||||
void gen_text_input(Xml_generator &xml,
|
||||
char const *name,
|
||||
String<256> const &text,
|
||||
bool selected);
|
||||
|
||||
void gen_titled_text_input(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *title,
|
||||
String<256> const &text,
|
||||
bool selected);
|
||||
|
||||
void gen_info_line(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *text);
|
||||
|
||||
void gen_centered_info_line(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *text);
|
||||
|
||||
void gen_empty_line(Xml_generator &xml,
|
||||
char const *name,
|
||||
size_t min_width);
|
||||
|
||||
void gen_multiple_choice_entry(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *text,
|
||||
bool hovered,
|
||||
bool selected);
|
||||
|
||||
void gen_menu_title(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *label,
|
||||
char const *label_annex,
|
||||
bool hovered,
|
||||
bool selected);
|
||||
|
||||
void gen_closed_menu(Xml_generator &xml,
|
||||
char const *label,
|
||||
char const *label_annex,
|
||||
bool hovered);
|
||||
|
||||
template <typename GEN_CONTENT>
|
||||
void gen_opened_menu(Xml_generator &xml,
|
||||
char const *label,
|
||||
char const *label_annex,
|
||||
bool hovered,
|
||||
GEN_CONTENT const &gen_content)
|
||||
{
|
||||
xml.node("vbox", [&] () {
|
||||
xml.attribute("name", label);
|
||||
|
||||
gen_menu_title(xml, "Leave", label, label_annex, hovered, true);
|
||||
gen_content(xml);
|
||||
});
|
||||
}
|
||||
|
||||
void gen_input_passphrase(Xml_generator &xml,
|
||||
size_t max_width,
|
||||
Input_passphrase const &passphrase,
|
||||
bool input_selected,
|
||||
bool show_hide_button_hovered,
|
||||
bool show_hide_button_selected);
|
||||
|
||||
void gen_action_button(Xml_generator &xml,
|
||||
char const *name,
|
||||
char const *label,
|
||||
bool hovered,
|
||||
bool selected,
|
||||
size_t min_ex = 0);
|
||||
|
||||
void gen_global_controls(Xml_generator &xml,
|
||||
size_t min_width,
|
||||
size_t cbe_image_size,
|
||||
size_t client_fs_size,
|
||||
size_t nr_of_clients,
|
||||
bool shut_down_button_hovered,
|
||||
bool shut_down_button_selected);
|
||||
}
|
||||
|
||||
#endif /* _MENU_VIEW_DIALOG_H_ */
|
91
repos/gems/src/app/file_vault/report_session_component.h
Normal file
91
repos/gems/src/app/file_vault/report_session_component.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* \brief Report session provided by the CBE manager
|
||||
* \author Martin Stein
|
||||
* \author Norman Feske
|
||||
* \date 2021-02-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _REPORT_SESSION_COMPONENT_H_
|
||||
#define _REPORT_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <base/session_object.h>
|
||||
#include <report_session/report_session.h>
|
||||
|
||||
namespace Report {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
class Session_component;
|
||||
}
|
||||
|
||||
|
||||
class Report::Session_component : public Session_object<Report::Session>
|
||||
{
|
||||
public:
|
||||
|
||||
struct Handler_base : Interface, Genode::Noncopyable
|
||||
{
|
||||
virtual void handle_report(char const *, size_t) = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Xml_handler : Handler_base
|
||||
{
|
||||
T &_obj;
|
||||
void (T::*_member) (Xml_node const &);
|
||||
|
||||
Xml_handler(T &obj, void (T::*member)(Xml_node const &))
|
||||
: _obj(obj), _member(member) { }
|
||||
|
||||
void handle_report(char const *start, size_t length) override
|
||||
{
|
||||
(_obj.*_member)(Xml_node(start, length));
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Attached_ram_dataspace _ds;
|
||||
|
||||
Handler_base &_handler;
|
||||
|
||||
|
||||
/*******************************
|
||||
** Report::Session interface **
|
||||
*******************************/
|
||||
|
||||
Dataspace_capability dataspace() override { return _ds.cap(); }
|
||||
|
||||
void submit(size_t length) override
|
||||
{
|
||||
_handler.handle_report(_ds.local_addr<char const>(),
|
||||
min(_ds.size(), length));
|
||||
}
|
||||
|
||||
void response_sigh(Signal_context_capability) override { }
|
||||
|
||||
size_t obtain_response() override { return 0; }
|
||||
|
||||
public:
|
||||
|
||||
template <typename... ARGS>
|
||||
Session_component(Env &env, Handler_base &handler,
|
||||
Entrypoint &ep, Resources const &resources,
|
||||
ARGS &&... args)
|
||||
:
|
||||
Session_object(ep, resources, args...),
|
||||
_ds(env.ram(), env.rm(), resources.ram_quota.value),
|
||||
_handler(handler)
|
||||
{ }
|
||||
};
|
||||
|
||||
#endif /* _REPORT_SESSION_COMPONENT_H_ */
|
997
repos/gems/src/app/file_vault/sandbox.h
Normal file
997
repos/gems/src/app/file_vault/sandbox.h
Normal file
@ -0,0 +1,997 @@
|
||||
/*
|
||||
* \brief Local utilities for the sandbox API
|
||||
* \author Martin Stein
|
||||
* \date 2021-02-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SANDBOX_H_
|
||||
#define _SANDBOX_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/string.h>
|
||||
#include <sandbox/sandbox.h>
|
||||
|
||||
/* local includes */
|
||||
#include <input.h>
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
template <typename ARG>
|
||||
void gen_arg(Xml_generator &xml, ARG const &arg)
|
||||
{
|
||||
xml.node("arg", [&] () { xml.attribute("value", arg); });
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
static inline void gen_named_node(Xml_generator &xml,
|
||||
char const *type, char const *name, FN const &fn)
|
||||
{
|
||||
xml.node(type, [&] () {
|
||||
xml.attribute("name", name);
|
||||
fn();
|
||||
});
|
||||
}
|
||||
|
||||
static inline void gen_common_start_content(Xml_generator &xml,
|
||||
char const *name,
|
||||
Cap_quota const caps,
|
||||
Ram_quota const ram)
|
||||
{
|
||||
xml.attribute("name", name);
|
||||
xml.attribute("caps", caps.value);
|
||||
gen_named_node(xml, "resource", "RAM", [&] () {
|
||||
xml.attribute("quantum", String<64>(Number_of_bytes(ram.value))); });
|
||||
}
|
||||
|
||||
void route_to_child_service(Genode::Xml_generator &xml,
|
||||
char const *child_name,
|
||||
char const *service_name,
|
||||
char const *service_label = "")
|
||||
{
|
||||
xml.node("service", [&] () {
|
||||
xml.attribute("name", service_name);
|
||||
if (Genode::strcmp(service_label, "")) {
|
||||
xml.attribute("label", service_label);
|
||||
}
|
||||
xml.attribute("name", service_name);
|
||||
xml.node("child", [&] () {
|
||||
xml.attribute("name", child_name);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
void route_to_parent_service(Genode::Xml_generator &xml,
|
||||
char const *service_name,
|
||||
char const *src_label = "",
|
||||
char const *dst_label = "")
|
||||
{
|
||||
xml.node("service", [&] () {
|
||||
xml.attribute("name", service_name);
|
||||
if (Genode::strcmp(src_label, "")) {
|
||||
xml.attribute("label", src_label);
|
||||
}
|
||||
xml.node("parent", [&] () {
|
||||
if (Genode::strcmp(dst_label, "")) {
|
||||
xml.attribute("label", dst_label);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
void route_to_local_service(Genode::Xml_generator &xml,
|
||||
char const *service_name,
|
||||
char const *service_label = "")
|
||||
{
|
||||
xml.node("service", [&] () {
|
||||
xml.attribute("name", service_name);
|
||||
if (Genode::strcmp(service_label, "")) {
|
||||
xml.attribute("label", service_label);
|
||||
}
|
||||
xml.node("local", [&] () { });
|
||||
});
|
||||
};
|
||||
|
||||
void service_node(Genode::Xml_generator &xml,
|
||||
char const *service_name)
|
||||
{
|
||||
xml.node("service", [&] () {
|
||||
xml.attribute("name", service_name);
|
||||
});
|
||||
};
|
||||
|
||||
void gen_provides_service(Xml_generator &xml,
|
||||
char const *service_name)
|
||||
{
|
||||
xml.node("provides", [&] () {
|
||||
xml.node("service", [&] () {
|
||||
xml.attribute("name", service_name);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_parent_routes_for_pd_rom_cpu_log(Xml_generator &xml)
|
||||
{
|
||||
route_to_parent_service(xml, "PD");
|
||||
route_to_parent_service(xml, "ROM");
|
||||
route_to_parent_service(xml, "CPU");
|
||||
route_to_parent_service(xml, "LOG");
|
||||
}
|
||||
|
||||
void gen_parent_provides_and_report_nodes(Xml_generator &xml)
|
||||
{
|
||||
xml.attribute("verbose", "no");
|
||||
|
||||
xml.node("report", [&] () {
|
||||
xml.attribute("provided", "yes");
|
||||
xml.attribute("child_ram", "yes");
|
||||
xml.attribute("child_caps", "yes");
|
||||
xml.attribute("delay_ms", 500);
|
||||
});
|
||||
|
||||
xml.node("parent-provides", [&] () {
|
||||
service_node(xml, "ROM");
|
||||
service_node(xml, "CPU");
|
||||
service_node(xml, "PD");
|
||||
service_node(xml, "LOG");
|
||||
service_node(xml, "RM");
|
||||
service_node(xml, "File_system");
|
||||
service_node(xml, "Gui");
|
||||
service_node(xml, "Timer");
|
||||
service_node(xml, "Report");
|
||||
});
|
||||
}
|
||||
|
||||
void gen_menu_view_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.attribute("xpos", "100");
|
||||
xml.attribute("ypos", "50");
|
||||
|
||||
xml.node("report", [&] () {
|
||||
xml.attribute("hover", "yes"); });
|
||||
|
||||
xml.node("libc", [&] () {
|
||||
xml.attribute("stderr", "/dev/log"); });
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("tar", [&] () {
|
||||
xml.attribute("name", "menu_view_styles.tar"); });
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "dev");
|
||||
xml.node("log", [&] () { });
|
||||
});
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "fonts");
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("label", "fonts");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
xml.node("route", [&] () {
|
||||
route_to_local_service(xml, "ROM", "dialog");
|
||||
route_to_local_service(xml, "Report", "hover");
|
||||
route_to_local_service(xml, "Gui");
|
||||
route_to_parent_service(xml, "File_system", "fonts");
|
||||
route_to_parent_service(xml, "Timer");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_mke2fs_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.node("libc", [&] () {
|
||||
xml.attribute("stdout", "/dev/log");
|
||||
xml.attribute("stderr", "/dev/log");
|
||||
xml.attribute("stdin", "/dev/null");
|
||||
xml.attribute("rtc", "/dev/rtc");
|
||||
});
|
||||
xml.node("vfs", [&] () {
|
||||
gen_named_node(xml, "dir", "dev", [&] () {
|
||||
gen_named_node(xml, "block", "block", [&] () {
|
||||
xml.attribute("label", "default");
|
||||
xml.attribute("block_buffer_count", 128);
|
||||
});
|
||||
gen_named_node(xml, "inline", "rtc", [&] () {
|
||||
xml.append("2018-01-01 00:01");
|
||||
});
|
||||
xml.node("null", [&] () {});
|
||||
xml.node("log", [&] () {});
|
||||
});
|
||||
});
|
||||
gen_arg(xml, "mkfs.ext2");
|
||||
gen_arg(xml, "-F");
|
||||
gen_arg(xml, "/dev/block");
|
||||
});
|
||||
|
||||
xml.node("route", [&] () {
|
||||
route_to_child_service(xml, "vfs_block", "Block");
|
||||
route_to_parent_service(xml, "Timer");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_resize2fs_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.node("libc", [&] () {
|
||||
xml.attribute("stdout", "/dev/log");
|
||||
xml.attribute("stderr", "/dev/log");
|
||||
xml.attribute("stdin", "/dev/null");
|
||||
xml.attribute("rtc", "/dev/rtc");
|
||||
});
|
||||
xml.node("vfs", [&] () {
|
||||
gen_named_node(xml, "dir", "dev", [&] () {
|
||||
gen_named_node(xml, "block", "block", [&] () {
|
||||
xml.attribute("label", "default");
|
||||
xml.attribute("block_buffer_count", 128);
|
||||
});
|
||||
gen_named_node(xml, "inline", "rtc", [&] () {
|
||||
xml.append("2018-01-01 00:01");
|
||||
});
|
||||
xml.node("null", [&] () {});
|
||||
xml.node("log", [&] () {});
|
||||
});
|
||||
});
|
||||
gen_arg(xml, "resize2fs");
|
||||
gen_arg(xml, "-f");
|
||||
gen_arg(xml, "-p");
|
||||
gen_arg(xml, "/dev/block");
|
||||
});
|
||||
|
||||
xml.node("route", [&] () {
|
||||
route_to_child_service(xml, "vfs_block", "Block");
|
||||
route_to_parent_service(xml, "Timer");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_cbe_vfs_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
gen_provides_service(xml, "File_system");
|
||||
xml.node("config", [&] () {
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("buffer_size", "1M");
|
||||
xml.attribute("label", "cbe_fs");
|
||||
});
|
||||
xml.node("cbe_crypto_aes_cbc", [&] () {
|
||||
xml.attribute("name", "crypto");
|
||||
});
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "trust_anchor");
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("buffer_size", "1M");
|
||||
xml.attribute("label", "trust_anchor");
|
||||
});
|
||||
});
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "dev");
|
||||
|
||||
xml.node("cbe", [&] () {
|
||||
xml.attribute("name", "cbe");
|
||||
xml.attribute("verbose", "no");
|
||||
xml.attribute("debug", "no");
|
||||
xml.attribute("block", "/cbe.img");
|
||||
xml.attribute("crypto", "/crypto");
|
||||
xml.attribute("trust_anchor", "/trust_anchor");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "resizing_fs_tool -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "rekeying_fs_tool -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "shut_down_fs_tool -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "create_snap_fs_tool -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "discard_snap_fs_tool -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "snapshots_fs_query -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "resizing_fs_query -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "rekeying_fs_query -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "shut_down_fs_query -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "vfs_block -> ");
|
||||
xml.attribute("root", "/dev/cbe/current");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "client_fs_fs_query -> ");
|
||||
xml.attribute("root", "/dev/cbe/current");
|
||||
xml.attribute("writeable", "no");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "sync_to_cbe_vfs_init -> ");
|
||||
xml.attribute("root", "/dev");
|
||||
xml.attribute("writeable", "no");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_child_service(xml, "cbe_trust_anchor_vfs", "File_system", "trust_anchor");
|
||||
route_to_parent_service(xml, "File_system", "cbe_fs");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_cbe_trust_anchor_vfs_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
gen_provides_service(xml, "File_system");
|
||||
xml.node("config", [&] () {
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "storage_dir");
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("buffer_size", "1M");
|
||||
xml.attribute("label", "storage_dir");
|
||||
});
|
||||
});
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "dev");
|
||||
|
||||
xml.node("cbe_trust_anchor", [&] () {
|
||||
xml.attribute("name", "cbe_trust_anchor");
|
||||
xml.attribute("storage_dir", "/storage_dir");
|
||||
});
|
||||
|
||||
xml.node("jitterentropy", [&] () {
|
||||
xml.attribute("name", "jitterentropy");
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "cbe_init_trust_anchor -> trust_anchor");
|
||||
xml.attribute("root", "/dev/cbe_trust_anchor");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "cbe_init -> trust_anchor");
|
||||
xml.attribute("root", "/dev/cbe_trust_anchor");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "cbe_vfs -> trust_anchor");
|
||||
xml.attribute("root", "/dev/cbe_trust_anchor");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_parent_service(xml, "File_system", "storage_dir");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_rump_vfs_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
gen_provides_service(xml, "File_system");
|
||||
xml.node("config", [&] () {
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("rump", [&] () {
|
||||
xml.attribute("fs", "ext2fs");
|
||||
xml.attribute("ram", "10M");
|
||||
});
|
||||
});
|
||||
|
||||
xml.node("default-policy", [&] () {
|
||||
xml.attribute("root", "/");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_child_service(xml, "vfs_block", "Block");
|
||||
route_to_parent_service(xml, "Timer");
|
||||
route_to_parent_service(xml, "RM");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_truncate_file_start_node(Xml_generator &xml,
|
||||
Child_state const &child,
|
||||
char const *path,
|
||||
size_t size)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.attribute("size", size);
|
||||
xml.attribute("path", path);
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "cbe");
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("label", "cbe");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_parent_service(xml, "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_sync_to_cbe_vfs_init_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.attribute("ld_verbose", "no");
|
||||
|
||||
xml.node("libc", [&] () {
|
||||
xml.attribute("stdin", "/dev/log");
|
||||
xml.attribute("stdout", "/dev/log");
|
||||
xml.attribute("stderr", "/dev/log");
|
||||
});
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "dev");
|
||||
xml.node("log", [&] () { });
|
||||
});
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "cbe");
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_cbe_vfs_block_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
gen_provides_service(xml, "Block");
|
||||
xml.node("config", [&] () {
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("buffer_size", "1M");
|
||||
});
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "mke2fs -> default");
|
||||
xml.attribute("block_size", "512");
|
||||
xml.attribute("file", "/data");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "resize2fs -> default");
|
||||
xml.attribute("block_size", "512");
|
||||
xml.attribute("file", "/data");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "rump_vfs -> ");
|
||||
xml.attribute("block_size", "512");
|
||||
xml.attribute("file", "/data");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_image_fs_query_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "no");
|
||||
});
|
||||
});
|
||||
xml.node("query", [&] () {
|
||||
xml.attribute("path", "/");
|
||||
xml.attribute("content", "no");
|
||||
xml.attribute("size", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_local_service(xml, "Report");
|
||||
route_to_parent_service(xml, "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_client_fs_fs_query_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "no");
|
||||
});
|
||||
});
|
||||
xml.node("query", [&] () {
|
||||
xml.attribute("path", "/");
|
||||
xml.attribute("content", "no");
|
||||
xml.attribute("size", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_local_service(xml, "Report");
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_fs_query_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("query", [&] () {
|
||||
xml.attribute("path", "/file_vault");
|
||||
xml.attribute("content", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_local_service(xml, "Report");
|
||||
route_to_parent_service(xml, "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_cbe_init_trust_anchor_start_node(Xml_generator &xml,
|
||||
Child_state const &child,
|
||||
Input_passphrase const &passphrase)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
|
||||
xml.attribute("passphrase", passphrase.plaintext().string());
|
||||
xml.attribute("trust_anchor_dir", "/trust_anchor");
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "trust_anchor");
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("label", "trust_anchor");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_child_service(xml, "cbe_trust_anchor_vfs", "File_system", "trust_anchor");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_cbe_image_vfs_block_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
gen_provides_service(xml, "Block");
|
||||
xml.node("config", [&] () {
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("buffer_size", "1M");
|
||||
});
|
||||
});
|
||||
xml.node("policy", [&] () {
|
||||
xml.attribute("label", "cbe_init -> ");
|
||||
xml.attribute("block_size", "512");
|
||||
xml.attribute("file", "/cbe.img");
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_parent_service(xml, "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_cbe_init_start_node(Xml_generator &xml,
|
||||
Child_state const &child,
|
||||
Tree_geometry const &vbd_geom,
|
||||
Tree_geometry const &ft_geom)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.attribute("trust_anchor_dir", "/trust_anchor");
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "trust_anchor");
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("label", "trust_anchor");
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("key", [&] () {
|
||||
xml.attribute("id", "12");
|
||||
});
|
||||
xml.node("virtual-block-device", [&] () {
|
||||
xml.attribute("nr_of_levels", vbd_geom.nr_of_levels());
|
||||
xml.attribute("nr_of_children", vbd_geom.nr_of_children());
|
||||
xml.attribute("nr_of_leafs", vbd_geom.nr_of_leaves());
|
||||
});
|
||||
xml.node("free-tree", [&] () {
|
||||
xml.attribute("nr_of_levels", ft_geom.nr_of_levels());
|
||||
xml.attribute("nr_of_children", ft_geom.nr_of_children());
|
||||
xml.attribute("nr_of_leafs", ft_geom.nr_of_leaves());
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_child_service(xml, "cbe_trust_anchor_vfs", "File_system", "trust_anchor");
|
||||
route_to_child_service(xml, "vfs_block", "Block");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_policy_for_child_service(Xml_generator &xml,
|
||||
char const *service_name,
|
||||
Child_state const &child)
|
||||
{
|
||||
xml.node("service", [&] () {
|
||||
xml.attribute("name", service_name);
|
||||
xml.node("default-policy", [&] () {
|
||||
xml.node("child", [&] () {
|
||||
xml.attribute("name", child.start_name());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_snapshots_fs_query_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("query", [&] () {
|
||||
xml.attribute("path", "/cbe/snapshots");
|
||||
xml.attribute("content", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_local_service(xml, "Report");
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_resizing_fs_tool_start_node(Xml_generator &xml,
|
||||
Child_state const &child,
|
||||
char const *tree,
|
||||
unsigned long nr_of_blocks)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.attribute("exit", "yes");
|
||||
xml.attribute("verbose", "no");
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "cbe");
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("new-file", [&] () {
|
||||
xml.attribute("path", "/cbe/cbe/control/extend");
|
||||
xml.append_content("tree=", tree, ",blocks=", nr_of_blocks);
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_resizing_fs_query_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("query", [&] () {
|
||||
xml.attribute("path", "/cbe/control");
|
||||
xml.attribute("content", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_local_service(xml, "Report");
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_shut_down_fs_tool_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.attribute("exit", "yes");
|
||||
xml.attribute("verbose", "no");
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "cbe");
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("new-file", [&] () {
|
||||
xml.attribute("path", "/cbe/cbe/control/deinitialize");
|
||||
xml.append_content("true");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_rekeying_fs_tool_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.attribute("exit", "yes");
|
||||
xml.attribute("verbose", "no");
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "cbe");
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("new-file", [&] () {
|
||||
xml.attribute("path", "/cbe/cbe/control/rekey");
|
||||
xml.append_content("true");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_shut_down_fs_query_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("query", [&] () {
|
||||
xml.attribute("path", "/cbe/control");
|
||||
xml.attribute("content", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_local_service(xml, "Report");
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_rekeying_fs_query_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("query", [&] () {
|
||||
xml.attribute("path", "/cbe/control");
|
||||
xml.attribute("content", "yes");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
route_to_local_service(xml, "Report");
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_create_snap_fs_tool_start_node(Xml_generator &xml,
|
||||
Child_state const &child)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.attribute("exit", "yes");
|
||||
xml.attribute("verbose", "no");
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "cbe");
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("new-file", [&] () {
|
||||
xml.attribute("path", "/cbe/cbe/control/create_snapshot");
|
||||
xml.append_content("true");
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void gen_discard_snap_fs_tool_start_node(Xml_generator &xml,
|
||||
Child_state const &child,
|
||||
Generation generation)
|
||||
{
|
||||
child.gen_start_node(xml, [&] () {
|
||||
|
||||
xml.node("config", [&] () {
|
||||
xml.attribute("exit", "yes");
|
||||
xml.attribute("verbose", "no");
|
||||
|
||||
xml.node("vfs", [&] () {
|
||||
xml.node("dir", [&] () {
|
||||
xml.attribute("name", "cbe");
|
||||
|
||||
xml.node("fs", [&] () {
|
||||
xml.attribute("writeable", "yes");
|
||||
});
|
||||
});
|
||||
});
|
||||
xml.node("new-file", [&] () {
|
||||
xml.attribute("path", "/cbe/cbe/control/discard_snapshot");
|
||||
xml.append_content(Generation_string(generation));
|
||||
});
|
||||
});
|
||||
xml.node("route", [&] () {
|
||||
|
||||
route_to_child_service(xml, "cbe_vfs", "File_system");
|
||||
gen_parent_routes_for_pd_rom_cpu_log(xml);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* SANDBOX_H_ */
|
45
repos/gems/src/app/file_vault/snapshot.h
Normal file
45
repos/gems/src/app/file_vault/snapshot.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* \brief Pointer of const object safe against null dereferencing
|
||||
* \author Martin Stein
|
||||
* \date 2021-04-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SNAPSHOT_H_
|
||||
#define _SNAPSHOT_H_
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
class Snapshot;
|
||||
}
|
||||
|
||||
class File_vault::Snapshot
|
||||
{
|
||||
private:
|
||||
|
||||
Generation const _generation;
|
||||
|
||||
public:
|
||||
|
||||
Snapshot(Generation const &generation)
|
||||
:
|
||||
_generation { generation }
|
||||
{ }
|
||||
|
||||
virtual ~Snapshot() { }
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Generation const &generation() const { return _generation; }
|
||||
};
|
||||
|
||||
#endif /* _SNAPSHOT_H_ */
|
36
repos/gems/src/app/file_vault/sync_to_cbe_vfs_init/main.cc
Normal file
36
repos/gems/src/app/file_vault/sync_to_cbe_vfs_init/main.cc
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* \brief Helps synchronizing the CBE manager to the CBE-driver initialization
|
||||
* \author Martin Stein
|
||||
* \date 2021-03-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* libC includes */
|
||||
extern "C" {
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
}
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
char const *file_path { "/cbe/cbe/current/data" };
|
||||
int const file_descriptor = open(file_path, O_RDONLY);
|
||||
if (file_descriptor < 0) {
|
||||
printf("Error: failed to open file %s\n", file_path);
|
||||
exit(-1);
|
||||
}
|
||||
int const result { fsync(file_descriptor) };
|
||||
if (result != 0) {
|
||||
printf("Error: fsync on file %s failed\n", file_path);
|
||||
exit(-1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
TARGET = file_vault-sync_to_cbe_vfs_init
|
||||
LIBS = posix
|
||||
SRC_CC = main.cc
|
6
repos/gems/src/app/file_vault/target.mk
Normal file
6
repos/gems/src/app/file_vault/target.mk
Normal file
@ -0,0 +1,6 @@
|
||||
TARGET := file_vault
|
||||
SRC_CC += main.cc menu_view_dialog.cc capacity.cc
|
||||
INC_DIR += $(PRG_DIR)
|
||||
LIBS += base sandbox vfs
|
||||
|
||||
CC_OPT += -Os
|
85
repos/gems/src/app/file_vault/truncate_file/main.cc
Normal file
85
repos/gems/src/app/file_vault/truncate_file/main.cc
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* \brief Helps synchronizing the CBE manager to the CBE-driver initialization
|
||||
* \author Martin Stein
|
||||
* \date 2021-03-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/component.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/heap.h>
|
||||
#include <os/vfs.h>
|
||||
|
||||
namespace Truncate_file {
|
||||
|
||||
class Main;
|
||||
}
|
||||
|
||||
using namespace Truncate_file;
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
class Truncate_file::Main
|
||||
{
|
||||
private:
|
||||
|
||||
Env &_env;
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
Root_directory _vfs { _env, _heap, _config.xml().sub_node("vfs") };
|
||||
Vfs::File_system &_fs { _vfs.root_dir() };
|
||||
Directory::Path const _path { _config.xml().attribute_value("path", Directory::Path { }) };
|
||||
Number_of_bytes const _size { _config.xml().attribute_value("size", Number_of_bytes { }) };
|
||||
|
||||
public:
|
||||
|
||||
Main(Env &env);
|
||||
};
|
||||
|
||||
|
||||
/*************************
|
||||
** Truncate_file::Main **
|
||||
*************************/
|
||||
|
||||
Main::Main(Env &env)
|
||||
:
|
||||
_env { env }
|
||||
{
|
||||
unsigned mode = Vfs::Directory_service::OPEN_MODE_WRONLY;
|
||||
|
||||
Vfs::Directory_service::Stat stat { };
|
||||
if (_fs.stat(_path.string(), stat) != Vfs::Directory_service::STAT_OK) {
|
||||
mode |= Vfs::Directory_service::OPEN_MODE_CREATE;
|
||||
}
|
||||
|
||||
Vfs::Vfs_handle *handle_ptr = nullptr;
|
||||
Vfs::Directory_service::Open_result const res =
|
||||
_fs.open(_path.string(), mode, &handle_ptr, _heap);
|
||||
|
||||
if (res != Vfs::Directory_service::OPEN_OK || (handle_ptr == nullptr)) {
|
||||
|
||||
error("failed to create file '", _path, "'");
|
||||
class Create_failed { };
|
||||
throw Create_failed { };
|
||||
}
|
||||
handle_ptr->fs().ftruncate(handle_ptr, _size);
|
||||
handle_ptr->ds().close(handle_ptr);
|
||||
_env.parent().exit(0);
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** Genode::Component **
|
||||
***********************/
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
static Truncate_file::Main main { env };
|
||||
}
|
4
repos/gems/src/app/file_vault/truncate_file/target.mk
Normal file
4
repos/gems/src/app/file_vault/truncate_file/target.mk
Normal file
@ -0,0 +1,4 @@
|
||||
TARGET := file_vault-truncate_file
|
||||
SRC_CC += main.cc
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
LIBS += base vfs
|
55
repos/gems/src/app/file_vault/types.h
Normal file
55
repos/gems/src/app/file_vault/types.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* \brief Common types
|
||||
* \author Martin Stein
|
||||
* \date 2021-02-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _TYPES_H_
|
||||
#define _TYPES_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <cbe/types.h>
|
||||
|
||||
namespace Genode { }
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
using namespace Cbe;
|
||||
using namespace Genode;
|
||||
|
||||
using Node_name = String<32>;
|
||||
|
||||
class Tree_geometry
|
||||
{
|
||||
private:
|
||||
|
||||
uint64_t const _nr_of_levels;
|
||||
uint64_t const _nr_of_children;
|
||||
uint64_t const _nr_of_leaves;
|
||||
|
||||
public:
|
||||
|
||||
Tree_geometry(
|
||||
uint64_t nr_of_levels,
|
||||
uint64_t nr_of_children,
|
||||
uint64_t nr_of_leaves)
|
||||
:
|
||||
_nr_of_levels { nr_of_levels },
|
||||
_nr_of_children { nr_of_children },
|
||||
_nr_of_leaves { nr_of_leaves }
|
||||
{ }
|
||||
|
||||
uint64_t nr_of_levels() const { return _nr_of_levels ; }
|
||||
uint64_t nr_of_children() const { return _nr_of_children; }
|
||||
uint64_t nr_of_leaves() const { return _nr_of_leaves ; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _TYPES_H_ */
|
32
repos/gems/src/app/file_vault/utf8.h
Normal file
32
repos/gems/src/app/file_vault/utf8.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* \brief Local extension of Genodes UTF8 utilities
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2021-03-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _UTF8_H_
|
||||
#define _UTF8_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/utf8.h>
|
||||
|
||||
/* local includes */
|
||||
#include <types.h>
|
||||
|
||||
namespace File_vault {
|
||||
|
||||
enum {
|
||||
CODEPOINT_BACKSPACE = 8,
|
||||
CODEPOINT_TAB = 9,
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _UTF8_H_ */
|
Loading…
Reference in New Issue
Block a user