From 29a148d211fa0698cb4e97c96cd94500a833b418 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 1 Jul 2021 15:32:07 -0700 Subject: [PATCH] Successfully set up reverse ssh forward system, allowing the host to run commands on the guest over ssh --- dangerzone-converter/Dockerfile | 132 ++++++++++---------- dangerzone/gui/__init__.py | 8 +- dangerzone/gui/vm.py | 136 ++++++++++++++++----- dangerzone/gui/waiting_widget.py | 21 +--- install/vm-builder/README.md | 46 +------ install/vm-builder/etc/apk/world | 7 +- install/vm-builder/etc/init.d/dangerzone | 2 +- install/vm-builder/etc/ssh-to-host.py | 25 ++-- install/vm-builder/etc/ssh/sshd_config | 7 -- install/vm-builder/genapkovl-dangerzone.sh | 4 +- install/vm-builder/mkimg.dangerzone.sh | 2 +- install/vm-builder/run-vm.sh | 61 ++++++++- poetry.lock | 43 ++++++- pyproject.toml | 1 + 14 files changed, 306 insertions(+), 189 deletions(-) delete mode 100644 install/vm-builder/etc/ssh/sshd_config diff --git a/dangerzone-converter/Dockerfile b/dangerzone-converter/Dockerfile index a11f6be..240c98b 100644 --- a/dangerzone-converter/Dockerfile +++ b/dangerzone-converter/Dockerfile @@ -10,72 +10,72 @@ RUN apk -U upgrade && \ poppler-utils \ py3-magic \ py3-pillow \ - sudo -# tesseract-ocr \ -# tesseract-ocr-data-afr \ -# tesseract-ocr-data-ara \ -# tesseract-ocr-data-aze \ -# tesseract-ocr-data-bel \ -# tesseract-ocr-data-ben \ -# tesseract-ocr-data-bul \ -# tesseract-ocr-data-cat \ -# tesseract-ocr-data-ces \ -# tesseract-ocr-data-chi_sim \ -# tesseract-ocr-data-chi_tra \ -# tesseract-ocr-data-chr \ -# tesseract-ocr-data-dan \ -# tesseract-ocr-data-deu \ -# tesseract-ocr-data-ell \ -# tesseract-ocr-data-enm \ -# tesseract-ocr-data-epo \ -# tesseract-ocr-data-equ \ -# tesseract-ocr-data-est \ -# tesseract-ocr-data-eus \ -# tesseract-ocr-data-fin \ -# tesseract-ocr-data-fra \ -# tesseract-ocr-data-frk \ -# tesseract-ocr-data-frm \ -# tesseract-ocr-data-glg \ -# tesseract-ocr-data-grc \ -# tesseract-ocr-data-heb \ -# tesseract-ocr-data-hin \ -# tesseract-ocr-data-hrv \ -# tesseract-ocr-data-hun \ -# tesseract-ocr-data-ind \ -# tesseract-ocr-data-isl \ -# tesseract-ocr-data-ita \ -# tesseract-ocr-data-ita_old \ -# tesseract-ocr-data-jpn \ -# tesseract-ocr-data-kan \ -# tesseract-ocr-data-kat \ -# tesseract-ocr-data-kor \ -# tesseract-ocr-data-lav \ -# tesseract-ocr-data-lit \ -# tesseract-ocr-data-mal \ -# tesseract-ocr-data-mkd \ -# tesseract-ocr-data-mlt \ -# tesseract-ocr-data-msa \ -# tesseract-ocr-data-nld \ -# tesseract-ocr-data-nor \ -# tesseract-ocr-data-pol \ -# tesseract-ocr-data-por \ -# tesseract-ocr-data-ron \ -# tesseract-ocr-data-rus \ -# tesseract-ocr-data-slk \ -# tesseract-ocr-data-slv \ -# tesseract-ocr-data-spa \ -# tesseract-ocr-data-spa_old \ -# tesseract-ocr-data-sqi \ -# tesseract-ocr-data-srp \ -# tesseract-ocr-data-swa \ -# tesseract-ocr-data-swe \ -# tesseract-ocr-data-tam \ -# tesseract-ocr-data-tel \ -# tesseract-ocr-data-tgl \ -# tesseract-ocr-data-tha \ -# tesseract-ocr-data-tur \ -# tesseract-ocr-data-ukr \ -# tesseract-ocr-data-vie + sudo \ + tesseract-ocr \ + tesseract-ocr-data-afr \ + tesseract-ocr-data-ara \ + tesseract-ocr-data-aze \ + tesseract-ocr-data-bel \ + tesseract-ocr-data-ben \ + tesseract-ocr-data-bul \ + tesseract-ocr-data-cat \ + tesseract-ocr-data-ces \ + tesseract-ocr-data-chi_sim \ + tesseract-ocr-data-chi_tra \ + tesseract-ocr-data-chr \ + tesseract-ocr-data-dan \ + tesseract-ocr-data-deu \ + tesseract-ocr-data-ell \ + tesseract-ocr-data-enm \ + tesseract-ocr-data-epo \ + tesseract-ocr-data-equ \ + tesseract-ocr-data-est \ + tesseract-ocr-data-eus \ + tesseract-ocr-data-fin \ + tesseract-ocr-data-fra \ + tesseract-ocr-data-frk \ + tesseract-ocr-data-frm \ + tesseract-ocr-data-glg \ + tesseract-ocr-data-grc \ + tesseract-ocr-data-heb \ + tesseract-ocr-data-hin \ + tesseract-ocr-data-hrv \ + tesseract-ocr-data-hun \ + tesseract-ocr-data-ind \ + tesseract-ocr-data-isl \ + tesseract-ocr-data-ita \ + tesseract-ocr-data-ita_old \ + tesseract-ocr-data-jpn \ + tesseract-ocr-data-kan \ + tesseract-ocr-data-kat \ + tesseract-ocr-data-kor \ + tesseract-ocr-data-lav \ + tesseract-ocr-data-lit \ + tesseract-ocr-data-mal \ + tesseract-ocr-data-mkd \ + tesseract-ocr-data-mlt \ + tesseract-ocr-data-msa \ + tesseract-ocr-data-nld \ + tesseract-ocr-data-nor \ + tesseract-ocr-data-pol \ + tesseract-ocr-data-por \ + tesseract-ocr-data-ron \ + tesseract-ocr-data-rus \ + tesseract-ocr-data-slk \ + tesseract-ocr-data-slv \ + tesseract-ocr-data-spa \ + tesseract-ocr-data-spa_old \ + tesseract-ocr-data-sqi \ + tesseract-ocr-data-srp \ + tesseract-ocr-data-swa \ + tesseract-ocr-data-swe \ + tesseract-ocr-data-tam \ + tesseract-ocr-data-tel \ + tesseract-ocr-data-tgl \ + tesseract-ocr-data-tha \ + tesseract-ocr-data-tur \ + tesseract-ocr-data-ukr \ + tesseract-ocr-data-vie # Install pdftk RUN \ diff --git a/dangerzone/gui/__init__.py b/dangerzone/gui/__init__.py index 4923172..1714919 100644 --- a/dangerzone/gui/__init__.py +++ b/dangerzone/gui/__init__.py @@ -170,4 +170,10 @@ def gui_main(custom_container, filename): # If the application is activated and all windows are closed, open a new one app_wrapper.application_activated.connect(application_activated) - sys.exit(app.exec_()) + # Launch the GUI + ret = app.exec_() + + if vm: + vm.stop() + + sys.exit(ret) diff --git a/dangerzone/gui/vm.py b/dangerzone/gui/vm.py index b7c1ce1..ac28567 100644 --- a/dangerzone/gui/vm.py +++ b/dangerzone/gui/vm.py @@ -8,6 +8,8 @@ import socket import random import getpass import json +import psutil +import time from PySide2 import QtCore @@ -15,6 +17,7 @@ class Vm(QtCore.QObject): STATE_OFF = 0 STATE_STARTING = 1 STATE_ON = 2 + STATE_FAIL = 3 vm_state_change = QtCore.Signal(int) @@ -25,9 +28,14 @@ class Vm(QtCore.QObject): # VM starts off self.state = self.STATE_OFF + # Ports for ssh services + self.sshd_port = None + self.sshd_tunnel_port = None + # Processes self.vpnkit_p = None self.hyperkit_p = None + self.sshd_pid = None # Relevant paths self.vpnkit_path = self.global_common.get_resource_path("bin/vpnkit") @@ -50,6 +58,8 @@ class Vm(QtCore.QObject): self.ssh_client_pubkey_path = os.path.join( self.state_dir.name, "client_ed25519.pub" ) + self.sshd_pid_path = os.path.join(self.state_dir.name, "sshd.pid") + self.sshd_log_path = os.path.join(self.state_dir.name, "sshd.log") self.vm_disk_img_path = os.path.join(self.state_dir.name, "disk.img") # UDID for VM @@ -58,6 +68,12 @@ class Vm(QtCore.QObject): "earlyprintk=serial console=ttyS0 modules=loop,squashfs,sd-mod" ) + # Threads + self.wait_t = None + + def __del__(self): + self.stop() + def start(self): self.state = self.STATE_STARTING self.vm_state_change.emit(self.state) @@ -105,35 +121,39 @@ class Vm(QtCore.QObject): ssh_client_pubkey = f.read() # Find an open port - sshd_port = self.find_open_port() - sshd_tunnel_port = self.find_open_port() + self.sshd_port = self.find_open_port() + self.sshd_tunnel_port = self.find_open_port() # Start an sshd service on this port - subprocess.run( - [ - "/usr/sbin/sshd", - "-4", - "-o", - f"HostKey={self.ssh_host_key_path}", - "-o", - f"ListenAddress=127.0.0.1:{sshd_port}", - "-o", - f"AllowUsers={getpass.getuser()}", - "-o", - "PasswordAuthentication=no", - "-o", - "PubkeyAuthentication=yes", - "-o", - "Compression=yes", - "-o", - "ForceCommand=/usr/bin/whoami", - "-o", - "UseDNS=no", - "-o", - f"AuthorizedKeysFile={self.ssh_client_pubkey_path}", - ] - ) - # TODO: keep track of the sshd process so we can kill it on close + args = [ + "/usr/sbin/sshd", + "-4", + "-E", + self.sshd_log_path, + "-o", + f"PidFile={self.sshd_pid_path}", + "-o", + f"HostKey={self.ssh_host_key_path}", + "-o", + f"ListenAddress=127.0.0.1:{self.sshd_port}", + "-o", + f"AllowUsers={getpass.getuser()}", + "-o", + "PasswordAuthentication=no", + "-o", + "PubkeyAuthentication=yes", + "-o", + "Compression=yes", + "-o", + "ForceCommand=/usr/bin/whoami", + "-o", + "UseDNS=no", + "-o", + f"AuthorizedKeysFile={self.ssh_client_pubkey_path}", + ] + args_str = " ".join(pipes.quote(s) for s in args) + print("> " + args_str) + subprocess.run(args) # Create a JSON object to pass into the VM # This is a 512kb file that starts with a JSON object, followed by null bytes @@ -142,8 +162,8 @@ class Vm(QtCore.QObject): "id_ed25519.pub": ssh_client_pubkey, "user": getpass.getuser(), "ip": "192.168.65.2", - "port": sshd_port, - "tunnel_port": sshd_tunnel_port, + "port": self.sshd_port, + "tunnel_port": self.sshd_tunnel_port, } with open(self.vm_disk_img_path, "wb") as f: vm_info_bytes = json.dumps(vm_info).encode() @@ -200,16 +220,39 @@ class Vm(QtCore.QObject): print("> " + args_str) self.hyperkit_p = subprocess.Popen( args, - stdout=sys.stdout, - stderr=subprocess.STDOUT, + # stdout=sys.stdout, + # stderr=subprocess.STDOUT, ) + # Get the sshd PID + with open(self.sshd_pid_path) as f: + self.sshd_pid = int(f.read()) + + print(f"sshd PID: {self.sshd_pid}") + print(f"vpnkit PID: {self.vpnkit_p.pid}") + print(f"hyperkit PID: {self.hyperkit_p.pid}") + + # Wait for SSH thread + self.wait_t = WaitForSsh(self.sshd_tunnel_port) + self.wait_t.connected.connect(self.vm_connected) + self.wait_t.timeout.connect(self.vm_timeout) + self.wait_t.start() + + def vm_connected(self): + self.state = self.STATE_ON + self.vm_state_change.emit() + + def vm_timeout(self): + self.state = self.STATE_FAIL + self.vm_state_change.emit() + def restart(self): self.stop() self.start() def stop(self): # Kill existing processes + self.kill_sshd() if self.vpnkit_p is not None: self.vpnkit_p.terminate() self.vpnkit_p = None @@ -228,3 +271,34 @@ class Vm(QtCore.QObject): _, port = tmpsock.getsockname() return port + + def kill_sshd(self): + if self.sshd_pid and psutil.pid_exists(self.sshd_pid): + try: + proc = psutil.Process(self.sshd_pid) + proc.kill() + except Exception: + pass + + self.sshd_pid = None + + +class WaitForSsh(QtCore.QThread): + connected = QtCore.Signal() + timeout = QtCore.Signal() + + def __init__(self, ssh_port): + super(WaitForSsh, self).__init__() + self.ssh_port = ssh_port + + def run(self): + # Wait for the SSH port to be open + timeout_seconds = 45 + sock = socket.socket() + sock.settimeout(timeout_seconds) + try: + sock.connect(("127.0.0.1", int(self.ssh_port))) + self.connected.emit() + sock.close() + except socket.timeout: + self.timeout.emit() diff --git a/dangerzone/gui/waiting_widget.py b/dangerzone/gui/waiting_widget.py index 10153c5..dc0884e 100644 --- a/dangerzone/gui/waiting_widget.py +++ b/dangerzone/gui/waiting_widget.py @@ -17,32 +17,15 @@ class WaitingWidget(QtWidgets.QWidget): self.label.setAlignment(QtCore.Qt.AlignCenter) self.label.setStyleSheet("QLabel { font-size: 20px; }") - self.details = QtWidgets.QLabel() - self.details.setStyleSheet( - "QLabel { background-color: #ffffff; font-size: 12px; padding: 10px; }" - ) - self.details.setFont(self.gui_common.fixed_font) - self.details.setAlignment(QtCore.Qt.AlignTop) - - self.details_scrollarea = QtWidgets.QScrollArea() - self.details_scrollarea.setMinimumHeight(200) - self.details_scrollarea.setWidgetResizable(True) - self.details_scrollarea.setWidget(self.details) - self.details_scrollarea.verticalScrollBar().rangeChanged.connect( - self.scroll_to_bottom - ) - # Layout layout = QtWidgets.QVBoxLayout() layout.addStretch() layout.addWidget(self.label) - layout.addWidget(self.details_scrollarea) layout.addStretch() self.setLayout(layout) def vm_state_change(self, state): if state == self.vm.STATE_ON: self.vm_started.emit() - - def scroll_to_bottom(self, minimum, maximum): - self.scrollarea.verticalScrollBar().setValue(maximum) + elif state == self.vm.STATE_FAIL: + self.label.setText("Dangerzone virtual machine failed to start :(") diff --git a/install/vm-builder/README.md b/install/vm-builder/README.md index 9d9653e..6e7329a 100644 --- a/install/vm-builder/README.md +++ b/install/vm-builder/README.md @@ -14,54 +14,10 @@ This takes awhile to run. It: - Builds a new `dangerzone-converter` docker image - Builds an ISO, which includes a copy of this image -- Outputs the ISO, as well as vmlinuz and initramfs files, in the `vm` folder +- Outputs files in the `vm` folder ## Run the VM ```sh ./run-vm.sh ``` - -You can ssh in as the unprivileged user like this (you need to `brew install socat`): - -```sh -ssh -i ./ssh-key/id_ed25519 \ - -o LogLevel=FATAL \ - -o Compression=yes \ - -o IdentitiesOnly=yes \ - -o StrictHostKeyChecking=no \ - -o UserKnownHostsFile=/dev/null \ - -o "ProxyCommand nc -U /Users/user/code/dangerzone/rip_docker/vm/connect" \ - -v \ - user@localhost -``` - -(doesn't work yet) - - -Notes on sshd: - -``` -# Generate keys -rm -r state -mkdir state -ssh-keygen -t ed25519 -C dangerzone-vm-key -N "" -f state/host_ed25519 -ssh-keygen -t ed25519 -C dangerzone-vm-key -N "" -f state/client_ed25519 - -# start sshd service -/usr/sbin/sshd -4 \ - -o HostKey=$(pwd)/state/host_ed25519 \ - -o ListenAddress=127.0.0.1:4444 \ - -o AllowUsers=$(whoami) \ - -o PasswordAuthentication=no \ - -o PubkeyAuthentication=yes \ - -o Compression=yes \ - -o ForceCommand=/usr/bin/whoami \ - -o UseDNS=no \ - -o AuthorizedKeysFile=$(pwd)/state/client_ed25519.pub - -# in the vm, making an ssh tunnel - - ssh -o StrictHostKeyChecking=no -N -R 52038:127.0.0.1:22 -p 52039 user@192.168.65.2 - -``` \ No newline at end of file diff --git a/install/vm-builder/etc/apk/world b/install/vm-builder/etc/apk/world index bfa3c1e..1cabf13 100644 --- a/install/vm-builder/etc/apk/world +++ b/install/vm-builder/etc/apk/world @@ -1,3 +1,6 @@ alpine-base -openssh -podman \ No newline at end of file +podman +dropbear +sshfs +python3 +sudo \ No newline at end of file diff --git a/install/vm-builder/etc/init.d/dangerzone b/install/vm-builder/etc/init.d/dangerzone index 68e918d..682d9e4 100755 --- a/install/vm-builder/etc/init.d/dangerzone +++ b/install/vm-builder/etc/init.d/dangerzone @@ -1,6 +1,6 @@ #!/sbin/openrc-run name="Dangerzone init script" -start_pre() { +start() { # Setup Alpine /sbin/setup-alpine -f /etc/answers.txt -e -q rm /etc/answers.txt diff --git a/install/vm-builder/etc/ssh-to-host.py b/install/vm-builder/etc/ssh-to-host.py index 9fd862b..05fb829 100755 --- a/install/vm-builder/etc/ssh-to-host.py +++ b/install/vm-builder/etc/ssh-to-host.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 import os import json -import stat import subprocess +import shutil def main(): @@ -17,25 +17,36 @@ def main(): info = json.loads(s[0 : s.find(b"\0")]) # Create SSH files - os.makedirs("/home/user/.ssh", mode=0o700, exist_ok=True) - perms = stat.S_IRUSR | stat.S_IWUSR + os.makedirs("/home/user/.ssh", exist_ok=True) with open("/home/user/.ssh/id_ed25519", "w") as f: f.write(info["id_ed25519"]) + f.write("\n") with open("/home/user/.ssh/id_ed25519.pub", "w") as f: f.write(info["id_ed25519.pub"]) + f.write("\n") with open("/home/user/.ssh/authorized_keys", "w") as f: f.write(info["id_ed25519.pub"]) + f.write("\n") - os.chmod("/home/user/.ssh/id_ed25519", perms) - os.chmod("/home/user/.ssh/id_ed25519.pub", perms) - os.chmod("/home/user/.ssh/authorized_keys", perms) + os.chmod("/home/user/.ssh", 0o700) + os.chmod("/home/user/.ssh/id_ed25519", 0o600) + os.chmod("/home/user/.ssh/id_ed25519.pub", 0o644) + os.chmod("/home/user/.ssh/authorized_keys", 0o600) + + shutil.chown("/home/user/.ssh", "user", "user") + shutil.chown("/home/user/.ssh/id_ed25519", "user", "user") + shutil.chown("/home/user/.ssh/id_ed25519.pub", "user", "user") + shutil.chown("/home/user/.ssh/authorized_keys", "user", "user") # Start SSH reverse port forward subprocess.run( [ + "/usr/bin/sudo", + "-u", + "user", "/usr/bin/ssh", "-o", "StrictHostKeyChecking=no", @@ -45,7 +56,7 @@ def main(): "-R", f"{info['tunnel_port']}:127.0.0.1:22", "-p", - info["port"], + str(info["port"]), f"{info['user']}@{info['ip']}", ] ) diff --git a/install/vm-builder/etc/ssh/sshd_config b/install/vm-builder/etc/ssh/sshd_config deleted file mode 100644 index 19b5c55..0000000 --- a/install/vm-builder/etc/ssh/sshd_config +++ /dev/null @@ -1,7 +0,0 @@ -AuthorizedKeysFile .ssh/authorized_keys -AllowTcpForwarding no -GatewayPorts no -X11Forwarding no -Subsystem sftp /usr/lib/ssh/sftp-server -UseDNS no -PasswordAuthentication no \ No newline at end of file diff --git a/install/vm-builder/genapkovl-dangerzone.sh b/install/vm-builder/genapkovl-dangerzone.sh index d07040e..6455263 100644 --- a/install/vm-builder/genapkovl-dangerzone.sh +++ b/install/vm-builder/genapkovl-dangerzone.sh @@ -31,8 +31,8 @@ cp -r /home/user/.local/share/containers "$tmp"/etc/container-data # Start cgroups, required by podman rc_add cgroups boot -# Start sshd -rc_add sshd boot +# Start dropbear (ssh server) +rc_add dropbear boot # Run setup-alpine rc_add dangerzone boot diff --git a/install/vm-builder/mkimg.dangerzone.sh b/install/vm-builder/mkimg.dangerzone.sh index b3bed50..ddf9d94 100644 --- a/install/vm-builder/mkimg.dangerzone.sh +++ b/install/vm-builder/mkimg.dangerzone.sh @@ -9,5 +9,5 @@ profile_dangerzone() { kernel_cmdline="console=tty0 console=ttyS0,115200" syslinux_serial="0 115200" apkovl="genapkovl-dangerzone.sh" - apks="$apks podman openssh sshfs python3" + apks="$apks podman dropbear sshfs python3 sudo" } diff --git a/install/vm-builder/run-vm.sh b/install/vm-builder/run-vm.sh index c0d76db..fe4602c 100755 --- a/install/vm-builder/run-vm.sh +++ b/install/vm-builder/run-vm.sh @@ -4,20 +4,69 @@ ROOT=$(pwd)/vm HYPERKIT=/Applications/Docker.app/Contents/Resources/bin/com.docker.hyperkit VPNKIT=/Applications/Docker.app/Contents/Resources/bin/com.docker.vpnkit +SSHD_PORT=4445 +SSHD_TUNNEL_PORT=4446 + +tmp="$(mktemp -d)" +trap rm -rf "$tmp" EXIT + +# make ssh keys +/usr/bin/ssh-keygen \ + -t ed25519 \ + -C dangerzone-host \ + -N "" \ + -f "$tmp/host_ed25519" +/usr/bin/ssh-keygen \ + -t ed25519 \ + -C dangerzone-client \ + -N "" \ + -f "$tmp/client_ed25519" + +# run sshd +SSHD_PIDFILE=$ROOT/sshd.pid +/usr/sbin/sshd \ + -4 \ + -E $ROOT/sshd.log \ + -o PidFile=$ROOT/sshd.pid \ + -o HostKey=$tmp/host_ed25519 \ + -o ListenAddress=127.0.0.1:$SSHD_PORT \ + -o AllowUsers=$(whoami) \ + -o PasswordAuthentication=no \ + -o PubkeyAuthentication=yes \ + -o Compression=yes \ + -o ForceCommand=/usr/bin/whoami \ + -o UseDNS=no \ + -o AuthorizedKeysFile=$tmp/client_ed25519.pub & +echo $! > $SSHD_PIDFILE +trap 'test -f $SSHD_PIDFILE && kill `cat $SSHD_PIDFILE` && rm $SSHD_PIDFILE' EXIT + +# create disk image +cd $ROOT +cat > info.json << EOF +{ + "id_ed25519": "$(cat $tmp/client_ed25519 | awk '{printf "%s\\n", $0}')", + "id_ed25519.pub": "$(cat $tmp/client_ed25519.pub)", + "user": "$(whoami)", + "ip": "192.168.65.2", + "port": $SSHD_PORT, + "tunnel_port": $SSHD_TUNNEL_PORT +} +EOF +python3 -c 's=open("info.json").read(); open("disk.img", "wb").write(s.encode()+b"\x00"*(512*1024-len(s)))' + +# run vpnkit VPNKIT_SOCK=$ROOT/vpnkit.eth.sock -PIDFILE=$ROOT/vpnkit.pid +VPNKIT_PIDFILE=$ROOT/vpnkit.pid $VPNKIT \ --ethernet=$VPNKIT_SOCK \ --gateway-ip 192.168.65.1 \ --host-ip 192.168.65.2 \ --lowest-ip 192.168.65.3 \ --highest-ip 192.168.65.254 & -echo $! > $PIDFILE -trap 'test -f $PIDFILE && kill `cat $PIDFILE` && rm $PIDFILE' EXIT - -cd $ROOT -python3 -c 's="this is a test"; open("disk.img", "wb").write(s.encode()+b"\x00"*(512*1024-len(s)))' +echo $! > $VPNKIT_PIDFILE +trap 'test -f $VPNKIT_PIDFILE && kill `cat $VPNKIT_PIDFILE` && rm $VPNKIT_PIDFILE' EXIT +# run hyperkit $HYPERKIT \ -F $ROOT/hyperkit.pid \ -A -u \ diff --git a/poetry.lock b/poetry.lock index 4613f75..3bd3c96 100644 --- a/poetry.lock +++ b/poetry.lock @@ -144,6 +144,17 @@ python-versions = ">=3.6.0" [package.dependencies] future = "*" +[[package]] +name = "psutil" +version = "5.8.0" +description = "Cross-platform lib for process and system monitoring in Python." +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] + [[package]] name = "pyinstaller" version = "4.3" @@ -382,7 +393,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = ">=3.7,<3.10" -content-hash = "6db74c36125b2d3ad4d04c864c24ecbcf376d5ac75ee7402d950010cade5de96" +content-hash = "234d09a8607647ed536d6737a98bdacc9d6296d6f71e1382b9d97342de1911e5" [metadata.files] altgraph = [ @@ -439,6 +450,36 @@ pathspec = [ pefile = [ {file = "pefile-2021.5.24.tar.gz", hash = "sha256:ed79b2353daa58421459abf4d685953bde0adf9f6e188944f97ba9795f100246"}, ] +psutil = [ + {file = "psutil-5.8.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64"}, + {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c"}, + {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df"}, + {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131"}, + {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60"}, + {file = "psutil-5.8.0-cp27-none-win32.whl", hash = "sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876"}, + {file = "psutil-5.8.0-cp27-none-win_amd64.whl", hash = "sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65"}, + {file = "psutil-5.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8"}, + {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6"}, + {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac"}, + {file = "psutil-5.8.0-cp36-cp36m-win32.whl", hash = "sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2"}, + {file = "psutil-5.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d"}, + {file = "psutil-5.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935"}, + {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d"}, + {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023"}, + {file = "psutil-5.8.0-cp37-cp37m-win32.whl", hash = "sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394"}, + {file = "psutil-5.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563"}, + {file = "psutil-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef"}, + {file = "psutil-5.8.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28"}, + {file = "psutil-5.8.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b"}, + {file = "psutil-5.8.0-cp38-cp38-win32.whl", hash = "sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d"}, + {file = "psutil-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d"}, + {file = "psutil-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7"}, + {file = "psutil-5.8.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4"}, + {file = "psutil-5.8.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b"}, + {file = "psutil-5.8.0-cp39-cp39-win32.whl", hash = "sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0"}, + {file = "psutil-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3"}, + {file = "psutil-5.8.0.tar.gz", hash = "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6"}, +] pyinstaller = [ {file = "pyinstaller-4.3.tar.gz", hash = "sha256:5ecf8bbc230d7298a796e52bb745b95eee12878d141f1645612c99246ecd23f2"}, ] diff --git a/pyproject.toml b/pyproject.toml index 06bf852..a10a706 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ pyobjc-core = {version = "*", platform = "darwin"} pyobjc-framework-launchservices = {version = "*", platform = "darwin"} strip-ansi = {version = "*", platform = "darwin"} colorama = "^0.4.4" +psutil = "^5.8.0" [tool.poetry.dev-dependencies] pyinstaller = {version = "*", platform = "darwin"}