Compare commits
15 Commits
eaf6ffdbef
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5c3a865c7f | |||
| 58937cfe7f | |||
| 6029ebfd77 | |||
| 451d4b4c79 | |||
| ac7251b722 | |||
| f63af45d10 | |||
| 2c8998aeb4 | |||
| 7e491f4b8c | |||
| c8610f9ded | |||
| 346682eedb | |||
| e1c072cf16 | |||
| ba45bc5a3e | |||
| 974ea68865 | |||
| 33a439173c | |||
| c417a6f3f9 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -18,8 +18,6 @@ dist/
|
|||||||
downloads/
|
downloads/
|
||||||
eggs/
|
eggs/
|
||||||
.eggs/
|
.eggs/
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
parts/
|
||||||
sdist/
|
sdist/
|
||||||
var/
|
var/
|
||||||
|
|||||||
191
Makefile
191
Makefile
@@ -2,40 +2,32 @@ ROLES=base proxy toxcore
|
|||||||
SHELLCHECK_OPTS=SC2003,SC2006,SC2010,SC2039,SC2181,SC2046,SC2086,SC2048,SC2162,SC2034,SC2030,SC2166,SC2242,SC2223,SC2319,SC3009,SC3011,SC3030,SC3043,SC3054,SC2009,SC1090,SC2164,SC3044
|
SHELLCHECK_OPTS=SC2003,SC2006,SC2010,SC2039,SC2181,SC2046,SC2086,SC2048,SC2162,SC2034,SC2030,SC2166,SC2242,SC2223,SC2319,SC3009,SC3011,SC3030,SC3043,SC3054,SC2009,SC1090,SC2164,SC3044
|
||||||
|
|
||||||
# FixMe
|
# FixMe
|
||||||
ANSIBLE_PLUGINS=/usr/local/lib/python3.11/site-packages/ansible-2.9.22-py3.11.egg/ansible/plugins
|
ANSIBLE_PLUGINS=/usr/local/lib/python3.11/site-packages/ansible/plugins/connection/
|
||||||
|
|
||||||
# Edit this to be one of pentoo or devuan depending on your host platform
|
# Edit this to be one of pentoo or devuan depending on your host platform
|
||||||
# Find the corresponding host in hosts.yml and edit the settings, then
|
# Find the corresponding host in hosts.yml and edit the settings, then
|
||||||
# change this to be that hostname
|
# change this to be that hostname
|
||||||
LOCALHOST=`cat /etc/hostname`
|
LOCALHOST=`cat /etc/hostname`
|
||||||
|
|
||||||
BOX_NBD_BASE_DIR=/a/tmp/GentooImgr
|
|
||||||
BOX_NBD_BASE_FILE=gentoo.qcow2
|
|
||||||
BOX_NBD_BASE_QCOW=${BOX_NBD_BASE_DIR}/${BOX_NBD_BASE_FILE}
|
|
||||||
# set this to the name linux_local_group host in hosts.yml
|
# set this to the name linux_local_group host in hosts.yml
|
||||||
LOCAL_HOSTS_NAME=pentoo
|
LOCAL_HOSTS_NAME=pentoo
|
||||||
# set this to the name linux_chroot_group host in hosts.yml
|
# set this to the name linux_chroot_group host in hosts.yml
|
||||||
YAML_CHROOT_NAME=linuxGentoo
|
YAML_CHROOT_NAME=linuxGentoo
|
||||||
# set this to the libvirt name of the linux_libvirt_group host in hosts.yml
|
# set this to the libvirt name of the linux_libvirt_group host in hosts.yml
|
||||||
YAML_BOX_NAME=gentoo1
|
OVERLAY_HOSTS_NAME=gentoo_overlay-2
|
||||||
INST_BOX_NAME=gentoo1
|
|
||||||
|
BOX_NBD_BASE_QCOW="`/usr/local/bin/ansible_get_inventory.bash BOX_NBD_BASE_QCOW ${OVERLAY_HOSTS_NAME}`"
|
||||||
|
BOX_NBD_OVERLAY_DIR="`/usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAT_DIR ${OVERLAY_HOSTS_NAME}`"
|
||||||
|
BOX_NBD_OVERLAY_QCOW="`/usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAT_QCOW ${OVERLAY_HOSTS_NAME}`"
|
||||||
|
BOX_NBD_OVERLAY_XML=${BOX_NBD_OVERLAY_DIR}/xml/${OVERLAY_HOSTS_NAME}.xml
|
||||||
|
BOX_NBD_OVERLAY_NAME="`/usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_NAME ${OVERLAY_HOSTS_NAME}`"
|
||||||
|
|
||||||
#INST_BOX_DIR=/mnt/o/home/root/vms/virsh
|
|
||||||
INST_BOX_DIR=${BOX_NBD_BASE_DIR}/create-vm
|
|
||||||
PWD=/o/var/local/src/play_tox/
|
PWD=/o/var/local/src/play_tox/
|
||||||
NETWORK=default
|
NETWORK=Whonix-External
|
||||||
VERBOSE=2
|
VERBOSE=2
|
||||||
|
|
||||||
all: install lint build check run test
|
all: install lint build check run test
|
||||||
|
|
||||||
# groddy but works for me
|
|
||||||
install::
|
|
||||||
# ( /usr/local/src ; ansible-galaxy collection install \
|
|
||||||
# file:///usr/local/src/community.general )
|
|
||||||
[ -e $(ANSIBLE_PLUGINS)/connection/libvirt_qemu.py ] \
|
|
||||||
|| ln -s ${PWD}/lib/plugins/libvirt_qemu.py \
|
|
||||||
$(ANSIBLE_PLUGINS)/connection/q || true
|
|
||||||
|
|
||||||
lint::
|
lint::
|
||||||
@sudo xmllint -noout roles/ansible-gentoo_install/templates/etc/libvirt/qemu/gentoo.xml
|
@sudo xmllint -noout roles/ansible-gentoo_install/templates/etc/libvirt/qemu/gentoo.xml
|
||||||
@yamllint -c .yamllint.yml -f standard *.yml roles/*/*s/*yml 2>&1| \
|
@yamllint -c .yamllint.yml -f standard *.yml roles/*/*s/*yml 2>&1| \
|
||||||
@@ -44,18 +36,29 @@ lint::
|
|||||||
grep -B 2 error | tee .yamllint.err || true
|
grep -B 2 error | tee .yamllint.err || true
|
||||||
grep Error .yamllint.out || true
|
grep Error .yamllint.out || true
|
||||||
|
|
||||||
build:: build_base
|
# groddy but works for me
|
||||||
|
install:: lint
|
||||||
|
# ( /usr/local/src ; ansible-galaxy collection install \
|
||||||
|
# file:///usr/local/src/community.general )
|
||||||
|
[ -e $(ANSIBLE_PLUGINS)/connection/libvirt_qemu.py ] \
|
||||||
|
|| ln -s ${PWD}/lib/plugins/libvirt_qemu.py \
|
||||||
|
$(ANSIBLE_PLUGINS)/connection/ || true
|
||||||
|
@[ -f ${BOX_NBD_BASE_QCOW} ] || { \
|
||||||
|
echo ERROR: not created BOX_NBD_DEV="${BOX_NBD_DEV}" - use ; \
|
||||||
|
echo qemu-img create -f qcow2 "${BOX_NBD_BASE_QCOW}" 20G ; \
|
||||||
|
exit 2 ; }
|
||||||
|
@( ps ax | grep -v grep | \
|
||||||
|
grep "qemu-nbd.*/dev/nbd.*${BOX_NBD_BASE_QCOW}" ) || { \
|
||||||
|
echo ERROR: not mounted BOX_NBD_DEV="${BOX_NBD_DEV}" - use ; \
|
||||||
|
echo qemu-nbd -n -f qcow2 -c /dev/nbd1 ${BOX_NBD_BASE_QCOW} ;\
|
||||||
|
exit 1 ; }
|
||||||
|
|
||||||
|
build::
|
||||||
|
sudo $(MAKE) -$(MAKEFLAGS) build_base
|
||||||
sudo $(MAKE) -$(MAKEFLAGS) build_overlay
|
sudo $(MAKE) -$(MAKEFLAGS) build_overlay
|
||||||
|
|
||||||
build_base:: lint
|
build_base:: install
|
||||||
echo INFO: $@ "${BOX_NBD_BASE_QCOW}"
|
echo INFO: $@ "${BOX_NBD_BASE_QCOW}"
|
||||||
@[ ! -f ${BOX_NBD_BASE_QCOW} ] || { \
|
|
||||||
echo WARN looks like theres already a build of \
|
|
||||||
"${BOX_NBD_BASE_QCOW}" ; exit 2 ; }
|
|
||||||
@( ! ps ax | grep -v grep | \
|
|
||||||
grep "qemu-nbd.*/dev/nbd.*${BOX_NBD_BASE_QCOW}" ) ||{ \
|
|
||||||
echo WARN looks like theres an active nbd mount of \
|
|
||||||
"${BOX_NBD_BASE_QCOW}" && exit 1 ; }
|
|
||||||
echo INFO running the toxcore role will build ${BOX_NBD_BASE_QCOW}
|
echo INFO running the toxcore role will build ${BOX_NBD_BASE_QCOW}
|
||||||
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml \
|
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml \
|
||||||
-l ${LOCALHOST} -c local --verbose ${VERBOSE} \
|
-l ${LOCALHOST} -c local --verbose ${VERBOSE} \
|
||||||
@@ -63,24 +66,27 @@ build_base:: lint
|
|||||||
[ -f ${BOX_NBD_BASE_QCOW} ]
|
[ -f ${BOX_NBD_BASE_QCOW} ]
|
||||||
|
|
||||||
build_overlay::
|
build_overlay::
|
||||||
@virsh list | grep "${INST_BOX_NAME}.*running" && \
|
@virsh list | grep "${OVERLAY_HOSTS_NAME}.*running" && \
|
||||||
virsh destroy ${INST_BOX_NAME} ; true
|
virsh destroy ${OVERLAY_HOSTS_NAME} ; true
|
||||||
# @virsh list | grep "${INST_BOX_NAME}.*running" && exit 1
|
# @virsh list | grep "${OVERLAY_HOSTS_NAME}.*running" && exit 1
|
||||||
@virsh list --all | grep ${INST_BOX_NAME} && \
|
@virsh list --all | grep ${OVERLAY_HOSTS_NAME} && \
|
||||||
virsh undefine ${INST_BOX_NAME} && \
|
virsh undefine ${OVERLAY_HOSTS_NAME} && \
|
||||||
rm -f /a/tmp/GentooImgr/create-vm/xml/gentoo1.xml \
|
rm -f \
|
||||||
${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml \
|
${BOX_NBD_OVERLAY_XML} \
|
||||||
${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ; true
|
${BOX_NBD_OVERLAY_QCOW} ; true
|
||||||
# ! virsh list --all | grep "${INST_BOX_NAME}" && exit 2
|
# /a/tmp/GentooImgr/create-vm/xml/gentoo1.xml
|
||||||
[ ! -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ] || { \
|
# ! virsh list --all | grep "${OVERLAY_HOSTS_NAME}" && exit 2
|
||||||
echo WARN ; echo rm -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ; \
|
[ ! -f ${BOX_NBD_OVERLAY_QCOW} ] || { \
|
||||||
|
echo WARN delete this file to continue; \
|
||||||
|
echo rm -f ${BOX_NBD_OVERLAY_QCOW} ; \
|
||||||
exit 3 ; }
|
exit 3 ; }
|
||||||
[ ! -f ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml ] || { \
|
[ ! -f ${BOX_NBD_OVERLAY_XML} ] || { \
|
||||||
echo WARN ; echo rm -f ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml ; \
|
echo WARN delete this file to continue ; \
|
||||||
|
echo rm -f ${BOX_NBD_OVERLAY_XML} ; \
|
||||||
exit 4 ; }
|
exit 4 ; }
|
||||||
PLAY_ANSIBLE_SRC=${PWD} bash /usr/local/bin/toxcore_build_overlay_qcow.bash
|
PLAY_ANSIBLE_SRC=${PWD} bash bin/toxcore_build_overlay_qcow.bash
|
||||||
[ -f ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml ]
|
[ -f ${BOX_NBD_OVERLAY_XML} ]
|
||||||
xmllint -noout ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml
|
xmllint -noout ${BOX_NBD_OVERLAY_XML}
|
||||||
|
|
||||||
check::
|
check::
|
||||||
grep -n 'shell: *$$' roles/*/tasks/*.yml && { echo ERROR: "shell: in .yml" ; false ; } || true
|
grep -n 'shell: *$$' roles/*/tasks/*.yml && { echo ERROR: "shell: in .yml" ; false ; } || true
|
||||||
@@ -90,7 +96,7 @@ check::
|
|||||||
$(MAKE) -$(MAKEFLAGS) check_base
|
$(MAKE) -$(MAKEFLAGS) check_base
|
||||||
@[ -d /mnt/gentoo/lost+found ] && \
|
@[ -d /mnt/gentoo/lost+found ] && \
|
||||||
sudo $(MAKE) -$(MAKEFLAGS) $@_chroot
|
sudo $(MAKE) -$(MAKEFLAGS) $@_chroot
|
||||||
@[ -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ] && \
|
@[ -f ${BOX_NBD_OVERLAY_QCOW} ] && \
|
||||||
sudo $(MAKE) -$(MAKEFLAGS) $@_overlay
|
sudo $(MAKE) -$(MAKEFLAGS) $@_overlay
|
||||||
|
|
||||||
check_localhost::
|
check_localhost::
|
||||||
@@ -100,9 +106,9 @@ check_localhost::
|
|||||||
|
|
||||||
check_base::
|
check_base::
|
||||||
ls ${BOX_NBD_BASE_QCOW}
|
ls ${BOX_NBD_BASE_QCOW}
|
||||||
ls ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img
|
ls ${BOX_NBD_OVERLAY_QCOW}
|
||||||
ls ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml
|
ls ${BOX_NBD_OVERLAY_XML}
|
||||||
ps axf | grep 'qemu-system-x86_64 -name guest='${INST_BOX_NAME} ; \
|
ps axf | grep 'qemu-system-x86_64 -name guest='${OVERLAY_HOSTS_NAME} ; \
|
||||||
true
|
true
|
||||||
|
|
||||||
check_chroot::
|
check_chroot::
|
||||||
@@ -114,18 +120,19 @@ check_chroot::
|
|||||||
$(ROLES) > .$@-${YAML_CHROOT_NAME}-${LOCALHOST} 2>&1
|
$(ROLES) > .$@-${YAML_CHROOT_NAME}-${LOCALHOST} 2>&1
|
||||||
|
|
||||||
check_overlay::
|
check_overlay::
|
||||||
sudo /var/local/sbin/hostvms_libvirt_test_ga.bash ${INST_BOX_NAME} ls /
|
sudo /usr/local/sbin/toxcore_libvirt_test_ga.bash ${OVERLAY_HOSTS_NAME} ls /
|
||||||
|
sudo /usr/local/sbin/toxcore_libvirt_test_ga.bash ${OVERLAY_HOSTS_NAME}
|
||||||
# domain-*-gentoo/org.qemu.guest_agent.0 || true
|
# domain-*-gentoo/org.qemu.guest_agent.0 || true
|
||||||
|
sudo virsh list | grep -q ${OVERLAY_HOSTS_NAME} || exit 0
|
||||||
sudo find /var/lib/libvirt/qemu/channel/target/ | \
|
sudo find /var/lib/libvirt/qemu/channel/target/ | \
|
||||||
grep org.qemu.guest_agent.0
|
grep org.qemu.guest_agent.0
|
||||||
sudo find /var/lib/libvirt/qemu/channel/target/ -type s | \
|
sudo find /var/lib/libvirt/qemu/channel/target/ -type s | \
|
||||||
grep ${INST_BOX_NAME}
|
grep ${OVERLAY_HOSTS_NAME}
|
||||||
ansible -c libvirt_qemu -l ${YAML_BOX_NAME} -i hosts.yml \
|
ansible -c libvirt_qemu -l ${OVERLAY_HOSTS_NAME} -i hosts.yml \
|
||||||
-m setup -vvv ${YAML_BOX_NAME}
|
-m setup -vvv ${OVERLAY_HOSTS_NAME}
|
||||||
sudo virsh list | grep -q ${INST_BOX_NAME} || exit 0
|
sudo sh ansible_local.bash --diff -i hosts.yml -l ${OVERLAY_HOSTS_NAME} \
|
||||||
sudo sh ansible_local.bash --diff -i hosts.yml -l ${INST_BOX_NAME} \
|
|
||||||
--check -c libvirt_qemu --verbose ${VERBOSE} \
|
--check -c libvirt_qemu --verbose ${VERBOSE} \
|
||||||
$(ROLES) > .$@-${INST_BOX_NAME}-${LOCALHOST} 2>&1
|
$(ROLES) > .$@-${OVERLAY_HOSTS_NAME}-${LOCALHOST} 2>&1
|
||||||
|
|
||||||
# Edit hosts.yml and customize this target if you are on a Debianish
|
# Edit hosts.yml and customize this target if you are on a Debianish
|
||||||
devuan::
|
devuan::
|
||||||
@@ -144,8 +151,8 @@ run::
|
|||||||
$(MAKE) -$(MAKEFLAGS) $@_local
|
$(MAKE) -$(MAKEFLAGS) $@_local
|
||||||
@[ -d /mnt/gentoo/lost+found ] && \
|
@[ -d /mnt/gentoo/lost+found ] && \
|
||||||
sudo $(MAKE) -$(MAKEFLAGS) $@_chroot
|
sudo $(MAKE) -$(MAKEFLAGS) $@_chroot
|
||||||
@[ ! -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ] && \
|
@[ ! -f ${BOX_NBD_OVERLAY_QCOW} ] && \
|
||||||
sudo $(MAKE) -$(MAKEFLAGS) $@_libvirt
|
sudo $(MAKE) -$(MAKEFLAGS) $@_overlay
|
||||||
|
|
||||||
run_local:: lint
|
run_local:: lint
|
||||||
A=`grep nbd /proc/partitions | wc -l`
|
A=`grep nbd /proc/partitions | wc -l`
|
||||||
@@ -168,26 +175,35 @@ run_chroot::
|
|||||||
-c chroot --verbose ${VERBOSE} $(ROLES) \
|
-c chroot --verbose ${VERBOSE} $(ROLES) \
|
||||||
> .$@-${YAML_CHROOT_NAME}-${LOCALHOST} 2>&1
|
> .$@-${YAML_CHROOT_NAME}-${LOCALHOST} 2>&1
|
||||||
|
|
||||||
run_libvirt::
|
install_libvirt::
|
||||||
[ -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ]
|
|
||||||
@virsh net-list | grep "${NETWORK}.*active" || \
|
@virsh net-list | grep "${NETWORK}.*active" || \
|
||||||
sudo virsh net-start "${NETWORK}"
|
sudo virsh net-start "${NETWORK}" || { \
|
||||||
@virsh list | grep ${INST_BOX_NAME} && \
|
echo WARN: error virsh net-start "${NETWORK}" ; }
|
||||||
virsh define ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml
|
[ -f ${BOX_NBD_OVERLAY_XML} ]
|
||||||
@virsh list | grep "${INST_BOX_NAME}.*running" || \
|
# xmlstarlet sel -t -v
|
||||||
virsh start ${INST_BOX_NAME}
|
A=$(grep 'source file=' ${BOX_NBD_OVERLAY_XML} | sed -e 's@.*file=.@@' -e "s@'.*@@" )
|
||||||
sh ansible_local.bash --diff -i hosts.yml -l ${INST_BOX_NAME} \
|
[ -n "${A}" ] && [ -f "${A}" ]
|
||||||
|
@virsh list --all | grep ${OVERLAY_HOSTS_NAME} || \
|
||||||
|
virsh define ${BOX_NBD_OVERLAY_XML}
|
||||||
|
@virsh list | grep "${OVERLAY_HOSTS_NAME}.*running" || \
|
||||||
|
{ virsh start ${OVERLAY_HOSTS_NAME} ; sleep 40 ; }
|
||||||
|
|
||||||
|
run_overlay:: install_libvirt
|
||||||
|
[ -f ${BOX_NBD_OVERLAY_QCOW} ] || { \
|
||||||
|
echo WARN ${BOX_NBD_OVERLAY_QCOW} doesnt exist - make build_overlay ; \
|
||||||
|
exit 1 ; }
|
||||||
|
sh ansible_local.bash --diff -i hosts.yml -l ${OVERLAY_HOSTS_NAME} \
|
||||||
-c libvirt_qemu --verbose ${VERBOSE} $(ROLES) \
|
-c libvirt_qemu --verbose ${VERBOSE} $(ROLES) \
|
||||||
> .run-${INST_BOX_NAME}-${LOCALHOST} 2>&1
|
> .run-${OVERLAY_HOSTS_NAME}-${LOCALHOST} 2>&1
|
||||||
|
|
||||||
# hourly is quick tests, weekly is medium tests, monthly is long tests
|
# hourly is quick tests, weekly is medium tests, monthly is long tests
|
||||||
weekly:: test
|
weekly:: test
|
||||||
test::
|
test::
|
||||||
|
# bash .pyanal.sh &
|
||||||
@[ -d /mnt/gentoo/lost+found ] && \
|
@[ -d /mnt/gentoo/lost+found ] && \
|
||||||
sudo $(MAKE) -$(MAKEFLAGS) $@_local
|
sudo $(MAKE) -$(MAKEFLAGS) $@_local
|
||||||
@[ -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ] && \
|
@[ -f ${BOX_NBD_OVERLAY_QCOW} ] && \
|
||||||
sudo $(MAKE) -$(MAKEFLAGS) $@_libvert
|
sudo $(MAKE) -$(MAKEFLAGS) $@_overlay
|
||||||
|
|
||||||
test_local::
|
test_local::
|
||||||
bash .pyanal.sh &
|
bash .pyanal.sh &
|
||||||
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml -l ${LOCALHOST} \
|
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml -l ${LOCALHOST} \
|
||||||
@@ -195,18 +211,49 @@ test_local::
|
|||||||
--verbose ${VERBOSE} -t weekly \
|
--verbose ${VERBOSE} -t weekly \
|
||||||
$(ROLES) > .$@-${LOCALHOST} 2>&1
|
$(ROLES) > .$@-${LOCALHOST} 2>&1
|
||||||
|
|
||||||
test_libvirt::
|
test_overlay:: install_libvirt
|
||||||
# bash .pyanal.sh &
|
! sudo virsh list | grep -q ${OVERLAY_HOSTS_NAME} && exit 0
|
||||||
# check if ${INST_BOX_NAME} is running
|
|
||||||
! sudo virsh list | grep -q ${INST_BOX_NAME} && exit 0
|
|
||||||
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml \
|
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml \
|
||||||
-l ${INST_BOX_NAME} -c libvirt_qemu \
|
-l ${OVERLAY_HOSTS_NAME} -c libvirt_qemu \
|
||||||
--verbose ${VERBOSE} -t weekly \
|
--verbose ${VERBOSE} -t weekly \
|
||||||
$(ROLES) > .$@-${LOCALHOST} 2>&1
|
$(ROLES) > .$@-${LOCALHOST} 2>&1
|
||||||
|
|
||||||
|
# this is a special test target to test a copy of the base qcow2
|
||||||
|
VM_HOSTS_NAME=gentoo_vm-2
|
||||||
|
VM_XML=/etc/libvirt/qemu/${VM_HOSTS_NAME}.xml
|
||||||
|
A="`grep 'source file=.*qcow2' ${VM_XML} | sed -e 's@.*file=.@@' -e "s@'.*@@"`"
|
||||||
|
install_vm::
|
||||||
|
@virsh net-list | grep "${NETWORK}.*active" || \
|
||||||
|
sudo virsh net-start "${NETWORK}" || { \
|
||||||
|
echo WARN: error virsh net-start "${NETWORK}" ; }
|
||||||
|
[ -f ${VM_XML} ]
|
||||||
|
@virsh list --all | grep ${VM_HOSTS_NAME} || { \
|
||||||
|
echo ERROR virsh define ${VM_XML} ; exit 8 ; }
|
||||||
|
# xmlstarlet sel -t -v
|
||||||
|
[ -n "${A}" ] && [ -f "${A}" ]
|
||||||
|
@virsh list | grep "${VM_HOSTS_NAME}.*running" || \
|
||||||
|
{ virsh start ${VM_HOSTS_NAME} ; sleep 40 ; }
|
||||||
|
|
||||||
|
test_vm:: install_vm
|
||||||
|
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml \
|
||||||
|
-l ${VM_HOSTS_NAME} -c libvirt_qemu \
|
||||||
|
--check --verbose ${VERBOSE} -t daily \
|
||||||
|
$(ROLES) > .$@-${LOCALHOST} 2>&1
|
||||||
|
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml \
|
||||||
|
-l ${VM_HOSTS_NAME} -c libvirt_qemu \
|
||||||
|
--verbose ${VERBOSE} -t daily \
|
||||||
|
$(ROLES) > .$@-${LOCALHOST} 2>&1
|
||||||
|
# ${VERBOSE}
|
||||||
|
rsync::
|
||||||
|
bash .rsync.sh
|
||||||
|
|
||||||
veryclean:: clean
|
veryclean:: clean
|
||||||
rm -f .run* .check*
|
rm -f .run* .check*
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
find . -name \*~ -delete
|
find . -name \*~ -delete
|
||||||
rm roles/*/vars/*.txt
|
rm roles/*/vars/*.txt
|
||||||
|
rm -rf roles/toxcore/overlay/Linux/usr/local/src/_Old
|
||||||
|
|
||||||
|
test::
|
||||||
|
DEBUG=1 sudo bash -x /usr/local/sbin/toxcore_libvirt_test_ga.bash gentoo_vm-2 ls /
|
||||||
|
|||||||
38
README.md
38
README.md
@@ -77,26 +77,36 @@ the hosts.yml file from the host called gentoo1 in the linux_libvirt_group.
|
|||||||
There are 3 ansible roles:
|
There are 3 ansible roles:
|
||||||
|
|
||||||
1. base : The base role sets up the basics and is required to be run.
|
1. base : The base role sets up the basics and is required to be run.
|
||||||
|
It sets up the essential parameters to run roles on the host or client.
|
||||||
|
Check the settings in roles/base/defaults/main.yml before running the role.
|
||||||
|
|
||||||
2. proxy : The proxy role sets up the networking with proxies,
|
2. proxy : The proxy role sets up the networking with proxies,
|
||||||
and is required to be run, even if you don't use a proxy.
|
and is required to be run, even if you don't use a proxy.
|
||||||
|
It sets proxying and installs basic packages on the host or client.
|
||||||
|
Check the settings in roles/proxy/defaults/main.yml before running the role.
|
||||||
|
|
||||||
3. toxcore :
|
3. toxcore :
|
||||||
|
This role sets up the software to run libvirt on the host.
|
||||||
|
Check the settings in roles/toxcore/defaults/main.yml before running the role.
|
||||||
|
|
||||||
|
In addition, toxcore calls an included role ansible-gentoo_install.
|
||||||
|
This is an updated version of the abandonned
|
||||||
|
https://github.com/agaffney/ansible-gentoo_install/ This role,
|
||||||
|
when run on the host, builds the Gentoo base qcow image. As a safety
|
||||||
|
feature, you must create the qcow2 image and activate it with:
|
||||||
|
|
||||||
|
The host creates the base qcow2 image and then creates the overlay
|
||||||
|
image. When both are created, it install Tox software on the host and
|
||||||
|
client.
|
||||||
|
|
||||||
In addition, toxcore calls an included role ansible-gentoo_install.
|
modprobe nbd
|
||||||
This is an updated version of the abandonned
|
qemu-img $BOX_NBD_BASE_QCOW 20G
|
||||||
https://github.com/agaffney/ansible-gentoo_install/ This role,
|
qemu-nbd -c $BOX_NBD_DEV $BOX_NBD_BASE_QCOW
|
||||||
when run on the host, builds the Gentoo base qcow image. As a safety
|
|
||||||
feature, you must create the qcow2 image and activate it with:
|
|
||||||
|
|
||||||
modprobe nbd
|
and put these values into the hosts.yml file in the pentoo or devuan
|
||||||
qemu-img $BOX_NBD_BASE_QCOW 20G
|
target, depending on your host operating system. The filesytem that
|
||||||
qemu-nbd -c $BOX_NBD_DEV $BOX_NBD_BASE_QCOW
|
holds base qcow2 $BOX_NBD_BASE_QCOW must have at least 12G available,
|
||||||
|
and may grow to almost 20G.
|
||||||
and put these values into the hosts.yml file in the pentoo or devuan
|
|
||||||
target, depending on your host operating system. The filesytem that
|
|
||||||
holds base qcow2 $BOX_NBD_BASE_QCOW must have at least 12G available,
|
|
||||||
and may grow to almost 20G.
|
|
||||||
|
|
||||||
After you have finished building the base qcow2 image, you will want
|
After you have finished building the base qcow2 image, you will want
|
||||||
to dismount it with qemu-nbd -d $BOX_NBD_DEV. Be careful and look
|
to dismount it with qemu-nbd -d $BOX_NBD_DEV. Be careful and look
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[defaults]
|
[defaults]
|
||||||
log_path = var/tmp/2023/12/31/pentoo/base_proxy_toxcore.log
|
log_path = var/tmp/2024/01/09/gentoo_vm-2/base_proxy_toxcore.log
|
||||||
callback_plugins = ./lib/plugins/
|
callback_plugins = ./lib/plugins/
|
||||||
# /i/data/DevOps/net/Http/docs.ansible.com/ansible/intro_configuration.html
|
# /i/data/DevOps/net/Http/docs.ansible.com/ansible/intro_configuration.html
|
||||||
# http://docs.ansible.com/ansible/intro_configuration.html#command-warnings
|
# http://docs.ansible.com/ansible/intro_configuration.html#command-warnings
|
||||||
@@ -36,3 +36,5 @@ nocows = 0
|
|||||||
roles_path = ./roles
|
roles_path = ./roles
|
||||||
handler_includes_static = True
|
handler_includes_static = True
|
||||||
timeout = 60
|
timeout = 60
|
||||||
|
# added
|
||||||
|
libvirt_timeout = 14
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
- hosts: "{{ BOX_HOST }}" # |default('localhost')
|
- hosts: "{{ BOX_HOST|default('localhost')} }}" # |default('localhost')
|
||||||
#?? become: "{{ 'false' if ansible_connection|default('') == 'chroot' else 'true'}}"
|
#?? become: "{{ 'false' if ansible_connection|default('') == 'chroot' else 'true'}}"
|
||||||
# become_method: "'' if ansible_connection|default('') == 'chroot' else 'sudo'"
|
# become_method: "'' if ansible_connection|default('') == 'chroot' else 'sudo'"
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
# other things that use /usr/local, including some things from other OSes.
|
# other things that use /usr/local, including some things from other OSes.
|
||||||
VAR_LOCAL: "/var/local"
|
VAR_LOCAL: "/var/local"
|
||||||
VAR_LOG: "{{VAR_LOCAL}}/var/log/testforge"
|
VAR_LOG: "{{VAR_LOCAL}}/var/log/testforge"
|
||||||
|
PLAY_TESTFORGE_YML: ''
|
||||||
PIP_CACHE: "/root/.cache/pip"
|
PIP_CACHE: "/root/.cache/pip"
|
||||||
# lynx uses SSL_CERT_DIR/SSL_CERT_FILE
|
# lynx uses SSL_CERT_DIR/SSL_CERT_FILE
|
||||||
PIP_CA_CERT: "{{USR_LOCAL}}/etc/ssl/cacert-testserver.pem"
|
PIP_CA_CERT: "{{USR_LOCAL}}/etc/ssl/cacert-testserver.pem"
|
||||||
@@ -101,10 +101,10 @@
|
|||||||
that:
|
that:
|
||||||
- "'{{ansible_lsb.id}}' == '{{BOX_OS_NAME}}'"
|
- "'{{ansible_lsb.id}}' == '{{BOX_OS_NAME}}'"
|
||||||
success_msg: "BOX_OS_FAMILY={{BOX_OS_FAMILY}}"
|
success_msg: "BOX_OS_FAMILY={{BOX_OS_FAMILY}}"
|
||||||
fail_msg: "ON tHE WRONG BOX {{ansible_lsb.id}} "
|
fail_msg: "ON tHE WRONG BOX {{ansible_lsb.id}}"
|
||||||
when:
|
when:
|
||||||
- ansible_connection != 'local'
|
# - ansible_connection != 'local'
|
||||||
- ansible_lsb.id|default('')" != ''
|
- ansible_lsb.id|default('') != ''
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
|
|
||||||
- name: "check BOX_ANSIBLE_CONNECTIONS"
|
- name: "check BOX_ANSIBLE_CONNECTIONS"
|
||||||
@@ -148,39 +148,8 @@
|
|||||||
check_mode: false
|
check_mode: false
|
||||||
when: ansible_connection == 'local' or ansible_connection == 'chroot'
|
when: ansible_connection == 'local' or ansible_connection == 'chroot'
|
||||||
|
|
||||||
- block:
|
|
||||||
|
|
||||||
- name: "spinup libvirt hosts"
|
|
||||||
shell: |
|
|
||||||
sudo virsh net-list | grep -q default || \
|
|
||||||
sudo virsh net-start default
|
|
||||||
sudo virsh list | grep -q "{{ inventory_hostname }}" || \
|
|
||||||
sudo virsh start "{{ inventory_hostname }}"
|
|
||||||
delegate_to: localhost
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
- name: "spinup libvirt hosts"
|
|
||||||
# pip3.sh install ovirt-engine-sdk-python --break-system-packages
|
|
||||||
ovirt:
|
|
||||||
url: "qemu:///system"
|
|
||||||
instance_name: ubuntu18.04
|
|
||||||
instance_cpus: "1"
|
|
||||||
state: started
|
|
||||||
# instance_rootpw
|
|
||||||
user: "{{ BOX_USER_NAME }}" #
|
|
||||||
password: "{{ BOX_USER_NAME }}" # "{{ ansible_ssh_user }}
|
|
||||||
become: yes
|
|
||||||
# msg: ovirtsdk required for this module
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
# required
|
|
||||||
tags: always
|
|
||||||
check_mode: false
|
|
||||||
when: ansible_connection == 'libvirt_qemu'
|
|
||||||
|
|
||||||
- block:
|
- block:
|
||||||
|
|
||||||
# after spinup
|
|
||||||
- name: "we will use sudo and make it a prerequisite"
|
- name: "we will use sudo and make it a prerequisite"
|
||||||
shell: |
|
shell: |
|
||||||
[ -z "$TMPDIR" ] || [ -d "$TMPDIR" ] || mkdir -p "$TMPDIR"
|
[ -z "$TMPDIR" ] || [ -d "$TMPDIR" ] || mkdir -p "$TMPDIR"
|
||||||
|
|||||||
448
etc/hosts.yml
Normal file
448
etc/hosts.yml
Normal file
@@ -0,0 +1,448 @@
|
|||||||
|
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-
|
||||||
|
# use double quotes exclusively around strings and
|
||||||
|
# use single quotes exclusively with lists - for bash post-processing
|
||||||
|
|
||||||
|
all:
|
||||||
|
|
||||||
|
children:
|
||||||
|
|
||||||
|
vbox_winrm_group:
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
|
||||||
|
y_UEFI_MediCat_VHD_DW:
|
||||||
|
# /var/lib/libvirt/qemu/channel/target/domain-37-y_UEFI_MediCat_VHD_D/org.qemu.guest_agent.0
|
||||||
|
# doesnt work: ansible_connection: "libvirt_qemu"
|
||||||
|
|
||||||
|
BOX_SERVICE_MGR: "win11"
|
||||||
|
BOX_HOST_NAME: "y_UEFI_MediCat_VHD_DW"
|
||||||
|
|
||||||
|
UPD_WINRM_CRT_PASSWORD: ""
|
||||||
|
UPD_WINRM_CRT_NAME: "WINRM_WIN11VBOX cert for "
|
||||||
|
UPD_WINRM_FILE_BASE: "winrm-win11vbox"
|
||||||
|
UPD_WINRM_KEY_BITS: 4096
|
||||||
|
|
||||||
|
UPD_WINRM_HOST_NAME: "y_UEFI_MediCat_VHD_D"
|
||||||
|
UPD_WINRM_HOST_DEV: "vboxnet0"
|
||||||
|
UPD_WINRM_ADMIN_NAME: "administrator"
|
||||||
|
UPD_WINRM_ADMIN_PASS: "<get from vault>"
|
||||||
|
|
||||||
|
# NOT remote_addr:
|
||||||
|
ansible_winrm_host: "192.168.56.1"
|
||||||
|
# remote_user
|
||||||
|
ansible_winrm_user: "administrator"
|
||||||
|
BOX_DEFAULT_OUTPUT_IF: fixme
|
||||||
|
|
||||||
|
UPD_WINRM_WINRM_ADMIN_NAME: "winrmadmin"
|
||||||
|
UPD_WINRM_WINRM_ADMIN_PASS: "winrmadmin"
|
||||||
|
|
||||||
|
# List of winrm transports to attempt to to use (ssl, plaintext, kerberos, etc)
|
||||||
|
# python2 -c 'import winrm;print winrm.FEATURE_SUPPORTED_AUTHTYPES'
|
||||||
|
# ['basic', 'certificate', 'ntlm', 'kerberos', 'plaintext', 'ssl', 'credssp']
|
||||||
|
# FixMe: which one works?
|
||||||
|
UPD_WINRM_WINRM_TRANSPORT: "basic"
|
||||||
|
# Lati sda Disk identifier: 0A00A495-684B-425E-823F-60257EBD6D3B
|
||||||
|
|
||||||
|
vars:
|
||||||
|
#maybe ansible_connection: "winrm"
|
||||||
|
BOX_ANSIBLE_CONNECTIONS: ["libvirt_qemu"]
|
||||||
|
ansible_winrm_port: 5985
|
||||||
|
ansible_winrm_scheme: http
|
||||||
|
ansible_winrm_transport: ['basic', 'plaintext', 'certificate', 'ssl']
|
||||||
|
# NOT remote_user
|
||||||
|
# ansible_user
|
||||||
|
ansible_winrm_user: "Administrator"
|
||||||
|
#? ansible_password: ""
|
||||||
|
ansible_winrm_server_cert_validation: ignore
|
||||||
|
validate_certs: false
|
||||||
|
# NO proxy from environment - or ensure no_proxy
|
||||||
|
no_proxy: "localhost,127.0.0.1,192.168.56.1"
|
||||||
|
|
||||||
|
linux_unix_group:
|
||||||
|
|
||||||
|
children:
|
||||||
|
|
||||||
|
linux_local_group:
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
|
||||||
|
pentoo:
|
||||||
|
ansible_remote_addr: "/mnt/linuxPen19"
|
||||||
|
BOX_HOST_NAME: "pentoo"
|
||||||
|
BOX_SERVICE_MGR: "openrc"
|
||||||
|
BOX_USER_NAME: "vagrant"
|
||||||
|
BOX_USER_GROUP: "users"
|
||||||
|
BOX_USER_HOME: "/home/vagrant"
|
||||||
|
BOX_OS_FAMILY: Gentoo
|
||||||
|
BOX_OS_NAME: gentoo
|
||||||
|
BOX_OS_FLAVOR: "Pentoo"
|
||||||
|
BOX_USR_LIB: lib
|
||||||
|
BOX_DEFAULT_OUTPUT_IF: wlan4
|
||||||
|
BOX_PROXY_MODE: selektor
|
||||||
|
BOX_WHONIX_PROXY_HOST: ""
|
||||||
|
BOX_GENTOO_DISTFILES_ARCHIVES: "/i/net/Http/distfiles.gentoo.org/distfiles"
|
||||||
|
BOX_PROXY_JAVA_NET_PROPERTIES: /etc/java-config-2/current-system-vm/jre/lib/net.properties
|
||||||
|
# /usr/lib/jvm/openjdk-bin-*/conf/net.properties
|
||||||
|
BOX_ALSO_USERS:
|
||||||
|
- pentoo
|
||||||
|
BOX_PORTAGE_PYTHON_MINOR: "3.11"
|
||||||
|
BOX_PYTHON2_MINOR: "2.7"
|
||||||
|
BOX_PYTHON3_MINOR: "3.11"
|
||||||
|
BOX_GENTOO_FROM_MP: "/"
|
||||||
|
|
||||||
|
devuan:
|
||||||
|
ansible_remote_addr: "/mnt/linuxDev4" #ignored for local
|
||||||
|
BOX_HOST_NAME: "devuan"
|
||||||
|
BOX_SERVICE_MGR: "sysvinit"
|
||||||
|
BOX_USER_NAME: "devuan"
|
||||||
|
BOX_USER_GROUP: "adm"
|
||||||
|
BOX_USER_HOME: "/home/devuan"
|
||||||
|
BOX_OS_FAMILY: Debian
|
||||||
|
BOX_OS_NAME: Devuan
|
||||||
|
BOX_OS_FLAVOR: "Devuan"
|
||||||
|
BOX_USR_LIB: lib
|
||||||
|
BOX_DEFAULT_OUTPUT_IF: wlan6
|
||||||
|
BOX_DEVUAN5_VAR_APT_ARCHIVES: "/mnt/o/Cache/Devuan/5/var/cache/apt/archives"
|
||||||
|
BOX_ALSO_USERS: []
|
||||||
|
BOX_PORTAGE_PYTHON_MINOR: "3.11"
|
||||||
|
BOX_PYTHON2_MINOR: "2.7"
|
||||||
|
BOX_PYTHON3_MINOR: "3.11"
|
||||||
|
|
||||||
|
BOX_JAVA_NET_PROPERTIES: /etc/java-11-openjdk/net.properties
|
||||||
|
|
||||||
|
BOX_WHONIX_PROXY_HOST: ""
|
||||||
|
BOX_PROXY_MODE: tor
|
||||||
|
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
|
||||||
|
|
||||||
|
vars:
|
||||||
|
BOX_ANSIBLE_CONNECTIONS: ["local"]
|
||||||
|
BOX_REMOTE_MOUNTS: ['/mnt/h', '/mnt/j','/mnt/i', '/mnt/o', '/mnt/mnt/linuxPen19']
|
||||||
|
BOX_BASE_FEATURES: ['insecure_sudo']
|
||||||
|
BOX_PROXY_FEATURES: ['run_dnsmasq', 'run_privoxy']
|
||||||
|
BOX_TOXCORE_FEATURES: []
|
||||||
|
|
||||||
|
# libvirt_group could also be ssh_group
|
||||||
|
linux_libvirt_group:
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
|
||||||
|
gentoo1:
|
||||||
|
|
||||||
|
ansible_remote_addr: "gentoo1"
|
||||||
|
ansible_host: "gentoo1"
|
||||||
|
ansible_ssh_user: "gentoo"
|
||||||
|
BOX_SERVICE_MGR: "openrc"
|
||||||
|
BOX_HOST_NAME: "gentoo1"
|
||||||
|
BOX_USER_NAME: "gentoo"
|
||||||
|
BOX_USER_GROUP: "adm"
|
||||||
|
BOX_ALSO_GROUP: "adm"
|
||||||
|
BOX_USER_HOME: "/home/gentoo"
|
||||||
|
BOX_OS_NAME: Gentoo
|
||||||
|
BOX_OS_FAMILY: Gentoo
|
||||||
|
BOX_OS_FLAVOR: "Gentoo"
|
||||||
|
BOX_USR_LIB: lib64
|
||||||
|
BOX_DEFAULT_OUTPUT_IF: eth0
|
||||||
|
BOX_PYTHON2_MINOR: ""
|
||||||
|
BOX_PYTHON3_MINOR: "3.11"
|
||||||
|
BASE_PORTAGE_PYTHON_MINOR: 3.11
|
||||||
|
BOX_HOST_CONTAINER_MOUNTS: []
|
||||||
|
BOX_GENTOO_DISTFILES_ARCHIVES: "/mnt/linuxPen19/usr/portage/distfiles"
|
||||||
|
BOX_PROXY_JAVA_NET_PROPERTIES: /etc/java-config-2/current-system-vm/jre/lib/net.properties
|
||||||
|
BOX_ALSO_USERS:
|
||||||
|
- gentoo
|
||||||
|
BOX_BASE_FEATURES: []
|
||||||
|
BOX_PROXY_FEATURES: []
|
||||||
|
BOX_TOXCORE_FEATURES: ['libvirt', 'docker']
|
||||||
|
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
|
||||||
|
|
||||||
|
ubuntu18.04:
|
||||||
|
# /mnt
|
||||||
|
ansible_remote_addr: "ubuntu18.04"
|
||||||
|
# this is what the libvirt-qemu connector uses
|
||||||
|
ansible_host: "ubuntu18.04"
|
||||||
|
ansible_ssh_user: "vagrant"
|
||||||
|
BOX_SERVICE_MGR: systemd
|
||||||
|
BOX_HOST_NAME: "Ubuntu18.04"
|
||||||
|
BOX_USER_NAME: "vagrant"
|
||||||
|
BOX_USER_GROUP: "users"
|
||||||
|
BOX_USER_HOME: "/home/vagrant"
|
||||||
|
BOX_OS_FAMILY: Debian
|
||||||
|
BOX_OS_NAME: Ubuntu
|
||||||
|
BOX_OS_FLAVOR: "Ubuntu18"
|
||||||
|
BOX_USR_LIB: lib
|
||||||
|
BOX_UBUNTU16_VAR_APT_ARCHIVES: "/o/Cache/Apt/Ubuntu/18/var/cache/apt/archives"
|
||||||
|
ansible_python_interpreter: "/usr/bin/python3.6"
|
||||||
|
BOX_PYTHON2_MINOR: ""
|
||||||
|
BOX_PYTHON3_MINOR: "3.6"
|
||||||
|
BOX_REMOTE_MOUNTS: ['/mnt/o']
|
||||||
|
# BOX_WHONIX_PROXY_HOST: "Whonix-Gateway"
|
||||||
|
# BOX_PROXY_MODE: ws
|
||||||
|
# FixMe
|
||||||
|
base_system_users: ['vagrant']
|
||||||
|
BOX_TOXCORE_FEATURES: ['libvirt', 'docker']
|
||||||
|
|
||||||
|
vars:
|
||||||
|
BOX_ANSIBLE_CONNECTIONS: ["ssh", "libvirt_qemu"]
|
||||||
|
# proxy from environment
|
||||||
|
# ansible_ssh_extra_args: "-o StrictHostKeyChecking=no"
|
||||||
|
# ansible_ssh_host: "127.0.0.1"
|
||||||
|
BOX_PROXY_FEATURES: []
|
||||||
|
BOX_ROOT_GROUP: root
|
||||||
|
BOX_PROXY_MODE: nat
|
||||||
|
BOX_DEFAULT_OUTPUT_IF: eth0
|
||||||
|
http_proxy: "http://127.0.0.1:3128"
|
||||||
|
https_proxy: "http://127.0.0.1:9128"
|
||||||
|
socks_proxy: "socks5://127.0.0.1:9050"
|
||||||
|
no_proxy: "localhost,127.0.0.1,127.0.0.1"
|
||||||
|
|
||||||
|
linux_chroot_group :
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
|
||||||
|
linuxGentoo:
|
||||||
|
|
||||||
|
ansible_remote_addr: "/mnt/gentoo"
|
||||||
|
# required
|
||||||
|
ansible_host: "/mnt/gentoo"
|
||||||
|
BOX_SERVICE_MGR: "openrc"
|
||||||
|
BOX_HOST_NAME: "gentoo"
|
||||||
|
BOX_USER_NAME: "gentoo"
|
||||||
|
BOX_USER_GROUP: "adm"
|
||||||
|
BOX_USER_HOME: "/home/gentoo"
|
||||||
|
BOX_OS_FAMILY: Gentoo
|
||||||
|
BOX_OS_NAME: gentoo
|
||||||
|
BOX_OS_FLAVOR: "Gentoo"
|
||||||
|
BOX_USR_LIB: lib64
|
||||||
|
BOX_DEFAULT_OUTPUT_IF: wlan6
|
||||||
|
BASE_PORTAGE_PYTHON_MINOR: 3.11
|
||||||
|
ansible_python_interpreter: "/usr/bin/python3.11"
|
||||||
|
BOX_GENTOO_DISTFILES_ARCHIVES: "/mnt/linuxPen19/usr/portage/distfiles"
|
||||||
|
BOX_PROXY_JAVA_NET_PROPERTIES: /etc/java-config-2/current-system-vm/jre/lib/net.properties
|
||||||
|
BOX_ALSO_USERS:
|
||||||
|
- gentoo
|
||||||
|
BOX_PROXY_MODE: "{{lookup('env', 'MODE'|default('tor'}}"
|
||||||
|
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
|
||||||
|
|
||||||
|
linuxPen19:
|
||||||
|
|
||||||
|
ansible_remote_addr: "/mnt/linuxPen19"
|
||||||
|
# required
|
||||||
|
ansible_host: "/mnt/linuxPen19"
|
||||||
|
BOX_SERVICE_MGR: "openrc"
|
||||||
|
BOX_HOST_NAME: "linuxPen19"
|
||||||
|
BOX_USER_NAME: "vagrant"
|
||||||
|
BOX_USER_GROUP: "adm"
|
||||||
|
BOX_USER_HOME: "/home/vagrant"
|
||||||
|
BOX_OS_FAMILY: Gentoo
|
||||||
|
BOX_OS_NAME: gentoo
|
||||||
|
BOX_OS_FLAVOR: "Pentoo"
|
||||||
|
BOX_USR_LIB: lib64
|
||||||
|
BOX_DEFAULT_OUTPUT_IF: wlan6
|
||||||
|
BASE_PORTAGE_PYTHON_MINOR: 3.11
|
||||||
|
ansible_python_interpreter: "/usr/bin/python3.11"
|
||||||
|
BOX_GENTOO_DISTFILES_ARCHIVES: "/mnt/i/net/Http/distfiles.gentoo.org/distfiles"
|
||||||
|
BOX_PROXY_JAVA_NET_PROPERTIES: /etc/java-config-2/current-system-vm/jre/lib/net.properties
|
||||||
|
BOX_ALSO_USERS:
|
||||||
|
- gentoo
|
||||||
|
BOX_BASE_FEATURES: []
|
||||||
|
BOX_TOXCORE_FEATURES: ['nbd', 'libvirt', 'docker']
|
||||||
|
BOX_PROXY_MODE: "{{lookup('env', 'MODE'|default('tor'}}"
|
||||||
|
|
||||||
|
# linux_chroot_group vars
|
||||||
|
vars:
|
||||||
|
BOX_ANSIBLE_CONNECTIONS: ["local", "chroot"]
|
||||||
|
# ignored? chroot_connection/exe in ansible.cfg?
|
||||||
|
ansible_chroot_exe: "/usr/local/sbin/base_chroot.bash"
|
||||||
|
|
||||||
|
#? ansible_ssh_common_args: "/usr/bin/env -i CHROOT=1"
|
||||||
|
# -i "PATH"
|
||||||
|
# -i "http_proxy https_proxy socks_proxy no_proxy"
|
||||||
|
#? -l
|
||||||
|
# for a non-root login: ansible_ssh_extra_args: "--userspec=foo:adm"
|
||||||
|
vars: # linux_unix_group
|
||||||
|
# toxcore
|
||||||
|
BOX_NBD_DEV: nbd1
|
||||||
|
BOX_NBD_MP: /mnt/gentoo
|
||||||
|
BOX_NBD_OVERLAY_NAME: "gentoo1"
|
||||||
|
BOX_NBD_FILES: "/i/data/Agile/tmp/Topics/GentooImgr"
|
||||||
|
BOX_NBD_PORTAGE_FILE: "{{AGI_NBD_FILES}}/portage-20231223.tar.xz"
|
||||||
|
BOX_NBD_STAGE3_FILE: "{{AGI_NBD_FILES}}/stage3-amd64-openrc-20231217T170203Z.tar.xz"
|
||||||
|
BOX_NBD_KERNEL_DIR: /usr/src/linux
|
||||||
|
BOX_NBD_BASE_PROFILE: openrc
|
||||||
|
BOX_NBD_BASE_DIR: "/a/tmp/GentooImgr"
|
||||||
|
BOX_NBD_BASE_QCOW: "{{BOX_NBD_BASE_DIR}}/gentoo.qcow2"
|
||||||
|
BOX_NBD_OVERLAY_QCOW: "/o/var/lib/libvirt/images/gentoo1.qcow2"
|
||||||
|
BOX_NBD_BASE_PUBKEY: "/root/.ssh/id_rsa-ansible.pub"
|
||||||
|
|
||||||
|
# libvirt overlay
|
||||||
|
BOX_NBD_OVERLAY_DIR: "/a/tmp/GentooImgr/create-vm"
|
||||||
|
BOX_NBD_LOGLEVEL: 10
|
||||||
|
BOX_NBD_OVERLAY_GB: "20"
|
||||||
|
BOX_NBD_OVERLAY_CPUS: 1
|
||||||
|
BOX_NBD_OVERLAY_RAM: 2048
|
||||||
|
BOX_NBD_OVERLAY_BR: virbr1
|
||||||
|
# unused?
|
||||||
|
BOX_NBD_OVERLAY_NETWORK: default
|
||||||
|
# plaintext
|
||||||
|
BOX_NBD_OVERLAY_PASS: "gentoo"
|
||||||
|
BOX_GENTOOIMGR_CONFIGFILE: "/g/Agile/tmp/Topics/GentooImgr/base.json"
|
||||||
|
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# These come from the inventory overridden for connection = local,chroot in base_proxy.yml
|
||||||
|
http_proxy: ""
|
||||||
|
https_proxy: ""
|
||||||
|
socks_proxy: ""
|
||||||
|
ftp_proxy: ""
|
||||||
|
no_proxy: "localhost,127.0.0.1"
|
||||||
|
SSL_CERT_FILE: "/usr/local/etc/ssl/cacert-testforge.pem"
|
||||||
|
RSYNC_PROXY: ""
|
||||||
|
|
||||||
|
BOX_OS_FAMILY: ""
|
||||||
|
BOX_OS_NAME: ""
|
||||||
|
BOX_OS_FLAVOR: ""
|
||||||
|
BOX_DEFAULT_OUTPUT_IF: ""
|
||||||
|
BOX_ALSO_GROUP: "adm"
|
||||||
|
|
||||||
|
# only common to local and vagrant because /mnt/j is remote mounted - need a linux_group
|
||||||
|
BOX_ROOT_PIP_CACHE: "/mnt/o/Cache/Pip"
|
||||||
|
BOX_BOXUSER_PIP_CACHE: "/mnt/o/Cache/Pip"
|
||||||
|
|
||||||
|
HOST_MOUNT_SYMLINKS: []
|
||||||
|
HOST_MOUNT_SYMLINK_CONTENTS: {}
|
||||||
|
|
||||||
|
LXD_TRUST_PASSWORD: sekret
|
||||||
|
|
||||||
|
BOX_HOST_CONTAINER_MOUNTS:
|
||||||
|
- /mnt/l
|
||||||
|
- /mnt/e
|
||||||
|
- /mnt/h
|
||||||
|
- /mnt/i
|
||||||
|
- /mnt/j
|
||||||
|
- /mnt/q
|
||||||
|
- /mnt/w
|
||||||
|
- /mnt/o
|
||||||
|
|
||||||
|
BOX_DOS_SCAN_DIRS:
|
||||||
|
- /mnt/h
|
||||||
|
- /mnt/i
|
||||||
|
- /mnt/j
|
||||||
|
- /mnt/e
|
||||||
|
- /mnt/q
|
||||||
|
- /mnt/w
|
||||||
|
- /mnt/c
|
||||||
|
|
||||||
|
# These will fluctuate with what's been started - it's safe to open them all
|
||||||
|
# FixMe: should these go on no_proxy systematically
|
||||||
|
PRIV_TOR_LOCAL_NETS:
|
||||||
|
- "192.168.56.0/24"
|
||||||
|
|
||||||
|
BOX_ALSO_USERS: []
|
||||||
|
BOX_PYTHON2_MINOR: ""
|
||||||
|
BOX_PYTHON3_MINOR: "3.11"
|
||||||
|
BOX_BASH_SHELL: /bin/bash
|
||||||
|
BOX_IPV6_DISABLE: 1
|
||||||
|
BOX_EMACS_VERSION: 27
|
||||||
|
|
||||||
|
BOX_ROOT_USER: root
|
||||||
|
BOX_ROOT_GROUP: root
|
||||||
|
|
||||||
|
BOX_BYPASS_PROXY_GROUP: tor
|
||||||
|
BOX_FIREWALL_ALLOW_TRANS: false
|
||||||
|
BOX_PROXY_JAVA_NET_PROPERTIES: /etc/java-config-2/current-system-vm/jre/lib/net.properties
|
||||||
|
|
||||||
|
BOX_BASE_FEATURES: []
|
||||||
|
BOX_LOGG_FEATURES: []
|
||||||
|
BOX_KEYS_FEATURES: ['tpm2'] # truecrypt
|
||||||
|
BOX_HARDEN_FEATURES: ['bubblewrap', 'sysctl', 'jabber'] # 'clamscan', firejail
|
||||||
|
# libvirt means 'qemu'
|
||||||
|
BOX_HOSTVMS_FEATURES: []
|
||||||
|
|
||||||
|
BOX_MISP_FEATURES: [] # 'kitchen'
|
||||||
|
BOX_W3AF_FEATURES: [] # 'kitchen'
|
||||||
|
BOX_MISP_GPG_PASS: gpg_pass_to_change_fast
|
||||||
|
|
||||||
|
BOX_timezone: UTC
|
||||||
|
BOX_hwclock_local: false
|
||||||
|
BOX_hwclock_systohc: true
|
||||||
|
BOX_hwclock_hctosys: false
|
||||||
|
|
||||||
|
BOX_PROXY_MODE: ""
|
||||||
|
BOX_DNS_PROXY: dnsmasq
|
||||||
|
BOX_TIME_DAEMON: ntpd
|
||||||
|
BOX_NTP_GROUP: ntp
|
||||||
|
BOX_NET_MANAGER: "networkmanager"
|
||||||
|
BOX_HTTP_PROXY: privoxy
|
||||||
|
|
||||||
|
# toxcore
|
||||||
|
BOX_NBD_DEV: ""
|
||||||
|
BOX_NBD_MP: ""
|
||||||
|
BOX_NBD_FILES: ""
|
||||||
|
BOX_NBD_LOGLEVEL: 20
|
||||||
|
BOX_NBD_PORTAGE_FILE: "{{AGI_NBD_FILES}}/portage-20231223.tar.xz"
|
||||||
|
BOX_NBD_STAGE3_FILE: "{{AGI_NBD_FILES}}/stage3-amd64-openrc-20231217T170203Z.tar.xz"
|
||||||
|
BOX_NBD_KERNEL_DIR: /usr/src/linux
|
||||||
|
BOX_NBD_BASE_PROFILE: openrc
|
||||||
|
BOX_NBD_BASE_DIR: ""
|
||||||
|
BOX_NBD_BASE_QCOW: ""
|
||||||
|
BOX_NBD_BASE_PUBKEY: ""
|
||||||
|
|
||||||
|
# libvirt overlay
|
||||||
|
BOX_NBD_OVERLAY_QCOW: ""
|
||||||
|
BOX_NBD_OVERLAY_DIR: ""
|
||||||
|
BOX_NBD_OVERLAY_BR: ""
|
||||||
|
BOX_NBD_OVERLAY_GB: "20"
|
||||||
|
BOX_NBD_OVERLAY_NAME: ""
|
||||||
|
BOX_NBD_OVERLAY_CPUS: 1
|
||||||
|
BOX_NBD_OVERLAY_RAM: 2048
|
||||||
|
# plaintext
|
||||||
|
BOX_NBD_OVERLAY_PASS: ""
|
||||||
|
BOX_GENTOOIMGR_CONFIGFILE: ""
|
||||||
|
|
||||||
|
# Controls what compression method is used for new-style ansible modules when
|
||||||
|
# they are sent to the remote system. The compression types depend on having
|
||||||
|
# support compiled into both the controller's python and the client's python.
|
||||||
|
# The names should match with the python Zipfile compression types:
|
||||||
|
# * ZIP_STORED (no compression. available everywhere)
|
||||||
|
# * ZIP_DEFLATED (uses zlib, the default)
|
||||||
|
# These values may be set per host via the ansible_module_compression inventory variable.
|
||||||
|
#
|
||||||
|
ansible_module_compression: "ZIP_STORED"
|
||||||
|
ansible_python_interpreter: "/usr/local/bin/python3.sh"
|
||||||
|
|
||||||
|
BOX_ANSIBLE_VERSION: "2.9.22"
|
||||||
|
# Cannot communicate securely with peer: no common encryption algorithm(s).
|
||||||
|
# git.kernel.org/ sslversion = tlsv1.3
|
||||||
|
BOX_TLS_VERSION: "1.3"
|
||||||
|
BOX_SSL_GIT_SSLVERSION: "1.3"
|
||||||
|
|
||||||
|
# unused so far - needed by src/ansible_gentooimgr/gentooimgr/
|
||||||
|
BOX_ARCHITECTURE: amd64
|
||||||
|
BOX_SUBTYPE: -hardened
|
||||||
|
# https://distfiles.gentoo.org/releases/amd64/autobuilds/latest-stage3-amd64-hardened-openrc.txt
|
||||||
|
GENTOO_BASE_STAGE_OPENRC_TXT_URL: "https://distfiles.gentoo.org/releases/{{BOX_ARCHITECTURE}}/autobuilds/latest-stage3-{{BOX_ARCHITECTURE}}{{BOX_SUBTYPE}}-openrc.txt"
|
||||||
|
# plus .gpgsig and .md5sum
|
||||||
|
GENTOO_BASE_PORTAGE_URL: "https://distfiles.gentoo.org/snapshots/portage-latest.tar.xz"
|
||||||
|
BOX_GENTOO_DISTFILES_ARCHIVES: "/i/net/Http/distfiles.gentoo.org/distfiles"
|
||||||
|
#? Gentoo specific?
|
||||||
|
|
||||||
|
# unused so far
|
||||||
|
# missing HOSTVMS_LXD_TRUST_PASSWORD base_passwords_database
|
||||||
|
# /mnt/o/data/TestForge/src/ansible/roles/hostvms/tasks/vms.yml
|
||||||
|
box_passwords_database: "{{ lookup('env', 'USER')}}/Passwords.kdbx"
|
||||||
|
|
||||||
|
BOX_WHONIX_PROXY_HOST: ""
|
||||||
|
BOX_PROXY_FEATURES: []
|
||||||
|
BOX_GPG_SERVER: "keys.gnupg.net"
|
||||||
|
BOX_USR_LIB: lib
|
||||||
|
# if you are on a Gentoo, then / else the mp of a Gentoo if you have one, else ''
|
||||||
|
BOX_GENTOO_FROM_MP: ''
|
||||||
|
|
||||||
|
# bc
|
||||||
|
MOUNT_GENTOO_DISTFILES_ARCHIVES: "{{BOX_GENTOO_DISTFILES_ARCHIVES}}"
|
||||||
|
|
||||||
|
# # These are inventory overridden for connection = chroot in base_proxy.yml
|
||||||
|
# http_proxy: "{{ lookup('env', 'http_proxy')|default('http://127.0.0.1:3128') }}"
|
||||||
|
# https_proxy: "{{ lookup('env', 'https_proxy')|default('http://10.0.2.15:9128') }}"
|
||||||
|
# socks_proxy: "{{ lookup('env', 'socks_proxy')|default('socks5://10.0.2.15:9050') }}"
|
||||||
|
# no_proxy: "{{ lookup('env', 'no_proxy')|default('10.0.2.15,127.0.0.1,localhost') }}"
|
||||||
255
etc/libvirt/qemu/gentoo_bridge.xml
Normal file
255
etc/libvirt/qemu/gentoo_bridge.xml
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
<domain type='kvm' id='20'>
|
||||||
|
<name>gentoo_bridge</name>
|
||||||
|
<metadata>
|
||||||
|
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
|
||||||
|
<libosinfo:os id="http://gentoo.org/gentoo/rolling"/>
|
||||||
|
</libosinfo:libosinfo>
|
||||||
|
</metadata>
|
||||||
|
<memory unit='KiB'>2097152</memory>
|
||||||
|
<currentMemory unit='KiB'>2097152</currentMemory>
|
||||||
|
<vcpu placement='static'>1</vcpu>
|
||||||
|
<resource>
|
||||||
|
<partition>/machine</partition>
|
||||||
|
</resource>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc-q35-7.2'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
<acpi/>
|
||||||
|
<apic/>
|
||||||
|
<vmport state='off'/>
|
||||||
|
</features>
|
||||||
|
<cpu mode='host-passthrough' check='none' migratable='on'/>
|
||||||
|
<clock offset='utc'>
|
||||||
|
<timer name='rtc' tickpolicy='catchup'/>
|
||||||
|
<timer name='pit' tickpolicy='delay'/>
|
||||||
|
<timer name='hpet' present='no'/>
|
||||||
|
</clock>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<pm>
|
||||||
|
<suspend-to-mem enabled='no'/>
|
||||||
|
<suspend-to-disk enabled='no'/>
|
||||||
|
</pm>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||||
|
<disk type='file' device='disk'>
|
||||||
|
<driver name='qemu' type='qcow2'/>
|
||||||
|
<source file='/root/vms/virsh/images/gentoo5.img' index='2'/>
|
||||||
|
<backingStore type='file' index='3'>
|
||||||
|
<format type='qcow2'/>
|
||||||
|
<source file='/g/Linux/net/Http/mirror.init7.net/gentoo/experimental/amd64/openstack/gentoo-openstack-amd64-hardened-latest.qcow2'/>
|
||||||
|
<backingStore/>
|
||||||
|
</backingStore>
|
||||||
|
<target dev='vda' bus='virtio'/>
|
||||||
|
<alias name='virtio-disk0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
|
||||||
|
</disk>
|
||||||
|
<disk type='file' device='cdrom'>
|
||||||
|
<driver name='qemu' type='raw'/>
|
||||||
|
<source file='/root/vms/virsh/images/gentoo5-cidata.img' index='1'/>
|
||||||
|
<backingStore/>
|
||||||
|
<target dev='sda' bus='sata'/>
|
||||||
|
<readonly/>
|
||||||
|
<alias name='sata0-0-0'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
|
||||||
|
<alias name='usb'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='0' model='pcie-root'>
|
||||||
|
<alias name='pcie.0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='1' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='1' port='0x10'/>
|
||||||
|
<alias name='pci.1'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='2' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='2' port='0x11'/>
|
||||||
|
<alias name='pci.2'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='3' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='3' port='0x12'/>
|
||||||
|
<alias name='pci.3'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='4' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='4' port='0x13'/>
|
||||||
|
<alias name='pci.4'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='5' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='5' port='0x14'/>
|
||||||
|
<alias name='pci.5'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='6' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='6' port='0x15'/>
|
||||||
|
<alias name='pci.6'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='7' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='7' port='0x16'/>
|
||||||
|
<alias name='pci.7'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='8' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='8' port='0x17'/>
|
||||||
|
<alias name='pci.8'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='9' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='9' port='0x18'/>
|
||||||
|
<alias name='pci.9'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='10' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='10' port='0x19'/>
|
||||||
|
<alias name='pci.10'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='11' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='11' port='0x1a'/>
|
||||||
|
<alias name='pci.11'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='12' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='12' port='0x1b'/>
|
||||||
|
<alias name='pci.12'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='13' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='13' port='0x1c'/>
|
||||||
|
<alias name='pci.13'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='14' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='14' port='0x1d'/>
|
||||||
|
<alias name='pci.14'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='sata' index='0'>
|
||||||
|
<alias name='ide'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='virtio-serial' index='0'>
|
||||||
|
<alias name='virtio-serial0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='15' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='15' port='0x1e'/>
|
||||||
|
<alias name='pci.15'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x6'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='16' model='pcie-to-pci-bridge'>
|
||||||
|
<model name='pcie-pci-bridge'/>
|
||||||
|
<alias name='pci.16'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<mac address='52:54:00:e8:20:5a'/>
|
||||||
|
<source bridge='virbr0'/>
|
||||||
|
<target dev='vnet17'/>
|
||||||
|
<model type='virtio'/>
|
||||||
|
<alias name='net0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
|
||||||
|
</interface>
|
||||||
|
<serial type='pty'>
|
||||||
|
<source path='/dev/pts/12'/>
|
||||||
|
<target type='isa-serial' port='0'>
|
||||||
|
<model name='isa-serial'/>
|
||||||
|
</target>
|
||||||
|
<alias name='serial0'/>
|
||||||
|
</serial>
|
||||||
|
<console type='pty' tty='/dev/pts/12'>
|
||||||
|
<source path='/dev/pts/12'/>
|
||||||
|
<target type='serial' port='0'/>
|
||||||
|
<alias name='serial0'/>
|
||||||
|
</console>
|
||||||
|
<channel type='spicevmc'>
|
||||||
|
<target type='virtio' name='com.redhat.spice.0' state='disconnected'/>
|
||||||
|
<alias name='channel0'/>
|
||||||
|
<address type='virtio-serial' controller='0' bus='0' port='1'/>
|
||||||
|
</channel>
|
||||||
|
<channel type='unix'>
|
||||||
|
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-20-gentoo5/org.qemu.guest_agent.0'/>
|
||||||
|
<target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/>
|
||||||
|
<alias name='channel1'/>
|
||||||
|
<address type='virtio-serial' controller='0' bus='0' port='2'/>
|
||||||
|
</channel>
|
||||||
|
<input type='tablet' bus='usb'>
|
||||||
|
<alias name='input0'/>
|
||||||
|
<address type='usb' bus='0' port='1'/>
|
||||||
|
</input>
|
||||||
|
<input type='mouse' bus='ps2'>
|
||||||
|
<alias name='input1'/>
|
||||||
|
</input>
|
||||||
|
<input type='keyboard' bus='ps2'>
|
||||||
|
<alias name='input2'/>
|
||||||
|
</input>
|
||||||
|
<graphics type='spice'>
|
||||||
|
<listen type='socket' socket='/var/lib/libvirt/qemu/domain-20-gentoo5/spice.sock'/>
|
||||||
|
<image compression='off'/>
|
||||||
|
</graphics>
|
||||||
|
<sound model='ich9'>
|
||||||
|
<alias name='sound0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
|
||||||
|
</sound>
|
||||||
|
<audio id='1' type='spice'/>
|
||||||
|
<video>
|
||||||
|
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
|
||||||
|
<alias name='video0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
|
||||||
|
</video>
|
||||||
|
<redirdev bus='usb' type='spicevmc'>
|
||||||
|
<alias name='redir0'/>
|
||||||
|
<address type='usb' bus='0' port='2'/>
|
||||||
|
</redirdev>
|
||||||
|
<redirdev bus='usb' type='spicevmc'>
|
||||||
|
<alias name='redir1'/>
|
||||||
|
<address type='usb' bus='0' port='3'/>
|
||||||
|
</redirdev>
|
||||||
|
<watchdog model='i6300esb' action='reset'>
|
||||||
|
<alias name='watchdog0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x10' slot='0x01' function='0x0'/>
|
||||||
|
</watchdog>
|
||||||
|
<memballoon model='virtio'>
|
||||||
|
<alias name='balloon0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
|
||||||
|
</memballoon>
|
||||||
|
<rng model='virtio'>
|
||||||
|
<backend model='random'>/dev/urandom</backend>
|
||||||
|
<alias name='rng0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/>
|
||||||
|
</rng>
|
||||||
|
</devices>
|
||||||
|
<seclabel type='dynamic' model='apparmor' relabel='yes'>
|
||||||
|
<label>libvirt-c7a5d87b-348e-412c-9e81-afce3232ff65</label>
|
||||||
|
<imagelabel>libvirt-c7a5d87b-348e-412c-9e81-afce3232ff65</imagelabel>
|
||||||
|
</seclabel>
|
||||||
|
<seclabel type='dynamic' model='dac' relabel='yes'>
|
||||||
|
<label>+0:+0</label>
|
||||||
|
<imagelabel>+0:+0</imagelabel>
|
||||||
|
</seclabel>
|
||||||
|
</domain>
|
||||||
|
|
||||||
255
etc/libvirt/qemu/gentoo_network.xml
Normal file
255
etc/libvirt/qemu/gentoo_network.xml
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
<domain type='kvm' id='33'>
|
||||||
|
<name>gentoo_network</name>
|
||||||
|
<metadata>
|
||||||
|
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
|
||||||
|
<libosinfo:os id="http://gentoo.org/gentoo/rolling"/>
|
||||||
|
</libosinfo:libosinfo>
|
||||||
|
</metadata>
|
||||||
|
<memory unit='KiB'>2097152</memory>
|
||||||
|
<currentMemory unit='KiB'>2097152</currentMemory>
|
||||||
|
<vcpu placement='static'>1</vcpu>
|
||||||
|
<resource>
|
||||||
|
<partition>/machine</partition>
|
||||||
|
</resource>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc-q35-7.2'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
<acpi/>
|
||||||
|
<apic/>
|
||||||
|
<vmport state='off'/>
|
||||||
|
</features>
|
||||||
|
<cpu mode='host-passthrough' check='none' migratable='on'/>
|
||||||
|
<clock offset='utc'>
|
||||||
|
<timer name='rtc' tickpolicy='catchup'/>
|
||||||
|
<timer name='pit' tickpolicy='delay'/>
|
||||||
|
<timer name='hpet' present='no'/>
|
||||||
|
</clock>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<pm>
|
||||||
|
<suspend-to-mem enabled='no'/>
|
||||||
|
<suspend-to-disk enabled='no'/>
|
||||||
|
</pm>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||||
|
<disk type='file' device='disk'>
|
||||||
|
<driver name='qemu' type='qcow2'/>
|
||||||
|
<source file='/root/vms/virsh/images/gentoo6.img' index='2'/>
|
||||||
|
<backingStore type='file' index='3'>
|
||||||
|
<format type='qcow2'/>
|
||||||
|
<source file='/g/Linux/net/Http/mirror.init7.net/gentoo/experimental/amd64/openstack/gentoo-openstack-amd64-hardened-latest.qcow2'/>
|
||||||
|
<backingStore/>
|
||||||
|
</backingStore>
|
||||||
|
<target dev='vda' bus='virtio'/>
|
||||||
|
<alias name='virtio-disk0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
|
||||||
|
</disk>
|
||||||
|
<disk type='file' device='cdrom'>
|
||||||
|
<driver name='qemu' type='raw'/>
|
||||||
|
<source file='/root/vms/virsh/images/gentoo6-cidata.img' index='1'/>
|
||||||
|
<backingStore/>
|
||||||
|
<target dev='sda' bus='sata'/>
|
||||||
|
<readonly/>
|
||||||
|
<alias name='sata0-0-0'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
|
||||||
|
<alias name='usb'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='0' model='pcie-root'>
|
||||||
|
<alias name='pcie.0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='1' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='1' port='0x10'/>
|
||||||
|
<alias name='pci.1'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='2' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='2' port='0x11'/>
|
||||||
|
<alias name='pci.2'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='3' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='3' port='0x12'/>
|
||||||
|
<alias name='pci.3'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='4' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='4' port='0x13'/>
|
||||||
|
<alias name='pci.4'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='5' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='5' port='0x14'/>
|
||||||
|
<alias name='pci.5'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='6' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='6' port='0x15'/>
|
||||||
|
<alias name='pci.6'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='7' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='7' port='0x16'/>
|
||||||
|
<alias name='pci.7'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='8' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='8' port='0x17'/>
|
||||||
|
<alias name='pci.8'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='9' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='9' port='0x18'/>
|
||||||
|
<alias name='pci.9'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='10' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='10' port='0x19'/>
|
||||||
|
<alias name='pci.10'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='11' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='11' port='0x1a'/>
|
||||||
|
<alias name='pci.11'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='12' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='12' port='0x1b'/>
|
||||||
|
<alias name='pci.12'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='13' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='13' port='0x1c'/>
|
||||||
|
<alias name='pci.13'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='14' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='14' port='0x1d'/>
|
||||||
|
<alias name='pci.14'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='sata' index='0'>
|
||||||
|
<alias name='ide'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='virtio-serial' index='0'>
|
||||||
|
<alias name='virtio-serial0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='15' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='15' port='0x1e'/>
|
||||||
|
<alias name='pci.15'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x6'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='16' model='pcie-to-pci-bridge'>
|
||||||
|
<model name='pcie-pci-bridge'/>
|
||||||
|
<alias name='pci.16'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<interface type='network'>
|
||||||
|
<mac address='52:54:00:1d:9c:6f'/>
|
||||||
|
<source network='Whonix-External' portid='7748c5ca-d57c-4913-9d00-aa7884b87666' bridge='virbr1'/>
|
||||||
|
<target dev='vnet29'/>
|
||||||
|
<model type='virtio'/>
|
||||||
|
<alias name='net0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
|
||||||
|
</interface>
|
||||||
|
<serial type='pty'>
|
||||||
|
<source path='/dev/pts/0'/>
|
||||||
|
<target type='isa-serial' port='0'>
|
||||||
|
<model name='isa-serial'/>
|
||||||
|
</target>
|
||||||
|
<alias name='serial0'/>
|
||||||
|
</serial>
|
||||||
|
<console type='pty' tty='/dev/pts/0'>
|
||||||
|
<source path='/dev/pts/0'/>
|
||||||
|
<target type='serial' port='0'/>
|
||||||
|
<alias name='serial0'/>
|
||||||
|
</console>
|
||||||
|
<channel type='spicevmc'>
|
||||||
|
<target type='virtio' name='com.redhat.spice.0' state='disconnected'/>
|
||||||
|
<alias name='channel0'/>
|
||||||
|
<address type='virtio-serial' controller='0' bus='0' port='1'/>
|
||||||
|
</channel>
|
||||||
|
<channel type='unix'>
|
||||||
|
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-33-gentoo6/org.qemu.guest_agent.0'/>
|
||||||
|
<target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/>
|
||||||
|
<alias name='channel1'/>
|
||||||
|
<address type='virtio-serial' controller='0' bus='0' port='2'/>
|
||||||
|
</channel>
|
||||||
|
<input type='tablet' bus='usb'>
|
||||||
|
<alias name='input0'/>
|
||||||
|
<address type='usb' bus='0' port='1'/>
|
||||||
|
</input>
|
||||||
|
<input type='mouse' bus='ps2'>
|
||||||
|
<alias name='input1'/>
|
||||||
|
</input>
|
||||||
|
<input type='keyboard' bus='ps2'>
|
||||||
|
<alias name='input2'/>
|
||||||
|
</input>
|
||||||
|
<graphics type='spice'>
|
||||||
|
<listen type='socket' socket='/var/lib/libvirt/qemu/domain-33-gentoo6/spice.sock'/>
|
||||||
|
<image compression='off'/>
|
||||||
|
</graphics>
|
||||||
|
<sound model='ich9'>
|
||||||
|
<alias name='sound0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
|
||||||
|
</sound>
|
||||||
|
<audio id='1' type='spice'/>
|
||||||
|
<video>
|
||||||
|
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
|
||||||
|
<alias name='video0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
|
||||||
|
</video>
|
||||||
|
<redirdev bus='usb' type='spicevmc'>
|
||||||
|
<alias name='redir0'/>
|
||||||
|
<address type='usb' bus='0' port='2'/>
|
||||||
|
</redirdev>
|
||||||
|
<redirdev bus='usb' type='spicevmc'>
|
||||||
|
<alias name='redir1'/>
|
||||||
|
<address type='usb' bus='0' port='3'/>
|
||||||
|
</redirdev>
|
||||||
|
<watchdog model='i6300esb' action='reset'>
|
||||||
|
<alias name='watchdog0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x10' slot='0x01' function='0x0'/>
|
||||||
|
</watchdog>
|
||||||
|
<memballoon model='virtio'>
|
||||||
|
<alias name='balloon0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
|
||||||
|
</memballoon>
|
||||||
|
<rng model='virtio'>
|
||||||
|
<backend model='random'>/dev/urandom</backend>
|
||||||
|
<alias name='rng0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/>
|
||||||
|
</rng>
|
||||||
|
</devices>
|
||||||
|
<seclabel type='dynamic' model='apparmor' relabel='yes'>
|
||||||
|
<label>libvirt-069ed70a-e004-4120-9987-81a4a2c650d2</label>
|
||||||
|
<imagelabel>libvirt-069ed70a-e004-4120-9987-81a4a2c650d2</imagelabel>
|
||||||
|
</seclabel>
|
||||||
|
<seclabel type='dynamic' model='dac' relabel='yes'>
|
||||||
|
<label>+0:+0</label>
|
||||||
|
<imagelabel>+0:+0</imagelabel>
|
||||||
|
</seclabel>
|
||||||
|
</domain>
|
||||||
|
|
||||||
80
hosts.yml
80
hosts.yml
@@ -79,7 +79,6 @@ all:
|
|||||||
BOX_USR_LIB: lib
|
BOX_USR_LIB: lib
|
||||||
BOX_DEFAULT_OUTPUT_IF: wlan4
|
BOX_DEFAULT_OUTPUT_IF: wlan4
|
||||||
BOX_PROXY_MODE: selektor
|
BOX_PROXY_MODE: selektor
|
||||||
BOX_WHONIX_PROXY_HOST: ""
|
|
||||||
BOX_GENTOO_DISTFILES_ARCHIVES: "/i/net/Http/distfiles.gentoo.org/distfiles"
|
BOX_GENTOO_DISTFILES_ARCHIVES: "/i/net/Http/distfiles.gentoo.org/distfiles"
|
||||||
BOX_PROXY_JAVA_NET_PROPERTIES: /etc/java-config-2/current-system-vm/jre/lib/net.properties
|
BOX_PROXY_JAVA_NET_PROPERTIES: /etc/java-config-2/current-system-vm/jre/lib/net.properties
|
||||||
# /usr/lib/jvm/openjdk-bin-*/conf/net.properties
|
# /usr/lib/jvm/openjdk-bin-*/conf/net.properties
|
||||||
@@ -110,7 +109,6 @@ all:
|
|||||||
|
|
||||||
BOX_JAVA_NET_PROPERTIES: /etc/java-11-openjdk/net.properties
|
BOX_JAVA_NET_PROPERTIES: /etc/java-11-openjdk/net.properties
|
||||||
|
|
||||||
BOX_WHONIX_PROXY_HOST: ""
|
|
||||||
BOX_PROXY_MODE: tor
|
BOX_PROXY_MODE: tor
|
||||||
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
|
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
|
||||||
|
|
||||||
@@ -126,13 +124,13 @@ all:
|
|||||||
|
|
||||||
hosts:
|
hosts:
|
||||||
|
|
||||||
gentoo1:
|
gentoo_overlay-2:
|
||||||
|
|
||||||
ansible_remote_addr: "gentoo1"
|
ansible_remote_addr: "gentoo_overlay-2"
|
||||||
ansible_host: "gentoo1"
|
ansible_host: "gentoo_overlay-2"
|
||||||
ansible_ssh_user: "gentoo"
|
ansible_ssh_user: "gentoo"
|
||||||
BOX_SERVICE_MGR: "openrc"
|
BOX_SERVICE_MGR: "openrc"
|
||||||
BOX_HOST_NAME: "gentoo1"
|
BOX_HOST_NAME: "gentoo_overlay-2"
|
||||||
BOX_USER_NAME: "gentoo"
|
BOX_USER_NAME: "gentoo"
|
||||||
BOX_USER_GROUP: "adm"
|
BOX_USER_GROUP: "adm"
|
||||||
BOX_ALSO_GROUP: "adm"
|
BOX_ALSO_GROUP: "adm"
|
||||||
@@ -140,6 +138,7 @@ all:
|
|||||||
BOX_OS_NAME: Gentoo
|
BOX_OS_NAME: Gentoo
|
||||||
BOX_OS_FAMILY: Gentoo
|
BOX_OS_FAMILY: Gentoo
|
||||||
BOX_OS_FLAVOR: "Gentoo"
|
BOX_OS_FLAVOR: "Gentoo"
|
||||||
|
BOX_PROXY_MODE: nat
|
||||||
BOX_USR_LIB: lib64
|
BOX_USR_LIB: lib64
|
||||||
BOX_DEFAULT_OUTPUT_IF: eth0
|
BOX_DEFAULT_OUTPUT_IF: eth0
|
||||||
BOX_PYTHON2_MINOR: ""
|
BOX_PYTHON2_MINOR: ""
|
||||||
@@ -151,8 +150,42 @@ all:
|
|||||||
BOX_ALSO_USERS:
|
BOX_ALSO_USERS:
|
||||||
- gentoo
|
- gentoo
|
||||||
BOX_BASE_FEATURES: []
|
BOX_BASE_FEATURES: []
|
||||||
BOX_TOXCORE_FEATURES: ['libvirt', 'docker']
|
BOX_TOXCORE_FEATURES: ['libvirt'] # ', 'docker
|
||||||
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
|
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
|
||||||
|
BOX_NBD_OVERLAY_NAME: "gentoo_overlay-2" # was gentoo1
|
||||||
|
BOX_NBD_OVERLAY_BASE: "/a/tmp/GentooImgr/gentoo_base-2.qcow2"
|
||||||
|
BOX_NBD_OVERLAY_QCOW: "/a/tmp/GentooImgr/create-vm/images/gentoo_overlay-2.img"
|
||||||
|
|
||||||
|
gentoo_vm-2:
|
||||||
|
# vm no overlay, copy of the overlay's base
|
||||||
|
ansible_remote_addr: "gentoo_vm-2"
|
||||||
|
ansible_host: "gentoo_vm-2"
|
||||||
|
ansible_ssh_user: "gentoo"
|
||||||
|
BOX_SERVICE_MGR: "openrc"
|
||||||
|
BOX_HOST_NAME: "gentoo_vm-2"
|
||||||
|
BOX_USER_NAME: "gentoo"
|
||||||
|
BOX_USER_GROUP: "adm"
|
||||||
|
BOX_ALSO_GROUP: "adm"
|
||||||
|
BOX_USER_HOME: "/home/gentoo"
|
||||||
|
BOX_OS_NAME: Gentoo
|
||||||
|
BOX_OS_FAMILY: Gentoo
|
||||||
|
BOX_OS_FLAVOR: "Gentoo"
|
||||||
|
BOX_PROXY_MODE: nat
|
||||||
|
BOX_USR_LIB: lib64
|
||||||
|
BOX_DEFAULT_OUTPUT_IF: eth0
|
||||||
|
BOX_PYTHON2_MINOR: ""
|
||||||
|
BOX_PYTHON3_MINOR: "3.11"
|
||||||
|
BASE_PORTAGE_PYTHON_MINOR: 3.11
|
||||||
|
BOX_HOST_CONTAINER_MOUNTS: []
|
||||||
|
BOX_GENTOO_DISTFILES_ARCHIVES: "/mnt/linuxPen19/usr/portage/distfiles"
|
||||||
|
BOX_PROXY_JAVA_NET_PROPERTIES: /etc/java-config-2/current-system-vm/jre/lib/net.properties
|
||||||
|
BOX_ALSO_USERS:
|
||||||
|
- gentoo
|
||||||
|
BOX_BASE_FEATURES: []
|
||||||
|
BOX_TOXCORE_FEATURES: ['libvirt'] # ', 'docker
|
||||||
|
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
|
||||||
|
BOX_VM_NAME: "gentoo_vm-2" # was gentoo1
|
||||||
|
BOX_VM_QCOW: "/o/var/lib/libvirt/images/gentoo_vm-2.qcow2"
|
||||||
|
|
||||||
ubuntu18.04:
|
ubuntu18.04:
|
||||||
# /mnt
|
# /mnt
|
||||||
@@ -186,12 +219,13 @@ all:
|
|||||||
# proxy from environment
|
# proxy from environment
|
||||||
# ansible_ssh_extra_args: "-o StrictHostKeyChecking=no"
|
# ansible_ssh_extra_args: "-o StrictHostKeyChecking=no"
|
||||||
# ansible_ssh_host: "127.0.0.1"
|
# ansible_ssh_host: "127.0.0.1"
|
||||||
BOX_ROOT_GROUP: root
|
BOX_NBD_OVERLAY_EXTERNAL: "0.0.0.0"
|
||||||
BOX_PROXY_MODE: client
|
http_proxy: "http://{{BOX_NBD_OVERLAY_EXTERNAL}}:3128"
|
||||||
http_proxy: "http://127.0.0.1:3128"
|
https_proxy: "http://{{BOX_NBD_OVERLAY_EXTERNAL}}:9128"
|
||||||
https_proxy: "http://127.0.0.1:9128"
|
socks_proxy: "socks5://{{BOX_NBD_OVERLAY_EXTERNAL}}:9050"
|
||||||
socks_proxy: "socks5://127.0.0.1:9050"
|
ftp_proxy: ""
|
||||||
no_proxy: "localhost,127.0.0.1,127.0.0.1"
|
RSYNC_PROXY : "{{BOX_NBD_OVERLAY_EXTERNAL}}:3128"
|
||||||
|
no_proxy: "localhost,127.0.0.1"
|
||||||
|
|
||||||
linux_chroot_group :
|
linux_chroot_group :
|
||||||
|
|
||||||
@@ -259,9 +293,8 @@ all:
|
|||||||
# for a non-root login: ansible_ssh_extra_args: "--userspec=foo:adm"
|
# for a non-root login: ansible_ssh_extra_args: "--userspec=foo:adm"
|
||||||
vars: # linux_unix_group
|
vars: # linux_unix_group
|
||||||
# toxcore
|
# toxcore
|
||||||
BOX_NBD_DEV: nbd3
|
BOX_NBD_DEV: nbd1
|
||||||
BOX_NBD_MP: /mnt/gentoo
|
BOX_NBD_MP: /mnt/gentoo
|
||||||
BOX_NBD_OVERLAY_NAME: "gentoo1"
|
|
||||||
BOX_NBD_FILES: "/i/data/Agile/tmp/Topics/GentooImgr"
|
BOX_NBD_FILES: "/i/data/Agile/tmp/Topics/GentooImgr"
|
||||||
BOX_NBD_PORTAGE_FILE: "{{AGI_NBD_FILES}}/portage-20231223.tar.xz"
|
BOX_NBD_PORTAGE_FILE: "{{AGI_NBD_FILES}}/portage-20231223.tar.xz"
|
||||||
BOX_NBD_STAGE3_FILE: "{{AGI_NBD_FILES}}/stage3-amd64-openrc-20231217T170203Z.tar.xz"
|
BOX_NBD_STAGE3_FILE: "{{AGI_NBD_FILES}}/stage3-amd64-openrc-20231217T170203Z.tar.xz"
|
||||||
@@ -269,7 +302,6 @@ all:
|
|||||||
BOX_NBD_BASE_PROFILE: openrc
|
BOX_NBD_BASE_PROFILE: openrc
|
||||||
BOX_NBD_BASE_DIR: "/a/tmp/GentooImgr"
|
BOX_NBD_BASE_DIR: "/a/tmp/GentooImgr"
|
||||||
BOX_NBD_BASE_QCOW: "{{BOX_NBD_BASE_DIR}}/gentoo.qcow2"
|
BOX_NBD_BASE_QCOW: "{{BOX_NBD_BASE_DIR}}/gentoo.qcow2"
|
||||||
BOX_NBD_OVERLAY_QCOW: "/o/var/lib/libvirt/images/gentoo1.qcow2"
|
|
||||||
BOX_NBD_BASE_PUBKEY: "/root/.ssh/id_rsa-ansible.pub"
|
BOX_NBD_BASE_PUBKEY: "/root/.ssh/id_rsa-ansible.pub"
|
||||||
|
|
||||||
# libvirt overlay
|
# libvirt overlay
|
||||||
@@ -279,22 +311,21 @@ all:
|
|||||||
BOX_NBD_OVERLAY_CPUS: 1
|
BOX_NBD_OVERLAY_CPUS: 1
|
||||||
BOX_NBD_OVERLAY_RAM: 2048
|
BOX_NBD_OVERLAY_RAM: 2048
|
||||||
BOX_NBD_OVERLAY_BR: virbr1
|
BOX_NBD_OVERLAY_BR: virbr1
|
||||||
# unused?
|
BOX_NBD_OVERLAY_SUBNET: 10.0.2.0
|
||||||
BOX_NBD_OVERLAY_NETWORK: default
|
BOX_NBD_OVERLAY_NETWORK: External
|
||||||
# plaintext
|
# plaintext
|
||||||
BOX_NBD_OVERLAY_PASS: "gentoo"
|
BOX_NBD_OVERLAY_PASS: "gentoo"
|
||||||
BOX_GENTOOIMGR_CONFIGFILE: "/g/Agile/tmp/Topics/GentooImgr/base.json"
|
BOX_GENTOOIMGR_CONFIGFILE: "/g/Agile/tmp/Topics/GentooImgr/base.json"
|
||||||
|
|
||||||
|
|
||||||
vars:
|
vars:
|
||||||
# These come from the inventory overridden for connection = local,chroot in base_proxy.yml
|
# These come from the inventory overridden for connection = local,chroot in base_proxy.yml
|
||||||
http_proxy: ""
|
http_proxy: ""
|
||||||
https_proxy: ""
|
https_proxy: ""
|
||||||
socks_proxy: ""
|
socks_proxy: ""
|
||||||
ftp_proxy: ""
|
ftp_proxy: ""
|
||||||
|
RSYNC_PROXY: ""
|
||||||
no_proxy: "localhost,127.0.0.1"
|
no_proxy: "localhost,127.0.0.1"
|
||||||
SSL_CERT_FILE: "/usr/local/etc/ssl/cacert-testforge.pem"
|
SSL_CERT_FILE: "/usr/local/etc/ssl/cacert-testforge.pem"
|
||||||
RSYNC_PROXY: ""
|
|
||||||
|
|
||||||
BOX_OS_FAMILY: ""
|
BOX_OS_FAMILY: ""
|
||||||
BOX_OS_NAME: ""
|
BOX_OS_NAME: ""
|
||||||
@@ -431,6 +462,7 @@ all:
|
|||||||
|
|
||||||
BOX_WHONIX_PROXY_HOST: ""
|
BOX_WHONIX_PROXY_HOST: ""
|
||||||
BOX_PROXY_FEATURES: []
|
BOX_PROXY_FEATURES: []
|
||||||
|
# get this from grep '^keyserver ' /root/.gnupg/dirmngr.conf instead
|
||||||
BOX_GPG_SERVER: "keys.gnupg.net"
|
BOX_GPG_SERVER: "keys.gnupg.net"
|
||||||
BOX_USR_LIB: lib
|
BOX_USR_LIB: lib
|
||||||
# if you are on a Gentoo, then / else the mp of a Gentoo if you have one, else ''
|
# if you are on a Gentoo, then / else the mp of a Gentoo if you have one, else ''
|
||||||
@@ -440,7 +472,7 @@ all:
|
|||||||
MOUNT_GENTOO_DISTFILES_ARCHIVES: "{{BOX_GENTOO_DISTFILES_ARCHIVES}}"
|
MOUNT_GENTOO_DISTFILES_ARCHIVES: "{{BOX_GENTOO_DISTFILES_ARCHIVES}}"
|
||||||
|
|
||||||
# # These are inventory overridden for connection = chroot in base_proxy.yml
|
# # These are inventory overridden for connection = chroot in base_proxy.yml
|
||||||
# http_proxy: "{{ lookup('env', 'http_proxy')|default('http://127.0.0.1:3128') }}"
|
# HTTP_PROXY: "{{ lookup('env', 'http_proxy')|default('http://127.0.0.1:3128') }}"
|
||||||
# https_proxy: "{{ lookup('env', 'https_proxy')|default('http://10.0.2.15:9128') }}"
|
# HTTPS_PROXY: "{{ lookup('env', 'https_proxy')|default('http://10.0.2.15:9128') }}"
|
||||||
# socks_proxy: "{{ lookup('env', 'socks_proxy')|default('socks5://10.0.2.15:9050') }}"
|
# SOCKS_PROXY: "{{ lookup('env', 'socks_proxy')|default('socks5://10.0.2.15:9050') }}"
|
||||||
# no_proxy: "{{ lookup('env', 'no_proxy')|default('10.0.2.15,127.0.0.1,localhost') }}"
|
# NO_PROXY: "{{ lookup('env', 'no_proxy')|default('10.0.2.15,127.0.0.1,localhost') }}"
|
||||||
|
|||||||
@@ -38,6 +38,17 @@ DOCUMENTATION = """
|
|||||||
default: qemu:///system
|
default: qemu:///system
|
||||||
vars:
|
vars:
|
||||||
- name: ansible_libvirt_uri
|
- name: ansible_libvirt_uri
|
||||||
|
timeout:
|
||||||
|
description: timeout for libvirt to connect to access the VM
|
||||||
|
ini:
|
||||||
|
- section: defaults
|
||||||
|
key: libvirt_timeout
|
||||||
|
env:
|
||||||
|
- name: ANSIBLE_LIBVIRT_TIMEOUT
|
||||||
|
vars:
|
||||||
|
- name: timeout
|
||||||
|
default: 5
|
||||||
|
required: false
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
@@ -59,7 +70,7 @@ from os.path import exists, getsize
|
|||||||
|
|
||||||
display = Display()
|
display = Display()
|
||||||
|
|
||||||
iMAX_WAIT = 10 # sec.
|
iMAX_WAIT = 15 # sec.
|
||||||
|
|
||||||
REQUIRED_CAPABILITIES = [
|
REQUIRED_CAPABILITIES = [
|
||||||
{'enabled': True, 'name': 'guest-exec', 'success-response': True},
|
{'enabled': True, 'name': 'guest-exec', 'success-response': True},
|
||||||
@@ -84,6 +95,7 @@ class Connection(ConnectionBase):
|
|||||||
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
|
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
|
||||||
|
|
||||||
self._host = self._play_context.remote_addr
|
self._host = self._play_context.remote_addr
|
||||||
|
self._play_context = play_context
|
||||||
|
|
||||||
# Windows operates differently from a POSIX connection/shell plugin,
|
# Windows operates differently from a POSIX connection/shell plugin,
|
||||||
# we need to set various properties to ensure SSH on Windows continues
|
# we need to set various properties to ensure SSH on Windows continues
|
||||||
@@ -93,6 +105,7 @@ class Connection(ConnectionBase):
|
|||||||
self.always_pipeline_modules = True
|
self.always_pipeline_modules = True
|
||||||
self.module_implementation_preferences = ('.ps1', '.exe', '')
|
self.module_implementation_preferences = ('.ps1', '.exe', '')
|
||||||
self.allow_executable = False
|
self.allow_executable = False
|
||||||
|
self._timeout = self.get_option('timeout', iMAX_WAIT)
|
||||||
|
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
''' connect to the virtual machine; nothing to do here '''
|
''' connect to the virtual machine; nothing to do here '''
|
||||||
@@ -116,7 +129,7 @@ class Connection(ConnectionBase):
|
|||||||
raise AnsibleConnectionFailure(to_native(err))
|
raise AnsibleConnectionFailure(to_native(err))
|
||||||
|
|
||||||
request_cap = json.dumps({'execute': 'guest-info'})
|
request_cap = json.dumps({'execute': 'guest-info'})
|
||||||
response_cap = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_cap, 5, 0))
|
response_cap = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_cap, self._timeout, 0))
|
||||||
self.capabilities = response_cap['return']['supported_commands']
|
self.capabilities = response_cap['return']['supported_commands']
|
||||||
self._display.vvvvv(u"GUEST CAPABILITIES: {0}".format(self.capabilities), host=self._host)
|
self._display.vvvvv(u"GUEST CAPABILITIES: {0}".format(self.capabilities), host=self._host)
|
||||||
missing_caps = []
|
missing_caps = []
|
||||||
@@ -130,11 +143,13 @@ class Connection(ConnectionBase):
|
|||||||
display.vvv(u"ESTABLISH {0} CONNECTION".format(self.transport), host=self._host)
|
display.vvv(u"ESTABLISH {0} CONNECTION".format(self.transport), host=self._host)
|
||||||
self._connected = True
|
self._connected = True
|
||||||
|
|
||||||
def exec_command(self, cmd, in_data=None, sudoable=True):
|
def exec_command(self, cmd, in_data=None, sudoable=True, timeout=None):
|
||||||
""" execute a command on the virtual machine host """
|
""" execute a command on the virtual machine host """
|
||||||
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
||||||
|
|
||||||
self._display.vvv(u"EXEC {0}".format(cmd), host=self._host)
|
self._display.vvv(u"EXEC {0}".format(cmd), host=self._host)
|
||||||
|
if timeout is None:
|
||||||
|
timeout = self._timeout
|
||||||
|
|
||||||
cmd_args_list = shlex.split(to_native(cmd, errors='surrogate_or_strict'))
|
cmd_args_list = shlex.split(to_native(cmd, errors='surrogate_or_strict'))
|
||||||
|
|
||||||
@@ -148,6 +163,15 @@ class Connection(ConnectionBase):
|
|||||||
cmd_args_list = self._shell._encode_script(cmd, as_list=True, strict_mode=False, preserve_rc=False)
|
cmd_args_list = self._shell._encode_script(cmd, as_list=True, strict_mode=False, preserve_rc=False)
|
||||||
|
|
||||||
# TODO(odyssey4me):
|
# TODO(odyssey4me):
|
||||||
|
cmd_list = cmd_args_list[0]
|
||||||
|
if self._play_context.become and \
|
||||||
|
self._play_context.become_user not in ['', 'root']:
|
||||||
|
cmd_args_list = [self._play_context.become_exe, '-u',
|
||||||
|
self._play_context.become_user] + \
|
||||||
|
self._play_context.become_flags.split(' ') + \
|
||||||
|
cmd_args_list
|
||||||
|
# pl = f"cmd_args_list={cmd_args_list} become_flags={self._play_context.become_flags}"
|
||||||
|
# display.vv(u"BECOMME {0} CONNECTION".format(pl), host=self._host)
|
||||||
# Implement buffering much like the other connection plugins
|
# Implement buffering much like the other connection plugins
|
||||||
# Implement 'env' for the environment settings
|
# Implement 'env' for the environment settings
|
||||||
# Implement 'input-data' for whatever it might be useful for
|
# Implement 'input-data' for whatever it might be useful for
|
||||||
@@ -161,20 +185,21 @@ class Connection(ConnectionBase):
|
|||||||
}
|
}
|
||||||
request_exec_json = json.dumps(request_exec)
|
request_exec_json = json.dumps(request_exec)
|
||||||
|
|
||||||
display.vvv("GA send: {0}".format(request_exec_json), host=self._host)
|
display.vvvv("GA send: {0}".format(request_exec_json), host=self._host)
|
||||||
# sys.stderr.write("GA send: {0}\n".format(request_exec_json))
|
# sys.stderr.write("GA send: {0}\n".format(request_exec_json))
|
||||||
command_start = time.clock_gettime(time.CLOCK_MONOTONIC)
|
command_start = time.clock_gettime(time.CLOCK_MONOTONIC)
|
||||||
# TODO(odyssey4me):
|
# TODO(odyssey4me):
|
||||||
# Add timeout parameter
|
# Add timeout parameter
|
||||||
|
flags = 0
|
||||||
try:
|
try:
|
||||||
result_exec = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_exec_json, 5, 0))
|
result_exec = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_exec_json, timeout, flags))
|
||||||
except libvirt.libvirtError as err:
|
except libvirt.libvirtError as err:
|
||||||
self._display.vv(u"ERROR: libvirtError EXEC TO {0}\n{1}".format(self._virt_uri, to_native(err)), host=self._host)
|
self._display.vv(u"ERROR: libvirtError EXEC TO {0}\n{1}".format(self._virt_uri, to_native(err)), host=self._host)
|
||||||
sys.stderr.write(u"ERROR: libvirtError EXEC TO {0}\n{1}\n".format(self._virt_uri, to_native(err)))
|
sys.stderr.write(u"ERROR: libvirtError EXEC TO {0}\n{1}\n".format(self._virt_uri, to_native(err)))
|
||||||
self._connected = False
|
self._connected = False
|
||||||
raise AnsibleConnectionFailure(to_native(err))
|
raise AnsibleConnectionFailure(to_native(err))
|
||||||
|
|
||||||
display.vvv(u"GA return: {0}".format(result_exec), host=self._host)
|
display.vvvv(u"GA return: {0}".format(result_exec), host=self._host)
|
||||||
|
|
||||||
request_status = {
|
request_status = {
|
||||||
'execute': 'guest-exec-status',
|
'execute': 'guest-exec-status',
|
||||||
@@ -184,15 +209,17 @@ class Connection(ConnectionBase):
|
|||||||
}
|
}
|
||||||
request_status_json = json.dumps(request_status)
|
request_status_json = json.dumps(request_status)
|
||||||
|
|
||||||
display.vvv(u"GA send: {0}".format(request_status_json), host=self._host)
|
display.vvvv(u"GA send: {0}".format(request_status_json), host=self._host)
|
||||||
|
|
||||||
# TODO(odyssey4me):
|
# TODO(odyssey4me):
|
||||||
# Work out a better way to wait until the command has exited
|
# Work out a better way to wait until the command has exited
|
||||||
max_time = iMAX_WAIT + time.clock_gettime(time.CLOCK_MONOTONIC)
|
max_time = timeout + time.clock_gettime(time.CLOCK_MONOTONIC)
|
||||||
result_status = {
|
result_status = {
|
||||||
'return': dict(exited=False),
|
'return': dict(exited=False),
|
||||||
}
|
}
|
||||||
while not result_status['return']['exited']:
|
i=0
|
||||||
|
while not result_status['return']['exited'] and i < 20:
|
||||||
|
i = i + 1
|
||||||
# Wait for 5% of the time already elapsed
|
# Wait for 5% of the time already elapsed
|
||||||
sleep_time = (time.clock_gettime(time.CLOCK_MONOTONIC) - command_start) * (5 / 100)
|
sleep_time = (time.clock_gettime(time.CLOCK_MONOTONIC) - command_start) * (5 / 100)
|
||||||
if sleep_time < 0.0002:
|
if sleep_time < 0.0002:
|
||||||
@@ -200,7 +227,7 @@ class Connection(ConnectionBase):
|
|||||||
elif sleep_time > 1:
|
elif sleep_time > 1:
|
||||||
sleep_time = 1
|
sleep_time = 1
|
||||||
time.sleep(sleep_time)
|
time.sleep(sleep_time)
|
||||||
result_status = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_status_json, 5, 0))
|
result_status = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_status_json, self._timeout, 0))
|
||||||
if time.clock_gettime(time.CLOCK_MONOTONIC) > max_time:
|
if time.clock_gettime(time.CLOCK_MONOTONIC) > max_time:
|
||||||
err = 'timeout'
|
err = 'timeout'
|
||||||
self._display.vv(u"ERROR: libvirtError EXEC TO {0}\n{1}".format(self._virt_uri, to_native(err)), host=self._host)
|
self._display.vv(u"ERROR: libvirtError EXEC TO {0}\n{1}".format(self._virt_uri, to_native(err)), host=self._host)
|
||||||
@@ -208,12 +235,12 @@ class Connection(ConnectionBase):
|
|||||||
self._connected = False
|
self._connected = False
|
||||||
raise AnsibleConnectionFailure(to_native(err))
|
raise AnsibleConnectionFailure(to_native(err))
|
||||||
|
|
||||||
display.vvv(u"GA return: {0}".format(result_status), host=self._host)
|
display.vvvv(u"GA return: {0}".format(result_status), host=self._host)
|
||||||
|
|
||||||
while not result_status['return']['exited']:
|
while not result_status['return']['exited']:
|
||||||
result_status = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_status_json, 5, 0))
|
result_status = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_status_json, self._timeout, 0))
|
||||||
|
|
||||||
display.vvv(u"GA return: {0}".format(result_status), host=self._host)
|
display.vvvv(u"GA return: {0}".format(result_status), host=self._host)
|
||||||
|
|
||||||
if result_status['return'].get('out-data'):
|
if result_status['return'].get('out-data'):
|
||||||
stdout = base64.b64decode(result_status['return']['out-data'])
|
stdout = base64.b64decode(result_status['return']['out-data'])
|
||||||
@@ -254,7 +281,7 @@ class Connection(ConnectionBase):
|
|||||||
|
|
||||||
display.vvv(u"GA send: {0}".format(request_handle_json), host=self._host)
|
display.vvv(u"GA send: {0}".format(request_handle_json), host=self._host)
|
||||||
|
|
||||||
result_handle = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_handle_json, 5, 0))
|
result_handle = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_handle_json, self._timeout, 0))
|
||||||
|
|
||||||
display.vvv(u"GA return: {0}".format(result_handle), host=self._host)
|
display.vvv(u"GA return: {0}".format(result_handle), host=self._host)
|
||||||
|
|
||||||
@@ -274,7 +301,7 @@ class Connection(ConnectionBase):
|
|||||||
|
|
||||||
display.vvvvv(u"GA send: {0}".format(request_write_json), host=self._host)
|
display.vvvvv(u"GA send: {0}".format(request_write_json), host=self._host)
|
||||||
|
|
||||||
result_write = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_write_json, 5, 0))
|
result_write = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_write_json, self._timeout, 0))
|
||||||
|
|
||||||
display.vvvvv(u"GA return: {0}".format(result_write), host=self._host)
|
display.vvvvv(u"GA return: {0}".format(result_write), host=self._host)
|
||||||
|
|
||||||
@@ -292,7 +319,7 @@ class Connection(ConnectionBase):
|
|||||||
|
|
||||||
display.vvv(u"GA send: {0}".format(request_close_json), host=self._host)
|
display.vvv(u"GA send: {0}".format(request_close_json), host=self._host)
|
||||||
|
|
||||||
result_close = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_close_json, 5, 0))
|
result_close = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_close_json, self._timeout, 0))
|
||||||
|
|
||||||
display.vvv(u"GA return: {0}".format(result_close), host=self._host)
|
display.vvv(u"GA return: {0}".format(result_close), host=self._host)
|
||||||
|
|
||||||
@@ -312,7 +339,7 @@ class Connection(ConnectionBase):
|
|||||||
|
|
||||||
display.vvv(u"GA send: {0}".format(request_handle_json), host=self._host)
|
display.vvv(u"GA send: {0}".format(request_handle_json), host=self._host)
|
||||||
|
|
||||||
result_handle = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_handle_json, 5, 0))
|
result_handle = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_handle_json, self._timeout, 0))
|
||||||
|
|
||||||
display.vvv(u"GA return: {0}".format(result_handle), host=self._host)
|
display.vvv(u"GA return: {0}".format(result_handle), host=self._host)
|
||||||
|
|
||||||
@@ -329,11 +356,11 @@ class Connection(ConnectionBase):
|
|||||||
|
|
||||||
with open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb+') as out_file:
|
with open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb+') as out_file:
|
||||||
try:
|
try:
|
||||||
result_read = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_read_json, 5, 0))
|
result_read = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_read_json, self._timeout, 0))
|
||||||
display.vvvvv(u"GA return: {0}".format(result_read), host=self._host)
|
display.vvvvv(u"GA return: {0}".format(result_read), host=self._host)
|
||||||
out_file.write(base64.b64decode(result_read['return']['buf-b64']))
|
out_file.write(base64.b64decode(result_read['return']['buf-b64']))
|
||||||
while not result_read['return']['eof']:
|
while not result_read['return']['eof']:
|
||||||
result_read = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_read_json, 5, 0))
|
result_read = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_read_json, self._timeout, 0))
|
||||||
display.vvvvv(u"GA return: {0}".format(result_read), host=self._host)
|
display.vvvvv(u"GA return: {0}".format(result_read), host=self._host)
|
||||||
out_file.write(base64.b64decode(result_read['return']['buf-b64']))
|
out_file.write(base64.b64decode(result_read['return']['buf-b64']))
|
||||||
|
|
||||||
@@ -351,7 +378,7 @@ class Connection(ConnectionBase):
|
|||||||
|
|
||||||
display.vvv(u"GA send: {0}".format(request_close_json), host=self._host)
|
display.vvv(u"GA send: {0}".format(request_close_json), host=self._host)
|
||||||
|
|
||||||
result_close = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_close_json, 5, 0))
|
result_close = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_close_json, self._timeout, 0))
|
||||||
|
|
||||||
display.vvv(u"GA return: {0}".format(result_close), host=self._host)
|
display.vvv(u"GA return: {0}".format(result_close), host=self._host)
|
||||||
|
|
||||||
|
|||||||
@@ -163,7 +163,8 @@ def run_module():
|
|||||||
action=dict(type='str', required=True),
|
action=dict(type='str', required=True),
|
||||||
loglevel=dict(type='int', required=False, default=logging.INFO),
|
loglevel=dict(type='int', required=False, default=logging.INFO),
|
||||||
threads=dict(type='int', required=False, default=1),
|
threads=dict(type='int', required=False, default=1),
|
||||||
config=dict(type='path', default=def_config, required=True),
|
# Module error: required and default are mutually exclusive for config
|
||||||
|
config=dict(type='path', default=def_config),
|
||||||
profile=dict(type='str', required=False),
|
profile=dict(type='str', required=False),
|
||||||
kernel_dir=dict(type='path', required=False),
|
kernel_dir=dict(type='path', required=False),
|
||||||
portage=dict(type='path', required=False),
|
portage=dict(type='path', required=False),
|
||||||
@@ -215,9 +216,8 @@ def run_module():
|
|||||||
# is stdout already in result? how can it be?
|
# is stdout already in result? how can it be?
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
result['message'] = str(e)
|
result['message'] = str(e)
|
||||||
e = traceback.print_exc()
|
result['original_message'] = f"{traceback.print_exc()}"
|
||||||
if e: result['original_message'] += f"{e}"
|
module.fail_json(msg=f'Exception {e.__class__}', **result)
|
||||||
module.fail_json(msg='Exception', **result)
|
|
||||||
else:
|
else:
|
||||||
result['message'] = str(retval)
|
result['message'] = str(retval)
|
||||||
|
|
||||||
|
|||||||
45
pyproject.toml
Normal file
45
pyproject.toml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
[project]
|
||||||
|
name = "stem_examples"
|
||||||
|
version = "2023.12"
|
||||||
|
description = "examples of using stem"
|
||||||
|
authors = [{ name = "emdee", email = "Ingvar@gitgub.com" } ]
|
||||||
|
requires-python = ">=3.6"
|
||||||
|
dependencies = [
|
||||||
|
'stem',
|
||||||
|
]
|
||||||
|
keywords = ["stem", "python3", "tor"]
|
||||||
|
classifiers = [
|
||||||
|
"License :: OSI Approved",
|
||||||
|
"Operating System :: POSIX :: BSD :: FreeBSD",
|
||||||
|
"Operating System :: POSIX :: Linux",
|
||||||
|
"Programming Language :: Python :: 3 :: Only",
|
||||||
|
"Programming Language :: Python :: 3.6",
|
||||||
|
"Programming Language :: Python :: 3.7",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
|
"Programming Language :: Python :: Implementation :: CPython",
|
||||||
|
]
|
||||||
|
dynamic = ["version", "readme", ] # cannot be dynamic ['license']
|
||||||
|
scripts = { exclude_badExits = "stem_examples.exclude_badExits:iMain" }
|
||||||
|
|
||||||
|
#[project.license]
|
||||||
|
#file = "LICENSE.md"
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
repository = "https://git.plastiras.org/emdee/stem_examples"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools >= 61.0"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[tool.setuptools.dynamic]
|
||||||
|
version = {attr = "stem_examples.__version__"}
|
||||||
|
readme = {file = ["README.md", "exclude_badExits.md"]}
|
||||||
|
|
||||||
|
[tool.setuptools]
|
||||||
|
packages = ["stem_examples"]
|
||||||
|
|
||||||
|
#[tool.setuptools.packages.find]
|
||||||
|
#where = "src"
|
||||||
@@ -14,7 +14,7 @@ AGI_PROXY_MODE: "{{PROXY_MODE|default('')}}"
|
|||||||
|
|
||||||
AGI_use_local_kernel: false
|
AGI_use_local_kernel: false
|
||||||
AGI_install_disklabel: msdos
|
AGI_install_disklabel: msdos
|
||||||
AGI_install_timezone: UTC
|
AGI_install_timezone: "{{ BASE_TIMEZONE|default('Etc/UTC') }}"
|
||||||
AGI_install_locales:
|
AGI_install_locales:
|
||||||
- en_US ISO-8859-1
|
- en_US ISO-8859-1
|
||||||
- en_US.UTF-8 UTF-8
|
- en_US.UTF-8 UTF-8
|
||||||
@@ -28,9 +28,95 @@ AGI_install_network_interfaces:
|
|||||||
config: dhcp
|
config: dhcp
|
||||||
AGI_container_disk: /dev/vda
|
AGI_container_disk: /dev/vda
|
||||||
|
|
||||||
|
AGI_install_syslog_daemon: syslog-ng # sysklogd
|
||||||
|
AGI_install_cron_daemon: cronie #
|
||||||
|
AGI_install_bootloader: syslinux # grub:2
|
||||||
|
|
||||||
|
AGI_syslinux_date: 2023_09_30
|
||||||
|
AGI_syslinux_vmlinuz: vmlinuz-6.1.52-pentoo
|
||||||
|
AGI_syslinux_initramfs: initramfs-pentoo-x86_64-6.1.52-pentoo
|
||||||
|
AGI_syslinux_vga: "0x037f" # 0x37f?
|
||||||
|
AGI_syslinux_ipv6disable: 1
|
||||||
|
AGI_syslinux_cmdline:
|
||||||
|
- rootfstype=ext2
|
||||||
|
# fsck should NOT be done by the bootloader
|
||||||
|
- rd.skipfsck=1
|
||||||
|
# remove this if you want IPV6
|
||||||
|
- ipv6.disable=1
|
||||||
|
# this is required I think
|
||||||
|
- console=ttyS0
|
||||||
|
- lang=en
|
||||||
|
- keymap=us
|
||||||
|
- vga={{AGI_syslinux_vga}}
|
||||||
|
# this is required I think
|
||||||
|
- text
|
||||||
|
# these may not all be needed or useful in a container
|
||||||
|
# - pti=on
|
||||||
|
# - iommu=pt
|
||||||
|
# - amd_iommu=on
|
||||||
|
# - intel_iommu=on
|
||||||
|
# - debug
|
||||||
|
|
||||||
|
# remove the unused ones:
|
||||||
|
AGI_install_syslinux_c32:
|
||||||
|
- vesa.c32
|
||||||
|
- vesainfo.c32
|
||||||
|
- vesamenu.c32
|
||||||
|
- cat.c32
|
||||||
|
- chain.c32
|
||||||
|
- cmd.c32
|
||||||
|
- cmenu.c32
|
||||||
|
- cptime.c32
|
||||||
|
- cpu.c32
|
||||||
|
- cpuid.c32
|
||||||
|
- cpuidtest.c32
|
||||||
|
- debug.c32
|
||||||
|
- dir.c32
|
||||||
|
- disk.c32
|
||||||
|
- dmi.c32
|
||||||
|
- dmitest.c32
|
||||||
|
- elf.c32
|
||||||
|
- ethersel.c32
|
||||||
|
- gfxboot.c32
|
||||||
|
- gpxecmd.c32
|
||||||
|
- hdt.c32
|
||||||
|
- host.c32
|
||||||
|
- ifcpu.c32
|
||||||
|
- ifcpu64.c32
|
||||||
|
- ifmemdsk.c32
|
||||||
|
- ifplop.c32
|
||||||
|
- kbdmap.c32
|
||||||
|
- kontron_wdt.c32
|
||||||
|
- ldlinux.c32
|
||||||
|
- lfs.c32
|
||||||
|
- libcom32.c32
|
||||||
|
- libgpl.c32
|
||||||
|
- liblua.c32
|
||||||
|
- libmenu.c32
|
||||||
|
- libutil.c32
|
||||||
|
- linux.c32
|
||||||
|
- ls.c32
|
||||||
|
- mboot.c32
|
||||||
|
- meminfo.c32
|
||||||
|
- menu.c32
|
||||||
|
- pci.c32
|
||||||
|
- pcitest.c32
|
||||||
|
- pmload.c32
|
||||||
|
- poweroff.c32
|
||||||
|
- prdhcp.c32
|
||||||
|
- pwd.c32
|
||||||
|
- pxechn.c32
|
||||||
|
- reboot.c32
|
||||||
|
- rosh.c32
|
||||||
|
- sanboot.c32
|
||||||
|
- sdi.c32
|
||||||
|
- sysdump.c32
|
||||||
|
- syslinux.c32
|
||||||
|
- vpdtest.c32
|
||||||
|
- whichsys.c32
|
||||||
|
|
||||||
|
|
||||||
AGI_install_root_password: root
|
AGI_install_root_password: root
|
||||||
AGI_install_syslog_daemon: syslog-ng # app-admin/sysklogd
|
|
||||||
AGI_install_cron_daemon: sys-process/cronie
|
|
||||||
|
|
||||||
AGI_bootstrap_mountpoints: []
|
AGI_bootstrap_mountpoints: []
|
||||||
|
|
||||||
|
|||||||
171
roles/ansible-gentoo_install/files/firewall.conf
Normal file
171
roles/ansible-gentoo_install/files/firewall.conf
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
# Generated by iptables-save v1.8.5 on Wed Nov 4 01:14:37 2020
|
||||||
|
*mangle
|
||||||
|
:PREROUTING ACCEPT [0:0]
|
||||||
|
:INPUT ACCEPT [0:0]
|
||||||
|
:FORWARD ACCEPT [0:0]
|
||||||
|
:OUTPUT ACCEPT [0:0]
|
||||||
|
:POSTROUTING ACCEPT [0:0]
|
||||||
|
:LIBVIRT_PRT - [0:0]
|
||||||
|
-A INPUT -j LOG --log-prefix "iptables_libvirt mangle-i: " --log-uid
|
||||||
|
-A POSTROUTING -j LIBVIRT_PRT
|
||||||
|
COMMIT
|
||||||
|
# Completed on Wed Nov 4 01:14:37 2020
|
||||||
|
|
||||||
|
# Generated by iptables-save v1.8.5 on Wed Nov 4 01:14:37 2020
|
||||||
|
*nat
|
||||||
|
:PREROUTING ACCEPT [0:0]
|
||||||
|
:INPUT ACCEPT [0:0]
|
||||||
|
:OUTPUT ACCEPT [0:0]
|
||||||
|
:POSTROUTING ACCEPT [0:0]
|
||||||
|
:LIBVIRT_PRT - [0:0]
|
||||||
|
|
||||||
|
# was ! -o lo
|
||||||
|
-A OUTPUT -o wlan6 -p tcp --dport 53 -m tcp -j DNAT --to-destination 127.0.0.1:53
|
||||||
|
-A OUTPUT -o wlan6 -p udp --dport 53 -m udp -j DNAT --to-destination 127.0.0.1:53
|
||||||
|
|
||||||
|
# .onion mapped addresses redirection to Tor.
|
||||||
|
-A OUTPUT -d 172.16.0.0/12 -p tcp -m tcp -j DNAT --to-destination 127.0.0.1:9040
|
||||||
|
## Log.
|
||||||
|
-A INPUT -j LOG --log-prefix "iptables_libvirt_nat-i: " --log-uid
|
||||||
|
-A POSTROUTING -j LIBVIRT_PRT
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 -d 224.0.0.0/24 -j RETURN
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 -d 255.255.255.255/32 -j RETURN
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 ! -d 10.0.2.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 ! -d 10.0.2.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 ! -d 10.0.2.0/24 -j MASQUERADE
|
||||||
|
COMMIT
|
||||||
|
# Completed on Wed Nov 4 01:14:37 2020
|
||||||
|
# Generated by iptables-save v1.8.5 on Wed Nov 4 01:14:37 2020
|
||||||
|
*filter
|
||||||
|
:INPUT ACCEPT [0:0]
|
||||||
|
:FORWARD DROP [0:0]
|
||||||
|
:OUTPUT DROP [0:0]
|
||||||
|
:LIBVIRT_FWI - [0:0]
|
||||||
|
:LIBVIRT_FWO - [0:0]
|
||||||
|
:LIBVIRT_FWX - [0:0]
|
||||||
|
:LIBVIRT_INP - [0:0]
|
||||||
|
:LIBVIRT_OUT - [0:0]
|
||||||
|
|
||||||
|
## DROP PACKETS WITH INCOMING FRAGMENTS. THIS ATTACK ONCE RESULTED IN KERNEL PANICS
|
||||||
|
-A INPUT -f -j DROP
|
||||||
|
## DROP INCOMING MALFORMED XMAS PACKETS
|
||||||
|
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP
|
||||||
|
## DROP INCOMING MALFORMED NULL PACKETS
|
||||||
|
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP
|
||||||
|
|
||||||
|
-A INPUT -i lo -j ACCEPT
|
||||||
|
## Traffic on the loopback interface is accepted.
|
||||||
|
-A INPUT -i lo -j ACCEPT
|
||||||
|
## Established incoming connections are accepted. RELATED?
|
||||||
|
-A INPUT -m state --state ESTABLISHED -j ACCEPT
|
||||||
|
### this is required for outgoing pings
|
||||||
|
-A INPUT -i wlan6 -p icmp -j LOG --log-prefix "iptables_icmp_ACCEPT-i: " --log-uid
|
||||||
|
-A INPUT -i wlan6 -p icmp -j ACCEPT
|
||||||
|
|
||||||
|
# let dhcp through? - YES
|
||||||
|
-A INPUT -i wlan6 -p udp -m udp --sport 137 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p udp -m udp --sport 138 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p udp -m udp --sport 139 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p tcp --sport 9055 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p tcp --sport 9054 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p tcp --sport 9053 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p tcp --sport 9051 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p udp --sport 53 -j ACCEPT
|
||||||
|
|
||||||
|
# SRC=0.0.0.0 DST=255.255.255.255 PROTO=UDP SPT=68 DPT=67
|
||||||
|
-A INPUT -j LOG --log-prefix "iptables_libvirt_jLIBVIRT_INP-i: " --log-uid
|
||||||
|
# -A INPUT -i wlan6 -p udp -j DROP
|
||||||
|
-A INPUT -i wlan6 -j DROP
|
||||||
|
|
||||||
|
-A INPUT -j LIBVIRT_INP
|
||||||
|
|
||||||
|
-A FORWARD -j LIBVIRT_FWX
|
||||||
|
-A FORWARD -j LIBVIRT_FWI
|
||||||
|
-A FORWARD -j LIBVIRT_FWO
|
||||||
|
#d#-A OUTPUT -o wlan6 -p icmp -j LOG --log-prefix iptables_icmp_ACCEPT-o: --log-uid
|
||||||
|
## Traffic on the loopback interface is accepted.
|
||||||
|
-A OUTPUT -o lo -j ACCEPT
|
||||||
|
|
||||||
|
## Existing connections are accepted.
|
||||||
|
-A OUTPUT -m state --state ESTABLISHED -j ACCEPT
|
||||||
|
-A OUTPUT -o wlan6 -p icmp -j LOG --log-prefix "iptables_icmp_ACCEPT-o: " --log-uid
|
||||||
|
-A OUTPUT -o wlan6 -p icmp -j ACCEPT
|
||||||
|
# st-routers.mcast.net.
|
||||||
|
-A OUTPUT -o wlan6 -p udp -d 224.0.0.0/8 -j REJECT
|
||||||
|
|
||||||
|
## Accept outgoing connections to local network, Whonix-Workstation and VirtualBox,
|
||||||
|
-A OUTPUT -d 192.168.1.0/24 -j ACCEPT
|
||||||
|
-A OUTPUT -d 10.0.2.0/24 -j ACCEPT
|
||||||
|
|
||||||
|
# gateway
|
||||||
|
#-A OUTPUT -d 10.0.2.0/24 -j ACCEPT
|
||||||
|
|
||||||
|
-A OUTPUT -o wlan6 -d 10.16.238.0/24 -j ACCEPT
|
||||||
|
-A OUTPUT -o wlan6 -d 10.0.0.0/8 -j DROP
|
||||||
|
-A OUTPUT -o wlan6 -d 172.16.0.0/12 -j DROP
|
||||||
|
#-A OUTPUT -o wlan6 -d 192.168.0.0/16 -j DROP
|
||||||
|
-A OUTPUT -o wlan6 -d 224.0.0.0/4 -j DROP
|
||||||
|
-A OUTPUT -o wlan6 -d 240.0.0.0/5 -j DROP
|
||||||
|
|
||||||
|
# The ntp user is allowed to connect to services listening on the ntp port...
|
||||||
|
# If root runs ntpdate manually you will see requests to port 53 UID=0
|
||||||
|
#-A OUTPUT -o wlan6 -m owner --gid-owner 226 -p udp --dport 123 -j LOG --log-uid --log-prefix "iptables_123_ACCEPT-o: "
|
||||||
|
-A OUTPUT -o wlan6 -m owner --gid-owner 226 -p UDP --dport 123 -j ACCEPT
|
||||||
|
-A OUTPUT -o wlan6 -m owner --uid-owner 0 -p UDP --dport 123 -j ACCEPT
|
||||||
|
#-A OUTPUT -o wlan6 -m tcp -p TCP --dport 22 -j LOG --log-uid --log-prefix "IPTABLES_ssh_REJECT: "
|
||||||
|
-A OUTPUT -o wlan6 -m tcp -p TCP --dport 22 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
#test-A OUTPUT -o virbr1 -m tcp -p TCP --dport 22 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o wlan6 -m owner -p tcp --gid-owner 216 -j ACCEPT
|
||||||
|
-A OUTPUT -o wlan6 -m owner --gid-owner 1 -j ACCEPT
|
||||||
|
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 22 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9028 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9028 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9040 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9040 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9050 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9050 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9053 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9053 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m udp -p udp --dport 9053 -j ACCEPT
|
||||||
|
-A OUTPUT -j LIBVIRT_OUT
|
||||||
|
-A LIBVIRT_FWI -o virbr1 -j LOG --log-uid --log-prefix "IPTABLES_FWI_REJECT-o: "
|
||||||
|
-A LIBVIRT_FWI -o virbr2 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
|
||||||
|
-A LIBVIRT_FWI -d 10.0.2.0/24 -o virbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_FWI -o virbr1 -j LOG --log-uid --log-prefix "IPTABLES_FWI_REJECT-o: "
|
||||||
|
-A LIBVIRT_FWI -o virbr1 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
|
||||||
|
-A LIBVIRT_FWO -i virbr2 -j LOG --log-uid --log-prefix "IPTABLES_FWO_REJECT-i: "
|
||||||
|
-A LIBVIRT_FWO -i virbr2 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
|
||||||
|
-A LIBVIRT_FWO -s 10.0.2.0/24 -i virbr1 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_FWO -i virbr1 -j LOG --log-uid --log-prefix "IPTABLES_FWO_REJECT-i: "
|
||||||
|
-A LIBVIRT_FWO -i virbr1 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
|
||||||
|
-A LIBVIRT_FWX -i virbr2 -o virbr2 -j ACCEPT
|
||||||
|
-A LIBVIRT_FWX -i virbr1 -o virbr1 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_INP -i virbr2 -p udp -m udp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr2 -p tcp -m tcp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr2 -p udp -m udp --dport 67 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr2 -p tcp -m tcp --dport 67 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_INP -i virbr1 -p udp -m udp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr1 -p tcp -m tcp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr1 -p udp -m udp --dport 67 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr1 -p tcp -m tcp --dport 67 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_OUT -o virbr2 -p udp -m udp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr2 -p tcp -m tcp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr2 -p udp -m udp --dport 68 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr2 -p tcp -m tcp --dport 68 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_OUT -o virbr1 -p udp -m udp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr1 -p tcp -m tcp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr1 -p udp -m udp --dport 68 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr1 -p tcp -m tcp --dport 68 -j ACCEPT
|
||||||
|
COMMIT
|
||||||
|
# Completed on Wed Nov 4 01:14:37 2020
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
|
|
||||||
---
|
|
||||||
- name: "DEBUG: ansible-gentoo_install local"
|
|
||||||
debug:
|
|
||||||
verbosity: 0
|
|
||||||
msg: "DEBUG: ansible-gentoo_install local BOX_NBD_DEV={{BOX_NBD_DEV}}"
|
|
||||||
check_mode: no
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- "'{{BOX_NBD_DEV}}' != ''"
|
|
||||||
when: ansible_connection in ['local', 'chroot']
|
|
||||||
|
|
||||||
- set_fact:
|
|
||||||
AGI_use_local_kernel: true
|
|
||||||
when:
|
|
||||||
- ansible_distribution == 'Gentoo' or BOX_GENTOO_FROM_MP not in ['/', '']
|
|
||||||
|
|
||||||
- set_fact:
|
|
||||||
AGI_PROXY_MODE: "{{PROXY_MODE|default('')}}"
|
|
||||||
when:
|
|
||||||
- PROXY_MODE|default('') != ''
|
|
||||||
check_mode: no
|
|
||||||
|
|
||||||
- set_fact:
|
|
||||||
AGI_PROXY_MODE: "{{BOX_PROXY_MODE|default('')}}"
|
|
||||||
when:
|
|
||||||
- AGI_PROXY_MODE == ''
|
|
||||||
check_mode: no
|
|
||||||
|
|
||||||
- block:
|
|
||||||
|
|
||||||
- name: check for mounted disk
|
|
||||||
shell: |
|
|
||||||
grep '/dev/{{AGI_NBD_DEV}}' /proc/mounts && exit 0
|
|
||||||
ps ax | grep -v grep | \
|
|
||||||
grep "qemu-nbd.*/dev/nbd.*{{BOX_NBD_BASE_QCOW}}" && \
|
|
||||||
echo WARN looks like theres an active nbd mount of \
|
|
||||||
"${BOX_NBD_BASE_QCOW}" && exit 1
|
|
||||||
exit 2
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
register: check_mounted_disk
|
|
||||||
check_mode: no
|
|
||||||
|
|
||||||
- name: partition if disk not mounted
|
|
||||||
fail:
|
|
||||||
msg: "looks like theres an active nbd mount of {{BOX_NBD_BASE_QCOW}}"
|
|
||||||
when:
|
|
||||||
- check_mounted_disk.rc == 1
|
|
||||||
check_mode: no
|
|
||||||
|
|
||||||
- name: partition if disk not mounted or active
|
|
||||||
include: disk.yml
|
|
||||||
when:
|
|
||||||
- check_mounted_disk.rc > 1
|
|
||||||
check_mode: no
|
|
||||||
|
|
||||||
- name: mount root partition
|
|
||||||
mount:
|
|
||||||
name: "{{AGI_NBD_MP}}"
|
|
||||||
src: "{{ AGI_install_disk }}p3"
|
|
||||||
fstype: ext4
|
|
||||||
state: mounted
|
|
||||||
check_mode: false
|
|
||||||
|
|
||||||
- name: create /boot mountpoint
|
|
||||||
file:
|
|
||||||
path: "{{AGI_NBD_MP}}/boot"
|
|
||||||
state: directory
|
|
||||||
check_mode: false
|
|
||||||
|
|
||||||
- name: mount boot partition
|
|
||||||
mount:
|
|
||||||
name: "{{AGI_NBD_MP}}/boot"
|
|
||||||
src: "{{ AGI_install_disk }}p1"
|
|
||||||
fstype: ext2
|
|
||||||
state: mounted
|
|
||||||
check_mode: false
|
|
||||||
|
|
||||||
- include: tarball.yml
|
|
||||||
- include: copy.yml
|
|
||||||
when: AGI_use_local_kernel
|
|
||||||
|
|
||||||
- name: mount distfiles
|
|
||||||
delegate_to: localhost
|
|
||||||
shell: |
|
|
||||||
[ -d "{{MOUNT_GENTOO_DISTFILES_ARCHIVES}}" ] || exit 1
|
|
||||||
grep {{MOUNT_GENTOO_DISTFILES_ARCHIVES}} /proc/mounts && exit 0
|
|
||||||
[ -d {{AGI_NBD_MP}}/usr/portage/ ] || exit 0
|
|
||||||
[ -d {{AGI_NBD_MP}}/usr/portage/distfiles ] || mkdir {{AGI_NBD_MP}}/usr/portage/distfiles
|
|
||||||
mount --bind {{MOUNT_GENTOO_DISTFILES_ARCHIVES}} {{AGI_NBD_MP}}/usr/portage/distfiles
|
|
||||||
when:
|
|
||||||
- "MOUNT_GENTOO_DISTFILES_ARCHIVES != ''"
|
|
||||||
- "AGI_NBD_MP != ''"
|
|
||||||
|
|
||||||
- include: chroot.yml
|
|
||||||
|
|
||||||
delegate_to: localhost
|
|
||||||
when: ansible_connection in ['chroot', 'local'] # libvirt?
|
|
||||||
|
|
||||||
- block:
|
|
||||||
|
|
||||||
- name: check chroot wrapper installed
|
|
||||||
shell: |
|
|
||||||
[ -x /var/tmp/chroot_wrapper.sh ] || exit 1
|
|
||||||
df /mnt/gentoo || exit 2
|
|
||||||
/var/tmp/chroot_wrapper.sh /bin/df | grep /mnt/gentoo && exit 4
|
|
||||||
exit 0
|
|
||||||
register: chroot_out
|
|
||||||
check_mode: false
|
|
||||||
|
|
||||||
- name: enable chroot wrapper
|
|
||||||
set_fact:
|
|
||||||
ansible_shell_executable: /var/tmp/chroot_wrapper.sh
|
|
||||||
old_ansible_python_interpreter: "{{ansible_python_interpreter}}"
|
|
||||||
ansible_python_interpreter: "/usr/bin/python3"
|
|
||||||
check_mode: false
|
|
||||||
|
|
||||||
when: ansible_connection in ['local']
|
|
||||||
|
|
||||||
- block:
|
|
||||||
|
|
||||||
- include: portage.yml
|
|
||||||
- include: misc.yml
|
|
||||||
|
|
||||||
- include: network.yml
|
|
||||||
|
|
||||||
- include: kernel.yml
|
|
||||||
when: not AGI_use_local_kernel
|
|
||||||
|
|
||||||
- include: bootloader.yml
|
|
||||||
- include: daemons.yml
|
|
||||||
|
|
||||||
# - include: finish.yml
|
|
||||||
|
|
||||||
check_mode: false
|
|
||||||
when:
|
|
||||||
- "ansible_connection in ['chroot'] or (ansible_connection in ['local'] or and chroot_out.rc|default(1) == 0)"
|
|
||||||
rescue:
|
|
||||||
- debug:
|
|
||||||
msg: "ERROR: error during chroot execution"
|
|
||||||
|
|
||||||
- name: disable chroot wrapper
|
|
||||||
set_fact:
|
|
||||||
ansible_shell_executable: /bin/sh
|
|
||||||
ansible_python_interpreter: "{{old_ansible_python_interpreter}}"
|
|
||||||
when:
|
|
||||||
- "ansible_connection in ['local'] and chroot_out.rc|default(1) == 0"
|
|
||||||
check_mode: false
|
|
||||||
|
|
||||||
- name: unmount filesystems
|
|
||||||
mount:
|
|
||||||
name: "{{AGI_NBD_MP}}/{{ item }}"
|
|
||||||
state: unmounted
|
|
||||||
with_items:
|
|
||||||
- proc
|
|
||||||
- sys
|
|
||||||
- dev/pts
|
|
||||||
- dev/shm
|
|
||||||
- dev
|
|
||||||
- boot
|
|
||||||
- ''
|
|
||||||
loop_control:
|
|
||||||
label: "{{AGI_NBD_MP}}/{{ item }}"
|
|
||||||
when:
|
|
||||||
- "ansible_connection in ['local'] and chroot_out.rc|default(1) == 0"
|
|
||||||
- false # leave it mounted for testing
|
|
||||||
|
|
||||||
- name: dismount any other mounts
|
|
||||||
shell: |
|
|
||||||
if [ -z "{{MOUNT_GENTOO_DISTFILES_ARCHIVES}}" ] && \
|
|
||||||
[ -d "{{MOUNT_GENTOO_DISTFILES_ARCHIVES}}" ] && \
|
|
||||||
grep {{MOUNT_GENTOO_DISTFILES_ARCHIVES}} /proc/mounts ; then
|
|
||||||
umount {{MOUNT_GENTOO_DISTFILES_ARCHIVES}}
|
|
||||||
fi
|
|
||||||
df -a | grep "{{AGI_NBD_MP}}" | sed -e 's/.* //' | tac | while read elt;do
|
|
||||||
umount $elt
|
|
||||||
done
|
|
||||||
base_chroot_unbind.bash "{{AGI_NBD_MP}}"
|
|
||||||
when:
|
|
||||||
- "ansible_connection in ['chroot'] or chroot_out.rc|default(1) == 0"
|
|
||||||
- false # leave it mounted for testing
|
|
||||||
@@ -7,58 +7,160 @@
|
|||||||
|
|
||||||
- name: test we are in the chroot
|
- name: test we are in the chroot
|
||||||
shell: |
|
shell: |
|
||||||
df | grep {{AGI_NBD_MP}} && exit 1
|
df | grep {{AGI_install_disk}} && exit 1
|
||||||
check_mode: false
|
check_mode: false
|
||||||
|
|
||||||
- name: install grub
|
- name: install grub or syslinx
|
||||||
portage:
|
portage:
|
||||||
package: sys-boot/grub:2
|
package: sys-boot/{{AGI_install_bootloader}}
|
||||||
state: installed
|
state: installed
|
||||||
|
|
||||||
- name: install grub to MBR
|
- block:
|
||||||
command: grub-install {{ AGI_install_disk }}
|
|
||||||
args:
|
|
||||||
creates: /boot/grub
|
|
||||||
|
|
||||||
- name: generate grub config
|
- name: setup syslinux
|
||||||
shell: grub-mkconfig -o /boot/grub/grub.cfg
|
shell: |
|
||||||
args:
|
[ -d /boot/syslinux ] || mkdir /boot/syslinux
|
||||||
creates: /boot/grub/grub.cfg
|
[ ! -d /usr/share/syslinux/ ] || \
|
||||||
|
for elt in {{' '.join(AGI_install_syslinux_c32)}}; do
|
||||||
|
[ -f /boot/syslinux/$elt ] && continue
|
||||||
|
cp -np /usr/share/syslinux/$elt /boot/syslinux
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
|
|
||||||
- name: edit grub config
|
- name: setup syslinux.cfg
|
||||||
shell: |
|
template: |
|
||||||
[ -f /etc/default/grub.dst ] || cp -p /etc/default/grub /etc/default/grub.dst
|
dest: /boot/syslinux/syslinux.cfg
|
||||||
a=$(cat /proc/cmdline | sed -e 's/ BOOT_IMAGE=[^ ]*/ /' \
|
src: boot/syslinux/syslinux.cfg
|
||||||
-e 's/ initrd=[^ ]*/ /'
|
force: no
|
||||||
-e 's/ resume=[^ ]*/ /'
|
newline_sequence: '\r\n'
|
||||||
-e 's/ root=[^ ]*/ /')
|
owner: root
|
||||||
sed -e "s/^#*GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"$a\"/" \
|
mode: '0644'
|
||||||
-i /etc/default/grub
|
|
||||||
grub-script-check /etc/default/grub
|
|
||||||
|
|
||||||
|
- name: do syslinux install manually
|
||||||
|
shell: |
|
||||||
|
df | grep {{AGI_install_disk}} && \
|
||||||
|
echo ERROR: somethings wrong - {{AGI_install_disk}} isnt mounted
|
||||||
|
&& exit 1
|
||||||
|
# should unmount it?
|
||||||
|
dd if={{AGI_install_disk}}p1 count=440 bs=1|strings|grep SYSLINUX
|
||||||
|
[ $? -eq 0 ] && exit 0
|
||||||
|
echo HALT: YOU MUST INSTALL THE MBR YOURSELF - do this
|
||||||
|
echo dd if=/usr/share/syslinux/mbr.bin of={{AGI_install_disk}}p1 count=440 bs=1 conv=notrunc
|
||||||
|
echo HALT: YOU MUST INSTALL SYSLINUX YOURSELF - do this
|
||||||
|
syslinux -d syslinux --install {{AGI_install_disk}}p1
|
||||||
|
exit 999
|
||||||
|
register: syslinux_out
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: install syslinux install manually
|
||||||
|
fail:
|
||||||
|
msg: "HALT: install syslinux install manually"
|
||||||
|
when: syslinux_out.rc != 0
|
||||||
|
|
||||||
|
when: AGI_install_bootloader == 'syslinux'
|
||||||
|
|
||||||
|
- block:
|
||||||
|
|
||||||
|
- name: install grub to MBR
|
||||||
|
command: grub-install {{ AGI_install_disk }}
|
||||||
|
args:
|
||||||
|
creates: /boot/grub
|
||||||
|
|
||||||
|
- name: generate grub config
|
||||||
|
shell: grub-mkconfig -o /boot/grub/grub.cfg
|
||||||
|
args:
|
||||||
|
creates: /boot/grub/grub.cfg
|
||||||
|
|
||||||
|
- name: edit grub config
|
||||||
|
shell: |
|
||||||
|
[ -f /etc/default/grub.dst ] || cp -p /etc/default/grub /etc/default/grub.dst
|
||||||
|
a=$(cat /proc/cmdline | sed -e 's/ BOOT_IMAGE=[^ ]*/ /' \
|
||||||
|
-e 's/ initrd=[^ ]*/ /'
|
||||||
|
-e 's/ resume=[^ ]*/ /'
|
||||||
|
-e 's/ root=[^ ]*/ /')
|
||||||
|
sed -e "s/^#*GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"$a\"/" \
|
||||||
|
-i /etc/default/grub
|
||||||
|
grub-script-check /etc/default/grub
|
||||||
|
|
||||||
|
- name: roles/ansible-gentoo_install/tasks/
|
||||||
|
shell: |
|
||||||
|
LINE="rd.skipfsck=1 ipv6.disable=1 console=ttys0 lang=en keymap=us "
|
||||||
|
# LINE="$LINE pti=on doscsi iommu=pt amd_iommu=on debugfs=off efi=disable_early_pci_dma extra_latent_entropy init_on_free=1 kvm.nx_huge_pages=force l1tf=full,force mce=0 mds=full,nosmt nosmt=force page_alloc.shuffle=1 pti=on random.trust_cpu=off slab_nomerge slub_debug=FZ spec_store_bypass_disable=on spectre_v2=on tsx_async_abort=full,nosmt vsyscall=none "
|
||||||
|
LINE="$LINE intel_iommu=on vga=0x315 text
|
||||||
|
df | grep /boot || mount /dev/vda1 /boot
|
||||||
|
[ -d /boot/grub ] || exit 2
|
||||||
|
[ -f /boot/grub/grub.cfg ] || exit 3
|
||||||
|
cd /
|
||||||
|
# boot/initramfs-pentoo-x86_64-6.1.52-pentoo_2023_09_30.img
|
||||||
|
|
||||||
|
- name: /etc/default/grub
|
||||||
|
lineinfile:
|
||||||
|
dest: /etc/default/grub
|
||||||
|
line: '{{item.from}}="{{item.to}}"'
|
||||||
|
regexp: '^#*{{item.from}}=.*'
|
||||||
|
owner: root
|
||||||
|
mode: '0644'
|
||||||
|
with_items:
|
||||||
|
# Append parameters to the linux kernel command line for non-recovery entries
|
||||||
|
- from: GRUB_CMDLINE_LINUX_DEFAULT
|
||||||
|
to: " rd.skipfsck=1 ipv6.disable=1 console=ttyS0 lang=en keymap=us intel_iommu=on vga=0x315 text"
|
||||||
|
# The resolution used on graphical terminal.
|
||||||
|
# Note that you can use only modes which your graphic card supports via VBE.
|
||||||
|
# You can see them in real GRUB with the command `vbeinfo'.
|
||||||
|
- from: GRUB_GFXMODE
|
||||||
|
to: 640x480
|
||||||
|
# Set to 'text' to force the Linux kernel to boot in normal text
|
||||||
|
- from: GRUB_GFXPAYLOAD_LINUX
|
||||||
|
to: text
|
||||||
|
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to kernel
|
||||||
|
- from: GRUB_DISABLE_LINUX_UUID
|
||||||
|
to: true
|
||||||
|
|
||||||
|
- name: grub.cfg from roles/ansible-gentoo_install/tasks/
|
||||||
|
shell: |
|
||||||
|
LINE="{{' '.join(AGI_install_syslinux_kernel_line)}}"
|
||||||
|
# LINE="$LINE pti=on doscsi iommu=pt amd_iommu=on debugfs=off efi=disable_early_pci_dma extra_latent_entropy init_on_free=1 kvm.nx_huge_pages=force l1tf=full,force mce=0 mds=full,nosmt nosmt=force page_alloc.shuffle=1 pti=on random.trust_cpu=off slab_nomerge slub_debug=FZ spec_store_bypass_disable=on spectre_v2=on tsx_async_abort=full,nosmt vsyscall=none "
|
||||||
|
grep /boot /etc/fstab || exit 1
|
||||||
|
df | grep /boot || mount /boot || exit 2
|
||||||
|
[ -d /boot/grub ] || exit 3
|
||||||
|
[ -f /boot/grub/grub.cfg ] || exit 4
|
||||||
|
[ -f /boot/grub/grub.cfg.dst ] || cp -p /boot/grub/grub.cfg /boot/grub/grub.cfg.dst
|
||||||
|
sed -e 's@ ro *$@ '"$LINE"' ro@' -i /boot/grub/grub.cfg
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
when: AGI_install_bootloader == 'grub:2'
|
||||||
|
|
||||||
- name: fstab root
|
- name: fstab root
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/fstab
|
dest: /etc/fstab
|
||||||
line: '{{AGI_container_disk}}3 / ext4 defaults,noatime 0 1'
|
line: '{{AGI_container_disk}}3 / ext4 defaults,noatime 0 1'
|
||||||
regexp: '^{{AGI_container_disk}}3'
|
regexp: '^{{AGI_container_disk}}3'
|
||||||
|
owner: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
- name: fstab boot
|
- name: fstab boot
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/fstab
|
dest: /etc/fstab
|
||||||
line: '{{AGI_container_disk}}1 /boot ext3 defaults,noatime 0 1'
|
line: '{{AGI_container_disk}}1 /boot ext3 defaults,noatime 0 1'
|
||||||
regexp: '^{{AGI_container_disk}}3'
|
regexp: '^{{AGI_container_disk}}3'
|
||||||
|
owner: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
- name: fstab swap
|
- name: fstab swap
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/fstab
|
dest: /etc/fstab
|
||||||
line: '{{AGI_container_disk}}2 none swap nofail,sw 0 0'
|
line: '{{AGI_container_disk}}2 none swap nofail,sw 0 0'
|
||||||
regexp: '^{{AGI_container_disk}}2'
|
regexp: '^{{AGI_container_disk}}2'
|
||||||
|
owner: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
- name: fstab shm
|
- name: fstab shm
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/fstab
|
dest: /etc/fstab
|
||||||
line: 'tmpfs /run/shm tmpfs defaults,noexec,size=5% 0 0'
|
line: 'tmpfs /run/shm tmpfs defaults,noexec,size=5% 0 0'
|
||||||
regexp: '^tmpfs */run/shm'
|
regexp: '^tmpfs */run/shm'
|
||||||
|
owner: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
# linuxPen19 /mnt/linuxPen19 virtiofs defaults,dirsync 0 0
|
# linuxPen19 /mnt/linuxPen19 virtiofs defaults,dirsync 0 0
|
||||||
|
|
||||||
@@ -67,42 +169,54 @@
|
|||||||
dest: /etc/security/passwdqc.conf
|
dest: /etc/security/passwdqc.conf
|
||||||
line: 'enforce=none'
|
line: 'enforce=none'
|
||||||
regexp: '^enforce=.*'
|
regexp: '^enforce=.*'
|
||||||
|
owner: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
- name: /etc/security/passwdqc.conf
|
- name: /etc/security/passwdqc.conf
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/security/passwdqc.conf
|
dest: /etc/security/passwdqc.conf
|
||||||
line: 'enforce=none'
|
line: 'enforce=none'
|
||||||
regexp: '^enforce=.*'
|
regexp: '^enforce=.*'
|
||||||
|
owner: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
- name: /etc/conf.d/consolefont
|
- name: /etc/conf.d/consolefont
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/conf.d/consolefont
|
dest: /etc/conf.d/consolefont
|
||||||
line: 'consolefont="ter-v{{AGI_consolefont_font_size}}b"'
|
line: 'consolefont="ter-v{{AGI_consolefont_font_size}}b"'
|
||||||
regexp: '^consolefont=.*'
|
regexp: '^consolefont=.*'
|
||||||
|
owner: root
|
||||||
- name: roles/ansible-gentoo_install/tasks/
|
mode: '0644'
|
||||||
shell: |
|
|
||||||
LINE="rd.skipfsck=1 ipv6.disable=1 console=tty1 lang=en keymap=us "
|
|
||||||
# LINE="$LINE pti=on doscsi iommu=pt amd_iommu=on debugfs=off efi=disable_early_pci_dma extra_latent_entropy init_on_free=1 kvm.nx_huge_pages=force l1tf=full,force mce=0 mds=full,nosmt nosmt=force page_alloc.shuffle=1 pti=on random.trust_cpu=off slab_nomerge slub_debug=FZ spec_store_bypass_disable=on spectre_v2=on tsx_async_abort=full,nosmt vsyscall=none "
|
|
||||||
LINE="$LINE intel_iommu=on vga=0x315 text
|
|
||||||
df | grep /boot || mount /dev/vda1 /boot
|
|
||||||
[ -d /boot/grub ] || exit 2
|
|
||||||
[ -f /boot/grub/grub.cfg ] || exit 3
|
|
||||||
sed -e "s@ ro *$@ $LINE ro@" -i /boot/grub/grub.cfg
|
|
||||||
|
|
||||||
- name: consolefont
|
- name: consolefont
|
||||||
shell: |
|
shell: |
|
||||||
rc-update add consolefont
|
grep -q /etc/init.d/consolefont /etc/rc.local || \
|
||||||
cat >> /etc/rc.local << EOF
|
cat >> /etc/rc.local << EOF
|
||||||
|
#!/bin/sh
|
||||||
/etc/init.d consolefont stop
|
/etc/init.d consolefont stop
|
||||||
/etc/init.d consolefont start
|
/etc/init.d consolefont start
|
||||||
stty -F /dev/tty1 cols 80 rows 24
|
# these are right for ter-v28b consolefont
|
||||||
|
if tty|grep -q /dev/ttyS0 ; then
|
||||||
|
stty cols 80 rows 34
|
||||||
|
elif tty|grep -q /dev/tty[1-6] ; then
|
||||||
|
stty cols 80 rows 22
|
||||||
|
fi
|
||||||
EOF
|
EOF
|
||||||
bash /etc/rc.local
|
chmod 755 /etc/rc.local
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
|
|
||||||
- name: rc-update add bootlogd boot
|
- name: rc-update add bootlogd boot
|
||||||
shell: |
|
shell: |
|
||||||
|
[ -d /etc/modules-load.d ] || mkdir /etc/modules-load.d
|
||||||
|
[ -f /etc/modules-load.d/virtio.conf ] || \
|
||||||
|
echo "{{'\n'.join(AGI_bootstrap_modules)}}" \
|
||||||
|
> /etc/modules-load.d/virtio.conf
|
||||||
|
rc-update add consolefont
|
||||||
rc-update | grep -q 'bootlogd .* boot' || \
|
rc-update | grep -q 'bootlogd .* boot' || \
|
||||||
rc-update add bootlogd boot
|
rc-update add bootlogd boot
|
||||||
|
grep -q '^s0:' /etc/inittab || \
|
||||||
|
sed -e 's/^#s0:/s0:/' /etc/inittab
|
||||||
|
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,11 @@
|
|||||||
|
|
||||||
- name: copy resolv.conf into chroot
|
- name: copy resolv.conf into chroot
|
||||||
copy:
|
copy:
|
||||||
src: /etc/resolv.conf
|
src: "/{{item}}"
|
||||||
dest: "{{AGI_NBD_MP}}/etc/resolv.conf"
|
dest: "{{AGI_NBD_MP}}/{{item}}"
|
||||||
|
mode: '0644'
|
||||||
remote_src: yes
|
remote_src: yes
|
||||||
|
with_items: "{{AGI_bootstrap_files}}"
|
||||||
when: not ansible_check_mode
|
when: not ansible_check_mode
|
||||||
|
|
||||||
- name: mount /proc in chroot
|
- name: mount /proc in chroot
|
||||||
|
|||||||
@@ -39,12 +39,12 @@
|
|||||||
- name: copy kernel sources
|
- name: copy kernel sources
|
||||||
copy:
|
copy:
|
||||||
src: "{{AGI_GENTOO_FROM_MP}}/usr/src/{{kernel_out.stdout}}"
|
src: "{{AGI_GENTOO_FROM_MP}}/usr/src/{{kernel_out.stdout}}"
|
||||||
dest: "{{AGI_NBD_MP}}/usr/src"
|
dest: "{{AGI_NBD_MP}}/usr/src/{{kernel_out.stdout}}"
|
||||||
remote_src: no
|
remote_src: no
|
||||||
creates: "{{AGI_NBD_MP}}/usr/src/{{kernel_out.stdout}}"
|
|
||||||
when:
|
when:
|
||||||
- kernel_out.rc|default(1) == 0
|
- kernel_out.rc|default(1) == 0
|
||||||
- AGI_use_local_kernel
|
- AGI_use_local_kernel
|
||||||
|
- false
|
||||||
|
|
||||||
- name: resolve kver
|
- name: resolve kver
|
||||||
shell: |
|
shell: |
|
||||||
@@ -99,6 +99,8 @@
|
|||||||
when:
|
when:
|
||||||
- AGI_use_local_kernel
|
- AGI_use_local_kernel
|
||||||
- ramfs_out.rc|default(1) == 0
|
- ramfs_out.rc|default(1) == 0
|
||||||
|
- false
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
- name: make directories
|
- name: make directories
|
||||||
shell: |
|
shell: |
|
||||||
@@ -111,6 +113,6 @@
|
|||||||
[ -f "{{AGI_NBD_MP}}/$file" ] && continue
|
[ -f "{{AGI_NBD_MP}}/$file" ] && continue
|
||||||
cp -np "$file" "{{AGI_NBD_MP}}/$file"
|
cp -np "$file" "{{AGI_NBD_MP}}/$file"
|
||||||
done
|
done
|
||||||
ignore_errors: false
|
ignore_errors: true
|
||||||
|
|
||||||
# dracut
|
# dracut
|
||||||
|
|||||||
@@ -16,8 +16,16 @@
|
|||||||
[ -d "{{AGI_GENTOO_FROM_MP}}" ] || exit 5
|
[ -d "{{AGI_GENTOO_FROM_MP}}" ] || exit 5
|
||||||
check_mode: false
|
check_mode: false
|
||||||
|
|
||||||
|
- name: check for partitions
|
||||||
|
shell: |
|
||||||
|
grep '/dev/{{AGI_NBD_DEV}}p3' /proc/partitions && exit 0
|
||||||
|
exit 1
|
||||||
|
register: partitions_out
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
- block:
|
- block:
|
||||||
|
# old code
|
||||||
|
|
||||||
- name: create disklabel
|
- name: create disklabel
|
||||||
command: parted -s {{ AGI_install_disk }} mklabel {{ AGI_install_disklabel }}
|
command: parted -s {{ AGI_install_disk }} mklabel {{ AGI_install_disklabel }}
|
||||||
register: disklabel_out
|
register: disklabel_out
|
||||||
@@ -44,7 +52,7 @@
|
|||||||
# able to install to the MBR
|
# able to install to the MBR
|
||||||
- name: create boot partition
|
- name: create boot partition
|
||||||
shell: |
|
shell: |
|
||||||
parted -s {{ AGI_install_disk }} mkpart primary ext2 1M 200M
|
parted -s {{ AGI_install_disk }} mkpart primary {{'ext2' if AGI_install_bootloader != 'syslinux' else 'fat32'}} 1M 200M
|
||||||
args:
|
args:
|
||||||
creates: "{{ AGI_install_disk }}p1"
|
creates: "{{ AGI_install_disk }}p1"
|
||||||
|
|
||||||
@@ -65,7 +73,7 @@
|
|||||||
creates: "{{ AGI_install_disk }}p3"
|
creates: "{{ AGI_install_disk }}p3"
|
||||||
|
|
||||||
- name: format boot partition
|
- name: format boot partition
|
||||||
filesystem: dev={{ AGI_install_disk }}p1 fstype=ext2 force=yes
|
filesystem: dev={{ AGI_install_disk }}p1 fstype={{'ext2' if AGI_install_bootloader != 'syslinux' else 'vfat'}} force=yes
|
||||||
check_mode: false
|
check_mode: false
|
||||||
when: not ansible_check_mode
|
when: not ansible_check_mode
|
||||||
|
|
||||||
@@ -85,7 +93,15 @@
|
|||||||
e2label {{ AGI_install_disk }}p3 root
|
e2label {{ AGI_install_disk }}p3 root
|
||||||
e2label {{ AGI_install_disk }}p1 boot
|
e2label {{ AGI_install_disk }}p1 boot
|
||||||
mkswap -L swap "{{ AGI_install_disk }}p2"
|
mkswap -L swap "{{ AGI_install_disk }}p2"
|
||||||
sync
|
when: AGI_install_bootloader != 'syslinux'
|
||||||
|
|
||||||
|
- name: label partitions syslinux
|
||||||
|
shell: |
|
||||||
|
partprobe
|
||||||
|
fatlabel {{ AGI_install_disk }}p3 root
|
||||||
|
e2label {{ AGI_install_disk }}p1 boot
|
||||||
|
mkswap -L swap "{{ AGI_install_disk }}p2"
|
||||||
|
when: AGI_install_bootloader == 'syslinux'
|
||||||
|
|
||||||
when: false
|
when: false
|
||||||
|
|
||||||
@@ -100,15 +116,29 @@
|
|||||||
unit: sectors
|
unit: sectors
|
||||||
sector-size: 512
|
sector-size: 512
|
||||||
|
|
||||||
{{ AGI_install_disk }}p1 : start= 2048, size= 819200, type=83, bootable
|
{{ AGI_install_disk }}p1 : start= 2048, size= 819200, type={{'83' if AGI_install_bootloader != 'syslinux' else 'c'}}, bootable
|
||||||
{{ AGI_install_disk }}p2 : start= 821248, size= 4096000, type=82
|
{{ AGI_install_disk }}p2 : start= 821248, size= 4096000, type=82
|
||||||
{{ AGI_install_disk }}p3 : start= 4917248, size= 37025792, type=83
|
{{ AGI_install_disk }}p3 : start= 4917248, size= 37025792, type=83
|
||||||
EOF
|
EOF
|
||||||
partprobe
|
partprobe
|
||||||
|
|
||||||
|
- name: format disk partitions grub:2
|
||||||
|
shell: |
|
||||||
mke2fs -L boot {{ AGI_install_disk }}p1
|
mke2fs -L boot {{ AGI_install_disk }}p1
|
||||||
mke2fs -L root {{ AGI_install_disk }}p3
|
mke2fs -L root {{ AGI_install_disk }}p3
|
||||||
mkswap -L swap "{{ AGI_install_disk }}p2"
|
mkswap -L swap "{{ AGI_install_disk }}p2"
|
||||||
sync
|
|
||||||
|
when: AGI_install_bootloader != 'syslinux'
|
||||||
when: true
|
|
||||||
|
- name: format disk partitions syslinux
|
||||||
|
shell: |
|
||||||
|
mkfs.vfat -F 32 -n boot {{ AGI_install_disk }}p1
|
||||||
|
mke2fs -L root {{ AGI_install_disk }}p3
|
||||||
|
mkswap -L swap "{{ AGI_install_disk }}p2"
|
||||||
|
|
||||||
|
when: AGI_install_bootloader == 'syslinux'
|
||||||
|
|
||||||
|
when:
|
||||||
|
- partitions_out.rc != 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
23
roles/ansible-gentoo_install/tasks/libvirt.yml
Normal file
23
roles/ansible-gentoo_install/tasks/libvirt.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
|
||||||
|
# localhost
|
||||||
|
---
|
||||||
|
- name: "DEBUG: ansible-gentoo_install libvirt"
|
||||||
|
debug:
|
||||||
|
verbosity: 1
|
||||||
|
msg: "DEBUG: ansible-gentoo_install libvirt"
|
||||||
|
|
||||||
|
- name: test we are NOT in the chroot
|
||||||
|
shell: |
|
||||||
|
[ -n "{{AGI_NBD_MP}}" ] || exit 2
|
||||||
|
[ -d "{{AGI_NBD_MP}}" ] || exit 3
|
||||||
|
check_mode: false
|
||||||
|
|
||||||
|
# - name: setup libvirt network
|
||||||
|
# - name: setup libvirt iptables
|
||||||
|
# net.ipv4.conf.virbr1.forwarding = 1
|
||||||
|
# net.ipv4.ip_forward = 1
|
||||||
|
# mkdir /etc/libvirt/qemu
|
||||||
|
# qemu-ga -D > /etc/libvirt/qemu/qemu-ga.conf
|
||||||
|
# for elt in unix-listen virtio-serial isa-serial vsock-listen ; do
|
||||||
|
# /etc/conf.d/qemu-ga
|
||||||
|
|
||||||
@@ -32,12 +32,19 @@
|
|||||||
|
|
||||||
- name: check for mounted disk
|
- name: check for mounted disk
|
||||||
shell: |
|
shell: |
|
||||||
grep '/dev/{{AGI_NBD_DEV}}' /proc/mounts && exit 0
|
grep '/dev/{{AGI_NBD_DEV}}p3' /proc/mounts && exit 0
|
||||||
ps ax | grep -v grep | \
|
if [ ! -f "{{BOX_NBD_BASE_QCOW}}" ] ; then
|
||||||
grep "qemu-nbd.*/dev/nbd.*{{BOX_NBD_BASE_QCOW}}" && \
|
echo ERROR: not created BOX_NBD_DEV="{{BOX_NBD_DEV}}" - use
|
||||||
echo WARN looks like theres an active nbd mount of \
|
echo qemu-img create -f qcow2 "{{BOX_NBD_BASE_QCOW}}" 20G
|
||||||
"${BOX_NBD_BASE_QCOW}" && exit 1
|
exit 1
|
||||||
exit 2
|
fi
|
||||||
|
if ! ps ax | grep -v grep | \
|
||||||
|
grep "qemu-nbd.*{{AGI_NBD_DEV}}.*{{BOX_NBD_BASE_QCOW}}" ; then
|
||||||
|
echo ERROR: not mounted BOX_NBD_DEV="{{BOX_NBD_DEV}}" - use
|
||||||
|
echo qemu-nbd -n -f qcow2 -c /dev/nbd1 {{BOX_NBD_BASE_QCOW}}
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
exit 3
|
||||||
failed_when: false
|
failed_when: false
|
||||||
changed_when: false
|
changed_when: false
|
||||||
register: check_mounted_disk
|
register: check_mounted_disk
|
||||||
@@ -45,15 +52,15 @@
|
|||||||
|
|
||||||
- name: partition if disk not mounted
|
- name: partition if disk not mounted
|
||||||
fail:
|
fail:
|
||||||
msg: "looks like theres an active nbd mount of {{BOX_NBD_BASE_QCOW}}"
|
msg: "make and nbd mount {{BOX_NBD_BASE_QCOW}}"
|
||||||
when:
|
when:
|
||||||
- check_mounted_disk.rc == 1
|
- check_mounted_disk.rc in [2, 1]
|
||||||
check_mode: no
|
check_mode: no
|
||||||
|
|
||||||
- name: partition if disk not mounted or active
|
- name: partition if disk not mounted or active
|
||||||
include: disk.yml
|
include: disk.yml
|
||||||
when:
|
when:
|
||||||
- check_mounted_disk.rc > 1
|
- check_mounted_disk.rc > 2
|
||||||
check_mode: no
|
check_mode: no
|
||||||
|
|
||||||
- name: mount root partition
|
- name: mount root partition
|
||||||
@@ -78,6 +85,7 @@
|
|||||||
state: mounted
|
state: mounted
|
||||||
check_mode: false
|
check_mode: false
|
||||||
|
|
||||||
|
- include: libvirt.yml
|
||||||
- include: tarball.yml
|
- include: tarball.yml
|
||||||
- include: copy.yml
|
- include: copy.yml
|
||||||
when: AGI_use_local_kernel
|
when: AGI_use_local_kernel
|
||||||
@@ -136,7 +144,7 @@
|
|||||||
|
|
||||||
check_mode: false
|
check_mode: false
|
||||||
when:
|
when:
|
||||||
- "ansible_connection in ['chroot'] or (ansible_connection in ['local'] or and chroot_out.rc|default(1) == 0)"
|
- "ansible_connection in ['chroot'] or (ansible_connection in ['local'] and chroot_out.rc|default(1) == 0)"
|
||||||
rescue:
|
rescue:
|
||||||
- debug:
|
- debug:
|
||||||
msg: "ERROR: error during chroot execution"
|
msg: "ERROR: error during chroot execution"
|
||||||
|
|||||||
@@ -52,6 +52,8 @@
|
|||||||
fi
|
fi
|
||||||
if ! grep -q "{{BOX_NBD_DEV}}" /proc/partitions ; then
|
if ! grep -q "{{BOX_NBD_DEV}}" /proc/partitions ; then
|
||||||
echo ERROR: not mounted BOX_NBD_DEV="{{BOX_NBD_DEV}}" - use qemu-nbd
|
echo ERROR: not mounted BOX_NBD_DEV="{{BOX_NBD_DEV}}" - use qemu-nbd
|
||||||
|
echo qemu-img create -f qcow2 /a/tmp/GentooImgr/gentoo.qcow2 20G
|
||||||
|
echo qemu-nbd -n -f qcow2 -c /dev/nbd1 /a/tmp/GentooImgr/gentoo.qcow
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
@@ -71,19 +73,27 @@
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
# should operate on json with jq
|
# should operate on json with jq
|
||||||
# "imgsize": "20G",
|
|
||||||
# "memory": 4096,
|
|
||||||
# "mountpoint": "/mnt/gentoo",
|
|
||||||
# "imagename": null,
|
|
||||||
# "initsys": "openrc",
|
|
||||||
# "iso": null,
|
|
||||||
# "portage": null,
|
|
||||||
# "stage3": null,
|
|
||||||
# "partition": 1
|
|
||||||
if [ -f "$tofile" ] ; then
|
if [ -f "$tofile" ] ; then
|
||||||
|
# "imgsize": "20G",
|
||||||
|
sed -i -e 's@"imgsize": ".*"@"imgsize": "{{BOX_NBD_OVERLAY_GB}}"@' $tofile
|
||||||
|
# "memory": 4096,
|
||||||
|
sed -i -e 's@"memory": ".*"@"imgsize": "{{BOX_NBD_OVERLAY_RAM}}"@' $tofile
|
||||||
|
# "mountpoint": "/mnt/gentoo",
|
||||||
|
sed -i -e 's@"mountpoint": ".*"@"mountpoint": "{{BOX_NBD_MP}}"@' $tofile
|
||||||
|
# "imagename": null,
|
||||||
|
sed -i -e 's@"imagename": ".*"@"imagename": "{{BOX_NBD_OVERLAY_NAME}}"@' $tofile
|
||||||
|
# "initsys": "openrc",
|
||||||
|
sed -i -e 's@"initsys": ".*"@"initsys: "{{BOX_NBD_BASE_PROFILE}}"@' $tofile
|
||||||
|
# "iso": null,
|
||||||
|
# "portage": null,
|
||||||
|
sed -i -e 's@""portage": ".*"@""portage: "{{BOX_NBD_PORTAGE_FILE}}"@' $tofile
|
||||||
|
# "stage3": null,
|
||||||
|
sed -i -e 's@""stage3": ".*"@""stage3: "{{BOX_NBD_STAGE3_FILE}}"@' $tofile
|
||||||
|
# "partition": 1
|
||||||
|
sed -i -e 's@"partition": ".*"@"partition": 3@' $tofile
|
||||||
# but this is crucial
|
# but this is crucial
|
||||||
# "disk": "/dev/sda",
|
# "disk": "/dev/sda",
|
||||||
sed -i -e 's@"disk": ".*"@"disk": "'{{BOX_NBD_DEV}}'"@' $tofile
|
sed -i -e 's@"disk": ".*"@"disk": "{{BOX_NBD_DEV}}"@' $tofile
|
||||||
grep {{BOX_NBD_DEV}} $tofile || exit 4
|
grep {{BOX_NBD_DEV}} $tofile || exit 4
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -103,7 +113,8 @@
|
|||||||
action: status
|
action: status
|
||||||
loglevel: "{{BOX_NBD_LOGLEVEL}}"
|
loglevel: "{{BOX_NBD_LOGLEVEL}}"
|
||||||
threads: 1
|
threads: 1
|
||||||
config: "{{AGI_GENTOOIMGR_CONFIGFILE}}" # base.json - bare filename in configs
|
# base.json - bare filename in configs
|
||||||
|
config: "{{AGI_GENTOOIMGR_CONFIGFILE}}"
|
||||||
profile: "{{BOX_NBD_BASE_PROFILE}}"
|
profile: "{{BOX_NBD_BASE_PROFILE}}"
|
||||||
kernel_dir: "{{BOX_NBD_KERNEL_DIR}}"
|
kernel_dir: "{{BOX_NBD_KERNEL_DIR}}"
|
||||||
portage: "{{BOX_NBD_PORTAGE_FILE}}"
|
portage: "{{BOX_NBD_PORTAGE_FILE}}"
|
||||||
@@ -118,15 +129,11 @@
|
|||||||
debug:
|
debug:
|
||||||
verbosity: 0
|
verbosity: 0
|
||||||
var: ansible_gentooimgr_out
|
var: ansible_gentooimgr_out
|
||||||
|
check_mode: false
|
||||||
|
|
||||||
check_mode: false
|
- name: include_tasks local.yml
|
||||||
when:
|
include_tasks: local.yml
|
||||||
- ansible_connection in ['chroot', 'local', 'libvirt_qemu']
|
|
||||||
- ansible_distribution == 'Gentoo' or BOX_GENTOO_FROM_MP not in ['/', '']
|
|
||||||
# - nbd_disk|default('') == AGI_NBD_DISK
|
|
||||||
|
|
||||||
- name: include_tasks local.yml
|
|
||||||
include_tasks: local.yml
|
|
||||||
when:
|
when:
|
||||||
- ansible_connection in ['chroot', 'local']
|
- ansible_connection in ['chroot', 'local']
|
||||||
- ansible_distribution == 'Gentoo' or BOX_GENTOO_FROM_MP not in ['/', '']
|
- ansible_distribution == 'Gentoo' or BOX_GENTOO_FROM_MP not in ['/', '']
|
||||||
|
|||||||
@@ -15,6 +15,11 @@
|
|||||||
for elt in {{ AGI_bootstrap_mountpoints|join(' ') }} ; do
|
for elt in {{ AGI_bootstrap_mountpoints|join(' ') }} ; do
|
||||||
[ -d $elt ] || mkdir $elt
|
[ -d $elt ] || mkdir $elt
|
||||||
done
|
done
|
||||||
|
# 700 files from ansible umask
|
||||||
|
find /usr/local/*bin/ /usr/local/etc/ -name '*sh' -exec chmod 755 {} \;
|
||||||
|
find /usr/local/{src,bin,share,etc} -type f \
|
||||||
|
-exec chown ${BOX_USER_NAME}:${BOX_USER_GROUP} {} \;
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
when: AGI_bootstrap_mountpoints|default([])|length > 0
|
when: AGI_bootstrap_mountpoints|default([])|length > 0
|
||||||
|
|
||||||
@@ -32,7 +37,7 @@
|
|||||||
dest: /etc/localtime
|
dest: /etc/localtime
|
||||||
src: /usr/share/zoneinfo/{{ AGI_install_timezone }}
|
src: /usr/share/zoneinfo/{{ AGI_install_timezone }}
|
||||||
state: link
|
state: link
|
||||||
force: yes
|
force: no
|
||||||
|
|
||||||
- name: configure locales
|
- name: configure locales
|
||||||
lineinfile:
|
lineinfile:
|
||||||
@@ -86,6 +91,13 @@
|
|||||||
user:
|
user:
|
||||||
name: gentoo
|
name: gentoo
|
||||||
password: "{{ gentoo_password_out.stdout }}"
|
password: "{{ gentoo_password_out.stdout }}"
|
||||||
|
group: "{{ BOX_USER_GROUP }}"
|
||||||
|
append: true
|
||||||
|
groups: ['{{ BOX_ALSO_GROUP }}', 'wheel']
|
||||||
|
create_home: yes
|
||||||
|
shell: /bin/bash
|
||||||
|
#? usermod: user vagrant is currently used by process 2190
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
- name: configure sudoers
|
- name: configure sudoers
|
||||||
lineinfile:
|
lineinfile:
|
||||||
@@ -96,6 +108,13 @@
|
|||||||
owner: root
|
owner: root
|
||||||
mode: '0640'
|
mode: '0640'
|
||||||
|
|
||||||
|
- name: make symlinks
|
||||||
|
shell: |
|
||||||
|
[ -e /var/db/repos/gentoo ] || \
|
||||||
|
ln -s /usr/portage /var/db/repos/gentoo
|
||||||
|
grep -q ^tmpfs /etc/fstab || \
|
||||||
|
echo >> /etc/fstab 'tmpfs /dev/shm tmpfs defaults,noexec,size=5% 0 0'
|
||||||
|
|
||||||
- block:
|
- block:
|
||||||
|
|
||||||
- name: make symlinks
|
- name: make symlinks
|
||||||
|
|||||||
@@ -5,11 +5,6 @@
|
|||||||
verbosity: 1
|
verbosity: 1
|
||||||
msg: "DEBUG: ansible-gentoo_install portage ansible_shell_executable={{ansible_shell_executable}}"
|
msg: "DEBUG: ansible-gentoo_install portage ansible_shell_executable={{ansible_shell_executable}}"
|
||||||
|
|
||||||
- name: reenable chroot wrapper
|
|
||||||
set_fact:
|
|
||||||
ansible_shell_executable: /var/tmp/chroot_wrapper.sh
|
|
||||||
ansible_python_interpreter: "/usr/bin/python3"
|
|
||||||
|
|
||||||
- name: test we are in the chroot
|
- name: test we are in the chroot
|
||||||
shell: |
|
shell: |
|
||||||
df | grep /mnt/gentoo && exit 1
|
df | grep /mnt/gentoo && exit 1
|
||||||
|
|||||||
30
roles/ansible-gentoo_install/templates/boot/syslinux/syslinux.cfg
Executable file
30
roles/ansible-gentoo_install/templates/boot/syslinux/syslinux.cfg
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
# -*-mode: sh; tab-width: 8; coding: utf-8-dos -*-
|
||||||
|
|
||||||
|
default vesamenu.c32
|
||||||
|
|
||||||
|
##? SERIAL 0 115200
|
||||||
|
##? CONSOLE 0
|
||||||
|
prompt 0
|
||||||
|
|
||||||
|
timeout 150
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
menu title {{BOX_NBD_DEV}} TAB to edit RETURN to boot
|
||||||
|
|
||||||
|
menu color title 1;36;44 #c0ffffff #00000000 std
|
||||||
|
|
||||||
|
menu color sel 7;37;40 #e0000000 #20ECEAC7 all
|
||||||
|
|
||||||
|
menu rows 15
|
||||||
|
|
||||||
|
menu tabmsgrow 21
|
||||||
|
|
||||||
|
menu timeoutrow 23
|
||||||
|
|
||||||
|
menu helpmsgrow 23
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# rd.shell rd.debug
|
||||||
|
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
# Generated by iptables-save v1.8.5 on Wed Nov 4 01:14:37 2020
|
||||||
|
*mangle
|
||||||
|
:PREROUTING ACCEPT [0:0]
|
||||||
|
:INPUT ACCEPT [0:0]
|
||||||
|
:FORWARD ACCEPT [0:0]
|
||||||
|
:OUTPUT ACCEPT [0:0]
|
||||||
|
:POSTROUTING ACCEPT [0:0]
|
||||||
|
:LIBVIRT_PRT - [0:0]
|
||||||
|
-A INPUT -j LOG --log-prefix "iptables_libvirt mangle-i: " --log-uid
|
||||||
|
-A POSTROUTING -j LIBVIRT_PRT
|
||||||
|
COMMIT
|
||||||
|
# Completed on Wed Nov 4 01:14:37 2020
|
||||||
|
|
||||||
|
# Generated by iptables-save v1.8.5 on Wed Nov 4 01:14:37 2020
|
||||||
|
*nat
|
||||||
|
:PREROUTING ACCEPT [0:0]
|
||||||
|
:INPUT ACCEPT [0:0]
|
||||||
|
:OUTPUT ACCEPT [0:0]
|
||||||
|
:POSTROUTING ACCEPT [0:0]
|
||||||
|
:LIBVIRT_PRT - [0:0]
|
||||||
|
|
||||||
|
# was ! -o lo
|
||||||
|
-A OUTPUT -o wlan6 -p tcp --dport 53 -m tcp -j DNAT --to-destination 127.0.0.1:53
|
||||||
|
-A OUTPUT -o wlan6 -p udp --dport 53 -m udp -j DNAT --to-destination 127.0.0.1:53
|
||||||
|
|
||||||
|
# .onion mapped addresses redirection to Tor.
|
||||||
|
-A OUTPUT -d 172.16.0.0/12 -p tcp -m tcp -j DNAT --to-destination 127.0.0.1:9040
|
||||||
|
## Log.
|
||||||
|
-A INPUT -j LOG --log-prefix "iptables_libvirt_nat-i: " --log-uid
|
||||||
|
-A POSTROUTING -j LIBVIRT_PRT
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 -d 224.0.0.0/24 -j RETURN
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 -d 255.255.255.255/32 -j RETURN
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 ! -d 10.0.2.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 ! -d 10.0.2.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
|
||||||
|
-A LIBVIRT_PRT -s 10.0.2.0/24 ! -d 10.0.2.0/24 -j MASQUERADE
|
||||||
|
COMMIT
|
||||||
|
# Completed on Wed Nov 4 01:14:37 2020
|
||||||
|
# Generated by iptables-save v1.8.5 on Wed Nov 4 01:14:37 2020
|
||||||
|
*filter
|
||||||
|
:INPUT ACCEPT [0:0]
|
||||||
|
:FORWARD DROP [0:0]
|
||||||
|
:OUTPUT DROP [0:0]
|
||||||
|
:LIBVIRT_FWI - [0:0]
|
||||||
|
:LIBVIRT_FWO - [0:0]
|
||||||
|
:LIBVIRT_FWX - [0:0]
|
||||||
|
:LIBVIRT_INP - [0:0]
|
||||||
|
:LIBVIRT_OUT - [0:0]
|
||||||
|
|
||||||
|
## DROP PACKETS WITH INCOMING FRAGMENTS. THIS ATTACK ONCE RESULTED IN KERNEL PANICS
|
||||||
|
-A INPUT -f -j DROP
|
||||||
|
## DROP INCOMING MALFORMED XMAS PACKETS
|
||||||
|
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP
|
||||||
|
## DROP INCOMING MALFORMED NULL PACKETS
|
||||||
|
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP
|
||||||
|
|
||||||
|
-A INPUT -i lo -j ACCEPT
|
||||||
|
## Traffic on the loopback interface is accepted.
|
||||||
|
-A INPUT -i lo -j ACCEPT
|
||||||
|
## Established incoming connections are accepted. RELATED?
|
||||||
|
-A INPUT -m state --state ESTABLISHED -j ACCEPT
|
||||||
|
### this is required for outgoing pings
|
||||||
|
-A INPUT -i wlan6 -p icmp -j LOG --log-prefix "iptables_icmp_ACCEPT-i: " --log-uid
|
||||||
|
-A INPUT -i wlan6 -p icmp -j ACCEPT
|
||||||
|
|
||||||
|
# let dhcp through? - YES
|
||||||
|
-A INPUT -i wlan6 -p udp -m udp --sport 137 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p udp -m udp --sport 138 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p udp -m udp --sport 139 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p tcp --sport 9055 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p tcp --sport 9054 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p tcp --sport 9053 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p tcp --sport 9051 -j DROP
|
||||||
|
-A INPUT -i wlan6 -p udp --sport 53 -j ACCEPT
|
||||||
|
|
||||||
|
# SRC=0.0.0.0 DST=255.255.255.255 PROTO=UDP SPT=68 DPT=67
|
||||||
|
-A INPUT -j LOG --log-prefix "iptables_libvirt_jLIBVIRT_INP-i: " --log-uid
|
||||||
|
# -A INPUT -i wlan6 -p udp -j DROP
|
||||||
|
-A INPUT -i wlan6 -j DROP
|
||||||
|
|
||||||
|
-A INPUT -j LIBVIRT_INP
|
||||||
|
|
||||||
|
-A FORWARD -j LIBVIRT_FWX
|
||||||
|
-A FORWARD -j LIBVIRT_FWI
|
||||||
|
-A FORWARD -j LIBVIRT_FWO
|
||||||
|
#d#-A OUTPUT -o wlan6 -p icmp -j LOG --log-prefix iptables_icmp_ACCEPT-o: --log-uid
|
||||||
|
## Traffic on the loopback interface is accepted.
|
||||||
|
-A OUTPUT -o lo -j ACCEPT
|
||||||
|
|
||||||
|
## Existing connections are accepted.
|
||||||
|
-A OUTPUT -m state --state ESTABLISHED -j ACCEPT
|
||||||
|
-A OUTPUT -o wlan6 -p icmp -j LOG --log-prefix "iptables_icmp_ACCEPT-o: " --log-uid
|
||||||
|
-A OUTPUT -o wlan6 -p icmp -j ACCEPT
|
||||||
|
# st-routers.mcast.net.
|
||||||
|
-A OUTPUT -o wlan6 -p udp -d 224.0.0.0/8 -j REJECT
|
||||||
|
|
||||||
|
## Accept outgoing connections to local network, Whonix-Workstation and VirtualBox,
|
||||||
|
-A OUTPUT -d 192.168.1.0/24 -j ACCEPT
|
||||||
|
-A OUTPUT -d 10.0.2.0/24 -j ACCEPT
|
||||||
|
|
||||||
|
# gateway
|
||||||
|
#-A OUTPUT -d 10.0.2.0/24 -j ACCEPT
|
||||||
|
|
||||||
|
-A OUTPUT -o wlan6 -d 10.16.238.0/24 -j ACCEPT
|
||||||
|
-A OUTPUT -o wlan6 -d 10.0.0.0/8 -j DROP
|
||||||
|
-A OUTPUT -o wlan6 -d 172.16.0.0/12 -j DROP
|
||||||
|
#-A OUTPUT -o wlan6 -d 192.168.0.0/16 -j DROP
|
||||||
|
-A OUTPUT -o wlan6 -d 224.0.0.0/4 -j DROP
|
||||||
|
-A OUTPUT -o wlan6 -d 240.0.0.0/5 -j DROP
|
||||||
|
|
||||||
|
# The ntp user is allowed to connect to services listening on the ntp port...
|
||||||
|
# If root runs ntpdate manually you will see requests to port 53 UID=0
|
||||||
|
#-A OUTPUT -o wlan6 -m owner --gid-owner 226 -p udp --dport 123 -j LOG --log-uid --log-prefix "iptables_123_ACCEPT-o: "
|
||||||
|
-A OUTPUT -o wlan6 -m owner --gid-owner 226 -p UDP --dport 123 -j ACCEPT
|
||||||
|
-A OUTPUT -o wlan6 -m owner --uid-owner 0 -p UDP --dport 123 -j ACCEPT
|
||||||
|
#-A OUTPUT -o wlan6 -m tcp -p TCP --dport 22 -j LOG --log-uid --log-prefix "IPTABLES_ssh_REJECT: "
|
||||||
|
-A OUTPUT -o wlan6 -m tcp -p TCP --dport 22 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
#test-A OUTPUT -o virbr1 -m tcp -p TCP --dport 22 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o wlan6 -m owner -p tcp --gid-owner 216 -j ACCEPT
|
||||||
|
-A OUTPUT -o wlan6 -m owner --gid-owner 1 -j ACCEPT
|
||||||
|
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 22 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9028 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9028 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9040 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9040 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9050 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9050 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9053 -j LOG --log-uid --log-prefix "iptables_: "
|
||||||
|
-A OUTPUT -o virbr1 -m tcp -p TCP --dport 9053 -j ACCEPT
|
||||||
|
-A OUTPUT -o virbr1 -m udp -p udp --dport 9053 -j ACCEPT
|
||||||
|
-A OUTPUT -j LIBVIRT_OUT
|
||||||
|
-A LIBVIRT_FWI -o virbr1 -j LOG --log-uid --log-prefix "IPTABLES_FWI_REJECT-o: "
|
||||||
|
-A LIBVIRT_FWI -o virbr2 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
|
||||||
|
-A LIBVIRT_FWI -d 10.0.2.0/24 -o virbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_FWI -o virbr1 -j LOG --log-uid --log-prefix "IPTABLES_FWI_REJECT-o: "
|
||||||
|
-A LIBVIRT_FWI -o virbr1 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
|
||||||
|
-A LIBVIRT_FWO -i virbr2 -j LOG --log-uid --log-prefix "IPTABLES_FWO_REJECT-i: "
|
||||||
|
-A LIBVIRT_FWO -i virbr2 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
|
||||||
|
-A LIBVIRT_FWO -s 10.0.2.0/24 -i virbr1 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_FWO -i virbr1 -j LOG --log-uid --log-prefix "IPTABLES_FWO_REJECT-i: "
|
||||||
|
-A LIBVIRT_FWO -i virbr1 -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
|
||||||
|
-A LIBVIRT_FWX -i virbr2 -o virbr2 -j ACCEPT
|
||||||
|
-A LIBVIRT_FWX -i virbr1 -o virbr1 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_INP -i virbr2 -p udp -m udp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr2 -p tcp -m tcp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr2 -p udp -m udp --dport 67 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr2 -p tcp -m tcp --dport 67 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_INP -i virbr1 -p udp -m udp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr1 -p tcp -m tcp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr1 -p udp -m udp --dport 67 -j ACCEPT
|
||||||
|
-A LIBVIRT_INP -i virbr1 -p tcp -m tcp --dport 67 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_OUT -o virbr2 -p udp -m udp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr2 -p tcp -m tcp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr2 -p udp -m udp --dport 68 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr2 -p tcp -m tcp --dport 68 -j ACCEPT
|
||||||
|
|
||||||
|
-A LIBVIRT_OUT -o virbr1 -p udp -m udp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr1 -p tcp -m tcp --dport 53 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr1 -p udp -m udp --dport 68 -j ACCEPT
|
||||||
|
-A LIBVIRT_OUT -o virbr1 -p tcp -m tcp --dport 68 -j ACCEPT
|
||||||
|
COMMIT
|
||||||
|
# Completed on Wed Nov 4 01:14:37 2020
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<!--
|
||||||
|
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
|
||||||
|
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
|
||||||
|
virsh net-edit Whonix-External
|
||||||
|
or other application using the libvirt API.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<network>
|
||||||
|
<name>External</name>
|
||||||
|
<forward mode='nat'/>
|
||||||
|
<bridge name='virbr1' stp='on' delay='0'/>
|
||||||
|
<mac address='52:54:00:f7:fb:37'/>
|
||||||
|
<ip address='10.0.2.2' netmask='255.255.255.0'>
|
||||||
|
<dhcp>
|
||||||
|
<range start='10.0.2.20' end='10.0.2.254'/>
|
||||||
|
</dhcp>
|
||||||
|
</ip>
|
||||||
|
</network>
|
||||||
@@ -16,6 +16,7 @@ AGI_install_portage_makeconf_default:
|
|||||||
MAKEOPTS: "-j{{ ansible_processor_vcpus | default(1) }}"
|
MAKEOPTS: "-j{{ ansible_processor_vcpus | default(1) }}"
|
||||||
USE: "-X verify-sig"
|
USE: "-X verify-sig"
|
||||||
CFLAGS: "-march=native -O2 -pipe"
|
CFLAGS: "-march=native -O2 -pipe"
|
||||||
|
|
||||||
AGI_install_portage_conf_files:
|
AGI_install_portage_conf_files:
|
||||||
'package.accept_keywords': |
|
'package.accept_keywords': |
|
||||||
=sys-kernel/genkernel-4.3* ~amd64
|
=sys-kernel/genkernel-4.3* ~amd64
|
||||||
@@ -26,6 +27,9 @@ AGI_bootstrap_links:
|
|||||||
- from: /var/db/repos/gentoo
|
- from: /var/db/repos/gentoo
|
||||||
to: /usr/portage
|
to: /usr/portage
|
||||||
|
|
||||||
|
AGI_bootstrap_modules:
|
||||||
|
- virtio_console
|
||||||
|
|
||||||
# NO LEADING /
|
# NO LEADING /
|
||||||
AGI_bootstrap_dirs:
|
AGI_bootstrap_dirs:
|
||||||
- usr/local/etc/local.d
|
- usr/local/etc/local.d
|
||||||
@@ -41,11 +45,15 @@ AGI_bootstrap_dirs:
|
|||||||
- etc/portage/repos.conf
|
- etc/portage/repos.conf
|
||||||
- etc/portage/savedconfig
|
- etc/portage/savedconfig
|
||||||
- etc/portage/sets
|
- etc/portage/sets
|
||||||
|
- usr/local/tmp/bootstrap/logs
|
||||||
|
- usr/local/tmp/bootstrap/distfiles
|
||||||
|
|
||||||
AGI_bootstrap_files:
|
AGI_bootstrap_files:
|
||||||
- usr/local/etc/local.d/local.bash
|
- usr/local/etc/local.d/local.bash
|
||||||
- usr/local/bin/usr_local_tput.bash
|
- usr/local/bin/usr_local_tput.bash
|
||||||
- usr/local/bin/proxy_export.bash
|
- usr/local/bin/proxy_export.bash
|
||||||
|
- etc/hosts
|
||||||
|
- etc/resolv.conf
|
||||||
|
|
||||||
AGI_bootstrap_uris:
|
AGI_bootstrap_uris:
|
||||||
- http://distfiles.gentoo.org/distfiles/00/elfutils-0.190.tar.bz2
|
- http://distfiles.gentoo.org/distfiles/00/elfutils-0.190.tar.bz2
|
||||||
@@ -53,23 +61,35 @@ AGI_bootstrap_uris:
|
|||||||
- http://distfiles.gentoo.org/distfiles/60/shared-mime-info-2.2.tar.gz
|
- http://distfiles.gentoo.org/distfiles/60/shared-mime-info-2.2.tar.gz
|
||||||
- http://distfiles.gentoo.org/distfiles/fc/qemu-8.0.3.tar.xz
|
- http://distfiles.gentoo.org/distfiles/fc/qemu-8.0.3.tar.xz
|
||||||
|
|
||||||
|
AGI_bootstrap_pips3:
|
||||||
|
- negotiator-guest
|
||||||
|
|
||||||
|
# proxy_pkgs_inst:
|
||||||
AGI_bootstrap_pkgs:
|
AGI_bootstrap_pkgs:
|
||||||
- app-admin/sudo
|
- app-admin/sudo
|
||||||
- sys-boot/grub:2
|
- sys-boot/grub:2
|
||||||
|
- sys-boot/syslinux
|
||||||
- app-editors/mg
|
- app-editors/mg
|
||||||
- qemu-guest-agent
|
- qemu-guest-agent
|
||||||
- app-admin/logrotate
|
|
||||||
- "{{ AGI_install_cron_daemon }}"
|
|
||||||
- "{{AGI_install_syslog_daemon}}"
|
|
||||||
- media-fonts/terminus-font
|
|
||||||
- sys-apps/gptfdisk
|
- sys-apps/gptfdisk
|
||||||
- net-analyzer/openbsd-netcat
|
- net-analyzer/openbsd-netcat
|
||||||
|
- app-admin/logrotate
|
||||||
|
- "sys-process/{{ AGI_install_cron_daemon }}"
|
||||||
|
- "app-admin/{{ AGI_install_syslog_daemon}}"
|
||||||
|
- "sys-boot/{{ AGI_install_bootloader }}"
|
||||||
|
- media-fonts/terminus-font
|
||||||
|
- net-misc/curl
|
||||||
|
- app-arch/unzip
|
||||||
|
- net-libs/pacparser
|
||||||
- sys-process/lsof
|
- sys-process/lsof
|
||||||
- dev-util/strace
|
- dev-util/strace
|
||||||
- sys-libs/gpm
|
|
||||||
- app-portage/eix
|
- app-portage/eix
|
||||||
- www-client/lynx
|
- sys-libs/gpm
|
||||||
- linux-firmware
|
- linux-firmware
|
||||||
|
- net-dns/bind-tools
|
||||||
|
# - www-client/lynx
|
||||||
|
- app-admin/supervisor
|
||||||
|
- dev-python/pip
|
||||||
|
|
||||||
AGI_cloud_pkgs:
|
AGI_cloud_pkgs:
|
||||||
# get these from base.json
|
# get these from base.json
|
||||||
@@ -83,12 +103,10 @@ AGI_cloud_pkgs:
|
|||||||
- tmux
|
- tmux
|
||||||
- app-misc/screen
|
- app-misc/screen
|
||||||
- dev-vcs/git
|
- dev-vcs/git
|
||||||
- net-misc/curl
|
|
||||||
- usbutils
|
- usbutils
|
||||||
- pciutils
|
- pciutils
|
||||||
- net-misc/ntp
|
- net-misc/ntp
|
||||||
- net-fs/nfs-utils
|
- net-fs/nfs-utils
|
||||||
# get these from config.json
|
# get these from config.json
|
||||||
- app-emulation/cloud-init
|
# - app-emulation/cloud-init
|
||||||
- sys-block/open-iscsi
|
# - sys-block/open-iscsi
|
||||||
|
|
||||||
|
|||||||
1
roles/base
Symbolic link
1
roles/base
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/o/data/TestForge/src/ansible/roles/base
|
||||||
1
roles/proxy
Symbolic link
1
roles/proxy
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/o/data/TestForge/src/ansible/roles/proxy
|
||||||
@@ -12,6 +12,7 @@ DOCTEST=$(LOCAL_DOCTEST)
|
|||||||
|
|
||||||
default:: local
|
default:: local
|
||||||
|
|
||||||
|
update::
|
||||||
test:: local # hourly
|
test:: local # hourly
|
||||||
sudo -u ${USER} /var/local/src/var_local_$(ROLE).bash $@
|
sudo -u ${USER} /var/local/src/var_local_$(ROLE).bash $@
|
||||||
|
|
||||||
|
|||||||
25
roles/toxcore/README.md
Normal file
25
roles/toxcore/README.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
This role builds on, and requires, ../proxy_role which
|
||||||
|
basics for cntlm and socks and http and https proxies.
|
||||||
|
|
||||||
|
Look at the variables in defaults/main.yml to customize the role, and
|
||||||
|
double-check the settings in vars/*.yml.
|
||||||
|
|
||||||
|
It is multi-target and should run on Gentoo2, Debian4, Devuan5, Ubuntu18
|
||||||
|
athough only tested on Gentoo. To bring it up to date, just copy the
|
||||||
|
existing files in vars and maybe tasks to the new name and edit to suit,
|
||||||
|
but be advised that this code is systemd-challenged, like its author.
|
||||||
|
|
||||||
|
This role assumes a proxy is working, and has tests to check SSL
|
||||||
|
security, and expects you want to require TLS1.3, as anything less
|
||||||
|
is broken. We are seeing wide-spread MITM ssl attacks on anything less.
|
||||||
|
There is support for testing SSL across proxies, including tor.
|
||||||
|
|
||||||
|
It has basic testing scripts in place like pylint to test itself and
|
||||||
|
anything else.
|
||||||
|
|
||||||
|
It then puts the software in place to use the Tox internet-messager,
|
||||||
|
including ctypes wrapping of the library into Python, and an
|
||||||
|
integration testsuite.
|
||||||
|
|
||||||
|
It has 2 test scripts toxcore_daily.bash and toxcore_daily.bash than
|
||||||
|
run quick status checks and indepth testing respectively.
|
||||||
193
roles/toxcore/files/gentoo.xml
Normal file
193
roles/toxcore/files/gentoo.xml
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
<!--
|
||||||
|
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
|
||||||
|
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
|
||||||
|
virsh edit gentoo
|
||||||
|
or other application using the libvirt API.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<domain type='kvm'>
|
||||||
|
<name>gentoo</name>
|
||||||
|
<uuid>1362f7fd-ea55-4f2f-91c5-3b61ec26c1a0</uuid>
|
||||||
|
<metadata>
|
||||||
|
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
|
||||||
|
<libosinfo:os id="http://gentoo.org/gentoo/rolling"/>
|
||||||
|
</libosinfo:libosinfo>
|
||||||
|
</metadata>
|
||||||
|
<memory unit='KiB'>3121152</memory>
|
||||||
|
<currentMemory unit='KiB'>2097152</currentMemory>
|
||||||
|
<memoryBacking>
|
||||||
|
<source type='memfd'/>
|
||||||
|
<access mode='shared'/>
|
||||||
|
</memoryBacking>
|
||||||
|
<vcpu placement='static'>1</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc-q35-8.1'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
<acpi/>
|
||||||
|
<apic/>
|
||||||
|
<vmport state='off'/>
|
||||||
|
</features>
|
||||||
|
<cpu mode='host-passthrough' check='none' migratable='on'/>
|
||||||
|
<clock offset='utc'>
|
||||||
|
<timer name='rtc' tickpolicy='catchup'/>
|
||||||
|
<timer name='pit' tickpolicy='delay'/>
|
||||||
|
<timer name='hpet' present='no'/>
|
||||||
|
</clock>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<pm>
|
||||||
|
<suspend-to-mem enabled='no'/>
|
||||||
|
<suspend-to-disk enabled='no'/>
|
||||||
|
</pm>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||||
|
<disk type='file' device='disk'>
|
||||||
|
<driver name='qemu' type='qcow2'/>
|
||||||
|
<source file='/var/lib/libvirt/images/gentoo1.qcow2'/>
|
||||||
|
<target dev='vda' bus='virtio'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
|
||||||
|
</disk>
|
||||||
|
<disk type='file' device='cdrom'>
|
||||||
|
<driver name='qemu' type='raw'/>
|
||||||
|
<target dev='sda' bus='sata'/>
|
||||||
|
<readonly/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='0' model='pcie-root'/>
|
||||||
|
<controller type='pci' index='1' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='1' port='0x10'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='2' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='2' port='0x11'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='3' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='3' port='0x12'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='4' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='4' port='0x13'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='5' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='5' port='0x14'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='6' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='6' port='0x15'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='7' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='7' port='0x16'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='8' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='8' port='0x17'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='9' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='9' port='0x18'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='10' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='10' port='0x19'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='11' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='11' port='0x1a'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='12' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='12' port='0x1b'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='13' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='13' port='0x1c'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='14' model='pcie-root-port'>
|
||||||
|
<model name='pcie-root-port'/>
|
||||||
|
<target chassis='14' port='0x1d'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='sata' index='0'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='virtio-serial' index='0'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<interface type='network'>
|
||||||
|
<mac address='52:54:00:be:61:e1'/>
|
||||||
|
<source network='Whonix-External'/>
|
||||||
|
<model type='virtio'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
|
||||||
|
</interface>
|
||||||
|
<serial type='pty'>
|
||||||
|
<target type='isa-serial' port='0'>
|
||||||
|
<model name='isa-serial'/>
|
||||||
|
</target>
|
||||||
|
</serial>
|
||||||
|
<console type='pty'>
|
||||||
|
<target type='serial' port='0'/>
|
||||||
|
</console>
|
||||||
|
<channel type='unix'>
|
||||||
|
<target type='virtio' name='org.qemu.guest_agent.0'/>
|
||||||
|
<address type='virtio-serial' controller='0' bus='0' port='1'/>
|
||||||
|
</channel>
|
||||||
|
<channel type='spicevmc'>
|
||||||
|
<target type='virtio' name='com.redhat.spice.0'/>
|
||||||
|
<address type='virtio-serial' controller='0' bus='0' port='2'/>
|
||||||
|
</channel>
|
||||||
|
<input type='tablet' bus='usb'>
|
||||||
|
<address type='usb' bus='0' port='1'/>
|
||||||
|
</input>
|
||||||
|
<input type='mouse' bus='ps2'/>
|
||||||
|
<input type='keyboard' bus='ps2'/>
|
||||||
|
<graphics type='spice' autoport='yes'>
|
||||||
|
<listen type='address'/>
|
||||||
|
<image compression='off'/>
|
||||||
|
</graphics>
|
||||||
|
<sound model='ich9'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
|
||||||
|
</sound>
|
||||||
|
<audio id='1' type='spice'/>
|
||||||
|
<video>
|
||||||
|
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
|
||||||
|
</video>
|
||||||
|
<redirdev bus='usb' type='spicevmc'>
|
||||||
|
<address type='usb' bus='0' port='2'/>
|
||||||
|
</redirdev>
|
||||||
|
<redirdev bus='usb' type='spicevmc'>
|
||||||
|
<address type='usb' bus='0' port='3'/>
|
||||||
|
</redirdev>
|
||||||
|
<watchdog model='itco' action='reset'/>
|
||||||
|
<memballoon model='virtio'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
|
||||||
|
</memballoon>
|
||||||
|
<rng model='virtio'>
|
||||||
|
<backend model='random'>/dev/urandom</backend>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
|
||||||
|
</rng>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
||||||
674
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/COPYING
Normal file
674
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/COPYING
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
91
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/README
Normal file
91
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/README
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
Python module and tools for communicating in the Assuan_ protocol.
|
||||||
|
|
||||||
|
There are a number of GnuPG_ wrappers for python `out there`__, but
|
||||||
|
they mostly work via the ``gpg`` executable. This is an attempt to
|
||||||
|
cut to the chase and speak directly to ``gpgme-tool`` (source__) over
|
||||||
|
a well-defined socket protocol.
|
||||||
|
|
||||||
|
__ wrappers_
|
||||||
|
__ gpgme-tool_
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
Packages
|
||||||
|
--------
|
||||||
|
|
||||||
|
Gentoo
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
I've packaged ``pyassuan`` for Gentoo_. You need layman_ and
|
||||||
|
my `wtk overlay`_. Install with::
|
||||||
|
|
||||||
|
# emerge -av app-portage/layman
|
||||||
|
# layman --add wtk
|
||||||
|
# emerge -av dev-python/pyassuan
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
``pyassuan`` is a simple package with no external dependencies outside
|
||||||
|
the Python 3.3+ standard library.
|
||||||
|
|
||||||
|
Installing by hand
|
||||||
|
------------------
|
||||||
|
|
||||||
|
``pyassuan`` is available as a Git_ repository::
|
||||||
|
|
||||||
|
$ git clone git://tremily.us/pyassuan.git
|
||||||
|
|
||||||
|
See the homepage_ for details. To install the checkout, run the
|
||||||
|
standard::
|
||||||
|
|
||||||
|
$ python setup.py install
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
Checkout the docstrings and the examples in ``bin``.
|
||||||
|
|
||||||
|
Testing
|
||||||
|
=======
|
||||||
|
|
||||||
|
Run the internal unit tests with `Python 3.2+'s unittest discovery`__::
|
||||||
|
|
||||||
|
$ python -m unittest discover
|
||||||
|
|
||||||
|
To test running servers by hand, you can use `gpg-connect-agent`_.
|
||||||
|
Despite the name, this program can connect to any Assuan server::
|
||||||
|
|
||||||
|
$ gpg-connect-agent --raw-socket name
|
||||||
|
|
||||||
|
__ unittest-discovery_
|
||||||
|
|
||||||
|
Licence
|
||||||
|
=======
|
||||||
|
|
||||||
|
This project is distributed under the `GNU General Public License
|
||||||
|
Version 3`_ or greater.
|
||||||
|
|
||||||
|
Author
|
||||||
|
======
|
||||||
|
|
||||||
|
W. Trevor King
|
||||||
|
wking@tremily.us
|
||||||
|
|
||||||
|
|
||||||
|
.. _Assuan: http://www.gnupg.org/documentation/manuals/assuan/
|
||||||
|
.. _GnuPG: http://www.gnupg.org/
|
||||||
|
.. _wrappers: http://wiki.python.org/moin/GnuPrivacyGuard
|
||||||
|
.. _gpgme-tool:
|
||||||
|
http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gpgme.git;a=blob;f=src/gpgme-tool.c;hb=HEAD
|
||||||
|
.. _Gentoo: http://www.gentoo.org/
|
||||||
|
.. _layman: http://layman.sourceforge.net/
|
||||||
|
.. _wtk overlay: http://blog.tremily.us/posts/Gentoo_overlay/
|
||||||
|
.. _Git: http://git-scm.com/
|
||||||
|
.. _homepage: http://blog.tremily.us/posts/pyassuan/
|
||||||
|
.. _gpg-connect-agent:
|
||||||
|
http://www.gnupg.org/documentation/manuals/gnupg-devel/gpg_002dconnect_002dagent.html
|
||||||
|
.. _unittest-discovery:
|
||||||
|
https://docs.python.org/3.5/library/unittest.html#unittest-test-discovery
|
||||||
|
.. _GNU General Public License Version 3: http://www.gnu.org/licenses/gpl.html
|
||||||
67
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/bin/get-info.py
Executable file
67
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/bin/get-info.py
Executable file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Simple pinentry program for getting server info.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pyassuan import __version__
|
||||||
|
from pyassuan import client as _client
|
||||||
|
from pyassuan import common as _common
|
||||||
|
from pyassuan import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
parser.add_argument(
|
||||||
|
'-v', '--version', action='version',
|
||||||
|
version='%(prog)s {}'.format(__version__))
|
||||||
|
parser.add_argument(
|
||||||
|
'-V', '--verbose', action='count', default=0,
|
||||||
|
help='increase verbosity')
|
||||||
|
parser.add_argument(
|
||||||
|
'filename',
|
||||||
|
help="path to server's unix socket")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
client = _client.AssuanClient(name='get-info', close_on_disconnect=True)
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
client.logger.setLevel(max(
|
||||||
|
logging.DEBUG, client.logger.level - 10*args.verbose))
|
||||||
|
|
||||||
|
client.connect(socket_path=args.filename)
|
||||||
|
try:
|
||||||
|
response = client.read_response()
|
||||||
|
assert response.type == 'OK', response
|
||||||
|
client.make_request(_common.Request('HELP'))
|
||||||
|
client.make_request(_common.Request('HELP GETINFO'))
|
||||||
|
for attribute in ['version', 'pid', 'socket_name', 'ssh_socket_name']:
|
||||||
|
try:
|
||||||
|
client.make_request(_common.Request('GETINFO', attribute))
|
||||||
|
except _error.AssuanError as e:
|
||||||
|
if e.message.startswith('No data'):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
client.make_request(_common.Request('BYE'))
|
||||||
|
client.disconnect()
|
||||||
393
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/bin/pinentry.py
Executable file
393
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/bin/pinentry.py
Executable file
@@ -0,0 +1,393 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (C) 2012-2017 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Simple pinentry program for getting pins from a terminal.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import copy as _copy
|
||||||
|
import os as _os
|
||||||
|
import os.path as _os_path
|
||||||
|
import pprint as _pprint
|
||||||
|
import re as _re
|
||||||
|
import signal as _signal
|
||||||
|
import sys as _sys
|
||||||
|
import termios as _termios
|
||||||
|
|
||||||
|
from pyassuan import __version__
|
||||||
|
from pyassuan import server as _server
|
||||||
|
from pyassuan import common as _common
|
||||||
|
from pyassuan import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
class PinEntry (_server.AssuanServer):
|
||||||
|
"""pinentry protocol server
|
||||||
|
|
||||||
|
See ``pinentry-0.8.0/doc/pinentry.texi`` at::
|
||||||
|
|
||||||
|
ftp://ftp.gnupg.org/gcrypt/pinentry/
|
||||||
|
http://www.gnupg.org/aegypten/
|
||||||
|
|
||||||
|
for details on the pinentry interface.
|
||||||
|
|
||||||
|
Alternatively, you can just watch the logs and guess ;). Here's a
|
||||||
|
trace when driven by GnuPG 2.0.28 (libgcrypt 1.6.3)::
|
||||||
|
|
||||||
|
S: OK Your orders please
|
||||||
|
C: OPTION grab
|
||||||
|
S: OK
|
||||||
|
C: OPTION ttyname=/dev/pts/6
|
||||||
|
S: OK
|
||||||
|
C: OPTION ttytype=xterm
|
||||||
|
S: OK
|
||||||
|
C: OPTION lc-ctype=en_US.UTF-8
|
||||||
|
S: OK
|
||||||
|
C: OPTION lc-messages=en_US.UTF-8
|
||||||
|
S: OK
|
||||||
|
C: OPTION allow-external-password-cache
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-ok=_OK
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-cancel=_Cancel
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-yes=_Yes
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-no=_No
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-prompt=PIN:
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-pwmngr=_Save in password manager
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-cf-visi=Do you really want to make your passphrase visible on the screen?
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-tt-visi=Make passphrase visible
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-tt-hide=Hide passphrase
|
||||||
|
S: OK
|
||||||
|
C: GETINFO pid
|
||||||
|
S: D 14309
|
||||||
|
S: OK
|
||||||
|
C: SETKEYINFO u/S9464F2C2825D2FE3
|
||||||
|
S: OK
|
||||||
|
C: SETDESC Enter passphrase%0A
|
||||||
|
S: OK
|
||||||
|
C: SETPROMPT Passphrase
|
||||||
|
S: OK
|
||||||
|
C: GETPIN
|
||||||
|
S: D testing!
|
||||||
|
S: OK
|
||||||
|
C: BYE
|
||||||
|
S: OK closing connection
|
||||||
|
"""
|
||||||
|
_digit_regexp = _re.compile(r'\d+')
|
||||||
|
|
||||||
|
# from proc(5): pid comm state ppid pgrp session tty_nr tpgid
|
||||||
|
_tpgrp_regexp = _re.compile(r'\d+ \(\S+\) . \d+ \d+ \d+ \d+ (\d+)')
|
||||||
|
|
||||||
|
def __init__(self, name='pinentry', strict_options=False,
|
||||||
|
single_request=True, **kwargs):
|
||||||
|
self.strings = {}
|
||||||
|
self.connection = {}
|
||||||
|
super(PinEntry, self).__init__(
|
||||||
|
name=name, strict_options=strict_options,
|
||||||
|
single_request=single_request, **kwargs)
|
||||||
|
self.valid_options.append('ttyname')
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
super(PinEntry, self).reset()
|
||||||
|
self.strings.clear()
|
||||||
|
self.connection.clear()
|
||||||
|
|
||||||
|
# user interface
|
||||||
|
|
||||||
|
def _connect(self):
|
||||||
|
self.logger.info('connecting to user')
|
||||||
|
self.logger.debug('options:\n{}'.format(_pprint.pformat(self.options)))
|
||||||
|
tty_name = self.options.get('ttyname', None)
|
||||||
|
if tty_name:
|
||||||
|
self.connection['tpgrp'] = self._get_pgrp(tty_name)
|
||||||
|
self.logger.info(
|
||||||
|
'open to-user output stream for {}'.format(tty_name))
|
||||||
|
self.connection['to_user'] = open(tty_name, 'w')
|
||||||
|
self.logger.info(
|
||||||
|
'open from-user input stream for {}'.format(tty_name))
|
||||||
|
self.connection['from_user'] = open(tty_name, 'r')
|
||||||
|
self.logger.info('get current termios line discipline')
|
||||||
|
self.connection['original termios'] = _termios.tcgetattr(
|
||||||
|
self.connection['to_user']) # [iflag, oflag, cflag, lflag, ...]
|
||||||
|
new_termios = _copy.deepcopy(self.connection['original termios'])
|
||||||
|
# translate carriage return to newline on input
|
||||||
|
new_termios[0] |= _termios.ICRNL
|
||||||
|
# do not ignore carriage return on input
|
||||||
|
new_termios[0] &= ~_termios.IGNCR
|
||||||
|
# do not echo input characters
|
||||||
|
new_termios[3] &= ~_termios.ECHO
|
||||||
|
# echo input characters
|
||||||
|
#new_termios[3] |= _termios.ECHO
|
||||||
|
# echo the NL character even if ECHO is not set
|
||||||
|
new_termios[3] |= _termios.ECHONL
|
||||||
|
# enable canonical mode
|
||||||
|
new_termios[3] |= _termios.ICANON
|
||||||
|
self.logger.info('adjust termios line discipline')
|
||||||
|
_termios.tcsetattr(
|
||||||
|
self.connection['to_user'], _termios.TCSANOW, new_termios)
|
||||||
|
self.logger.info('send SIGSTOP to pgrp {}'.format(
|
||||||
|
self.connection['tpgrp']))
|
||||||
|
#_os.killpg(self.connection['tpgrp'], _signal.SIGSTOP)
|
||||||
|
_os.kill(-self.connection['tpgrp'], _signal.SIGSTOP)
|
||||||
|
self.connection['tpgrp stopped'] = True
|
||||||
|
else:
|
||||||
|
self.logger.info('no TTY name given; use stdin/stdout for I/O')
|
||||||
|
self.connection['to_user'] = _sys.stdout
|
||||||
|
self.connection['from_user'] = _sys.stdin
|
||||||
|
self.logger.info('connected to user')
|
||||||
|
self.connection['to_user'].write('\n') # give a clean line to work on
|
||||||
|
self.connection['active'] = True
|
||||||
|
|
||||||
|
def _disconnect(self):
|
||||||
|
self.logger.info('disconnecting from user')
|
||||||
|
try:
|
||||||
|
if self.connection.get('original termios', None):
|
||||||
|
self.logger.info('restore original termios line discipline')
|
||||||
|
_termios.tcsetattr(
|
||||||
|
self.connection['to_user'], _termios.TCSANOW,
|
||||||
|
self.connection['original termios'])
|
||||||
|
if self.connection.get('tpgrp stopped', None) is True:
|
||||||
|
self.logger.info(
|
||||||
|
'send SIGCONT to pgrp {}'.format(self.connection['tpgrp']))
|
||||||
|
#_os.killpg(self.connection['tpgrp'], _signal.SIGCONT)
|
||||||
|
_os.kill(-self.connection['tpgrp'], _signal.SIGCONT)
|
||||||
|
if self.connection.get('to_user', None) not in [None, _sys.stdout]:
|
||||||
|
self.logger.info('close to-user output stream')
|
||||||
|
self.connection['to_user'].close()
|
||||||
|
if self.connection.get('from_user',None) not in [None,_sys.stdout]:
|
||||||
|
self.logger.info('close from-user input stream')
|
||||||
|
self.connection['from_user'].close()
|
||||||
|
finally:
|
||||||
|
self.connection = {'active': False}
|
||||||
|
self.logger.info('disconnected from user')
|
||||||
|
|
||||||
|
def _get_pgrp(self, tty_name):
|
||||||
|
self.logger.info('find process group contolling {}'.format(tty_name))
|
||||||
|
proc = '/proc'
|
||||||
|
for name in _os.listdir(proc):
|
||||||
|
path = _os_path.join(proc, name)
|
||||||
|
if not (self._digit_regexp.match(name) and _os_path.isdir(path)):
|
||||||
|
continue # not a process directory
|
||||||
|
self.logger.debug('checking process {}'.format(name))
|
||||||
|
fd_path = _os_path.join(path, 'fd', '0')
|
||||||
|
try:
|
||||||
|
link = _os.readlink(fd_path)
|
||||||
|
except OSError as e:
|
||||||
|
self.logger.debug('not our process: {}'.format(e))
|
||||||
|
continue # permission denied (not one of our processes)
|
||||||
|
if link != tty_name:
|
||||||
|
self.logger.debug('wrong tty: {}'.format(link))
|
||||||
|
continue # not attached to our target tty
|
||||||
|
stat_path = _os_path.join(path, 'stat')
|
||||||
|
stat = open(stat_path, 'r').read()
|
||||||
|
self.logger.debug('check stat for pgrp: {}'.format(stat))
|
||||||
|
match = self._tpgrp_regexp.match(stat)
|
||||||
|
assert match != None, stat
|
||||||
|
pgrp = int(match.group(1))
|
||||||
|
self.logger.info('found pgrp {} for {}'.format(pgrp, tty_name))
|
||||||
|
return pgrp
|
||||||
|
raise ValueError(tty_name)
|
||||||
|
|
||||||
|
def _write(self, string):
|
||||||
|
"Write text to the user's terminal."
|
||||||
|
self.connection['to_user'].write(string + '\n')
|
||||||
|
self.connection['to_user'].flush()
|
||||||
|
|
||||||
|
def _read(self):
|
||||||
|
"Read and return a line from the user's terminal."
|
||||||
|
# drop trailing newline
|
||||||
|
return self.connection['from_user'].readline()[:-1]
|
||||||
|
|
||||||
|
def _prompt(self, prompt='?', error=None, add_colon=True):
|
||||||
|
if add_colon:
|
||||||
|
prompt += ':'
|
||||||
|
if error:
|
||||||
|
self.connection['to_user'].write(error)
|
||||||
|
self.connection['to_user'].write('\n')
|
||||||
|
self.connection['to_user'].write(prompt)
|
||||||
|
self.connection['to_user'].write(' ')
|
||||||
|
self.connection['to_user'].flush()
|
||||||
|
return self._read()
|
||||||
|
|
||||||
|
# assuan handlers
|
||||||
|
|
||||||
|
def _handle_GETINFO(self, arg):
|
||||||
|
if arg == 'pid':
|
||||||
|
yield _common.Response('D', str(_os.getpid()).encode('ascii'))
|
||||||
|
elif arg == 'version':
|
||||||
|
yield _common.Response('D', __version__.encode('ascii'))
|
||||||
|
else:
|
||||||
|
raise _error.AssuanError(message='Invalid parameter')
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETKEYINFO(self, arg):
|
||||||
|
self.strings['key info'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_CLEARPASSPHRASE(self, arg):
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETDESC(self, arg):
|
||||||
|
self.strings['description'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETPROMPT(self, arg):
|
||||||
|
self.strings['prompt'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETERROR(self, arg):
|
||||||
|
self.strings['error'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETTITLE(self, arg):
|
||||||
|
self.strings['title'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETOK(self, arg):
|
||||||
|
self.strings['ok'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETCANCEL(self, arg):
|
||||||
|
self.strings['cancel'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETNOTOK(self, arg):
|
||||||
|
self.strings['not ok'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETQUALITYBAR(self, arg):
|
||||||
|
"""Adds a quality indicator to the GETPIN window.
|
||||||
|
|
||||||
|
This indicator is updated as the passphrase is typed. The
|
||||||
|
clients needs to implement an inquiry named "QUALITY" which
|
||||||
|
gets passed the current passphrase (percent-plus escaped) and
|
||||||
|
should send back a string with a single numerical vauelue
|
||||||
|
between -100 and 100. Negative values will be displayed in
|
||||||
|
red.
|
||||||
|
|
||||||
|
If a custom label for the quality bar is required, just add
|
||||||
|
that label as an argument as percent escaped string. You will
|
||||||
|
need this feature to translate the label because pinentry has
|
||||||
|
no internal gettext except for stock strings from the toolkit
|
||||||
|
library.
|
||||||
|
|
||||||
|
If you want to show a tooltip for the quality bar, you may use
|
||||||
|
|
||||||
|
C: SETQUALITYBAR_TT string
|
||||||
|
S: OK
|
||||||
|
|
||||||
|
With STRING being a percent escaped string shown as the tooltip.
|
||||||
|
|
||||||
|
Here is a real world example of these commands in use:
|
||||||
|
|
||||||
|
C: SETQUALITYBAR Quality%3a
|
||||||
|
S: OK
|
||||||
|
C: SETQUALITYBAR_TT The quality of the text entered above.%0aPlease ask your administrator for details about the criteria.
|
||||||
|
S: OK
|
||||||
|
"""
|
||||||
|
self.strings['qualitybar'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETQUALITYBAR_TT(self, arg):
|
||||||
|
self.strings['qualitybar_tooltip'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_GETPIN(self, arg):
|
||||||
|
try:
|
||||||
|
self._connect()
|
||||||
|
self._write(self.strings['description'])
|
||||||
|
if 'key info' in self.strings:
|
||||||
|
self._write('key: {}'.format(self.strings['key info']))
|
||||||
|
if 'qualitybar' in self.strings:
|
||||||
|
self._write(self.strings['qualitybar'])
|
||||||
|
pin = self._prompt(
|
||||||
|
prompt=self.strings['prompt'],
|
||||||
|
error=self.strings.get('error'),
|
||||||
|
add_colon=False)
|
||||||
|
finally:
|
||||||
|
self._disconnect()
|
||||||
|
yield _common.Response('D', pin.encode('ascii'))
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_CONFIRM(self, arg):
|
||||||
|
try:
|
||||||
|
self._connect()
|
||||||
|
self._write(self.strings['description'])
|
||||||
|
self._write('1) '+self.strings['ok'])
|
||||||
|
self._write('2) '+self.strings['not ok'])
|
||||||
|
value = self._prompt('?')
|
||||||
|
finally:
|
||||||
|
self._disconnect()
|
||||||
|
if value == '1':
|
||||||
|
yield _common.Response('OK')
|
||||||
|
else:
|
||||||
|
raise _error.AssuanError(message='Not confirmed')
|
||||||
|
|
||||||
|
def _handle_MESSAGE(self, arg):
|
||||||
|
self._write(self.strings['description'])
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_CONFIRM(self, args):
|
||||||
|
assert args == '--one-button', args
|
||||||
|
try:
|
||||||
|
self._connect()
|
||||||
|
self._write(self.strings['description'])
|
||||||
|
self._write('1) '+self.strings['ok'])
|
||||||
|
value = self._prompt('?')
|
||||||
|
finally:
|
||||||
|
self._disconnect()
|
||||||
|
assert value == '1', value
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
parser.add_argument(
|
||||||
|
'-v', '--version', action='version',
|
||||||
|
version='%(prog)s {}'.format(__version__))
|
||||||
|
parser.add_argument(
|
||||||
|
'-V', '--verbose', action='count', default=0,
|
||||||
|
help='increase verbosity')
|
||||||
|
parser.add_argument(
|
||||||
|
'--display',
|
||||||
|
help='set X display (ignored by this implementation)')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
p = PinEntry()
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
p.logger.setLevel(max(
|
||||||
|
logging.DEBUG, p.logger.level - 10*args.verbose))
|
||||||
|
|
||||||
|
try:
|
||||||
|
p.run()
|
||||||
|
except:
|
||||||
|
p.logger.error(
|
||||||
|
'exiting due to exception:\n{}'.format(
|
||||||
|
traceback.format_exc().rstrip()))
|
||||||
|
raise
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""A Python implementation of the `Assuan protocol`_.
|
||||||
|
|
||||||
|
.. _Assuan protocol: http://www.gnupg.org/documentation/manuals/assuan/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging as _logging
|
||||||
|
import logging.handlers as _logging_handlers
|
||||||
|
|
||||||
|
|
||||||
|
__version__ = '0.2'
|
||||||
|
|
||||||
|
LOG = _logging.getLogger('pyassuan')
|
||||||
|
LOG.setLevel(_logging.ERROR)
|
||||||
|
LOG.addHandler(_logging.StreamHandler())
|
||||||
|
#LOG.addHandler(_logging.FileHandler('/tmp/pinentry.log'))
|
||||||
|
#LOG.addHandler(_logging_handlers.SysLogHandler(address='/dev/log'))
|
||||||
|
LOG.handlers[0].setFormatter(
|
||||||
|
_logging.Formatter('%(name)s: %(levelname)s: %(message)s'))
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import logging as _logging
|
||||||
|
import socket as _socket
|
||||||
|
import sys as _sys
|
||||||
|
|
||||||
|
from . import LOG as _LOG
|
||||||
|
from . import common as _common
|
||||||
|
from . import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
class AssuanClient (object):
|
||||||
|
"""A single-threaded Assuan client based on the `development suggestions`_
|
||||||
|
|
||||||
|
.. _development suggestions:
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-code.html
|
||||||
|
"""
|
||||||
|
def __init__(self, name, logger=_LOG, use_sublogger=True,
|
||||||
|
close_on_disconnect=False):
|
||||||
|
self.name = name
|
||||||
|
if use_sublogger:
|
||||||
|
logger = _logging.getLogger('{}.{}'.format(logger.name, self.name))
|
||||||
|
self.logger = logger
|
||||||
|
self.close_on_disconnect = close_on_disconnect
|
||||||
|
self.input = self.output = self.socket = None
|
||||||
|
|
||||||
|
def connect(self, socket_path=None):
|
||||||
|
if socket_path:
|
||||||
|
self.logger.info(
|
||||||
|
'connect to Unix socket at {}'.format(socket_path))
|
||||||
|
self.socket = _socket.socket(_socket.AF_UNIX, _socket.SOCK_STREAM)
|
||||||
|
self.socket.connect(socket_path)
|
||||||
|
self.input = self.socket.makefile('rb')
|
||||||
|
self.output = self.socket.makefile('wb')
|
||||||
|
else:
|
||||||
|
if not self.input:
|
||||||
|
self.logger.info('read from stdin')
|
||||||
|
self.input = _sys.stdin.buffer
|
||||||
|
if not self.output:
|
||||||
|
self.logger.info('write to stdout')
|
||||||
|
self.output = _sys.stdout.buffer
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
if self.close_on_disconnect:
|
||||||
|
self.logger.info('disconnecting')
|
||||||
|
if self.input is not None:
|
||||||
|
self.input.close()
|
||||||
|
self.input = None
|
||||||
|
if self.output is not None:
|
||||||
|
self.output.close()
|
||||||
|
self.output = None
|
||||||
|
if self.socket is not None:
|
||||||
|
self.socket.shutdown(_socket.SHUT_RDWR)
|
||||||
|
self.socket.close()
|
||||||
|
self.socket = None
|
||||||
|
|
||||||
|
def raise_error(self, error):
|
||||||
|
self.logger.error(str(error))
|
||||||
|
raise(error)
|
||||||
|
|
||||||
|
def read_response(self):
|
||||||
|
line = self.input.readline()
|
||||||
|
if not line:
|
||||||
|
self.raise_error(
|
||||||
|
_error.AssuanError(message='IPC accept call failed'))
|
||||||
|
if len(line) > _common.LINE_LENGTH:
|
||||||
|
self.raise_error(
|
||||||
|
_error.AssuanError(message='Line too long'))
|
||||||
|
if not line.endswith(b'\n'):
|
||||||
|
self.logger.info('S: {}'.format(line))
|
||||||
|
self.raise_error(
|
||||||
|
_error.AssuanError(message='Invalid response'))
|
||||||
|
line = line[:-1] # remove trailing newline
|
||||||
|
response = _common.Response()
|
||||||
|
try:
|
||||||
|
response.from_bytes(line)
|
||||||
|
except _error.AssuanError as e:
|
||||||
|
self.logger.error(str(e))
|
||||||
|
raise
|
||||||
|
self.logger.info('S: {}'.format(response))
|
||||||
|
return response
|
||||||
|
|
||||||
|
def _write_request(self, request):
|
||||||
|
self.logger.info('C: {}'.format(request))
|
||||||
|
self.output.write(bytes(request))
|
||||||
|
self.output.write(b'\n')
|
||||||
|
try:
|
||||||
|
self.output.flush()
|
||||||
|
except IOError:
|
||||||
|
raise
|
||||||
|
|
||||||
|
def make_request(self, request, response=True, expect=['OK']):
|
||||||
|
self._write_request(request=request)
|
||||||
|
if response:
|
||||||
|
return self.get_responses(requests=[request], expect=expect)
|
||||||
|
|
||||||
|
def get_responses(self, requests=None, expect=['OK']):
|
||||||
|
responses = list(self.responses())
|
||||||
|
if responses[-1].type == 'ERR':
|
||||||
|
eresponse = responses[-1]
|
||||||
|
fields = eresponse.parameters.split(' ', 1)
|
||||||
|
code = int(fields[0])
|
||||||
|
if len(fields) > 1:
|
||||||
|
message = fields[1].strip()
|
||||||
|
else:
|
||||||
|
message = None
|
||||||
|
error = _error.AssuanError(code=code, message=message)
|
||||||
|
if requests is not None:
|
||||||
|
error.requests = requests
|
||||||
|
error.responses = responses
|
||||||
|
raise error
|
||||||
|
if expect:
|
||||||
|
assert responses[-1].type in expect, [str(r) for r in responses]
|
||||||
|
data = []
|
||||||
|
for response in responses:
|
||||||
|
if response.type == 'D':
|
||||||
|
data.append(response.parameters)
|
||||||
|
if data:
|
||||||
|
data = b''.join(data)
|
||||||
|
else:
|
||||||
|
data = None
|
||||||
|
return (responses, data)
|
||||||
|
|
||||||
|
def responses(self):
|
||||||
|
while True:
|
||||||
|
response = self.read_response()
|
||||||
|
yield response
|
||||||
|
if response.type not in ['S', '#', 'D']:
|
||||||
|
break
|
||||||
|
|
||||||
|
def send_data(self, data=None, response=True, expect=['OK']):
|
||||||
|
"""Iterate through requests necessary to send ``data`` to a server.
|
||||||
|
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-requests.html
|
||||||
|
"""
|
||||||
|
requests = []
|
||||||
|
if data:
|
||||||
|
encoded_data = _common.encode(data)
|
||||||
|
start = 0
|
||||||
|
stop = min(_common.LINE_LENGTH-4, len(encoded_data)) # 'D ', CR, CL
|
||||||
|
self.logger.debug('sending {} bytes of encoded data'.format(
|
||||||
|
len(encoded_data)))
|
||||||
|
while stop > start:
|
||||||
|
d = encoded_data[start:stop]
|
||||||
|
request = _common.Request(
|
||||||
|
command='D', parameters=encoded_data[start:stop],
|
||||||
|
encoded=True)
|
||||||
|
requests.append(request)
|
||||||
|
self.logger.debug('send {} byte chunk'.format(stop-start))
|
||||||
|
self._write_request(request=request)
|
||||||
|
start = stop
|
||||||
|
stop = start + min(_common.LINE_LENGTH-4,
|
||||||
|
len(encoded_data) - start)
|
||||||
|
request = _common.Request('END')
|
||||||
|
requests.append(request)
|
||||||
|
self._write_request(request=request)
|
||||||
|
if response:
|
||||||
|
return self.get_responses(requests=requests, expect=expect)
|
||||||
|
|
||||||
|
def send_fds(self, fds):
|
||||||
|
"""Send a file descriptor over a Unix socket.
|
||||||
|
"""
|
||||||
|
msg = '# descriptors in flight: {}\n'.format(fds)
|
||||||
|
self.logger.info('C: {}'.format(msg.rstrip('\n')))
|
||||||
|
msg = msg.encode('ascii')
|
||||||
|
return _common.send_fds(
|
||||||
|
socket=self.socket, msg=msg, fds=fds, logger=None)
|
||||||
|
|
||||||
|
def receive_fds(self, msglen=200, maxfds=10):
|
||||||
|
"""Receive file descriptors over a Unix socket.
|
||||||
|
"""
|
||||||
|
msg,fds = _common.receive_fds(
|
||||||
|
socket=self.socket, msglen=msglen, maxfds=maxfds, logger=None)
|
||||||
|
msg = str(msg, 'utf-8')
|
||||||
|
self.logger.info('S: {}'.format(msg.rstrip('\n')))
|
||||||
|
return fds
|
||||||
@@ -0,0 +1,314 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Items common to both the client and server
|
||||||
|
"""
|
||||||
|
|
||||||
|
import array as _array
|
||||||
|
import re as _re
|
||||||
|
import socket as _socket
|
||||||
|
|
||||||
|
from . import LOG as _LOG
|
||||||
|
from . import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
LINE_LENGTH = 1002 # 1000 + [CR,]LF
|
||||||
|
_ENCODE_PATTERN = '(' + '|'.join(['%', '\r', '\n']) + ')'
|
||||||
|
_ENCODE_STR_REGEXP = _re.compile(_ENCODE_PATTERN)
|
||||||
|
_ENCODE_BYTE_REGEXP = _re.compile(_ENCODE_PATTERN.encode('ascii'))
|
||||||
|
_DECODE_STR_REGEXP = _re.compile('(%[0-9A-Fa-f]{2})')
|
||||||
|
_DECODE_BYTE_REGEXP = _re.compile(b'(%[0-9A-Fa-f]{2})')
|
||||||
|
_REQUEST_REGEXP = _re.compile('^(\w+)( *)(.*)\Z')
|
||||||
|
|
||||||
|
|
||||||
|
def encode(data):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> encode('It grew by 5%!\n')
|
||||||
|
'It grew by 5%25!%0A'
|
||||||
|
>>> encode(b'It grew by 5%!\n')
|
||||||
|
b'It grew by 5%25!%0A'
|
||||||
|
"""
|
||||||
|
if isinstance(data, bytes):
|
||||||
|
regexp = _ENCODE_BYTE_REGEXP
|
||||||
|
else:
|
||||||
|
regexp = _ENCODE_STR_REGEXP
|
||||||
|
return regexp.sub(
|
||||||
|
lambda x : to_hex(x.group()), data)
|
||||||
|
|
||||||
|
def decode(data):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> decode('%22Look out!%22%0AWhere%3F')
|
||||||
|
'"Look out!"\nWhere?'
|
||||||
|
>>> decode(b'%22Look out!%22%0AWhere%3F')
|
||||||
|
b'"Look out!"\nWhere?'
|
||||||
|
"""
|
||||||
|
if isinstance(data, bytes):
|
||||||
|
regexp = _DECODE_BYTE_REGEXP
|
||||||
|
else:
|
||||||
|
regexp = _DECODE_STR_REGEXP
|
||||||
|
return regexp.sub(
|
||||||
|
lambda x : from_hex(x.group()), data)
|
||||||
|
|
||||||
|
def from_hex(code):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> from_hex('%22')
|
||||||
|
'"'
|
||||||
|
>>> from_hex('%0A')
|
||||||
|
'\n'
|
||||||
|
>>> from_hex(b'%0A')
|
||||||
|
b'\n'
|
||||||
|
"""
|
||||||
|
c = chr(int(code[1:], 16))
|
||||||
|
if isinstance(code, bytes):
|
||||||
|
c =c.encode('ascii')
|
||||||
|
return c
|
||||||
|
|
||||||
|
def to_hex(char):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> to_hex('"')
|
||||||
|
'%22'
|
||||||
|
>>> to_hex('\n')
|
||||||
|
'%0A'
|
||||||
|
>>> to_hex(b'\n')
|
||||||
|
b'%0A'
|
||||||
|
"""
|
||||||
|
hx = '%{:02X}'.format(ord(char))
|
||||||
|
if isinstance(char, bytes):
|
||||||
|
hx = hx.encode('ascii')
|
||||||
|
return hx
|
||||||
|
|
||||||
|
|
||||||
|
class Request (object):
|
||||||
|
"""A client request
|
||||||
|
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-requests.html
|
||||||
|
|
||||||
|
>>> r = Request(command='BYE')
|
||||||
|
>>> str(r)
|
||||||
|
'BYE'
|
||||||
|
>>> r = Request(command='OPTION', parameters='testing at 5%')
|
||||||
|
>>> str(r)
|
||||||
|
'OPTION testing at 5%25'
|
||||||
|
>>> bytes(r)
|
||||||
|
b'OPTION testing at 5%25'
|
||||||
|
>>> r.from_bytes(b'BYE')
|
||||||
|
>>> r.command
|
||||||
|
'BYE'
|
||||||
|
>>> print(r.parameters)
|
||||||
|
None
|
||||||
|
>>> r.from_bytes(b'OPTION testing at 5%25')
|
||||||
|
>>> r.command
|
||||||
|
'OPTION'
|
||||||
|
>>> print(r.parameters)
|
||||||
|
testing at 5%
|
||||||
|
>>> r.from_bytes(b' invalid')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 170 Invalid request
|
||||||
|
>>> r.from_bytes(b'in-valid')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 170 Invalid request
|
||||||
|
"""
|
||||||
|
def __init__(self, command=None, parameters=None, encoded=False):
|
||||||
|
self.command = command
|
||||||
|
self.parameters = parameters
|
||||||
|
self.encoded = encoded
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.parameters:
|
||||||
|
if self.encoded:
|
||||||
|
encoded_parameters = self.parameters
|
||||||
|
else:
|
||||||
|
encoded_parameters = encode(self.parameters)
|
||||||
|
return '{} {}'.format(self.command, encoded_parameters)
|
||||||
|
return self.command
|
||||||
|
|
||||||
|
def __bytes__(self):
|
||||||
|
if self.parameters:
|
||||||
|
if self.encoded:
|
||||||
|
encoded_parameters = self.parameters
|
||||||
|
else:
|
||||||
|
encoded_parameters = encode(self.parameters)
|
||||||
|
return '{} {}'.format(
|
||||||
|
self.command, encoded_parameters).encode('utf-8')
|
||||||
|
return self.command.encode('utf-8')
|
||||||
|
|
||||||
|
def from_bytes(self, line):
|
||||||
|
if len(line) > 1000: # TODO: byte-vs-str and newlines?
|
||||||
|
raise _error.AssuanError(message='Line too long')
|
||||||
|
line = str(line, encoding='utf-8')
|
||||||
|
match = _REQUEST_REGEXP.match(line)
|
||||||
|
if not match:
|
||||||
|
raise _error.AssuanError(message='Invalid request')
|
||||||
|
self.command = match.group(1)
|
||||||
|
if match.group(3):
|
||||||
|
if match.group(2):
|
||||||
|
self.parameters = decode(match.group(3))
|
||||||
|
else:
|
||||||
|
raise _error.AssuanError(message='Invalid request')
|
||||||
|
else:
|
||||||
|
self.parameters = None
|
||||||
|
|
||||||
|
|
||||||
|
class Response (object):
|
||||||
|
"""A server response
|
||||||
|
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Server-responses.html
|
||||||
|
|
||||||
|
>>> r = Response(type='OK')
|
||||||
|
>>> str(r)
|
||||||
|
'OK'
|
||||||
|
>>> r = Response(type='ERR', parameters='1 General error')
|
||||||
|
>>> str(r)
|
||||||
|
'ERR 1 General error'
|
||||||
|
>>> bytes(r)
|
||||||
|
b'ERR 1 General error'
|
||||||
|
>>> r.from_bytes(b'OK')
|
||||||
|
>>> r.type
|
||||||
|
'OK'
|
||||||
|
>>> print(r.parameters)
|
||||||
|
None
|
||||||
|
>>> r.from_bytes(b'ERR 1 General error')
|
||||||
|
>>> r.type
|
||||||
|
'ERR'
|
||||||
|
>>> print(r.parameters)
|
||||||
|
1 General error
|
||||||
|
>>> r.from_bytes(b' invalid')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 76 Invalid response
|
||||||
|
>>> r.from_bytes(b'in-valid')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 76 Invalid response
|
||||||
|
"""
|
||||||
|
types = {
|
||||||
|
'O': 'OK',
|
||||||
|
'E': 'ERR',
|
||||||
|
'S': 'S',
|
||||||
|
'#': '#',
|
||||||
|
'D': 'D',
|
||||||
|
'I': 'INQUIRE',
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, type=None, parameters=None):
|
||||||
|
self.type = type
|
||||||
|
self.parameters = parameters
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.parameters:
|
||||||
|
return '{} {}'.format(self.type, encode(self.parameters))
|
||||||
|
return self.type
|
||||||
|
|
||||||
|
def __bytes__(self):
|
||||||
|
if self.parameters:
|
||||||
|
if self.type == 'D':
|
||||||
|
return b' '.join((b'D', self.parameters))
|
||||||
|
else:
|
||||||
|
return '{} {}'.format(
|
||||||
|
self.type, encode(self.parameters)).encode('utf-8')
|
||||||
|
return self.type.encode('utf-8')
|
||||||
|
|
||||||
|
def from_bytes(self, line):
|
||||||
|
if len(line) > 1000: # TODO: byte-vs-str and newlines?
|
||||||
|
raise _error.AssuanError(message='Line too long')
|
||||||
|
if line.startswith(b'D'):
|
||||||
|
self.command = t = 'D'
|
||||||
|
else:
|
||||||
|
line = str(line, encoding='utf-8')
|
||||||
|
t = line[0]
|
||||||
|
try:
|
||||||
|
type = self.types[t]
|
||||||
|
except KeyError:
|
||||||
|
raise _error.AssuanError(message='Invalid response')
|
||||||
|
self.type = type
|
||||||
|
if type == 'D': # data
|
||||||
|
self.parameters = decode(line[2:])
|
||||||
|
elif type == '#': # comment
|
||||||
|
self.parameters = decode(line[2:])
|
||||||
|
else:
|
||||||
|
match = _REQUEST_REGEXP.match(line)
|
||||||
|
if not match:
|
||||||
|
raise _error.AssuanError(message='Invalid request')
|
||||||
|
if match.group(3):
|
||||||
|
if match.group(2):
|
||||||
|
self.parameters = decode(match.group(3))
|
||||||
|
else:
|
||||||
|
raise _error.AssuanError(message='Invalid request')
|
||||||
|
else:
|
||||||
|
self.parameters = None
|
||||||
|
|
||||||
|
|
||||||
|
def error_response(error):
|
||||||
|
"""
|
||||||
|
|
||||||
|
>>> from pyassuan.error import AssuanError
|
||||||
|
>>> error = AssuanError(1)
|
||||||
|
>>> response = error_response(error)
|
||||||
|
>>> print(response)
|
||||||
|
ERR 1 General error
|
||||||
|
"""
|
||||||
|
return Response(type='ERR', parameters=str(error))
|
||||||
|
|
||||||
|
|
||||||
|
def send_fds(socket, msg=None, fds=None, logger=_LOG):
|
||||||
|
"""Send a file descriptor over a Unix socket using ``sendmsg``.
|
||||||
|
|
||||||
|
``sendmsg`` suport requires Python >= 3.3.
|
||||||
|
|
||||||
|
Code from
|
||||||
|
http://docs.python.org/dev/library/socket.html#socket.socket.sendmsg
|
||||||
|
|
||||||
|
Assuan equivalent is
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-code.html#function-assuan_005fsendfd
|
||||||
|
"""
|
||||||
|
if msg is None:
|
||||||
|
msg = b''.join(
|
||||||
|
[b'# descriptors in flight: ', str(fds).encode('ascii'), b'\n'])
|
||||||
|
if logger is not None:
|
||||||
|
logger.debug('sending file descriptors {} down {}'.format(fds, socket))
|
||||||
|
return socket.sendmsg(
|
||||||
|
[msg],
|
||||||
|
[(_socket.SOL_SOCKET, _socket.SCM_RIGHTS, _array.array('i', fds))])
|
||||||
|
|
||||||
|
def receive_fds(socket, msglen=200, maxfds=10, logger=_LOG):
|
||||||
|
"""Recieve file descriptors using ``recvmsg``.
|
||||||
|
|
||||||
|
``recvmsg`` suport requires Python >= 3.3.
|
||||||
|
|
||||||
|
Code from http://docs.python.org/dev/library/socket.html
|
||||||
|
|
||||||
|
Assuan equivalent is
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-code.html#fun_002dassuan_005freceivedfd
|
||||||
|
"""
|
||||||
|
fds = _array.array('i') # Array of ints
|
||||||
|
msg,ancdata,flags,addr = socket.recvmsg(
|
||||||
|
msglen, _socket.CMSG_LEN(maxfds * fds.itemsize))
|
||||||
|
for cmsg_level,cmsg_type,cmsg_data in ancdata:
|
||||||
|
if (cmsg_level == _socket.SOL_SOCKET and
|
||||||
|
cmsg_type == _socket.SCM_RIGHTS):
|
||||||
|
# Append data, ignoring any truncated integers at the end.
|
||||||
|
fds.fromstring(
|
||||||
|
cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
|
||||||
|
if logger is not None:
|
||||||
|
logger.debug('receiving file descriptors {} from {} ({})'.format(
|
||||||
|
fds, socket, msg))
|
||||||
|
return (msg, list(fds))
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Assuan errors as defined in `libgpg-error`_.
|
||||||
|
|
||||||
|
The Assuan_ docs_ suggest these error codes.
|
||||||
|
|
||||||
|
.. _libgpg-error: http://www.gnupg.org/related_software/libgpg-error/
|
||||||
|
.. _Assuan:
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Server-responses.html
|
||||||
|
.. _docs: http://www.gnupg.org/documentation/manuals/assuan/Error-codes.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
MESSAGE = { # extracted from libgpg-error-1.10/src/err-codes.h and gpg-error.h
|
||||||
|
0: 'Success',
|
||||||
|
1: 'General error',
|
||||||
|
2: 'Unknown packet',
|
||||||
|
3: 'Unknown version in packet',
|
||||||
|
4: 'Invalid public key algorithm',
|
||||||
|
5: 'Invalid digest algorithm',
|
||||||
|
6: 'Bad public key',
|
||||||
|
7: 'Bad secret key',
|
||||||
|
8: 'Bad signature',
|
||||||
|
9: 'No public key',
|
||||||
|
10: 'Checksum error',
|
||||||
|
11: 'Bad passphrase',
|
||||||
|
12: 'Invalid cipher algorithm',
|
||||||
|
13: 'Keyring open',
|
||||||
|
14: 'Invalid packet',
|
||||||
|
15: 'Invalid armor',
|
||||||
|
16: 'No user ID',
|
||||||
|
17: 'No secret key',
|
||||||
|
18: 'Wrong secret key used',
|
||||||
|
19: 'Bad session key',
|
||||||
|
20: 'Unknown compression algorithm',
|
||||||
|
21: 'Number is not prime',
|
||||||
|
22: 'Invalid encoding method',
|
||||||
|
23: 'Invalid encryption scheme',
|
||||||
|
24: 'Invalid signature scheme',
|
||||||
|
25: 'Invalid attribute',
|
||||||
|
26: 'No value',
|
||||||
|
27: 'Not found',
|
||||||
|
28: 'Value not found',
|
||||||
|
29: 'Syntax error',
|
||||||
|
30: 'Bad MPI value',
|
||||||
|
31: 'Invalid passphrase',
|
||||||
|
32: 'Invalid signature class',
|
||||||
|
33: 'Resources exhausted',
|
||||||
|
34: 'Invalid keyring',
|
||||||
|
35: 'Trust DB error',
|
||||||
|
36: 'Bad certificate',
|
||||||
|
37: 'Invalid user ID',
|
||||||
|
38: 'Unexpected error',
|
||||||
|
39: 'Time conflict',
|
||||||
|
40: 'Keyserver error',
|
||||||
|
41: 'Wrong public key algorithm',
|
||||||
|
42: 'Tribute to D. A.',
|
||||||
|
43: 'Weak encryption key',
|
||||||
|
44: 'Invalid key length',
|
||||||
|
45: 'Invalid argument',
|
||||||
|
46: 'Syntax error in URI',
|
||||||
|
47: 'Invalid URI',
|
||||||
|
48: 'Network error',
|
||||||
|
49: 'Unknown host',
|
||||||
|
50: 'Selftest failed',
|
||||||
|
51: 'Data not encrypted',
|
||||||
|
52: 'Data not processed',
|
||||||
|
53: 'Unusable public key',
|
||||||
|
54: 'Unusable secret key',
|
||||||
|
55: 'Invalid value',
|
||||||
|
56: 'Bad certificate chain',
|
||||||
|
57: 'Missing certificate',
|
||||||
|
58: 'No data',
|
||||||
|
59: 'Bug',
|
||||||
|
60: 'Not supported',
|
||||||
|
61: 'Invalid operation code',
|
||||||
|
62: 'Timeout',
|
||||||
|
63: 'Internal error',
|
||||||
|
64: 'EOF (gcrypt)',
|
||||||
|
65: 'Invalid object',
|
||||||
|
66: 'Provided object is too short',
|
||||||
|
67: 'Provided object is too large',
|
||||||
|
68: 'Missing item in object',
|
||||||
|
69: 'Not implemented',
|
||||||
|
70: 'Conflicting use',
|
||||||
|
71: 'Invalid cipher mode',
|
||||||
|
72: 'Invalid flag',
|
||||||
|
73: 'Invalid handle',
|
||||||
|
74: 'Result truncated',
|
||||||
|
75: 'Incomplete line',
|
||||||
|
76: 'Invalid response',
|
||||||
|
77: 'No agent running',
|
||||||
|
78: 'agent error',
|
||||||
|
79: 'Invalid data',
|
||||||
|
80: 'Unspecific Assuan server fault',
|
||||||
|
81: 'General Assuan error',
|
||||||
|
82: 'Invalid session key',
|
||||||
|
83: 'Invalid S-expression',
|
||||||
|
84: 'Unsupported algorithm',
|
||||||
|
85: 'No pinentry',
|
||||||
|
86: 'pinentry error',
|
||||||
|
87: 'Bad PIN',
|
||||||
|
88: 'Invalid name',
|
||||||
|
89: 'Bad data',
|
||||||
|
90: 'Invalid parameter',
|
||||||
|
91: 'Wrong card',
|
||||||
|
92: 'No dirmngr',
|
||||||
|
93: 'dirmngr error',
|
||||||
|
94: 'Certificate revoked',
|
||||||
|
95: 'No CRL known',
|
||||||
|
96: 'CRL too old',
|
||||||
|
97: 'Line too long',
|
||||||
|
98: 'Not trusted',
|
||||||
|
99: 'Operation cancelled',
|
||||||
|
100: 'Bad CA certificate',
|
||||||
|
101: 'Certificate expired',
|
||||||
|
102: 'Certificate too young',
|
||||||
|
103: 'Unsupported certificate',
|
||||||
|
104: 'Unknown S-expression',
|
||||||
|
105: 'Unsupported protection',
|
||||||
|
106: 'Corrupted protection',
|
||||||
|
107: 'Ambiguous name',
|
||||||
|
108: 'Card error',
|
||||||
|
109: 'Card reset required',
|
||||||
|
110: 'Card removed',
|
||||||
|
111: 'Invalid card',
|
||||||
|
112: 'Card not present',
|
||||||
|
113: 'No PKCS15 application',
|
||||||
|
114: 'Not confirmed',
|
||||||
|
115: 'Configuration error',
|
||||||
|
116: 'No policy match',
|
||||||
|
117: 'Invalid index',
|
||||||
|
118: 'Invalid ID',
|
||||||
|
119: 'No SmartCard daemon',
|
||||||
|
120: 'SmartCard daemon error',
|
||||||
|
121: 'Unsupported protocol',
|
||||||
|
122: 'Bad PIN method',
|
||||||
|
123: 'Card not initialized',
|
||||||
|
124: 'Unsupported operation',
|
||||||
|
125: 'Wrong key usage',
|
||||||
|
126: 'Nothing found',
|
||||||
|
127: 'Wrong blob type',
|
||||||
|
128: 'Missing value',
|
||||||
|
129: 'Hardware problem',
|
||||||
|
130: 'PIN blocked',
|
||||||
|
131: 'Conditions of use not satisfied',
|
||||||
|
132: 'PINs are not synced',
|
||||||
|
133: 'Invalid CRL',
|
||||||
|
134: 'BER error',
|
||||||
|
135: 'Invalid BER',
|
||||||
|
136: 'Element not found',
|
||||||
|
137: 'Identifier not found',
|
||||||
|
138: 'Invalid tag',
|
||||||
|
139: 'Invalid length',
|
||||||
|
140: 'Invalid key info',
|
||||||
|
141: 'Unexpected tag',
|
||||||
|
142: 'Not DER encoded',
|
||||||
|
143: 'No CMS object',
|
||||||
|
144: 'Invalid CMS object',
|
||||||
|
145: 'Unknown CMS object',
|
||||||
|
146: 'Unsupported CMS object',
|
||||||
|
147: 'Unsupported encoding',
|
||||||
|
148: 'Unsupported CMS version',
|
||||||
|
149: 'Unknown algorithm',
|
||||||
|
150: 'Invalid crypto engine',
|
||||||
|
151: 'Public key not trusted',
|
||||||
|
152: 'Decryption failed',
|
||||||
|
153: 'Key expired',
|
||||||
|
154: 'Signature expired',
|
||||||
|
155: 'Encoding problem',
|
||||||
|
156: 'Invalid state',
|
||||||
|
157: 'Duplicated value',
|
||||||
|
158: 'Missing action',
|
||||||
|
159: 'ASN.1 module not found',
|
||||||
|
160: 'Invalid OID string',
|
||||||
|
161: 'Invalid time',
|
||||||
|
162: 'Invalid CRL object',
|
||||||
|
163: 'Unsupported CRL version',
|
||||||
|
164: 'Invalid certificate object',
|
||||||
|
165: 'Unknown name',
|
||||||
|
166: 'A locale function failed',
|
||||||
|
167: 'Not locked',
|
||||||
|
168: 'Protocol violation',
|
||||||
|
169: 'Invalid MAC',
|
||||||
|
170: 'Invalid request',
|
||||||
|
171: 'Unknown extension',
|
||||||
|
172: 'Unknown critical extension',
|
||||||
|
173: 'Locked',
|
||||||
|
174: 'Unknown option',
|
||||||
|
175: 'Unknown command',
|
||||||
|
176: 'Not operational',
|
||||||
|
177: 'No passphrase given',
|
||||||
|
178: 'No PIN given',
|
||||||
|
179: 'Not enabled',
|
||||||
|
180: 'No crypto engine',
|
||||||
|
181: 'Missing key',
|
||||||
|
182: 'Too many objects',
|
||||||
|
183: 'Limit reached',
|
||||||
|
184: 'Not initialized',
|
||||||
|
185: 'Missing issuer certificate',
|
||||||
|
198: 'Operation fully cancelled',
|
||||||
|
199: 'Operation not yet finished',
|
||||||
|
200: 'Buffer too short',
|
||||||
|
201: 'Invalid length specifier in S-expression',
|
||||||
|
202: 'String too long in S-expression',
|
||||||
|
203: 'Unmatched parentheses in S-expression',
|
||||||
|
204: 'S-expression not canonical',
|
||||||
|
205: 'Bad character in S-expression',
|
||||||
|
206: 'Bad quotation in S-expression',
|
||||||
|
207: 'Zero prefix in S-expression',
|
||||||
|
208: 'Nested display hints in S-expression',
|
||||||
|
209: 'Unmatched display hints',
|
||||||
|
210: 'Unexpected reserved punctuation in S-expression',
|
||||||
|
211: 'Bad hexadecimal character in S-expression',
|
||||||
|
212: 'Odd hexadecimal numbers in S-expression',
|
||||||
|
213: 'Bad octal character in S-expression',
|
||||||
|
257: 'General IPC error',
|
||||||
|
258: 'IPC accept call failed',
|
||||||
|
259: 'IPC connect call failed',
|
||||||
|
260: 'Invalid IPC response',
|
||||||
|
261: 'Invalid value passed to IPC',
|
||||||
|
262: 'Incomplete line passed to IPC',
|
||||||
|
263: 'Line passed to IPC too long',
|
||||||
|
264: 'Nested IPC commands',
|
||||||
|
265: 'No data callback in IPC',
|
||||||
|
266: 'No inquire callback in IPC',
|
||||||
|
267: 'Not an IPC server',
|
||||||
|
268: 'Not an IPC client',
|
||||||
|
269: 'Problem starting IPC server',
|
||||||
|
270: 'IPC read error',
|
||||||
|
271: 'IPC write error',
|
||||||
|
273: 'Too much data for IPC layer',
|
||||||
|
274: 'Unexpected IPC command',
|
||||||
|
275: 'Unknown IPC command',
|
||||||
|
276: 'IPC syntax error',
|
||||||
|
277: 'IPC call has been cancelled',
|
||||||
|
278: 'No input source for IPC',
|
||||||
|
279: 'No output source for IPC',
|
||||||
|
280: 'IPC parameter error',
|
||||||
|
281: 'Unknown IPC inquire',
|
||||||
|
1024: 'User defined error code 1',
|
||||||
|
1025: 'User defined error code 2',
|
||||||
|
1026: 'User defined error code 3',
|
||||||
|
1027: 'User defined error code 4',
|
||||||
|
1028: 'User defined error code 5',
|
||||||
|
1029: 'User defined error code 6',
|
||||||
|
1030: 'User defined error code 7',
|
||||||
|
1031: 'User defined error code 8',
|
||||||
|
1032: 'User defined error code 9',
|
||||||
|
1033: 'User defined error code 10',
|
||||||
|
1034: 'User defined error code 11',
|
||||||
|
1035: 'User defined error code 12',
|
||||||
|
1036: 'User defined error code 13',
|
||||||
|
1037: 'User defined error code 14',
|
||||||
|
1038: 'User defined error code 15',
|
||||||
|
1039: 'User defined error code 16',
|
||||||
|
16381: 'System error w/o errno',
|
||||||
|
16382: 'Unknown system error',
|
||||||
|
16383: 'End of file',
|
||||||
|
}
|
||||||
|
UNKNOWN = 'Unknown error code'
|
||||||
|
|
||||||
|
CODE = dict((message,code) for code,message in MESSAGE.items())
|
||||||
|
|
||||||
|
# TODO: system errors (GPG_ERR_E2BIG = GPG_ERR_SYSTEM_ERROR | 0, etc.)
|
||||||
|
|
||||||
|
class AssuanError (Exception):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> e = AssuanError(1)
|
||||||
|
>>> print(e)
|
||||||
|
1 General error
|
||||||
|
>>> e = AssuanError(1024, 'testing!')
|
||||||
|
>>> print(e)
|
||||||
|
1024 testing!
|
||||||
|
>>> e = AssuanError(message='Unknown packet')
|
||||||
|
>>> print(e)
|
||||||
|
2 Unknown packet
|
||||||
|
"""
|
||||||
|
def __init__(self, code=None, message=None):
|
||||||
|
if code is None and message is None:
|
||||||
|
raise ValueError('missing both `code` and `message`')
|
||||||
|
if message is None:
|
||||||
|
message = MESSAGE[code]
|
||||||
|
if code is None:
|
||||||
|
code = CODE.get(message, UNKNOWN)
|
||||||
|
self.code = code
|
||||||
|
self.message = message
|
||||||
|
super(AssuanError, self).__init__('{} {}'.format(code, message))
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import logging as _logging
|
||||||
|
import re as _re
|
||||||
|
import socket as _socket
|
||||||
|
import sys as _sys
|
||||||
|
import threading as _threading
|
||||||
|
import traceback as _traceback
|
||||||
|
|
||||||
|
from . import LOG as _LOG
|
||||||
|
from . import common as _common
|
||||||
|
from . import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
_OPTION_REGEXP = _re.compile('^-?-?([-\w]+)( *)(=?) *(.*?) *\Z')
|
||||||
|
|
||||||
|
|
||||||
|
class AssuanServer (object):
|
||||||
|
"""A single-threaded Assuan server based on the `devolpment suggestions`_
|
||||||
|
|
||||||
|
Extend by subclassing and adding ``_handle_XXX`` methods for each
|
||||||
|
command you want to handle.
|
||||||
|
|
||||||
|
.. _development suggestions:
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Server-code.html
|
||||||
|
"""
|
||||||
|
def __init__(self, name, logger=_LOG, use_sublogger=True,
|
||||||
|
valid_options=None, strict_options=True,
|
||||||
|
single_request=False, listen_to_quit=False,
|
||||||
|
close_on_disconnect=False):
|
||||||
|
self.name = name
|
||||||
|
if use_sublogger:
|
||||||
|
logger = _logging.getLogger('{}.{}'.format(logger.name, self.name))
|
||||||
|
self.logger = logger
|
||||||
|
if valid_options is None:
|
||||||
|
valid_options = []
|
||||||
|
self.valid_options = valid_options
|
||||||
|
self.strict_options = strict_options
|
||||||
|
self.single_request = single_request
|
||||||
|
self.listen_to_quit = listen_to_quit
|
||||||
|
self.close_on_disconnect = close_on_disconnect
|
||||||
|
self.input = self.output = None
|
||||||
|
self.options = {}
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.stop = False
|
||||||
|
self.options.clear()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.reset()
|
||||||
|
self.logger.info('running')
|
||||||
|
self.connect()
|
||||||
|
try:
|
||||||
|
self.handle_requests()
|
||||||
|
finally:
|
||||||
|
self.disconnect()
|
||||||
|
self.logger.info('stopping')
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
if not self.input:
|
||||||
|
self.logger.info('read from stdin')
|
||||||
|
self.input = _sys.stdin.buffer
|
||||||
|
if not self.output:
|
||||||
|
self.logger.info('write to stdout')
|
||||||
|
self.output = _sys.stdout.buffer
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
if self.close_on_disconnect:
|
||||||
|
self.logger.info('disconnecting')
|
||||||
|
self.input = None
|
||||||
|
self.output = None
|
||||||
|
|
||||||
|
def handle_requests(self):
|
||||||
|
self.send_response(_common.Response('OK', 'Your orders please'))
|
||||||
|
self.output.flush()
|
||||||
|
while not self.stop:
|
||||||
|
line = self.input.readline()
|
||||||
|
if not line:
|
||||||
|
break # EOF
|
||||||
|
if len(line) > _common.LINE_LENGTH:
|
||||||
|
self.raise_error(
|
||||||
|
_error.AssuanError(message='Line too long'))
|
||||||
|
if not line.endswith(b'\n'):
|
||||||
|
self.logger.info('C: {}'.format(line))
|
||||||
|
self.send_error_response(
|
||||||
|
_error.AssuanError(message='Invalid request'))
|
||||||
|
continue
|
||||||
|
line = line[:-1] # remove the trailing newline
|
||||||
|
self.logger.info('C: {}'.format(line))
|
||||||
|
request = _common.Request()
|
||||||
|
try:
|
||||||
|
request.from_bytes(line)
|
||||||
|
except _error.AssuanError as e:
|
||||||
|
self.send_error_response(e)
|
||||||
|
continue
|
||||||
|
self.handle_request(request)
|
||||||
|
|
||||||
|
def handle_request(self, request):
|
||||||
|
try:
|
||||||
|
handle = getattr(
|
||||||
|
self, '_handle_{}'.format(request.command))
|
||||||
|
except AttributeError:
|
||||||
|
self.logger.warn('unknown command: {}'.format(request.command))
|
||||||
|
self.send_error_response(
|
||||||
|
_error.AssuanError(message='Unknown command'))
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
responses = handle(request.parameters)
|
||||||
|
for response in responses:
|
||||||
|
self.send_response(response)
|
||||||
|
except _error.AssuanError as error:
|
||||||
|
self.send_error_response(error)
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(
|
||||||
|
'exception while executing {}:\n{}'.format(
|
||||||
|
handle, _traceback.format_exc().rstrip()))
|
||||||
|
self.send_error_response(
|
||||||
|
_error.AssuanError(message='Unspecific Assuan server fault'))
|
||||||
|
return
|
||||||
|
|
||||||
|
def send_response(self, response):
|
||||||
|
"""For internal use by ``.handle_requests()``
|
||||||
|
"""
|
||||||
|
rstring = str(response)
|
||||||
|
self.logger.info('S: {}'.format(response))
|
||||||
|
self.output.write(bytes(response))
|
||||||
|
self.output.write(b'\n')
|
||||||
|
try:
|
||||||
|
self.output.flush()
|
||||||
|
except IOError:
|
||||||
|
if not self.stop:
|
||||||
|
raise
|
||||||
|
|
||||||
|
def send_error_response(self, error):
|
||||||
|
"""For internal use by ``.handle_requests()``
|
||||||
|
"""
|
||||||
|
self.send_response(_common.error_response(error))
|
||||||
|
|
||||||
|
# common commands defined at
|
||||||
|
# http://www.gnupg.org/documentation/manuals/assuan/Client-requests.html
|
||||||
|
|
||||||
|
def _handle_BYE(self, arg):
|
||||||
|
if self.single_request:
|
||||||
|
self.stop = True
|
||||||
|
yield _common.Response('OK', 'closing connection')
|
||||||
|
|
||||||
|
def _handle_RESET(self, arg):
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def _handle_END(self, arg):
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
def _handle_HELP(self, arg):
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
def _handle_QUIT(self, arg):
|
||||||
|
if self.listen_to_quit:
|
||||||
|
self.stop = True
|
||||||
|
yield _common.Response('OK', 'stopping the server')
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
def _handle_OPTION(self, arg):
|
||||||
|
"""
|
||||||
|
|
||||||
|
>>> s = AssuanServer(name='test', valid_options=['my-op'])
|
||||||
|
>>> list(s._handle_OPTION('my-op = 1 ')) # doctest: +ELLIPSIS
|
||||||
|
[<pyassuan.common.Response object at ...>]
|
||||||
|
>>> s.options
|
||||||
|
{'my-op': '1'}
|
||||||
|
>>> list(s._handle_OPTION('my-op 2')) # doctest: +ELLIPSIS
|
||||||
|
[<pyassuan.common.Response object at ...>]
|
||||||
|
>>> s.options
|
||||||
|
{'my-op': '2'}
|
||||||
|
>>> list(s._handle_OPTION('--my-op 3')) # doctest: +ELLIPSIS
|
||||||
|
[<pyassuan.common.Response object at ...>]
|
||||||
|
>>> s.options
|
||||||
|
{'my-op': '3'}
|
||||||
|
>>> list(s._handle_OPTION('my-op')) # doctest: +ELLIPSIS
|
||||||
|
[<pyassuan.common.Response object at ...>]
|
||||||
|
>>> s.options
|
||||||
|
{'my-op': None}
|
||||||
|
>>> list(s._handle_OPTION('inv'))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 174 Unknown option
|
||||||
|
>>> list(s._handle_OPTION('in|valid'))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 90 Invalid parameter
|
||||||
|
"""
|
||||||
|
match = _OPTION_REGEXP.match(arg)
|
||||||
|
if not match:
|
||||||
|
raise _error.AssuanError(message='Invalid parameter')
|
||||||
|
name,space,equal,value = match.groups()
|
||||||
|
if value and not space and not equal:
|
||||||
|
# need either space or equal to separate value
|
||||||
|
raise _error.AssuanError(message='Invalid parameter')
|
||||||
|
if name not in self.valid_options:
|
||||||
|
if self.strict_options:
|
||||||
|
raise _error.AssuanError(message='Unknown option')
|
||||||
|
else:
|
||||||
|
self.logger.info('skipping invalid option: {}'.format(name))
|
||||||
|
else:
|
||||||
|
if not value:
|
||||||
|
value = None
|
||||||
|
self.options[name] = value
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_CANCEL(self, arg):
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
def _handle_AUTH(self, arg):
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
|
||||||
|
class AssuanSocketServer (object):
|
||||||
|
"""A threaded server spawning ``AssuanServer``\s for each connection
|
||||||
|
"""
|
||||||
|
def __init__(self, name, socket, server, kwargs={}, max_threads=10,
|
||||||
|
logger=_LOG, use_sublogger=True):
|
||||||
|
self.name = name
|
||||||
|
if use_sublogger:
|
||||||
|
logger = _logging.getLogger('{}.{}'.format(logger.name, self.name))
|
||||||
|
self.logger = logger
|
||||||
|
self.socket = socket
|
||||||
|
self.server = server
|
||||||
|
assert 'name' not in kwargs, kwargs['name']
|
||||||
|
assert 'logger' not in kwargs, kwargs['logger']
|
||||||
|
kwargs['logger'] = self.logger
|
||||||
|
assert 'use_sublogger' not in kwargs, kwargs['use_sublogger']
|
||||||
|
kwargs['use_sublogger'] = True
|
||||||
|
if 'close_on_disconnect' in kwargs:
|
||||||
|
assert kwargs['close_on_disconnect'] == True, (
|
||||||
|
kwargs['close_on_disconnect'])
|
||||||
|
else:
|
||||||
|
kwargs['close_on_disconnect'] = True
|
||||||
|
self.kwargs = kwargs
|
||||||
|
self.max_threads = max_threads
|
||||||
|
self.threads = []
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.logger.info('listen on socket')
|
||||||
|
self.socket.listen()
|
||||||
|
thread_index = 0
|
||||||
|
while True:
|
||||||
|
socket,address = self.socket.accept()
|
||||||
|
self.logger.info('connection from {}'.format(address))
|
||||||
|
self.cleanup_threads()
|
||||||
|
if len(threads) > self.max_threads:
|
||||||
|
self.drop_connection(socket, address)
|
||||||
|
self.spawn_thread(
|
||||||
|
'server-thread-{}'.format(thread_index), socket, address)
|
||||||
|
thread_index = (thread_index + 1) % self.max_threads
|
||||||
|
|
||||||
|
def cleanup_threads(self):
|
||||||
|
i = 0
|
||||||
|
while i < len(self.threads):
|
||||||
|
thread = self.threads[i]
|
||||||
|
thread.join(0)
|
||||||
|
if thread.is_alive():
|
||||||
|
self.logger.info('joined thread {}'.format(thread.name))
|
||||||
|
self.threads.pop(i)
|
||||||
|
thread.socket.shutdown()
|
||||||
|
thread.socket.close()
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
def drop_connection(self, socket, address):
|
||||||
|
self.logger.info('drop connection from {}'.format(address))
|
||||||
|
# TODO: proper error to send to the client?
|
||||||
|
|
||||||
|
def spawn_thread(self, name, socket, address):
|
||||||
|
server = self.server(name=name, **self.kwargs)
|
||||||
|
server.input = socket.makefile('rb')
|
||||||
|
server.output = socket.makefile('wb')
|
||||||
|
thread = _threading.Thread(target=server.run, name=name)
|
||||||
|
thread.start()
|
||||||
|
self.threads.append(thread)
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (C) 2012-2018 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import doctest
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from . import common
|
||||||
|
|
||||||
|
|
||||||
|
def load_tests(loader, tests, ignore):
|
||||||
|
tests.addTests(doctest.DocTestSuite(common))
|
||||||
|
return tests
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (C) 2012-2018 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import doctest
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from . import error
|
||||||
|
|
||||||
|
|
||||||
|
def load_tests(loader, tests, ignore):
|
||||||
|
tests.addTests(doctest.DocTestSuite(error))
|
||||||
|
return tests
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (C) 2012-2018 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import doctest
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from . import server
|
||||||
|
|
||||||
|
|
||||||
|
def load_tests(loader, tests, ignore):
|
||||||
|
tests.addTests(doctest.DocTestSuite(server))
|
||||||
|
return tests
|
||||||
54
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/setup.py
Normal file
54
roles/toxcore/net/Git/http-git.tremily.us/pyassuan/setup.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Copyright (C) 2012-2018 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"Python module and tools for communicating in the Assuan protocol."
|
||||||
|
|
||||||
|
from distutils.core import setup as _setup
|
||||||
|
import os.path as _os_path
|
||||||
|
|
||||||
|
from pyassuan import __version__
|
||||||
|
|
||||||
|
|
||||||
|
_this_dir = _os_path.dirname(__file__)
|
||||||
|
|
||||||
|
_setup(
|
||||||
|
name='pyassuan',
|
||||||
|
version=__version__,
|
||||||
|
maintainer='W. Trevor King',
|
||||||
|
maintainer_email='wking@tremily.us',
|
||||||
|
url='http://blog.tremily.us/posts/pyassuan/',
|
||||||
|
download_url='http://git.tremily.us/?p=pyassuan.git;a=snapshot;h=v{};sf=tgz'.format(__version__),
|
||||||
|
license = 'GNU General Public License (GPL)',
|
||||||
|
platforms = ['all'],
|
||||||
|
description = __doc__,
|
||||||
|
long_description=open(_os_path.join(_this_dir, 'README'), 'r').read(),
|
||||||
|
classifiers = [
|
||||||
|
'Development Status :: 3 - Alpha',
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'Operating System :: OS Independent',
|
||||||
|
'License :: OSI Approved :: GNU General Public License (GPL)',
|
||||||
|
'Programming Language :: Python :: 3',
|
||||||
|
'Programming Language :: Python :: 3.3',
|
||||||
|
'Programming Language :: Python :: 3.4',
|
||||||
|
'Programming Language :: Python :: 3.5',
|
||||||
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Topic :: Security :: Cryptography',
|
||||||
|
'Topic :: Software Development'
|
||||||
|
],
|
||||||
|
scripts = ['bin/get-info.py', 'bin/pinentry.py'],
|
||||||
|
packages = ['pyassuan'],
|
||||||
|
provides = ['pyassuan'],
|
||||||
|
)
|
||||||
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
Python module and tools for communicating in the Assuan_ protocol.
|
||||||
|
|
||||||
|
There are a number of GnuPG_ wrappers for python `out there`__, but
|
||||||
|
they mostly work via the ``gpg`` executable. This is an attempt to
|
||||||
|
cut to the chase and speak directly to ``gpgme-tool`` (source__) over
|
||||||
|
a well-defined socket protocol.
|
||||||
|
|
||||||
|
__ wrappers_
|
||||||
|
__ gpgme-tool_
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
Packages
|
||||||
|
--------
|
||||||
|
|
||||||
|
Gentoo
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
I've packaged ``pyassuan`` for Gentoo_. You need layman_ and
|
||||||
|
my `wtk overlay`_. Install with::
|
||||||
|
|
||||||
|
# emerge -av app-portage/layman
|
||||||
|
# layman --add wtk
|
||||||
|
# emerge -av dev-python/pyassuan
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
``pyassuan`` is a simple package with no external dependencies outside
|
||||||
|
the Python 3.3+ standard library.
|
||||||
|
|
||||||
|
Installing by hand
|
||||||
|
------------------
|
||||||
|
|
||||||
|
``pyassuan`` is available as a Git_ repository::
|
||||||
|
|
||||||
|
$ git clone git://tremily.us/pyassuan.git
|
||||||
|
|
||||||
|
See the homepage_ for details. To install the checkout, run the
|
||||||
|
standard::
|
||||||
|
|
||||||
|
$ python setup.py install
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
Checkout the docstrings and the examples in ``bin``.
|
||||||
|
|
||||||
|
Testing
|
||||||
|
=======
|
||||||
|
|
||||||
|
Run the internal unit tests with `Python 3.2+'s unittest discovery`__::
|
||||||
|
|
||||||
|
$ python -m unittest discover
|
||||||
|
|
||||||
|
To test running servers by hand, you can use `gpg-connect-agent`_.
|
||||||
|
Despite the name, this program can connect to any Assuan server::
|
||||||
|
|
||||||
|
$ gpg-connect-agent --raw-socket name
|
||||||
|
|
||||||
|
__ unittest-discovery_
|
||||||
|
|
||||||
|
Licence
|
||||||
|
=======
|
||||||
|
|
||||||
|
This project is distributed under the `GNU General Public License
|
||||||
|
Version 3`_ or greater.
|
||||||
|
|
||||||
|
Author
|
||||||
|
======
|
||||||
|
|
||||||
|
W. Trevor King
|
||||||
|
wking@tremily.us
|
||||||
|
|
||||||
|
|
||||||
|
.. _Assuan: http://www.gnupg.org/documentation/manuals/assuan/
|
||||||
|
.. _GnuPG: http://www.gnupg.org/
|
||||||
|
.. _wrappers: http://wiki.python.org/moin/GnuPrivacyGuard
|
||||||
|
.. _gpgme-tool:
|
||||||
|
http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gpgme.git;a=blob;f=src/gpgme-tool.c;hb=HEAD
|
||||||
|
.. _Gentoo: http://www.gentoo.org/
|
||||||
|
.. _layman: http://layman.sourceforge.net/
|
||||||
|
.. _wtk overlay: http://blog.tremily.us/posts/Gentoo_overlay/
|
||||||
|
.. _Git: http://git-scm.com/
|
||||||
|
.. _homepage: http://blog.tremily.us/posts/pyassuan/
|
||||||
|
.. _gpg-connect-agent:
|
||||||
|
http://www.gnupg.org/documentation/manuals/gnupg-devel/gpg_002dconnect_002dagent.html
|
||||||
|
.. _unittest-discovery:
|
||||||
|
https://docs.python.org/3.5/library/unittest.html#unittest-test-discovery
|
||||||
|
.. _GNU General Public License Version 3: http://www.gnu.org/licenses/gpl.html
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Simple pinentry program for getting server info.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pyassuan import __version__
|
||||||
|
from pyassuan import client as _client
|
||||||
|
from pyassuan import common as _common
|
||||||
|
from pyassuan import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
parser.add_argument(
|
||||||
|
'-v', '--version', action='version',
|
||||||
|
version='%(prog)s {}'.format(__version__))
|
||||||
|
parser.add_argument(
|
||||||
|
'-V', '--verbose', action='count', default=0,
|
||||||
|
help='increase verbosity')
|
||||||
|
parser.add_argument(
|
||||||
|
'filename',
|
||||||
|
help="path to server's unix socket")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
client = _client.AssuanClient(name='get-info', close_on_disconnect=True)
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
client.logger.setLevel(max(
|
||||||
|
logging.DEBUG, client.logger.level - 10*args.verbose))
|
||||||
|
|
||||||
|
client.connect(socket_path=args.filename)
|
||||||
|
try:
|
||||||
|
response = client.read_response()
|
||||||
|
assert response.type == 'OK', response
|
||||||
|
client.make_request(_common.Request('HELP'))
|
||||||
|
client.make_request(_common.Request('HELP GETINFO'))
|
||||||
|
for attribute in ['version', 'pid', 'socket_name', 'ssh_socket_name']:
|
||||||
|
try:
|
||||||
|
client.make_request(_common.Request('GETINFO', attribute))
|
||||||
|
except _error.AssuanError as e:
|
||||||
|
if e.message.startswith('No data'):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
client.make_request(_common.Request('BYE'))
|
||||||
|
client.disconnect()
|
||||||
393
roles/toxcore/overlay/Linux/net/Git/http-git.tremily.us/pyassuan/bin/pinentry.py
Executable file
393
roles/toxcore/overlay/Linux/net/Git/http-git.tremily.us/pyassuan/bin/pinentry.py
Executable file
@@ -0,0 +1,393 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (C) 2012-2017 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Simple pinentry program for getting pins from a terminal.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import copy as _copy
|
||||||
|
import os as _os
|
||||||
|
import os.path as _os_path
|
||||||
|
import pprint as _pprint
|
||||||
|
import re as _re
|
||||||
|
import signal as _signal
|
||||||
|
import sys as _sys
|
||||||
|
import termios as _termios
|
||||||
|
|
||||||
|
from pyassuan import __version__
|
||||||
|
from pyassuan import server as _server
|
||||||
|
from pyassuan import common as _common
|
||||||
|
from pyassuan import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
class PinEntry (_server.AssuanServer):
|
||||||
|
"""pinentry protocol server
|
||||||
|
|
||||||
|
See ``pinentry-0.8.0/doc/pinentry.texi`` at::
|
||||||
|
|
||||||
|
ftp://ftp.gnupg.org/gcrypt/pinentry/
|
||||||
|
http://www.gnupg.org/aegypten/
|
||||||
|
|
||||||
|
for details on the pinentry interface.
|
||||||
|
|
||||||
|
Alternatively, you can just watch the logs and guess ;). Here's a
|
||||||
|
trace when driven by GnuPG 2.0.28 (libgcrypt 1.6.3)::
|
||||||
|
|
||||||
|
S: OK Your orders please
|
||||||
|
C: OPTION grab
|
||||||
|
S: OK
|
||||||
|
C: OPTION ttyname=/dev/pts/6
|
||||||
|
S: OK
|
||||||
|
C: OPTION ttytype=xterm
|
||||||
|
S: OK
|
||||||
|
C: OPTION lc-ctype=en_US.UTF-8
|
||||||
|
S: OK
|
||||||
|
C: OPTION lc-messages=en_US.UTF-8
|
||||||
|
S: OK
|
||||||
|
C: OPTION allow-external-password-cache
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-ok=_OK
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-cancel=_Cancel
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-yes=_Yes
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-no=_No
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-prompt=PIN:
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-pwmngr=_Save in password manager
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-cf-visi=Do you really want to make your passphrase visible on the screen?
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-tt-visi=Make passphrase visible
|
||||||
|
S: OK
|
||||||
|
C: OPTION default-tt-hide=Hide passphrase
|
||||||
|
S: OK
|
||||||
|
C: GETINFO pid
|
||||||
|
S: D 14309
|
||||||
|
S: OK
|
||||||
|
C: SETKEYINFO u/S9464F2C2825D2FE3
|
||||||
|
S: OK
|
||||||
|
C: SETDESC Enter passphrase%0A
|
||||||
|
S: OK
|
||||||
|
C: SETPROMPT Passphrase
|
||||||
|
S: OK
|
||||||
|
C: GETPIN
|
||||||
|
S: D testing!
|
||||||
|
S: OK
|
||||||
|
C: BYE
|
||||||
|
S: OK closing connection
|
||||||
|
"""
|
||||||
|
_digit_regexp = _re.compile(r'\d+')
|
||||||
|
|
||||||
|
# from proc(5): pid comm state ppid pgrp session tty_nr tpgid
|
||||||
|
_tpgrp_regexp = _re.compile(r'\d+ \(\S+\) . \d+ \d+ \d+ \d+ (\d+)')
|
||||||
|
|
||||||
|
def __init__(self, name='pinentry', strict_options=False,
|
||||||
|
single_request=True, **kwargs):
|
||||||
|
self.strings = {}
|
||||||
|
self.connection = {}
|
||||||
|
super(PinEntry, self).__init__(
|
||||||
|
name=name, strict_options=strict_options,
|
||||||
|
single_request=single_request, **kwargs)
|
||||||
|
self.valid_options.append('ttyname')
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
super(PinEntry, self).reset()
|
||||||
|
self.strings.clear()
|
||||||
|
self.connection.clear()
|
||||||
|
|
||||||
|
# user interface
|
||||||
|
|
||||||
|
def _connect(self):
|
||||||
|
self.logger.info('connecting to user')
|
||||||
|
self.logger.debug('options:\n{}'.format(_pprint.pformat(self.options)))
|
||||||
|
tty_name = self.options.get('ttyname', None)
|
||||||
|
if tty_name:
|
||||||
|
self.connection['tpgrp'] = self._get_pgrp(tty_name)
|
||||||
|
self.logger.info(
|
||||||
|
'open to-user output stream for {}'.format(tty_name))
|
||||||
|
self.connection['to_user'] = open(tty_name, 'w')
|
||||||
|
self.logger.info(
|
||||||
|
'open from-user input stream for {}'.format(tty_name))
|
||||||
|
self.connection['from_user'] = open(tty_name, 'r')
|
||||||
|
self.logger.info('get current termios line discipline')
|
||||||
|
self.connection['original termios'] = _termios.tcgetattr(
|
||||||
|
self.connection['to_user']) # [iflag, oflag, cflag, lflag, ...]
|
||||||
|
new_termios = _copy.deepcopy(self.connection['original termios'])
|
||||||
|
# translate carriage return to newline on input
|
||||||
|
new_termios[0] |= _termios.ICRNL
|
||||||
|
# do not ignore carriage return on input
|
||||||
|
new_termios[0] &= ~_termios.IGNCR
|
||||||
|
# do not echo input characters
|
||||||
|
new_termios[3] &= ~_termios.ECHO
|
||||||
|
# echo input characters
|
||||||
|
#new_termios[3] |= _termios.ECHO
|
||||||
|
# echo the NL character even if ECHO is not set
|
||||||
|
new_termios[3] |= _termios.ECHONL
|
||||||
|
# enable canonical mode
|
||||||
|
new_termios[3] |= _termios.ICANON
|
||||||
|
self.logger.info('adjust termios line discipline')
|
||||||
|
_termios.tcsetattr(
|
||||||
|
self.connection['to_user'], _termios.TCSANOW, new_termios)
|
||||||
|
self.logger.info('send SIGSTOP to pgrp {}'.format(
|
||||||
|
self.connection['tpgrp']))
|
||||||
|
#_os.killpg(self.connection['tpgrp'], _signal.SIGSTOP)
|
||||||
|
_os.kill(-self.connection['tpgrp'], _signal.SIGSTOP)
|
||||||
|
self.connection['tpgrp stopped'] = True
|
||||||
|
else:
|
||||||
|
self.logger.info('no TTY name given; use stdin/stdout for I/O')
|
||||||
|
self.connection['to_user'] = _sys.stdout
|
||||||
|
self.connection['from_user'] = _sys.stdin
|
||||||
|
self.logger.info('connected to user')
|
||||||
|
self.connection['to_user'].write('\n') # give a clean line to work on
|
||||||
|
self.connection['active'] = True
|
||||||
|
|
||||||
|
def _disconnect(self):
|
||||||
|
self.logger.info('disconnecting from user')
|
||||||
|
try:
|
||||||
|
if self.connection.get('original termios', None):
|
||||||
|
self.logger.info('restore original termios line discipline')
|
||||||
|
_termios.tcsetattr(
|
||||||
|
self.connection['to_user'], _termios.TCSANOW,
|
||||||
|
self.connection['original termios'])
|
||||||
|
if self.connection.get('tpgrp stopped', None) is True:
|
||||||
|
self.logger.info(
|
||||||
|
'send SIGCONT to pgrp {}'.format(self.connection['tpgrp']))
|
||||||
|
#_os.killpg(self.connection['tpgrp'], _signal.SIGCONT)
|
||||||
|
_os.kill(-self.connection['tpgrp'], _signal.SIGCONT)
|
||||||
|
if self.connection.get('to_user', None) not in [None, _sys.stdout]:
|
||||||
|
self.logger.info('close to-user output stream')
|
||||||
|
self.connection['to_user'].close()
|
||||||
|
if self.connection.get('from_user',None) not in [None,_sys.stdout]:
|
||||||
|
self.logger.info('close from-user input stream')
|
||||||
|
self.connection['from_user'].close()
|
||||||
|
finally:
|
||||||
|
self.connection = {'active': False}
|
||||||
|
self.logger.info('disconnected from user')
|
||||||
|
|
||||||
|
def _get_pgrp(self, tty_name):
|
||||||
|
self.logger.info('find process group contolling {}'.format(tty_name))
|
||||||
|
proc = '/proc'
|
||||||
|
for name in _os.listdir(proc):
|
||||||
|
path = _os_path.join(proc, name)
|
||||||
|
if not (self._digit_regexp.match(name) and _os_path.isdir(path)):
|
||||||
|
continue # not a process directory
|
||||||
|
self.logger.debug('checking process {}'.format(name))
|
||||||
|
fd_path = _os_path.join(path, 'fd', '0')
|
||||||
|
try:
|
||||||
|
link = _os.readlink(fd_path)
|
||||||
|
except OSError as e:
|
||||||
|
self.logger.debug('not our process: {}'.format(e))
|
||||||
|
continue # permission denied (not one of our processes)
|
||||||
|
if link != tty_name:
|
||||||
|
self.logger.debug('wrong tty: {}'.format(link))
|
||||||
|
continue # not attached to our target tty
|
||||||
|
stat_path = _os_path.join(path, 'stat')
|
||||||
|
stat = open(stat_path, 'r').read()
|
||||||
|
self.logger.debug('check stat for pgrp: {}'.format(stat))
|
||||||
|
match = self._tpgrp_regexp.match(stat)
|
||||||
|
assert match != None, stat
|
||||||
|
pgrp = int(match.group(1))
|
||||||
|
self.logger.info('found pgrp {} for {}'.format(pgrp, tty_name))
|
||||||
|
return pgrp
|
||||||
|
raise ValueError(tty_name)
|
||||||
|
|
||||||
|
def _write(self, string):
|
||||||
|
"Write text to the user's terminal."
|
||||||
|
self.connection['to_user'].write(string + '\n')
|
||||||
|
self.connection['to_user'].flush()
|
||||||
|
|
||||||
|
def _read(self):
|
||||||
|
"Read and return a line from the user's terminal."
|
||||||
|
# drop trailing newline
|
||||||
|
return self.connection['from_user'].readline()[:-1]
|
||||||
|
|
||||||
|
def _prompt(self, prompt='?', error=None, add_colon=True):
|
||||||
|
if add_colon:
|
||||||
|
prompt += ':'
|
||||||
|
if error:
|
||||||
|
self.connection['to_user'].write(error)
|
||||||
|
self.connection['to_user'].write('\n')
|
||||||
|
self.connection['to_user'].write(prompt)
|
||||||
|
self.connection['to_user'].write(' ')
|
||||||
|
self.connection['to_user'].flush()
|
||||||
|
return self._read()
|
||||||
|
|
||||||
|
# assuan handlers
|
||||||
|
|
||||||
|
def _handle_GETINFO(self, arg):
|
||||||
|
if arg == 'pid':
|
||||||
|
yield _common.Response('D', str(_os.getpid()).encode('ascii'))
|
||||||
|
elif arg == 'version':
|
||||||
|
yield _common.Response('D', __version__.encode('ascii'))
|
||||||
|
else:
|
||||||
|
raise _error.AssuanError(message='Invalid parameter')
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETKEYINFO(self, arg):
|
||||||
|
self.strings['key info'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_CLEARPASSPHRASE(self, arg):
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETDESC(self, arg):
|
||||||
|
self.strings['description'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETPROMPT(self, arg):
|
||||||
|
self.strings['prompt'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETERROR(self, arg):
|
||||||
|
self.strings['error'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETTITLE(self, arg):
|
||||||
|
self.strings['title'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETOK(self, arg):
|
||||||
|
self.strings['ok'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETCANCEL(self, arg):
|
||||||
|
self.strings['cancel'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETNOTOK(self, arg):
|
||||||
|
self.strings['not ok'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETQUALITYBAR(self, arg):
|
||||||
|
"""Adds a quality indicator to the GETPIN window.
|
||||||
|
|
||||||
|
This indicator is updated as the passphrase is typed. The
|
||||||
|
clients needs to implement an inquiry named "QUALITY" which
|
||||||
|
gets passed the current passphrase (percent-plus escaped) and
|
||||||
|
should send back a string with a single numerical vauelue
|
||||||
|
between -100 and 100. Negative values will be displayed in
|
||||||
|
red.
|
||||||
|
|
||||||
|
If a custom label for the quality bar is required, just add
|
||||||
|
that label as an argument as percent escaped string. You will
|
||||||
|
need this feature to translate the label because pinentry has
|
||||||
|
no internal gettext except for stock strings from the toolkit
|
||||||
|
library.
|
||||||
|
|
||||||
|
If you want to show a tooltip for the quality bar, you may use
|
||||||
|
|
||||||
|
C: SETQUALITYBAR_TT string
|
||||||
|
S: OK
|
||||||
|
|
||||||
|
With STRING being a percent escaped string shown as the tooltip.
|
||||||
|
|
||||||
|
Here is a real world example of these commands in use:
|
||||||
|
|
||||||
|
C: SETQUALITYBAR Quality%3a
|
||||||
|
S: OK
|
||||||
|
C: SETQUALITYBAR_TT The quality of the text entered above.%0aPlease ask your administrator for details about the criteria.
|
||||||
|
S: OK
|
||||||
|
"""
|
||||||
|
self.strings['qualitybar'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_SETQUALITYBAR_TT(self, arg):
|
||||||
|
self.strings['qualitybar_tooltip'] = arg
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_GETPIN(self, arg):
|
||||||
|
try:
|
||||||
|
self._connect()
|
||||||
|
self._write(self.strings['description'])
|
||||||
|
if 'key info' in self.strings:
|
||||||
|
self._write('key: {}'.format(self.strings['key info']))
|
||||||
|
if 'qualitybar' in self.strings:
|
||||||
|
self._write(self.strings['qualitybar'])
|
||||||
|
pin = self._prompt(
|
||||||
|
prompt=self.strings['prompt'],
|
||||||
|
error=self.strings.get('error'),
|
||||||
|
add_colon=False)
|
||||||
|
finally:
|
||||||
|
self._disconnect()
|
||||||
|
yield _common.Response('D', pin.encode('ascii'))
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_CONFIRM(self, arg):
|
||||||
|
try:
|
||||||
|
self._connect()
|
||||||
|
self._write(self.strings['description'])
|
||||||
|
self._write('1) '+self.strings['ok'])
|
||||||
|
self._write('2) '+self.strings['not ok'])
|
||||||
|
value = self._prompt('?')
|
||||||
|
finally:
|
||||||
|
self._disconnect()
|
||||||
|
if value == '1':
|
||||||
|
yield _common.Response('OK')
|
||||||
|
else:
|
||||||
|
raise _error.AssuanError(message='Not confirmed')
|
||||||
|
|
||||||
|
def _handle_MESSAGE(self, arg):
|
||||||
|
self._write(self.strings['description'])
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_CONFIRM(self, args):
|
||||||
|
assert args == '--one-button', args
|
||||||
|
try:
|
||||||
|
self._connect()
|
||||||
|
self._write(self.strings['description'])
|
||||||
|
self._write('1) '+self.strings['ok'])
|
||||||
|
value = self._prompt('?')
|
||||||
|
finally:
|
||||||
|
self._disconnect()
|
||||||
|
assert value == '1', value
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
parser.add_argument(
|
||||||
|
'-v', '--version', action='version',
|
||||||
|
version='%(prog)s {}'.format(__version__))
|
||||||
|
parser.add_argument(
|
||||||
|
'-V', '--verbose', action='count', default=0,
|
||||||
|
help='increase verbosity')
|
||||||
|
parser.add_argument(
|
||||||
|
'--display',
|
||||||
|
help='set X display (ignored by this implementation)')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
p = PinEntry()
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
p.logger.setLevel(max(
|
||||||
|
logging.DEBUG, p.logger.level - 10*args.verbose))
|
||||||
|
|
||||||
|
try:
|
||||||
|
p.run()
|
||||||
|
except:
|
||||||
|
p.logger.error(
|
||||||
|
'exiting due to exception:\n{}'.format(
|
||||||
|
traceback.format_exc().rstrip()))
|
||||||
|
raise
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""A Python implementation of the `Assuan protocol`_.
|
||||||
|
|
||||||
|
.. _Assuan protocol: http://www.gnupg.org/documentation/manuals/assuan/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging as _logging
|
||||||
|
import logging.handlers as _logging_handlers
|
||||||
|
|
||||||
|
|
||||||
|
__version__ = '0.2'
|
||||||
|
|
||||||
|
LOG = _logging.getLogger('pyassuan')
|
||||||
|
LOG.setLevel(_logging.ERROR)
|
||||||
|
LOG.addHandler(_logging.StreamHandler())
|
||||||
|
#LOG.addHandler(_logging.FileHandler('/tmp/pinentry.log'))
|
||||||
|
#LOG.addHandler(_logging_handlers.SysLogHandler(address='/dev/log'))
|
||||||
|
LOG.handlers[0].setFormatter(
|
||||||
|
_logging.Formatter('%(name)s: %(levelname)s: %(message)s'))
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import logging as _logging
|
||||||
|
import socket as _socket
|
||||||
|
import sys as _sys
|
||||||
|
|
||||||
|
from . import LOG as _LOG
|
||||||
|
from . import common as _common
|
||||||
|
from . import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
class AssuanClient (object):
|
||||||
|
"""A single-threaded Assuan client based on the `development suggestions`_
|
||||||
|
|
||||||
|
.. _development suggestions:
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-code.html
|
||||||
|
"""
|
||||||
|
def __init__(self, name, logger=_LOG, use_sublogger=True,
|
||||||
|
close_on_disconnect=False):
|
||||||
|
self.name = name
|
||||||
|
if use_sublogger:
|
||||||
|
logger = _logging.getLogger('{}.{}'.format(logger.name, self.name))
|
||||||
|
self.logger = logger
|
||||||
|
self.close_on_disconnect = close_on_disconnect
|
||||||
|
self.input = self.output = self.socket = None
|
||||||
|
|
||||||
|
def connect(self, socket_path=None):
|
||||||
|
if socket_path:
|
||||||
|
self.logger.info(
|
||||||
|
'connect to Unix socket at {}'.format(socket_path))
|
||||||
|
self.socket = _socket.socket(_socket.AF_UNIX, _socket.SOCK_STREAM)
|
||||||
|
self.socket.connect(socket_path)
|
||||||
|
self.input = self.socket.makefile('rb')
|
||||||
|
self.output = self.socket.makefile('wb')
|
||||||
|
else:
|
||||||
|
if not self.input:
|
||||||
|
self.logger.info('read from stdin')
|
||||||
|
self.input = _sys.stdin.buffer
|
||||||
|
if not self.output:
|
||||||
|
self.logger.info('write to stdout')
|
||||||
|
self.output = _sys.stdout.buffer
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
if self.close_on_disconnect:
|
||||||
|
self.logger.info('disconnecting')
|
||||||
|
if self.input is not None:
|
||||||
|
self.input.close()
|
||||||
|
self.input = None
|
||||||
|
if self.output is not None:
|
||||||
|
self.output.close()
|
||||||
|
self.output = None
|
||||||
|
if self.socket is not None:
|
||||||
|
self.socket.shutdown(_socket.SHUT_RDWR)
|
||||||
|
self.socket.close()
|
||||||
|
self.socket = None
|
||||||
|
|
||||||
|
def raise_error(self, error):
|
||||||
|
self.logger.error(str(error))
|
||||||
|
raise(error)
|
||||||
|
|
||||||
|
def read_response(self):
|
||||||
|
line = self.input.readline()
|
||||||
|
if not line:
|
||||||
|
self.raise_error(
|
||||||
|
_error.AssuanError(message='IPC accept call failed'))
|
||||||
|
if len(line) > _common.LINE_LENGTH:
|
||||||
|
self.raise_error(
|
||||||
|
_error.AssuanError(message='Line too long'))
|
||||||
|
if not line.endswith(b'\n'):
|
||||||
|
self.logger.info('S: {}'.format(line))
|
||||||
|
self.raise_error(
|
||||||
|
_error.AssuanError(message='Invalid response'))
|
||||||
|
line = line[:-1] # remove trailing newline
|
||||||
|
response = _common.Response()
|
||||||
|
try:
|
||||||
|
response.from_bytes(line)
|
||||||
|
except _error.AssuanError as e:
|
||||||
|
self.logger.error(str(e))
|
||||||
|
raise
|
||||||
|
self.logger.info('S: {}'.format(response))
|
||||||
|
return response
|
||||||
|
|
||||||
|
def _write_request(self, request):
|
||||||
|
self.logger.info('C: {}'.format(request))
|
||||||
|
self.output.write(bytes(request))
|
||||||
|
self.output.write(b'\n')
|
||||||
|
try:
|
||||||
|
self.output.flush()
|
||||||
|
except IOError:
|
||||||
|
raise
|
||||||
|
|
||||||
|
def make_request(self, request, response=True, expect=['OK']):
|
||||||
|
self._write_request(request=request)
|
||||||
|
if response:
|
||||||
|
return self.get_responses(requests=[request], expect=expect)
|
||||||
|
|
||||||
|
def get_responses(self, requests=None, expect=['OK']):
|
||||||
|
responses = list(self.responses())
|
||||||
|
if responses[-1].type == 'ERR':
|
||||||
|
eresponse = responses[-1]
|
||||||
|
fields = eresponse.parameters.split(' ', 1)
|
||||||
|
code = int(fields[0])
|
||||||
|
if len(fields) > 1:
|
||||||
|
message = fields[1].strip()
|
||||||
|
else:
|
||||||
|
message = None
|
||||||
|
error = _error.AssuanError(code=code, message=message)
|
||||||
|
if requests is not None:
|
||||||
|
error.requests = requests
|
||||||
|
error.responses = responses
|
||||||
|
raise error
|
||||||
|
if expect:
|
||||||
|
assert responses[-1].type in expect, [str(r) for r in responses]
|
||||||
|
data = []
|
||||||
|
for response in responses:
|
||||||
|
if response.type == 'D':
|
||||||
|
data.append(response.parameters)
|
||||||
|
if data:
|
||||||
|
data = b''.join(data)
|
||||||
|
else:
|
||||||
|
data = None
|
||||||
|
return (responses, data)
|
||||||
|
|
||||||
|
def responses(self):
|
||||||
|
while True:
|
||||||
|
response = self.read_response()
|
||||||
|
yield response
|
||||||
|
if response.type not in ['S', '#', 'D']:
|
||||||
|
break
|
||||||
|
|
||||||
|
def send_data(self, data=None, response=True, expect=['OK']):
|
||||||
|
"""Iterate through requests necessary to send ``data`` to a server.
|
||||||
|
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-requests.html
|
||||||
|
"""
|
||||||
|
requests = []
|
||||||
|
if data:
|
||||||
|
encoded_data = _common.encode(data)
|
||||||
|
start = 0
|
||||||
|
stop = min(_common.LINE_LENGTH-4, len(encoded_data)) # 'D ', CR, CL
|
||||||
|
self.logger.debug('sending {} bytes of encoded data'.format(
|
||||||
|
len(encoded_data)))
|
||||||
|
while stop > start:
|
||||||
|
d = encoded_data[start:stop]
|
||||||
|
request = _common.Request(
|
||||||
|
command='D', parameters=encoded_data[start:stop],
|
||||||
|
encoded=True)
|
||||||
|
requests.append(request)
|
||||||
|
self.logger.debug('send {} byte chunk'.format(stop-start))
|
||||||
|
self._write_request(request=request)
|
||||||
|
start = stop
|
||||||
|
stop = start + min(_common.LINE_LENGTH-4,
|
||||||
|
len(encoded_data) - start)
|
||||||
|
request = _common.Request('END')
|
||||||
|
requests.append(request)
|
||||||
|
self._write_request(request=request)
|
||||||
|
if response:
|
||||||
|
return self.get_responses(requests=requests, expect=expect)
|
||||||
|
|
||||||
|
def send_fds(self, fds):
|
||||||
|
"""Send a file descriptor over a Unix socket.
|
||||||
|
"""
|
||||||
|
msg = '# descriptors in flight: {}\n'.format(fds)
|
||||||
|
self.logger.info('C: {}'.format(msg.rstrip('\n')))
|
||||||
|
msg = msg.encode('ascii')
|
||||||
|
return _common.send_fds(
|
||||||
|
socket=self.socket, msg=msg, fds=fds, logger=None)
|
||||||
|
|
||||||
|
def receive_fds(self, msglen=200, maxfds=10):
|
||||||
|
"""Receive file descriptors over a Unix socket.
|
||||||
|
"""
|
||||||
|
msg,fds = _common.receive_fds(
|
||||||
|
socket=self.socket, msglen=msglen, maxfds=maxfds, logger=None)
|
||||||
|
msg = str(msg, 'utf-8')
|
||||||
|
self.logger.info('S: {}'.format(msg.rstrip('\n')))
|
||||||
|
return fds
|
||||||
@@ -0,0 +1,314 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Items common to both the client and server
|
||||||
|
"""
|
||||||
|
|
||||||
|
import array as _array
|
||||||
|
import re as _re
|
||||||
|
import socket as _socket
|
||||||
|
|
||||||
|
from . import LOG as _LOG
|
||||||
|
from . import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
LINE_LENGTH = 1002 # 1000 + [CR,]LF
|
||||||
|
_ENCODE_PATTERN = '(' + '|'.join(['%', '\r', '\n']) + ')'
|
||||||
|
_ENCODE_STR_REGEXP = _re.compile(_ENCODE_PATTERN)
|
||||||
|
_ENCODE_BYTE_REGEXP = _re.compile(_ENCODE_PATTERN.encode('ascii'))
|
||||||
|
_DECODE_STR_REGEXP = _re.compile('(%[0-9A-Fa-f]{2})')
|
||||||
|
_DECODE_BYTE_REGEXP = _re.compile(b'(%[0-9A-Fa-f]{2})')
|
||||||
|
_REQUEST_REGEXP = _re.compile('^(\w+)( *)(.*)\Z')
|
||||||
|
|
||||||
|
|
||||||
|
def encode(data):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> encode('It grew by 5%!\n')
|
||||||
|
'It grew by 5%25!%0A'
|
||||||
|
>>> encode(b'It grew by 5%!\n')
|
||||||
|
b'It grew by 5%25!%0A'
|
||||||
|
"""
|
||||||
|
if isinstance(data, bytes):
|
||||||
|
regexp = _ENCODE_BYTE_REGEXP
|
||||||
|
else:
|
||||||
|
regexp = _ENCODE_STR_REGEXP
|
||||||
|
return regexp.sub(
|
||||||
|
lambda x : to_hex(x.group()), data)
|
||||||
|
|
||||||
|
def decode(data):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> decode('%22Look out!%22%0AWhere%3F')
|
||||||
|
'"Look out!"\nWhere?'
|
||||||
|
>>> decode(b'%22Look out!%22%0AWhere%3F')
|
||||||
|
b'"Look out!"\nWhere?'
|
||||||
|
"""
|
||||||
|
if isinstance(data, bytes):
|
||||||
|
regexp = _DECODE_BYTE_REGEXP
|
||||||
|
else:
|
||||||
|
regexp = _DECODE_STR_REGEXP
|
||||||
|
return regexp.sub(
|
||||||
|
lambda x : from_hex(x.group()), data)
|
||||||
|
|
||||||
|
def from_hex(code):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> from_hex('%22')
|
||||||
|
'"'
|
||||||
|
>>> from_hex('%0A')
|
||||||
|
'\n'
|
||||||
|
>>> from_hex(b'%0A')
|
||||||
|
b'\n'
|
||||||
|
"""
|
||||||
|
c = chr(int(code[1:], 16))
|
||||||
|
if isinstance(code, bytes):
|
||||||
|
c =c.encode('ascii')
|
||||||
|
return c
|
||||||
|
|
||||||
|
def to_hex(char):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> to_hex('"')
|
||||||
|
'%22'
|
||||||
|
>>> to_hex('\n')
|
||||||
|
'%0A'
|
||||||
|
>>> to_hex(b'\n')
|
||||||
|
b'%0A'
|
||||||
|
"""
|
||||||
|
hx = '%{:02X}'.format(ord(char))
|
||||||
|
if isinstance(char, bytes):
|
||||||
|
hx = hx.encode('ascii')
|
||||||
|
return hx
|
||||||
|
|
||||||
|
|
||||||
|
class Request (object):
|
||||||
|
"""A client request
|
||||||
|
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-requests.html
|
||||||
|
|
||||||
|
>>> r = Request(command='BYE')
|
||||||
|
>>> str(r)
|
||||||
|
'BYE'
|
||||||
|
>>> r = Request(command='OPTION', parameters='testing at 5%')
|
||||||
|
>>> str(r)
|
||||||
|
'OPTION testing at 5%25'
|
||||||
|
>>> bytes(r)
|
||||||
|
b'OPTION testing at 5%25'
|
||||||
|
>>> r.from_bytes(b'BYE')
|
||||||
|
>>> r.command
|
||||||
|
'BYE'
|
||||||
|
>>> print(r.parameters)
|
||||||
|
None
|
||||||
|
>>> r.from_bytes(b'OPTION testing at 5%25')
|
||||||
|
>>> r.command
|
||||||
|
'OPTION'
|
||||||
|
>>> print(r.parameters)
|
||||||
|
testing at 5%
|
||||||
|
>>> r.from_bytes(b' invalid')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 170 Invalid request
|
||||||
|
>>> r.from_bytes(b'in-valid')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 170 Invalid request
|
||||||
|
"""
|
||||||
|
def __init__(self, command=None, parameters=None, encoded=False):
|
||||||
|
self.command = command
|
||||||
|
self.parameters = parameters
|
||||||
|
self.encoded = encoded
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.parameters:
|
||||||
|
if self.encoded:
|
||||||
|
encoded_parameters = self.parameters
|
||||||
|
else:
|
||||||
|
encoded_parameters = encode(self.parameters)
|
||||||
|
return '{} {}'.format(self.command, encoded_parameters)
|
||||||
|
return self.command
|
||||||
|
|
||||||
|
def __bytes__(self):
|
||||||
|
if self.parameters:
|
||||||
|
if self.encoded:
|
||||||
|
encoded_parameters = self.parameters
|
||||||
|
else:
|
||||||
|
encoded_parameters = encode(self.parameters)
|
||||||
|
return '{} {}'.format(
|
||||||
|
self.command, encoded_parameters).encode('utf-8')
|
||||||
|
return self.command.encode('utf-8')
|
||||||
|
|
||||||
|
def from_bytes(self, line):
|
||||||
|
if len(line) > 1000: # TODO: byte-vs-str and newlines?
|
||||||
|
raise _error.AssuanError(message='Line too long')
|
||||||
|
line = str(line, encoding='utf-8')
|
||||||
|
match = _REQUEST_REGEXP.match(line)
|
||||||
|
if not match:
|
||||||
|
raise _error.AssuanError(message='Invalid request')
|
||||||
|
self.command = match.group(1)
|
||||||
|
if match.group(3):
|
||||||
|
if match.group(2):
|
||||||
|
self.parameters = decode(match.group(3))
|
||||||
|
else:
|
||||||
|
raise _error.AssuanError(message='Invalid request')
|
||||||
|
else:
|
||||||
|
self.parameters = None
|
||||||
|
|
||||||
|
|
||||||
|
class Response (object):
|
||||||
|
"""A server response
|
||||||
|
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Server-responses.html
|
||||||
|
|
||||||
|
>>> r = Response(type='OK')
|
||||||
|
>>> str(r)
|
||||||
|
'OK'
|
||||||
|
>>> r = Response(type='ERR', parameters='1 General error')
|
||||||
|
>>> str(r)
|
||||||
|
'ERR 1 General error'
|
||||||
|
>>> bytes(r)
|
||||||
|
b'ERR 1 General error'
|
||||||
|
>>> r.from_bytes(b'OK')
|
||||||
|
>>> r.type
|
||||||
|
'OK'
|
||||||
|
>>> print(r.parameters)
|
||||||
|
None
|
||||||
|
>>> r.from_bytes(b'ERR 1 General error')
|
||||||
|
>>> r.type
|
||||||
|
'ERR'
|
||||||
|
>>> print(r.parameters)
|
||||||
|
1 General error
|
||||||
|
>>> r.from_bytes(b' invalid')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 76 Invalid response
|
||||||
|
>>> r.from_bytes(b'in-valid')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 76 Invalid response
|
||||||
|
"""
|
||||||
|
types = {
|
||||||
|
'O': 'OK',
|
||||||
|
'E': 'ERR',
|
||||||
|
'S': 'S',
|
||||||
|
'#': '#',
|
||||||
|
'D': 'D',
|
||||||
|
'I': 'INQUIRE',
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, type=None, parameters=None):
|
||||||
|
self.type = type
|
||||||
|
self.parameters = parameters
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.parameters:
|
||||||
|
return '{} {}'.format(self.type, encode(self.parameters))
|
||||||
|
return self.type
|
||||||
|
|
||||||
|
def __bytes__(self):
|
||||||
|
if self.parameters:
|
||||||
|
if self.type == 'D':
|
||||||
|
return b' '.join((b'D', self.parameters))
|
||||||
|
else:
|
||||||
|
return '{} {}'.format(
|
||||||
|
self.type, encode(self.parameters)).encode('utf-8')
|
||||||
|
return self.type.encode('utf-8')
|
||||||
|
|
||||||
|
def from_bytes(self, line):
|
||||||
|
if len(line) > 1000: # TODO: byte-vs-str and newlines?
|
||||||
|
raise _error.AssuanError(message='Line too long')
|
||||||
|
if line.startswith(b'D'):
|
||||||
|
self.command = t = 'D'
|
||||||
|
else:
|
||||||
|
line = str(line, encoding='utf-8')
|
||||||
|
t = line[0]
|
||||||
|
try:
|
||||||
|
type = self.types[t]
|
||||||
|
except KeyError:
|
||||||
|
raise _error.AssuanError(message='Invalid response')
|
||||||
|
self.type = type
|
||||||
|
if type == 'D': # data
|
||||||
|
self.parameters = decode(line[2:])
|
||||||
|
elif type == '#': # comment
|
||||||
|
self.parameters = decode(line[2:])
|
||||||
|
else:
|
||||||
|
match = _REQUEST_REGEXP.match(line)
|
||||||
|
if not match:
|
||||||
|
raise _error.AssuanError(message='Invalid request')
|
||||||
|
if match.group(3):
|
||||||
|
if match.group(2):
|
||||||
|
self.parameters = decode(match.group(3))
|
||||||
|
else:
|
||||||
|
raise _error.AssuanError(message='Invalid request')
|
||||||
|
else:
|
||||||
|
self.parameters = None
|
||||||
|
|
||||||
|
|
||||||
|
def error_response(error):
|
||||||
|
"""
|
||||||
|
|
||||||
|
>>> from pyassuan.error import AssuanError
|
||||||
|
>>> error = AssuanError(1)
|
||||||
|
>>> response = error_response(error)
|
||||||
|
>>> print(response)
|
||||||
|
ERR 1 General error
|
||||||
|
"""
|
||||||
|
return Response(type='ERR', parameters=str(error))
|
||||||
|
|
||||||
|
|
||||||
|
def send_fds(socket, msg=None, fds=None, logger=_LOG):
|
||||||
|
"""Send a file descriptor over a Unix socket using ``sendmsg``.
|
||||||
|
|
||||||
|
``sendmsg`` suport requires Python >= 3.3.
|
||||||
|
|
||||||
|
Code from
|
||||||
|
http://docs.python.org/dev/library/socket.html#socket.socket.sendmsg
|
||||||
|
|
||||||
|
Assuan equivalent is
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-code.html#function-assuan_005fsendfd
|
||||||
|
"""
|
||||||
|
if msg is None:
|
||||||
|
msg = b''.join(
|
||||||
|
[b'# descriptors in flight: ', str(fds).encode('ascii'), b'\n'])
|
||||||
|
if logger is not None:
|
||||||
|
logger.debug('sending file descriptors {} down {}'.format(fds, socket))
|
||||||
|
return socket.sendmsg(
|
||||||
|
[msg],
|
||||||
|
[(_socket.SOL_SOCKET, _socket.SCM_RIGHTS, _array.array('i', fds))])
|
||||||
|
|
||||||
|
def receive_fds(socket, msglen=200, maxfds=10, logger=_LOG):
|
||||||
|
"""Recieve file descriptors using ``recvmsg``.
|
||||||
|
|
||||||
|
``recvmsg`` suport requires Python >= 3.3.
|
||||||
|
|
||||||
|
Code from http://docs.python.org/dev/library/socket.html
|
||||||
|
|
||||||
|
Assuan equivalent is
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Client-code.html#fun_002dassuan_005freceivedfd
|
||||||
|
"""
|
||||||
|
fds = _array.array('i') # Array of ints
|
||||||
|
msg,ancdata,flags,addr = socket.recvmsg(
|
||||||
|
msglen, _socket.CMSG_LEN(maxfds * fds.itemsize))
|
||||||
|
for cmsg_level,cmsg_type,cmsg_data in ancdata:
|
||||||
|
if (cmsg_level == _socket.SOL_SOCKET and
|
||||||
|
cmsg_type == _socket.SCM_RIGHTS):
|
||||||
|
# Append data, ignoring any truncated integers at the end.
|
||||||
|
fds.fromstring(
|
||||||
|
cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
|
||||||
|
if logger is not None:
|
||||||
|
logger.debug('receiving file descriptors {} from {} ({})'.format(
|
||||||
|
fds, socket, msg))
|
||||||
|
return (msg, list(fds))
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Assuan errors as defined in `libgpg-error`_.
|
||||||
|
|
||||||
|
The Assuan_ docs_ suggest these error codes.
|
||||||
|
|
||||||
|
.. _libgpg-error: http://www.gnupg.org/related_software/libgpg-error/
|
||||||
|
.. _Assuan:
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Server-responses.html
|
||||||
|
.. _docs: http://www.gnupg.org/documentation/manuals/assuan/Error-codes.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
MESSAGE = { # extracted from libgpg-error-1.10/src/err-codes.h and gpg-error.h
|
||||||
|
0: 'Success',
|
||||||
|
1: 'General error',
|
||||||
|
2: 'Unknown packet',
|
||||||
|
3: 'Unknown version in packet',
|
||||||
|
4: 'Invalid public key algorithm',
|
||||||
|
5: 'Invalid digest algorithm',
|
||||||
|
6: 'Bad public key',
|
||||||
|
7: 'Bad secret key',
|
||||||
|
8: 'Bad signature',
|
||||||
|
9: 'No public key',
|
||||||
|
10: 'Checksum error',
|
||||||
|
11: 'Bad passphrase',
|
||||||
|
12: 'Invalid cipher algorithm',
|
||||||
|
13: 'Keyring open',
|
||||||
|
14: 'Invalid packet',
|
||||||
|
15: 'Invalid armor',
|
||||||
|
16: 'No user ID',
|
||||||
|
17: 'No secret key',
|
||||||
|
18: 'Wrong secret key used',
|
||||||
|
19: 'Bad session key',
|
||||||
|
20: 'Unknown compression algorithm',
|
||||||
|
21: 'Number is not prime',
|
||||||
|
22: 'Invalid encoding method',
|
||||||
|
23: 'Invalid encryption scheme',
|
||||||
|
24: 'Invalid signature scheme',
|
||||||
|
25: 'Invalid attribute',
|
||||||
|
26: 'No value',
|
||||||
|
27: 'Not found',
|
||||||
|
28: 'Value not found',
|
||||||
|
29: 'Syntax error',
|
||||||
|
30: 'Bad MPI value',
|
||||||
|
31: 'Invalid passphrase',
|
||||||
|
32: 'Invalid signature class',
|
||||||
|
33: 'Resources exhausted',
|
||||||
|
34: 'Invalid keyring',
|
||||||
|
35: 'Trust DB error',
|
||||||
|
36: 'Bad certificate',
|
||||||
|
37: 'Invalid user ID',
|
||||||
|
38: 'Unexpected error',
|
||||||
|
39: 'Time conflict',
|
||||||
|
40: 'Keyserver error',
|
||||||
|
41: 'Wrong public key algorithm',
|
||||||
|
42: 'Tribute to D. A.',
|
||||||
|
43: 'Weak encryption key',
|
||||||
|
44: 'Invalid key length',
|
||||||
|
45: 'Invalid argument',
|
||||||
|
46: 'Syntax error in URI',
|
||||||
|
47: 'Invalid URI',
|
||||||
|
48: 'Network error',
|
||||||
|
49: 'Unknown host',
|
||||||
|
50: 'Selftest failed',
|
||||||
|
51: 'Data not encrypted',
|
||||||
|
52: 'Data not processed',
|
||||||
|
53: 'Unusable public key',
|
||||||
|
54: 'Unusable secret key',
|
||||||
|
55: 'Invalid value',
|
||||||
|
56: 'Bad certificate chain',
|
||||||
|
57: 'Missing certificate',
|
||||||
|
58: 'No data',
|
||||||
|
59: 'Bug',
|
||||||
|
60: 'Not supported',
|
||||||
|
61: 'Invalid operation code',
|
||||||
|
62: 'Timeout',
|
||||||
|
63: 'Internal error',
|
||||||
|
64: 'EOF (gcrypt)',
|
||||||
|
65: 'Invalid object',
|
||||||
|
66: 'Provided object is too short',
|
||||||
|
67: 'Provided object is too large',
|
||||||
|
68: 'Missing item in object',
|
||||||
|
69: 'Not implemented',
|
||||||
|
70: 'Conflicting use',
|
||||||
|
71: 'Invalid cipher mode',
|
||||||
|
72: 'Invalid flag',
|
||||||
|
73: 'Invalid handle',
|
||||||
|
74: 'Result truncated',
|
||||||
|
75: 'Incomplete line',
|
||||||
|
76: 'Invalid response',
|
||||||
|
77: 'No agent running',
|
||||||
|
78: 'agent error',
|
||||||
|
79: 'Invalid data',
|
||||||
|
80: 'Unspecific Assuan server fault',
|
||||||
|
81: 'General Assuan error',
|
||||||
|
82: 'Invalid session key',
|
||||||
|
83: 'Invalid S-expression',
|
||||||
|
84: 'Unsupported algorithm',
|
||||||
|
85: 'No pinentry',
|
||||||
|
86: 'pinentry error',
|
||||||
|
87: 'Bad PIN',
|
||||||
|
88: 'Invalid name',
|
||||||
|
89: 'Bad data',
|
||||||
|
90: 'Invalid parameter',
|
||||||
|
91: 'Wrong card',
|
||||||
|
92: 'No dirmngr',
|
||||||
|
93: 'dirmngr error',
|
||||||
|
94: 'Certificate revoked',
|
||||||
|
95: 'No CRL known',
|
||||||
|
96: 'CRL too old',
|
||||||
|
97: 'Line too long',
|
||||||
|
98: 'Not trusted',
|
||||||
|
99: 'Operation cancelled',
|
||||||
|
100: 'Bad CA certificate',
|
||||||
|
101: 'Certificate expired',
|
||||||
|
102: 'Certificate too young',
|
||||||
|
103: 'Unsupported certificate',
|
||||||
|
104: 'Unknown S-expression',
|
||||||
|
105: 'Unsupported protection',
|
||||||
|
106: 'Corrupted protection',
|
||||||
|
107: 'Ambiguous name',
|
||||||
|
108: 'Card error',
|
||||||
|
109: 'Card reset required',
|
||||||
|
110: 'Card removed',
|
||||||
|
111: 'Invalid card',
|
||||||
|
112: 'Card not present',
|
||||||
|
113: 'No PKCS15 application',
|
||||||
|
114: 'Not confirmed',
|
||||||
|
115: 'Configuration error',
|
||||||
|
116: 'No policy match',
|
||||||
|
117: 'Invalid index',
|
||||||
|
118: 'Invalid ID',
|
||||||
|
119: 'No SmartCard daemon',
|
||||||
|
120: 'SmartCard daemon error',
|
||||||
|
121: 'Unsupported protocol',
|
||||||
|
122: 'Bad PIN method',
|
||||||
|
123: 'Card not initialized',
|
||||||
|
124: 'Unsupported operation',
|
||||||
|
125: 'Wrong key usage',
|
||||||
|
126: 'Nothing found',
|
||||||
|
127: 'Wrong blob type',
|
||||||
|
128: 'Missing value',
|
||||||
|
129: 'Hardware problem',
|
||||||
|
130: 'PIN blocked',
|
||||||
|
131: 'Conditions of use not satisfied',
|
||||||
|
132: 'PINs are not synced',
|
||||||
|
133: 'Invalid CRL',
|
||||||
|
134: 'BER error',
|
||||||
|
135: 'Invalid BER',
|
||||||
|
136: 'Element not found',
|
||||||
|
137: 'Identifier not found',
|
||||||
|
138: 'Invalid tag',
|
||||||
|
139: 'Invalid length',
|
||||||
|
140: 'Invalid key info',
|
||||||
|
141: 'Unexpected tag',
|
||||||
|
142: 'Not DER encoded',
|
||||||
|
143: 'No CMS object',
|
||||||
|
144: 'Invalid CMS object',
|
||||||
|
145: 'Unknown CMS object',
|
||||||
|
146: 'Unsupported CMS object',
|
||||||
|
147: 'Unsupported encoding',
|
||||||
|
148: 'Unsupported CMS version',
|
||||||
|
149: 'Unknown algorithm',
|
||||||
|
150: 'Invalid crypto engine',
|
||||||
|
151: 'Public key not trusted',
|
||||||
|
152: 'Decryption failed',
|
||||||
|
153: 'Key expired',
|
||||||
|
154: 'Signature expired',
|
||||||
|
155: 'Encoding problem',
|
||||||
|
156: 'Invalid state',
|
||||||
|
157: 'Duplicated value',
|
||||||
|
158: 'Missing action',
|
||||||
|
159: 'ASN.1 module not found',
|
||||||
|
160: 'Invalid OID string',
|
||||||
|
161: 'Invalid time',
|
||||||
|
162: 'Invalid CRL object',
|
||||||
|
163: 'Unsupported CRL version',
|
||||||
|
164: 'Invalid certificate object',
|
||||||
|
165: 'Unknown name',
|
||||||
|
166: 'A locale function failed',
|
||||||
|
167: 'Not locked',
|
||||||
|
168: 'Protocol violation',
|
||||||
|
169: 'Invalid MAC',
|
||||||
|
170: 'Invalid request',
|
||||||
|
171: 'Unknown extension',
|
||||||
|
172: 'Unknown critical extension',
|
||||||
|
173: 'Locked',
|
||||||
|
174: 'Unknown option',
|
||||||
|
175: 'Unknown command',
|
||||||
|
176: 'Not operational',
|
||||||
|
177: 'No passphrase given',
|
||||||
|
178: 'No PIN given',
|
||||||
|
179: 'Not enabled',
|
||||||
|
180: 'No crypto engine',
|
||||||
|
181: 'Missing key',
|
||||||
|
182: 'Too many objects',
|
||||||
|
183: 'Limit reached',
|
||||||
|
184: 'Not initialized',
|
||||||
|
185: 'Missing issuer certificate',
|
||||||
|
198: 'Operation fully cancelled',
|
||||||
|
199: 'Operation not yet finished',
|
||||||
|
200: 'Buffer too short',
|
||||||
|
201: 'Invalid length specifier in S-expression',
|
||||||
|
202: 'String too long in S-expression',
|
||||||
|
203: 'Unmatched parentheses in S-expression',
|
||||||
|
204: 'S-expression not canonical',
|
||||||
|
205: 'Bad character in S-expression',
|
||||||
|
206: 'Bad quotation in S-expression',
|
||||||
|
207: 'Zero prefix in S-expression',
|
||||||
|
208: 'Nested display hints in S-expression',
|
||||||
|
209: 'Unmatched display hints',
|
||||||
|
210: 'Unexpected reserved punctuation in S-expression',
|
||||||
|
211: 'Bad hexadecimal character in S-expression',
|
||||||
|
212: 'Odd hexadecimal numbers in S-expression',
|
||||||
|
213: 'Bad octal character in S-expression',
|
||||||
|
257: 'General IPC error',
|
||||||
|
258: 'IPC accept call failed',
|
||||||
|
259: 'IPC connect call failed',
|
||||||
|
260: 'Invalid IPC response',
|
||||||
|
261: 'Invalid value passed to IPC',
|
||||||
|
262: 'Incomplete line passed to IPC',
|
||||||
|
263: 'Line passed to IPC too long',
|
||||||
|
264: 'Nested IPC commands',
|
||||||
|
265: 'No data callback in IPC',
|
||||||
|
266: 'No inquire callback in IPC',
|
||||||
|
267: 'Not an IPC server',
|
||||||
|
268: 'Not an IPC client',
|
||||||
|
269: 'Problem starting IPC server',
|
||||||
|
270: 'IPC read error',
|
||||||
|
271: 'IPC write error',
|
||||||
|
273: 'Too much data for IPC layer',
|
||||||
|
274: 'Unexpected IPC command',
|
||||||
|
275: 'Unknown IPC command',
|
||||||
|
276: 'IPC syntax error',
|
||||||
|
277: 'IPC call has been cancelled',
|
||||||
|
278: 'No input source for IPC',
|
||||||
|
279: 'No output source for IPC',
|
||||||
|
280: 'IPC parameter error',
|
||||||
|
281: 'Unknown IPC inquire',
|
||||||
|
1024: 'User defined error code 1',
|
||||||
|
1025: 'User defined error code 2',
|
||||||
|
1026: 'User defined error code 3',
|
||||||
|
1027: 'User defined error code 4',
|
||||||
|
1028: 'User defined error code 5',
|
||||||
|
1029: 'User defined error code 6',
|
||||||
|
1030: 'User defined error code 7',
|
||||||
|
1031: 'User defined error code 8',
|
||||||
|
1032: 'User defined error code 9',
|
||||||
|
1033: 'User defined error code 10',
|
||||||
|
1034: 'User defined error code 11',
|
||||||
|
1035: 'User defined error code 12',
|
||||||
|
1036: 'User defined error code 13',
|
||||||
|
1037: 'User defined error code 14',
|
||||||
|
1038: 'User defined error code 15',
|
||||||
|
1039: 'User defined error code 16',
|
||||||
|
16381: 'System error w/o errno',
|
||||||
|
16382: 'Unknown system error',
|
||||||
|
16383: 'End of file',
|
||||||
|
}
|
||||||
|
UNKNOWN = 'Unknown error code'
|
||||||
|
|
||||||
|
CODE = dict((message,code) for code,message in MESSAGE.items())
|
||||||
|
|
||||||
|
# TODO: system errors (GPG_ERR_E2BIG = GPG_ERR_SYSTEM_ERROR | 0, etc.)
|
||||||
|
|
||||||
|
class AssuanError (Exception):
|
||||||
|
r"""
|
||||||
|
|
||||||
|
>>> e = AssuanError(1)
|
||||||
|
>>> print(e)
|
||||||
|
1 General error
|
||||||
|
>>> e = AssuanError(1024, 'testing!')
|
||||||
|
>>> print(e)
|
||||||
|
1024 testing!
|
||||||
|
>>> e = AssuanError(message='Unknown packet')
|
||||||
|
>>> print(e)
|
||||||
|
2 Unknown packet
|
||||||
|
"""
|
||||||
|
def __init__(self, code=None, message=None):
|
||||||
|
if code is None and message is None:
|
||||||
|
raise ValueError('missing both `code` and `message`')
|
||||||
|
if message is None:
|
||||||
|
message = MESSAGE[code]
|
||||||
|
if code is None:
|
||||||
|
code = CODE.get(message, UNKNOWN)
|
||||||
|
self.code = code
|
||||||
|
self.message = message
|
||||||
|
super(AssuanError, self).__init__('{} {}'.format(code, message))
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
# Copyright (C) 2012 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import logging as _logging
|
||||||
|
import re as _re
|
||||||
|
import socket as _socket
|
||||||
|
import sys as _sys
|
||||||
|
import threading as _threading
|
||||||
|
import traceback as _traceback
|
||||||
|
|
||||||
|
from . import LOG as _LOG
|
||||||
|
from . import common as _common
|
||||||
|
from . import error as _error
|
||||||
|
|
||||||
|
|
||||||
|
_OPTION_REGEXP = _re.compile('^-?-?([-\w]+)( *)(=?) *(.*?) *\Z')
|
||||||
|
|
||||||
|
|
||||||
|
class AssuanServer (object):
|
||||||
|
"""A single-threaded Assuan server based on the `devolpment suggestions`_
|
||||||
|
|
||||||
|
Extend by subclassing and adding ``_handle_XXX`` methods for each
|
||||||
|
command you want to handle.
|
||||||
|
|
||||||
|
.. _development suggestions:
|
||||||
|
http://www.gnupg.org/documentation/manuals/assuan/Server-code.html
|
||||||
|
"""
|
||||||
|
def __init__(self, name, logger=_LOG, use_sublogger=True,
|
||||||
|
valid_options=None, strict_options=True,
|
||||||
|
single_request=False, listen_to_quit=False,
|
||||||
|
close_on_disconnect=False):
|
||||||
|
self.name = name
|
||||||
|
if use_sublogger:
|
||||||
|
logger = _logging.getLogger('{}.{}'.format(logger.name, self.name))
|
||||||
|
self.logger = logger
|
||||||
|
if valid_options is None:
|
||||||
|
valid_options = []
|
||||||
|
self.valid_options = valid_options
|
||||||
|
self.strict_options = strict_options
|
||||||
|
self.single_request = single_request
|
||||||
|
self.listen_to_quit = listen_to_quit
|
||||||
|
self.close_on_disconnect = close_on_disconnect
|
||||||
|
self.input = self.output = None
|
||||||
|
self.options = {}
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.stop = False
|
||||||
|
self.options.clear()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.reset()
|
||||||
|
self.logger.info('running')
|
||||||
|
self.connect()
|
||||||
|
try:
|
||||||
|
self.handle_requests()
|
||||||
|
finally:
|
||||||
|
self.disconnect()
|
||||||
|
self.logger.info('stopping')
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
if not self.input:
|
||||||
|
self.logger.info('read from stdin')
|
||||||
|
self.input = _sys.stdin.buffer
|
||||||
|
if not self.output:
|
||||||
|
self.logger.info('write to stdout')
|
||||||
|
self.output = _sys.stdout.buffer
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
if self.close_on_disconnect:
|
||||||
|
self.logger.info('disconnecting')
|
||||||
|
self.input = None
|
||||||
|
self.output = None
|
||||||
|
|
||||||
|
def handle_requests(self):
|
||||||
|
self.send_response(_common.Response('OK', 'Your orders please'))
|
||||||
|
self.output.flush()
|
||||||
|
while not self.stop:
|
||||||
|
line = self.input.readline()
|
||||||
|
if not line:
|
||||||
|
break # EOF
|
||||||
|
if len(line) > _common.LINE_LENGTH:
|
||||||
|
self.raise_error(
|
||||||
|
_error.AssuanError(message='Line too long'))
|
||||||
|
if not line.endswith(b'\n'):
|
||||||
|
self.logger.info('C: {}'.format(line))
|
||||||
|
self.send_error_response(
|
||||||
|
_error.AssuanError(message='Invalid request'))
|
||||||
|
continue
|
||||||
|
line = line[:-1] # remove the trailing newline
|
||||||
|
self.logger.info('C: {}'.format(line))
|
||||||
|
request = _common.Request()
|
||||||
|
try:
|
||||||
|
request.from_bytes(line)
|
||||||
|
except _error.AssuanError as e:
|
||||||
|
self.send_error_response(e)
|
||||||
|
continue
|
||||||
|
self.handle_request(request)
|
||||||
|
|
||||||
|
def handle_request(self, request):
|
||||||
|
try:
|
||||||
|
handle = getattr(
|
||||||
|
self, '_handle_{}'.format(request.command))
|
||||||
|
except AttributeError:
|
||||||
|
self.logger.warn('unknown command: {}'.format(request.command))
|
||||||
|
self.send_error_response(
|
||||||
|
_error.AssuanError(message='Unknown command'))
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
responses = handle(request.parameters)
|
||||||
|
for response in responses:
|
||||||
|
self.send_response(response)
|
||||||
|
except _error.AssuanError as error:
|
||||||
|
self.send_error_response(error)
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(
|
||||||
|
'exception while executing {}:\n{}'.format(
|
||||||
|
handle, _traceback.format_exc().rstrip()))
|
||||||
|
self.send_error_response(
|
||||||
|
_error.AssuanError(message='Unspecific Assuan server fault'))
|
||||||
|
return
|
||||||
|
|
||||||
|
def send_response(self, response):
|
||||||
|
"""For internal use by ``.handle_requests()``
|
||||||
|
"""
|
||||||
|
rstring = str(response)
|
||||||
|
self.logger.info('S: {}'.format(response))
|
||||||
|
self.output.write(bytes(response))
|
||||||
|
self.output.write(b'\n')
|
||||||
|
try:
|
||||||
|
self.output.flush()
|
||||||
|
except IOError:
|
||||||
|
if not self.stop:
|
||||||
|
raise
|
||||||
|
|
||||||
|
def send_error_response(self, error):
|
||||||
|
"""For internal use by ``.handle_requests()``
|
||||||
|
"""
|
||||||
|
self.send_response(_common.error_response(error))
|
||||||
|
|
||||||
|
# common commands defined at
|
||||||
|
# http://www.gnupg.org/documentation/manuals/assuan/Client-requests.html
|
||||||
|
|
||||||
|
def _handle_BYE(self, arg):
|
||||||
|
if self.single_request:
|
||||||
|
self.stop = True
|
||||||
|
yield _common.Response('OK', 'closing connection')
|
||||||
|
|
||||||
|
def _handle_RESET(self, arg):
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def _handle_END(self, arg):
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
def _handle_HELP(self, arg):
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
def _handle_QUIT(self, arg):
|
||||||
|
if self.listen_to_quit:
|
||||||
|
self.stop = True
|
||||||
|
yield _common.Response('OK', 'stopping the server')
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
def _handle_OPTION(self, arg):
|
||||||
|
"""
|
||||||
|
|
||||||
|
>>> s = AssuanServer(name='test', valid_options=['my-op'])
|
||||||
|
>>> list(s._handle_OPTION('my-op = 1 ')) # doctest: +ELLIPSIS
|
||||||
|
[<pyassuan.common.Response object at ...>]
|
||||||
|
>>> s.options
|
||||||
|
{'my-op': '1'}
|
||||||
|
>>> list(s._handle_OPTION('my-op 2')) # doctest: +ELLIPSIS
|
||||||
|
[<pyassuan.common.Response object at ...>]
|
||||||
|
>>> s.options
|
||||||
|
{'my-op': '2'}
|
||||||
|
>>> list(s._handle_OPTION('--my-op 3')) # doctest: +ELLIPSIS
|
||||||
|
[<pyassuan.common.Response object at ...>]
|
||||||
|
>>> s.options
|
||||||
|
{'my-op': '3'}
|
||||||
|
>>> list(s._handle_OPTION('my-op')) # doctest: +ELLIPSIS
|
||||||
|
[<pyassuan.common.Response object at ...>]
|
||||||
|
>>> s.options
|
||||||
|
{'my-op': None}
|
||||||
|
>>> list(s._handle_OPTION('inv'))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 174 Unknown option
|
||||||
|
>>> list(s._handle_OPTION('in|valid'))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
pyassuan.error.AssuanError: 90 Invalid parameter
|
||||||
|
"""
|
||||||
|
match = _OPTION_REGEXP.match(arg)
|
||||||
|
if not match:
|
||||||
|
raise _error.AssuanError(message='Invalid parameter')
|
||||||
|
name,space,equal,value = match.groups()
|
||||||
|
if value and not space and not equal:
|
||||||
|
# need either space or equal to separate value
|
||||||
|
raise _error.AssuanError(message='Invalid parameter')
|
||||||
|
if name not in self.valid_options:
|
||||||
|
if self.strict_options:
|
||||||
|
raise _error.AssuanError(message='Unknown option')
|
||||||
|
else:
|
||||||
|
self.logger.info('skipping invalid option: {}'.format(name))
|
||||||
|
else:
|
||||||
|
if not value:
|
||||||
|
value = None
|
||||||
|
self.options[name] = value
|
||||||
|
yield _common.Response('OK')
|
||||||
|
|
||||||
|
def _handle_CANCEL(self, arg):
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
def _handle_AUTH(self, arg):
|
||||||
|
raise _error.AssuanError(
|
||||||
|
code=175, message='Unknown command (reserved)')
|
||||||
|
|
||||||
|
|
||||||
|
class AssuanSocketServer (object):
|
||||||
|
"""A threaded server spawning ``AssuanServer``\s for each connection
|
||||||
|
"""
|
||||||
|
def __init__(self, name, socket, server, kwargs={}, max_threads=10,
|
||||||
|
logger=_LOG, use_sublogger=True):
|
||||||
|
self.name = name
|
||||||
|
if use_sublogger:
|
||||||
|
logger = _logging.getLogger('{}.{}'.format(logger.name, self.name))
|
||||||
|
self.logger = logger
|
||||||
|
self.socket = socket
|
||||||
|
self.server = server
|
||||||
|
assert 'name' not in kwargs, kwargs['name']
|
||||||
|
assert 'logger' not in kwargs, kwargs['logger']
|
||||||
|
kwargs['logger'] = self.logger
|
||||||
|
assert 'use_sublogger' not in kwargs, kwargs['use_sublogger']
|
||||||
|
kwargs['use_sublogger'] = True
|
||||||
|
if 'close_on_disconnect' in kwargs:
|
||||||
|
assert kwargs['close_on_disconnect'] == True, (
|
||||||
|
kwargs['close_on_disconnect'])
|
||||||
|
else:
|
||||||
|
kwargs['close_on_disconnect'] = True
|
||||||
|
self.kwargs = kwargs
|
||||||
|
self.max_threads = max_threads
|
||||||
|
self.threads = []
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.logger.info('listen on socket')
|
||||||
|
self.socket.listen()
|
||||||
|
thread_index = 0
|
||||||
|
while True:
|
||||||
|
socket,address = self.socket.accept()
|
||||||
|
self.logger.info('connection from {}'.format(address))
|
||||||
|
self.cleanup_threads()
|
||||||
|
if len(threads) > self.max_threads:
|
||||||
|
self.drop_connection(socket, address)
|
||||||
|
self.spawn_thread(
|
||||||
|
'server-thread-{}'.format(thread_index), socket, address)
|
||||||
|
thread_index = (thread_index + 1) % self.max_threads
|
||||||
|
|
||||||
|
def cleanup_threads(self):
|
||||||
|
i = 0
|
||||||
|
while i < len(self.threads):
|
||||||
|
thread = self.threads[i]
|
||||||
|
thread.join(0)
|
||||||
|
if thread.is_alive():
|
||||||
|
self.logger.info('joined thread {}'.format(thread.name))
|
||||||
|
self.threads.pop(i)
|
||||||
|
thread.socket.shutdown()
|
||||||
|
thread.socket.close()
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
def drop_connection(self, socket, address):
|
||||||
|
self.logger.info('drop connection from {}'.format(address))
|
||||||
|
# TODO: proper error to send to the client?
|
||||||
|
|
||||||
|
def spawn_thread(self, name, socket, address):
|
||||||
|
server = self.server(name=name, **self.kwargs)
|
||||||
|
server.input = socket.makefile('rb')
|
||||||
|
server.output = socket.makefile('wb')
|
||||||
|
thread = _threading.Thread(target=server.run, name=name)
|
||||||
|
thread.start()
|
||||||
|
self.threads.append(thread)
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (C) 2012-2018 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import doctest
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from . import common
|
||||||
|
|
||||||
|
|
||||||
|
def load_tests(loader, tests, ignore):
|
||||||
|
tests.addTests(doctest.DocTestSuite(common))
|
||||||
|
return tests
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (C) 2012-2018 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import doctest
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from . import error
|
||||||
|
|
||||||
|
|
||||||
|
def load_tests(loader, tests, ignore):
|
||||||
|
tests.addTests(doctest.DocTestSuite(error))
|
||||||
|
return tests
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (C) 2012-2018 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import doctest
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from . import server
|
||||||
|
|
||||||
|
|
||||||
|
def load_tests(loader, tests, ignore):
|
||||||
|
tests.addTests(doctest.DocTestSuite(server))
|
||||||
|
return tests
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Copyright (C) 2012-2018 W. Trevor King <wking@tremily.us>
|
||||||
|
#
|
||||||
|
# This file is part of pyassuan.
|
||||||
|
#
|
||||||
|
# pyassuan 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 3 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# pyassuan 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
|
||||||
|
# pyassuan. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"Python module and tools for communicating in the Assuan protocol."
|
||||||
|
|
||||||
|
from distutils.core import setup as _setup
|
||||||
|
import os.path as _os_path
|
||||||
|
|
||||||
|
from pyassuan import __version__
|
||||||
|
|
||||||
|
|
||||||
|
_this_dir = _os_path.dirname(__file__)
|
||||||
|
|
||||||
|
_setup(
|
||||||
|
name='pyassuan',
|
||||||
|
version=__version__,
|
||||||
|
maintainer='W. Trevor King',
|
||||||
|
maintainer_email='wking@tremily.us',
|
||||||
|
url='http://blog.tremily.us/posts/pyassuan/',
|
||||||
|
download_url='http://git.tremily.us/?p=pyassuan.git;a=snapshot;h=v{};sf=tgz'.format(__version__),
|
||||||
|
license = 'GNU General Public License (GPL)',
|
||||||
|
platforms = ['all'],
|
||||||
|
description = __doc__,
|
||||||
|
long_description=open(_os_path.join(_this_dir, 'README'), 'r').read(),
|
||||||
|
classifiers = [
|
||||||
|
'Development Status :: 3 - Alpha',
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'Operating System :: OS Independent',
|
||||||
|
'License :: OSI Approved :: GNU General Public License (GPL)',
|
||||||
|
'Programming Language :: Python :: 3',
|
||||||
|
'Programming Language :: Python :: 3.3',
|
||||||
|
'Programming Language :: Python :: 3.4',
|
||||||
|
'Programming Language :: Python :: 3.5',
|
||||||
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Topic :: Security :: Cryptography',
|
||||||
|
'Topic :: Software Development'
|
||||||
|
],
|
||||||
|
scripts = ['bin/get-info.py', 'bin/pinentry.py'],
|
||||||
|
packages = ['pyassuan'],
|
||||||
|
provides = ['pyassuan'],
|
||||||
|
)
|
||||||
7
roles/toxcore/overlay/Linux/usr/local/bin/analyze-ssl.pl.bash
Executable file
7
roles/toxcore/overlay/Linux/usr/local/bin/analyze-ssl.pl.bash
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
# https://github.com/noxxi/p5-ssl-tools/
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
cd /usr/local/src/ || exit 1
|
||||||
|
exec perl analyze-ssl.pl "$@"
|
||||||
89
roles/toxcore/overlay/Linux/usr/local/bin/ansible.bash
Executable file
89
roles/toxcore/overlay/Linux/usr/local/bin/ansible.bash
Executable file
@@ -0,0 +1,89 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
#? broken in ansible
|
||||||
|
|
||||||
|
PYVER=3
|
||||||
|
P="BASE_PYTHON${PYVER}_MINOR"
|
||||||
|
PYTHON_MINOR="$(eval echo \$$P)"
|
||||||
|
[ -z "$PYTHON_MINOR" ] || PYTHON_MINOR=3.9
|
||||||
|
PYTHON_EXE_MSYS=$PREFIX/bin/python$PYVER.sh
|
||||||
|
PYTHON_EXE=$PYTHON_EXE_MSYS
|
||||||
|
DESC=""
|
||||||
|
|
||||||
|
PKG="ansible"
|
||||||
|
MOD="$PKG"
|
||||||
|
|
||||||
|
VER="2.9.22"
|
||||||
|
AVER="2.9.22"
|
||||||
|
DIR="${PKG}-$VER"
|
||||||
|
EXT="tar.gz"
|
||||||
|
URL="files.pythonhosted.org/packages/03/4f/cccab1ec2e0ecb05120184088e00404b38854809cf35aa76889406fbcbad/ansible-2.9.10.tar.gz"
|
||||||
|
TODIR=/o/data/TestForge/src/ansible
|
||||||
|
|
||||||
|
if [ -f /var/local/src/var_local_src.bash ] ; then
|
||||||
|
. /var/local/src/var_local_src.bash
|
||||||
|
else
|
||||||
|
ols_are_we_connected () { route | grep -q ^default ; return $? ; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $PREFIX/src || exit 2
|
||||||
|
WD=$PWD
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ] ; then
|
||||||
|
if [ ! -d "$DIR" ] ; then
|
||||||
|
if [ ! -f "$HTTP_DIR/$URL" ] ; then
|
||||||
|
ols_are_we_connected || { DEBUG not connected ; exit 0 ; }
|
||||||
|
wget -xc -P "$HTTP_DIR" "https://$URL" || exit 2
|
||||||
|
fi
|
||||||
|
if [ "$EXT" = "zip" ] ; then
|
||||||
|
unzip "$HTTP_DIR/$URL" || exit 3
|
||||||
|
else
|
||||||
|
tar xfvz "$HTTP_DIR/$URL" || exit 3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$DIR" || exit 4
|
||||||
|
|
||||||
|
[ -f lib/ansible/parsing/utils/yaml.py.dst ] || \
|
||||||
|
bash /usr/local/sbin/base_patch_from_diff.bash $ROLE \
|
||||||
|
$TODIR/roles/$ROLE/overlay/Linux/$PREFIX/patches/$ROLE/$PWD || exit 6$?
|
||||||
|
|
||||||
|
[ -d $PREFIX/$LIB/python$PYTHON_MINOR/site-packages/$DIR-py$PYTHON_MINOR.egg ] || \
|
||||||
|
pip3.sh install . >> install.log 2>&1\
|
||||||
|
|| { echo "ERROR: code $?" ; tail install.log ; exit 5 ; }
|
||||||
|
|
||||||
|
"$PYTHON_EXE" -c "import $MOD" || exit 10
|
||||||
|
|
||||||
|
|
||||||
|
grep -l '_tput\|_src' *sh ../bin*sh | \
|
||||||
|
xargs grep -l 'echo \(INFO\|DEBUG\|ERROR\|DEBUG\):' | \
|
||||||
|
xargs sed -e 's@echo \(INFO\|DEBUG\|ERROR\|DEBUG\):@\1 @'
|
||||||
|
|
||||||
|
if [ -d $PREFIX/src/ansible-$AVER/docs/docsite ] ; then
|
||||||
|
cd $PREFIX/src/ansible-$AVER/docs/docsite
|
||||||
|
[ -f htmldocs.log ] || make -n -f Makefile htmldocs > htmldocs.log 2>&1 || exit 2$?
|
||||||
|
[ -f info.log ] || make -n -f Makefile.sphinx info > info.log 2>&1 || exit 3$?
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
elif [ "$1" = 'check' ] ; then
|
||||||
|
"$PYTHON_EXE" -c "import $MOD" || exit 10
|
||||||
|
# msys_run_checks_requirements
|
||||||
|
|
||||||
|
elif [ $1 = 'test' ] ; then
|
||||||
|
cd $PREFIX/src/$DIR || exit 50
|
||||||
|
$PYTHON_EXE_MSYS -m tox >> test.log 2>&1 || \
|
||||||
|
{ echo "ERROR: $MOD code $?" ; cat test.log ; exit 51 ; }
|
||||||
|
|
||||||
|
elif [ "$1" = 'refresh' ] ; then
|
||||||
|
cd $PREFIX/src/$DIR || exit 60
|
||||||
|
env PWD=$PREFIX/src/$DIR \
|
||||||
|
/usr/local/sbin/base_diff_from_dst.bash $ROLE || exit 6$?
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
53
roles/toxcore/overlay/Linux/usr/local/bin/ansible_get_inventory.bash
Executable file
53
roles/toxcore/overlay/Linux/usr/local/bin/ansible_get_inventory.bash
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
# retval on stdout - messages on stderr
|
||||||
|
. /usr/local/bin/usr_local_tput.bash
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
AnsI=AnsI
|
||||||
|
|
||||||
|
# quiet
|
||||||
|
[ "$#" -eq 0 ] && exit 1
|
||||||
|
VARIABLE=$1
|
||||||
|
shift
|
||||||
|
[ "$#" -eq 0 ] && base=`hostname` || base=$1
|
||||||
|
|
||||||
|
[ -f $PREFIX/etc/testforge/testforge.bash ] && . $PREFIX/etc/testforge/testforge.bash
|
||||||
|
|
||||||
|
[ -n "$PLAY_ANSIBLE_SRC" ] || PLAY_ANSIBLE_SRC=$BASE_ANSIBLE_SRC
|
||||||
|
[ -n "$PLAY_ANSIBLE_SRC" ] || PLAY_ANSIBLE_SRC=/mnt/o/data/TestForge/src/ansible
|
||||||
|
[ -z "$PLAY_ANSIBLE_SRC" ] && ERROR export "PLAY_ANSIBLE_SRC" >&2 && exit 3
|
||||||
|
[ ! -d "$PLAY_ANSIBLE_SRC" ] && ERROR ! -d "PLAY_ANSIBLE_SRC" >&2 && exit 4
|
||||||
|
[ ! -f "$PLAY_ANSIBLE_SRC"/hosts.yml ] && ERROR ! -f "PLAY_ANSIBLE_SRC"/hosts.yml >&2 && exit 4
|
||||||
|
|
||||||
|
DBUG ansible-inventory -i $PLAY_ANSIBLE_SRC/hosts.yml \
|
||||||
|
--playbook-dir=$PLAY_ANSIBLE_SRC \
|
||||||
|
--host=$base >&2
|
||||||
|
ansible-inventory -i $PLAY_ANSIBLE_SRC/hosts.yml \
|
||||||
|
--playbook-dir=$PLAY_ANSIBLE_SRC \
|
||||||
|
--host=$base >> /tmp/${AnsI}$$.json 2> /tmp/${AnsI}$$.err
|
||||||
|
retval=$?
|
||||||
|
if [ $retval -eq 0 ] ; then
|
||||||
|
[ ! -s /tmp/${AnsI}$$.json ] && ERROR empty /tmp/${AnsI}$$.json >&2 && exit 4
|
||||||
|
#!? export
|
||||||
|
VALUE=`jq .$VARIABLE < /tmp/${AnsI}$$.json | sed -e 's/,//'|xargs echo 2>/tmp/${AnsI}$$.err`
|
||||||
|
jretval=$?
|
||||||
|
if [ $jretval -eq 0 ] ; then
|
||||||
|
[ -n "$DEBUG" ] && DBUG "$prog base=$base VALUE=$VALUE" >&2
|
||||||
|
[ "$VALUE" = "null" ] && VALUE=""
|
||||||
|
echo -n "$VALUE"
|
||||||
|
else
|
||||||
|
WARN $VARIABLE jretval=$jretval /tmp/${AnsI}$$.err >&2
|
||||||
|
exit 7$retval
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
ERROR $VARIABLE retval=$retval /tmp/${AnsI}$$.json /tmp/${AnsI}$$.err >&2
|
||||||
|
cat /tmp/${AnsI}$$.err >&2
|
||||||
|
exit 8
|
||||||
|
fi
|
||||||
|
# rm -f /tmp/${AnsI}$$.json
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
#https://mirrors.edge.kernel.org/pub/linux/utils/boot/dracut/dracut-055.tar.sign
|
||||||
|
#https://mirrors.edge.kernel.org/pub/linux/utils/boot/dracut/dracut-055.tar.gz
|
||||||
8
roles/toxcore/overlay/Linux/usr/local/bin/firewall.bash
Executable file
8
roles/toxcore/overlay/Linux/usr/local/bin/firewall.bash
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
PREFIX=/usr/local
|
||||||
|
|
||||||
|
ROLE=toxcore
|
||||||
|
iptables-legacy -F;iptables-legacy -F -t nat;iptables-legacy -F -t mangle
|
||||||
|
iptables-legacy-restore </etc/firewall.conf
|
||||||
11
roles/toxcore/overlay/Linux/usr/local/bin/gridfire.bash
Executable file
11
roles/toxcore/overlay/Linux/usr/local/bin/gridfire.bash
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
[ -f $PREFIX/bin/gridfire.rc ] && . $PREFIX/bin/gridfire.rc
|
||||||
|
|
||||||
|
cd /usr/local/src/gridfire || exit 3
|
||||||
|
|
||||||
|
exec /usr/local/bin/python3.sh gridfire.py "$@"
|
||||||
59
roles/toxcore/overlay/Linux/usr/local/bin/gridfire.sh
Executable file
59
roles/toxcore/overlay/Linux/usr/local/bin/gridfire.sh
Executable file
@@ -0,0 +1,59 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
declare -a ELTS LARGS RARGS
|
||||||
|
ELTS=(
|
||||||
|
gridfire_ansible-vault.sh
|
||||||
|
gridfire_keepassxc-cli.sh
|
||||||
|
gridfire_keepassxc.sh
|
||||||
|
gridfire_keyring.sh
|
||||||
|
gridfire_openssl.sh
|
||||||
|
gridfire_secret-tool.sh
|
||||||
|
gridfire_staticgpg.sh
|
||||||
|
gridfire_truecrypt.sh
|
||||||
|
gridfire_veracrypt.sh
|
||||||
|
)
|
||||||
|
SHORTOPTS="ha:cgulbodfpwm:nv:s:D:P:H:A:"
|
||||||
|
|
||||||
|
OARGS="$@"
|
||||||
|
ARGS=$(getopt --options $SHORTOPTS -- "$@")
|
||||||
|
[ $? != 0 ] && error 2 "Aborting."
|
||||||
|
eval set -- "$ARGS"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h|-c|-g|-u|-l|-b|-o|-d|-f|-p|-w|-n)
|
||||||
|
LARGS+=($1)
|
||||||
|
shift;;
|
||||||
|
-a|-m|-v|-s|-D|-P|-H|-A)
|
||||||
|
LARGS+=($1)
|
||||||
|
shift
|
||||||
|
LARGS+=($1)
|
||||||
|
shift;;
|
||||||
|
'--')
|
||||||
|
shift
|
||||||
|
RARGS=("$@")
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
done
|
||||||
|
#echo DEBUG: LARGS ${LARGS[@]}
|
||||||
|
#echo DEBUG: RARGS ${RARGS[@]}
|
||||||
|
case ${RARGS[0]} in
|
||||||
|
ansible-vault|keepassxc-cli|keepassxc|keyring|openssl|secret-tool|staticgpg|truecrypt|veracrypt|foo)
|
||||||
|
elt=gridfire_${RARGS[0]}.bash
|
||||||
|
unset ${RARGS[0]}
|
||||||
|
RARGS[0]=""
|
||||||
|
exec bash $elt ${LARGS[@]} ${RARGS[@]}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
# echo ${RARGS[@]}
|
||||||
|
|
||||||
|
exec python3.sh $PREFIX/src/gridfire/gridfire.py "$OARGS"
|
||||||
11
roles/toxcore/overlay/Linux/usr/local/bin/gridfire2.bash
Executable file
11
roles/toxcore/overlay/Linux/usr/local/bin/gridfire2.bash
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
# https://github.com/reid-k/gridfire/
|
||||||
|
|
||||||
|
prog=$( basename $0 .bash )
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
PYVER=2
|
||||||
|
|
||||||
|
exec python$PYVER.sh /usr/local/src/gridfire/gridfire.py "$OARGS"
|
||||||
9
roles/toxcore/overlay/Linux/usr/local/bin/gridfire3.bash
Executable file
9
roles/toxcore/overlay/Linux/usr/local/bin/gridfire3.bash
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=$( basename $0 .bash )
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
PYVER=3
|
||||||
|
|
||||||
|
exec python$PYVER.sh /usr/local/src/gridfire/gridfire.py "$@"
|
||||||
13
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_ansible-vault.bash
Executable file
13
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_ansible-vault.bash
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
PYVER=3
|
||||||
|
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
export PYTHONPATH=$PREFIX/src/gridfire
|
||||||
|
exec $PREFIX/bin/gridfire -H "ansible-vault.py" -- \
|
||||||
|
$PREFIX/bin/python$PYVER.sh $PREFIX/src/gridfire/ansible-vault.py "$@"
|
||||||
|
|
||||||
174
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_ansible-vault.py.bash
Executable file
174
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_ansible-vault.py.bash
Executable file
@@ -0,0 +1,174 @@
|
|||||||
|
#!/usr/local/bin/python2.sh
|
||||||
|
# -*-mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
|
||||||
|
|
||||||
|
# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of Ansible
|
||||||
|
#
|
||||||
|
# Ansible 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 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ansible 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 Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
__requires__ = ['ansible']
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
from ansible import context
|
||||||
|
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
|
||||||
|
from ansible.module_utils._text import to_text
|
||||||
|
|
||||||
|
from gridfire import getpass
|
||||||
|
|
||||||
|
ROLE=toxcore
|
||||||
|
# Used for determining if the system is running a new enough python version
|
||||||
|
# and should only restrict on our documented minimum versions
|
||||||
|
_PY3_MIN = sys.version_info[:2] >= (3, 5)
|
||||||
|
_PY2_MIN = (2, 6) <= sys.version_info[:2] < (3,)
|
||||||
|
_PY_MIN = _PY3_MIN or _PY2_MIN
|
||||||
|
if not _PY_MIN:
|
||||||
|
raise SystemExit('ERROR: Ansible requires a minimum of Python2 version 2.6 or Python3 version 3.5. Current version: %s' % ''.join(sys.version.splitlines()))
|
||||||
|
|
||||||
|
|
||||||
|
class LastResort(object):
|
||||||
|
# OUTPUT OF LAST RESORT
|
||||||
|
def display(self, msg, log_only=None):
|
||||||
|
print(msg, file=sys.stderr)
|
||||||
|
|
||||||
|
def error(self, msg, wrap_text=None):
|
||||||
|
print(msg, file=sys.stderr)
|
||||||
|
|
||||||
|
def prompt(self, msg, private=True):
|
||||||
|
return getpass(msg)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
display = LastResort()
|
||||||
|
|
||||||
|
try: # bad ANSIBLE_CONFIG or config options can force ugly stacktrace
|
||||||
|
import ansible.constants as C
|
||||||
|
from ansible.utils.display import Display
|
||||||
|
except AnsibleOptionsError as e:
|
||||||
|
display.error(to_text(e), wrap_text=False)
|
||||||
|
sys.exit(5)
|
||||||
|
|
||||||
|
_Display = Display
|
||||||
|
class MyDisplay(_Display):
|
||||||
|
name = 'getpass'
|
||||||
|
def prompt(self, prompt, private=True):
|
||||||
|
return getpass(prompt)
|
||||||
|
|
||||||
|
Display = MyDisplay
|
||||||
|
display = MyDisplay()
|
||||||
|
from ansible.parsing import vault
|
||||||
|
vault.display = display
|
||||||
|
|
||||||
|
cli = None
|
||||||
|
me = os.path.basename(sys.argv[0])
|
||||||
|
|
||||||
|
try:
|
||||||
|
display.v("starting run")
|
||||||
|
|
||||||
|
sub = None
|
||||||
|
target = me.split('-')
|
||||||
|
if target[-1][0].isdigit():
|
||||||
|
# Remove any version or python version info as downstreams
|
||||||
|
# sometimes add that
|
||||||
|
target = target[:-1]
|
||||||
|
|
||||||
|
if len(target) > 1:
|
||||||
|
sub = target[1]
|
||||||
|
myclass = "%sCLI" % sub.capitalize()
|
||||||
|
elif target[0] == 'ansible':
|
||||||
|
sub = 'adhoc'
|
||||||
|
myclass = 'AdHocCLI'
|
||||||
|
else:
|
||||||
|
raise AnsibleError("Unknown Ansible alias: %s" % me)
|
||||||
|
|
||||||
|
try:
|
||||||
|
mycli = getattr(__import__("ansible.cli.%s" % sub, fromlist=[myclass]), myclass)
|
||||||
|
except ImportError as e:
|
||||||
|
# ImportError members have changed in py3
|
||||||
|
if 'msg' in dir(e):
|
||||||
|
msg = e.msg
|
||||||
|
else:
|
||||||
|
msg = e.message
|
||||||
|
if msg.endswith(' %s' % sub):
|
||||||
|
raise AnsibleError("Ansible sub-program not implemented: %s" % me)
|
||||||
|
raise
|
||||||
|
|
||||||
|
mycli.display = display
|
||||||
|
try:
|
||||||
|
args = [to_text(a, errors='surrogate_or_strict') for a in sys.argv]
|
||||||
|
except UnicodeError:
|
||||||
|
display.error('Command line args are not in utf-8, unable to continue. Ansible currently only understands utf-8')
|
||||||
|
display.display(u"The full traceback was:\n\n%s" % to_text(traceback.format_exc()))
|
||||||
|
exit_code = 6
|
||||||
|
else:
|
||||||
|
cli = mycli(args)
|
||||||
|
cli.parse()
|
||||||
|
cli.display = display
|
||||||
|
# import pdb; pdb.set_trace()
|
||||||
|
exit_code = cli.run()
|
||||||
|
|
||||||
|
except AnsibleOptionsError as e:
|
||||||
|
cli.parser.print_help()
|
||||||
|
display.error(to_text(e), wrap_text=False)
|
||||||
|
exit_code = 5
|
||||||
|
except AnsibleParserError as e:
|
||||||
|
display.error(to_text(e), wrap_text=False)
|
||||||
|
exit_code = 4
|
||||||
|
# TQM takes care of these, but leaving comment to reserve the exit codes
|
||||||
|
# except AnsibleHostUnreachable as e:
|
||||||
|
# display.error(str(e))
|
||||||
|
# exit_code = 3
|
||||||
|
# except AnsibleHostFailed as e:
|
||||||
|
# display.error(str(e))
|
||||||
|
# exit_code = 2
|
||||||
|
except AnsibleError as e:
|
||||||
|
display.error(to_text(e), wrap_text=False)
|
||||||
|
exit_code = 1
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
display.error("User interrupted execution")
|
||||||
|
exit_code = 99
|
||||||
|
except Exception as e:
|
||||||
|
if C.DEFAULT_DEBUG:
|
||||||
|
# Show raw stacktraces in debug mode, It also allow pdb to
|
||||||
|
# enter post mortem mode.
|
||||||
|
raise
|
||||||
|
have_cli_options = bool(context.CLIARGS)
|
||||||
|
display.error("Unexpected Exception, this is probably a bug: %s" % to_text(e), wrap_text=False)
|
||||||
|
if not have_cli_options or have_cli_options and context.CLIARGS['verbosity'] > 2:
|
||||||
|
log_only = False
|
||||||
|
if hasattr(e, 'orig_exc'):
|
||||||
|
display.vvv('\nexception type: %s' % to_text(type(e.orig_exc)))
|
||||||
|
why = to_text(e.orig_exc)
|
||||||
|
if to_text(e) != why:
|
||||||
|
display.vvv('\noriginal msg: %s' % why)
|
||||||
|
else:
|
||||||
|
display.display("to see the full traceback, use -vvv")
|
||||||
|
log_only = True
|
||||||
|
display.display(u"the full traceback was:\n\n%s" % to_text(traceback.format_exc()), log_only=log_only)
|
||||||
|
exit_code = 250
|
||||||
|
finally:
|
||||||
|
# Remove ansible tmpdir
|
||||||
|
shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
|
||||||
|
|
||||||
|
sys.exit(exit_code)
|
||||||
17
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_keepassxc-cli.bash
Executable file
17
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_keepassxc-cli.bash
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
DEBUG=1
|
||||||
|
. /usr/local/bin/usr_local_tput.bash
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
COMMAND=$1
|
||||||
|
shift
|
||||||
|
RARGS="--pw-stdin"
|
||||||
|
tail=`echo $@ | sed -e 's/.* \([^ ]*\) \([^ ]*\)/\1 \2/'`
|
||||||
|
exec $PREFIX/bin/gridfire -H "keepassxc-cli.bash $tail" -- \
|
||||||
|
keepassxc-cli.bash $COMMAND $RARGS "$@"
|
||||||
20
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_keepassxc.bash
Executable file
20
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_keepassxc.bash
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
DEBUG=1
|
||||||
|
. /usr/local/bin/usr_local_tput.bash
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
|
||||||
|
tail=`echo $@ | sed -e 's/.* \([^ ]*\) \([^ ]*\)/\1 \2/'`
|
||||||
|
LARGS="--bg"
|
||||||
|
LARGS=""
|
||||||
|
RARGS="--pw-stdin"
|
||||||
|
INFO $PREFIX/bin/gridfire -H "keepassxc $tail" $LARGS -- \
|
||||||
|
keepassxc $RARGS "$@"
|
||||||
|
exec $PREFIX/bin/gridfire -H "keepassxc $tail" $LARGS -- \
|
||||||
|
keepassxc $RARGS "$@"
|
||||||
58
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_kpsh.bash
Executable file
58
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_kpsh.bash
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
. /usr/local/bin/usr_local_tput.bash || exit 2
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ] ; then
|
||||||
|
echo USAGE: $0 [options]
|
||||||
|
cat << EOF
|
||||||
|
USAGE:
|
||||||
|
--password PASSWORD Database password.
|
||||||
|
--password-command PW_CMD
|
||||||
|
Password will be obtained from the output of this
|
||||||
|
command.
|
||||||
|
--keyfile KEYFILE Key file for unlocking database.
|
||||||
|
--pinentry PINENTRY Command used to run pinentry.
|
||||||
|
-c COMMAND, --command COMMAND
|
||||||
|
Command to execute. If command arguments contain
|
||||||
|
spaces, they must be enclosed in double quotes. With
|
||||||
|
this switch, kpsh will be started in non-interactive
|
||||||
|
mode. A list of available commands can be found by
|
||||||
|
running 'kpsh -c help':
|
||||||
|
{open,unlock,lock,db,ls,show,add,edit,delete,move,autotype,exit,echo,sleep,help}
|
||||||
|
open Change currently opened database.
|
||||||
|
unlock Unlock currently opened database.
|
||||||
|
lock Lock a database.
|
||||||
|
db Query opened database info.
|
||||||
|
ls List contents of database.
|
||||||
|
show Show contents of entry.
|
||||||
|
add Add a new entry if it doesn't exist yet.
|
||||||
|
edit Edit existing entry
|
||||||
|
delete Delete entry from database
|
||||||
|
move Move entry to the new path.
|
||||||
|
autotype Auto-type sequence of entry fields.
|
||||||
|
exit Exit shell.
|
||||||
|
echo Display a message.
|
||||||
|
sleep Sleep for a given number of seconds.
|
||||||
|
|
||||||
|
--prompt PROMPT Text used by shell for prompt.
|
||||||
|
-d, --daemon Start as a daemon listening on a socket given by
|
||||||
|
--socket-path
|
||||||
|
-s SOCKET_PATH, --socket-path SOCKET_PATH
|
||||||
|
Path to the socket which will be created in daemon
|
||||||
|
mode (default: /tmp/kpsh-$UID.sock).
|
||||||
|
|
||||||
|
USAGE: $0 -- kpsh-args
|
||||||
|
`basename $0` arguments go before the -- kpsh args go after
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# FixMe: nonewline
|
||||||
|
exec $PREFIX/bin/gridfire -H "kpsh password on stdin" --stdin -- \
|
||||||
|
kpsh "$@"
|
||||||
187
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_openssl.bash
Executable file
187
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_openssl.bash
Executable file
@@ -0,0 +1,187 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
COMMANDS=(
|
||||||
|
asn1parse ca ciphers cms crl crl2pkcs7 dgst dhparam dsa dsaparam ec
|
||||||
|
ecparam enc engine errstr gendsa genpkey genrsa help list nseq ocsp
|
||||||
|
passwd pkcs12 pkcs7 pkcs8 pkey pkeyparam pkeyutl prime rand rehash req
|
||||||
|
rsa rsautl s_client s_server s_time sess_id smime speed spkac srp
|
||||||
|
storeutl ts verify version x509 dgst enc
|
||||||
|
)
|
||||||
|
# for elt in ${COMMANDS[*]}; do echo INFO: openssl $elt;openssl $elt -help;done
|
||||||
|
|
||||||
|
usage () {
|
||||||
|
echo "USAGE: recognized commands are - ${PASSIN_COMMANDS[*]} ${PASSOUT_COMMANDS[*]} ${PASS_COMMANDS[*]}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ] || [ "$1" = '--help' ] || [ "$1" = '-h' ] ; then
|
||||||
|
echo USAGE: $0 command [options]
|
||||||
|
cat << EOF
|
||||||
|
Recognized commands:
|
||||||
|
|
||||||
|
-passin commands: -passin pass:stdin
|
||||||
|
ca \
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
cms
|
||||||
|
-pwri_password val (No additional info)
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
dgst
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
pkeyutl
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
rsautl
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
smime
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
spkac
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
storeutl
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
ts
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
x509
|
||||||
|
-passin val Private key password/pass-phrase source
|
||||||
|
dgst
|
||||||
|
-passin val Input file pass phrase source
|
||||||
|
|
||||||
|
-passout commands: -passout pass:stdin
|
||||||
|
gendsa
|
||||||
|
-passout val Output file pass phrase source
|
||||||
|
genrsa
|
||||||
|
-passout val Output file pass phrase source
|
||||||
|
|
||||||
|
-pass commands: -pass pass:stdin
|
||||||
|
enc
|
||||||
|
-pass val Passphrase source
|
||||||
|
genpkey
|
||||||
|
-pass val Output file pass phrase source
|
||||||
|
|
||||||
|
Options:
|
||||||
|
pass:stdin
|
||||||
|
pass:fd0
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
COMMAND=$1
|
||||||
|
|
||||||
|
# FixMe: make sure command is first
|
||||||
|
if [ $COMMAND = '-help' ] || [ $COMMAND = '--help' ] ; then
|
||||||
|
usage
|
||||||
|
echo "USAGE: all openssl commands are - ${COMMANDS[*]}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
if [ "${COMMAND:0:1}" = "-" ] ; then
|
||||||
|
echo "USAGE: command args - command must precede args"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $COMMAND in \
|
||||||
|
# PASSIN_COMMANDS=(
|
||||||
|
ca \
|
||||||
|
| cms \
|
||||||
|
| dgst \
|
||||||
|
| pkeyutl \
|
||||||
|
| rsautl \
|
||||||
|
| smime \
|
||||||
|
| spkac \
|
||||||
|
| storeutl \
|
||||||
|
| ts \
|
||||||
|
| x509 \
|
||||||
|
| dgst \
|
||||||
|
) # FixMe: check if already there
|
||||||
|
LARGS="-passin pass:stdin"
|
||||||
|
$PREFIX/bin/gridfire -H "openssl $LARGS" -- openssl $LARGS "$@" || exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
# PASSOUT_COMMANDS=(
|
||||||
|
gendsa \
|
||||||
|
| genrsa \
|
||||||
|
) # FixMe: check if already there
|
||||||
|
LARGS="-passout pass:stdin"
|
||||||
|
$PREFIX/bin/gridfire -H "openssl $LARGS" -- openssl $LARGS "$@" || exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
# PASS_COMMANDS=( \
|
||||||
|
enc \
|
||||||
|
| genpkey \
|
||||||
|
) # FixMe: check if already there
|
||||||
|
LARGS="-pass pass:stdin"
|
||||||
|
$PREFIX/bin/gridfire -H "openssl $LARGS" -- openssl $LARGS "$@" || exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
# PASSNOV_COMMANDS=( \
|
||||||
|
passwd \
|
||||||
|
| '-in infile Read passwords from file' \
|
||||||
|
| '-noverify Never verify when reading password from terminal' \
|
||||||
|
| '-stdin Read passwords from stdin' \
|
||||||
|
) # FixMe: check if already there
|
||||||
|
#? conflicts with -in?
|
||||||
|
LARGS=" -noverify -stdin"
|
||||||
|
bash $PREFIX/bin/gridfire -H "openssl $LARGS" -- openssl $LARGS "$@" || exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
# PASSINOUT_COMMANDS=( \
|
||||||
|
pkcs8 \
|
||||||
|
| '-passin val Input file pass phrase source' \
|
||||||
|
| '-passout val Output file pass phrase source' \
|
||||||
|
| pkey \
|
||||||
|
| '-passin val Input file pass phrase source' \
|
||||||
|
| '-passout val Output file pass phrase source' \
|
||||||
|
| rsa \
|
||||||
|
| '-passout val Output file pass phrase source' \
|
||||||
|
| '-passin val Input file pass phrase source' \
|
||||||
|
| srp \
|
||||||
|
| '-passin val Input file pass phrase source' \
|
||||||
|
| '-passout val Output file pass phrase source' \
|
||||||
|
) # FixMe: check if already there
|
||||||
|
# FixMe: fd:
|
||||||
|
LARGS="--passin"
|
||||||
|
passin=`sh $PREFIX/bin/gridfire -H "openssl $LARGS" `
|
||||||
|
LARGS="-passin pass:$passin -passout pass:stdin"
|
||||||
|
bash $PREFIX/bin/gridfire -H "openssl -passout pass:stdin" -- openssl $LARGS "$@" || exit $?
|
||||||
|
|
||||||
|
esac
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
# PASSDPASS_COMMANDS=( \
|
||||||
|
s_server \
|
||||||
|
# -pass val Private key file pass phrase source \
|
||||||
|
# -dpass val Second private key file pass phrase source \
|
||||||
|
) # FixMe: check if already there
|
||||||
|
# FixMe: fd:
|
||||||
|
pass=`sh $PREFIX/bin/gridfire.bash`
|
||||||
|
LARGS="-pass pass:$pass -dpass pass:stdin"
|
||||||
|
bash $PREFIX/bin/gridfire -- openssl $LARGS "$@" || exit $?
|
||||||
|
|
||||||
|
;; # PASSKPASS_COMMANDS=( \
|
||||||
|
enc \
|
||||||
|
# -pass val Passphrase source \
|
||||||
|
# -kfile infile Read passphrase from file \
|
||||||
|
) # FixMe: check if already there
|
||||||
|
# FixMe: fd:
|
||||||
|
#?pass=`sh $PREFIX/bin/gridfire.bash`
|
||||||
|
#?LARGS="-pass pass:$pass -dpass pass:stdin"
|
||||||
|
LARGS="-pass pass:stdin"
|
||||||
|
$PREFIX/bin/gridfire -H "openssl $LARGS" -- openssl $LARGS "$@" || exit $?
|
||||||
|
|
||||||
|
;; # PASSINOUTWORD_COMMANDS=( \ \
|
||||||
|
pkcs12 \
|
||||||
|
# -twopass Separate MAC, encryption passwords \
|
||||||
|
# -passin val Input file pass phrase source \
|
||||||
|
# -passout val Output file pass phrase source \
|
||||||
|
# -password val Set import/export password source \
|
||||||
|
) # FixMe: check if already there
|
||||||
|
|
||||||
|
|
||||||
|
# FixMe: pass: prefix
|
||||||
|
$PREFIX/bin/gridfire -H "-passin pass:" --single "passin" -- sh $PREFIX/bin/gridfire -H "-passout stdin" -- openssl "$@" || exit $?
|
||||||
|
esac
|
||||||
27
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_secret-tool.bash
Executable file
27
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_secret-tool.bash
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
. /usr/local/bin/usr_local_tput.bash || exit 2
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ] ; then
|
||||||
|
echo USAGE: $0 [options]
|
||||||
|
cat << EOF
|
||||||
|
usage: secret-tool store --label='label' attribute value ...
|
||||||
|
secret-tool lookup attribute value ...
|
||||||
|
secret-tool clear attribute value ...
|
||||||
|
secret-tool search [--all] [--unlock] attribute value ...
|
||||||
|
|
||||||
|
USAGE: $0 -- secret-tool-args
|
||||||
|
`basename $0` arguments go before the -- secret-tool args go after
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# FixMe: nonewline
|
||||||
|
exec $PREFIX/bin/gridfire -H "secret-tool password on stdin" --stdin -- \
|
||||||
|
secret-tool "$@"
|
||||||
11
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_staticgpg.bash
Executable file
11
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_staticgpg.bash
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
#? --pinentry-mode loopback
|
||||||
|
|
||||||
|
exec $PREFIX/bin/gridfire -H "staticgpg --passphrase-fd 0" -- \
|
||||||
|
staticgpg --passphrase-fd 0 "$@"
|
||||||
104
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_tomb.bash
Executable file
104
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_tomb.bash
Executable file
@@ -0,0 +1,104 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
PYVER=3
|
||||||
|
EXE=/var/local/bin/tomb.bash
|
||||||
|
|
||||||
|
. /usr/local/bin/usr_local_tput.bash || exit 2
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
# python3 -c "import keyring.util.platform_; print(keyring.util.platform_.config_root())"
|
||||||
|
# ~/.local/share/python_keyring
|
||||||
|
|
||||||
|
# what goes on stdin - the passwd to the keyfile with the keyfile as an arg?
|
||||||
|
# or open the keyfile?
|
||||||
|
# passwd from gridfire or from keepass
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Syntax: tomb [options] command [arguments]"
|
||||||
|
echo
|
||||||
|
echo " // Creation:"
|
||||||
|
echo " dig create a new empty TOMB file of size -s in MiB"
|
||||||
|
echo " forge create a new KEY file and set its password"
|
||||||
|
echo " lock installs a lock on a TOMB to use it with KEY"
|
||||||
|
echo
|
||||||
|
echo " // Operations on tombs:"
|
||||||
|
echo " open open an existing TOMB (-k KEY file or - for stdin)"
|
||||||
|
echo " index update the search indexes of tombs"
|
||||||
|
echo " search looks for filenames matching text patterns"
|
||||||
|
echo " list list of open TOMBs and information on them"
|
||||||
|
echo " ps list of running processes inside open TOMBs"
|
||||||
|
echo " close close a specific TOMB (or 'all')"
|
||||||
|
echo " slam slam a TOMB killing all programs using it"
|
||||||
|
[[ $RESIZER == 1 ]] && {
|
||||||
|
echo " resize resize a TOMB to a new size -s (can only grow)"
|
||||||
|
}
|
||||||
|
echo
|
||||||
|
echo " // Operations on keys:"
|
||||||
|
echo " passwd change the password of a KEY (needs old pass)"
|
||||||
|
echo " setkey change the KEY locking a TOMB (needs old key and pass)"
|
||||||
|
echo
|
||||||
|
[[ $QRENCODE == 1 ]] && {
|
||||||
|
echo " // Backup on paper:"
|
||||||
|
echo " engrave makes a QR code of a KEY to be saved on paper"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
[[ $STEGHIDE == 1 || $CLOAKIFY == 1 || $DECLOAKIFY == 1 ]] && {
|
||||||
|
echo " // Steganography:"
|
||||||
|
[[ $STEGHIDE == 1 ]] && {
|
||||||
|
echo " bury hide a KEY inside a JPEG image (for use with -k)"
|
||||||
|
echo " exhume extract a KEY from a JPEG image (prints to stdout)"
|
||||||
|
}
|
||||||
|
[[ $CLOAKIFY == 1 ]] && {
|
||||||
|
echo " cloak transform a KEY into TEXT using CIPHER (for use with -k)"
|
||||||
|
}
|
||||||
|
[[ $DECLOAKIFY == 1 ]] && {
|
||||||
|
echo " uncloak extract a KEY from a TEXT using CIPHER (prints to stdout)"
|
||||||
|
}
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
echo "Options:"
|
||||||
|
echo
|
||||||
|
echo " -s size of the tomb file when creating/resizing one (in MiB)"
|
||||||
|
echo " -k path to the key to be used ('-k -' to read from stdin)"
|
||||||
|
echo " -n don't launch the execution hooks found in tomb"
|
||||||
|
echo " -p preserve the ownership of all files in tomb"
|
||||||
|
echo " -o options passed to commands: open, lock, forge (see man)"
|
||||||
|
echo " -f force operation (i.e. even if swap is active)"
|
||||||
|
echo " -g use a GnuPG key to encrypt a tomb key"
|
||||||
|
echo " -r provide GnuPG recipients (separated by comma)"
|
||||||
|
echo " -R provide GnuPG hidden recipients (separated by comma)"
|
||||||
|
|
||||||
|
[[ $SPHINX == 1 ]] && {
|
||||||
|
echo " --sphx-user user associated with the key (for use with pitchforkedsphinx)"
|
||||||
|
echo " --sphx-host host associated with the key (for use with pitchforkedsphinx)"
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ $KDF == 1 ]] && {
|
||||||
|
echo " --kdf forge keys armored against dictionary attacks"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo " -q run quietly without printing informations"
|
||||||
|
echo " -D print debugging information at runtime"
|
||||||
|
}
|
||||||
|
|
||||||
|
# FixMe: make sure command is first
|
||||||
|
if [ "$#" -eq 0 ] || [ "$1" = '--help' -o "$1" = 'help' ] ; then
|
||||||
|
# usage
|
||||||
|
# exit 0
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
LARGS="-H \"tomb $tail\""
|
||||||
|
tail=`echo $@ | sed -e 's/.* \([^ ]*\) \([^ ]*\)/\1 \2/'`
|
||||||
|
if [[ "$*" =~ "-- " ]];then
|
||||||
|
RARGS=`echo $*|sed -e "s/-- /-- $EXE/"`
|
||||||
|
exec $PREFIX/bin/gridfire $LARGS $RARGS
|
||||||
|
else
|
||||||
|
exec $PREFIX/bin/gridfire $LARGS -- $EXE "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
32
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_truecrypt-console.bash
Executable file
32
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_truecrypt-console.bash
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
DEBUG=1
|
||||||
|
. /usr/local/bin/usr_local_tput.bash
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
usage () {
|
||||||
|
echo USAGE: $0 [options]
|
||||||
|
cat << EOF
|
||||||
|
USAGE: $0 [--arg password ] -- truecrypt-args
|
||||||
|
`basename $0` arguments go before the -- truecrypt args go after
|
||||||
|
MINIMUM of 2 args for truecrypt
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
if [ "$#" -eq 0 ] ; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
if [ "$#" -lt 2 ] ; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
tail=`sed -e 's/.* \([^ ]*\) \([^ ]*\)/\1 \2/' <<< $@`
|
||||||
|
RARGS="--non-interactive"
|
||||||
|
exec $PREFIX/bin/gridfire --double password -E -B -H "truecrypt-console $tail" -- \
|
||||||
|
$PREFIX/bin/truecrypt-console.bash $RARGS "$@"
|
||||||
|
|
||||||
|
# FixMe: --new-password=<str> New password
|
||||||
25
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_truecrypt.bash
Executable file
25
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_truecrypt.bash
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
. /usr/local/bin/usr_local_tput.bash || exit 2
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ] ; then
|
||||||
|
echo USAGE: $0 [options]
|
||||||
|
cat << EOF
|
||||||
|
USAGE: $0 [--arg password ] -- truecrypt-args
|
||||||
|
`basename $0` arguments go before the -- truecrypt args go after
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
tail=`sed -e 's/.* \([^ ]*\) \([^ ]*\)/\1 \2/' <<< $@`
|
||||||
|
exec $PREFIX/bin/gridfire -E --double password -H "truecrypt $tail" -- \
|
||||||
|
$PREFIX/bin/truecrypt.bash "$@"
|
||||||
|
|
||||||
|
# FixMe: --new-password=<str> New password
|
||||||
36
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_veracrypt-console.bash
Executable file
36
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_veracrypt-console.bash
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
DEBUG=1
|
||||||
|
. /usr/local/bin/usr_local_tput.bash
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
usage () {
|
||||||
|
echo USAGE: $0 [options]
|
||||||
|
cat << EOF
|
||||||
|
USAGE: $0 [--arg password ] -- veracrypt-args
|
||||||
|
`basename $0` arguments go before the -- veracrypt args go after
|
||||||
|
MINIMUM of 2 args for veracrypt
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
if [ "$#" -eq 0 ] ; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
if [ "$#" -lt 2 ] ; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
RARGS=""
|
||||||
|
[[ "$*" =~ "--stdin" ]] || LARGS="--stdin $LARGS"
|
||||||
|
#no [[ "$*" =~ "--create" ]] && LARGS="--repeat $LARGS"
|
||||||
|
#no [[ "$*" =~ "--new-password=" ]] && LARGS="--repeat $LARGS"
|
||||||
|
|
||||||
|
tail=`echo $@ | sed -e 's/.* \([^ ]*\) \([^ ]*\)/\1 \2/'`
|
||||||
|
$PREFIX/bin/gridfire $LARGS -H "veracrypt-console $tail" -- \
|
||||||
|
$PREFIX/bin/veracrypt-console.bash $RARGS "$@"
|
||||||
|
|
||||||
|
# FixMe: --new-password=<str> New password
|
||||||
17
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_veracrypt.bash
Executable file
17
roles/toxcore/overlay/Linux/usr/local/bin/gridfire_veracrypt.bash
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
. /usr/local/bin/usr_local_tput.bash
|
||||||
|
. /usr/local/bin/gridfire.rc
|
||||||
|
|
||||||
|
tail=`echo $@ | sed -e 's/.* \([^ ]*\) \([^ ]*\)/\1 \2/'`
|
||||||
|
RARGS=""
|
||||||
|
[[ "$*" =~ "--stdin" ]] || RARGS="--stdin $RARGS"
|
||||||
|
exec $PREFIX/bin/gridfire -H "veracrypt $tail" -- \
|
||||||
|
$PREFIX/bin/veracrypt.bash $RARGS "$@"
|
||||||
|
|
||||||
|
# FixMe: --new-password=<str> New password
|
||||||
6
roles/toxcore/overlay/Linux/usr/local/bin/pex2.bash
Executable file
6
roles/toxcore/overlay/Linux/usr/local/bin/pex2.bash
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
# --not-zip-safe --no-index linux_x86_64-cp-27-cp27mu
|
||||||
|
ROLE=toxcore
|
||||||
|
exec /usr/local/bin/python2.sh -m pex --python $PREFIX/bin/python2.sh --python-shebang $PREFIX/bin/python2.sh "$@"
|
||||||
|
|
||||||
7
roles/toxcore/overlay/Linux/usr/local/bin/pex3.bash
Executable file
7
roles/toxcore/overlay/Linux/usr/local/bin/pex3.bash
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
ROLE=toxcore
|
||||||
|
# -f /usr/lib/python3/dist-packages/
|
||||||
|
exec /usr/local/bin/pex \
|
||||||
|
--python /usr/local/bin/python3.sh \
|
||||||
|
--python-shebang /usr/local/bin/python3.sh "$@"
|
||||||
15
roles/toxcore/overlay/Linux/usr/local/bin/pinentry_gridfire.bash
Executable file
15
roles/toxcore/overlay/Linux/usr/local/bin/pinentry_gridfire.bash
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
[ -f $PREFIX/bin/gridfire.rc ] && . $PREFIX/bin/gridfire.rc
|
||||||
|
|
||||||
|
[ -e /run ] || exit 1
|
||||||
|
|
||||||
|
cd $PREFIX/src/gridfire || exit 3
|
||||||
|
|
||||||
|
export PYTHONPATH=$PREFIX/src/gridfire/pyassuan:$PREFIX/src/gridfire:$PWD
|
||||||
|
|
||||||
|
exec $PREFIX/bin/python3.sh bin/pinentry_gridfire.py "$@"
|
||||||
96
roles/toxcore/overlay/Linux/usr/local/bin/sdwdate.bash
Executable file
96
roles/toxcore/overlay/Linux/usr/local/bin/sdwdate.bash
Executable file
@@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
|
||||||
|
# 19 Nov 00:48:20 ntpdate[24018]: step time server 132.163.97.3 offset +4125.279643 sec
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
[ -f /usr/local/etc/testforge/testforge.bash ] && \
|
||||||
|
. /usr/local/etc/testforge/testforge.bash || exit 1
|
||||||
|
|
||||||
|
|
||||||
|
# python3.6 problems on gentoo with gevent not installing
|
||||||
|
# python3.7 -c 'import gevent'
|
||||||
|
|
||||||
|
PYVER=3
|
||||||
|
PYTHON_MINOR=3.11
|
||||||
|
|
||||||
|
PYTHON_EXE_MSYS=python$PYTHON_MINOR.sh
|
||||||
|
PYTHON_EXE=$PYTHON_EXE_MSYS
|
||||||
|
|
||||||
|
PKG=sdwdate
|
||||||
|
URL=github.com/Whonix/sdwdate
|
||||||
|
DIR=$PKG
|
||||||
|
|
||||||
|
cd $PREFIX/src || exit 2
|
||||||
|
WD=$PWD
|
||||||
|
|
||||||
|
cd $DIR || exit 3
|
||||||
|
|
||||||
|
site_packages=$PREFIX/$LIB/python$PYTHON_MINOR/site-packages
|
||||||
|
|
||||||
|
if ! [ -d $site_packages/$DIR/ ] ; then
|
||||||
|
rsync -vax usr/lib/python3/dist-packages/$DIR/ $site_packages/$DIR/
|
||||||
|
sed -e 's@/usr/lib@/usr/local/lib@' -i $site_packages/$DIR/*py
|
||||||
|
fi
|
||||||
|
[ -d $site_packages/$DIR/ ] || exit 4
|
||||||
|
|
||||||
|
[ -d $PREFIX/etc/sdwdate.d ] || mkdir $PREFIX/etc/sdwdate.d
|
||||||
|
[ -f $PREFIX/etc/sdwdate.d/30_default.conf ] || \
|
||||||
|
cp -p etc/sdwdate.d/30_default.conf $PREFIX/etc/sdwdate.d/30_default.conf
|
||||||
|
|
||||||
|
if [ ! -f $PREFIX/bin/${PKG}_.py ] ; then
|
||||||
|
cp -p usr/bin/${PKG} $PREFIX/bin/${PKG}_.py || exit 5
|
||||||
|
patch -b -z .dst $PREFIX/bin/${PKG}_.py < $PREFIX/src/${PKG}_.py,diff
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ -d /usr/local/lib/helper-scripts ] ; then
|
||||||
|
rsync -vax ../helper-scripts/ $PREFIX/lib/helper-scripts/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# share/sdwdate/onion_tester
|
||||||
|
if ! [ -d /usr/local/share/sdwdate ] ; then
|
||||||
|
rsync -vax usr/share/$DIR/ $PREFIX/share/$DIR/
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ -d /usr/local/lib/sdwdate ] ; then
|
||||||
|
rsync -vax usr/lib/$DIR/ $PREFIX/lib/$DIR/
|
||||||
|
|
||||||
|
## Compatibility with anon-ws-disable-stacked-tor.
|
||||||
|
# addgroup debian-tor 2>/dev/null || true
|
||||||
|
|
||||||
|
# adduser --home /run/sdwdate --no-create-home --quiet --system --group sdwdate || true
|
||||||
|
|
||||||
|
## Add sdwdate to group debian-tor so it can read
|
||||||
|
## /run/tor/control.authcookie which is required to check if Tor has
|
||||||
|
## already successfully established a circuit before fetching time.
|
||||||
|
# addgroup sdwdate debian-tor
|
||||||
|
cd /usr/local/lib/$DIR
|
||||||
|
[ -x sclockadj ] || \
|
||||||
|
gcc sclockadj.c -o sclockadj -ldl -D_GNU_SOURCE -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wl,-z,relro -Wl,-z,now || exit 7
|
||||||
|
cd $WD
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q /usr/lib /usr/local/lib/sdwdate/* ; then
|
||||||
|
sed -e 's@/usr/lib@/usr/local/lib@' -i /usr/local/lib/sdwdate/*
|
||||||
|
fi
|
||||||
|
cd $WD
|
||||||
|
|
||||||
|
if [ ! -e $PREFIX/bin/${ROLE}_${PKG}.bash ] ; then
|
||||||
|
cat > $PREFIX/bin/${ROLE}_${PKG}.bash << EOF
|
||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
if [ -x /usr/local/bin/proxy_ping_test.bash ] ; then
|
||||||
|
sh /usr/local/bin/proxy_ping_test.bash wifi || exit 1
|
||||||
|
sh /usr/local/bin/proxy_ping_test.bash 30 || exit 2
|
||||||
|
fi
|
||||||
|
export PYTHONPATH=$site_packages
|
||||||
|
exec $PYTHON_EXE_MSYS $PREFIX/bin/${PKG}_.py "\$@"
|
||||||
|
EOF
|
||||||
|
chmod 755 $PREFIX/bin/${ROLE}_${PKG}.bash
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
7
roles/toxcore/overlay/Linux/usr/local/bin/testforge_alsa_info.bash
Executable file
7
roles/toxcore/overlay/Linux/usr/local/bin/testforge_alsa_info.bash
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
ROLE=testforge
|
||||||
|
|
||||||
|
export http_proxy=localhost:9999
|
||||||
|
export https_proxy=localhost:9999
|
||||||
|
exec alsa-info.sh --stdout --no-load $*
|
||||||
150
roles/toxcore/overlay/Linux/usr/local/bin/testforge_backup_btrfs.bash
Executable file
150
roles/toxcore/overlay/Linux/usr/local/bin/testforge_backup_btrfs.bash
Executable file
@@ -0,0 +1,150 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
# https://lukas.dzunko.sk/index.php/Linux:_incremental_backup_using_rsync_on_btrfs_with_snapshots
|
||||||
|
|
||||||
|
PREFIX=/var/local
|
||||||
|
ROLE=testforge
|
||||||
|
|
||||||
|
MONIKER=4TA
|
||||||
|
DEST=/mnt/backup
|
||||||
|
snapshot=""
|
||||||
|
opt=""
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 [OPTIONS] dirs"
|
||||||
|
echo
|
||||||
|
echo " -s | --snapshot - snapshot"
|
||||||
|
echo " -c | --checksum - checksum"
|
||||||
|
echo " -p | --dedupe - dedupe"
|
||||||
|
echo " -d | --dest - destination (default - $DEST )"
|
||||||
|
echo
|
||||||
|
echo " -V | --version - print version of this script"
|
||||||
|
echo " -h | --help - print this help"
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$#" -eq 0 ] && usage && exit 1
|
||||||
|
|
||||||
|
SHORTOPTS="hVcspm:d:"
|
||||||
|
LONGOPTS="help,version,checksum,snapshot,dedupe,moniker:,dest:"
|
||||||
|
dedupe=
|
||||||
|
DIRS=
|
||||||
|
|
||||||
|
# . /usr/local/bin/usr_local_base.bash
|
||||||
|
. /usr/local/bin/usr_local_tput.bash || exit 2
|
||||||
|
error () { retval=$1 ; shift; echo "ERROR: $prog" $* ; exit $retval ; }
|
||||||
|
|
||||||
|
ARGS=$(getopt --options $SHORTOPTS --longoptions $LONGOPTS -- "$@")
|
||||||
|
[ $? != 0 ] && error 2 "Aborting."
|
||||||
|
|
||||||
|
eval set -- "$ARGS"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
# echo $*
|
||||||
|
case "$1" in
|
||||||
|
-p|--dedupe)
|
||||||
|
dedupe="true"
|
||||||
|
;;
|
||||||
|
-s|--snapshot)
|
||||||
|
snapshot="true"
|
||||||
|
;;
|
||||||
|
-c|--checksum)
|
||||||
|
opt="--checksum"
|
||||||
|
;;
|
||||||
|
-m|--moniker)
|
||||||
|
shift
|
||||||
|
MONIKER="$1"
|
||||||
|
;;
|
||||||
|
-d|--dest)
|
||||||
|
shift
|
||||||
|
DEST="$1"
|
||||||
|
;;
|
||||||
|
-v|--verbosity)
|
||||||
|
shift
|
||||||
|
verbosity="$1"
|
||||||
|
;;
|
||||||
|
-V|--version)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
'--')
|
||||||
|
shift
|
||||||
|
DIRS="$@"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error 3 "unrecognized arguments $*"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
[ -z "$DIRS" ] && error 4 "no directories given"
|
||||||
|
|
||||||
|
df | grep ${DEST} || mount -v ${DEST} || exit 3
|
||||||
|
|
||||||
|
echo "INFO: Copying data ..."
|
||||||
|
# output of following commands is saved along with backup
|
||||||
|
( echo; echo "lsusb:" ; lsusb;
|
||||||
|
echo; echo "lspci:"; lspci;
|
||||||
|
echo; echo "lshw:" ; lshw -short;
|
||||||
|
echo; echo "date:" ; date;
|
||||||
|
echo; echo "# EOF" ;
|
||||||
|
) > /.lastbackup_$MONIKER
|
||||||
|
echo
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
[ -d /var/local/etc/testforge/backup ] || mkdir /var/local/etc/testforge/backup
|
||||||
|
file=/var/local/etc/testforge/backup/$MONIKER.exclude
|
||||||
|
if ! [ -f $file ] ; then
|
||||||
|
cat > $file << EOF
|
||||||
|
/cdrom
|
||||||
|
/dev
|
||||||
|
/media
|
||||||
|
/mnt
|
||||||
|
/proc
|
||||||
|
/run
|
||||||
|
/sys
|
||||||
|
/tmp
|
||||||
|
EOF
|
||||||
|
for elt in /root/.cache /home/*/.cache ; do
|
||||||
|
grep -q ^$elt $file || echo $eelt >> $file
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
LARGS="${opt} -vaxHAX --delete --delete-excluded --human-readable --stats --exclude-from=$file"
|
||||||
|
for dir in $DIRS ; do
|
||||||
|
[ -d $dir ] || continue
|
||||||
|
# copy data to backup location
|
||||||
|
dest=$( echo $dir | sed -e 's@/mnt/@@' )
|
||||||
|
rsync $LARGS\
|
||||||
|
${DEST}/${MONIKER}/$dest || { retval=$? ; ERROR backing up $dir ; sync; exit $retval ; }
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Flushing file system buffers ..."
|
||||||
|
time sync
|
||||||
|
btrfs filesystem sync ${DEST}
|
||||||
|
time sync
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [ $dedupe = "true" ] ; then
|
||||||
|
echo "INFO: deduping backup ..."
|
||||||
|
time $PREFIX/bin/testforge_ln_dups.perl ${DEST}/${MONIKER}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $snapshot = "true" ] ; then
|
||||||
|
echo "INFO: Creating snapshot of backup ..."
|
||||||
|
btrfs sub snap -r ${DEST}/${MONIKER} "${DEST}/${MONIKER}_$(LANG=C date +%Y-%m-%d_%s)" || exit 4
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "INFO: Umounting backup filesystem ..."
|
||||||
|
umount -v ${DEST} || exit 6
|
||||||
|
echo
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
ROLE=testforge
|
||||||
|
|
||||||
|
ps axwe | grep -v grep | grep DBUS_SESSION_BUS_ADDRESS | \
|
||||||
|
sed -e 's/[A-Z][A-Z].*DBUS_SESSION_BUS_ADDRESS/DBUS_SESSION_BUS_ADDRESS/' \
|
||||||
|
-e 's/ [A-CE-Z][A-Z].*//'
|
||||||
40
roles/toxcore/overlay/Linux/usr/local/bin/testforge_local_bin.bash
Executable file
40
roles/toxcore/overlay/Linux/usr/local/bin/testforge_local_bin.bash
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
|
||||||
|
prog=$( basename $0 .bash )
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=base
|
||||||
|
# . /usr/local/bin/usr_local_base.bash
|
||||||
|
. /usr/local/bin/usr_local_tput.bash || exit 2
|
||||||
|
|
||||||
|
umask 0022
|
||||||
|
[ "$#" -gt 0 ] && inidir=$1 || inidir=/usr/local/etc/testforge
|
||||||
|
[ -f $inidir ] || mkdir -p $inidir
|
||||||
|
|
||||||
|
if [ -f $inidir ] ; then
|
||||||
|
inifile=$inidir
|
||||||
|
else
|
||||||
|
inifile=$inidir/testforge.ini
|
||||||
|
fi
|
||||||
|
|
||||||
|
# echo -n "DEBUG: $prog "; ls -l $inifile
|
||||||
|
[ -e $inifile ] || { ERROR no file $inifile ; exit 1 ; }
|
||||||
|
[ -s $inifile ] || { ERROR empty file $inifile ; exit 2 ; }
|
||||||
|
|
||||||
|
bashfile=$( echo $inifile | sed -e 's/.ini$/.bash/' )
|
||||||
|
if [ ! -s $bashfile ] || [ $inifile -nt $bashfile ] ; then
|
||||||
|
INFO "$inifile > $bashfile"
|
||||||
|
/usr/local/bin/fact_to_bash.bash < $inifile > $bashfile || exit 3
|
||||||
|
echo 'export PATH=$PATH:/sbin:/usr/local/bin:/var/local/bin' >> $bashfile
|
||||||
|
echo -n "DEBUG: $prog bashfile"; ls -l $bashfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
ymlfile=$( echo $inifile | sed -e 's/.ini$/.yml/' )
|
||||||
|
if [ ! -s $ymlfile ] || [ $inifile -nt $ymlfile ] ; then
|
||||||
|
INFO "$inifile > $ymlfile"
|
||||||
|
/usr/local/bin/fact_to_yaml.bash < $inifile > $ymlfile || exit 4
|
||||||
|
echo -n "DEBUG: $prog ymlfile "; ls -l $ymlfile
|
||||||
|
fi
|
||||||
|
. $bashfile || exit $?
|
||||||
|
|
||||||
|
exec bash /usr/local/bin/base_sheebang_after_pip.bash
|
||||||
33
roles/toxcore/overlay/Linux/usr/local/bin/testforge_perm.bash
Executable file
33
roles/toxcore/overlay/Linux/usr/local/bin/testforge_perm.bash
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
|
||||||
|
# very dangerous
|
||||||
|
[ "$#" -gt 0 ] && ROOT=$1 || ROOT=/
|
||||||
|
[ -n "$ROOT" ] || exit 1
|
||||||
|
[ -d "$ROOT" ] || exit 2
|
||||||
|
|
||||||
|
ROLE=testforge
|
||||||
|
|
||||||
|
cd $ROOT || exit 2
|
||||||
|
GROUP=adm
|
||||||
|
[ -f /usr/local/etc/testforge/testforge.bash ] && . /usr/local/etc/testforge/testforge.bash
|
||||||
|
[ -n "$BOX_ALSO_GROUP" ] && GROUP=$BOX_ALSO_GROUP
|
||||||
|
|
||||||
|
if [ -d ${ROOT}$PREFIX ] ; then
|
||||||
|
# allow
|
||||||
|
chgrp -R $GROUP ${ROOT}$PREFIX/{bin,data,lib64,src,net}
|
||||||
|
chmod -R g+rw,o-w ${ROOT}$PREFIX/{bin,data,lib64,src,net}
|
||||||
|
chmod a+x ${ROOT}$PREFIX/{bin,src,share/bash}/*sh
|
||||||
|
# if [ -d ${ROOT}$PREFIX/src/lynis ] ; then
|
||||||
|
|
||||||
|
chgrp -R $GROUP ${ROOT}$PREFIX/{bin,data,lib64,src,net}
|
||||||
|
# forbid /var
|
||||||
|
chgrp -R root ${ROOT}$PREFIX/{etc,var,share}
|
||||||
|
chmod -R g-w,o-w ${ROOT}$PREFIX/{etc,var,share}
|
||||||
|
fi
|
||||||
|
if [ -d ${ROOT}/usr/local ] ; then
|
||||||
|
# forbid /usr but lib/python* will be created and allowed on install
|
||||||
|
chgrp -R root ${ROOT}/usr/local/
|
||||||
|
chmod -R g-w,o-rw ${ROOT}/usr/local/
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=testforge
|
||||||
|
BASE=/usr/share/ca-certificates/mozilla
|
||||||
|
TO=/usr/local/share/ca-certificates/mozilla
|
||||||
|
VER=20190110
|
||||||
|
DIR=ca-certificates-$VER
|
||||||
|
URL=deb.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_$VER.tar.xz
|
||||||
|
URL_CERTDATA=hg.mozilla.org/releases/mozilla-beta/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt
|
||||||
|
LOG_DIR=/var/local/var/log
|
||||||
|
|
||||||
|
[ -d $LOG_DIR ] || mkdir $LOG_DIR
|
||||||
|
LOG_FILE=$LOG_DIR/ca-certificates_$$.log
|
||||||
|
rm -f $LOG_FILE
|
||||||
|
|
||||||
|
# on Gentoo it may be up to date
|
||||||
|
if false && which equery 2>/dev/null >/dev/null ; then
|
||||||
|
# 20190110.3.43
|
||||||
|
equery f app-misc/ca-certificates|grep /usr/share/doc/ca-certificates-$VER
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -d $TO ] || mkdir -p $TO
|
||||||
|
cd /usr/local/src || exit 1
|
||||||
|
|
||||||
|
if [ ! -d $DIR ] ; then
|
||||||
|
grep -q "^wlan[1-9][0-9]*[ ]00000000" /proc/net/route || { echo INFO: not connected ; exit 0 ; }
|
||||||
|
[ -f /usr/local/net/Http/$URL ] || \
|
||||||
|
wget -xcP /usr/local/net/Http/ http://$URL || exit 1
|
||||||
|
tar xvfJ /usr/local/net/Http/$URL
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $DIR/mozilla || exit 2
|
||||||
|
# will regenerate these if they exist
|
||||||
|
rm -f *crt
|
||||||
|
|
||||||
|
# leave the original OS /usr/share certs renamed to .old
|
||||||
|
ls $BASE/*.crt >/dev/null 2>/dev/null && \
|
||||||
|
for file in $BASE/*.crt ; do
|
||||||
|
[ -f "$file.old" ] && sudo rm "$file.old"
|
||||||
|
sudo mv "$file" "$file.old" || \
|
||||||
|
{ echo ERROR: moving $file $file.old ; exit 3 ; }
|
||||||
|
done
|
||||||
|
|
||||||
|
[ -f blacklist.txt ] || { echo ERROR: missing blacklist.txt ; exit 4 ; }
|
||||||
|
|
||||||
|
if [ ! -f certdata.txt.mozilla ] && grep -q "^wlan[1-9][0-9]*[ ]00000000" /proc/net/route ; then
|
||||||
|
[ -f /usr/local/net/Http/$URL_CERTDATA ] || \
|
||||||
|
wget -xcP /usr/local/net/Http/ http://$URL_CERTDATA
|
||||||
|
fi
|
||||||
|
if [ ! -f certdata.txt.mozilla ] && [ -f /usr/local/net/Http/$URL ] ; then
|
||||||
|
cp -p /usr/local/net/Http/$URL_CERTDATA certdata.txt.mozilla
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f certdata.txt.mozilla -a certdata.txt.mozilla -nt certdata.txt ] ; then
|
||||||
|
[ -f certdata.txt.debian ] || mv certdata.txt certdata.txt.debian
|
||||||
|
cp -p certdata.txt.mozilla certdata.txt
|
||||||
|
fi
|
||||||
|
python2 ./certdata2pem.py >> $LOG_FILE 2>&1 || exit 5
|
||||||
|
|
||||||
|
ls *.crt >/dev/null 2>/dev/null && \
|
||||||
|
for file in *crt ; do
|
||||||
|
sudo mv $file $TO/$file || \
|
||||||
|
{ echo ERROR: moving $file $TO/$file ; exit 6 ; }
|
||||||
|
done
|
||||||
|
|
||||||
|
[ -f $TO/blacklist.txt ] || \
|
||||||
|
sudo cp -p blacklist.txt $TO
|
||||||
|
|
||||||
|
#[ -f /etc/ca-certificates.conf ] && [ ! -f /etc/ca-certificates.conf.old ] && \
|
||||||
|
# sudo mv /etc/ca-certificates.conf /etc/ca-certificates.conf.old
|
||||||
|
# morons: this return rc=0 even when there is an exception - with java7 -
|
||||||
|
# org.debian.security.InvalidKeystorePasswordException: Cannot open Java keystore. Is the password correct?
|
||||||
|
sudo bash /usr/sbin/update-ca-certificates --verbose > $LOG_FILE 2>&1
|
||||||
|
[ $? -ne 0 ] && exit 7$?
|
||||||
|
|
||||||
|
grep Exception: $LOG_FILE && exit 8
|
||||||
|
|
||||||
|
cd /usr/local/share/ca-certificates/mozilla || exit 9
|
||||||
|
for file in *crt; do diff $file /usr/share/ca-certificates/mozilla/$file.old ; done \
|
||||||
|
>> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
cd /usr/share/ca-certificates/mozilla || exit 10
|
||||||
|
echo INFO: /usr/share/ca-certificates/mozilla >> $LOG_FILE 2>&1
|
||||||
|
for file in *.old; do diff $file /usr/local/share/ca-certificates/mozilla$( basename $file .old );done \
|
||||||
|
>> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
|
||||||
|
# alternate
|
||||||
|
# wget -xcP /usr/local/net/Http/ http://ftp.us.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_20190110_all.deb;alien -t -c /usr/local/net/Http/ftp.us.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_20190110_all.deb ; tar xvfz ca-certificates-20190110.tgz -C /usr/local/share/ca-certificates/mozilla
|
||||||
3
roles/toxcore/overlay/Linux/usr/local/bin/testssl.bash
Executable file
3
roles/toxcore/overlay/Linux/usr/local/bin/testssl.bash
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
cd /usr/local/src/testssl.sh || exit 1
|
||||||
|
exec bash testssl.sh "$@"
|
||||||
6
roles/toxcore/overlay/Linux/usr/local/bin/testssl.sh
Executable file
6
roles/toxcore/overlay/Linux/usr/local/bin/testssl.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
cd $PREFIX/src/testssl.sh || exit 1
|
||||||
|
exec bash testssl.sh "$@"
|
||||||
6
roles/toxcore/overlay/Linux/usr/local/bin/tor_bootstrap_check.bash
Executable file
6
roles/toxcore/overlay/Linux/usr/local/bin/tor_bootstrap_check.bash
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
|
||||||
|
ROLE=toxcore
|
||||||
|
exec python3.sh /usr/local/lib/helper-scripts/tor_bootstrap_check.py "$@"
|
||||||
|
|
||||||
9
roles/toxcore/overlay/Linux/usr/local/bin/tox-bootstrapd.bash
Executable file
9
roles/toxcore/overlay/Linux/usr/local/bin/tox-bootstrapd.bash
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
|
||||||
|
ROLE=toxcore
|
||||||
|
|
||||||
|
CONF=/var/local/etc/tox-bootstrapd.conf
|
||||||
|
|
||||||
|
[ -d /var/lib/tox-bootstrapd/ ] || mkdir /var/lib/tox-bootstrapd
|
||||||
|
exec torsocks /var/local/bin/tox-bootstrapd --config $CONF "$@"
|
||||||
51
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_DHTnodes_nmap.bash
Executable file
51
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_DHTnodes_nmap.bash
Executable file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
ROLE=toxcore
|
||||||
|
prog=$( basename $0 .bash )
|
||||||
|
NOW=`date "+%Y-%m-%d_%H"`
|
||||||
|
|
||||||
|
. /usr/local/bin/usr_local_tput.bash 2>/dev/null >/dev/null || exit 2
|
||||||
|
PREFIX=/var/local
|
||||||
|
BINDIR=$PREFIX/bin
|
||||||
|
[ -n "$USER" ] && USER=$( id -un )
|
||||||
|
|
||||||
|
DEBUG="" /usr/local/bin/proxy_ping_test.bash tor || exit 1
|
||||||
|
|
||||||
|
[ -n "$socks_proxy" ] || . /usr/local/bin/proxy_export.bash 2>/dev/null >/dev/null
|
||||||
|
[ -n "$socks_proxy" ] && sproxy=`echo $socks_proxy | sed -e 's@.*://@@'`
|
||||||
|
|
||||||
|
# https://nodes.tox.chat/json
|
||||||
|
ip=""
|
||||||
|
declare -a ports
|
||||||
|
|
||||||
|
[ $# -eq 0 ] && set -- ~/.config/tox/DHTnodes.json
|
||||||
|
|
||||||
|
cat "$@" | \
|
||||||
|
jq '.|with_entries(select(.key|match("nodes"))).nodes[]|select(.status_tcp)|select(.ipv4|match("."))|.ipv4,.tcp_ports' | while read line ; do
|
||||||
|
if [ -z "$ip" ] ; then
|
||||||
|
ip=`echo $line|sed -e 's/"//g'`
|
||||||
|
ports=()
|
||||||
|
continue
|
||||||
|
elif [ "$line" = '[' ] ; then
|
||||||
|
continue
|
||||||
|
elif [ "$line" = ']' ] ; then
|
||||||
|
grep -q "^wlan[1-9][ ]00000000" /proc/net/route || { ERROR no route ; exit 3 ; }
|
||||||
|
if [ "$ip" = '"NONE"' -o "$ip" = 'NONE' ] ; then
|
||||||
|
:
|
||||||
|
elif ping -c 1 $ip | grep '100% packet loss' ; then
|
||||||
|
WARN failed ping $ip
|
||||||
|
else
|
||||||
|
INFO $ip "${ports[*]}"
|
||||||
|
cmd="nmap -Pn -n -sT -p T:"`echo "${ports[*]}" |sed -e 's/ /,/g'`
|
||||||
|
DBUG $cmd $ip
|
||||||
|
$cmd $ip | grep /tcp
|
||||||
|
fi
|
||||||
|
ip=""
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
port=`echo $line|sed -e 's/,//'`
|
||||||
|
ports+=("$port")
|
||||||
|
# echo '>>' $ip "${ports[*]}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
43
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_bootstrap_node_info.bash
Executable file
43
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_bootstrap_node_info.bash
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
|
||||||
|
|
||||||
|
ROLE=toxcore
|
||||||
|
prog=$( basename $0 .bash )
|
||||||
|
NOW=`date "+%Y-%m-%d_%H"`
|
||||||
|
|
||||||
|
. /usr/local/bin/usr_local_tput.bash 2>/dev/null >/dev/null || exit 2
|
||||||
|
PREFIX=/var/local
|
||||||
|
BINDIR=$PREFIX/bin
|
||||||
|
[ -n "$USER" ] && USER=$( id -un )
|
||||||
|
|
||||||
|
[ -n "$socks_proxy" ] || . /usr/local/bin/proxy_export.bash 2>/dev/null >/dev/null
|
||||||
|
[ -n "$socks_proxy" ] && sproxy=`echo $socks_proxy | sed -e 's@.*://@@'`
|
||||||
|
|
||||||
|
|
||||||
|
if [ $# -gt 0 ] && [ $1 = --test ] ; then
|
||||||
|
test='--test'
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
test=''
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ $# -gt 0 ] && prot=$1 || prot=ipv4
|
||||||
|
|
||||||
|
[ $# -gt 1 ] && host=$2 || host=127.0.0.1
|
||||||
|
|
||||||
|
[ $# -gt 2 ] && port=$3 || {
|
||||||
|
[ -f /etc/tox-bootstrapd.conf ] && \
|
||||||
|
port=`grep ^port /etc/tox-bootstrapd.conf | sed -e 's/.*[ ]//'`
|
||||||
|
}
|
||||||
|
[ -n "$port" ] || port=33446
|
||||||
|
|
||||||
|
[ $# -gt 3 ] && network=$4 || network=old
|
||||||
|
if [ $network == new ] || [ $network == newlocal ] ; then
|
||||||
|
test=--test
|
||||||
|
elif [ $network == old ] ; then
|
||||||
|
test=
|
||||||
|
fi
|
||||||
|
|
||||||
|
dbug $PREFIX/src/toxygen/toxygen/tests/bootstrap_node_info.py $test $prot $host $port
|
||||||
|
python3.sh $PREFIX/src/toxygen/toxygen/tests/bootstrap_node_info.py $test $prot $host $port
|
||||||
|
|
||||||
220
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_bootstrap_node_info.py
Executable file
220
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_bootstrap_node_info.py
Executable file
@@ -0,0 +1,220 @@
|
|||||||
|
#!/var/local/bin/python3.bash
|
||||||
|
"""
|
||||||
|
Copyright (c) 2014 by nurupo <nurupo.contributions@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
if sys.version_info[0] == 2:
|
||||||
|
print("ERROR: This script requires Python 3+ in order to run.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
global LOG
|
||||||
|
LOG = logging.getLogger()
|
||||||
|
|
||||||
|
def print_help(prog: str) -> None:
|
||||||
|
"""Print program usage to stdout."""
|
||||||
|
LOG.info(f"Usage: {prog} <ipv4|ipv6> <ip/hostname> <port>")
|
||||||
|
LOG.info(f" Example: {prog} ipv4 192.210.149.121 33445")
|
||||||
|
LOG.info(f" Example: {prog} ipv4 23.226.230.47 33445")
|
||||||
|
LOG.info(f" Example: {prog} ipv4 node.tox.biribiri.org 33445")
|
||||||
|
LOG.info(f" Example: {prog} ipv4 cerberus.zodiaclabs.org 33445")
|
||||||
|
LOG.info(f" Example: {prog} ipv6 2604:180:1::3ded:b280 33445")
|
||||||
|
LOG.info(f" Example: {prog} socks '82.196.15.215' 33445"),
|
||||||
|
LOG.info(f" Example: {prog} socks5 '84.22.115.205' 33445"), # 'tox.verdict.gg'
|
||||||
|
LOG.info(f" Example: {prog} https '61.230.169.50' 33445"), # 'tox.initramfs.io'
|
||||||
|
LOG.info("socks or socks5 requires the environment_variable socks_proxy")
|
||||||
|
LOG.info("https requires the environment_variable https_proxy")
|
||||||
|
LOG.info("")
|
||||||
|
LOG.info("Return values:")
|
||||||
|
LOG.info(" 0 - received info reply from a node")
|
||||||
|
LOG.info(" 1 - incorrect command line arguments")
|
||||||
|
LOG.info(" 2 - didnt receive any reply from a node")
|
||||||
|
LOG.info(" 3 - received a malformed/unexpected reply")
|
||||||
|
|
||||||
|
|
||||||
|
# https://github.com/irungentoo/toxcore/blob/4940c4c62b6014d1f0586aa6aca7bf6e4ecfcf29/toxcore/network.h#L128
|
||||||
|
INFO_PACKET_ID = b"\xF0"
|
||||||
|
# https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L28
|
||||||
|
INFO_REQUEST_PACKET_LENGTH = 78
|
||||||
|
# first byte is INFO_REQUEST_ID, other bytes don't matter as long as reqest's
|
||||||
|
# length matches INFO_REQUEST_LENGTH
|
||||||
|
INFO_REQUEST_PACKET = INFO_PACKET_ID + (
|
||||||
|
b"0" * (INFO_REQUEST_PACKET_LENGTH - len(INFO_PACKET_ID)))
|
||||||
|
|
||||||
|
PACKET_ID_LENGTH = len(INFO_PACKET_ID)
|
||||||
|
PACKET_ID_LENGTH = 1
|
||||||
|
# https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L44
|
||||||
|
VERSION_LENGTH = 4
|
||||||
|
# https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L26
|
||||||
|
MAX_MOTD_LENGTH = 256
|
||||||
|
|
||||||
|
MAX_INFO_RESPONSE_PACKET_LENGTH = PACKET_ID_LENGTH + VERSION_LENGTH + MAX_MOTD_LENGTH
|
||||||
|
|
||||||
|
SOCK_TIMEOUT_SECONDS = 15.0
|
||||||
|
|
||||||
|
|
||||||
|
def iNodeInfo(protocol: str, host: str, port: int, key: str, environ=None) -> int:
|
||||||
|
"""Call the bootstrap node info RPC and output the response."""
|
||||||
|
|
||||||
|
socks = None
|
||||||
|
python_socks = None
|
||||||
|
if not environ:
|
||||||
|
environ = os.environ
|
||||||
|
if protocol == 'socks5' or protocol == 'https':
|
||||||
|
# https://github.com/4sp1r3/socksipy-branch
|
||||||
|
try:
|
||||||
|
import socks
|
||||||
|
except ImportError:
|
||||||
|
LOG.error("socks/https not supported; download to this directory\n" \
|
||||||
|
+" https://github.com/4sp1r3/socksipy-branch/socks.py")
|
||||||
|
return 4
|
||||||
|
|
||||||
|
elif protocol == 'socks':
|
||||||
|
# https://github.com/romis2012/python-socks
|
||||||
|
try:
|
||||||
|
import python_socks
|
||||||
|
except ImportError:
|
||||||
|
LOG.error("socks not supported; install python_socks\n" \
|
||||||
|
+'https://github.com/romis2012/python-socks')
|
||||||
|
return 4
|
||||||
|
|
||||||
|
if socks and protocol == "socks5" and 'socks_proxy' in environ:
|
||||||
|
sock = socks.socksocket()
|
||||||
|
proxy = environ['socks_proxy']
|
||||||
|
if proxy:
|
||||||
|
i = proxy.find('//')
|
||||||
|
if i > 0:
|
||||||
|
proxy = proxy[i+2:]
|
||||||
|
phost = proxy.split(':')[0]
|
||||||
|
pport = int(proxy.split(':')[1])
|
||||||
|
# LOG("DBUG: 'socks_proxy' in environment: ", phost, pport)
|
||||||
|
else:
|
||||||
|
LOG.debug("NO 'socks_proxy' in environment - defaulting to 127.0.0.1:1080")
|
||||||
|
phost = '127.0.0.1'
|
||||||
|
pport = 1080
|
||||||
|
sock.setproxy(socks.PROXY_TYPE_SOCKS5, phost, pport, True)
|
||||||
|
|
||||||
|
elif socks and protocol == "https" and 'https_proxy' in environ:
|
||||||
|
sock = socks.socksocket()
|
||||||
|
proxy = environ['https_proxy']
|
||||||
|
if proxy:
|
||||||
|
i = proxy.find('//')
|
||||||
|
if i > 0:
|
||||||
|
proxy = proxy[i+2:]
|
||||||
|
phost = proxy.split(':')[0]
|
||||||
|
pport = int(proxy.split(':')[1])
|
||||||
|
# LOG("DBUG: 'https_proxy' in environment: ", phost, pport)
|
||||||
|
else:
|
||||||
|
LOG.debug("NO 'https_proxy' in environment - defaulting to 127.0.0.1:8080")
|
||||||
|
phost = '127.0.0.1'
|
||||||
|
pport = 8080
|
||||||
|
sock.setproxy(socks.PROXY_TYPE_HTTP, phost, pport, True)
|
||||||
|
|
||||||
|
elif python_socks and protocol == "socks" and 'socks_proxy' in environ:
|
||||||
|
from python_socks.sync import Proxy
|
||||||
|
proxy = Proxy.from_url(environ['socks_proxy'], rdns=True)
|
||||||
|
elif protocol == "ipv4":
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
elif protocol == "ipv6":
|
||||||
|
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
|
else:
|
||||||
|
LOG.error("1 Invalid first argument " +protocol +" - one of: socks socks5 https ipv4 ipv6")
|
||||||
|
print_help(__file__)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
if python_socks:
|
||||||
|
sock = proxy.connect(dest_host=host, dest_port=port)
|
||||||
|
else:
|
||||||
|
sock.connect((host, port))
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("2 Could not connect to bootstrap node " \
|
||||||
|
+repr((host, port)) \
|
||||||
|
+': ' +str(e))
|
||||||
|
return 2
|
||||||
|
|
||||||
|
try:
|
||||||
|
sock.settimeout(SOCK_TIMEOUT_SECONDS)
|
||||||
|
sock.sendall(INFO_REQUEST_PACKET)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("3 Could not send to bootstrap node " \
|
||||||
|
+repr((host, port)) \
|
||||||
|
+' ' +str(e))
|
||||||
|
return 3
|
||||||
|
|
||||||
|
try:
|
||||||
|
data, _ = sock.recvfrom(MAX_INFO_RESPONSE_PACKET_LENGTH)
|
||||||
|
except socket.timeout:
|
||||||
|
LOG.warn("4 The DHT bootstrap node " \
|
||||||
|
+repr((host, port)) \
|
||||||
|
+" didnt reply in " + str(SOCK_TIMEOUT_SECONDS) + " sec.")
|
||||||
|
return 4
|
||||||
|
if len(data) == 0:
|
||||||
|
try:
|
||||||
|
data, _ = sock.recvfrom(MAX_INFO_RESPONSE_PACKET_LENGTH)
|
||||||
|
except socket.timeout:
|
||||||
|
LOG.warn("4b The DHT bootstrap node " \
|
||||||
|
+repr((host, port)) \
|
||||||
|
+" didnt reply in " + str(SOCK_TIMEOUT_SECONDS) + " sec.")
|
||||||
|
return 4
|
||||||
|
|
||||||
|
if len(data) == 0:
|
||||||
|
LOG.warn("5 Bad response, no data from " +repr((host, port)) )
|
||||||
|
return 5
|
||||||
|
|
||||||
|
packet_id = data[:PACKET_ID_LENGTH]
|
||||||
|
if packet_id != INFO_PACKET_ID:
|
||||||
|
LOG.warn("Bad response, first byte should be {info_packet_id!r}"
|
||||||
|
+" but got {packet_id!r}({data!r})".format(
|
||||||
|
info_packet_id=INFO_PACKET_ID,
|
||||||
|
packet_id=packet_id,
|
||||||
|
data=data,
|
||||||
|
))
|
||||||
|
LOG.warn("6 Are you sure that you are pointing the script at a Tox "
|
||||||
|
"DHT bootstrap node? " \
|
||||||
|
+repr((host, port)) \
|
||||||
|
)
|
||||||
|
return 6
|
||||||
|
|
||||||
|
version = int.from_bytes(data[PACKET_ID_LENGTH:PACKET_ID_LENGTH + VERSION_LENGTH],
|
||||||
|
byteorder="big")
|
||||||
|
motd = data[PACKET_ID_LENGTH + VERSION_LENGTH:].decode("utf-8")
|
||||||
|
LOG.info("Version: " + str(version) +" MOTD: " + motd[:-1])
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 4:
|
||||||
|
print_help(sys.argv[0])
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
i = iNodeInfo(
|
||||||
|
protocol=sys.argv[1],
|
||||||
|
host=sys.argv[2],
|
||||||
|
port=int(sys.argv[3]),
|
||||||
|
)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
i = 0
|
||||||
|
sys.exit(i)
|
||||||
58
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_bootstrap_test.bash
Executable file
58
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_bootstrap_test.bash
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
|
||||||
|
ROLE=toxcore
|
||||||
|
. /usr/local/bin/usr_local_tput.bash
|
||||||
|
|
||||||
|
[ $# -gt 0 ] && ERROR no arguments needed && exit 1
|
||||||
|
|
||||||
|
cd /var/local/bin/
|
||||||
|
network=new
|
||||||
|
|
||||||
|
[ -f /etc/tox-bootstrapd.conf ] && \
|
||||||
|
port=`grep ^port /etc/tox-bootstrapd.conf | sed -e 's/.*[ ]//'`
|
||||||
|
[ $? -eq 0 -a -n "$port" ] || port=33446
|
||||||
|
|
||||||
|
# EC8F7405F79F281569B6C66D9F03490973AB99BC9175C44FBEF4C3428A63B80D
|
||||||
|
python3.sh bootstrap_node_info.py ipv4 \
|
||||||
|
127.0.0.1 $port $network
|
||||||
|
python3.sh bootstrap_node_info.py tcp4 \
|
||||||
|
127.0.0.1 3389 $network
|
||||||
|
|
||||||
|
grep -q "^wlan[1-9][ ]00000000" /proc/net/route || { echo ERROR: not connected ; exit 1 ; }
|
||||||
|
|
||||||
|
if [ `id -un` = bin ] ; then
|
||||||
|
socks5=ipv4
|
||||||
|
socks=ipv4
|
||||||
|
else
|
||||||
|
socks5=socks5
|
||||||
|
socks=socks
|
||||||
|
fi
|
||||||
|
|
||||||
|
# onion
|
||||||
|
[ $socks5 = socks5 ] && \
|
||||||
|
python3.sh bootstrap_node_info.py $socks5 \
|
||||||
|
pvbgbm6bmn2d5xnmdqivowsi36ywawmixr645lnjuon22lriqj6gufqd.onion \
|
||||||
|
$port $network
|
||||||
|
[ $socks5 = socks5 ] && \
|
||||||
|
python3.sh bootstrap_node_info.py $socks5 \
|
||||||
|
pvbgbm6bmn2d5xnmdqivowsi36ywawmixr645lnjuon22lriqj6gufqd.onion \
|
||||||
|
38445 $network
|
||||||
|
[ $socks = socks ] && \
|
||||||
|
python3.sh bootstrap_node_info.py $socks \
|
||||||
|
pvbgbm6bmn2d5xnmdqivowsi36ywawmixr645lnjuon22lriqj6gufqd.onion \
|
||||||
|
$port $network
|
||||||
|
[ $socks = socks ] && \
|
||||||
|
python3.sh bootstrap_node_info.py $socks \
|
||||||
|
pvbgbm6bmn2d5xnmdqivowsi36ywawmixr645lnjuon22lriqj6gufqd.onion \
|
||||||
|
38445 $network
|
||||||
|
[ $socks = socks ] && \
|
||||||
|
python3.sh bootstrap_node_info.py $socks \
|
||||||
|
pvbgbm6bmn2d5xnmdqivowsi36ywawmixr645lnjuon22lriqj6gufqd.onion \
|
||||||
|
80
|
||||||
|
|
||||||
|
# $network
|
||||||
|
python3.sh bootstrap_node_info.py $socks \
|
||||||
|
172.93.52.70 $port $network
|
||||||
|
python3.sh bootstrap_node_info.py $socks5 \
|
||||||
|
172.93.52.70 $port $network
|
||||||
104
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_build_overlay_qcow.bash
Executable file
104
roles/toxcore/overlay/Linux/usr/local/bin/toxcore_build_overlay_qcow.bash
Executable file
@@ -0,0 +1,104 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
||||||
|
# from https://github.com/earlruby/create-vm/
|
||||||
|
|
||||||
|
[ -f /usr/local/bin/usr_local_tput.bash ] && \
|
||||||
|
. /usr/local/bin/usr_local_tput.bash || {
|
||||||
|
DBUG() { echo DEBUG $* ; }
|
||||||
|
INFO() { echo INFO $* ; }
|
||||||
|
WARN() { echo WARN $* ; }
|
||||||
|
ERROR() { echo ERROR $* ; }
|
||||||
|
}
|
||||||
|
|
||||||
|
prog=`basename $0 .bash`
|
||||||
|
PREFIX=/usr/local
|
||||||
|
ROLE=toxcore
|
||||||
|
BOX=gentoo_overlay-2
|
||||||
|
OVERLAY_HOSTS_NAME=${BOX}
|
||||||
|
|
||||||
|
export BASE_SRC_ANSIBLE=/o/var/local/src/play_tox
|
||||||
|
yamllint -c $BASE_SRC_ANSIBLE/.yamllint.rc $BASE_SRC_ANSIBLE/hosts.yml|| {
|
||||||
|
ERROR
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# put these values in $BASE_SRC_ANSIBLE/hosts.yml
|
||||||
|
[ -n "$BOX_NBD_OVERLAY_NAME" ] || \
|
||||||
|
BOX_NBD_OVERLAY_NAME=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_NAME ${OVERLAY_HOSTS_NAME})
|
||||||
|
|
||||||
|
if virsh list | grep "$BOX_NBD_OVERLAY_NAME" ; then
|
||||||
|
ERROR "$BOX_NBD_OVERLAY_NAME" is running - please virsh destroy "$BOX_NBD_OVERLAY_NAME"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
if virsh list --all | grep "$BOX_NBD_OVERLAY_NAME" ; then
|
||||||
|
ERROR "$BOX_NBD_OVERLAY_NAME" is running - please virsh undefine "$BOX_NBD_OVERLAY_NAME"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
[ -n "$BOX_NBD_BASE_PUBKEY" ] || \
|
||||||
|
BOX_NBD_BASE_PUBKEY=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_BASE_PUBKEY ${OVERLAY_HOSTS_NAME})
|
||||||
|
[ -n "$BOX_NBD_OVERLAY_BASE" ] || \
|
||||||
|
BOX_NBD_OVERLAY_BASE=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_BASE ${OVERLAY_HOSTS_NAME})
|
||||||
|
[ -n "$BOX_NBD_OVERLAY_GB" ] || \
|
||||||
|
BOX_NBD_OVERLAY_GB=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_GB ${OVERLAY_HOSTS_NAME})
|
||||||
|
[ -n "$BOX_NBD_OVERLAY_CPUS" ] || \
|
||||||
|
BOX_NBD_OVERLAY_CPUS=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_CPUS ${OVERLAY_HOSTS_NAME})
|
||||||
|
[ -n "$BOX_NBD_OVERLAY_RAM" ] || \
|
||||||
|
BOX_NBD_OVERLAY_RAM=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_RAM ${OVERLAY_HOSTS_NAME})
|
||||||
|
[ -n "$BOX_NBD_OVERLAY_DIR" ] || \
|
||||||
|
BOX_NBD_OVERLAY_DIR=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_DIR ${OVERLAY_HOSTS_NAME})
|
||||||
|
[ -n "$BOX_NBD_OVERLAY_BR" ] || \
|
||||||
|
BOX_NBD_OVERLAY_BR=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_BR ${OVERLAY_HOSTS_NAME})
|
||||||
|
#[ -n "$BOX_NBD_OVERLAY_NETWORK" ] || \
|
||||||
|
# BOX_NBD_OVERLAY_NETWORK=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_NETWORK ${OVERLAY_HOSTS_NAME})
|
||||||
|
[ -n "$BOX_NBD_OVERLAY_PASS" ] || \
|
||||||
|
BOX_NBD_OVERLAY_PASS=$( /usr/local/bin/ansible_get_inventory.bash BOX_NBD_OVERLAY_PASS ${OVERLAY_HOSTS_NAME})
|
||||||
|
|
||||||
|
[ ! -f "$BOX_NBD_OVERLAY_BASE" ] && \
|
||||||
|
ERROR BOX_NBD_OVERLAY_BASE=$BOX_NBD_OVERLAY_BASE must exist && exit 3
|
||||||
|
[ ! -d "$BOX_NBD_OVERLAY_DIR" ] && \
|
||||||
|
ERROR BOX_NBD_OVERLAY_DIR=$BOX_NBD_OVERLAY_DIR must exist && exit 5
|
||||||
|
|
||||||
|
[ -z "$BOX_NBD_OVERLAY_BR" ] && \
|
||||||
|
ERROR BOX_NBD_OVERLAY_BR=$BOX_NBD_OVERLAY_BR must not be null && exit 5
|
||||||
|
|
||||||
|
[ -n "$BOX_NBD_DEV" ] && grep "$BOX_NBD_DEV" /proc/mounts && WARN "$BOX_NBD_DEV" is mounted
|
||||||
|
export BOX_NBD_OVERLAY_DIR
|
||||||
|
|
||||||
|
# libvirt.libvirtError: Network not found: no network with matching name 'default'a
|
||||||
|
DBUG bash toxcore_create-vm.bash \
|
||||||
|
-n $BOX_NBD_OVERLAY_NAME \
|
||||||
|
-k $BOX_NBD_BASE_PUBKEY \
|
||||||
|
-i $BOX_NBD_OVERLAY_BASE \
|
||||||
|
-s $BOX_NBD_OVERLAY_GB \
|
||||||
|
-b $BOX_NBD_OVERLAY_BR \
|
||||||
|
-c $BOX_NBD_OVERLAY_CPUS \
|
||||||
|
-r $BOX_NBD_OVERLAY_RAM \
|
||||||
|
-d $BOX_NBD_OVERLAY_DIR \
|
||||||
|
-p $BOX_NBD_OVERLAY_PASS \
|
||||||
|
-o gentoo
|
||||||
|
bash toxcore_create-vm.bash \
|
||||||
|
-n $BOX_NBD_OVERLAY_NAME \
|
||||||
|
-k $BOX_NBD_BASE_PUBKEY \
|
||||||
|
-i $BOX_NBD_OVERLAY_BASE \
|
||||||
|
-s $BOX_NBD_OVERLAY_GB \
|
||||||
|
-b $BOX_NBD_OVERLAY_BR \
|
||||||
|
-c $BOX_NBD_OVERLAY_CPUS \
|
||||||
|
-r $BOX_NBD_OVERLAY_RAM \
|
||||||
|
-d $BOX_NBD_OVERLAY_DIR \
|
||||||
|
-p $BOX_NBD_OVERLAY_PASS \
|
||||||
|
-o gentoo < /dev/null
|
||||||
|
retval=$?
|
||||||
|
[ $retval -gt 0 ] && exit 1$retval
|
||||||
|
[ -f $BOX_NBD_OVERLAY_DIR/images/$BOX_NBD_OVERLAY_NAME.img ] && \
|
||||||
|
INFO $BOX_NBD_OVERLAY_DIR/images/$BOX_NBD_OVERLAY_NAME.img || {
|
||||||
|
ERROR NO $BOX_NBD_OVERLAY_DIR/images/$BOX_NBD_OVERLAY_NAME.img ; exit 2$retval ; }
|
||||||
|
|
||||||
|
INFO virsh define $BOX_NBD_OVERLAY_DIR/xml/$BOX_NBD_OVERLAY_NAME.xml
|
||||||
|
virsh define $BOX_NBD_OVERLAY_DIR/xml/$BOX_NBD_OVERLAY_NAME.xml
|
||||||
|
sleep 5
|
||||||
|
INFO virsh net-dhcp-leases default
|
||||||
|
sudo virsh net-dhcp-leases default
|
||||||
|
sudo find /var/lib/libvirt/qemu/channel/target/*${BOX_NBD_OVERLAY_NAME}* \
|
||||||
|
-name org.qemu.guest_agent.0
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user