github.com/crowdsecurity/crowdsec@v1.6.1/pkg/acquisition/modules/syslog/syslog_test.go (about) 1 package syslogacquisition 2 3 import ( 4 "fmt" 5 "net" 6 "runtime" 7 "testing" 8 "time" 9 10 "github.com/crowdsecurity/go-cs-lib/cstest" 11 12 "github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration" 13 "github.com/crowdsecurity/crowdsec/pkg/types" 14 log "github.com/sirupsen/logrus" 15 "gopkg.in/tomb.v2" 16 17 "github.com/stretchr/testify/assert" 18 ) 19 20 func TestConfigure(t *testing.T) { 21 tests := []struct { 22 config string 23 expectedErr string 24 }{ 25 { 26 config: ` 27 foobar: bla 28 source: syslog`, 29 expectedErr: "line 2: field foobar not found in type syslogacquisition.SyslogConfiguration", 30 }, 31 { 32 config: `source: syslog`, 33 expectedErr: "", 34 }, 35 { 36 config: ` 37 source: syslog 38 listen_port: asd`, 39 expectedErr: "cannot unmarshal !!str `asd` into int", 40 }, 41 { 42 config: ` 43 source: syslog 44 listen_port: 424242`, 45 expectedErr: "invalid port 424242", 46 }, 47 { 48 config: ` 49 source: syslog 50 listen_addr: 10.0.0`, 51 expectedErr: "invalid listen IP 10.0.0", 52 }, 53 } 54 55 subLogger := log.WithFields(log.Fields{ 56 "type": "syslog", 57 }) 58 for _, test := range tests { 59 s := SyslogSource{} 60 err := s.Configure([]byte(test.config), subLogger, configuration.METRICS_NONE) 61 cstest.AssertErrorContains(t, err, test.expectedErr) 62 } 63 } 64 65 func writeToSyslog(logs []string) { 66 conn, err := net.Dial("udp", "127.0.0.1:4242") 67 if err != nil { 68 fmt.Printf("could not establish connection to syslog server : %s", err) 69 return 70 } 71 for _, log := range logs { 72 n, err := fmt.Fprint(conn, log) 73 if err != nil { 74 fmt.Printf("could not write to syslog server : %s", err) 75 return 76 } 77 if n != len(log) { 78 fmt.Printf("could not write to syslog server : %s", err) 79 return 80 } 81 } 82 } 83 84 func TestStreamingAcquisition(t *testing.T) { 85 tests := []struct { 86 name string 87 config string 88 expectedErr string 89 logs []string 90 expectedLines int 91 }{ 92 { 93 name: "invalid msgs", 94 config: `source: syslog 95 listen_port: 4242 96 listen_addr: 127.0.0.1`, 97 logs: []string{"foobar", "bla", "pouet"}, 98 }, 99 { 100 name: "RFC5424", 101 config: `source: syslog 102 listen_port: 4242 103 listen_addr: 127.0.0.1`, 104 expectedLines: 2, 105 logs: []string{`<13>1 2021-05-18T11:58:40.828081+02:00 mantis sshd 49340 - [timeQuality isSynced="0" tzKnown="1"] blabla`, 106 `<13>1 2021-05-18T12:12:37.560695+02:00 mantis sshd 49340 - [timeQuality isSynced="0" tzKnown="1"] blabla2[foobar]`}, 107 }, 108 { 109 name: "RFC3164", 110 config: `source: syslog 111 listen_port: 4242 112 listen_addr: 127.0.0.1`, 113 expectedLines: 3, 114 logs: []string{`<13>May 18 12:37:56 mantis sshd[49340]: blabla2[foobar]`, 115 `<13>May 18 12:37:56 mantis sshd[49340]: blabla2`, 116 `<13>May 18 12:37:56 mantis sshd: blabla2`, 117 `<13>May 18 12:37:56 mantis sshd`}, 118 }, 119 } 120 if runtime.GOOS != "windows" { 121 tests = append(tests, struct { 122 name string 123 config string 124 expectedErr string 125 logs []string 126 expectedLines int 127 }{ 128 name: "privileged port", 129 config: `source: syslog`, 130 expectedErr: "could not start syslog server: could not listen on port 514: listen udp 127.0.0.1:514: bind: permission denied", 131 }) 132 } 133 134 for _, ts := range tests { 135 ts := ts 136 t.Run(ts.name, func(t *testing.T) { 137 subLogger := log.WithFields(log.Fields{ 138 "type": "syslog", 139 }) 140 s := SyslogSource{} 141 err := s.Configure([]byte(ts.config), subLogger, configuration.METRICS_NONE) 142 if err != nil { 143 t.Fatalf("could not configure syslog source : %s", err) 144 } 145 tomb := tomb.Tomb{} 146 out := make(chan types.Event) 147 err = s.StreamingAcquisition(out, &tomb) 148 cstest.AssertErrorContains(t, err, ts.expectedErr) 149 if ts.expectedErr != "" { 150 return 151 } 152 if err != nil && ts.expectedErr == "" { 153 t.Fatalf("unexpected error while starting syslog server: %s", err) 154 return 155 } 156 157 actualLines := 0 158 go writeToSyslog(ts.logs) 159 READLOOP: 160 for { 161 select { 162 case <-out: 163 actualLines++ 164 case <-time.After(2 * time.Second): 165 break READLOOP 166 } 167 } 168 assert.Equal(t, ts.expectedLines, actualLines) 169 tomb.Kill(nil) 170 tomb.Wait() 171 }) 172 } 173 }