Compare commits

..

9 Commits

Author SHA1 Message Date
yo
10201023f0 v0.6.3: BUGFIX: Append to current.godit so we do not block when file already exist 2023-12-22 09:42:42 +01:00
yo
3e4cdd6f35 Update readme 2023-12-18 14:00:28 +01:00
yo
f4314a8940 go version bump to 1.18 2023-12-18 13:13:51 +01:00
yo
30ea998620 v0.6.2 : Write to output file, SIGUSR1 will reopen output file so we can newsyslog 2023-12-18 11:55:23 +01:00
yo
e028ca7ee2 Write output to *bufio.Writer 2023-12-18 11:53:12 +01:00
yo
a1892cbe37 Bugfix when no input file specified 2023-09-11 16:14:33 +02:00
yo
9b849fad3a v0.6 2023-09-11 16:09:21 +02:00
yo
e9c7c7b744 Revert "v0.6"
This reverts commit 74ad307bd1b6587e8b0e93e0c4919b25ae63bcb3.
2023-09-11 16:08:20 +02:00
yo
74ad307bd1 v0.6 2023-09-11 16:05:39 +02:00
4 changed files with 105 additions and 33 deletions

View File

@ -8,3 +8,5 @@ See http://www.trustedbsd.org/openbsm.html
Include a binary "godit" which print audit logs in text or json format Include a binary "godit" which print audit logs in text or json format
Godit can read log files, /dev/auditpipe, or stdin with "-" Godit can read log files, /dev/auditpipe, or stdin with "-"
godit can be run as a service with included rc file. It needs audit to be configured to output to /dev/auditpipe.

2
go.mod
View File

@ -1,5 +1,5 @@
module godit module godit
go 1.17 go 1.18
require github.com/spf13/pflag v1.0.5 require github.com/spf13/pflag v1.0.5

View File

@ -156,7 +156,7 @@ type Record interface {
GetType() uint8 GetType() uint8
// Length() // Length()
LoadFromBinary(rdr *bufio.Reader) error LoadFromBinary(rdr *bufio.Reader) error
Print(*os.File, string, int) Print(*bufio.Writer, string, int)
} }
type Header32 struct { type Header32 struct {
@ -605,7 +605,7 @@ func (h *Header32) LoadFromBinary(rdr *bufio.Reader) error {
static void static void
print_header32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) print_header32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags)
*/ */
func (h *Header32) Print(file *os.File, delimiter string, flags int) { func (h *Header32) Print(file *bufio.Writer, delimiter string, flags int) {
var timeval string var timeval string
if PRT_TIMESYSLOG23 == flags&PRT_TIMESYSLOG23 { if PRT_TIMESYSLOG23 == flags&PRT_TIMESYSLOG23 {
timeval = time.Unix((int64)(h.S), 0).Add(time.Millisecond * (time.Duration)(h.Msec)).Format("2006-01-02T15:04:05.000Z07:00") timeval = time.Unix((int64)(h.S), 0).Add(time.Millisecond * (time.Duration)(h.Msec)).Format("2006-01-02T15:04:05.000Z07:00")
@ -704,7 +704,7 @@ func (e *ExecArg) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (e *ExecArg) Print(file *os.File, delimiter string, flags int) { func (e *ExecArg) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
// We don't need no count, bc we reconstiture command line // We don't need no count, bc we reconstiture command line
printable := struct { printable := struct {
@ -770,7 +770,7 @@ func (p *Path) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (p *Path) Print(file *os.File, delimiter string, flags int) { func (p *Path) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
// We don't need no length // We don't need no length
printable := struct { printable := struct {
@ -847,7 +847,7 @@ func (a *Attribute32) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (a *Attribute32) Print(file *os.File, delimiter string, flags int) { func (a *Attribute32) Print(file *bufio.Writer, delimiter string, flags int) {
var user string var user string
var group string var group string
@ -952,7 +952,7 @@ func (a *Attribute64) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (a *Attribute64) Print(file *os.File, delimiter string, flags int) { func (a *Attribute64) Print(file *bufio.Writer, delimiter string, flags int) {
var user string var user string
var group string var group string
// TODO : resolve Uid and Gid (also support domain accounts) // TODO : resolve Uid and Gid (also support domain accounts)
@ -1082,7 +1082,7 @@ func (s *Subject32) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (s *Subject32) Print(file *os.File, delimiter string, flags int) { func (s *Subject32) Print(file *bufio.Writer, delimiter string, flags int) {
var auser string var auser string
var euser string var euser string
var egroup string var egroup string
@ -1225,7 +1225,7 @@ func (p *Process32) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (p *Process32) Print(file *os.File, delimiter string, flags int) { func (p *Process32) Print(file *bufio.Writer, delimiter string, flags int) {
var auser string var auser string
var euser string var euser string
var egroup string var egroup string
@ -1386,7 +1386,7 @@ func (s *Subject32Ex) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (s *Subject32Ex) Print(file *os.File, delimiter string, flags int) { func (s *Subject32Ex) Print(file *bufio.Writer, delimiter string, flags int) {
var auser string var auser string
var euser string var euser string
var egroup string var egroup string
@ -1558,7 +1558,7 @@ func (p *Process32Ex) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (p *Process32Ex) Print(file *os.File, delimiter string, flags int) { func (p *Process32Ex) Print(file *bufio.Writer, delimiter string, flags int) {
var auser string var auser string
var euser string var euser string
var egroup string var egroup string
@ -1714,7 +1714,7 @@ func (s *Subject64) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (s *Subject64) Print(file *os.File, delimiter string, flags int) { func (s *Subject64) Print(file *bufio.Writer, delimiter string, flags int) {
var auser string var auser string
var euser string var euser string
var egroup string var egroup string
@ -1857,7 +1857,7 @@ func (p *Process64) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (p *Process64) Print(file *os.File, delimiter string, flags int) { func (p *Process64) Print(file *bufio.Writer, delimiter string, flags int) {
var auser string var auser string
var euser string var euser string
var egroup string var egroup string
@ -2017,7 +2017,7 @@ func (s *Subject64Ex) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (s *Subject64Ex) Print(file *os.File, delimiter string, flags int) { func (s *Subject64Ex) Print(file *bufio.Writer, delimiter string, flags int) {
var auser string var auser string
var euser string var euser string
var egroup string var egroup string
@ -2189,7 +2189,7 @@ func (p *Process64Ex) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (p *Process64Ex) Print(file *os.File, delimiter string, flags int) { func (p *Process64Ex) Print(file *bufio.Writer, delimiter string, flags int) {
var auser string var auser string
var euser string var euser string
var egroup string var egroup string
@ -2308,7 +2308,7 @@ func (r *Return32) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (r *Return32) Print(file *os.File, delimiter string, flags int) { func (r *Return32) Print(file *bufio.Writer, delimiter string, flags int) {
var errMsg string var errMsg string
errNo, err := lookupErrno(r.Status) errNo, err := lookupErrno(r.Status)
if err == nil { if err == nil {
@ -2369,7 +2369,7 @@ func (r *Return64) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (r *Return64) Print(file *os.File, delimiter string, flags int) { func (r *Return64) Print(file *bufio.Writer, delimiter string, flags int) {
var errMsg string var errMsg string
errNo, err := lookupErrno(r.Status) errNo, err := lookupErrno(r.Status)
if err == nil { if err == nil {
@ -2430,7 +2430,7 @@ func (t *Trailer) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (t *Trailer) Print(file *os.File, delimiter string, flags int) { func (t *Trailer) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
printable := struct { printable := struct {
Count uint32 `json:"length"` // Effective user ID Count uint32 `json:"length"` // Effective user ID
@ -2493,7 +2493,7 @@ func (a *Arg32) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (a *Arg32) Print(file *os.File, delimiter string, flags int) { func (a *Arg32) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
printable := struct { printable := struct {
Count uint32 `json:"count"` // Effective user ID Count uint32 `json:"count"` // Effective user ID
@ -2563,7 +2563,7 @@ func (a *Arg64) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (a *Arg64) Print(file *os.File, delimiter string, flags int) { func (a *Arg64) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
printable := struct { printable := struct {
Count uint32 `json:"count"` // Effective user ID Count uint32 `json:"count"` // Effective user ID
@ -2667,7 +2667,7 @@ func (s *SocketEx) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (s *SocketEx) Print(file *os.File, delimiter string, flags int) { func (s *SocketEx) Print(file *bufio.Writer, delimiter string, flags int) {
var lip string var lip string
var rip string var rip string
if s.AddrType == ISIPV4 { if s.AddrType == ISIPV4 {
@ -2732,7 +2732,7 @@ func (s *SockInet32) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (s *SockInet32) Print(file *os.File, delimiter string, flags int) { func (s *SockInet32) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
printable := struct { printable := struct {
Family uint16 `json:"family"` Family uint16 `json:"family"`
@ -2794,7 +2794,7 @@ func (s *SockInet128) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (s *SockInet128) Print(file *os.File, delimiter string, flags int) { func (s *SockInet128) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
printable := struct { printable := struct {
Family uint16 `json:"family"` Family uint16 `json:"family"`
@ -2852,7 +2852,7 @@ func (s *SockUnix) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (s *SockUnix) Print(file *os.File, delimiter string, flags int) { func (s *SockUnix) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
printable := struct { printable := struct {
Family uint16 `json:"family"` Family uint16 `json:"family"`
@ -2905,7 +2905,7 @@ func (e *Exit) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (e *Exit) Print(file *os.File, delimiter string, flags int) { func (e *Exit) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
j, err := json.Marshal(e) j, err := json.Marshal(e)
if err != nil { if err != nil {
@ -2953,7 +2953,7 @@ func (t *Text) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (t *Text) Print(file *os.File, delimiter string, flags int) { func (t *Text) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
j, err := json.Marshal(t) j, err := json.Marshal(t)
if err != nil { if err != nil {
@ -3001,7 +3001,7 @@ func (z *ZoneName) LoadFromBinary(rdr *bufio.Reader) error {
return nil return nil
} }
func (z *ZoneName) Print(file *os.File, delimiter string, flags int) { func (z *ZoneName) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
printable := struct { printable := struct {
Name string `json:"name"` Name string `json:"name"`
@ -3103,7 +3103,7 @@ func (c *Capabilities) MarshalJSON() ([]byte, error) {
return json.Marshal(cJSON) return json.Marshal(cJSON)
} }
func (r *Rights) Print(file *os.File, delimiter string, flags int) { func (r *Rights) Print(file *bufio.Writer, delimiter string, flags int) {
if flags&PRT_JSON == PRT_JSON { if flags&PRT_JSON == PRT_JSON {
// Do not print Rights.Length, only capabilities array // Do not print Rights.Length, only capabilities array
j, err := json.Marshal(r.Rights) j, err := json.Marshal(r.Rights)

80
main.go
View File

@ -27,13 +27,16 @@ import (
"io" "io"
"os" "os"
"fmt" "fmt"
"sync"
"bufio" "bufio"
"strings" "strings"
"syscall"
"os/signal"
"github.com/spf13/pflag" "github.com/spf13/pflag"
) )
const ( const (
version = "0.5.9c" version = "0.6.3"
) )
var ( var (
@ -42,19 +45,43 @@ var (
// Default delimiter // Default delimiter
delimiter = "," delimiter = ","
Writer *bufio.Writer
) )
func NewWriter(file string) (*bufio.Writer, *os.File, error) {
if len(file) > 0 {
var f *os.File
var err error
f, err = os.OpenFile(file, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0640)
if err != nil {
return nil, nil, err
}
Writer = bufio.NewWriter(f)
return Writer, f, nil
} else {
Writer = bufio.NewWriter(os.Stdout)
return Writer, nil, nil
}
}
func main() { func main() {
var flags int var flags int
var oneLine bool var oneLine bool
var noUserResolve bool var noUserResolve bool
var syslog23 bool var syslog23 bool
var json bool var json bool
var outputFile string
// Output file mutex
var outfMtx sync.Mutex
var outFile *os.File
pflag.BoolVarP(&oneLine, "oneline", "l", false, "Prints the entire record on the same line") pflag.BoolVarP(&oneLine, "oneline", "l", false, "Prints the entire record on the same line")
pflag.BoolVarP(&noUserResolve, "numeric", "n", false, "Do not convert user and group IDs to their names but leave in their numeric forms") pflag.BoolVarP(&noUserResolve, "numeric", "n", false, "Do not convert user and group IDs to their names but leave in their numeric forms")
pflag.BoolVarP(&json, "json", "j", false, "Print compact json") pflag.BoolVarP(&json, "json", "j", false, "Print compact json")
pflag.BoolVarP(&syslog23, "syslog23", "s", false, "Print time as \"2006-01-02T15:04:05.000Z07:00\", RFC339 with ms, also used on RSYSLOG_SyslogProtocol23Format. \"msec\" field will not be print in json output") pflag.BoolVarP(&syslog23, "syslog23", "s", false, "Print time as \"2006-01-02T15:04:05.000Z07:00\", RFC339 with ms, also used on RSYSLOG_SyslogProtocol23Format. \"msec\" field will not be print in json output")
pflag.StringVarP(&outputFile, "out", "o", "", "Output to file, overwrite existing. File will be re-opened receiving SIGUSR1.")
pflag.BoolVarP(&showVersion, "version", "V", false, "Show version and exit") pflag.BoolVarP(&showVersion, "version", "V", false, "Show version and exit")
var Usage = func() { var Usage = func() {
@ -84,11 +111,41 @@ func main() {
} }
args := os.Args args := os.Args
if len(os.Args) < 2 {
pflag.Usage()
os.Exit(1)
}
filename := args[len(args)-1] filename := args[len(args)-1]
// Get a writer, file or stdout
_, outFile, err := NewWriter(outputFile)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
if len(outputFile) > 0 {
// Manage output file rotation when receiving SIGUSR1
sig := make(chan os.Signal)
signal.Notify(sig, syscall.SIGUSR1)
go func() {
for {
<-sig
outfMtx.Lock()
fmt.Println("SIGUSR1 received, recreating output file")
outFile.Close()
_, outFile, err = NewWriter(outputFile)
if err != nil {
outfMtx.Unlock()
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
outfMtx.Unlock()
}
}()
}
var f *os.File var f *os.File
var r *bufio.Reader var r *bufio.Reader
var err error
if len(filename) > 0 { if len(filename) > 0 {
// If arg is "-", open stdin to read content // If arg is "-", open stdin to read content
if true == strings.EqualFold(filename, "-") { if true == strings.EqualFold(filename, "-") {
@ -96,13 +153,12 @@ func main() {
} else { } else {
f, err = os.Open(filename) f, err = os.Open(filename)
if err != nil { if err != nil {
fmt.Printf("Impossible d'ouvrir le fichier %s\n", filename) fmt.Fprintf(os.Stderr, "Impossible d'ouvrir le fichier %s\n", filename)
os.Exit(-1) os.Exit(-1)
} }
r = bufio.NewReader(f) r = bufio.NewReader(f)
} }
//for i := 0 ; i < 20 ; i++ {
for { for {
rec, err := readRecordToStruct(r) rec, err := readRecordToStruct(r)
if err != nil { if err != nil {
@ -112,7 +168,21 @@ func main() {
return return
} }
} }
rec.Print(os.Stdout, ",", flags) if len(outputFile) > 0 {
outfMtx.Lock()
rec.Print(Writer, ",", flags)
Writer.Flush() // Performance ?
outfMtx.Unlock()
} else {
// No need for mutex with stdout
rec.Print(Writer, ",", flags)
} }
} }
} }
if len(outputFile) > 0 && outFile != nil {
outfMtx.Lock()
outFile.Close()
outfMtx.Unlock()
}
}