X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=stest%2Fcommon.tcl;h=cd0780e417a9ad7839f32d570e5d0508114a2718;hb=564022994befb8f71b89ae015751b22c34ae3ee8;hp=ca503314eec88d75e651e8c6ba5a3aa108de45cb;hpb=6e553442518e7cd93e779d2895cb4c26ba5ba793;p=secnet.git diff --git a/stest/common.tcl b/stest/common.tcl index ca50331..cd0780e 100644 --- a/stest/common.tcl +++ b/stest/common.tcl @@ -1,3 +1,5 @@ +source test-common.tcl + package require Tclx load chiark_tcl_hbytes-1.so @@ -17,27 +19,48 @@ set netlink(outside) { set ports(inside) {16913 16910} set ports(outside) 16900 +set defnet_v4 198.51.100 +set defnet_v6 2001:db8:ff00 +set defaddr_v4 ${defnet_v4}.1 +set defaddr_v6 ${defnet_v6}::1 + set extra(inside) { local-mobile True; mtu-target 1260; } set extra(outside) {} -proc mkconf {which} { +set privkey(inside) test-example/inside.privkeys/ +set privkey(outside) test-example/outside.privkeys/ + +set initiator inside + +proc sitesconf_hook {l} { return $l } + +proc oldsecnet {site} { + upvar #0 oldsecnet($site) oldsecnet + expr {[info exists oldsecnet] && [set oldsecnet]} +} + +proc mkconf {location site} { global tmp + global builddir global netlink global ports global extra global netlinkfh - set pipefp $tmp/$which.netlink + global defaddr_v4 defaddr_v6 + upvar #0 privkey($site) privkey + set pipefp $tmp/$site.netlink foreach tr {t r} { file delete $pipefp.$tr exec mkfifo -m600 $pipefp.$tr - set netlinkfh($which.$tr) [set fh [open $pipefp.$tr r+]] + set netlinkfh($site.$tr) [set fh [open $pipefp.$tr r+]] fconfigure $fh -blocking 0 -buffering none -translation binary } - fileevent $netlinkfh($which.r) readable [list netlink-readable $which] - set fakeuf $tmp/$which.fake-userv + fileevent $netlinkfh($site.r) readable \ + [list netlink-readable $location $site] + set fakeuf $tmp/$site.fake-userv set fakeuh [open $fakeuf w 0755] puts $fakeuh "#!/bin/sh set -e @@ -50,37 +73,68 @@ exec cat " close $fakeuh set cfg " + hash sha1; netlink userv-ipif { name \"netlink\"; userv-path \"$fakeuf\"; - $netlink($which) + $netlink($site) mtu 1400; buffer sysbuffer(2048); - interface \"secnet-test-[string range $which 0 0]\"; + interface \"secnet-test-[string range $site 0 0]\"; }; comm " set delim {} - foreach port $ports($which) { + foreach port $ports($site) { append cfg "$delim udp { port $port; - address \"::1\", \"127.0.0.1\"; + address \"$defaddr_v6\", \"$defaddr_v4\"; buffer sysbuffer(4096); } " set delim , } append cfg "; - local-name \"test-example/$which/$which\"; - local-key rsa-private(\"test-example/$which.key\"); + local-name \"test-example/$location/$site\"; " - append cfg $extra($which) - append cfg { + switch -glob $privkey { + */ { + set sitesconf sites.conf + append cfg " + key-cache priv-cache({ + privkeys \"$builddir/${privkey}priv.\"; + }); +" + } + {load-private *} { + set sitesconf sites-nonego.conf + append cfg " + local-key load-private(\"[lindex $privkey 1]\",\"$builddir/[lindex $privkey 2]\"); +" + } + * { + set sitesconf sites-nonego.conf + append cfg " + local-key rsa-private(\"$builddir/$privkey\"); +" + } + } + set sitesconf $builddir/test-example/$sitesconf + + append cfg $extra($site) + append cfg " log logfile { - filename "/dev/tty"; - class "info","notice","warning","error","security","fatal"; + prefix \"$site\"; + class \"debug\",\"info\",\"notice\",\"warning\",\"error\",\"security\",\"fatal\"; + " + if {[oldsecnet $site]} { append cfg " + filename \"/dev/stderr\"; + " } + append cfg " }; + " + append cfg { system { }; resolver adns { @@ -90,44 +144,126 @@ exec cat transform eax-serpent { }, serpent256-cbc { }; } - set f [open test-example/sites.conf r] + set pubkeys $tmp/$site.pubkeys + file delete -force $pubkeys + exec cp -rl $builddir/test-example/pubkeys $pubkeys + + set f [open $sitesconf r] + while {[gets $f l] >= 0} { + regsub {\"[^\"]*test-example/pubkeys/} $l "\"$pubkeys/" l + regsub -all {\"\[127\.0\.0\.1\]\"} $l "\"\[$defaddr_v4\]\"" l + regsub -all {\"\[::1]\"} $l "\"\[$defaddr_v6\]\"" l + set l [sitesconf_hook $l] + append cfg $l "\n" + } set sites [read $f] close $f append cfg $sites append cfg { - sites map(site,vpn/test-example/all-sites); + sites map(site,all-sites); } + return $cfg } -proc spawn-secnet {which} { - global netlinkfh +proc spawn-secnet {location site} { global tmp - upvar #0 pids($which) pid - set cf $tmp/$which.conf + global builddir + global netlinkfh + global env + global pidmap + global readbuf + upvar #0 pids($site) pid + set readbuf($site) {} + set cf $tmp/$site.conf set ch [open $cf w] - puts $ch [mkconf $which] + puts $ch [mkconf $location $site] close $ch - set argl [list strace -o$tmp/$which.strace ./secnet -dvnc $cf] - set pid [fork] - if {!$pid} { - execl [lindex $argl 0] [lrange $argl 1 end] + set secnet $builddir/secnet + if {[oldsecnet $site]} { + set secnet $env(OLD_SECNET_DIR)/secnet + } + set argl [list $secnet -dvnc $cf] + set divertk SECNET_STEST_DIVERT_$site + puts "spawn:" + foreach k [array names env] { + switch -glob $k { + SECNET_STEST_DIVERT_* - + SECNET_TEST_BUILDDIR - OLD_SECNET_DIR { } + *SECNET* - + *PRELOAD* { puts -nonewline " $k=$env($k)" } + } } - puts -nonewline $netlinkfh($which.t) [hbytes h2raw c0] + if {[info exists env($divertk)]} { + switch -glob $env($divertk) { + i - {i *} { + regsub {^i} $env($divertk) {} divert_prefix + puts "$divert_prefix $argl" + puts -nonewline "run ^ command, hit return " + flush stdout + gets stdin + set argl {} + } + 0 - "" { + puts " $argl" + } + /* - ./* { + puts " $argl" + set argl [split $env($divertk)] + puts "... $argl" + } + * { + error "$divertk not understood" + } + } + } + if {[llength $argl]} { + set pid [fork] + set pidmap($pid) "secnet $location/$site" + if {!$pid} { + execl [lindex $argl 0] [lrange $argl 1 end] + } + } + puts -nonewline $netlinkfh($site.t) [hbytes h2raw c0] } -proc netlink-readable {which} { +proc netlink-readable {location site} { global ok - upvar #0 netlinkfh($which.r) fh - read $fh; # empty the buffer - switch -exact $which { - inside { - puts OK - set ok 1; # what a bodge - return + upvar #0 readbuf($site) buf + upvar #0 netlinkfh($site.r) fh + while 1 { + set x [read $fh] + set h [hbytes raw2h $x] + if {![hbytes length $h]} return + append buf $h + #puts "READABLE $site buf=$buf" + while {[regexp {^((?:..)*?)c0(.*)$} $buf dummy now buf]} { + #puts "READABLE $site now=$now (buf=$buf)" + regsub -all {^((?:..)*?)dbdc} $now {\1c0} now + regsub -all {^((?:..)*?)dbdd} $now {\1db} now + puts "netlink-got-packet $location $site $now" + netlink-got-packet $location $site $now + } + } +} + +proc netlink-got-packet {location site data} { + global initiator + if {![hbytes length $data]} return + switch -exact $site!$initiator { + inside!inside - outside!outside { + switch -glob $data { + 45000054ed9d4000fe0166d9ac12e802ac12e80900* { + puts "OK $data" + finish 0 + } + * { + error "unexpected $site $data" + } + } } - outside { - error "inside rx'd!" + default { + error "$site rx'd! (initiator $initiator)" } } } @@ -144,11 +280,12 @@ $message ---------------------------------------- " } - exit 1 + finish 1 } proc sendpkt {} { global netlinkfh + global initiator set p { 4500 0054 ed9d 4000 4001 24da ac12 e809 ac12 e802 0800 1de4 2d96 0001 f1d4 a05d @@ -157,32 +294,43 @@ proc sendpkt {} { 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 } - puts -nonewline $netlinkfh(inside.t) \ + puts -nonewline $netlinkfh($initiator.t) \ [hbytes h2raw c0[join $p ""]c0] } -if {![catch { - set tmp $env(AUTOPKGTEST_ARTIACTS) -}]} {} elseif {![catch { - set tmp $env(AUTOPKGTEST_TMP) -}]} {} elseif {[regsub {^stest/t-} $argv0 {stest/d-} tmp]} { - file mkdir $tmp -} - set socktmp $tmp/s exec mkdir -p -m700 $socktmp -regsub {^(?!/)} $socktmp {./} socktmp ;# dgram-socket wants ./ or / +regsub {^(?!/|\./)} $socktmp {./} socktmp ;# dgram-socket wants ./ or / -proc prefix_preload {lib} { - global env - set l {} - catch { set l [split $env(PRELOAD) :] } - set l [concat [list $lib] $l] - set env(LD_PRELOAD) [join $l :] -} +proc prefix_preload {lib} { prefix_some_path LD_PRELOAD $lib } set env(UDP_PRELOAD_DIR) $socktmp -prefix_preload stest/udp-preload.so +prefix_preload $builddir/stest/udp-preload.so + +proc finish {estatus} { + puts stderr "FINISHING $estatus" + signal default SIGCHLD + global pidmap + foreach pid [array names pidmap] { + kill KILL $pid + } + exit $estatus +} + +proc reap {} { + global pidmap + #puts stderr REAPING + foreach pid [array names pidmap] { + set got [wait -nohang $pid] + if {![llength $got]} continue + set info $pidmap($pid) + unset pidmap($pid) + puts stderr "reaped $info: $got" + finish 1 + } +} + +signal -restart trap SIGCHLD { after idle reap } proc udp-proxy {} { global socktmp udpsock @@ -216,14 +364,20 @@ proc udp-relay {data src sock args} { } } +proc adj-after {timeout args} { + upvar #0 env(SECNET_STEST_TIMEOUT_MUL) mul + if {[info exists mul]} { set timeout [expr {$timeout * $mul}] } + eval after $timeout $args +} + proc test-kex {} { udp-proxy - spawn-secnet inside - spawn-secnet outside + spawn-secnet in inside + spawn-secnet out outside - after 500 sendpkt - after 1000 sendpkt - after 5000 timed-out + adj-after 500 sendpkt + adj-after 1000 sendpkt + adj-after 5000 timed-out vwait ok }