Compare commits
245 Commits
release3.0
...
master
Author | SHA1 | Date |
---|---|---|
Rusty Bird | 9debe185fc | 4 years ago |
Frédéric Pierret (fepitre) | 29a0c0e7f4 | 4 years ago |
Marek Marczykowski-Górecki | 3a0a629a38 | 4 years ago |
Marek Marczykowski-Górecki | ef2ab997bf | 4 years ago |
Marek Marczykowski-Górecki | 2ba9fd6c23 | 4 years ago |
Marek Marczykowski-Górecki | 241f812304 | 4 years ago |
Patrick Schleizer | 8821906186 | 5 years ago |
Patrick Schleizer | 34c8212467 | 5 years ago |
Marek Marczykowski-Górecki | 9f0dc7dc34 | 5 years ago |
Frédéric Pierret (fepitre) | c110f98fdf | 5 years ago |
xaki23 | 699e10c057 | 5 years ago |
Marek Marczykowski-Górecki | 82a44bc850 | 5 years ago |
Marek Marczykowski-Górecki | bd55c1efe4 | 5 years ago |
Marek Marczykowski-Górecki | ba6be8d8be | 5 years ago |
Marek Marczykowski-Górecki | 61931747a8 | 5 years ago |
xaki23 | ecc0b70f67 | 5 years ago |
Marek Marczykowski-Górecki | 81c64d56a2 | 5 years ago |
Marek Marczykowski-Górecki | 84188910cf | 5 years ago |
Marek Marczykowski-Górecki | 66a6e33f41 | 5 years ago |
Marek Marczykowski-Górecki | d48e497aff | 5 years ago |
Marek Marczykowski-Górecki | c046807641 | 5 years ago |
Marek Marczykowski-Górecki | 7486078769 | 5 years ago |
Marek Marczykowski-Górecki | 042b6717a8 | 5 years ago |
Marek Marczykowski-Górecki | 9c6c825691 | 5 years ago |
Marek Marczykowski-Górecki | 90641b0dce | 5 years ago |
Marek Marczykowski-Górecki | e7c90c705f | 5 years ago |
Frédéric Pierret (fepitre) | f365d7cce8 | 5 years ago |
Frédéric Pierret (fepitre) | 2b8411346f | 5 years ago |
Frédéric Pierret (fepitre) | e00a64a915 | 5 years ago |
Marek Marczykowski-Górecki | 24a25cce5f | 5 years ago |
Marek Marczykowski-Górecki | de2150e3d3 | 5 years ago |
Marek Marczykowski-Górecki | ad790a53d4 | 5 years ago |
Marek Marczykowski-Górecki | 2c696013cd | 5 years ago |
Marek Marczykowski-Górecki | 4fe08d31e4 | 5 years ago |
Marek Marczykowski-Górecki | da61cb7511 | 5 years ago |
Marek Marczykowski-Górecki | 5eb526da4b | 5 years ago |
Marek Marczykowski-Górecki | 456fe99fa6 | 5 years ago |
Marek Marczykowski-Górecki | 14be8aa5ae | 6 years ago |
Marek Marczykowski-Górecki | 4543ab1ff0 | 6 years ago |
Marek Marczykowski-Górecki | 4bfd10baaa | 6 years ago |
Marek Marczykowski-Górecki | 0255f4d843 | 6 years ago |
Marek Marczykowski-Górecki | e2d7f08d42 | 6 years ago |
Marek Marczykowski-Górecki | 76fa9c9d9f | 6 years ago |
Marek Marczykowski-Górecki | 3ca9f130b7 | 6 years ago |
Rusty Bird | 6cd4a1b888 | 6 years ago |
Marek Marczykowski-Górecki | ab7ca7be89 | 6 years ago |
Marek Marczykowski-Górecki | f7b8a79ce6 | 6 years ago |
Marek Marczykowski-Górecki | 915c8f0cf7 | 6 years ago |
Marek Marczykowski-Górecki | 645d23b712 | 6 years ago |
Marek Marczykowski-Górecki | 89776c7f18 | 6 years ago |
Marek Marczykowski-Górecki | 4157f919b6 | 6 years ago |
Marek Marczykowski-Górecki | cf6438807b | 6 years ago |
Marek Marczykowski-Górecki | 0df0d23ec6 | 6 years ago |
Marek Marczykowski-Górecki | 9eafc65cb4 | 6 years ago |
Frédéric Pierret | f049d63571 | 6 years ago |
Frédéric Pierret | 2b3b684107 | 6 years ago |
Frédéric Pierret | a716102a08 | 6 years ago |
Frédéric Pierret | 0630c17588 | 6 years ago |
Marek Marczykowski-Górecki | 84c9ae4bf1 | 6 years ago |
Marek Marczykowski-Górecki | 610e7d8f3e | 6 years ago |
Marek Marczykowski-Górecki | 258b7926ef | 6 years ago |
Frédéric Pierret | d60964ee23 | 6 years ago |
Frédéric Pierret | 2f511d4881 | 6 years ago |
Frédéric Pierret | e3179e066c | 6 years ago |
Frédéric Pierret | d1ce12f610 | 6 years ago |
Marek Marczykowski-Górecki | ff36d11c19 | 6 years ago |
Marek Marczykowski-Górecki | d623a3e7d3 | 6 years ago |
Marek Marczykowski-Górecki | 50412a8a8f | 6 years ago |
Marek Marczykowski-Górecki | ff2e2dbc22 | 6 years ago |
Marek Marczykowski-Górecki | e37f9da355 | 6 years ago |
Marek Marczykowski-Górecki | 6eab71f678 | 6 years ago |
Marek Marczykowski-Górecki | ab2fa766b9 | 6 years ago |
Rusty Bird | 6b3830ba31 | 6 years ago |
Reynir Björnsson | f4ec550291 | 6 years ago |
Marek Marczykowski-Górecki | 929e03bcba | 6 years ago |
Marek Marczykowski-Górecki | f42951578a | 6 years ago |
Marek Marczykowski-Górecki | 2b1f8931a6 | 6 years ago |
Marek Marczykowski-Górecki | 34e3c3acf3 | 6 years ago |
Marek Marczykowski-Górecki | c57f28d8f7 | 6 years ago |
Marek Marczykowski-Górecki | 1a77802b20 | 6 years ago |
Marek Marczykowski-Górecki | 691f4e52f4 | 6 years ago |
Marek Marczykowski-Górecki | 20be8e2417 | 6 years ago |
Marek Marczykowski-Górecki | 3899ca1e5d | 6 years ago |
Marek Marczykowski-Górecki | 2ac5c03bb3 | 6 years ago |
Marek Marczykowski-Górecki | 3e41a2987c | 6 years ago |
Gianluca Guida | 5fbd19e1d6 | 7 years ago |
Marek Marczykowski-Górecki | 72343fe0cd | 7 years ago |
Marek Marczykowski-Górecki | ee66bb4c80 | 7 years ago |
Marek Marczykowski-Górecki | dc5d025247 | 7 years ago |
Marek Marczykowski-Górecki | 3d44d3a80b | 7 years ago |
Patrick Schleizer | 7360aee988 | 7 years ago |
Marek Marczykowski-Górecki | e784f3caa3 | 7 years ago |
Marek Marczykowski-Górecki | 68d7be77db | 7 years ago |
Marek Marczykowski-Górecki | 6cb980f5be | 7 years ago |
Marek Marczykowski-Górecki | 0a7d2c0789 | 7 years ago |
Marek Marczykowski-Górecki | 92a86fad18 | 7 years ago |
Marek Marczykowski-Górecki | 141b9912e8 | 7 years ago |
Marek Marczykowski-Górecki | 75fa0d3cb0 | 7 years ago |
Your Name | a96fe7203e | 7 years ago |
qubesuser | ee58088dec | 7 years ago |
qubesuser | 843ac6c477 | 7 years ago |
qubesuser | 86e9231ac9 | 7 years ago |
qubesuser | 6c6070ab49 | 7 years ago |
qubesuser | f893420871 | 7 years ago |
qubesuser | 4d08ff40a9 | 7 years ago |
Olivier MEDOC | 19cb61a0ed | 7 years ago |
Marek Marczykowski-Górecki | f7cd2b2a76 | 7 years ago |
Marek Marczykowski-Górecki | 09e6d2ac95 | 7 years ago |
Marek Marczykowski-Górecki | e9615899ff | 7 years ago |
Marek Marczykowski-Górecki | b227d01a8a | 7 years ago |
Marek Marczykowski-Górecki | 766f83de8e | 7 years ago |
Marek Marczykowski-Górecki | b2207b44fc | 7 years ago |
Frédéric Pierret | b3f24caaf2 | 7 years ago |
Marek Marczykowski-Górecki | c62c8e4416 | 7 years ago |
Marek Marczykowski-Górecki | c7420318e2 | 7 years ago |
Olivier MEDOC | 0207537b50 | 7 years ago |
Marek Marczykowski-Górecki | d703652070 | 7 years ago |
Marek Marczykowski-Górecki | 764b0f3f07 | 7 years ago |
Marek Marczykowski-Górecki | dd71f295e5 | 7 years ago |
Jean-Philippe Ouellet | 349f79bc66 | 7 years ago |
Marek Marczykowski-Górecki | 22c94c37a9 | 7 years ago |
Marek Marczykowski-Górecki | 823d73a524 | 7 years ago |
Marek Marczykowski-Górecki | 43908b7eaa | 7 years ago |
Marek Marczykowski-Górecki | b130b79b28 | 7 years ago |
Marek Marczykowski-Górecki | 4dd813c14b | 7 years ago |
Marek Marczykowski-Górecki | 0d4c561064 | 7 years ago |
HW42 | f14637a615 | 7 years ago |
Marek Marczykowski-Górecki | 1b437e57d5 | 7 years ago |
Marek Marczykowski-Górecki | eb1b20fd48 | 7 years ago |
Rusty Bird | 90a1e6abbd | 7 years ago |
Marek Marczykowski-Górecki | da3f3cd426 | 7 years ago |
Paras Chetal | e9b8e5a4d1 | 7 years ago |
Marek Marczykowski-Górecki | 77c6d8be6a | 7 years ago |
Marek Marczykowski-Górecki | 4d6579474d | 7 years ago |
Marek Marczykowski-Górecki | 02d9a1e68f | 7 years ago |
Marek Marczykowski-Górecki | 95805f6333 | 7 years ago |
Marek Marczykowski-Górecki | 6c36cb8de9 | 7 years ago |
unman | 1db0daea9c | 7 years ago |
Marek Marczykowski-Górecki | 40fe0d9c8f | 7 years ago |
Marek Marczykowski-Górecki | ae56d597f3 | 7 years ago |
Marek Marczykowski-Górecki | 488627e2e6 | 7 years ago |
Marek Marczykowski-Górecki | 513a1cecf2 | 7 years ago |
Marek Marczykowski-Górecki | 13b9ea7f1c | 7 years ago |
Marek Marczykowski-Górecki | d0fe5e6f9a | 7 years ago |
Marek Marczykowski-Górecki | 5c7c54adab | 7 years ago |
Marek Marczykowski-Górecki | 69a3f06f99 | 7 years ago |
Marek Marczykowski-Górecki | 9f6018bdb5 | 7 years ago |
Marek Marczykowski-Górecki | b52f4e0f36 | 7 years ago |
Marek Marczykowski-Górecki | fbbd21a54b | 7 years ago |
Marek Marczykowski-Górecki | 44edc8a9b2 | 7 years ago |
Wojtek Porczyk | 162e3734e5 | 7 years ago |
Wojtek Porczyk | 2a0bbe1c6f | 7 years ago |
Wojtek Porczyk | b6ad625b85 | 7 years ago |
Marek Marczykowski-Górecki | 4de6e4d9be | 7 years ago |
Marek Marczykowski-Górecki | ee5badddd5 | 7 years ago |
M. Vefa Bicakci | 7470251cb8 | 7 years ago |
Olivier MEDOC | e83c8036e6 | 7 years ago |
Marek Marczykowski-Górecki | d3cda230b4 | 7 years ago |
Olivier MEDOC | dfde69e9a7 | 7 years ago |
Olivier MEDOC | e398441481 | 7 years ago |
Marek Marczykowski-Górecki | db2b027153 | 8 years ago |
Johanna A | e01745f66f | 8 years ago |
Marek Marczykowski-Górecki | fbcad1cb17 | 8 years ago |
Marek Marczykowski-Górecki | e0acdee23c | 8 years ago |
Marek Marczykowski-Górecki | 3422cffe0d | 8 years ago |
Rusty Bird | a032129b80 | 8 years ago |
Rusty Bird | 6b32378158 | 8 years ago |
Rusty Bird | e7d7111f13 | 8 years ago |
Marek Marczykowski-Górecki | e9a21c03c2 | 8 years ago |
Marek Marczykowski-Górecki | a9d26d6ed0 | 8 years ago |
Marek Marczykowski-Górecki | f7eea5548a | 8 years ago |
Marek Marczykowski-Górecki | 281c628b0e | 8 years ago |
Marek Marczykowski-Górecki | b040debb36 | 8 years ago |
Marek Marczykowski-Górecki | 410ad3d25f | 8 years ago |
Marek Marczykowski-Górecki | 93f676d998 | 8 years ago |
Marek Marczykowski-Górecki | cf5f382d7a | 8 years ago |
Marek Marczykowski-Górecki | c926f4565d | 8 years ago |
Marek Marczykowski-Górecki | b442929695 | 8 years ago |
Marek Marczykowski-Górecki | cdbcb2eb55 | 8 years ago |
Marek Marczykowski-Górecki | b25bab4421 | 8 years ago |
Marek Marczykowski-Górecki | 098bfb634d | 8 years ago |
Marek Marczykowski-Górecki | efd9854376 | 8 years ago |
Marek Marczykowski-Górecki | 98aed38ec5 | 8 years ago |
Johanna A | 79cb426825 | 8 years ago |
Marek Marczykowski-Górecki | 29cf44233a | 8 years ago |
Marek Marczykowski-Górecki | 0a0b04f88d | 8 years ago |
Marek Marczykowski-Górecki | 22d6892ec9 | 8 years ago |
Olivier MEDOC | 269d87ff0d | 8 years ago |
Olivier MEDOC | 66eaa697dd | 8 years ago |
Olivier MEDOC | 0b35e4d327 | 8 years ago |
Olivier MEDOC | a8d9bd8842 | 8 years ago |
Olivier MEDOC | 8bd7132fa8 | 8 years ago |
Marek Marczykowski-Górecki | 1d20cdea89 | 8 years ago |
Marek Marczykowski-Górecki | 6ac3fc3247 | 8 years ago |
Marek Marczykowski-Górecki | 50145d448a | 8 years ago |
Marek Marczykowski-Górecki | e23cbbc261 | 8 years ago |
pqg | 86e7f7c2c8 | 9 years ago |
Marek Marczykowski-Górecki | 4dc959e94f | 9 years ago |
Marek Marczykowski-Górecki | c2c36d9c09 | 9 years ago |
HW42 | 931944f118 | 9 years ago |
Marek Marczykowski-Górecki | 8da3f09ccc | 9 years ago |
Marek Marczykowski-Górecki | fae64a2c69 | 9 years ago |
Marek Marczykowski-Górecki | 3fc71a3b40 | 9 years ago |
Marek Marczykowski-Górecki | 14297508e5 | 9 years ago |
Marek Marczykowski-Górecki | b625704edd | 9 years ago |
Marek Marczykowski-Górecki | d95174f52c | 9 years ago |
Marek Marczykowski-Górecki | 7148f8d135 | 9 years ago |
Marek Marczykowski-Górecki | 031dd4c844 | 9 years ago |
Marek Marczykowski-Górecki | 2f1c8ea459 | 9 years ago |
Marek Marczykowski-Górecki | a23030e49f | 9 years ago |
Marek Marczykowski-Górecki | 6cd22a42bb | 9 years ago |
Marek Marczykowski-Górecki | 61f6054ce3 | 9 years ago |
Marek Marczykowski-Górecki | cd277485bb | 9 years ago |
Rusty Bird | 4f59b3df6f | 9 years ago |
Marek Marczykowski-Górecki | 8311e1263d | 9 years ago |
Marek Marczykowski-Górecki | 170d46c40d | 9 years ago |
Marek Marczykowski-Górecki | 83c03af067 | 9 years ago |
Marek Marczykowski-Górecki | 3826f4070f | 9 years ago |
Rusty Bird | 74a1b4cc50 | 9 years ago |
Marek Marczykowski-Górecki | 5b250eb279 | 9 years ago |
Marek Marczykowski-Górecki | dfe5c11a55 | 9 years ago |
Marek Marczykowski-Górecki | 64331d7e09 | 9 years ago |
Marek Marczykowski-Górecki | 3cd77e4f70 | 9 years ago |
Marek Marczykowski-Górecki | 25c05a3bd3 | 9 years ago |
Marek Marczykowski-Górecki | aaf84ba305 | 9 years ago |
Marek Marczykowski-Górecki | 789e9c2549 | 9 years ago |
Marek Marczykowski-Górecki | 42469fdbe4 | 9 years ago |
Marek Marczykowski-Górecki | 882052eca0 | 9 years ago |
Marek Marczykowski-Górecki | d1238ce060 | 9 years ago |
Marek Marczykowski-Górecki | 603e8f8685 | 9 years ago |
qubesuser | 71ce41cf61 | 9 years ago |
Marek Marczykowski-Górecki | 1a3be481b5 | 9 years ago |
Marek Marczykowski-Górecki | 6a44eaeb09 | 9 years ago |
Marek Marczykowski-Górecki | 632522b35e | 9 years ago |
Marek Marczykowski-Górecki | a30d583249 | 9 years ago |
Marek Marczykowski-Górecki | 0f954034a1 | 9 years ago |
Marek Marczykowski-Górecki | d3d84d5d49 | 9 years ago |
Marek Marczykowski-Górecki | e9c1d12aa4 | 9 years ago |
Marek Marczykowski-Górecki | c9335ddc5c | 9 years ago |
Marek Marczykowski-Górecki | c1d42f1602 | 9 years ago |
qubesuser | ec9f12815b | 9 years ago |
qubesuser | 2f5ef8e2aa | 9 years ago |
qubesuser | 2d871075cc | 9 years ago |
Marek Marczykowski-Górecki | e745b87939 | 9 years ago |
Marek Marczykowski-Górecki | b853318baf | 9 years ago |
@ -0,0 +1,39 @@
|
||||
sudo: required
|
||||
dist: bionic
|
||||
language: python
|
||||
python:
|
||||
- '2.7'
|
||||
install:
|
||||
- test -z "$TESTS_ONLY" || pip install -r ci/requirements.txt
|
||||
- test -n "$TESTS_ONLY" || git clone https://github.com/QubesOS/qubes-builder ~/qubes-builder
|
||||
script:
|
||||
- test -z "$TESTS_ONLY" || python -m unittest discover -v imgconverter -p test.py
|
||||
- test -n "$TESTS_ONLY" || ~/qubes-builder/scripts/travis-build
|
||||
env:
|
||||
- DIST_DOM0=fc31 USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1
|
||||
- DISTS_VM=fc29 USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1
|
||||
- DISTS_VM=fc30 USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1
|
||||
- DISTS_VM=stretch USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1
|
||||
- DISTS_VM=buster USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1
|
||||
- DISTS_VM=centos7 USE_QUBES_REPO_VERSION=4.1 USE_QUBES_REPO_TESTING=1
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- env: TESTS_ONLY=1
|
||||
python: 2.7
|
||||
- env: TESTS_ONLY=1
|
||||
python: 3.5
|
||||
- env: TESTS_ONLY=1
|
||||
python: 3.6
|
||||
- env: TESTS_ONLY=1
|
||||
python: 3.7
|
||||
- stage: deploy
|
||||
python: 3.6
|
||||
env: DIST_DOM0=fc31 TESTS_ONLY=
|
||||
script: ~/qubes-builder/scripts/travis-deploy
|
||||
|
||||
# don't build tags which are meant for code signing only
|
||||
branches:
|
||||
except:
|
||||
- /.*_.*/
|
||||
|
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/ash
|
||||
|
||||
run_earlyhook() {
|
||||
|
||||
msg "Starting Qubes copy on write setup script"
|
||||
|
||||
/usr/lib/qubes/qubes_cow_setup.sh
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
build() {
|
||||
|
||||
add_module "xen-blkfront"
|
||||
add_binary "/usr/bin/sfdisk"
|
||||
add_binary "/usr/bin/mkswap"
|
||||
add_binary "/usr/bin/dmsetup"
|
||||
add_binary "/usr/lib/qubes/qubes_cow_setup.sh"
|
||||
|
||||
add_runscript
|
||||
|
||||
}
|
||||
|
||||
help() {
|
||||
cat <<HELPEOF
|
||||
This hook enables Qubes COW Setup (using lvm) in initramfs.
|
||||
HELPEOF
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
|
||||
help() {
|
||||
echo "Before using pvgrub, the kernel you want to use needs to be regenerated with Qubes kernel modules in the TemplateVM:"
|
||||
echo "1/ Ensure that your kernel and kernel sources are installed (ex: pacman -S linux-lts linux-lts-headers)"
|
||||
echo "2/ Ensure that grub config file has been generated for your kernel (ex: grub-mkconfig > /boot/grub/grub.cfg)"
|
||||
echo "3/ Reinstall qubes-vm-kernel-support to ensure Qubes-OS kernel module is compiled and that the initcpio is rebuilt"
|
||||
echo "This should then be handled automatically in your next kernel updates"
|
||||
}
|
||||
|
||||
## arg 1: the new package version
|
||||
post_install() {
|
||||
echo "Adding qubes required hooks to mkinitcpio.conf"
|
||||
sed 's/^HOOKS="base/HOOKS="lvm2 qubes base/' -i /etc/mkinitcpio.conf
|
||||
help
|
||||
}
|
||||
|
||||
post_upgrade() {
|
||||
echo "Adding qubes required hooks to mkinitcpio.conf"
|
||||
sed 's/^HOOKS="base/HOOKS="lvm2 qubes base/' -i /etc/mkinitcpio.conf
|
||||
help
|
||||
}
|
||||
|
||||
post_remove() {
|
||||
echo "Removing qubes required hooks to mkinitcpio.conf"
|
||||
sed 's/^HOOKS="lvm2 qubes base/HOOKS="base/' -i /etc/mkinitcpio.conf
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
Pillow
|
||||
numpy
|
@ -1,20 +0,0 @@
|
||||
PYTHON = /usr/bin/python2
|
||||
PYTHON_SITEARCH = `python2 -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1)'`
|
||||
|
||||
all:
|
||||
$(PYTHON) -m compileall .
|
||||
$(PYTHON) -O -m compileall .
|
||||
.PHONY: all
|
||||
|
||||
clean:
|
||||
$(RM) *.py[co]
|
||||
.PHONY: clean
|
||||
|
||||
install:
|
||||
mkdir -p $(DESTDIR)/$(PYTHON_SITEARCH)/qubes/
|
||||
ifeq (1,${DEBIANBUILD})
|
||||
cp *.py $(DESTDIR)/$(PYTHON_SITEARCH)/qubes/
|
||||
else
|
||||
cp *.py* $(DESTDIR)/$(PYTHON_SITEARCH)/qubes/
|
||||
endif
|
||||
.PHONY: install
|
@ -0,0 +1,2 @@
|
||||
usr/include/libqubes-rpc-filecopy.h
|
||||
usr/lib/libqubes-rpc-filecopy.so
|
@ -0,0 +1 @@
|
||||
usr/lib/libqubes-rpc-filecopy.so.2*
|
@ -0,0 +1 @@
|
||||
libqubes-rpc-filecopy 2 libqubes-rpc-filecopy2 (>= 3.1.3)
|
@ -0,0 +1,8 @@
|
||||
usr/share/initramfs-tools/scripts/local-top/scrub_pages
|
||||
usr/share/initramfs-tools/scripts/local-top/qubes_cow_setup
|
||||
usr/share/initramfs-tools/hooks/qubes_vm
|
||||
usr/lib/dracut/modules.d/90qubes-vm/*
|
||||
usr/lib/dracut/modules.d/90qubes-vm-modules/*
|
||||
usr/lib/dracut/modules.d/90qubes-vm-simple/*
|
||||
usr/lib/dracut/modules.d/80xen-scrub-pages/*
|
||||
etc/default/grub.d/30-qubes-kernel-vm-support.cfg
|
@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
# postinst script for qubes-kernel-vm-support
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# The postinst script may be called in the following ways:
|
||||
# * <postinst> 'configure' <most-recently-configured-version>
|
||||
# * <old-postinst> 'abort-upgrade' <new version>
|
||||
# * <conflictor's-postinst> 'abort-remove' 'in-favour' <package>
|
||||
# <new-version>
|
||||
# * <postinst> 'abort-remove'
|
||||
# * <deconfigured's-postinst> 'abort-deconfigure' 'in-favour'
|
||||
# <failed-install-package> <version> 'removing'
|
||||
# <conflicting-package> <version>
|
||||
#
|
||||
# For details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html or
|
||||
# the debian-policy package
|
||||
|
||||
|
||||
case "${1}" in
|
||||
configure)
|
||||
if [ -x /usr/sbin/update-initramfs ]; then
|
||||
if update-initramfs -u; then
|
||||
# "milestone" initramfs update version:
|
||||
# 1 - addition of xen scrub_pages enabling code
|
||||
echo 1 > /var/lib/qubes/initramfs-updated
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`${1}'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
## https://phabricator.whonix.org/T377
|
||||
## Debian has no update-grub trigger yet:
|
||||
## https://bugs.debian.org/481542
|
||||
|
||||
if command -v update-grub >/dev/null 2>&1; then
|
||||
update-grub || \
|
||||
echo "$DPKG_MAINTSCRIPT_PACKAGE $DPKG_MAINTSCRIPT_NAME ERROR: Running \
|
||||
'update-grub' failed with exit code $?. $DPKG_MAINTSCRIPT_PACKAGE is most \
|
||||
likely only the trigger, not the cause. Unless you know this is not an issue, \
|
||||
you should fix running 'update-grub', otherwise your system might no longer \
|
||||
boot." >&2
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# vim: set ts=4 sw=4 sts=4 et :
|
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
mkdir --parents /boot/grub || true
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
@ -0,0 +1,5 @@
|
||||
usr/sbin/meminfo-writer
|
||||
lib/systemd/system/qubes-meminfo-writer.service
|
||||
usr/lib/qubes/*
|
||||
usr/lib/python2.7/dist-packages/qubesimgconverter*/*
|
||||
lib/udev/*
|
@ -0,0 +1,3 @@
|
||||
rm_conffile /etc/udev/rules.d/99-qubes-block.rules 3.1.6~
|
||||
rm_conffile /etc/udev/rules.d/99-qubes-usb.rules 3.1.6~
|
||||
rm_conffile /etc/udev/rules.d/99-qubes-misc.rules 3.1.6~
|
@ -1,3 +1,5 @@
|
||||
install:
|
||||
$(MAKE) -C simple
|
||||
$(MAKE) -C full
|
||||
$(MAKE) -C full-dmroot
|
||||
$(MAKE) -C full-modules
|
||||
$(MAKE) -C xen-balloon-scrub-pages
|
||||
|
@ -1,4 +1,4 @@
|
||||
install:
|
||||
install -d $(DESTDIR)/usr/lib/dracut/modules.d/90qubes-vm
|
||||
install module-setup.sh mount_modules.sh qubes_cow_setup.sh \
|
||||
install module-setup.sh qubes_cow_setup.sh \
|
||||
$(DESTDIR)/usr/lib/dracut/modules.d/90qubes-vm/
|
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
check() {
|
||||
if xenstore-read qubes-vm-type &>/dev/null || qubesdb-read /qubes-vm-type &>/dev/null; then
|
||||
return 0
|
||||
else
|
||||
return 255
|
||||
fi
|
||||
}
|
||||
|
||||
depends() {
|
||||
echo dm
|
||||
return 0
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_hook pre-trigger 90 $moddir/qubes_cow_setup.sh
|
||||
inst_multiple \
|
||||
sfdisk \
|
||||
mkswap
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This file should be placed in pre-trigger directory in dracut's initramfs, or
|
||||
# scripts/local-top in case of initramfs-tools
|
||||
#
|
||||
|
||||
# initramfs-tools (Debian) API
|
||||
PREREQS=""
|
||||
case "$1" in
|
||||
prereqs)
|
||||
# This runs during initramfs creation
|
||||
echo "$PREREQS"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# This runs inside real initramfs
|
||||
if [ -r /scripts/functions ]; then
|
||||
# We're running in Debian's initramfs
|
||||
. /scripts/functions
|
||||
alias die=panic
|
||||
alias info=true
|
||||
alias warn=log_warning_msg
|
||||
alias log_begin=log_begin_msg
|
||||
alias log_end=log_end_msg
|
||||
elif [ -r /lib/dracut-lib.sh ]; then
|
||||
. /lib/dracut-lib.sh
|
||||
alias log_begin=info
|
||||
alias log_end=true
|
||||
else
|
||||
die() {
|
||||
echo "$@"
|
||||
exit 1
|
||||
}
|
||||
alias info=echo
|
||||
alias warn=echo
|
||||
alias log_begin=echo
|
||||
alias log_end=true
|
||||
fi
|
||||
|
||||
|
||||
info "Qubes initramfs script here:"
|
||||
|
||||
if ! grep -q 'root=[^ ]*dmroot' /proc/cmdline; then
|
||||
warn "dmroot not requested, probably not a Qubes VM"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -e /dev/mapper/dmroot ] ; then
|
||||
die "Qubes: FATAL error: /dev/mapper/dmroot already exists?!"
|
||||
fi
|
||||
|
||||
modprobe xenblk || modprobe xen-blkfront || warn "Qubes: Cannot load Xen Block Frontend..."
|
||||
|
||||
log_begin "Waiting for /dev/xvda* devices..."
|
||||
udevadm settle --exit-if-exists=/dev/xvda
|
||||
log_end
|
||||
|
||||
# prefer partition if exists
|
||||
if [ -b /dev/xvda1 ]; then
|
||||
if [ -e "/dev/disk/by-partlabel/Root\\x20filesystem" ]; then
|
||||
ROOT_DEV=$(basename $(readlink "/dev/disk/by-partlabel/Root\\x20filesystem"))
|
||||
else
|
||||
ROOT_DEV=xvda3
|
||||
fi
|
||||
else
|
||||
ROOT_DEV=xvda
|
||||
fi
|
||||
|
||||
SWAP_SIZE=$(( 1024 * 1024 * 2 )) # sectors, 1GB
|
||||
|
||||
if [ `cat /sys/class/block/$ROOT_DEV/ro` = 1 ] ; then
|
||||
log_begin "Qubes: Doing COW setup for AppVM..."
|
||||
|
||||
while ! [ -e /dev/xvdc ]; do sleep 0.1; done
|
||||
VOLATILE_SIZE=$(cat /sys/class/block/xvdc/size) # sectors
|
||||
ROOT_SIZE=$(cat /sys/class/block/$ROOT_DEV/size) # sectors
|
||||
if [ $VOLATILE_SIZE -lt $SWAP_SIZE ]; then
|
||||
die "volatile.img smaller than 1GB, cannot continue"
|
||||
fi
|
||||
sfdisk -q --unit S /dev/xvdc >/dev/null <<EOF
|
||||
xvdc1: type=82,start=2048,size=$SWAP_SIZE
|
||||
xvdc2: type=83
|
||||
EOF
|
||||
if [ $? -ne 0 ]; then
|
||||
die "Qubes: failed to setup partitions on volatile device"
|
||||
fi
|
||||
while ! [ -e /dev/xvdc1 ]; do sleep 0.1; done
|
||||
mkswap /dev/xvdc1
|
||||
while ! [ -e /dev/xvdc2 ]; do sleep 0.1; done
|
||||
|
||||
echo "0 `cat /sys/class/block/$ROOT_DEV/size` snapshot /dev/$ROOT_DEV /dev/xvdc2 N 16" | \
|
||||
dmsetup --noudevsync create dmroot || die "Qubes: FATAL: cannot create dmroot!"
|
||||
dmsetup mknodes dmroot
|
||||
log_end
|
||||
else
|
||||
log_begin "Qubes: Doing R/W setup for TemplateVM..."
|
||||
while ! [ -e /dev/xvdc ]; do sleep 0.1; done
|
||||
sfdisk -q --unit S /dev/xvdc >/dev/null <<EOF
|
||||
xvdc1: type=82,start=2048,size=$SWAP_SIZE
|
||||
xvdc3: type=83
|
||||
EOF
|
||||
if [ $? -ne 0 ]; then
|
||||
die "Qubes: failed to setup partitions on volatile device"
|
||||
fi
|
||||
while ! [ -e /dev/xvdc1 ]; do sleep 0.1; done
|
||||
mkswap /dev/xvdc1
|
||||
mkdir -p /etc/udev/rules.d
|
||||
printf 'KERNEL=="%s", SYMLINK+="mapper/dmroot"\n' "$ROOT_DEV" >> \
|
||||
/etc/udev/rules.d/99-root.rules
|
||||
udevadm control -R
|
||||
udevadm trigger
|
||||
log_end
|
||||
fi
|
@ -0,0 +1,4 @@
|
||||
install:
|
||||
install -d $(DESTDIR)/usr/lib/dracut/modules.d/90qubes-vm-modules
|
||||
install module-setup.sh mount_modules.sh \
|
||||
$(DESTDIR)/usr/lib/dracut/modules.d/90qubes-vm-modules/
|
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
check() {
|
||||
return 255
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_hook pre-pivot 50 $moddir/mount_modules.sh
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This file should be places in pre-pivot directory in dracut's initramfs
|
||||
#
|
||||
|
||||
|
||||
kver="`uname -r`"
|
||||
if ! [ -d "$NEWROOT/lib/modules/$kver/kernel" ]; then
|
||||
echo "Waiting for /dev/xvdd device..."
|
||||
while ! [ -e /dev/xvdd ]; do sleep 0.1; done
|
||||
|
||||
# Mount only `uname -r` subdirectory, to leave the rest of /lib/modules writable
|
||||
mkdir -p /tmp/modules
|
||||
mount -n -t ext3 /dev/xvdd /tmp/modules
|
||||
if ! [ -d "$NEWROOT/lib/modules/$kver" ]; then
|
||||
mount "$NEWROOT" -o remount,rw
|
||||
mkdir -p "$NEWROOT/lib/modules/$kver"
|
||||
mount "$NEWROOT" -o remount,ro
|
||||
fi
|
||||
mount --bind "/tmp/modules/$kver" "$NEWROOT/lib/modules/$kver"
|
||||
umount /tmp/modules
|
||||
rmdir /tmp/modules
|
||||
fi
|
||||
|
||||
killall udevd systemd-udevd
|
@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
check() {
|
||||
if xenstore-read qubes-vm-type &>/dev/null; then
|
||||
return 0
|
||||
else
|
||||
return 255
|
||||
fi
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_hook pre-udev 90 $moddir/qubes_cow_setup.sh
|
||||
inst_hook pre-pivot 50 $moddir/mount_modules.sh
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#
|
||||
# This file should be places in pre-pivot directory in dracut's initramfs
|
||||
#
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
if ! [ -d $NEWROOT/lib/modules/`uname -r` ]; then
|
||||
echo "Waiting for /dev/xvdd device..."
|
||||
while ! [ -e /dev/xvdd ]; do sleep 0.1; done
|
||||
|
||||
mount -n -t ext3 /dev/xvdd $NEWROOT/lib/modules
|
||||
fi
|
||||
|
||||
killall udevd systemd-udevd
|
@ -1,32 +0,0 @@
|
||||
#
|
||||
# This file should be places in pre-mount directory in dracut's initramfs
|
||||
#
|
||||
|
||||
#!/bin/sh
|
||||
echo "Qubes initramfs script here:"
|
||||
|
||||
if [ -e /dev/mapper/dmroot ] ; then
|
||||
die "Qubes: FATAL error: /dev/mapper/dmroot already exists?!"
|
||||
fi
|
||||
|
||||
modprobe xenblk || modprobe xen-blkfront || echo "Qubes: Cannot load Xen Block Frontend..."
|
||||
|
||||
echo "Waiting for /dev/xvda* devices..."
|
||||
while ! [ -e /dev/xvda ]; do sleep 0.1; done
|
||||
|
||||
if [ `cat /sys/block/xvda/ro` = 1 ] ; then
|
||||
echo "Qubes: Doing COW setup for AppVM..."
|
||||
|
||||
while ! [ -e /dev/xvdc ]; do sleep 0.1; done
|
||||
while ! [ -e /dev/xvdc2 ]; do sleep 0.1; done
|
||||
|
||||
echo "0 `cat /sys/block/xvda/size` snapshot /dev/xvda /dev/xvdc2 N 16" | \
|
||||
dmsetup create dmroot || { echo "Qubes: FATAL: cannot create dmroot!"; }
|
||||
echo Qubes: done.
|
||||
else
|
||||
echo "Qubes: Doing R/W setup for TemplateVM..."
|
||||
echo "0 `cat /sys/block/xvda/size` linear /dev/xvda 0" | \
|
||||
dmsetup create dmroot || { echo "Qubes: FATAL: cannot create dmroot!"; exit 1; }
|
||||
echo Qubes: done.
|
||||
fi
|
||||
dmsetup mknodes dmroot
|
@ -0,0 +1,4 @@
|
||||
install:
|
||||
install -d $(DESTDIR)/usr/lib/dracut/modules.d/80xen-scrub-pages
|
||||
install module-setup.sh scrub_pages.sh \
|
||||
$(DESTDIR)/usr/lib/dracut/modules.d/80xen-scrub-pages/
|
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
check() {
|
||||
if [ -r /usr/share/qubes/marker-vm ]; then
|
||||
return 0
|
||||
else
|
||||
return 255
|
||||
fi
|
||||
}
|
||||
|
||||
depends() {
|
||||
return 0
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_hook pre-trigger 60 $moddir/scrub_pages.sh
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This file should be placed in pre-trigger directory in dracut's initramfs, or
|
||||
# scripts/local-top in case of initramfs-tools
|
||||
#
|
||||
|
||||
# initramfs-tools (Debian) API
|
||||
PREREQS=""
|
||||
case "$1" in
|
||||
prereqs)
|
||||
# This runs during initramfs creation
|
||||
echo "$PREREQS"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -w /sys/devices/system/xen_memory/xen_memory0/scrub_pages ]; then
|
||||
# re-enable xen-balloon pages scrubbing, after initial balloon down
|
||||
echo 1 > /sys/devices/system/xen_memory/xen_memory0/scrub_pages
|
||||
fi
|
@ -0,0 +1,7 @@
|
||||
install-fedora:
|
||||
install -D -m 0644 grub.qubes-kernel-vm-support \
|
||||
$(DESTDIR)/etc/default/grub.qubes-kernel-vm-support
|
||||
|
||||
install-debian:
|
||||
install -D -m 0644 grub.qubes-kernel-vm-support \
|
||||
$(DESTDIR)/etc/default/grub.d/30-qubes-kernel-vm-support.cfg
|
@ -0,0 +1,8 @@
|
||||
# add kernel options only in VM, and only if initramfs is updated already
|
||||
# /var/lib/qubes/initramfs-updated contains "milestone" initramfs update version:
|
||||
# 1 - addition of xen scrub_pages enabling code
|
||||
if [ -r /usr/share/qubes/marker-vm ] &&
|
||||
[ "$(cat /var/lib/qubes/initramfs-updated 2>/dev/null || echo 0)" -ge 1 ]; then
|
||||
GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX xen_scrub_pages=0"
|
||||
fi
|
||||
GRUB_ENABLE_BLSCFG=false
|
@ -0,0 +1,18 @@
|
||||
PYTHON ?= python
|
||||
|
||||
all:
|
||||
$(PYTHON) setup.py build
|
||||
.PHONY: all
|
||||
|
||||
clean:
|
||||
$(PYTHON) setup.py clean
|
||||
.PHONY: clean
|
||||
|
||||
install:
|
||||
$(PYTHON) setup.py install -O1 $(PYTHON_PREFIX_ARG) --root $(DESTDIR)
|
||||
#ifeq (1,${DEBIANBUILD})
|
||||
# cp *.py $(DESTDIR)/$(PYTHON_SITEARCH)/qubes/
|
||||
#else
|
||||
# cp *.py* $(DESTDIR)/$(PYTHON_SITEARCH)/qubes/
|
||||
#endif
|
||||
.PHONY: install
|
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
'''Qubes Image Generation
|
||||
|
||||
Toolkit for generating icons and images for Qubes OS.'''
|
||||
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2013-2015 Wojtek Porczyk <woju@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
__all__ = ['make_padlock']
|
||||
|
||||
import math
|
||||
import cairo
|
||||
|
||||
import qubesimgconverter
|
||||
|
||||
def polar(r, a):
|
||||
return r * math.cos(a), r * math.sin(a)
|
||||
|
||||
def make_padlock(dst, colour, size=qubesimgconverter.ICON_MAXSIZE, disp=False):
|
||||
cs = cairo.ImageSurface(cairo.FORMAT_ARGB32, size, size)
|
||||
|
||||
cr = cairo.Context(cs)
|
||||
cr.set_source_rgb(*[c / 256.0
|
||||
for c in qubesimgconverter.hex_to_int(colour)])
|
||||
cr.set_line_width(.125 * size)
|
||||
|
||||
cr.rectangle(.125 * size, .5 * size, .75 * size, .4375 * size)
|
||||
cr.fill()
|
||||
|
||||
cr.move_to(.25 * size, .5 * size)
|
||||
cr.line_to(.25 * size, .375 * size)
|
||||
cr.arc(.5 * size, .375 * size, .25 * size, math.pi, 2 * math.pi)
|
||||
cr.move_to(.75 * size, .375 * size) # this is unneccessary, but helps readability
|
||||
cr.line_to(.75 * size, .5 * size)
|
||||
cr.stroke()
|
||||
|
||||
if disp:
|
||||
# Careful with those. I have run into severe
|
||||
# floating point errors when adjusting.
|
||||
arrows = 2
|
||||
gap = 45 * math.pi / 180
|
||||
offset = 0
|
||||
radius = .1875 * size
|
||||
width = 0.05 * size
|
||||
cx = .5 * size
|
||||
# cy = .6875 * size
|
||||
cy = .625 * size
|
||||
|
||||
arrow = 2 * math.pi / arrows
|
||||
|
||||
for i in range(arrows):
|
||||
cr.move_to(cx, cy)
|
||||
cr.rel_move_to(*polar( radius - width, offset + i * arrow))
|
||||
cr.arc(cx, cy, radius - width, offset + i * arrow, offset + (i + 1) * arrow - gap)
|
||||
cr.rel_line_to(*polar( width, offset + (i + 1) * arrow - gap + math.pi))
|
||||
cr.rel_line_to(*polar( width * math.sqrt(8), offset + (i + 1) * arrow - gap + math.pi / 4))
|
||||
cr.rel_line_to(*polar( width * math.sqrt(8), offset + (i + 1) * arrow - gap - math.pi / 4))
|
||||
cr.rel_line_to(*polar( width, offset + (i + 1) * arrow - gap + math.pi))
|
||||
cr.arc_negative(cx, cy, radius + width, offset + (i + 1) * arrow - gap, offset + i * arrow)
|
||||
cr.close_path()
|
||||
|
||||
cr.set_source_rgb(0xcc / 256.0, 0, 0) # tango's red
|
||||
cr.set_line_width(.0500 * size)
|
||||
cr.set_line_join(cairo.LINE_JOIN_ROUND)
|
||||
cr.stroke_preserve()
|
||||
|
||||
cr.set_source_rgb(1.0, 1.0, 1.0)
|
||||
cr.fill()
|
||||
|
||||
cs.write_to_png(dst)
|
||||
|
||||
# vim: ft=python sw=4 ts=4 et
|
@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
try:
|
||||
from io import BytesIO
|
||||
except ImportError:
|
||||
from cStringIO import StringIO as BytesIO
|
||||
import unittest
|
||||
|
||||
import qubesimgconverter
|
||||
|
||||
class TestCaseImage(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.rgba = \
|
||||
b'\x00\x00\x00\xff' b'\xff\x00\x00\xff' \
|
||||
b'\x00\xff\x00\xff' b'\x00\x00\x00\xff'
|
||||
self.size = (2, 2)
|
||||
|
||||
self.image = qubesimgconverter.Image(rgba=self.rgba, size=self.size)
|
||||
|
||||
def test_00_init(self):
|
||||
self.assertEqual(self.image._rgba, self.rgba)
|
||||
self.assertEqual(self.image._size, self.size)
|
||||
|
||||
def test_01_tint(self):
|
||||
image = self.image.tint('#0000ff')
|
||||
|
||||
self.assertEqual(image._rgba,
|
||||
b'\x00\x00\x3f\xff' b'\x00\x00\xff\xff'
|
||||
b'\x00\x00\xff\xff' b'\x00\x00\x3f\xff')
|
||||
|
||||
def test_10_get_from_stream(self):
|
||||
io = BytesIO('{0[0]} {0[1]}\n'.format(self.size).encode() + self.rgba)
|
||||
|
||||
image = qubesimgconverter.Image.get_from_stream(io)
|
||||
|
||||
self.assertEqual(image._rgba, self.rgba)
|
||||
self.assertEqual(image._size, self.size)
|
||||
|
||||
def test_11_get_from_stream_malformed(self):
|
||||
io = BytesIO('{0[0]} {0[1]}\n'.format(self.size).encode() +
|
||||
self.rgba[:-1]) # one byte too short
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
image = qubesimgconverter.Image.get_from_stream(io)
|
||||
|
||||
def test_12_get_from_stream_too_big(self):
|
||||
io = BytesIO('{0[0]} {0[1]}\n'.format(self.size).encode() + self.rgba) # 2x2
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
image = qubesimgconverter.Image.get_from_stream(io, max_width=1)
|
||||
|
||||
io.seek(0)
|
||||
with self.assertRaises(Exception):
|
||||
image = qubesimgconverter.Image.get_from_stream(io, max_height=1)
|
||||
|
||||
class TestCaseFunctionsAndConstants(unittest.TestCase):
|
||||
def test_00_imghdrlen(self):
|
||||
self.assertEqual(qubesimgconverter.imghdrlen(8, 15), len('8 15\n'))
|
||||
self.assertEqual(qubesimgconverter.imghdrlen(100, 100), len('100 100\n'))
|
||||
|
||||
def test_01_re_imghdr(self):
|
||||
self.assertTrue(qubesimgconverter.re_imghdr.match(b'8 15\n'))
|
||||
self.assertIsNone(qubesimgconverter.re_imghdr.match(b'8 15'))
|
||||
self.assertIsNone(qubesimgconverter.re_imghdr.match(b'815\n'))
|
||||
self.assertIsNone(qubesimgconverter.re_imghdr.match(b'x yx\n'))
|
||||
|
||||
def test_10_hex_to_float_result_00(self):
|
||||
self.assertEqual(qubesimgconverter.hex_to_int('#000000'), (0, 0, 0))
|
||||
|
||||
def test_11_hex_to_float_result_ff(self):
|
||||
self.assertEqual(qubesimgconverter.hex_to_int('0xffffff'),
|
||||
(0xff, 0xff, 0xff))
|
||||
|
||||
def test_12_hex_to_float_depth_3_not_implemented(self):
|
||||
with self.assertRaises(ValueError):
|
||||
qubesimgconverter.hex_to_int('123456', depth=3)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -0,0 +1,99 @@
|
||||
# vim: fileencoding=utf-8
|
||||
|
||||
#
|
||||
# The Qubes OS Project, https://www.qubes-os.org/
|
||||
#
|
||||
# Copyright (C) 2017
|
||||
# Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import itertools
|
||||
import qubes.tests.extra
|
||||
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
class TC_00_ImgConverter(qubes.tests.extra.ExtraTestCase):
|
||||
def setUp(self):
|
||||
super(TC_00_ImgConverter, self).setUp()
|
||||
# noinspection PyAttributeOutsideInit
|
||||
self.vm = self.create_vms(["vm"])[0]
|
||||
self.vm.start()
|
||||
|
||||
self.image_size = 16
|
||||
# RGB data for the image
|
||||
self.image_data = [
|
||||
(0xff // self.image_size * x, 0x80, 0xff // self.image_size * y,
|
||||
0xff)
|
||||
for x in range(self.image_size)
|
||||
for y in range(self.image_size)]
|
||||
|
||||
def create_img(self, filename):
|
||||
'''Create image file with given sample content
|
||||
|
||||
:param filename: output filename
|
||||
'''
|
||||
p = self.vm.run(
|
||||
'convert -size {}x{} -depth 8 rgba:- "{}" 2>&1'.format(
|
||||
self.image_size, self.image_size, filename),
|
||||
passio_popen=True)
|
||||
bytes_data = bytes(bytearray(itertools.chain(*self.image_data)))
|
||||
(stdout, _) = p.communicate(bytes_data)
|
||||
if p.returncode != 0:
|
||||
self.skipTest('failed to create test image: {}'.format(stdout))
|
||||
|
||||
def assertCorrectlyTransformed(self, orig_filename, trusted_filename):
|
||||
self.assertEquals(
|
||||
self.vm.run('test -r "{}"'.format(trusted_filename), wait=True), 0)
|
||||
self.assertEquals(
|
||||
self.vm.run('test -r "{}"'.format(orig_filename), wait=True), 0)
|
||||
# retrieve original image too, to compensate for compression
|
||||
p = self.vm.run('convert "{}" rgb:-'.format(orig_filename),
|
||||
passio_popen=True)
|
||||
orig_image_data, _ = p.communicate()
|
||||
p = self.vm.run('convert "{}" rgb:-'.format(trusted_filename),
|
||||
passio_popen=True)
|
||||
trusted_image_data, _ = p.communicate()
|
||||
self.assertEquals(orig_image_data, trusted_image_data)
|
||||
|
||||
def test_000_png(self):
|
||||
self.create_img('test.png')
|
||||
p = self.vm.run('qvm-convert-img test.png trusted.png 2>&1',
|
||||
passio_popen=True)
|
||||
(stdout, _) = p.communicate()
|
||||
if p.returncode == 127:
|
||||
self.skipTest('qubes-img-converter not installed')
|
||||
self.assertEquals(p.returncode, 0, 'qvm-convert-img failed: {}'.format(
|
||||
stdout))
|
||||
self.assertCorrectlyTransformed('test.png', 'trusted.png')
|
||||
|
||||
def test_010_filename_with_spaces(self):
|
||||
self.create_img('test with spaces.png')
|
||||
p = self.vm.run('qvm-convert-img "test with spaces.png" '
|
||||
'"trusted with spaces.png" 2>&1',
|
||||
passio_popen=True)
|
||||
(stdout, _) = p.communicate()
|
||||
if p.returncode == 127:
|
||||
self.skipTest('qubes-img-converter not installed')
|
||||
self.assertEquals(p.returncode, 0, 'qvm-convert-img failed: {}'.format(
|
||||
stdout))
|
||||
self.assertCorrectlyTransformed(
|
||||
'test with spaces.png', 'trusted with spaces.png')
|
||||
|
||||
|
||||
def list_tests():
|
||||
tests = [TC_00_ImgConverter]
|
||||
return tests
|
@ -0,0 +1,19 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
name='qubesimgconverter',
|
||||
version=open('../version').read().strip(),
|
||||
author='Invisible Things Lab',
|
||||
author_email='woju@invisiblethingslab.com',
|
||||
description='Toolkit for secure transfer and conversion of images between Qubes VMs.',
|
||||
license='GPL2+',
|
||||
url='https://www.qubes-os.org/',
|
||||
packages=['qubesimgconverter'],
|
||||
entry_points={
|
||||
'qubes.tests.extra.for_template':
|
||||
'qubesimgconverter = qubesimgconverter.test_integ:list_tests',
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
# vim: ts=4 sts=4 sw=4 et
|
@ -0,0 +1,8 @@
|
||||
install:
|
||||
install -D local-top/qubes_cow_setup.sh \
|
||||
$(DESTDIR)/usr/share/initramfs-tools/scripts/local-top/qubes_cow_setup
|
||||
install -D local-top/scrub_pages.sh \
|
||||
$(DESTDIR)/usr/share/initramfs-tools/scripts/local-top/scrub_pages
|
||||
install -D qubes_vm \
|
||||
$(DESTDIR)/usr/share/initramfs-tools/hooks/qubes_vm
|
||||
|
@ -0,0 +1 @@
|
||||
../../dracut/full-dmroot/qubes_cow_setup.sh
|
@ -0,0 +1 @@
|
||||
../../dracut/xen-balloon-scrub-pages/scrub_pages.sh
|
@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
if grep -q '^[0-]*$' /sys/hypervisor/uuid; then
|
||||
echo "Not intended for dom0"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PREREQS="dmsetup"
|
||||
case "$1" in
|
||||
prereqs)
|
||||
echo "$PREREQS"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
|
||||
copy_exec /sbin/sfdisk
|
||||
copy_exec /sbin/mkswap
|
||||
force_load xen-blkfront
|
||||
force_load dm-snapshot
|
@ -1,28 +0,0 @@
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
obj-m += u2mfn.o
|
||||
|
||||
clean:
|
||||
rm -f *.o *.ko *~
|
||||
rm -f .u2mfn.* *.mod.c Module.symvers modules.order
|
||||
rm -fr .tmp_versions
|
||||
rm -f Makefile.xen
|
@ -1,7 +0,0 @@
|
||||
PACKAGE_VERSION="@@VERSION@@"
|
||||
|
||||
# Items below here should not have to change with each driver version
|
||||
PACKAGE_NAME="u2mfn"
|
||||
|
||||
BUILT_MODULE_NAME[0]="u2mfn"
|
||||
DEST_MODULE_LOCATION[0]="/extra/"
|
@ -1,172 +0,0 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#ifndef FOREIGN_FRAME_BIT
|
||||
#include <xen/page.h>
|
||||
#endif
|
||||
#include <linux/highmem.h>
|
||||
|
||||
/* copy of /usr/include/u2mfn-kernel.h, to reduce requirements */
|
||||
#include <linux/ioctl.h>
|
||||
#define U2MFN_MAGIC 0xf5
|
||||
#define U2MFN_GET_MFN_FOR_PAGE _IOW(U2MFN_MAGIC, 1, int)
|
||||
#define U2MFN_GET_LAST_MFN _IO(U2MFN_MAGIC, 2)
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
|
||||
static inline unsigned long virt_to_phys(volatile void *address)
|
||||
{
|
||||
return __pa((unsigned long) address);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef virt_to_mfn
|
||||
#define VIRT_TO_MFN virt_to_mfn
|
||||
#else
|
||||
extern unsigned long *phys_to_machine_mapping;
|
||||
static inline unsigned long VIRT_TO_MFN(void *addr)
|
||||
{
|
||||
unsigned int pfn = virt_to_phys(addr) >> PAGE_SHIFT;
|
||||
return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// User virtual address to mfn translator
|
||||
/**
|
||||
\param cmd ignored
|
||||
\param data the user-specified address
|
||||
\return mfn corresponding to "data" argument, or -1 on error
|
||||
*/
|
||||
static long u2mfn_ioctl(struct file *f, unsigned int cmd,
|
||||
unsigned long data)
|
||||
{
|
||||
struct page *user_page;
|
||||
void *kaddr;
|
||||
int ret;
|
||||
|
||||
if (_IOC_TYPE(cmd) != U2MFN_MAGIC) {
|
||||
printk("Qubes u2mfn: wrong IOCTL magic");
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case U2MFN_GET_MFN_FOR_PAGE:
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
ret = get_user_pages
|
||||
(current, current->mm, data, 1, 1, 0, &user_page, 0);
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
if (ret != 1) {
|
||||
printk("U2MFN_GET_MFN_FOR_PAGE: get_user_pages failed, ret=0x%x\n", ret);
|
||||
return -1;
|
||||
}
|
||||
kaddr = kmap(user_page);
|
||||
ret = VIRT_TO_MFN(kaddr);
|
||||
kunmap(user_page);
|
||||
put_page(user_page);
|
||||
break;
|
||||
|
||||
case U2MFN_GET_LAST_MFN:
|
||||
if (f->private_data)
|
||||
ret = VIRT_TO_MFN(f->private_data);
|
||||
else
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("Qubes u2mfn: wrong ioctl passed!\n");
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int u2mfn_mmap(struct file *f, struct vm_area_struct *vma)
|
||||
{
|
||||
int ret;
|
||||
char *kbuf;
|
||||
long length = vma->vm_end - vma->vm_start;
|
||||
printk("u2mfn_mmap: entering, private=%p\n", f->private_data);
|
||||
if (f->private_data)
|
||||
return -EBUSY;
|
||||
if (length != PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
kbuf = (char *) __get_free_page(GFP_KERNEL);
|
||||
if (!kbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
f->private_data = kbuf;
|
||||
|
||||
ret = remap_pfn_range(vma, vma->vm_start,
|
||||
virt_to_phys(kbuf) >> PAGE_SHIFT,
|
||||
length, vma->vm_page_prot);
|
||||
|
||||
printk("u2mfn_mmap: calling remap return %d\n", ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int u2mfn_release(struct inode *i, struct file *f)
|
||||
{
|
||||
printk("u2mfn_release, priv=%p\n", f->private_data);
|
||||
if (f->private_data)
|
||||
__free_page(f->private_data);
|
||||
f->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations u2mfn_fops = {
|
||||
.unlocked_ioctl = u2mfn_ioctl,
|
||||
.mmap = u2mfn_mmap,
|
||||
.release = u2mfn_release
|
||||
};
|
||||
|
||||
/// u2mfn module registration
|
||||
/**
|
||||
tries to register "/proc/u2mfn" pseudofile
|
||||
*/
|
||||
static int u2mfn_init(void)
|
||||
{
|
||||
struct proc_dir_entry *u2mfn_node =
|
||||
proc_create_data("u2mfn", 0666, NULL,
|
||||
&u2mfn_fops, 0);
|
||||
if (!u2mfn_node)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void u2mfn_exit(void)
|
||||
{
|
||||
remove_proc_entry("u2mfn", 0);
|
||||
}
|
||||
|
||||
module_init(u2mfn_init);
|
||||
module_exit(u2mfn_exit);
|
||||
MODULE_LICENSE("GPL");
|
@ -1,115 +0,0 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libqrexec-utils.h"
|
||||
|
||||
#define BUFFER_LIMIT 50000000
|
||||
static int total_mem;
|
||||
static char *limited_malloc(int len)
|
||||
{
|
||||
char *ret;
|
||||
total_mem += len;
|
||||
if (total_mem > BUFFER_LIMIT) {
|
||||
fprintf(stderr, "attempt to allocate >BUFFER_LIMIT\n");
|
||||
exit(1);
|
||||
}
|
||||
ret = malloc(len);
|
||||
if (!ret) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void limited_free(char *ptr, int len)
|
||||
{
|
||||
free(ptr);
|
||||
total_mem -= len;
|
||||
}
|
||||
|
||||
void buffer_init(struct buffer *b)
|
||||
{
|
||||
b->buflen = 0;
|
||||
b->data = NULL;
|
||||
}
|
||||
|
||||
void buffer_free(struct buffer *b)
|
||||
{
|
||||
if (b->buflen)
|
||||
limited_free(b->data, b->buflen);
|
||||
buffer_init(b);
|
||||
}
|
||||
|
||||
/*
|
||||
The following two functions can be made much more efficient.
|
||||
Yet the profiling output show they are not significant CPU hogs, so
|
||||
we keep them so simple to make them obviously correct.
|
||||
*/
|
||||
|
||||
void buffer_append(struct buffer *b, const char *data, int len)
|
||||
{
|
||||
int newsize;
|
||||
char *qdata;
|
||||
if (len < 0 || len > BUFFER_LIMIT) {
|
||||
fprintf(stderr, "buffer_append %d\n", len);
|
||||
exit(1);
|
||||
}
|
||||
if (len == 0)
|
||||
return;
|
||||
newsize = len + b->buflen;
|
||||
qdata = limited_malloc(len + b->buflen);
|
||||
memcpy(qdata, b->data, b->buflen);
|
||||
memcpy(qdata + b->buflen, data, len);
|
||||
buffer_free(b);
|
||||
b->buflen = newsize;
|
||||
b->data = qdata;
|
||||
}
|
||||
|
||||
void buffer_remove(struct buffer *b, int len)
|
||||
{
|
||||
int newsize;
|
||||
char *qdata = NULL;
|
||||
if (len < 0 || len > b->buflen) {
|
||||
fprintf(stderr, "buffer_remove %d/%d\n", len, b->buflen);
|
||||
exit(1);
|
||||
}
|
||||
newsize = b->buflen - len;
|
||||
if (newsize > 0) {
|
||||
qdata = limited_malloc(newsize);
|
||||
memcpy(qdata, b->data + len, newsize);
|
||||
}
|
||||
buffer_free(b);
|
||||
b->buflen = newsize;
|
||||
b->data = qdata;
|
||||
}
|
||||
|
||||
int buffer_len(struct buffer *b)
|
||||
{
|
||||
return b->buflen;
|
||||
}
|
||||
|
||||
void *buffer_data(struct buffer *b)
|
||||
{
|
||||
return b->data;
|
||||
}
|
@ -1,49 +1,49 @@
|
||||
#include <unistd.h>
|
||||
#include <ioall.h>
|
||||
#include "ioall.h"
|
||||
#include "libqubes-rpc-filecopy.h"
|
||||
#include "crc32.h"
|
||||
|
||||
notify_progress_t *notify_progress_func = NULL;
|
||||
void register_notify_progress(notify_progress_t *func)
|
||||
{
|
||||
notify_progress_func = func;
|
||||
notify_progress_func = func;
|
||||
}
|
||||
|
||||
int copy_file(int outfd, int infd, long long size, unsigned long *crc32)
|
||||
{
|
||||
char buf[4096];
|
||||
long long written = 0;
|
||||
int ret;
|
||||
int count;
|
||||
while (written < size) {
|
||||
if (size - written > (int)sizeof(buf))
|
||||
count = sizeof buf;
|
||||
else
|
||||
count = size - written;
|
||||
ret = read(infd, buf, count);
|
||||
if (!ret)
|
||||
return COPY_FILE_READ_EOF;
|
||||
if (ret < 0)
|
||||
return COPY_FILE_READ_ERROR;
|
||||
/* acumulate crc32 if requested */
|
||||
if (crc32)
|
||||
*crc32 = Crc32_ComputeBuf(*crc32, buf, ret);
|
||||
if (!write_all(outfd, buf, ret))
|
||||
return COPY_FILE_WRITE_ERROR;
|
||||
if (notify_progress_func != NULL)
|
||||
notify_progress_func(ret, 0);
|
||||
written += ret;
|
||||
}
|
||||
return COPY_FILE_OK;
|
||||
char buf[4096];
|
||||
long long written = 0;
|
||||
int ret;
|
||||
int count;
|
||||
while (written < size) {
|
||||
if (size - written > (int)sizeof(buf))
|
||||
count = sizeof buf;
|
||||
else
|
||||
count = size - written;
|
||||
ret = read(infd, buf, count);
|
||||
if (!ret)
|
||||
return COPY_FILE_READ_EOF;
|
||||
if (ret < 0)
|
||||
return COPY_FILE_READ_ERROR;
|
||||
/* acumulate crc32 if requested */
|
||||
if (crc32)
|
||||
*crc32 = Crc32_ComputeBuf(*crc32, buf, ret);
|
||||
if (!write_all(outfd, buf, ret))
|
||||
return COPY_FILE_WRITE_ERROR;
|
||||
if (notify_progress_func != NULL)
|
||||
notify_progress_func(ret, 0);
|
||||
written += ret;
|
||||
}
|
||||
return COPY_FILE_OK;
|
||||
}
|
||||
|
||||
const char * copy_file_status_to_str(int status)
|
||||
{
|
||||
switch (status) {
|
||||
case COPY_FILE_OK: return "OK";
|
||||
case COPY_FILE_READ_EOF: return "Unexpected end of data while reading";
|
||||
case COPY_FILE_READ_ERROR: return "Error reading";
|
||||
case COPY_FILE_WRITE_ERROR: return "Error writing";
|
||||
default: return "????????";
|
||||
}
|
||||
switch (status) {
|
||||
case COPY_FILE_OK: return "OK";
|
||||
case COPY_FILE_READ_EOF: return "Unexpected end of data while reading";
|
||||
case COPY_FILE_READ_ERROR: return "Error reading";
|
||||
case COPY_FILE_WRITE_ERROR: return "Error writing";
|
||||
default: return "????????";
|
||||
}
|
||||
}
|
||||
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include "libqrexec-utils.h"
|
||||
|
||||
static do_exec_t *exec_func = NULL;
|
||||
void register_exec_func(do_exec_t *func) {
|
||||
exec_func = func;
|
||||
}
|
||||
|
||||
void fix_fds(int fdin, int fdout, int fderr)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (i != fdin && i != fdout && i != fderr)
|
||||
close(i);
|
||||
dup2(fdin, 0);
|
||||
dup2(fdout, 1);
|
||||
dup2(fderr, 2);
|
||||
close(fdin);
|
||||
close(fdout);
|
||||
if (fderr != 2)
|
||||
close(fderr);
|
||||
}
|
||||
|
||||
void do_fork_exec(const char *cmdline, int *pid, int *stdin_fd, int *stdout_fd,
|
||||
int *stderr_fd)
|
||||
{
|
||||
int inpipe[2], outpipe[2], errpipe[2];
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inpipe) ||
|
||||
socketpair(AF_UNIX, SOCK_STREAM, 0, outpipe) ||
|
||||
(stderr_fd && socketpair(AF_UNIX, SOCK_STREAM, 0, errpipe))) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
switch (*pid = fork()) {
|
||||
case -1:
|
||||
perror("fork");
|
||||
exit(-1);
|
||||
case 0:
|
||||
if (stderr_fd) {
|
||||
fix_fds(inpipe[0], outpipe[1], errpipe[1]);
|
||||
} else
|
||||
fix_fds(inpipe[0], outpipe[1], 2);
|
||||
|
||||
if (exec_func != NULL)
|
||||
exec_func(cmdline);
|
||||
exit(-1);
|
||||
default:;
|
||||
}
|
||||
close(inpipe[0]);
|
||||
close(outpipe[1]);
|
||||
*stdin_fd = inpipe[1];
|
||||
*stdout_fd = outpipe[0];
|
||||
if (stderr_fd) {
|
||||
close(errpipe[1]);
|
||||
*stderr_fd = errpipe[0];
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
* Copyright (C) 2013 Marek Marczykowski <marmarek@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <libvchan.h>
|
||||
|
||||
struct buffer {
|
||||
char *data;
|
||||
int buflen;
|
||||
};
|
||||
|
||||
typedef void (do_exec_t)(const char *);
|
||||
void register_exec_func(do_exec_t *func);
|
||||
|
||||
void buffer_init(struct buffer *b);
|
||||
void buffer_free(struct buffer *b);
|
||||
void buffer_append(struct buffer *b, const char *data, int len);
|
||||
void buffer_remove(struct buffer *b, int len);
|
||||
int buffer_len(struct buffer *b);
|
||||
void *buffer_data(struct buffer *b);
|
||||
|
||||
|
||||
void do_fork_exec(const char *cmdline, int *pid, int *stdin_fd, int *stdout_fd,
|
||||
int *stderr_fd);
|
||||
void wait_for_vchan_or_argfd(libvchan_t *vchan, int max, fd_set * rdset, fd_set * wrset);
|
||||
int read_vchan_all(libvchan_t *vchan, void *data, size_t size);
|
||||
int write_vchan_all(libvchan_t *vchan, const void *data, size_t size);
|
||||
int read_all(int fd, void *buf, int size);
|
||||
int write_all(int fd, const void *buf, int size);
|
||||
void fix_fds(int fdin, int fdout, int fderr);
|
||||
void set_nonblock(int fd);
|
||||
void set_block(int fd);
|
||||
|
||||
int get_server_socket(const char *);
|
||||
int do_accept(int s);
|
||||
|
||||
void set_nonblock(int fd);
|
@ -0,0 +1,229 @@
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include "libqubes-rpc-filecopy.h"
|
||||
|
||||
static unsigned long crc32_sum;
|
||||
static int ignore_quota_error = 0;
|
||||
error_handler_t *error_handler = NULL;
|
||||
|
||||
void register_error_handler(error_handler_t *value) {
|
||||
error_handler = value;
|
||||
}
|
||||
|
||||
_Noreturn static void call_error_handler(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
if (error_handler) {
|
||||
error_handler(fmt, args);
|
||||
} else {
|
||||
vfprintf(stderr, fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int write_all_with_crc(int fd, const void *buf, int size)
|
||||
{
|
||||
crc32_sum = Crc32_ComputeBuf(crc32_sum, buf, size);
|
||||
return write_all(fd, buf, size);
|
||||
}
|
||||
|
||||
void notify_end_and_wait_for_result(void)
|
||||
{
|
||||
struct file_header end_hdr;
|
||||
|
||||
/* nofity end of transfer */
|
||||
memset(&end_hdr, 0, sizeof(end_hdr));
|
||||
end_hdr.namelen = 0;
|
||||
end_hdr.filelen = 0;
|
||||
write_all_with_crc(1, &end_hdr, sizeof(end_hdr));
|
||||
|
||||
set_block(0);
|
||||
wait_for_result();
|
||||
}
|
||||
|
||||
void wait_for_result(void)
|
||||
{
|
||||
struct result_header hdr;
|
||||
struct result_header_ext hdr_ext;
|
||||
char last_filename[MAX_PATH_LENGTH + 1];
|
||||
char last_filename_prefix[] = "; Last file: ";
|
||||
|
||||
if (!read_all(0, &hdr, sizeof(hdr))) {
|
||||
if (errno == EAGAIN) {
|
||||
// no result sent and stdin still open
|
||||
return;
|
||||
} else {
|
||||
// other read error or EOF
|
||||
exit(1); // hopefully remote has produced error message
|
||||
}
|
||||
}
|
||||
if (!read_all(0, &hdr_ext, sizeof(hdr_ext))) {
|
||||
// remote used old result_header struct
|
||||
hdr_ext.last_namelen = 0;
|
||||
}
|
||||
if (hdr_ext.last_namelen > MAX_PATH_LENGTH) {
|
||||
// read only at most MAX_PATH_LENGTH chars
|
||||
hdr_ext.last_namelen = MAX_PATH_LENGTH;
|
||||
}
|
||||
if (!read_all(0, last_filename, hdr_ext.last_namelen)) {
|
||||
fprintf(stderr, "Failed to get last filename\n");
|
||||
hdr_ext.last_namelen = 0;
|
||||
}
|
||||
last_filename[hdr_ext.last_namelen] = '\0';
|
||||
if (!hdr_ext.last_namelen)
|
||||
/* set prefix to empty string */
|
||||
last_filename_prefix[0] = '\0';
|
||||
|
||||
errno = hdr.error_code;
|
||||
if (hdr.error_code != 0) {
|
||||
switch (hdr.error_code) {
|
||||
case EEXIST:
|
||||
call_error_handler("A file named %s already exists in QubesIncoming dir", last_filename);
|
||||
break;
|
||||
case EINVAL:
|
||||
call_error_handler("File copy: Corrupted data from packer%s%s", last_filename_prefix, last_filename);
|
||||
break;
|
||||
case EDQUOT:
|
||||
if (ignore_quota_error) {
|
||||
/* skip also CRC check as sender and receiver might be
|
||||
* desynchronized in this case */
|
||||
return;
|
||||
}
|
||||
/* fallthrough */
|
||||
default:
|
||||
call_error_handler("File copy: %s%s%s",
|
||||
strerror(hdr.error_code), last_filename_prefix, last_filename);
|
||||
}
|
||||
}
|
||||
if (hdr.crc32 != crc32_sum) {
|
||||
call_error_handler("File transfer failed: checksum mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
void write_headers(const struct file_header *hdr, const char *filename)
|
||||
{
|
||||
if (!write_all_with_crc(1, hdr, sizeof(*hdr))
|
||||
|| !write_all_with_crc(1, filename, hdr->namelen)) {
|
||||
set_block(0);
|
||||
wait_for_result();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int copy_file_with_crc(int outfd, int infd, long long size) {
|
||||
return copy_file(outfd, infd, size, &crc32_sum);
|
||||
}
|
||||
|
||||
int single_file_processor(const char *filename, const struct stat *st)
|
||||
{
|
||||
struct file_header hdr;
|
||||
int fd;
|
||||
mode_t mode = st->st_mode;
|
||||
|
||||
hdr.namelen = strlen(filename) + 1;
|
||||
hdr.mode = mode;
|
||||
hdr.atime = st->st_atim.tv_sec;
|
||||
hdr.atime_nsec = st->st_atim.tv_nsec;
|
||||
hdr.mtime = st->st_mtim.tv_sec;
|
||||
hdr.mtime_nsec = st->st_mtim.tv_nsec;
|
||||
|
||||
if (S_ISREG(mode)) {
|
||||
int ret;
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
call_error_handler("open %s", filename);
|
||||
hdr.filelen = st->st_size;
|
||||
write_headers(&hdr, filename);
|
||||
ret = copy_file(1, fd, hdr.filelen, &crc32_sum);
|
||||
if (ret != COPY_FILE_OK) {
|
||||
if (ret != COPY_FILE_WRITE_ERROR)
|
||||
call_error_handler("Copying file %s: %s", filename,
|
||||
copy_file_status_to_str(ret));
|
||||
else {
|
||||
set_block(0);
|
||||
wait_for_result();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
if (S_ISDIR(mode)) {
|
||||
hdr.filelen = 0;
|
||||
write_headers(&hdr, filename);
|
||||
}
|
||||
if (S_ISLNK(mode)) {
|
||||
char name[st->st_size + 1];
|
||||
if (readlink(filename, name, sizeof(name)) != st->st_size)
|
||||
call_error_handler("readlink %s", filename);
|
||||
hdr.filelen = st->st_size;
|
||||
write_headers(&hdr, filename);
|
||||
if (!write_all_with_crc(1, name, st->st_size)) {
|
||||
set_block(0);
|
||||
wait_for_result();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
// check for possible error from qfile-unpacker
|
||||
wait_for_result();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_fs_walk(const char *file, int ignore_symlinks)
|
||||
{
|
||||
char *newfile;
|
||||
struct stat st;
|
||||
struct dirent *ent;
|
||||
DIR *dir;
|
||||
|
||||
if (lstat(file, &st))
|
||||
call_error_handler("stat %s", file);
|
||||
if (S_ISLNK(st.st_mode) && ignore_symlinks)
|
||||
return 0;
|
||||
single_file_processor(file, &st);
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
return 0;
|
||||
dir = opendir(file);
|
||||
if (!dir)
|
||||
call_error_handler("opendir %s", file);
|
||||
while ((ent = readdir(dir))) {
|
||||
char *fname = ent->d_name;
|
||||
if (!strcmp(fname, ".") || !strcmp(fname, ".."))
|
||||
continue;
|
||||
if (asprintf(&newfile, "%s/%s", file, fname) >= 0) {
|
||||
do_fs_walk(newfile, ignore_symlinks);
|
||||
free(newfile);
|
||||
} else {
|
||||
fprintf(stderr, "asprintf failed\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
// directory metadata is resent; this makes the code simple,
|
||||
// and the atime/mtime is set correctly at the second time
|
||||
single_file_processor(file, &st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qfile_pack_init(void) {
|
||||
crc32_sum = 0;
|
||||
ignore_quota_error = 0;
|
||||
// this will allow checking for possible feedback packet in the middle of transfer
|
||||
set_nonblock(0);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
error_handler = NULL;
|
||||
}
|
||||
|
||||
void set_ignore_quota_error(int value) {
|
||||
ignore_quota_error = value;
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* See also http://wiki.qubes-os.org/trac/wiki/Qrexec */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define QREXEC_PROTOCOL_VERSION 2
|
||||
#define MAX_FDS 256
|
||||
#define MAX_DATA_CHUNK 4096
|
||||
|
||||
#define RPC_REQUEST_COMMAND "QUBESRPC"
|
||||
#define VCHAN_BASE_PORT 512
|
||||
#define MAX_DATA_CHUNK 4096
|
||||
|
||||
/* Messages sent over control vchan between daemon(dom0) and agent(vm).
|
||||
* The same are used between client(dom0) and daemon(dom0).
|
||||
*/
|
||||
enum {
|
||||
/* daemon->agent messages */
|
||||
|
||||
/* start process in VM and pass its stdin/out/err to dom0
|
||||
* struct exec_params passed as data */
|
||||
MSG_EXEC_CMDLINE = 0x200,
|
||||
|
||||
/* start process in VM discarding its stdin/out/err (connect to /dev/null)
|
||||
* struct exec_params passed as data */
|
||||
MSG_JUST_EXEC,
|
||||
|
||||
/* connect to existing process in VM to receive its stdin/out/err
|
||||
* struct service_params passed as cmdline field in exec_params */
|
||||
MSG_SERVICE_CONNECT,
|
||||
|
||||
/* refuse to start a service (denied by policy, invalid parameters etc)
|
||||
* struct service_params passed as data to identify which service call was
|
||||
* refused */
|
||||
MSG_SERVICE_REFUSED,
|
||||
|
||||
/* agent->daemon messages */
|
||||
/* call Qubes RPC service
|
||||
* struct trigger_service_params passed as data */
|
||||
MSG_TRIGGER_SERVICE = 0x210,
|
||||
|
||||
|
||||
/* connection was terminated, struct exec_params passed as data (with empty
|
||||
* cmdline field) informs about released vchan port */
|
||||
MSG_CONNECTION_TERMINATED,
|
||||
|
||||
/* common messages */
|
||||
/* initialize connection, struct peer_info passed as data
|
||||
* should be sent as the first message (server first, then client) */
|
||||
MSG_HELLO = 0x300,
|
||||
};
|
||||
|
||||
/* uniform for all peers, data type depends on message type */
|
||||
struct msg_header {
|
||||
uint32_t type; /* message type */
|
||||
uint32_t len; /* data length */
|
||||
};
|
||||
|
||||
/* variable size */
|
||||
struct exec_params {
|
||||
uint32_t connect_domain; /* target domain name */
|
||||
uint32_t connect_port; /* target vchan port for i/o exchange */
|
||||
char cmdline[0]; /* command line to execute, size = msg_header.len - sizeof(struct exec_params) */
|
||||
};
|
||||
|
||||
struct service_params {
|
||||
char ident[32];
|
||||
};
|
||||
|
||||
struct trigger_service_params {
|
||||
char service_name[64];
|
||||
char target_domain[32];
|
||||
struct service_params request_id; /* service request id */
|
||||
};
|
||||
|
||||
struct peer_info {
|
||||
uint32_t version; /* qrexec protocol version */
|
||||
};
|
||||
|
||||
/* data vchan client<->agent, separate for each VM process */
|
||||
enum {
|
||||
/* stdin dom0->VM */
|
||||
MSG_DATA_STDIN = 0x190,
|
||||
/* stdout VM->dom0 */
|
||||
MSG_DATA_STDOUT,
|
||||
/* stderr VM->dom0 */
|
||||
MSG_DATA_STDERR,
|
||||
/* VM process exit code VM->dom0 (int) */
|
||||
MSG_DATA_EXIT_CODE,
|
||||
};
|
||||
|
||||
// linux-specific stuff below
|
||||
|
||||
#define QREXEC_AGENT_TRIGGER_PATH "/var/run/qubes/qrexec-agent"
|
||||
#define QREXEC_AGENT_FDPASS_PATH "/var/run/qubes/qrexec-agent-fdpass"
|
||||
#define MEMINFO_WRITER_PIDFILE "/var/run/meminfo-writer.pid"
|
||||
#define QUBES_RPC_MULTIPLEXER_PATH "/usr/lib/qubes/qubes-rpc-multiplexer"
|
||||
#define QREXEC_DAEMON_SOCKET_DIR "/var/run/qubes"
|
||||
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <libvchan.h>
|
||||
|
||||
int wait_for_vchan_or_argfd_once(libvchan_t *ctrl, int max, fd_set * rdset, fd_set * wrset)
|
||||
{
|
||||
int vfd, ret;
|
||||
struct timespec tv = { 1, 100000000 };
|
||||
sigset_t empty_set;
|
||||
|
||||
sigemptyset(&empty_set);
|
||||
|
||||
vfd = libvchan_fd_for_select(ctrl);
|
||||
FD_SET(vfd, rdset);
|
||||
if (vfd > max)
|
||||
max = vfd;
|
||||
max++;
|
||||
ret = pselect(max, rdset, wrset, NULL, &tv, &empty_set);
|
||||
if (ret < 0) {
|
||||
if (errno != EINTR) {
|
||||
perror("select");
|
||||
exit(1);
|
||||
} else {
|
||||
FD_ZERO(rdset);
|
||||
FD_ZERO(wrset);
|
||||
fprintf(stderr, "eintr\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
if (!libvchan_is_open(ctrl)) {
|
||||
fprintf(stderr, "libvchan_is_eof\n");
|
||||
exit(0);
|
||||
}
|
||||
if (FD_ISSET(vfd, rdset))
|
||||
// the following will never block; we need to do this to
|
||||
// clear libvchan_fd pending state
|
||||
libvchan_wait(ctrl);
|
||||
if (libvchan_data_ready(ctrl))
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wait_for_vchan_or_argfd(libvchan_t *ctrl, int max, fd_set * rdset, fd_set * wrset)
|
||||
{
|
||||
fd_set r = *rdset, w = *wrset;
|
||||
do {
|
||||
*rdset = r;
|
||||
*wrset = w;
|
||||
}
|
||||
while (wait_for_vchan_or_argfd_once(ctrl, max, rdset, wrset) == 0);
|
||||
}
|
||||
|
||||
int write_vchan_all(libvchan_t *vchan, const void *data, size_t size) {
|
||||
size_t pos;
|
||||
int ret;
|
||||
|
||||
pos = 0;
|
||||
while (pos < size) {
|
||||
ret = libvchan_write(vchan, data+pos, size-pos);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
pos += ret;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read_vchan_all(libvchan_t *vchan, void *data, size_t size) {
|
||||
size_t pos;
|
||||
int ret;
|
||||
|
||||
pos = 0;
|
||||
while (pos < size) {
|
||||
ret = libvchan_read(vchan, data+pos, size-pos);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
pos += ret;
|
||||
}
|
||||
return 1;
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
//#include "qrexec.h"
|
||||
|
||||
int get_server_socket(const char *socket_address)
|
||||
{
|
||||
struct sockaddr_un sockname;
|
||||
int s;
|
||||
|
||||
unlink(socket_address);
|
||||
|
||||
s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
printf("socket() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
memset(&sockname, 0, sizeof(sockname));
|
||||
sockname.sun_family = AF_UNIX;
|
||||
strncpy(sockname.sun_path, socket_address, sizeof sockname.sun_path);
|
||||
sockname.sun_path[sizeof sockname.sun_path - 1] = 0;
|
||||
|
||||
if (bind(s, (struct sockaddr *) &sockname, sizeof(sockname)) == -1) {
|
||||
printf("bind() failed\n");
|
||||
close(s);
|
||||
exit(1);
|
||||
}
|
||||
// chmod(sockname.sun_path, 0666);
|
||||
if (listen(s, 5) == -1) {
|
||||
perror("listen() failed\n");
|
||||
close(s);
|
||||
exit(1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int do_accept(int s)
|
||||
{
|
||||
struct sockaddr_un peer;
|
||||
unsigned int addrlen;
|
||||
int fd;
|
||||
addrlen = sizeof(peer);
|
||||
fd = accept(s, (struct sockaddr *) &peer, &addrlen);
|
||||
if (fd == -1) {
|
||||
perror("unix accept");
|
||||
exit(1);
|
||||
}
|
||||
return fd;
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* The Qubes OS Project, http://www.qubes-os.org
|
||||
*
|
||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <libvchan.h>
|
||||
#include "qrexec.h"
|
||||
#include "libqrexec-utils.h"
|
||||
|
||||
/*
|
||||
There is buffered data in "buffer" for client id "client_id", and select()
|
||||
reports that "fd" is writable. Write as much as possible to fd, if all sent,
|
||||
notify the peer that this client's pipe is no longer full.
|
||||
*/
|
||||
int flush_client_data(libvchan_t *vchan, int fd, int client_id, struct buffer *buffer)
|
||||
{
|
||||
int ret;
|
||||
int len;
|
||||
for (;;) {
|
||||
len = buffer_len(buffer);
|
||||
if (len > MAX_DATA_CHUNK)
|
||||
len = MAX_DATA_CHUNK;
|
||||
ret = write(fd, buffer_data(buffer), len);
|
||||
if (ret == -1) {
|
||||
if (errno != EAGAIN) {
|
||||
return WRITE_STDIN_ERROR;
|
||||
} else
|
||||
return WRITE_STDIN_BUFFERED;
|
||||
}
|
||||
// we previously called buffer_remove(buffer, len)
|
||||
// it will be wrong if we change MAX_DATA_CHUNK to something large
|
||||
// as pipes writes are atomic only to PIPE_MAX limit
|
||||
buffer_remove(buffer, ret);
|
||||
len = buffer_len(buffer);
|
||||
if (!len) {
|
||||
struct server_header s_hdr;
|
||||
s_hdr.type = MSG_XON;
|
||||
s_hdr.client_id = client_id;
|
||||
s_hdr.len = 0;
|
||||
if (libvchan_send(vchan, (char*)&s_hdr, sizeof s_hdr) < 0)
|
||||
return WRITE_STDIN_ERROR;
|
||||
return WRITE_STDIN_OK;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Write "len" bytes from "data" to "fd". If not all written, buffer the rest
|
||||
to "buffer", and notify the peer that the client "client_id" pipe is full via
|
||||
MSG_XOFF message.
|
||||
*/
|
||||
int write_stdin(libvchan_t *vchan, int fd, int client_id, const char *data, int len,
|
||||
struct buffer *buffer)
|
||||
{
|
||||
int ret;
|
||||
int written = 0;
|
||||
|
||||
if (buffer_len(buffer)) {
|
||||
buffer_append(buffer, data, len);
|
||||
return WRITE_STDIN_BUFFERED;
|
||||
}
|
||||
while (written < len) {
|
||||
ret = write(fd, data + written, len - written);
|
||||
if (ret == 0) {
|
||||
perror("write_stdin: write returns 0 ???");
|
||||
exit(1);
|
||||
}
|
||||
if (ret == -1) {
|
||||
struct server_header s_hdr;
|
||||
|
||||
if (errno != EAGAIN)
|
||||
return WRITE_STDIN_ERROR;
|
||||
|
||||
buffer_append(buffer, data + written,
|
||||
len - written);
|
||||
|
||||
s_hdr.type = MSG_XOFF;
|
||||
s_hdr.client_id = client_id;
|
||||
s_hdr.len = 0;
|
||||
if (libvchan_send(vchan, (char*)&s_hdr, sizeof s_hdr) < 0)
|
||||
return WRITE_STDIN_ERROR;
|
||||
|
||||
return WRITE_STDIN_BUFFERED;
|
||||
}
|
||||
written += ret;
|
||||
}
|
||||
return WRITE_STDIN_OK;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Data feed process has exited, so we need to clear all control structures for
|
||||
the client. However, if we have buffered data for the client (which is rare btw),
|
||||
fire&forget a separate process to flush them.
|
||||
*/
|
||||
int fork_and_flush_stdin(int fd, struct buffer *buffer)
|
||||
{
|
||||
int i;
|
||||
if (!buffer_len(buffer))
|
||||
return 0;
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
perror("fork");
|
||||
exit(1);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < MAX_FDS; i++)
|
||||
if (i != fd && i != 2)
|
||||
close(i);
|
||||
set_block(fd);
|
||||
write_all(fd, buffer_data(buffer), buffer_len(buffer));
|
||||
_exit(0);
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
%define version %(cat version)
|
||||
%if 0%{?qubes_builder}
|
||||
%define _builddir %(pwd)
|
||||
%endif
|
||||
|
||||
%{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
|
||||
|
||||
Name: qubes-utils
|
||||
Version: %{version}
|
||||
Release: 1%{?dist}
|
||||
Summary: Common Linux files for Qubes Dom0 and VM
|
||||
|
||||
Group: Qubes
|
||||
License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
|
||||
Requires: udev
|
||||
Requires: %{name}-libs
|
||||
Requires: ImageMagick
|
||||
Requires: pycairo
|
||||
BuildRequires: qubes-libvchan-devel
|
||||
|
||||
%description
|
||||
Common Linux files for Qubes Dom0 and VM
|
||||
|
||||
%package devel
|
||||
Summary: Development headers for qubes-utils
|
||||
Release: 1%{?dist}
|
||||
Requires: %{name}-libs
|
||||
|
||||
%description devel
|
||||
Development header and files for qubes-utils
|
||||
|
||||
%package libs
|
||||
Summary: Qubes utils libraries
|
||||
Release: 1%{?dist}
|
||||
|
||||
%description libs
|
||||
Libraries for qubes-utils
|
||||
|
||||
%prep
|
||||
# we operate on the current directory, so no need to unpack anything
|
||||
# symlink is to generate useful debuginfo packages
|
||||
rm -f %{name}-%{version}
|
||||
ln -sf . %{name}-%{version}
|
||||
%setup -T -D
|
||||
|
||||
|
||||
%build
|
||||
make all
|
||||
|
||||
%install
|
||||
make install DESTDIR=%{buildroot}
|
||||
|
||||
%post
|
||||
# dom0
|
||||
/bin/systemctl enable qubes-meminfo-writer-dom0.service > /dev/null 2>&1
|
||||
# VM
|
||||
/bin/systemctl enable qubes-meminfo-writer.service > /dev/null 2>&1
|
||||
|
||||
%postun
|
||||
if [ $1 -eq 0 ]; then
|
||||
/bin/systemctl disable qubes-meminfo-writer.service > /dev/null 2>&1
|
||||
/bin/systemctl disable qubes-meminfo-writer.service > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
%post libs -p /sbin/ldconfig
|
||||
%postun libs -p /sbin/ldconfig
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
/etc/udev/rules.d/99-qubes-*.rules
|
||||
/usr/libexec/qubes/udev-*
|
||||
%{_sbindir}/meminfo-writer
|
||||
%{_unitdir}/qubes-meminfo-writer.service
|
||||
%{_unitdir}/qubes-meminfo-writer-dom0.service
|
||||
%{python_sitearch}/qubes/__init__.py
|
||||
%{python_sitearch}/qubes/__init__.pyc
|
||||
%{python_sitearch}/qubes/__init__.pyo
|
||||
%attr(0755,root,root) %{python_sitearch}/qubes/imgconverter.py
|
||||
%{python_sitearch}/qubes/imgconverter.pyc
|
||||
%{python_sitearch}/qubes/imgconverter.pyo
|
||||
|
||||
%files libs
|
||||
%{_libdir}/libqrexec-utils.so.1
|
||||
%{_libdir}/libqubes-rpc-filecopy.so.1
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
/usr/include/libqrexec-utils.h
|
||||
/usr/include/libqubes-rpc-filecopy.h
|
||||
/usr/include/qrexec.h
|
||||
%{_libdir}/libqrexec-utils.so
|
||||
%{_libdir}/libqubes-rpc-filecopy.so
|
||||
|
||||
%changelog
|
||||
|
@ -0,0 +1,132 @@
|
||||
Name: qubes-utils
|
||||
Version: @VERSION@
|
||||
Release: 1%{?dist}
|
||||
Summary: Common Linux files for Qubes Dom0 and VM
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
|
||||
Group: Qubes
|
||||
License: GPL
|
||||
URL: http://www.qubes-os.org
|
||||
|
||||
Requires: udev
|
||||
Requires: %{name}-libs
|
||||
Requires: ImageMagick
|
||||
Requires: python%{python3_pkgversion}-qubesimgconverter
|
||||
%{?systemd_requires}
|
||||
BuildRequires: systemd
|
||||
BuildRequires: python2-setuptools
|
||||
BuildRequires: python%{python3_pkgversion}-setuptools
|
||||
BuildRequires: python2-rpm-macros
|
||||
BuildRequires: python3-rpm-macros
|
||||
# for meminfo-writer
|
||||
BuildRequires: xen-devel
|
||||
BuildRequires: gcc
|
||||
|
||||
%description
|
||||
Common Linux files for Qubes Dom0 and VM
|
||||
|
||||
%package -n python2-qubesimgconverter
|
||||
Summary: Python package qubesimgconverter
|
||||
Requires: python2
|
||||
Requires: pycairo
|
||||
%if 0%{?rhel} >= 7
|
||||
Requires: python-pillow
|
||||
Requires: numpy
|
||||
%else
|
||||
Requires: python2-pillow
|
||||
Requires: python2-numpy
|
||||
%endif
|
||||
|
||||
%description -n python2-qubesimgconverter
|
||||
Python package qubesimgconverter
|
||||
|
||||
%package -n python%{python3_pkgversion}-qubesimgconverter
|
||||
Summary: Python package qubesimgconverter
|
||||
Requires: python%{python3_pkgversion}
|
||||
Requires: python%{python3_pkgversion}-cairo
|
||||
Requires: python%{python3_pkgversion}-pillow
|
||||
Requires: python%{python3_pkgversion}-numpy
|
||||
|
||||
%description -n python%{python3_pkgversion}-qubesimgconverter
|
||||
Python package qubesimgconverter
|
||||
|
||||
%package devel
|
||||
Summary: Development headers for qubes-utils
|
||||
Release: 1%{?dist}
|
||||
Requires: %{name}-libs
|
||||
|
||||
%description devel
|
||||
Development header and files for qubes-utils
|
||||
|
||||
%package libs
|
||||
Summary: Qubes utils libraries
|
||||
Release: 1%{?dist}
|
||||
|
||||
%description libs
|
||||
Libraries for qubes-utils
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
export PYTHON=%{__python2}
|
||||
make all BACKEND_VMM=@BACKEND_VMM@
|
||||
|
||||
%install
|
||||
make install DESTDIR=%{buildroot} PYTHON=%{__python2}
|
||||
rm -rf imgconverter/build
|
||||
%make_install -C imgconverter PYTHON=%{__python3}
|
||||
|
||||
%post
|
||||
# dom0
|
||||
%systemd_post qubes-meminfo-writer-dom0.service
|
||||
# VM
|
||||
%systemd_post qubes-meminfo-writer.service
|
||||
|
||||
%preun
|
||||
%systemd_preun qubes-meminfo-writer-dom0.service
|
||||
%systemd_preun qubes-meminfo-writer.service
|
||||
|
||||
%postun
|
||||
%systemd_postun_with_restart qubes-meminfo-writer-dom0.service
|
||||
%systemd_postun_with_restart qubes-meminfo-writer.service
|
||||
|
||||
%post libs -p /sbin/ldconfig
|
||||
%postun libs -p /sbin/ldconfig
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
/lib/udev/rules.d/*-qubes-*.rules
|
||||
/usr/lib/qubes/udev-*
|
||||
%{_sbindir}/meminfo-writer
|
||||
%{_unitdir}/qubes-meminfo-writer.service
|
||||
%{_unitdir}/qubes-meminfo-writer-dom0.service
|
||||
|
||||
%files -n python2-qubesimgconverter
|
||||
%{python2_sitelib}/qubesimgconverter/__init__.py*
|
||||
%{python2_sitelib}/qubesimgconverter/imggen.py*
|
||||
%{python2_sitelib}/qubesimgconverter/test.py*
|
||||
%{python2_sitelib}/qubesimgconverter/test_integ.py*
|
||||
%{python2_sitelib}/qubesimgconverter-%{version}-py?.?.egg-info
|
||||
|
||||
%files -n python%{python3_pkgversion}-qubesimgconverter
|
||||
%{python3_sitelib}/qubesimgconverter/__init__.py
|
||||
%{python3_sitelib}/qubesimgconverter/imggen.py
|
||||
%{python3_sitelib}/qubesimgconverter/test.py
|
||||
%{python3_sitelib}/qubesimgconverter/test_integ.py
|
||||
%{python3_sitelib}/qubesimgconverter-%{version}-py?.?.egg-info
|
||||
%{python3_sitelib}/qubesimgconverter/__pycache__
|
||||
|
||||
%files libs
|
||||
%{_libdir}/libqubes-rpc-filecopy.so.2
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
/usr/include/libqubes-rpc-filecopy.h
|
||||
%{_libdir}/libqubes-rpc-filecopy.so
|
||||
|
||||
%changelog
|
||||
@CHANGELOG@
|
@ -1,14 +1,14 @@
|
||||
all:
|
||||
|
||||
install:
|
||||
mkdir -p $(DESTDIR)/etc/udev/rules.d
|
||||
cp udev-qubes-block.rules $(DESTDIR)/etc/udev/rules.d/99-qubes-block.rules
|
||||
cp udev-qubes-usb.rules $(DESTDIR)/etc/udev/rules.d/99-qubes-usb.rules
|
||||
cp udev-qubes-misc.rules $(DESTDIR)/etc/udev/rules.d/99-qubes-misc.rules
|
||||
mkdir -p $(DESTDIR)$(SYSLIBDIR)/udev/rules.d
|
||||
cp udev-qubes-block.rules $(DESTDIR)$(SYSLIBDIR)/udev/rules.d/99-qubes-block.rules
|
||||
cp udev-qubes-usb.rules $(DESTDIR)$(SYSLIBDIR)/udev/rules.d/99-qubes-usb.rules
|
||||
cp udev-qubes-misc.rules $(DESTDIR)$(SYSLIBDIR)/udev/rules.d/99-qubes-misc.rules
|
||||
cp udev-qubes-dmroot.rules $(DESTDIR)$(SYSLIBDIR)/udev/rules.d/90-qubes-dmroot.rules
|
||||
|
||||
mkdir -p $(DESTDIR)/usr/libexec/qubes
|
||||
cp udev-block-add-change $(DESTDIR)/usr/libexec/qubes/
|
||||
cp udev-block-remove $(DESTDIR)/usr/libexec/qubes/
|
||||
cp udev-block-cleanup $(DESTDIR)/usr/libexec/qubes/
|
||||
cp udev-usb-add-change $(DESTDIR)/usr/libexec/qubes/
|
||||
cp udev-usb-remove $(DESTDIR)/usr/libexec/qubes/
|
||||
mkdir -p $(DESTDIR)$(SCRIPTSDIR)
|
||||
cp udev-block-add-change $(DESTDIR)$(SCRIPTSDIR)
|
||||
cp udev-block-remove $(DESTDIR)$(SCRIPTSDIR)
|
||||
cp udev-usb-add-change $(DESTDIR)$(SCRIPTSDIR)
|
||||
cp udev-usb-remove $(DESTDIR)$(SCRIPTSDIR)
|
||||
|
@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
DEVID=$[ $MAJOR * 256 + $MINOR ]
|
||||
|
||||
XS_PATH="device/vbd/$DEVID"
|
||||
|
||||
# Double check that DEVID is not empty
|
||||
[ -n "$DEVID" ] && xenstore-rm $XS_PATH
|
@ -0,0 +1,5 @@
|
||||
# Create /dev/mapper/dmroot symlink on TemplateVM/StandaloneVM to make
|
||||
# grub-mkconfig happy.
|
||||
# On TemplateBasedVM, it is really a device mapper device.
|
||||
|
||||
SUBSYSTEM=="block", ENV{ID_PART_ENTRY_NAME}=="Root\x20filesystem", ATTR{ro}=="0", SYMLINK+="mapper/dmroot"
|
Loading…
Reference in new issue