* feat(scan): load portscan settings from config.toml * feat(scan): support external port scanner:nmap * style: rename variable * feat(scan): logging apply options * feat(scan): remove spoof ip address option * feat(scan): more validate port scan config * style: change comment * fix: parse port number as uint16 * feat(discover): add portscan section * feat(discover): change default scanTechniques * feat(docker): add nmap and version update * feat(scan): nmap module upgrade * fix: wrap err using %w * feat(scan): print cmd using external port scanner * feat(scan): more details external port scan command * feat(scan): add capability check in validation * fix(scanner): format error * chore: change format
		
			
				
	
	
		
			431 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			431 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package models
 | 
						|
 | 
						|
import (
 | 
						|
	"reflect"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/k0kubun/pp"
 | 
						|
)
 | 
						|
 | 
						|
func TestMergeNewVersion(t *testing.T) {
 | 
						|
	var test = struct {
 | 
						|
		a        Packages
 | 
						|
		b        Packages
 | 
						|
		expected Packages
 | 
						|
	}{
 | 
						|
		Packages{
 | 
						|
			"hoge": {
 | 
						|
				Name: "hoge",
 | 
						|
			},
 | 
						|
		},
 | 
						|
		Packages{
 | 
						|
			"hoge": {
 | 
						|
				Name:       "hoge",
 | 
						|
				NewVersion: "1.0.0",
 | 
						|
				NewRelease: "release1",
 | 
						|
			},
 | 
						|
		},
 | 
						|
		Packages{
 | 
						|
			"hoge": {
 | 
						|
				Name:       "hoge",
 | 
						|
				NewVersion: "1.0.0",
 | 
						|
				NewRelease: "release1",
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	test.a.MergeNewVersion(test.b)
 | 
						|
	if !reflect.DeepEqual(test.a, test.expected) {
 | 
						|
		e := pp.Sprintf("%v", test.a)
 | 
						|
		a := pp.Sprintf("%v", test.expected)
 | 
						|
		t.Errorf("expected %s, actual %s", e, a)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestMerge(t *testing.T) {
 | 
						|
	var test = struct {
 | 
						|
		a        Packages
 | 
						|
		b        Packages
 | 
						|
		expected Packages
 | 
						|
	}{
 | 
						|
		Packages{
 | 
						|
			"hoge": {Name: "hoge"},
 | 
						|
			"fuga": {Name: "fuga"},
 | 
						|
		},
 | 
						|
		Packages{
 | 
						|
			"hega": {Name: "hega"},
 | 
						|
			"hage": {Name: "hage"},
 | 
						|
		},
 | 
						|
		Packages{
 | 
						|
			"hoge": {Name: "hoge"},
 | 
						|
			"fuga": {Name: "fuga"},
 | 
						|
			"hega": {Name: "hega"},
 | 
						|
			"hage": {Name: "hage"},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	actual := test.a.Merge(test.b)
 | 
						|
	if !reflect.DeepEqual(actual, test.expected) {
 | 
						|
		e := pp.Sprintf("%v", test.expected)
 | 
						|
		a := pp.Sprintf("%v", actual)
 | 
						|
		t.Errorf("expected %s, actual %s", e, a)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestAddBinaryName(t *testing.T) {
 | 
						|
	var tests = []struct {
 | 
						|
		in       SrcPackage
 | 
						|
		name     string
 | 
						|
		expected SrcPackage
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			SrcPackage{Name: "hoge"},
 | 
						|
			"curl",
 | 
						|
			SrcPackage{
 | 
						|
				Name:        "hoge",
 | 
						|
				BinaryNames: []string{"curl"},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SrcPackage{
 | 
						|
				Name:        "hoge",
 | 
						|
				BinaryNames: []string{"curl"},
 | 
						|
			},
 | 
						|
			"curl",
 | 
						|
			SrcPackage{
 | 
						|
				Name:        "hoge",
 | 
						|
				BinaryNames: []string{"curl"},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			SrcPackage{
 | 
						|
				Name:        "hoge",
 | 
						|
				BinaryNames: []string{"curl"},
 | 
						|
			},
 | 
						|
			"openssh",
 | 
						|
			SrcPackage{
 | 
						|
				Name:        "hoge",
 | 
						|
				BinaryNames: []string{"curl", "openssh"},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, tt := range tests {
 | 
						|
		tt.in.AddBinaryName(tt.name)
 | 
						|
		if !reflect.DeepEqual(tt.in, tt.expected) {
 | 
						|
			t.Errorf("expected %#v, actual %#v", tt.in, tt.expected)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestFindByBinName(t *testing.T) {
 | 
						|
	var tests = []struct {
 | 
						|
		in       SrcPackages
 | 
						|
		name     string
 | 
						|
		expected *SrcPackage
 | 
						|
		ok       bool
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			in: map[string]SrcPackage{
 | 
						|
				"packA": {
 | 
						|
					Name:        "srcA",
 | 
						|
					BinaryNames: []string{"binA"},
 | 
						|
					Version:     "1.0.0",
 | 
						|
				},
 | 
						|
				"packB": {
 | 
						|
					Name:        "srcB",
 | 
						|
					BinaryNames: []string{"binB"},
 | 
						|
					Version:     "2.0.0",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			name: "binA",
 | 
						|
			expected: &SrcPackage{
 | 
						|
				Name:        "srcA",
 | 
						|
				BinaryNames: []string{"binA"},
 | 
						|
				Version:     "1.0.0",
 | 
						|
			},
 | 
						|
			ok: true,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			in: map[string]SrcPackage{
 | 
						|
				"packA": {
 | 
						|
					Name:        "srcA",
 | 
						|
					BinaryNames: []string{"binA"},
 | 
						|
					Version:     "1.0.0",
 | 
						|
				},
 | 
						|
				"packB": {
 | 
						|
					Name:        "srcB",
 | 
						|
					BinaryNames: []string{"binB"},
 | 
						|
					Version:     "2.0.0",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			name:     "nobin",
 | 
						|
			expected: nil,
 | 
						|
			ok:       false,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for i, tt := range tests {
 | 
						|
		act, ok := tt.in.FindByBinName(tt.name)
 | 
						|
		if ok != tt.ok {
 | 
						|
			t.Errorf("[%d] expected %#v, actual %#v", i, tt.in, tt.expected)
 | 
						|
		}
 | 
						|
		if act != nil && !reflect.DeepEqual(*tt.expected, *act) {
 | 
						|
			t.Errorf("[%d] expected %#v, actual %#v", i, tt.in, tt.expected)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestPackage_FormatVersionFromTo(t *testing.T) {
 | 
						|
	type fields struct {
 | 
						|
		Name             string
 | 
						|
		Version          string
 | 
						|
		Release          string
 | 
						|
		NewVersion       string
 | 
						|
		NewRelease       string
 | 
						|
		Arch             string
 | 
						|
		Repository       string
 | 
						|
		Changelog        Changelog
 | 
						|
		AffectedProcs    []AffectedProcess
 | 
						|
		NeedRestartProcs []NeedRestartProcess
 | 
						|
	}
 | 
						|
	type args struct {
 | 
						|
		stat PackageFixStatus
 | 
						|
	}
 | 
						|
	tests := []struct {
 | 
						|
		name   string
 | 
						|
		fields fields
 | 
						|
		args   args
 | 
						|
		want   string
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name: "fixed",
 | 
						|
			fields: fields{
 | 
						|
				Name:       "packA",
 | 
						|
				Version:    "1.0.0",
 | 
						|
				Release:    "a",
 | 
						|
				NewVersion: "1.0.1",
 | 
						|
				NewRelease: "b",
 | 
						|
			},
 | 
						|
			args: args{
 | 
						|
				stat: PackageFixStatus{
 | 
						|
					NotFixedYet: false,
 | 
						|
					FixedIn:     "1.0.1-b",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			want: "packA-1.0.0-a -> 1.0.1-b (FixedIn: 1.0.1-b)",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "nfy",
 | 
						|
			fields: fields{
 | 
						|
				Name:    "packA",
 | 
						|
				Version: "1.0.0",
 | 
						|
				Release: "a",
 | 
						|
			},
 | 
						|
			args: args{
 | 
						|
				stat: PackageFixStatus{
 | 
						|
					NotFixedYet: true,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			want: "packA-1.0.0-a -> Not Fixed Yet",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "nfy",
 | 
						|
			fields: fields{
 | 
						|
				Name:    "packA",
 | 
						|
				Version: "1.0.0",
 | 
						|
				Release: "a",
 | 
						|
			},
 | 
						|
			args: args{
 | 
						|
				stat: PackageFixStatus{
 | 
						|
					NotFixedYet: false,
 | 
						|
					FixedIn:     "1.0.1-b",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			want: "packA-1.0.0-a -> Unknown (FixedIn: 1.0.1-b)",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "nfy2",
 | 
						|
			fields: fields{
 | 
						|
				Name:    "packA",
 | 
						|
				Version: "1.0.0",
 | 
						|
				Release: "a",
 | 
						|
			},
 | 
						|
			args: args{
 | 
						|
				stat: PackageFixStatus{
 | 
						|
					NotFixedYet: true,
 | 
						|
					FixedIn:     "1.0.1-b",
 | 
						|
					FixState:    "open",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			want: "packA-1.0.0-a -> open (FixedIn: 1.0.1-b)",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "nfy3",
 | 
						|
			fields: fields{
 | 
						|
				Name:    "packA",
 | 
						|
				Version: "1.0.0",
 | 
						|
				Release: "a",
 | 
						|
			},
 | 
						|
			args: args{
 | 
						|
				stat: PackageFixStatus{
 | 
						|
					NotFixedYet: true,
 | 
						|
					FixedIn:     "1.0.1-b",
 | 
						|
					FixState:    "open",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			want: "packA-1.0.0-a -> open (FixedIn: 1.0.1-b)",
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
			p := Package{
 | 
						|
				Name:             tt.fields.Name,
 | 
						|
				Version:          tt.fields.Version,
 | 
						|
				Release:          tt.fields.Release,
 | 
						|
				NewVersion:       tt.fields.NewVersion,
 | 
						|
				NewRelease:       tt.fields.NewRelease,
 | 
						|
				Arch:             tt.fields.Arch,
 | 
						|
				Repository:       tt.fields.Repository,
 | 
						|
				Changelog:        &tt.fields.Changelog,
 | 
						|
				AffectedProcs:    tt.fields.AffectedProcs,
 | 
						|
				NeedRestartProcs: tt.fields.NeedRestartProcs,
 | 
						|
			}
 | 
						|
			if got := p.FormatVersionFromTo(tt.args.stat); got != tt.want {
 | 
						|
				t.Errorf("Package.FormatVersionFromTo() = %v, want %v", got, tt.want)
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func Test_IsRaspbianPackage(t *testing.T) {
 | 
						|
	type args struct {
 | 
						|
		name string
 | 
						|
		ver  string
 | 
						|
	}
 | 
						|
	tests := []struct {
 | 
						|
		name   string
 | 
						|
		in     []args
 | 
						|
		expect []bool
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name: "nameRegExp",
 | 
						|
			in: []args{
 | 
						|
				{
 | 
						|
					name: "libraspberrypi-dev",
 | 
						|
					ver:  "1.20200811-1",
 | 
						|
				},
 | 
						|
				{
 | 
						|
					name: "rpi-eeprom",
 | 
						|
					ver:  "7.10-1",
 | 
						|
				},
 | 
						|
				{
 | 
						|
					name: "python3-rpi.gpio",
 | 
						|
					ver:  "0.7.0-0.1~bpo10+1",
 | 
						|
				},
 | 
						|
				{
 | 
						|
					name: "arping",
 | 
						|
					ver:  "2.19-6",
 | 
						|
				},
 | 
						|
				{
 | 
						|
					name: "pi-bluetooth",
 | 
						|
					ver:  "0.1.14",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			expect: []bool{true, true, true, false, true, false},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "verRegExp",
 | 
						|
			in: []args{
 | 
						|
				{
 | 
						|
					name: "ffmpeg",
 | 
						|
					ver:  "7:4.1.6-1~deb10u1+rpt1",
 | 
						|
				},
 | 
						|
				{
 | 
						|
					name: "gcc",
 | 
						|
					ver:  "4:8.3.0-1+rpi2",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			expect: []bool{true, true},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "nameList",
 | 
						|
			in: []args{
 | 
						|
				{
 | 
						|
					name: "piclone",
 | 
						|
					ver:  "0.16",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			expect: []bool{true},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name: "debianPackage",
 | 
						|
			in: []args{
 | 
						|
				{
 | 
						|
					name: "apt",
 | 
						|
					ver:  "1.8.2.1",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			expect: []bool{false},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
			for i, p := range tt.in {
 | 
						|
				ret := IsRaspbianPackage(p.name, p.ver)
 | 
						|
				if !reflect.DeepEqual(ret, tt.expect[i]) {
 | 
						|
					t.Errorf("[%s->%s] expected: %t, actual: %t, in: %#v", tt.name, tt.in[i].name, tt.expect[i], ret, tt.in[i])
 | 
						|
				}
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func Test_NewPortStat(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		name   string
 | 
						|
		args   string
 | 
						|
		expect PortStat
 | 
						|
	}{{
 | 
						|
		name: "empty",
 | 
						|
		args: "",
 | 
						|
		expect: PortStat{
 | 
						|
			BindAddress: "",
 | 
						|
			Port:        "",
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		name: "normal",
 | 
						|
		args: "127.0.0.1:22",
 | 
						|
		expect: PortStat{
 | 
						|
			BindAddress: "127.0.0.1",
 | 
						|
			Port:        "22",
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		name: "asterisk",
 | 
						|
		args: "*:22",
 | 
						|
		expect: PortStat{
 | 
						|
			BindAddress: "*",
 | 
						|
			Port:        "22",
 | 
						|
		},
 | 
						|
	}, {
 | 
						|
		name: "ipv6_loopback",
 | 
						|
		args: "[::1]:22",
 | 
						|
		expect: PortStat{
 | 
						|
			BindAddress: "[::1]",
 | 
						|
			Port:        "22",
 | 
						|
		},
 | 
						|
	}}
 | 
						|
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
			listenPort, err := NewPortStat(tt.args)
 | 
						|
			if err != nil {
 | 
						|
				t.Errorf("unexpected error occurred: %s", err)
 | 
						|
			} else if !reflect.DeepEqual(*listenPort, tt.expect) {
 | 
						|
				t.Errorf("base.NewPortStat() = %v, want %v", *listenPort, tt.expect)
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 |