diff --git a/probe.c b/probe.c index 7ffcfa9..91fe88d 100644 --- a/probe.c +++ b/probe.c @@ -394,11 +394,15 @@ int probe_client_protocol(struct connection *cnx) defer_write(&cnx->q[1], buffer, n); for (p = cnx->proto; p && res == PROBE_NEXT; p = p->next) { + char* probe_str[3] = {"PROBE_NEXT", + "PROBE_MATCH", + "PROBE_AGAIN"}; if (! p->probe) continue; - if (verbose) fprintf(stderr, "probing for %s\n", p->description); + if (verbose) fprintf(stderr, "probing for %s...", p->description); cnx->proto = p; res = p->probe(cnx->q[1].begin_deferred_data, cnx->q[1].deferred_data_size, p); + if (verbose) fprintf(stderr, "%s\n", probe_str[res]); } if (res != PROBE_NEXT) return res; diff --git a/t b/t index 2888dbf..1279675 100755 --- a/t +++ b/t @@ -25,6 +25,7 @@ my $SSL_CNX = 1; my $SSH_SHY_CNX = 1; my $SSH_BOLD_CNX = 1; my $SSH_PROBE_AGAIN = 1; +my $PROBES = 1; my $SSL_MIX_SSH = 1; my $SSH_MIX_SSL = 1; @@ -175,6 +176,52 @@ for my $binary (@binaries) { } + # Test: probes. For each probe, write one byte at a time + # and check we get connected to the right server. + if ($PROBES) { + my @probes = @{$conf->fetch_array("protocols")}; + foreach my $p (@probes) { + my %protocols = ( + 'ssh' => { data => "SSH-2.0 tester" }, + 'socks5' => { data => "\x05\x04\x01\x02\x03\x04" }, + 'http' => { + data => "GET index.html HTTP/1.1", + no_fragment => 1 }, + 'ssl' => { data => "\x16\x03\x031234" }, + 'openvpn' => { data => "\x00\x00" }, + 'tinc' => { data => "0 hello" }, + 'xmpp' => {data => "I should get a real jabber connection initialisation here" }, + 'adb' => { data => "CNXN....................host:..." }, + 'anyprot' => {data => "hello, this needs to be longer than the longest probe that returns PROBE_AGAIN" }, + ); + + my $cnx = new IO::Socket::INET(PeerHost => "localhost:$sslh_port"); + warn "$!\n" unless $cnx; + if (defined $cnx) { + my $pattern = $protocols{$p->{name}}->{data}; + if ($protocols{$p->{name}}->{no_fragment}) { + syswrite $cnx, $pattern; + } else { + while (length $pattern) { + syswrite $cnx, (substr $pattern, 0, 1, ''); + select undef, undef, undef, .1; + } + } + + my $data; + my $n = sysread $cnx, $data, 1024; + $data =~ /^(.*?): /; + my $prefix = $1; + $data =~ s/$prefix: //g; + print "Received: protocol $prefix data [$data]\n"; + close $cnx; + + is($prefix, $p->{name}); + is($data, $protocols{$p->{name}}->{data}); + } + } + } + my $pid = `cat $pidfile`; warn "killing $pid\n"; kill TERM => $pid or warn "kill process: $!\n"; diff --git a/test.cfg b/test.cfg index 96608b3..f5e7bf4 100644 --- a/test.cfg +++ b/test.cfg @@ -6,7 +6,7 @@ foreground: true; inetd: false; numeric: false; transparent: false; -timeout: 2; +timeout: 4; # Probe test writes slowly pidfile: "/tmp/sslh_test.pid"; syslog_facility: "auth"; @@ -26,8 +26,12 @@ protocols: { name: "ssh"; host: "localhost"; port: "9000"; fork: true; }, { name: "socks5"; host: "localhost"; port: "9001"; }, { name: "http"; host: "localhost"; port: "9002"; }, + { name: "tinc"; host: "localhost"; port: "9005"; }, + { name: "openvpn"; host: "localhost"; port: "9004"; }, { name: "ssl"; host: "localhost"; port: "9003"; }, - { name: "anyprot"; host: "localhost"; port: "9004"; } + { name: "xmpp"; host: "localhost"; port: "9006"; }, + { name: "adb"; host: "localhost"; port: "9007"; }, + { name: "anyprot"; host: "localhost"; port: "9010"; } ); on-timeout: "ssh";