Skip to content

Commit 2f66468

Browse files
committed
chore(alertsenders): Create a common eventlog package
This package is a foundation for the future consolidation of the shared eventlog functionality. Additionally, it offers the function for construction of the event id from multiple components.
1 parent 14ed9a2 commit 2f66468

File tree

3 files changed

+138
-43
lines changed

3 files changed

+138
-43
lines changed

pkg/util/eventlog/eventid.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2021-2022 by Nedim Sabic Sabic
3+
* https://www.fibratus.io
4+
* All Rights Reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package eventlog
20+
21+
import "golang.org/x/sys/windows"
22+
23+
// EventID produces the eventlog event identifier from the given
24+
// severity and event code. The format of the event id
25+
// integer is described by the next layout:
26+
//
27+
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
28+
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
29+
//
30+
// +---+-+-+-----------------------+-------------------------------+
31+
// |Sev|C|R| Facility | Code |
32+
// +---+-+-+-----------------------+-------------------------------+
33+
func EventID(etype, code uint16) uint32 {
34+
var id uint32
35+
36+
// severity
37+
switch etype {
38+
case windows.EVENTLOG_INFORMATION_TYPE:
39+
id = uint32(0)<<30 | uint32(1)<<29
40+
case windows.EVENTLOG_WARNING_TYPE:
41+
id = uint32(1)<<30 | uint32(0)<<29
42+
case windows.EVENTLOG_ERROR_TYPE:
43+
id = uint32(1)<<30 | uint32(1)<<29
44+
default:
45+
id = uint32(0)<<30 | uint32(1)<<29
46+
}
47+
// customer bit
48+
id |= uint32(0) << 28
49+
// reserved bit
50+
id |= uint32(0) << 27
51+
// facility
52+
id |= uint32(0) << 15
53+
// code
54+
id |= uint32(code)
55+
56+
return id
57+
}

pkg/util/eventlog/eventid_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2021-2022 by Nedim Sabic Sabic
3+
* https://www.fibratus.io
4+
* All Rights Reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package eventlog
20+
21+
import (
22+
"fmt"
23+
"github.com/stretchr/testify/assert"
24+
"golang.org/x/sys/windows"
25+
"testing"
26+
)
27+
28+
func TestEventID(t *testing.T) {
29+
var tests = []struct {
30+
eid uint32
31+
expected uint32
32+
}{
33+
{
34+
EventID(windows.EVENTLOG_INFORMATION_TYPE, 3191),
35+
0x20000c77,
36+
},
37+
{
38+
EventID(windows.EVENTLOG_WARNING_TYPE, 3191),
39+
0x40000c77,
40+
},
41+
{
42+
EventID(windows.EVENTLOG_ERROR_TYPE, 3191),
43+
0x60000c77,
44+
},
45+
}
46+
47+
for _, tt := range tests {
48+
t.Run(fmt.Sprintf("%d", tt.expected), func(t *testing.T) {
49+
assert.Equal(t, tt.expected, tt.eid)
50+
})
51+
}
52+
}

pkg/util/eventlog/eventlog.go

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,27 @@ package eventlog
2020

2121
import (
2222
"fmt"
23+
"github.com/rabbitstack/fibratus/pkg/kevent/ktypes"
2324
"golang.org/x/sys/windows/registry"
2425
)
2526

27+
const (
28+
// Source represents the event source that generates the alerts
29+
Source = "Fibratus"
30+
// Levels designates the supported eventlog levels
31+
Levels = uint32(Info | Warn | Erro)
32+
// msgFile specifies the location of the eventlog message DLL
33+
msgFile = "%ProgramFiles%\\Fibratus\\fibratus.dll"
34+
// keyName represents the registry key under which the eventlog source is registered
35+
keyName = `SYSTEM\CurrentControlSet\Services\EventLog\Application`
36+
)
37+
38+
// ErrKeyExists signals that the registry key already exists
39+
var ErrKeyExists = fmt.Errorf("%s\\%s already exists", keyName, Source)
40+
41+
// categoryCount indicates the number of current event categories
42+
var categoryCount = uint32(len(ktypes.Categories()))
43+
2644
// Level is the type definition for the eventlog log level
2745
type Level uint16
2846

@@ -35,77 +53,45 @@ const (
3553
Erro Level = 1
3654
)
3755

38-
// LevelFromString resolves the eventlog levle from string
39-
func LevelFromString(s string) Level {
40-
switch s {
41-
case "info", "INFO":
42-
return Info
43-
case "warn", "warning", "WARN", "WARNING":
44-
return Warn
45-
case "erro", "error", "ERRO", "ERROR":
46-
return Erro
47-
default:
48-
panic(fmt.Sprintf("unrecognized evtlog level: %s", s))
49-
}
50-
}
51-
52-
// ErrKeyExists signals that the registry key already exists
53-
type ErrKeyExists struct {
54-
src string
55-
key string
56-
}
57-
58-
func (e ErrKeyExists) Error() string {
59-
return fmt.Sprintf("%s\\%s already exists", e.key, e.src)
60-
}
61-
6256
// Install modifies PC registry to allow logging with an event source src.
6357
// It adds all required keys and values to the event log registry key.
6458
// Install uses msgFile as the event message file. If useExpandKey is true,
6559
// the event message file is installed as REG_EXPAND_SZ value,
66-
// otherwise as REG_SZ. Use bitwise of log.Error, log.Warning and
67-
// log.Info to specify events supported by the new event source.
68-
func Install(src, f, key string, useExpandKey bool, eventsSupported, cats uint32) error {
69-
appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, key, registry.CREATE_SUB_KEY)
60+
// otherwise as REG_SZ. Use bitwise of Errr, Warn, and Info to specify events
61+
// supported by the new event source.
62+
func Install(eventsSupported uint32) error {
63+
key, err := registry.OpenKey(registry.LOCAL_MACHINE, keyName, registry.CREATE_SUB_KEY)
7064
if err != nil {
7165
return err
7266
}
73-
defer appkey.Close()
67+
defer key.Close()
7468

75-
sk, alreadyExist, err := registry.CreateKey(appkey, src, registry.SET_VALUE)
69+
sk, exists, err := registry.CreateKey(key, Source, registry.SET_VALUE)
7670
if err != nil {
7771
return err
7872
}
7973
defer sk.Close()
80-
if alreadyExist {
81-
return ErrKeyExists{src, key}
74+
if exists {
75+
return ErrKeyExists
8276
}
8377

8478
err = sk.SetDWordValue("CustomSource", 1)
8579
if err != nil {
8680
return err
8781
}
88-
if useExpandKey {
89-
err = sk.SetExpandStringValue("EventMessageFile", f)
90-
} else {
91-
err = sk.SetStringValue("EventMessageFile", f)
92-
}
82+
err = sk.SetExpandStringValue("EventMessageFile", msgFile)
9383
if err != nil {
9484
return err
9585
}
96-
if useExpandKey {
97-
err = sk.SetExpandStringValue("CategoryMessageFile", f)
98-
} else {
99-
err = sk.SetStringValue("CategoryMessageFile", f)
100-
}
86+
err = sk.SetExpandStringValue("CategoryMessageFile", msgFile)
10187
if err != nil {
10288
return err
10389
}
10490
err = sk.SetDWordValue("TypesSupported", eventsSupported)
10591
if err != nil {
10692
return err
10793
}
108-
err = sk.SetDWordValue("CategoryCount", cats)
94+
err = sk.SetDWordValue("CategoryCount", categoryCount)
10995
if err != nil {
11096
return err
11197
}

0 commit comments

Comments
 (0)