buildAuditNetlinkMessage constructs a netlink audit message. This is separated from sendAuditMessage to allow testing the message format without requiring CAP_AUDIT_WRITE or a netlink socket.
(msgType uint16, message string)
| 48 | // This is separated from sendAuditMessage to allow testing the message format |
| 49 | // without requiring CAP_AUDIT_WRITE or a netlink socket. |
| 50 | func buildAuditNetlinkMessage(msgType uint16, message string) ([]byte, error) { |
| 51 | msgBytes := []byte(message) |
| 52 | if len(msgBytes) > maxAuditMessageLength { |
| 53 | msgBytes = msgBytes[:maxAuditMessageLength] |
| 54 | } |
| 55 | msgLen := len(msgBytes) |
| 56 | |
| 57 | totalLen := syscall.NLMSG_HDRLEN + msgLen |
| 58 | alignedLen := (totalLen + syscall.NLMSG_ALIGNTO - 1) & ^(syscall.NLMSG_ALIGNTO - 1) |
| 59 | |
| 60 | nlh := syscall.NlMsghdr{ |
| 61 | Len: uint32(totalLen), |
| 62 | Type: msgType, |
| 63 | Flags: nlmFRequest, |
| 64 | Seq: 1, |
| 65 | Pid: uint32(os.Getpid()), |
| 66 | } |
| 67 | |
| 68 | buf := bytes.NewBuffer(make([]byte, 0, alignedLen)) |
| 69 | if err := binary.Write(buf, binary.NativeEndian, nlh); err != nil { |
| 70 | return nil, err |
| 71 | } |
| 72 | buf.Write(msgBytes) |
| 73 | |
| 74 | for buf.Len() < alignedLen { |
| 75 | buf.WriteByte(0) |
| 76 | } |
| 77 | |
| 78 | return buf.Bytes(), nil |
| 79 | } |
| 80 | |
| 81 | // sendAuditMessage sends a message to the audit subsystem using raw netlink. |
| 82 | // It logs errors but does not return them. |
searching dependent graphs…