Implement timeout to accept float value (#111)

* Implement timeout as a float value vs int

* remove unnecessary second multiplier

* whoops, missed one

* Switch type to time.Duration

* Fixup integration tests, change default and description

* Whoops, bad merge

* fix build
This commit is contained in:
Alex Holland 2018-07-02 13:00:45 -04:00 committed by Zakir Durumeric
parent a3a1d7edd1
commit 4f046b3085
7 changed files with 22 additions and 27 deletions

@ -14,7 +14,7 @@ versions="cups cups-tls"
function test_cups() { function test_cups() {
echo "ipp/test: Tests runner for ipp_cups" echo "ipp/test: Tests runner for ipp_cups"
CONTAINER_NAME="zgrab_ipp_cups" $ZGRAB_ROOT/docker-runner/docker-run.sh ipp --timeout 3 --verbose > "$OUTPUT_ROOT/cups.json" CONTAINER_NAME="zgrab_ipp_cups" $ZGRAB_ROOT/docker-runner/docker-run.sh ipp --timeout 3s --verbose > "$OUTPUT_ROOT/cups.json"
# FIXME: No good reason to use a tmp file & saved file, b/c I'm not testing any failure states yet # FIXME: No good reason to use a tmp file & saved file, b/c I'm not testing any failure states yet
#CONTAINER_NAME="zgrab_ipp_cups" $ZGRAB_ROOT/docker-runner/docker-run.sh ipp --timeout 3 --verbose > out.tmp #CONTAINER_NAME="zgrab_ipp_cups" $ZGRAB_ROOT/docker-runner/docker-run.sh ipp --timeout 3 --verbose > out.tmp
major=$($ZGRAB_ROOT/jp -u data.ipp.result.version_major < "$OUTPUT_ROOT/cups.json") major=$($ZGRAB_ROOT/jp -u data.ipp.result.version_major < "$OUTPUT_ROOT/cups.json")
@ -38,7 +38,7 @@ function test_cups() {
function test_cups_tls() { function test_cups_tls() {
echo "ipp/test: Tests runner for ipp_cups" echo "ipp/test: Tests runner for ipp_cups"
CONTAINER_NAME="zgrab_ipp_cups-tls" $ZGRAB_ROOT/docker-runner/docker-run.sh ipp --timeout 3 --ipps --verbose > "$OUTPUT_ROOT/cups-tls.json" CONTAINER_NAME="zgrab_ipp_cups-tls" $ZGRAB_ROOT/docker-runner/docker-run.sh ipp --timeout 3s --ipps --verbose > "$OUTPUT_ROOT/cups-tls.json"
# FIXME: No good reason to use a tmp file & saved file, b/c I'm not testing any failure states yet # FIXME: No good reason to use a tmp file & saved file, b/c I'm not testing any failure states yet
#CONTAINER_NAME="zgrab_ipp_cups-tls" $ZGRAB_ROOT/docker-runner/docker-run.sh ipp --timeout 3 --ipps --verbose > out.tmp #CONTAINER_NAME="zgrab_ipp_cups-tls" $ZGRAB_ROOT/docker-runner/docker-run.sh ipp --timeout 3 --ipps --verbose > out.tmp
major=$($ZGRAB_ROOT/jp -u data.ipp.result.version_major < "$OUTPUT_ROOT/cups-tls.json") major=$($ZGRAB_ROOT/jp -u data.ipp.result.version_major < "$OUTPUT_ROOT/cups-tls.json")
@ -92,4 +92,4 @@ for version in $versions; do
#echo "ipp/test: BEGIN cups logs from $CONTAINER_NAME [{(" #echo "ipp/test: BEGIN cups logs from $CONTAINER_NAME [{("
#docker exec -t $CONTAINER_NAME cat //var/log/cups/page_log #docker exec -t $CONTAINER_NAME cat //var/log/cups/page_log
#echo ")}] END cups logs from $CONTAINER_NAME" #echo ")}] END cups logs from $CONTAINER_NAME"
done done

@ -19,7 +19,7 @@ function doTest() {
CONTAINER_NAME="zgrab_mysql-$MYSQL_VERSION" CONTAINER_NAME="zgrab_mysql-$MYSQL_VERSION"
OUTPUT_FILE="$ZGRAB_OUTPUT/mysql/$MYSQL_VERSION.json" OUTPUT_FILE="$ZGRAB_OUTPUT/mysql/$MYSQL_VERSION.json"
echo "mysql/test: Testing MySQL Version $MYSQL_VERSION..." echo "mysql/test: Testing MySQL Version $MYSQL_VERSION..."
CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh mysql --timeout 10 > $OUTPUT_FILE CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh mysql --timeout 10s > $OUTPUT_FILE
SERVER_VERSION=$($ZGRAB_ROOT/jp -u data.mysql.result.server_version < $OUTPUT_FILE) SERVER_VERSION=$($ZGRAB_ROOT/jp -u data.mysql.result.server_version < $OUTPUT_FILE)
if [[ "$SERVER_VERSION" == "$MYSQL_VERSION."* ]]; then if [[ "$SERVER_VERSION" == "$MYSQL_VERSION."* ]]; then
echo "mysql/test: Server version matches expected version: $SERVER_VERSION == $MYSQL_VERSION.*" echo "mysql/test: Server version matches expected version: $SERVER_VERSION == $MYSQL_VERSION.*"

@ -15,10 +15,10 @@ versions="openntp 4.2.6"
function test_openntp() { function test_openntp() {
echo "ntp/test: Tests runner for ntp_openntp" echo "ntp/test: Tests runner for ntp_openntp"
CONTAINER_NAME="zgrab_ntp_openntp" $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3 > "$OUTPUT_ROOT/openntp.json" CONTAINER_NAME="zgrab_ntp_openntp" $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3s > "$OUTPUT_ROOT/openntp.json"
# Don't drop this in the standard output root, since it will not have status = success # Don't drop this in the standard output root, since it will not have status = success
CONTAINER_NAME="zgrab_ntp_openntp" $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3 --monlist > out.tmp CONTAINER_NAME="zgrab_ntp_openntp" $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3s --monlist > out.tmp
time=$($ZGRAB_ROOT/jp -u data.ntp.result.time < out.tmp) time=$($ZGRAB_ROOT/jp -u data.ntp.result.time < out.tmp)
version=$($ZGRAB_ROOT/jp -u data.ntp.result.version < out.tmp) version=$($ZGRAB_ROOT/jp -u data.ntp.result.version < out.tmp)
rm -f out.tmp rm -f out.tmp
@ -35,7 +35,7 @@ function test_openntp() {
function test_bad_req() { function test_bad_req() {
code=$1 code=$1
expected_error=$2 expected_error=$2
CONTAINER_NAME="zgrab_ntp_4.2.6" $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3 --monlist --request-code $code --skip-get-time > out.tmp CONTAINER_NAME="zgrab_ntp_4.2.6" $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3s --monlist --request-code $code --skip-get-time > out.tmp
status=$($ZGRAB_ROOT/jp -u data.ntp.status < out.tmp) status=$($ZGRAB_ROOT/jp -u data.ntp.status < out.tmp)
error=$($ZGRAB_ROOT/jp -u data.ntp.error < out.tmp) error=$($ZGRAB_ROOT/jp -u data.ntp.error < out.tmp)
rm -f out.tmp rm -f out.tmp
@ -54,13 +54,13 @@ function test_4_2_6() {
echo "ntp/test: Tests runner for ntp_4.2.6" echo "ntp/test: Tests runner for ntp_4.2.6"
CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3 > "$OUTPUT_ROOT/4.2.6_normal.json" CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3s > "$OUTPUT_ROOT/4.2.6_normal.json"
CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3 --monlist > "$OUTPUT_ROOT/4.2.6_monlist.json" CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3s --monlist > "$OUTPUT_ROOT/4.2.6_monlist.json"
request_codes="REQ_MON_GETLIST_1 REQ_MON_GETLIST" request_codes="REQ_MON_GETLIST_1 REQ_MON_GETLIST"
for code in $request_codes; do for code in $request_codes; do
CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3 --monlist --request-code $code > "$OUTPUT_ROOT/4.2.6_$code.json" CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3s --monlist --request-code $code > "$OUTPUT_ROOT/4.2.6_$code.json"
CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3 --monlist --request-code $code --skip-get-time > "$OUTPUT_ROOT/4.2.6_${code}_solo.json" CONTAINER_NAME=$CONTAINER_NAME $ZGRAB_ROOT/docker-runner/docker-run.sh ntp --timeout 3s --monlist --request-code $code --skip-get-time > "$OUTPUT_ROOT/4.2.6_${code}_solo.json"
done done
# Check that when the server returns with a valid error code that we return status = application-error and we forward the INFO_ERR code from the server # Check that when the server returns with a valid error code that we return status = application-error and we forward the INFO_ERR code from the server

@ -1,5 +1,7 @@
package zgrab2 package zgrab2
import "time"
// Scanner is an interface that represents all functions necessary to run a scan // Scanner is an interface that represents all functions necessary to run a scan
type Scanner interface { type Scanner interface {
// Init runs once for this module at library init time // Init runs once for this module at library init time
@ -61,10 +63,10 @@ type ScanFlags interface {
// BaseFlags contains the options that every flags type must embed // BaseFlags contains the options that every flags type must embed
type BaseFlags struct { type BaseFlags struct {
Port uint `short:"p" long:"port" description:"Specify port to grab on"` Port uint `short:"p" long:"port" description:"Specify port to grab on"`
Name string `short:"n" long:"name" description:"Specify name for output json, only necessary if scanning multiple modules"` Name string `short:"n" long:"name" description:"Specify name for output json, only necessary if scanning multiple modules"`
Timeout uint `short:"t" long:"timeout" description:"Set connection timeout in seconds (0 = no timeout)" default:"10"` Timeout time.Duration `short:"t" long:"timeout" description:"Set connection timeout (0 = no timeout)" default:"10s"`
Trigger string `short:"g" long:"trigger" description:"Invoke only on targets with specified tag"` Trigger string `short:"g" long:"trigger" description:"Invoke only on targets with specified tag"`
} }
// UDPFlags contains the common options used for all UDP scans // UDPFlags contains the common options used for all UDP scans

@ -14,7 +14,6 @@ import (
"net" "net"
"net/url" "net/url"
"strconv" "strconv"
"time"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/zmap/zgrab2" "github.com/zmap/zgrab2"
@ -147,7 +146,7 @@ func (scan *scan) Cleanup() {
// zgrab2.GetTLSConnection() // zgrab2.GetTLSConnection()
func (scan *scan) getTLSDialer() func(net, addr string) (net.Conn, error) { func (scan *scan) getTLSDialer() func(net, addr string) (net.Conn, error) {
return func(net, addr string) (net.Conn, error) { return func(net, addr string) (net.Conn, error) {
outer, err := zgrab2.DialTimeoutConnection(net, addr, time.Second*time.Duration(scan.scanner.config.BaseFlags.Timeout)) outer, err := zgrab2.DialTimeoutConnection(net, addr, scan.scanner.config.Timeout)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -246,7 +245,7 @@ func (scanner *Scanner) newHTTPScan(t *zgrab2.ScanTarget) *scan {
client: http.MakeNewClient(), client: http.MakeNewClient(),
} }
ret.transport.DialTLS = ret.getTLSDialer() ret.transport.DialTLS = ret.getTLSDialer()
ret.transport.DialContext = zgrab2.GetTimeoutConnectionDialer(time.Duration(scanner.config.Timeout) * time.Second).DialContext ret.transport.DialContext = zgrab2.GetTimeoutConnectionDialer(scanner.config.Timeout).DialContext
ret.client.UserAgent = scanner.config.UserAgent ret.client.UserAgent = scanner.config.UserAgent
ret.client.CheckRedirect = ret.getCheckRedirect() ret.client.CheckRedirect = ret.getCheckRedirect()
ret.client.Transport = ret.transport ret.client.Transport = ret.transport

@ -4,7 +4,6 @@ import (
"net" "net"
"strconv" "strconv"
"strings" "strings"
"time"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/zmap/zgrab2" "github.com/zmap/zgrab2"
@ -84,7 +83,7 @@ func (s *SSHScanner) Scan(t zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{},
rhost := net.JoinHostPort(t.Host(), port) rhost := net.JoinHostPort(t.Host(), port)
sshConfig := ssh.MakeSSHConfig() sshConfig := ssh.MakeSSHConfig()
sshConfig.Timeout = time.Duration(s.config.Timeout) * time.Second sshConfig.Timeout = s.config.Timeout
sshConfig.ConnLog = data sshConfig.ConnLog = data
sshConfig.ClientVersion = s.config.ClientID sshConfig.ClientVersion = s.config.ClientID
if err := sshConfig.SetHostKeyAlgorithms(s.config.HostKeyAlgorithms); err != nil { if err := sshConfig.SetHostKeyAlgorithms(s.config.HostKeyAlgorithms); err != nil {

@ -6,7 +6,6 @@ import (
"fmt" "fmt"
"net" "net"
"sync" "sync"
"time"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/zmap/zgrab2/lib/output" "github.com/zmap/zgrab2/lib/output"
@ -58,19 +57,15 @@ func (target *ScanTarget) Host() string {
// Open connects to the ScanTarget using the configured flags, and returns a net.Conn that uses the configured timeouts for Read/Write operations. // Open connects to the ScanTarget using the configured flags, and returns a net.Conn that uses the configured timeouts for Read/Write operations.
func (target *ScanTarget) Open(flags *BaseFlags) (net.Conn, error) { func (target *ScanTarget) Open(flags *BaseFlags) (net.Conn, error) {
timeout := time.Second * time.Duration(flags.Timeout)
address := net.JoinHostPort(target.Host(), fmt.Sprintf("%d", flags.Port)) address := net.JoinHostPort(target.Host(), fmt.Sprintf("%d", flags.Port))
return DialTimeoutConnection("tcp", address, timeout) return DialTimeoutConnection("tcp", address, flags.Timeout)
} }
// OpenUDP connects to the ScanTarget using the configured flags, and returns a net.Conn that uses the configured timeouts for Read/Write operations. // OpenUDP connects to the ScanTarget using the configured flags, and returns a net.Conn that uses the configured timeouts for Read/Write operations.
// Note that the UDP "connection" does not have an associated timeout. // Note that the UDP "connection" does not have an associated timeout.
func (target *ScanTarget) OpenUDP(flags *BaseFlags, udp *UDPFlags) (net.Conn, error) { func (target *ScanTarget) OpenUDP(flags *BaseFlags, udp *UDPFlags) (net.Conn, error) {
timeout := time.Second * time.Duration(flags.Timeout)
address := net.JoinHostPort(target.Host(), fmt.Sprintf("%d", flags.Port)) address := net.JoinHostPort(target.Host(), fmt.Sprintf("%d", flags.Port))
var local *net.UDPAddr var local *net.UDPAddr
var err error
if udp != nil && (udp.LocalAddress != "" || udp.LocalPort != 0) { if udp != nil && (udp.LocalAddress != "" || udp.LocalPort != 0) {
local = &net.UDPAddr{} local = &net.UDPAddr{}
if udp.LocalAddress != "" && udp.LocalAddress != "*" { if udp.LocalAddress != "" && udp.LocalAddress != "*" {
@ -90,7 +85,7 @@ func (target *ScanTarget) OpenUDP(flags *BaseFlags, udp *UDPFlags) (net.Conn, er
} }
return &TimeoutConnection{ return &TimeoutConnection{
Conn: conn, Conn: conn,
Timeout: timeout, Timeout: flags.Timeout,
}, nil }, nil
} }