2017-08-23 17:36:27 +03:00
|
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
2016-07-27 21:30:26 +03:00
|
|
|
package libaudit
|
|
|
|
|
|
|
|
import (
|
2017-08-22 23:00:23 +03:00
|
|
|
"bufio"
|
2016-07-27 21:30:26 +03:00
|
|
|
"bytes"
|
2017-08-22 23:00:23 +03:00
|
|
|
"math/rand"
|
2016-07-27 21:30:26 +03:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
2017-08-22 23:00:23 +03:00
|
|
|
"strconv"
|
2016-07-27 21:30:26 +03:00
|
|
|
"strings"
|
|
|
|
"syscall"
|
|
|
|
"testing"
|
2017-08-22 23:00:23 +03:00
|
|
|
"time"
|
2016-07-27 21:30:26 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestWireFormat(t *testing.T) {
|
|
|
|
rr := NetlinkMessage{}
|
|
|
|
rr.Header.Len = uint32(syscall.NLMSG_HDRLEN + 4)
|
|
|
|
rr.Header.Type = syscall.AF_NETLINK
|
|
|
|
rr.Header.Flags = syscall.NLM_F_REQUEST | syscall.NLM_F_ACK
|
|
|
|
rr.Header.Seq = 2
|
2017-08-22 23:00:23 +03:00
|
|
|
|
2016-07-27 21:30:26 +03:00
|
|
|
data := make([]byte, 4)
|
2017-08-22 22:56:06 +03:00
|
|
|
hostEndian.PutUint32(data, 12)
|
2016-07-27 21:30:26 +03:00
|
|
|
rr.Data = append(rr.Data[:], data[:]...)
|
|
|
|
|
2017-08-22 23:00:23 +03:00
|
|
|
expected := []byte{20, 0, 0, 0, 16, 0, 5, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0}
|
|
|
|
result := rr.ToWireFormat()
|
|
|
|
if bytes.Compare(expected, result) != 0 {
|
|
|
|
t.Fatalf("ToWireFormat: resulting bytes unexpected")
|
|
|
|
}
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestNetlinkConnection(t *testing.T) {
|
2016-08-04 22:41:20 +03:00
|
|
|
if os.Getuid() != 0 {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Skipf("skipping test, not root user")
|
2016-08-04 22:41:20 +03:00
|
|
|
}
|
2016-07-27 21:30:26 +03:00
|
|
|
s, err := NewNetlinkConnection()
|
|
|
|
if err != nil {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Fatalf("NewNetlinkConnection: %v", err)
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
|
|
|
defer s.Close()
|
|
|
|
wb := newNetlinkAuditRequest(uint16(AUDIT_GET), syscall.AF_NETLINK, 0)
|
|
|
|
if err = s.Send(wb); err != nil {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Errorf("Send: %v", err)
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
2017-03-02 06:55:33 +03:00
|
|
|
_, err = auditGetReply(s, wb.Header.Seq, true)
|
2016-08-07 12:45:22 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("TestNetlinkConnection: test failed %v", err)
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSetters(t *testing.T) {
|
2017-08-22 23:00:23 +03:00
|
|
|
rand.Seed(time.Now().Unix())
|
2016-07-27 21:30:26 +03:00
|
|
|
var (
|
2017-08-22 23:00:23 +03:00
|
|
|
s *NetlinkConnection
|
|
|
|
pid = os.Getpid()
|
|
|
|
ratelimit = 20 + rand.Intn(480)
|
|
|
|
backlog = 20 + rand.Intn(480)
|
2016-07-27 21:30:26 +03:00
|
|
|
)
|
2016-08-04 22:41:20 +03:00
|
|
|
if os.Getuid() != 0 {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Skipf("skipping test, not root user")
|
|
|
|
}
|
|
|
|
s, err := NewNetlinkConnection()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("NewNetlinkConnection: %v", err)
|
2016-08-04 22:41:20 +03:00
|
|
|
}
|
2016-07-27 21:30:26 +03:00
|
|
|
defer s.Close()
|
2017-03-02 00:57:45 +03:00
|
|
|
err = AuditSetEnabled(s, true)
|
2016-07-27 21:30:26 +03:00
|
|
|
if err != nil {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Fatalf("AuditSetEnabled: %v", err)
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
2017-03-02 06:55:33 +03:00
|
|
|
auditstatus, err := AuditIsEnabled(s)
|
|
|
|
if err != nil {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Fatalf("AuditIsEnabled: %v", err)
|
2017-03-02 06:55:33 +03:00
|
|
|
}
|
|
|
|
if !auditstatus {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Fatalf("AuditIsEnabled returned false")
|
2017-03-02 06:55:33 +03:00
|
|
|
}
|
2017-08-22 23:00:23 +03:00
|
|
|
err = AuditSetRateLimit(s, ratelimit)
|
2016-07-27 21:30:26 +03:00
|
|
|
if err != nil {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Fatalf("AuditSetRateLimit: %v", err)
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
2017-08-22 23:00:23 +03:00
|
|
|
err = AuditSetBacklogLimit(s, backlog)
|
2016-07-27 21:30:26 +03:00
|
|
|
if err != nil {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Fatalf("AuditSetBacklogLimit: %v", err)
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
2017-08-22 23:00:23 +03:00
|
|
|
err = AuditSetPID(s, pid)
|
2016-07-27 21:30:26 +03:00
|
|
|
if err != nil {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Fatalf("AuditSetPID: %v", err)
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
|
|
|
|
2017-08-22 23:00:23 +03:00
|
|
|
// Use the external auditctl program to obtain the set values, and compare to what we
|
|
|
|
// expect
|
2016-07-27 21:30:26 +03:00
|
|
|
cmd := exec.Command("auditctl", "-s")
|
|
|
|
cmdOutput := &bytes.Buffer{}
|
|
|
|
cmd.Stdout = cmdOutput
|
|
|
|
if err := cmd.Run(); err != nil {
|
2017-08-22 23:00:23 +03:00
|
|
|
t.Fatalf("exec auditctl: %v", err)
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
|
|
|
|
2017-08-22 23:00:23 +03:00
|
|
|
scanner := bufio.NewScanner(cmdOutput)
|
|
|
|
for scanner.Scan() {
|
|
|
|
args := strings.Split(scanner.Text(), " ")
|
|
|
|
if len(args) < 2 {
|
|
|
|
t.Fatalf("auditctl: malformed output %q", scanner.Text())
|
|
|
|
}
|
|
|
|
switch args[0] {
|
|
|
|
case "enabled":
|
|
|
|
if args[1] != "1" {
|
|
|
|
t.Fatalf("enabled should have been 1")
|
|
|
|
}
|
|
|
|
case "pid":
|
|
|
|
v, err := strconv.Atoi(args[1])
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("pid argument was not an integer")
|
|
|
|
}
|
|
|
|
if v != pid {
|
|
|
|
t.Fatalf("pid should have been %v, was %v", pid, v)
|
|
|
|
}
|
|
|
|
case "rate_limit":
|
|
|
|
v, err := strconv.Atoi(args[1])
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("rate_limit argument was not an integer")
|
|
|
|
}
|
|
|
|
if v != ratelimit {
|
|
|
|
t.Fatalf("ratelimit should have been %v, was %v", ratelimit, v)
|
|
|
|
}
|
|
|
|
case "backlog_limit":
|
|
|
|
v, err := strconv.Atoi(args[1])
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("backlog_limit argument was not an integer")
|
|
|
|
}
|
|
|
|
if v != backlog {
|
|
|
|
t.Fatalf("backlog_limit should have been %v, was %v", backlog, v)
|
|
|
|
}
|
|
|
|
}
|
2016-07-27 21:30:26 +03:00
|
|
|
}
|
|
|
|
}
|