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/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
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
|
||||
|
||||
# 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
|
||||
# Find the corresponding host in hosts.yml and edit the settings, then
|
||||
# change this to be that 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
|
||||
LOCAL_HOSTS_NAME=pentoo
|
||||
# set this to the name linux_chroot_group host in hosts.yml
|
||||
YAML_CHROOT_NAME=linuxGentoo
|
||||
# set this to the libvirt name of the linux_libvirt_group host in hosts.yml
|
||||
YAML_BOX_NAME=gentoo1
|
||||
INST_BOX_NAME=gentoo1
|
||||
OVERLAY_HOSTS_NAME=gentoo_overlay-2
|
||||
|
||||
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/
|
||||
NETWORK=default
|
||||
NETWORK=Whonix-External
|
||||
VERBOSE=2
|
||||
|
||||
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::
|
||||
@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| \
|
||||
@@ -44,18 +36,29 @@ lint::
|
||||
grep -B 2 error | tee .yamllint.err || 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
|
||||
|
||||
build_base:: lint
|
||||
build_base:: install
|
||||
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}
|
||||
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml \
|
||||
-l ${LOCALHOST} -c local --verbose ${VERBOSE} \
|
||||
@@ -63,24 +66,27 @@ build_base:: lint
|
||||
[ -f ${BOX_NBD_BASE_QCOW} ]
|
||||
|
||||
build_overlay::
|
||||
@virsh list | grep "${INST_BOX_NAME}.*running" && \
|
||||
virsh destroy ${INST_BOX_NAME} ; true
|
||||
# @virsh list | grep "${INST_BOX_NAME}.*running" && exit 1
|
||||
@virsh list --all | grep ${INST_BOX_NAME} && \
|
||||
virsh undefine ${INST_BOX_NAME} && \
|
||||
rm -f /a/tmp/GentooImgr/create-vm/xml/gentoo1.xml \
|
||||
${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml \
|
||||
${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ; true
|
||||
# ! virsh list --all | grep "${INST_BOX_NAME}" && exit 2
|
||||
[ ! -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ] || { \
|
||||
echo WARN ; echo rm -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ; \
|
||||
@virsh list | grep "${OVERLAY_HOSTS_NAME}.*running" && \
|
||||
virsh destroy ${OVERLAY_HOSTS_NAME} ; true
|
||||
# @virsh list | grep "${OVERLAY_HOSTS_NAME}.*running" && exit 1
|
||||
@virsh list --all | grep ${OVERLAY_HOSTS_NAME} && \
|
||||
virsh undefine ${OVERLAY_HOSTS_NAME} && \
|
||||
rm -f \
|
||||
${BOX_NBD_OVERLAY_XML} \
|
||||
${BOX_NBD_OVERLAY_QCOW} ; true
|
||||
# /a/tmp/GentooImgr/create-vm/xml/gentoo1.xml
|
||||
# ! virsh list --all | grep "${OVERLAY_HOSTS_NAME}" && exit 2
|
||||
[ ! -f ${BOX_NBD_OVERLAY_QCOW} ] || { \
|
||||
echo WARN delete this file to continue; \
|
||||
echo rm -f ${BOX_NBD_OVERLAY_QCOW} ; \
|
||||
exit 3 ; }
|
||||
[ ! -f ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml ] || { \
|
||||
echo WARN ; echo rm -f ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml ; \
|
||||
[ ! -f ${BOX_NBD_OVERLAY_XML} ] || { \
|
||||
echo WARN delete this file to continue ; \
|
||||
echo rm -f ${BOX_NBD_OVERLAY_XML} ; \
|
||||
exit 4 ; }
|
||||
PLAY_ANSIBLE_SRC=${PWD} bash /usr/local/bin/toxcore_build_overlay_qcow.bash
|
||||
[ -f ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml ]
|
||||
xmllint -noout ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml
|
||||
PLAY_ANSIBLE_SRC=${PWD} bash bin/toxcore_build_overlay_qcow.bash
|
||||
[ -f ${BOX_NBD_OVERLAY_XML} ]
|
||||
xmllint -noout ${BOX_NBD_OVERLAY_XML}
|
||||
|
||||
check::
|
||||
grep -n 'shell: *$$' roles/*/tasks/*.yml && { echo ERROR: "shell: in .yml" ; false ; } || true
|
||||
@@ -90,7 +96,7 @@ check::
|
||||
$(MAKE) -$(MAKEFLAGS) check_base
|
||||
@[ -d /mnt/gentoo/lost+found ] && \
|
||||
sudo $(MAKE) -$(MAKEFLAGS) $@_chroot
|
||||
@[ -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ] && \
|
||||
@[ -f ${BOX_NBD_OVERLAY_QCOW} ] && \
|
||||
sudo $(MAKE) -$(MAKEFLAGS) $@_overlay
|
||||
|
||||
check_localhost::
|
||||
@@ -100,9 +106,9 @@ check_localhost::
|
||||
|
||||
check_base::
|
||||
ls ${BOX_NBD_BASE_QCOW}
|
||||
ls ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img
|
||||
ls ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml
|
||||
ps axf | grep 'qemu-system-x86_64 -name guest='${INST_BOX_NAME} ; \
|
||||
ls ${BOX_NBD_OVERLAY_QCOW}
|
||||
ls ${BOX_NBD_OVERLAY_XML}
|
||||
ps axf | grep 'qemu-system-x86_64 -name guest='${OVERLAY_HOSTS_NAME} ; \
|
||||
true
|
||||
|
||||
check_chroot::
|
||||
@@ -114,18 +120,19 @@ check_chroot::
|
||||
$(ROLES) > .$@-${YAML_CHROOT_NAME}-${LOCALHOST} 2>&1
|
||||
|
||||
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
|
||||
sudo virsh list | grep -q ${OVERLAY_HOSTS_NAME} || exit 0
|
||||
sudo find /var/lib/libvirt/qemu/channel/target/ | \
|
||||
grep org.qemu.guest_agent.0
|
||||
sudo find /var/lib/libvirt/qemu/channel/target/ -type s | \
|
||||
grep ${INST_BOX_NAME}
|
||||
ansible -c libvirt_qemu -l ${YAML_BOX_NAME} -i hosts.yml \
|
||||
-m setup -vvv ${YAML_BOX_NAME}
|
||||
sudo virsh list | grep -q ${INST_BOX_NAME} || exit 0
|
||||
sudo sh ansible_local.bash --diff -i hosts.yml -l ${INST_BOX_NAME} \
|
||||
grep ${OVERLAY_HOSTS_NAME}
|
||||
ansible -c libvirt_qemu -l ${OVERLAY_HOSTS_NAME} -i hosts.yml \
|
||||
-m setup -vvv ${OVERLAY_HOSTS_NAME}
|
||||
sudo sh ansible_local.bash --diff -i hosts.yml -l ${OVERLAY_HOSTS_NAME} \
|
||||
--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
|
||||
devuan::
|
||||
@@ -144,8 +151,8 @@ run::
|
||||
$(MAKE) -$(MAKEFLAGS) $@_local
|
||||
@[ -d /mnt/gentoo/lost+found ] && \
|
||||
sudo $(MAKE) -$(MAKEFLAGS) $@_chroot
|
||||
@[ ! -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ] && \
|
||||
sudo $(MAKE) -$(MAKEFLAGS) $@_libvirt
|
||||
@[ ! -f ${BOX_NBD_OVERLAY_QCOW} ] && \
|
||||
sudo $(MAKE) -$(MAKEFLAGS) $@_overlay
|
||||
|
||||
run_local:: lint
|
||||
A=`grep nbd /proc/partitions | wc -l`
|
||||
@@ -168,26 +175,35 @@ run_chroot::
|
||||
-c chroot --verbose ${VERBOSE} $(ROLES) \
|
||||
> .$@-${YAML_CHROOT_NAME}-${LOCALHOST} 2>&1
|
||||
|
||||
run_libvirt::
|
||||
[ -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ]
|
||||
install_libvirt::
|
||||
@virsh net-list | grep "${NETWORK}.*active" || \
|
||||
sudo virsh net-start "${NETWORK}"
|
||||
@virsh list | grep ${INST_BOX_NAME} && \
|
||||
virsh define ${INST_BOX_DIR}/xml/${INST_BOX_NAME}.xml
|
||||
@virsh list | grep "${INST_BOX_NAME}.*running" || \
|
||||
virsh start ${INST_BOX_NAME}
|
||||
sh ansible_local.bash --diff -i hosts.yml -l ${INST_BOX_NAME} \
|
||||
sudo virsh net-start "${NETWORK}" || { \
|
||||
echo WARN: error virsh net-start "${NETWORK}" ; }
|
||||
[ -f ${BOX_NBD_OVERLAY_XML} ]
|
||||
# xmlstarlet sel -t -v
|
||||
A=$(grep 'source file=' ${BOX_NBD_OVERLAY_XML} | sed -e 's@.*file=.@@' -e "s@'.*@@" )
|
||||
[ -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) \
|
||||
> .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
|
||||
weekly:: test
|
||||
test::
|
||||
# bash .pyanal.sh &
|
||||
@[ -d /mnt/gentoo/lost+found ] && \
|
||||
sudo $(MAKE) -$(MAKEFLAGS) $@_local
|
||||
@[ -f ${INST_BOX_DIR}/images/${INST_BOX_NAME}.img ] && \
|
||||
sudo $(MAKE) -$(MAKEFLAGS) $@_libvert
|
||||
|
||||
@[ -f ${BOX_NBD_OVERLAY_QCOW} ] && \
|
||||
sudo $(MAKE) -$(MAKEFLAGS) $@_overlay
|
||||
test_local::
|
||||
bash .pyanal.sh &
|
||||
sudo sh ansible_local.bash --diff -i ${PWD}/hosts.yml -l ${LOCALHOST} \
|
||||
@@ -195,18 +211,49 @@ test_local::
|
||||
--verbose ${VERBOSE} -t weekly \
|
||||
$(ROLES) > .$@-${LOCALHOST} 2>&1
|
||||
|
||||
test_libvirt::
|
||||
# bash .pyanal.sh &
|
||||
# check if ${INST_BOX_NAME} is running
|
||||
! sudo virsh list | grep -q ${INST_BOX_NAME} && exit 0
|
||||
test_overlay:: install_libvirt
|
||||
! sudo virsh list | grep -q ${OVERLAY_HOSTS_NAME} && exit 0
|
||||
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 \
|
||||
$(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
|
||||
rm -f .run* .check*
|
||||
|
||||
clean::
|
||||
find . -name \*~ -delete
|
||||
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 /
|
||||
|
34
README.md
34
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:
|
||||
|
||||
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,
|
||||
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 :
|
||||
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:
|
||||
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:
|
||||
|
||||
modprobe nbd
|
||||
qemu-img $BOX_NBD_BASE_QCOW 20G
|
||||
qemu-nbd -c $BOX_NBD_DEV $BOX_NBD_BASE_QCOW
|
||||
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.
|
||||
|
||||
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.
|
||||
modprobe nbd
|
||||
qemu-img $BOX_NBD_BASE_QCOW 20G
|
||||
qemu-nbd -c $BOX_NBD_DEV $BOX_NBD_BASE_QCOW
|
||||
|
||||
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
|
||||
to dismount it with qemu-nbd -d $BOX_NBD_DEV. Be careful and look
|
||||
|
@@ -1,5 +1,5 @@
|
||||
[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/
|
||||
# /i/data/DevOps/net/Http/docs.ansible.com/ansible/intro_configuration.html
|
||||
# http://docs.ansible.com/ansible/intro_configuration.html#command-warnings
|
||||
@@ -36,3 +36,5 @@ nocows = 0
|
||||
roles_path = ./roles
|
||||
handler_includes_static = True
|
||||
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_method: "'' if ansible_connection|default('') == 'chroot' else 'sudo'"
|
||||
gather_facts: true
|
||||
@@ -43,7 +43,7 @@
|
||||
# other things that use /usr/local, including some things from other OSes.
|
||||
VAR_LOCAL: "/var/local"
|
||||
VAR_LOG: "{{VAR_LOCAL}}/var/log/testforge"
|
||||
|
||||
PLAY_TESTFORGE_YML: ''
|
||||
PIP_CACHE: "/root/.cache/pip"
|
||||
# lynx uses SSL_CERT_DIR/SSL_CERT_FILE
|
||||
PIP_CA_CERT: "{{USR_LOCAL}}/etc/ssl/cacert-testserver.pem"
|
||||
@@ -101,10 +101,10 @@
|
||||
that:
|
||||
- "'{{ansible_lsb.id}}' == '{{BOX_OS_NAME}}'"
|
||||
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:
|
||||
- ansible_connection != 'local'
|
||||
- ansible_lsb.id|default('')" != ''
|
||||
# - ansible_connection != 'local'
|
||||
- ansible_lsb.id|default('') != ''
|
||||
ignore_errors: true
|
||||
|
||||
- name: "check BOX_ANSIBLE_CONNECTIONS"
|
||||
@@ -150,37 +150,6 @@
|
||||
|
||||
- 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:
|
||||
|
||||
# after spinup
|
||||
- name: "we will use sudo and make it a prerequisite"
|
||||
shell: |
|
||||
[ -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_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
|
||||
@@ -110,7 +109,6 @@ all:
|
||||
|
||||
BOX_JAVA_NET_PROPERTIES: /etc/java-11-openjdk/net.properties
|
||||
|
||||
BOX_WHONIX_PROXY_HOST: ""
|
||||
BOX_PROXY_MODE: tor
|
||||
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
|
||||
|
||||
@@ -126,13 +124,13 @@ all:
|
||||
|
||||
hosts:
|
||||
|
||||
gentoo1:
|
||||
gentoo_overlay-2:
|
||||
|
||||
ansible_remote_addr: "gentoo1"
|
||||
ansible_host: "gentoo1"
|
||||
ansible_remote_addr: "gentoo_overlay-2"
|
||||
ansible_host: "gentoo_overlay-2"
|
||||
ansible_ssh_user: "gentoo"
|
||||
BOX_SERVICE_MGR: "openrc"
|
||||
BOX_HOST_NAME: "gentoo1"
|
||||
BOX_HOST_NAME: "gentoo_overlay-2"
|
||||
BOX_USER_NAME: "gentoo"
|
||||
BOX_USER_GROUP: "adm"
|
||||
BOX_ALSO_GROUP: "adm"
|
||||
@@ -140,6 +138,7 @@ all:
|
||||
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: ""
|
||||
@@ -151,8 +150,42 @@ all:
|
||||
BOX_ALSO_USERS:
|
||||
- gentoo
|
||||
BOX_BASE_FEATURES: []
|
||||
BOX_TOXCORE_FEATURES: ['libvirt', 'docker']
|
||||
BOX_TOXCORE_FEATURES: ['libvirt'] # ', 'docker
|
||||
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:
|
||||
# /mnt
|
||||
@@ -186,12 +219,13 @@ all:
|
||||
# proxy from environment
|
||||
# ansible_ssh_extra_args: "-o StrictHostKeyChecking=no"
|
||||
# ansible_ssh_host: "127.0.0.1"
|
||||
BOX_ROOT_GROUP: root
|
||||
BOX_PROXY_MODE: client
|
||||
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"
|
||||
BOX_NBD_OVERLAY_EXTERNAL: "0.0.0.0"
|
||||
http_proxy: "http://{{BOX_NBD_OVERLAY_EXTERNAL}}:3128"
|
||||
https_proxy: "http://{{BOX_NBD_OVERLAY_EXTERNAL}}:9128"
|
||||
socks_proxy: "socks5://{{BOX_NBD_OVERLAY_EXTERNAL}}:9050"
|
||||
ftp_proxy: ""
|
||||
RSYNC_PROXY : "{{BOX_NBD_OVERLAY_EXTERNAL}}:3128"
|
||||
no_proxy: "localhost,127.0.0.1"
|
||||
|
||||
linux_chroot_group :
|
||||
|
||||
@@ -259,9 +293,8 @@ all:
|
||||
# for a non-root login: ansible_ssh_extra_args: "--userspec=foo:adm"
|
||||
vars: # linux_unix_group
|
||||
# toxcore
|
||||
BOX_NBD_DEV: nbd3
|
||||
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"
|
||||
@@ -269,7 +302,6 @@ all:
|
||||
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
|
||||
@@ -279,22 +311,21 @@ all:
|
||||
BOX_NBD_OVERLAY_CPUS: 1
|
||||
BOX_NBD_OVERLAY_RAM: 2048
|
||||
BOX_NBD_OVERLAY_BR: virbr1
|
||||
# unused?
|
||||
BOX_NBD_OVERLAY_NETWORK: default
|
||||
BOX_NBD_OVERLAY_SUBNET: 10.0.2.0
|
||||
BOX_NBD_OVERLAY_NETWORK: External
|
||||
# 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: ""
|
||||
RSYNC_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: ""
|
||||
@@ -431,6 +462,7 @@ all:
|
||||
|
||||
BOX_WHONIX_PROXY_HOST: ""
|
||||
BOX_PROXY_FEATURES: []
|
||||
# get this from grep '^keyserver ' /root/.gnupg/dirmngr.conf instead
|
||||
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 ''
|
||||
@@ -440,7 +472,7 @@ all:
|
||||
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') }}"
|
||||
# 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') }}"
|
||||
|
@@ -38,6 +38,17 @@ DOCUMENTATION = """
|
||||
default: qemu:///system
|
||||
vars:
|
||||
- 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
|
||||
@@ -59,7 +70,7 @@ from os.path import exists, getsize
|
||||
|
||||
display = Display()
|
||||
|
||||
iMAX_WAIT = 10 # sec.
|
||||
iMAX_WAIT = 15 # sec.
|
||||
|
||||
REQUIRED_CAPABILITIES = [
|
||||
{'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)
|
||||
|
||||
self._host = self._play_context.remote_addr
|
||||
self._play_context = play_context
|
||||
|
||||
# Windows operates differently from a POSIX connection/shell plugin,
|
||||
# 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.module_implementation_preferences = ('.ps1', '.exe', '')
|
||||
self.allow_executable = False
|
||||
self._timeout = self.get_option('timeout', iMAX_WAIT)
|
||||
|
||||
def _connect(self):
|
||||
''' connect to the virtual machine; nothing to do here '''
|
||||
@@ -116,7 +129,7 @@ class Connection(ConnectionBase):
|
||||
raise AnsibleConnectionFailure(to_native(err))
|
||||
|
||||
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._display.vvvvv(u"GUEST CAPABILITIES: {0}".format(self.capabilities), host=self._host)
|
||||
missing_caps = []
|
||||
@@ -130,11 +143,13 @@ class Connection(ConnectionBase):
|
||||
display.vvv(u"ESTABLISH {0} CONNECTION".format(self.transport), host=self._host)
|
||||
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 """
|
||||
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
||||
|
||||
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'))
|
||||
|
||||
@@ -148,6 +163,15 @@ class Connection(ConnectionBase):
|
||||
cmd_args_list = self._shell._encode_script(cmd, as_list=True, strict_mode=False, preserve_rc=False)
|
||||
|
||||
# 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 'env' for the environment settings
|
||||
# Implement 'input-data' for whatever it might be useful for
|
||||
@@ -161,20 +185,21 @@ class Connection(ConnectionBase):
|
||||
}
|
||||
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))
|
||||
command_start = time.clock_gettime(time.CLOCK_MONOTONIC)
|
||||
# TODO(odyssey4me):
|
||||
# Add timeout parameter
|
||||
flags = 0
|
||||
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:
|
||||
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)))
|
||||
self._connected = False
|
||||
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 = {
|
||||
'execute': 'guest-exec-status',
|
||||
@@ -184,15 +209,17 @@ class Connection(ConnectionBase):
|
||||
}
|
||||
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):
|
||||
# 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 = {
|
||||
'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
|
||||
sleep_time = (time.clock_gettime(time.CLOCK_MONOTONIC) - command_start) * (5 / 100)
|
||||
if sleep_time < 0.0002:
|
||||
@@ -200,7 +227,7 @@ class Connection(ConnectionBase):
|
||||
elif sleep_time > 1:
|
||||
sleep_time = 1
|
||||
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:
|
||||
err = 'timeout'
|
||||
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
|
||||
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']:
|
||||
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'):
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
@@ -274,7 +301,7 @@ class Connection(ConnectionBase):
|
||||
|
||||
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)
|
||||
|
||||
@@ -292,7 +319,7 @@ class Connection(ConnectionBase):
|
||||
|
||||
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)
|
||||
|
||||
@@ -312,7 +339,7 @@ class Connection(ConnectionBase):
|
||||
|
||||
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)
|
||||
|
||||
@@ -329,11 +356,11 @@ class Connection(ConnectionBase):
|
||||
|
||||
with open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb+') as out_file:
|
||||
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)
|
||||
out_file.write(base64.b64decode(result_read['return']['buf-b64']))
|
||||
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)
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
|
@@ -163,7 +163,8 @@ def run_module():
|
||||
action=dict(type='str', required=True),
|
||||
loglevel=dict(type='int', required=False, default=logging.INFO),
|
||||
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),
|
||||
kernel_dir=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?
|
||||
except Exception as e:
|
||||
result['message'] = str(e)
|
||||
e = traceback.print_exc()
|
||||
if e: result['original_message'] += f"{e}"
|
||||
module.fail_json(msg='Exception', **result)
|
||||
result['original_message'] = f"{traceback.print_exc()}"
|
||||
module.fail_json(msg=f'Exception {e.__class__}', **result)
|
||||
else:
|
||||
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_install_disklabel: msdos
|
||||
AGI_install_timezone: UTC
|
||||
AGI_install_timezone: "{{ BASE_TIMEZONE|default('Etc/UTC') }}"
|
||||
AGI_install_locales:
|
||||
- en_US ISO-8859-1
|
||||
- en_US.UTF-8 UTF-8
|
||||
@@ -28,9 +28,95 @@ AGI_install_network_interfaces:
|
||||
config: dhcp
|
||||
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_syslog_daemon: syslog-ng # app-admin/sysklogd
|
||||
AGI_install_cron_daemon: sys-process/cronie
|
||||
|
||||
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,25 +7,71 @@
|
||||
|
||||
- name: test we are in the chroot
|
||||
shell: |
|
||||
df | grep {{AGI_NBD_MP}} && exit 1
|
||||
df | grep {{AGI_install_disk}} && exit 1
|
||||
check_mode: false
|
||||
|
||||
- name: install grub
|
||||
- name: install grub or syslinx
|
||||
portage:
|
||||
package: sys-boot/grub:2
|
||||
package: sys-boot/{{AGI_install_bootloader}}
|
||||
state: installed
|
||||
|
||||
- name: install grub to MBR
|
||||
- block:
|
||||
|
||||
- name: setup syslinux
|
||||
shell: |
|
||||
[ -d /boot/syslinux ] || mkdir /boot/syslinux
|
||||
[ ! -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: setup syslinux.cfg
|
||||
template: |
|
||||
dest: /boot/syslinux/syslinux.cfg
|
||||
src: boot/syslinux/syslinux.cfg
|
||||
force: no
|
||||
newline_sequence: '\r\n'
|
||||
owner: root
|
||||
mode: '0644'
|
||||
|
||||
- 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
|
||||
- name: generate grub config
|
||||
shell: grub-mkconfig -o /boot/grub/grub.cfg
|
||||
args:
|
||||
creates: /boot/grub/grub.cfg
|
||||
|
||||
- name: edit grub config
|
||||
- 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=[^ ]*/ /' \
|
||||
@@ -36,29 +82,85 @@
|
||||
-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
|
||||
lineinfile:
|
||||
dest: /etc/fstab
|
||||
line: '{{AGI_container_disk}}3 / ext4 defaults,noatime 0 1'
|
||||
regexp: '^{{AGI_container_disk}}3'
|
||||
owner: root
|
||||
mode: '0644'
|
||||
|
||||
- name: fstab boot
|
||||
lineinfile:
|
||||
dest: /etc/fstab
|
||||
line: '{{AGI_container_disk}}1 /boot ext3 defaults,noatime 0 1'
|
||||
regexp: '^{{AGI_container_disk}}3'
|
||||
owner: root
|
||||
mode: '0644'
|
||||
|
||||
- name: fstab swap
|
||||
lineinfile:
|
||||
dest: /etc/fstab
|
||||
line: '{{AGI_container_disk}}2 none swap nofail,sw 0 0'
|
||||
regexp: '^{{AGI_container_disk}}2'
|
||||
owner: root
|
||||
mode: '0644'
|
||||
|
||||
- name: fstab shm
|
||||
lineinfile:
|
||||
dest: /etc/fstab
|
||||
line: 'tmpfs /run/shm tmpfs defaults,noexec,size=5% 0 0'
|
||||
regexp: '^tmpfs */run/shm'
|
||||
owner: root
|
||||
mode: '0644'
|
||||
|
||||
# linuxPen19 /mnt/linuxPen19 virtiofs defaults,dirsync 0 0
|
||||
|
||||
@@ -67,42 +169,54 @@
|
||||
dest: /etc/security/passwdqc.conf
|
||||
line: 'enforce=none'
|
||||
regexp: '^enforce=.*'
|
||||
owner: root
|
||||
mode: '0644'
|
||||
|
||||
- name: /etc/security/passwdqc.conf
|
||||
lineinfile:
|
||||
dest: /etc/security/passwdqc.conf
|
||||
line: 'enforce=none'
|
||||
regexp: '^enforce=.*'
|
||||
owner: root
|
||||
mode: '0644'
|
||||
|
||||
- name: /etc/conf.d/consolefont
|
||||
lineinfile:
|
||||
dest: /etc/conf.d/consolefont
|
||||
line: 'consolefont="ter-v{{AGI_consolefont_font_size}}b"'
|
||||
regexp: '^consolefont=.*'
|
||||
|
||||
- name: roles/ansible-gentoo_install/tasks/
|
||||
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
|
||||
owner: root
|
||||
mode: '0644'
|
||||
|
||||
- name: consolefont
|
||||
shell: |
|
||||
rc-update add consolefont
|
||||
grep -q /etc/init.d/consolefont /etc/rc.local || \
|
||||
cat >> /etc/rc.local << EOF
|
||||
#!/bin/sh
|
||||
/etc/init.d consolefont stop
|
||||
/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
|
||||
bash /etc/rc.local
|
||||
chmod 755 /etc/rc.local
|
||||
ignore_errors: true
|
||||
|
||||
- name: rc-update add bootlogd boot
|
||||
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 add bootlogd boot
|
||||
grep -q '^s0:' /etc/inittab || \
|
||||
sed -e 's/^#s0:/s0:/' /etc/inittab
|
||||
|
||||
|
||||
exit 0
|
||||
|
||||
|
@@ -18,9 +18,11 @@
|
||||
|
||||
- name: copy resolv.conf into chroot
|
||||
copy:
|
||||
src: /etc/resolv.conf
|
||||
dest: "{{AGI_NBD_MP}}/etc/resolv.conf"
|
||||
src: "/{{item}}"
|
||||
dest: "{{AGI_NBD_MP}}/{{item}}"
|
||||
mode: '0644'
|
||||
remote_src: yes
|
||||
with_items: "{{AGI_bootstrap_files}}"
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: mount /proc in chroot
|
||||
|
@@ -39,12 +39,12 @@
|
||||
- name: copy kernel sources
|
||||
copy:
|
||||
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
|
||||
creates: "{{AGI_NBD_MP}}/usr/src/{{kernel_out.stdout}}"
|
||||
when:
|
||||
- kernel_out.rc|default(1) == 0
|
||||
- AGI_use_local_kernel
|
||||
- false
|
||||
|
||||
- name: resolve kver
|
||||
shell: |
|
||||
@@ -99,6 +99,8 @@
|
||||
when:
|
||||
- AGI_use_local_kernel
|
||||
- ramfs_out.rc|default(1) == 0
|
||||
- false
|
||||
ignore_errors: true
|
||||
|
||||
- name: make directories
|
||||
shell: |
|
||||
@@ -111,6 +113,6 @@
|
||||
[ -f "{{AGI_NBD_MP}}/$file" ] && continue
|
||||
cp -np "$file" "{{AGI_NBD_MP}}/$file"
|
||||
done
|
||||
ignore_errors: false
|
||||
ignore_errors: true
|
||||
|
||||
# dracut
|
||||
|
@@ -16,7 +16,15 @@
|
||||
[ -d "{{AGI_GENTOO_FROM_MP}}" ] || exit 5
|
||||
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:
|
||||
# old code
|
||||
|
||||
- name: create disklabel
|
||||
command: parted -s {{ AGI_install_disk }} mklabel {{ AGI_install_disklabel }}
|
||||
@@ -44,7 +52,7 @@
|
||||
# able to install to the MBR
|
||||
- name: create boot partition
|
||||
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:
|
||||
creates: "{{ AGI_install_disk }}p1"
|
||||
|
||||
@@ -65,7 +73,7 @@
|
||||
creates: "{{ AGI_install_disk }}p3"
|
||||
|
||||
- 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
|
||||
when: not ansible_check_mode
|
||||
|
||||
@@ -85,7 +93,15 @@
|
||||
e2label {{ AGI_install_disk }}p3 root
|
||||
e2label {{ AGI_install_disk }}p1 boot
|
||||
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
|
||||
|
||||
@@ -100,15 +116,29 @@
|
||||
unit: sectors
|
||||
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 }}p3 : start= 4917248, size= 37025792, type=83
|
||||
EOF
|
||||
partprobe
|
||||
|
||||
- name: format disk partitions grub:2
|
||||
shell: |
|
||||
mke2fs -L boot {{ AGI_install_disk }}p1
|
||||
mke2fs -L root {{ AGI_install_disk }}p3
|
||||
mkswap -L swap "{{ AGI_install_disk }}p2"
|
||||
sync
|
||||
|
||||
when: true
|
||||
when: AGI_install_bootloader != 'syslinux'
|
||||
|
||||
- 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
|
||||
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
|
||||
grep '/dev/{{AGI_NBD_DEV}}p3' /proc/mounts && exit 0
|
||||
if [ ! -f "{{BOX_NBD_BASE_QCOW}}" ] ; then
|
||||
echo ERROR: not created BOX_NBD_DEV="{{BOX_NBD_DEV}}" - use
|
||||
echo qemu-img create -f qcow2 "{{BOX_NBD_BASE_QCOW}}" 20G
|
||||
exit 1
|
||||
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
|
||||
changed_when: false
|
||||
register: check_mounted_disk
|
||||
@@ -45,15 +52,15 @@
|
||||
|
||||
- name: partition if disk not mounted
|
||||
fail:
|
||||
msg: "looks like theres an active nbd mount of {{BOX_NBD_BASE_QCOW}}"
|
||||
msg: "make and nbd mount {{BOX_NBD_BASE_QCOW}}"
|
||||
when:
|
||||
- check_mounted_disk.rc == 1
|
||||
- check_mounted_disk.rc in [2, 1]
|
||||
check_mode: no
|
||||
|
||||
- name: partition if disk not mounted or active
|
||||
include: disk.yml
|
||||
when:
|
||||
- check_mounted_disk.rc > 1
|
||||
- check_mounted_disk.rc > 2
|
||||
check_mode: no
|
||||
|
||||
- name: mount root partition
|
||||
@@ -78,6 +85,7 @@
|
||||
state: mounted
|
||||
check_mode: false
|
||||
|
||||
- include: libvirt.yml
|
||||
- include: tarball.yml
|
||||
- include: copy.yml
|
||||
when: AGI_use_local_kernel
|
||||
@@ -136,7 +144,7 @@
|
||||
|
||||
check_mode: false
|
||||
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:
|
||||
- debug:
|
||||
msg: "ERROR: error during chroot execution"
|
||||
|
@@ -52,6 +52,8 @@
|
||||
fi
|
||||
if ! grep -q "{{BOX_NBD_DEV}}" /proc/partitions ; then
|
||||
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
|
||||
fi
|
||||
exit 0
|
||||
@@ -71,19 +73,27 @@
|
||||
fi
|
||||
fi
|
||||
# should operate on json with jq
|
||||
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
|
||||
if [ -f "$tofile" ] ; then
|
||||
sed -i -e 's@"partition": ".*"@"partition": 3@' $tofile
|
||||
# but this is crucial
|
||||
# "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
|
||||
fi
|
||||
|
||||
@@ -103,7 +113,8 @@
|
||||
action: status
|
||||
loglevel: "{{BOX_NBD_LOGLEVEL}}"
|
||||
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}}"
|
||||
kernel_dir: "{{BOX_NBD_KERNEL_DIR}}"
|
||||
portage: "{{BOX_NBD_PORTAGE_FILE}}"
|
||||
@@ -118,15 +129,11 @@
|
||||
debug:
|
||||
verbosity: 0
|
||||
var: ansible_gentooimgr_out
|
||||
|
||||
check_mode: false
|
||||
when:
|
||||
- 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
|
||||
- name: include_tasks local.yml
|
||||
include_tasks: local.yml
|
||||
|
||||
when:
|
||||
- ansible_connection in ['chroot', 'local']
|
||||
- ansible_distribution == 'Gentoo' or BOX_GENTOO_FROM_MP not in ['/', '']
|
||||
|
@@ -15,6 +15,11 @@
|
||||
for elt in {{ AGI_bootstrap_mountpoints|join(' ') }} ; do
|
||||
[ -d $elt ] || mkdir $elt
|
||||
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
|
||||
when: AGI_bootstrap_mountpoints|default([])|length > 0
|
||||
|
||||
@@ -32,7 +37,7 @@
|
||||
dest: /etc/localtime
|
||||
src: /usr/share/zoneinfo/{{ AGI_install_timezone }}
|
||||
state: link
|
||||
force: yes
|
||||
force: no
|
||||
|
||||
- name: configure locales
|
||||
lineinfile:
|
||||
@@ -86,6 +91,13 @@
|
||||
user:
|
||||
name: gentoo
|
||||
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
|
||||
lineinfile:
|
||||
@@ -96,6 +108,13 @@
|
||||
owner: root
|
||||
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:
|
||||
|
||||
- name: make symlinks
|
||||
|
@@ -5,11 +5,6 @@
|
||||
verbosity: 1
|
||||
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
|
||||
shell: |
|
||||
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) }}"
|
||||
USE: "-X verify-sig"
|
||||
CFLAGS: "-march=native -O2 -pipe"
|
||||
|
||||
AGI_install_portage_conf_files:
|
||||
'package.accept_keywords': |
|
||||
=sys-kernel/genkernel-4.3* ~amd64
|
||||
@@ -26,6 +27,9 @@ AGI_bootstrap_links:
|
||||
- from: /var/db/repos/gentoo
|
||||
to: /usr/portage
|
||||
|
||||
AGI_bootstrap_modules:
|
||||
- virtio_console
|
||||
|
||||
# NO LEADING /
|
||||
AGI_bootstrap_dirs:
|
||||
- usr/local/etc/local.d
|
||||
@@ -41,11 +45,15 @@ AGI_bootstrap_dirs:
|
||||
- etc/portage/repos.conf
|
||||
- etc/portage/savedconfig
|
||||
- etc/portage/sets
|
||||
- usr/local/tmp/bootstrap/logs
|
||||
- usr/local/tmp/bootstrap/distfiles
|
||||
|
||||
AGI_bootstrap_files:
|
||||
- usr/local/etc/local.d/local.bash
|
||||
- usr/local/bin/usr_local_tput.bash
|
||||
- usr/local/bin/proxy_export.bash
|
||||
- etc/hosts
|
||||
- etc/resolv.conf
|
||||
|
||||
AGI_bootstrap_uris:
|
||||
- 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/fc/qemu-8.0.3.tar.xz
|
||||
|
||||
AGI_bootstrap_pips3:
|
||||
- negotiator-guest
|
||||
|
||||
# proxy_pkgs_inst:
|
||||
AGI_bootstrap_pkgs:
|
||||
- app-admin/sudo
|
||||
- sys-boot/grub:2
|
||||
- sys-boot/syslinux
|
||||
- app-editors/mg
|
||||
- qemu-guest-agent
|
||||
- app-admin/logrotate
|
||||
- "{{ AGI_install_cron_daemon }}"
|
||||
- "{{AGI_install_syslog_daemon}}"
|
||||
- media-fonts/terminus-font
|
||||
- sys-apps/gptfdisk
|
||||
- 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
|
||||
- dev-util/strace
|
||||
- sys-libs/gpm
|
||||
- app-portage/eix
|
||||
- www-client/lynx
|
||||
- sys-libs/gpm
|
||||
- linux-firmware
|
||||
- net-dns/bind-tools
|
||||
# - www-client/lynx
|
||||
- app-admin/supervisor
|
||||
- dev-python/pip
|
||||
|
||||
AGI_cloud_pkgs:
|
||||
# get these from base.json
|
||||
@@ -83,12 +103,10 @@ AGI_cloud_pkgs:
|
||||
- tmux
|
||||
- app-misc/screen
|
||||
- dev-vcs/git
|
||||
- net-misc/curl
|
||||
- usbutils
|
||||
- pciutils
|
||||
- net-misc/ntp
|
||||
- net-fs/nfs-utils
|
||||
# get these from config.json
|
||||
- app-emulation/cloud-init
|
||||
- sys-block/open-iscsi
|
||||
|
||||
# - app-emulation/cloud-init
|
||||
# - 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
|
||||
|
||||
update::
|
||||
test:: local # hourly
|
||||
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