...
 
Commits (4)
......@@ -18,6 +18,15 @@ linux:
# -v `pwd`/:/home/build/src $(DOCKER_EXTRA) boundery-client-android \
# /bin/sh -c "python3 setup.py android && python3 setup.py android --build"
.vagrant/vfat.img:
dd if=/dev/zero of=$@ bs=1024 count=10k
printf 'n\np\n1\n\n\nt\nc\nw\n' | fdisk $@
mformat -i$@@@1M -s32 -h64 -t9 -v"BNDRY TEST"
.vagrant/vfat-windows.vdi: .vagrant/vfat.img
VBoxManage convertfromraw $< $@ --format vdi --uuid 00000000-4455-6677-8899-aabbccddeeff
.vagrant/vfat-macos.vdi: .vagrant/vfat.img
VBoxManage convertfromraw $< $@ --format vdi --uuid 11111111-4455-6677-8899-aabbccddeeff
.PHONY: windows
windows:
rm -rf windows
......@@ -26,7 +35,7 @@ windows:
while [ ! -f "windows/builddone" ]; do sleep 1; done
$(VAGRANT) halt windows
.PHONY: windows-test #XXX Make this depend on the built .msi!
windows-test:
windows-test: .vagrant/vfat-windows.vdi
rm -f windows/tests_passed
$(VAGRANT) up windows
$(VAGRANT) provision --provision-with test windows
......@@ -44,7 +53,7 @@ macos:
$(VAGRANT) ssh macos --no-tty -c "tar cf - -C /vagrant macOS" | tar xf -
$(VAGRANT) halt macos
.PHONY: macos-test #XXX Make this depend on the built .dmg!
macos-test:
macos-test: .vagrant/vfat-macos.vdi
rm -f macOS/tests_passed
$(VAGRANT) up macos
$(VAGRANT) provision --provision-with test macos
......
raise "Run: vagrant plugin install winrm" unless Vagrant.has_plugin?('winrm')
raise "Run: vagrant plugin install winrm-elevated" unless Vagrant.has_plugin?('winrm-elevated')
def add_usb_vdi(vb, machine)
vdi = File.join(File.dirname(File.expand_path(__FILE__)), ".vagrant/vfat-#{machine}.vdi")
if not File.exist?(vdi)
return
end
id = File.read(".vagrant/machines/#{machine}/virtualbox/id")
if `VBoxManage showvminfo #{id} --machinereadable | egrep '^storagecontrollername[0-9]+="BOUNDERYUSB"$'`.length <= 0
vb.customize ['storagectl', id, '--name', 'BOUNDERYUSB', '--add', 'usb', '--controller', 'USB']
end
vb.customize ['storageattach', id, '--storagectl', 'BOUNDERYUSB',
'--port', 1, '--device', 0, '--type', 'hdd',
'--medium', vdi, '--hotpluggable', 'on', '--nonrotational', 'on']
end
Vagrant.configure("2") do |config|
config.vm.box = ""
......@@ -10,6 +24,9 @@ Vagrant.configure("2") do |config|
win.vm.provider "virtualbox" do |vb|
#vb.gui = true
vb.memory = "2048"
vb.customize ['modifyvm', :id, '--usb', 'on']
add_usb_vdi(vb, 'windows')
end
win.vm.guest = :windows
......@@ -19,6 +36,7 @@ Vagrant.configure("2") do |config|
win.vm.box = "opentable/win-2012r2-standard-amd64-nocm"
win.vm.network "forwarded_port", host: 33389, guest: 3389
win.ssh.extra_args = ['-oHostKeyAlgorithms=+ssh-dss']
win.vm.provision "prep", type: "shell", inline: <<-SHELL
echo " ****** Installing chocolatey ******"
......@@ -87,6 +105,7 @@ Vagrant.configure("2") do |config|
echo " ****** Run tests *******"
cd "\\Program Files (x86)\\Boundery Client"
$env:BOUNDERY_APP_TEST = '1'
$env:BOUNDERY_ENUM_FIXED = '1' #VirtualBox USB devices aren't removable.
& "\\Program Files (x86)\\Boundery Client\\python\\python.exe" app\\start.py
echo "" > \\vagrant\\windows\\tests_passed
......@@ -108,6 +127,8 @@ Vagrant.configure("2") do |config|
vb.customize ['modifyvm', :id, '--ostype', 'MacOS_64']
vb.customize ['modifyvm', :id, '--usbxhci', 'off']
vb.customize ['modifyvm', :id, '--usbehci', 'off']
add_usb_vdi(vb, 'macos')
end
mac.vm.synced_folder ".", "/vagrant", type: "rsync",
......@@ -177,17 +198,10 @@ Vagrant.configure("2") do |config|
VOL=`sudo hdiutil attach "/vagrant/macOS/Boundery Client.dmg" | grep /Volumes/ | cut -f3`
echo " ****** Run tests *******"
dd if=/dev/zero bs=512 count=2880 of=/tmp/msdos.img 2>&1
DEV=`hdid -nomount /tmp/msdos.img`
newfs_msdos -v BOUNDERYTST $DEV 2>&1
hdiutil detach $DEV -force
DEV=`hdid /tmp/msdos.img | cut -d ' ' -f 1`
diskutil mount "BNDRY TEST" #No one is logged in, so we have to manually mount.
sudo BOUNDERY_APP_TEST=1 "$VOL/Boundery Client.app/Contents/MacOS/Boundery Client"
touch /vagrant/macOS/tests_passed
hdiutil detach $DEV -force
echo " ****** Tests done, detaching .dmg *******"
sudo hdiutil detach "$VOL" -force
......
......@@ -123,7 +123,7 @@ step1_thread = None
@post('/step1')
def step1_post():
mount = request.forms.get('mount')
if mount not in osal.get_mounts():
if mount not in [ i[1] for i in osal.get_mounts() ]:
raise Exception("Bad mountpoint from client!")
#XXX This is busted if your ssid is actually '__other'
......@@ -144,6 +144,7 @@ def step1_post():
return template("step1_post")
#XXX Handle errors here, and signal back to the client.
def step1_handler(ssid, wifi_pw, mount):
if "ZIPFILE" not in os.environ:
r = requests.get(CENTRAL_URL + "/static/images/rpi3.zip", stream=True)
......
......@@ -8,4 +8,33 @@ if os.name == "posix":
else:
from .osal_windows import *
def self_test():
import logging
if os.name == 'nt':
zerotier = 'c:\Program Files (x86)\ZeroTier\One\zerotier-cli.bat'
else:
zerotier = 'zerotier-cli'
try:
print("Testing get_mounts")
mounts = get_mounts()
if len(mounts) != 1 or mounts[0][0] != 'BNDRY TEST':
logging.error("get_mounts failed: '%s'" % mounts)
return 10
#XXX Just use --privsub directly here?
print("Testing ZT info")
zt = sudo(zerotier, 'info')
zt_out = zt.stdout.read()
if not zt_out.startswith('200 info '):
logging.error("sudo failed: '%s'" % zt_out)
return 20
print("Testing get_ssids")
get_ssids()
print("Testing complete")
except:
logging.error("foo", exc_info=True)
return 99
#XXX Get wifi password. Pypi has "ng" which claims to do so.
......@@ -12,11 +12,11 @@ def get_mounts():
continue
mnt = mnt.replace('\\040', ' ').replace('\\011', '\t')
mnt = mnt.replace('\\134', '\\').replace('\\012', '\n')
if mnt == "/" or mnt.startswith("/boot") or mnt.startswith("/run/user"):
if mnt == "/" or mnt.startswith("/boot"):
continue
if not os.access(mnt, os.W_OK):
continue
ret.append(mnt)
ret.append((mnt.split('/')[-1], mnt))
return ret
#XXX Some fallback if pkexec isn't available? sudo in a terminal?
......
......@@ -18,7 +18,7 @@ def get_mounts():
continue
if not os.access(mnt, os.W_OK):
continue
ret.append(mnt)
ret.append((mnt.split('/')[-1], mnt))
return ret
#osascript's elevate command does weird stuff to stdin/stdout, so we use a pair of fifos.
......@@ -77,26 +77,3 @@ def get_ssids():
#XXX Figure out which SSID client is currently connected to.
ssids.append((False, min(max(2 * (int(ap.rssiValue) + 100), 0), 100), str(ap.ssid)))
return ssids
def self_test():
import logging
try:
print("Testing get_mounts")
mounts = get_mounts()
if '/Volumes/BOUNDERYTST' not in mounts:
logging.error("get_mounts failed: '%s'" % mounts)
return 10
print("Testing ZT info")
zt = sudo('zerotier-cli', 'info')
zt_out = zt.stdout.read()
if not zt_out.startswith('200 info '):
logging.error("sudo failed: '%s'" % zt_out)
return 20
print("Testing get_ssids")
get_ssids()
print("Testing complete")
except:
logging.error("foo", exc_info=True)
return 99
import sys, os, subprocess, ctypes
import sys, os, subprocess
#briefcase's start.py adds app_packages to sys.path, which skips pywin32's .pth file. sitedirs don't.
import site
site.addsitedir(next(filter(lambda i: i.endswith('app_packages'), sys.path), ''))
from ctypes import windll, create_unicode_buffer, sizeof, c_wchar_p
from . import win32wifi
import win32pipe, win32file, msvcrt
from win32api import GetLogicalDriveStrings
from win32file import GetDriveType
#XXX Would be nice to get human-readable description as well...
def get_mounts():
drives = GetLogicalDriveStrings()
drives = [i for i in drives.split("\x00") if i]
return [i[:2] for i in drives if GetDriveType(i) == win32file.DRIVE_REMOVABLE]
DRIVE_REMOVABLE = 2
DRIVE_CDROM = 5
buf = create_unicode_buffer(1024)
count = windll.kernel32.GetLogicalDriveStringsW(sizeof(buf)-1, buf)
drives = buf[:count-1].split('\x00')
ret = []
for drive in drives:
if os.environ.get("BOUNDERY_ENUM_FIXED", None):
if drive[0] == 'C' or windll.kernel32.GetDriveTypeW(drive) == DRIVE_CDROM:
continue
else:
if windll.kernel32.GetDriveTypeW(drive) != DRIVE_REMOVABLE:
continue
volume_name = create_unicode_buffer(1024)
fs_type = create_unicode_buffer(1024)
windll. kernel32.GetVolumeInformationW(c_wchar_p(drive),
volume_name, sizeof(volume_name)-1,
None, None, None,
fs_type, sizeof(fs_type)-1)
if fs_type.value != 'FAT':
continue
ret.append((volume_name.value, drive[:2]))
return ret
class NPWrapper:
def __init__(self, pipe):
......@@ -44,8 +65,8 @@ def sudo(cmd, *args):
python = python[:-len('python.exe')] + 'pythonw.exe'
if fullargs[1].upper().endswith('\\PYTHON.EXE'):
fullargs[1] = fullargs[1][:-len('python.exe')] + 'pythonw.exe'
ctypes.windll.shell32.ShellExecuteW(None, "runas",
python, subprocess.list2cmdline(fullargs), None, 1)
windll.shell32.ShellExecuteW(None, "runas",
python, subprocess.list2cmdline(fullargs), None, 1)
return NPWrapper(pipe)
def get_zerotier_token_path():
......@@ -55,26 +76,3 @@ def get_ssids():
#XXX Figure out which SSID client is currently connected to.
#XXX Filter out non AP mode aps here.
return [ (False, min(max(2 * (x[1] + 100), 0), 100), x[0]) for x in win32wifi.get_BSSI().values() ]
def self_test():
import logging
try:
print("Testing get_mounts")
get_mounts()
#if '/Volumes/BOUNDERYTST' not in mounts:
# logging.error("get_mounts failed: '%s'" % mounts)
# return 10
print("Testing ZT info")
zt = sudo('c:\Program Files (x86)\ZeroTier\One\zerotier-cli.bat', 'info')
zt_out = zt.stdout.read()
if not zt_out.startswith('200 info '):
logging.error("sudo failed: '%s'" % zt_out)
return 20
print("Testing get_ssids")
get_ssids()
print("Testing complete")
except:
logging.error("foo", exc_info=True)
return 99
<label>Choose your SD Card:</label>
% for mount in mounts:
<div class="button">
<button name="mount" value="{{mount}}">Write to {{mount}}</button>
<button name="mount" value="{{mount[1]}}">Write to {{mount[0]}} ({{mount[1]}})</button>
</div>
% end