syslog_test.go 3.8 KB

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