github.com/mholt/caddy-l4@v0.0.0-20241104153248-ec8fae209322/modules/l4winbox/matcher_test.go (about) 1 // Copyright 2024 VNXME 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package l4winbox 16 17 import ( 18 "bytes" 19 "context" 20 "errors" 21 "io" 22 "net" 23 "testing" 24 25 "github.com/caddyserver/caddy/v2" 26 "go.uber.org/zap" 27 28 "github.com/mholt/caddy-l4/layer4" 29 ) 30 31 func assertNoError(t *testing.T, err error) { 32 t.Helper() 33 if err != nil && !errors.Is(err, io.EOF) && !errors.Is(err, io.ErrUnexpectedEOF) { 34 t.Fatalf("Unexpected error: %s\n", err) 35 } 36 } 37 38 func Test_MessageAuth_FromBytes_ToBytes(t *testing.T) { 39 var msg *MessageAuth 40 var err error 41 for _, packet := range [][]byte{packetS1, packetS2, packetR1, packetR2} { 42 msg = &MessageAuth{} 43 if err = msg.FromBytes(packet); err != nil { 44 t.Fatalf("Failed to parse MessageAuth from bytes: %s\n", err) 45 } 46 if !bytes.Equal(packet, msg.ToBytes()) { 47 t.Fatalf("Bytes don't match.\nExpected: %x\nComposed: %x", packet, msg.ToBytes()) 48 } 49 } 50 } 51 52 func Test_MatchWinbox_Match(t *testing.T) { 53 type test struct { 54 matcher *MatchWinbox 55 data []byte 56 shouldMatch bool 57 } 58 59 m0 := &MatchWinbox{} 60 m1 := &MatchWinbox{Modes: []string{ModeStandard}} 61 m2 := &MatchWinbox{Modes: []string{ModeRoMON}} 62 m3 := &MatchWinbox{Username: "toms"} 63 m4 := &MatchWinbox{UsernameRegexp: "^andris|edgars|juris$"} 64 65 tests := []test{ 66 {matcher: m0, data: packetS1[:len(packetS1)-1], shouldMatch: false}, 67 {matcher: m0, data: packetS2[:len(packetS2)-1], shouldMatch: false}, 68 {matcher: m0, data: packetR1[:len(packetR1)-1], shouldMatch: false}, 69 {matcher: m0, data: packetR2[:len(packetR2)-1], shouldMatch: false}, 70 71 {matcher: m0, data: packetS1, shouldMatch: true}, 72 {matcher: m0, data: packetS2, shouldMatch: true}, 73 {matcher: m0, data: packetR1, shouldMatch: true}, 74 {matcher: m0, data: packetR2, shouldMatch: true}, 75 76 {matcher: m1, data: packetS1, shouldMatch: true}, 77 {matcher: m1, data: packetS2, shouldMatch: true}, 78 {matcher: m1, data: packetR1, shouldMatch: false}, 79 {matcher: m1, data: packetR2, shouldMatch: false}, 80 81 {matcher: m2, data: packetS1, shouldMatch: false}, 82 {matcher: m2, data: packetS2, shouldMatch: false}, 83 {matcher: m2, data: packetR1, shouldMatch: true}, 84 {matcher: m2, data: packetR2, shouldMatch: true}, 85 86 {matcher: m3, data: packetS1, shouldMatch: true}, 87 {matcher: m3, data: packetS2, shouldMatch: false}, 88 {matcher: m3, data: packetR1, shouldMatch: true}, 89 {matcher: m3, data: packetR2, shouldMatch: false}, 90 91 {matcher: m4, data: packetS1, shouldMatch: false}, 92 {matcher: m4, data: packetS2, shouldMatch: true}, 93 {matcher: m4, data: packetR1, shouldMatch: false}, 94 {matcher: m4, data: packetR2, shouldMatch: true}, 95 } 96 97 ctx, cancel := caddy.NewContext(caddy.Context{Context: context.Background()}) 98 defer cancel() 99 100 for i, tc := range tests { 101 func() { 102 err := tc.matcher.Provision(ctx) 103 assertNoError(t, err) 104 105 in, out := net.Pipe() 106 defer func() { 107 _, _ = io.Copy(io.Discard, out) 108 _ = out.Close() 109 }() 110 111 cx := layer4.WrapConnection(out, []byte{}, zap.NewNop()) 112 go func() { 113 _, err := in.Write(tc.data) 114 assertNoError(t, err) 115 _ = in.Close() 116 }() 117 118 matched, err := tc.matcher.Match(cx) 119 assertNoError(t, err) 120 121 if matched != tc.shouldMatch { 122 if tc.shouldMatch { 123 t.Fatalf("Test %d: matcher did not match | %+v\n", i, tc.matcher) 124 } else { 125 t.Fatalf("Test %d: matcher should not match | %+v\n", i, tc.matcher) 126 } 127 } 128 }() 129 } 130 } 131 132 // Packet examples 133 var packetS1 = []byte{38, 6, 116, 111, 109, 115, 0, 16, 224, 171, 254, 156, 62, 32, 96, 105, 79, 183, 32, 18, 98, 154, 210, 88, 231, 107, 124, 235, 252, 112, 176, 226, 63, 148, 136, 155, 149, 250, 151, 0} 134 var packetS2 = []byte{40, 6, 97, 110, 100, 114, 105, 115, 0, 14, 185, 111, 184, 198, 199, 177, 230, 112, 205, 86, 92, 179, 165, 60, 173, 240, 56, 44, 175, 102, 201, 198, 26, 252, 174, 71, 206, 89, 58, 169, 17, 1} 135 var packetR1 = []byte{40, 6, 116, 111, 109, 115, 43, 114, 0, 65, 165, 44, 39, 101, 48, 138, 138, 139, 207, 103, 177, 231, 74, 148, 181, 203, 140, 104, 13, 19, 95, 116, 84, 172, 115, 20, 170, 6, 178, 163, 172, 0} 136 var packetR2 = []byte{42, 6, 97, 110, 100, 114, 105, 115, 43, 114, 0, 18, 158, 36, 11, 95, 8, 113, 35, 73, 92, 164, 206, 35, 223, 100, 63, 183, 98, 232, 182, 51, 93, 1, 56, 212, 183, 106, 169, 185, 69, 244, 81, 0}