Advertisement
Guest User

Untitled

a guest
Jan 29th, 2015
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.46 KB | None | 0 0
  1. package netlinkAudit
  2.  
  3. import (
  4. "bytes"
  5. "encoding/binary"
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "io/ioutil"
  10. "log"
  11. "os"
  12. "strconv"
  13. "strings"
  14. "sync/atomic"
  15. "syscall"
  16. "unsafe"
  17. )
  18.  
  19. var ParsedResult AuditStatus
  20. var nextSeqNr uint32
  21. var rulesRetrieved AuditRuleData
  22.  
  23. type AuditStatus struct {
  24. Mask uint32 /* Bit mask for valid entries */
  25. Enabled uint32 /* 1 = enabled, 0 = disabled */
  26. Failure uint32 /* Failure-to-log action */
  27. Pid uint32 /* pid of auditd process */
  28. Rate_limit uint32 /* messages rate limit (per second) */
  29. Backlog_limit uint32 /* waiting messages limit */
  30. Lost uint32 /* messages lost */
  31. Backlog uint32 /* messages waiting in queue */
  32. }
  33.  
  34. type AuditRuleData struct {
  35. Flags uint32 /* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
  36. Action uint32 /* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
  37. Field_count uint32
  38. Mask [AUDIT_BITMASK_SIZE]uint32 /* syscall(s) affected */
  39. Fields [AUDIT_MAX_FIELDS]uint32
  40. Values [AUDIT_MAX_FIELDS]uint32
  41. Fieldflags [AUDIT_MAX_FIELDS]uint32
  42. Buflen uint32 /* total length of string fields */
  43. Buf []byte //[0]byte /* string fields buffer */
  44. }
  45.  
  46. type NetlinkSocket struct {
  47. fd int
  48. lsa syscall.SockaddrNetlink
  49. }
  50.  
  51. type NetlinkAuditRequest struct {
  52. Header syscall.NlMsghdr
  53. Data []byte
  54. }
  55.  
  56. // for config
  57. type CMap struct {
  58. Name string
  59. Id int
  60. }
  61.  
  62. //for fieldtab
  63. type FMap struct {
  64. Name string
  65. Fieldid float64
  66. }
  67.  
  68. // for config
  69. type Config struct {
  70. Xmap []CMap
  71. }
  72.  
  73. type Field struct {
  74. Fieldmap []FMap
  75. }
  76.  
  77. func nativeEndian() binary.ByteOrder {
  78. var x uint32 = 0x01020304
  79. if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
  80. return binary.BigEndian
  81. }
  82. return binary.LittleEndian
  83. }
  84.  
  85. func (rule *AuditRuleData) ToWireFormat() []byte {
  86.  
  87. newbuff := make([]byte, int(unsafe.Sizeof(*rule))+int(rule.Buflen))
  88. *(*uint32)(unsafe.Pointer(&newbuff[0:4][0])) = rule.Flags
  89. *(*uint32)(unsafe.Pointer(&newbuff[4:8][0])) = rule.Action
  90. *(*uint32)(unsafe.Pointer(&newbuff[8:12][0])) = rule.Field_count
  91. *(*[AUDIT_BITMASK_SIZE]uint32)(unsafe.Pointer(&newbuff[12:268][0])) = rule.Mask
  92. *(*[AUDIT_MAX_FIELDS]uint32)(unsafe.Pointer(&newbuff[268:524][0])) = rule.Fields
  93. *(*[AUDIT_MAX_FIELDS]uint32)(unsafe.Pointer(&newbuff[524:780][0])) = rule.Values
  94. *(*[AUDIT_MAX_FIELDS]uint32)(unsafe.Pointer(&newbuff[780:1036][0])) = rule.Fieldflags
  95. *(*uint32)(unsafe.Pointer(&newbuff[1036:1040][0])) = rule.Buflen
  96. copy(newbuff[1040:1040+rule.Buflen], rule.Buf[:])
  97. return newbuff
  98. }
  99.  
  100. //recvfrom in go takes only a byte [] to put the data recieved from the kernel that removes the need
  101. //for having a separate audit_reply Struct for recieving data from kernel.
  102. func (rr *NetlinkAuditRequest) ToWireFormat() []byte {
  103. b := make([]byte, rr.Header.Len)
  104. *(*uint32)(unsafe.Pointer(&b[0:4][0])) = rr.Header.Len
  105. *(*uint16)(unsafe.Pointer(&b[4:6][0])) = rr.Header.Type
  106. *(*uint16)(unsafe.Pointer(&b[6:8][0])) = rr.Header.Flags
  107. *(*uint32)(unsafe.Pointer(&b[8:12][0])) = rr.Header.Seq
  108. *(*uint32)(unsafe.Pointer(&b[12:16][0])) = rr.Header.Pid
  109. b = append(b[:16], rr.Data[:]...) //Important b[:16]
  110. return b
  111. }
  112.  
  113. func newNetlinkAuditRequest(proto, family, sizeofData int) *NetlinkAuditRequest {
  114. rr := &NetlinkAuditRequest{}
  115.  
  116. rr.Header.Len = uint32(syscall.NLMSG_HDRLEN + sizeofData)
  117. rr.Header.Type = uint16(proto)
  118. rr.Header.Flags = syscall.NLM_F_REQUEST | syscall.NLM_F_ACK
  119. rr.Header.Seq = atomic.AddUint32(&nextSeqNr, 1) //Autoincrementing Sequence
  120. return rr
  121. // return rr.ToWireFormat()
  122. }
  123.  
  124. // Round the length of a netlink message up to align it properly.
  125. func nlmAlignOf(msglen int) int {
  126. return (msglen + syscall.NLMSG_ALIGNTO - 1) & ^(syscall.NLMSG_ALIGNTO - 1)
  127. }
  128.  
  129. // Parse a byte stream to an array of NetlinkMessage structs
  130. func ParseAuditNetlinkMessage(b []byte) ([]syscall.NetlinkMessage, error) {
  131.  
  132. var msgs []syscall.NetlinkMessage
  133. h, dbuf, dlen, err := netlinkMessageHeaderAndData(b)
  134. if err != nil {
  135. log.Println("Error in parsing")
  136. return nil, err
  137. }
  138.  
  139. m := syscall.NetlinkMessage{Header: *h, Data: dbuf[:int(h.Len) /* -syscall.NLMSG_HDRLEN*/]}
  140. msgs = append(msgs, m)
  141. b = b[dlen:]
  142.  
  143. return msgs, nil
  144. }
  145.  
  146. // Internal Function, uses unsafe pointer conversions for separating Netlink Header and the Data appended with it
  147. func netlinkMessageHeaderAndData(b []byte) (*syscall.NlMsghdr, []byte, int, error) {
  148.  
  149. h := (*syscall.NlMsghdr)(unsafe.Pointer(&b[0]))
  150. if int(h.Len) < syscall.NLMSG_HDRLEN || int(h.Len) > len(b) {
  151. foo := int32(nativeEndian().Uint32(b[0:4]))
  152. log.Println("Headerlength with ", foo, b[0]) //bug!
  153. log.Println("Error due to....HDRLEN:", syscall.NLMSG_HDRLEN, " Header Length:", h.Len, " Length of BYTE Array:", len(b))
  154. return nil, nil, 0, syscall.EINVAL
  155. }
  156. return h, b[syscall.NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil
  157. }
  158.  
  159. //Connect with kernel space and is to be used for all further socket communication
  160. func GetNetlinkSocket() (*NetlinkSocket, error) {
  161. fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_AUDIT)
  162. if err != nil {
  163. return nil, err
  164. }
  165. s := &NetlinkSocket{
  166. fd: fd,
  167. }
  168. s.lsa.Family = syscall.AF_NETLINK
  169. s.lsa.Groups = 0
  170. s.lsa.Pid = 0 //Kernel space pid is always set to be 0
  171.  
  172. if err := syscall.Bind(fd, &s.lsa); err != nil {
  173. syscall.Close(fd)
  174. return nil, err
  175. }
  176. return s, nil
  177. }
  178.  
  179. //To end the socket conncetion
  180. func (s *NetlinkSocket) Close() {
  181. syscall.Close(s.fd)
  182. }
  183.  
  184. // Wrapper for Sendto
  185. func (s *NetlinkSocket) Send(request *NetlinkAuditRequest) error {
  186. if err := syscall.Sendto(s.fd, request.ToWireFormat(), 0, &s.lsa); err != nil {
  187. return err
  188. }
  189. return nil
  190. }
  191.  
  192. // Wrapper for Recvfrom
  193. func (s *NetlinkSocket) Receive(bytesize int, block int) ([]syscall.NetlinkMessage, error) {
  194. rb := make([]byte, bytesize)
  195. nr, _, err := syscall.Recvfrom(s.fd, rb, 0|block)
  196. //nr, _, err := syscall.Recvfrom(s, rb, syscall.MSG_PEEK|syscall.MSG_DONTWAIT)
  197.  
  198. if err != nil {
  199. return nil, err
  200. }
  201. if nr < syscall.NLMSG_HDRLEN {
  202. return nil, syscall.EINVAL
  203. }
  204. rb = rb[:nr]
  205. return ParseAuditNetlinkMessage(rb)
  206. }
  207.  
  208. //HandleAck ?
  209. func AuditGetReply(s *NetlinkSocket, bytesize, block int, seq uint32) error {
  210. done:
  211. for {
  212. msgs, err := s.Receive(bytesize, block) //ParseAuditNetlinkMessage(rb)
  213. if err != nil {
  214. return err
  215. }
  216. for _, m := range msgs {
  217. lsa, err := syscall.Getsockname(s.fd)
  218. if err != nil {
  219. return err
  220. }
  221. switch v := lsa.(type) {
  222. case *syscall.SockaddrNetlink:
  223.  
  224. if m.Header.Seq != seq {
  225. return fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, seq)
  226. }
  227. if m.Header.Pid != v.Pid {
  228. return fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, v.Pid)
  229. }
  230. default:
  231. return syscall.EINVAL
  232. }
  233.  
  234. if m.Header.Type == syscall.NLMSG_DONE {
  235. break done
  236. }
  237. if m.Header.Type == syscall.NLMSG_ERROR {
  238. error := int32(nativeEndian().Uint32(m.Data[0:4]))
  239. if error == 0 {
  240. log.Println("Acknowledged!!")
  241. break done
  242. } else {
  243. log.Println("NLMSG_ERROR Received..")
  244. }
  245. break done
  246. }
  247. if m.Header.Type == AUDIT_GET {
  248. log.Println("AUDIT_GET")
  249. break done
  250. }
  251. }
  252. }
  253. return nil
  254. }
  255.  
  256. // Sends a message to kernel to turn on audit
  257. func AuditSetEnabled(s *NetlinkSocket) error {
  258. var status AuditStatus
  259. status.Enabled = 1
  260. status.Mask = AUDIT_STATUS_ENABLED
  261. buff := new(bytes.Buffer)
  262. err := binary.Write(buff, nativeEndian(), status)
  263. if err != nil {
  264. log.Println("binary.Write failed:", err)
  265. return err
  266. }
  267.  
  268. wb := newNetlinkAuditRequest(AUDIT_SET, syscall.AF_NETLINK, int(unsafe.Sizeof(status)))
  269. wb.Data = append(wb.Data[:], buff.Bytes()[:]...)
  270. if err := s.Send(wb); err != nil {
  271. return err
  272. }
  273.  
  274. // Receiving IN JUST ONE TRY
  275. err = AuditGetReply(s, syscall.Getpagesize(), 0, wb.Header.Seq)
  276. if err != nil {
  277. return err
  278. }
  279. return nil
  280. }
  281.  
  282. // Sends a signal to kernel to check if Audit is enabled
  283. func AuditIsEnabled(s *NetlinkSocket) error {
  284. wb := newNetlinkAuditRequest(AUDIT_GET, syscall.AF_NETLINK, 0)
  285.  
  286. if err := s.Send(wb); err != nil {
  287. return err
  288. }
  289.  
  290. done:
  291. for {
  292. //Make the rb byte bigger because of large messages from Kernel doesn't fit in 4096
  293. msgs, err := s.Receive(MAX_AUDIT_MESSAGE_LENGTH,0) //ADD syscall.MSG_DONWAIT
  294. if err != nil {
  295. return err
  296. }
  297.  
  298. for _, m := range msgs {
  299. lsa, er := syscall.Getsockname(s.fd)
  300. if er != nil {
  301. return nil
  302. }
  303. switch v := lsa.(type) {
  304. case *syscall.SockaddrNetlink:
  305. if m.Header.Seq != uint32(wb.Header.Seq) {
  306. return fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, wb.Header.Seq)
  307. }
  308. if m.Header.Pid != v.Pid {
  309. return fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, v.Pid)
  310. }
  311.  
  312. default:
  313. return syscall.EINVAL
  314. }
  315. if m.Header.Type == syscall.NLMSG_DONE {
  316. log.Println("Done")
  317. break done
  318.  
  319. }
  320. if m.Header.Type == syscall.NLMSG_ERROR {
  321. log.Println("NLMSG_ERROR Received..")
  322. }
  323. if m.Header.Type == AUDIT_GET {
  324. //Convert the data part written to AuditStatus struct
  325. b := m.Data[:]
  326. // h := (*AuditStatus)(unsafe.Pointer(&b[0])) Unsafe Method avoided
  327. buf := bytes.NewBuffer(b)
  328. var dumm AuditStatus
  329. err = binary.Read(buf, nativeEndian(), &dumm)
  330. if err != nil {
  331. log.Println("binary.Read failed:", err)
  332. return err
  333. }
  334. ParsedResult = dumm
  335. break done
  336. }
  337. }
  338. }
  339. return nil
  340. }
  341.  
  342. // Sends a message to kernel for setting of program pid
  343. func AuditSetPid(s *NetlinkSocket, pid uint32 /*,Wait mode WAIT_YES | WAIT_NO */) error {
  344. var status AuditStatus
  345. status.Mask = AUDIT_STATUS_PID
  346. status.Pid = pid
  347. buff := new(bytes.Buffer)
  348. err := binary.Write(buff, nativeEndian(), status)
  349. if err != nil {
  350. log.Println("binary.Write failed:", err)
  351. return err
  352. }
  353.  
  354. wb := newNetlinkAuditRequest(AUDIT_SET, syscall.AF_NETLINK, int(unsafe.Sizeof(status)))
  355. wb.Data = append(wb.Data[:], buff.Bytes()[:]...)
  356. if err := s.Send(wb); err != nil {
  357. return err
  358. }
  359.  
  360. err = AuditGetReply(s, syscall.Getpagesize(), 0, wb.Header.Seq)
  361. if err != nil {
  362. return err
  363. }
  364. //Polling in GO Is it needed ?
  365. return nil
  366. }
  367.  
  368. func auditWord(nr int) uint32 {
  369. audit_word := (uint32)((nr) / 32)
  370. return (uint32)(audit_word)
  371. }
  372.  
  373. func auditBit(nr int) uint32 {
  374. audit_bit := 1 << ((uint32)(nr) - auditWord(nr)*32)
  375. return (uint32)(audit_bit)
  376. }
  377.  
  378. // Make changes in the rule struct according to system call number
  379. func AuditRuleSyscallData(rule *AuditRuleData, scall int) error {
  380. word := auditWord(scall)
  381. bit := auditBit(scall)
  382.  
  383. if word >= AUDIT_BITMASK_SIZE-1 {
  384. return fmt.Errorf("Word Size greater than AUDIT_BITMASK_SIZE")
  385. }
  386. rule.Mask[word] |= bit
  387. return nil
  388. }
  389.  
  390. /*
  391. Requires More work
  392. func AuditWatchRuleData(s *NetlinkSocket, rule *AuditRuleData, path []byte) error {
  393. rule.Flags = uint32(AUDIT_FILTER_EXIT)
  394. rule.Action = uint32(AUDIT_ALWAYS)
  395. // set mask
  396. rule.Field_count = uint32(2)
  397. rule.Fields[0] = uint32(105)
  398. rule.Values[0] = uint32(len(path))
  399. rule.Fieldflags[0] = uint32(AUDIT_EQUAL)
  400. rule.Buflen = uint32(len(path))
  401. rule.Buf = append(rule.Buf[:], path[:]...)
  402.  
  403. buff := new(bytes.Buffer)
  404. err := binary.Write(buff, nativeEndian(), *rule)
  405. if err != nil {
  406. log.Println("binary.Write failed:", err)
  407. return err
  408. }
  409.  
  410. wb := newNetlinkAuditRequest(AUDIT_ADD_RULE, syscall.AF_NETLINK, int(buff.Len())+int(rule.Buflen))
  411. wb.Data = append(wb.Data[:], buff.Bytes()[:]...)
  412. if err := s.Send(wb); err != nil {
  413. return err
  414. }
  415.  
  416. return nil
  417. }
  418. */
  419. func AuditSetRateLimit(s *NetlinkSocket, limit int) error {
  420. var foo AuditStatus
  421. foo.Mask = AUDIT_STATUS_RATE_LIMIT
  422. foo.Rate_limit = (uint32)(limit)
  423. buff := new(bytes.Buffer)
  424. err := binary.Write(buff, nativeEndian(), foo)
  425. if err != nil {
  426. log.Println("binary.Write failed:", err)
  427. return err
  428. }
  429.  
  430. wb := newNetlinkAuditRequest(AUDIT_SET, syscall.AF_NETLINK, int(unsafe.Sizeof(foo)))
  431. wb.Data = append(wb.Data[:], buff.Bytes()[:]...)
  432. if err := s.Send(wb); err != nil {
  433. return err
  434. }
  435.  
  436. err = AuditGetReply(s, syscall.Getpagesize(), 0, wb.Header.Seq)
  437. if err != nil {
  438. return err
  439. }
  440. return nil
  441.  
  442. }
  443.  
  444. func AuditSetBacklogLimit(s *NetlinkSocket, limit int) error {
  445. var foo AuditStatus
  446. foo.Mask = AUDIT_STATUS_BACKLOG_LIMIT
  447. foo.Backlog_limit = (uint32)(limit)
  448. buff := new(bytes.Buffer)
  449. err := binary.Write(buff, nativeEndian(), foo)
  450. if err != nil {
  451. log.Println("binary.Write failed:", err)
  452. return err
  453. }
  454.  
  455. wb := newNetlinkAuditRequest(AUDIT_SET, syscall.AF_NETLINK, int(unsafe.Sizeof(foo)))
  456. wb.Data = append(wb.Data[:], buff.Bytes()[:]...)
  457. if err := s.Send(wb); err != nil {
  458. return err
  459. }
  460.  
  461. err = AuditGetReply(s, syscall.Getpagesize(), 0, wb.Header.Seq)
  462. if err != nil {
  463. return err
  464. }
  465. return nil
  466.  
  467. }
  468.  
  469. var errEntryDep = errors.New("Use of entry filter is deprecated")
  470.  
  471. func AuditAddRuleData(s *NetlinkSocket, rule *AuditRuleData, flags int, action int) error {
  472.  
  473. if flags == AUDIT_FILTER_ENTRY {
  474. log.Println("Use of entry filter is deprecated")
  475. return errEntryDep
  476. }
  477.  
  478. rule.Flags = uint32(flags)
  479. rule.Action = uint32(action)
  480. // Using unsafe for conversion
  481. newbuff := rule.ToWireFormat()
  482. // Following method avoided as it require the 0 byte array to be fixed size array
  483. // buff := new(bytes.Buffer)
  484. // err := binary.Write(buff, nativeEndian(), *rule)
  485. // if err != nil {
  486. // log.Println("binary.Write failed:", err)
  487. // return err
  488. // }
  489. // wb := newNetlinkAuditRequest(AUDIT_ADD_RULE, syscall.AF_NETLINK, int(buff.Len())+int(rule.Buflen))
  490. // wb.Data = append(wb.Data[:], buff.Bytes()[:]...)
  491.  
  492. newwb := newNetlinkAuditRequest(AUDIT_ADD_RULE, syscall.AF_NETLINK, len(newbuff) /*+int(rule.Buflen)*/) //Length of newbuff takes care of Rule.buf too
  493. newwb.Data = append(newwb.Data[:], newbuff[:]...)
  494. var err error
  495. if err = s.Send(newwb); err != nil {
  496. return err
  497. }
  498.  
  499. if err != nil {
  500. log.Println("Error sending add rule data request")
  501. return err
  502. }
  503. return nil
  504. }
  505. func isDone(msgchan chan string, errchan chan error, done <-chan bool) bool {
  506. var d bool
  507. select {
  508. case d = <-done:
  509. close(msgchan)
  510. close(errchan)
  511. default:
  512. }
  513. return d
  514. }
  515.  
  516. //For Debugging Purposes
  517. func GetreplyWithoutSync(s *NetlinkSocket) {
  518. f, err := os.OpenFile("log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0660)
  519. if err != nil {
  520. log.Println("Error Creating File!!")
  521. return
  522. }
  523. defer f.Close()
  524. for {
  525. rb := make([]byte, MAX_AUDIT_MESSAGE_LENGTH)
  526. nr, _, err := syscall.Recvfrom(s.fd, rb, 0)
  527. if err != nil {
  528. log.Println("Error While Recieving !!")
  529. continue
  530. }
  531. if nr < syscall.NLMSG_HDRLEN {
  532. log.Println("Message Too Short!!")
  533. continue
  534. }
  535.  
  536. rb = rb[:nr]
  537. msgs, err := ParseAuditNetlinkMessage(rb)
  538.  
  539. if err != nil {
  540. log.Println("Not Parsed Successfuly !!")
  541. continue
  542. }
  543. for _, m := range msgs {
  544. //Decide on various message Types
  545. if m.Header.Type == syscall.NLMSG_DONE {
  546. log.Println("Done")
  547. } else if m.Header.Type == syscall.NLMSG_ERROR {
  548. err := int32(nativeEndian().Uint32(m.Data[0:4]))
  549. if err == 0 {
  550. //Acknowledgement from kernel
  551. log.Println("Ack")
  552. } else {
  553. log.Println("NLMSG_ERROR...")
  554. }
  555. } else if m.Header.Type == AUDIT_GET {
  556. log.Println("AUDIT_GET")
  557. } else if m.Header.Type == AUDIT_FIRST_USER_MSG {
  558. log.Println("AUDIT_FIRST_USER_MSG")
  559. } else if m.Header.Type == AUDIT_SYSCALL {
  560. log.Println("Syscall Event")
  561. log.Println(string(m.Data[:]))
  562. _, err := f.WriteString(string(m.Data[:]) + "\n")
  563. if err != nil {
  564. log.Println("Writing Error!!")
  565. }
  566. } else if m.Header.Type == AUDIT_CWD {
  567. log.Println("CWD Event")
  568. log.Println(string(m.Data[:]))
  569. _, err := f.WriteString(string(m.Data[:]) + "\n")
  570. if err != nil {
  571. log.Println("Writing Error!!")
  572. }
  573.  
  574. } else if m.Header.Type == AUDIT_PATH {
  575. log.Println("Path Event")
  576. log.Println(string(m.Data[:]))
  577. _, err := f.WriteString(string(m.Data[:]) + "\n")
  578. if err != nil {
  579. log.Println("Writing Error!!")
  580. }
  581.  
  582. } else if m.Header.Type == AUDIT_EOE {
  583. log.Println("Event Ends ", string(m.Data[:]))
  584. } else if m.Header.Type == AUDIT_CONFIG_CHANGE {
  585. log.Println("Config Change ", string(m.Data[:]))
  586. _, err := f.WriteString(string(m.Data[:]) + "\n")
  587. if err != nil {
  588. log.Println("Writing Error!!")
  589. }
  590. } else {
  591. log.Println("Unknown: ", m.Header.Type)
  592. }
  593. }
  594. }
  595. }
  596.  
  597. // Receives messages from Kernel and forwards to channels
  598. func Getreply(s *NetlinkSocket, done <-chan bool, msgchan chan string, errchan chan error) {
  599. for {
  600. rb := make([]byte, MAX_AUDIT_MESSAGE_LENGTH)
  601. nr, _, err := syscall.Recvfrom(s.fd, rb, 0)
  602. if isDone(msgchan, errchan, done) {
  603. return
  604. }
  605. if err != nil {
  606. log.Println("Error While Recieving !!")
  607. errchan <- err
  608. continue
  609. }
  610. if nr < syscall.NLMSG_HDRLEN {
  611. log.Println("Message Too Short!!")
  612. errchan <- syscall.EINVAL
  613. continue
  614. }
  615.  
  616. rb = rb[:nr]
  617. msgs, err := ParseAuditNetlinkMessage(rb)
  618.  
  619. if err != nil {
  620. log.Println("Not Parsed Successfuly !!")
  621. errchan <- err
  622. continue
  623. }
  624. for _, m := range msgs {
  625. //Decide on various message Types
  626. //Add more message Types
  627. if m.Header.Type == syscall.NLMSG_DONE {
  628. log.Println("Done")
  629. } else if m.Header.Type == syscall.NLMSG_ERROR {
  630. err := int32(nativeEndian().Uint32(m.Data[0:4]))
  631. if err == 0 {
  632. //Acknowledgement from kernel
  633. log.Println("Ack")
  634. } else {
  635. log.Println("NLMSG_ERROR")
  636. }
  637. } else if m.Header.Type == AUDIT_GET {
  638. log.Println("AUDIT_GET")
  639. } else if m.Header.Type == AUDIT_FIRST_USER_MSG {
  640. log.Println("AUDIT_FIRST_USER_MSG")
  641. } else if m.Header.Type == AUDIT_SYSCALL {
  642. msgchan <- ("type=SYSCALL " + "msg=" + string(m.Data[:]))
  643. } else if m.Header.Type == AUDIT_CWD {
  644. msgchan <- ("type=CWD " + "msg=" + string(m.Data[:]))
  645. } else if m.Header.Type == AUDIT_PATH {
  646. msgchan <- ("type=PATH " + "msg=" + string(m.Data[:]))
  647. } else if m.Header.Type == AUDIT_EOE {
  648. // log.Println("Event Ends ", string(m.Data[:]))
  649. } else if m.Header.Type == AUDIT_CONFIG_CHANGE {
  650. msgchan <- ("type=CONFIG_CHANGE " + "msg=" + string(m.Data[:]))
  651. } else {
  652. log.Println("Unknown: ", m.Header.Type)
  653. }
  654. }
  655. }
  656.  
  657. }
  658.  
  659. /*
  660. // List all rules
  661. // TODO: this funcion needs a lot of work to print actual rules
  662. func ListAllRules(s *NetlinkSocket) error {
  663. wb := newNetlinkAuditRequest(AUDIT_LIST_RULES, syscall.AF_NETLINK, 0)
  664. if err := s.Send(wb); err != nil {
  665. log.Print("Error:", err)
  666. return err
  667. }
  668.  
  669. done:
  670. for {
  671. msgs, err := s.Receive(MAX_AUDIT_MESSAGE_LENGTH, syscall.MSG_DONTWAIT)
  672. if err != nil {
  673. log.Println("ERROR while receiving rules:", err)
  674. return err
  675. }
  676.  
  677. for _, m := range msgs {
  678. lsa, er := syscall.Getsockname(s.fd)
  679. if er != nil {
  680. log.Println("ERROR:", er)
  681. return err
  682. }
  683. switch v := lsa.(type) {
  684. case *syscall.SockaddrNetlink:
  685. if m.Header.Seq != uint32(wb.Header.Seq) {
  686. return fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, wb.Header.Seq)
  687. }
  688. if m.Header.Pid != v.Pid {
  689. return fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, v.Pid)
  690. }
  691. default:
  692. log.Println("ERROR:", syscall.EINVAL)
  693. }
  694.  
  695. if m.Header.Type == syscall.NLMSG_DONE {
  696. log.Println("All rules deleted")
  697. break done
  698. }
  699. if m.Header.Type == syscall.NLMSG_ERROR {
  700. log.Println("NLMSG_ERROR")
  701. }
  702. if m.Header.Type == AUDIT_LIST_RULES {
  703. b := m.Data[:]
  704. //Should revert to rule.ToWireFormat()
  705. buf := bytes.NewBuffer(b)
  706. var rules AuditRuleData
  707. rules.Buf = make([]byte, 0)
  708. err = binary.Read(buf, nativeEndian(), &rules)
  709. if err != nil {
  710. log.Println("binary.Read failed:", err)
  711. return err
  712. }
  713. // TODO : save all rules to an array so delete all rules function can use this
  714. rulesRetrieved = rules
  715. }
  716. }
  717. }
  718. }
  719. */
  720.  
  721. //Delete Rule Data Function
  722. func AuditDeleteRuleData(s *NetlinkSocket, rule *AuditRuleData, flags uint32, action uint32) error {
  723. var sizePurpose AuditRuleData
  724. sizePurpose.Buf = make([]byte, 0)
  725. if flags == AUDIT_FILTER_ENTRY {
  726. log.Println("Entry Filters Deprecated!!")
  727. return errEntryDep
  728. }
  729. rule.Flags = flags
  730. rule.Action = action
  731.  
  732. newbuff := rule.ToWireFormat()
  733. // buff := new(bytes.Buffer)
  734. // err := binary.Write(buff, nativeEndian(), *rule)
  735. // if err != nil {
  736. // log.Println("binary.Write failed:", err)
  737. // return err
  738. // }
  739. // wb := newNetlinkAuditRequest(AUDIT_DEL_RULE, syscall.AF_NETLINK, int(unsafe.Sizeof(sizePurpose))+int(rule.Buflen))
  740. // wb.Data = append(wb.Data[:], buff.Bytes()[:]...)
  741.  
  742. newwb := newNetlinkAuditRequest(AUDIT_DEL_RULE, syscall.AF_NETLINK, len(newbuff) /*+int(rule.Buflen)*/)
  743. newwb.Data = append(newwb.Data[:], newbuff[:]...)
  744. if err := s.Send(newwb); err != nil {
  745. return err
  746. }
  747. return nil
  748. }
  749.  
  750. // This function Deletes all rules
  751. func DeleteAllRules(s *NetlinkSocket) error {
  752. wb := newNetlinkAuditRequest(AUDIT_LIST_RULES, syscall.AF_NETLINK, 0)
  753. if err := s.Send(wb); err != nil {
  754. log.Print("Error:", err)
  755. return err
  756. }
  757.  
  758. done:
  759. for {
  760. //Make the rb byte bigger because of large messages from Kernel doesn't fit in 4096
  761. msgs, err := s.Receive(MAX_AUDIT_MESSAGE_LENGTH, syscall.MSG_DONTWAIT)
  762. if err != nil {
  763. log.Println("ERROR while receiving rules:", err)
  764. return err
  765. }
  766.  
  767. for _, m := range msgs {
  768. lsa, er := syscall.Getsockname(s.fd)
  769. if er != nil {
  770. log.Println("ERROR:", er)
  771. return er
  772. }
  773. switch v := lsa.(type) {
  774. case *syscall.SockaddrNetlink:
  775. if m.Header.Seq != uint32(wb.Header.Seq) {
  776. return fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, wb.Header.Seq)
  777. }
  778. if m.Header.Pid != v.Pid {
  779. return fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, v.Pid)
  780. }
  781. }
  782.  
  783. if m.Header.Type == syscall.NLMSG_DONE {
  784. log.Println("Deleting Done!")
  785. break done
  786.  
  787. }
  788. if m.Header.Type == syscall.NLMSG_ERROR {
  789. log.Println("NLMSG_ERROR\n")
  790. }
  791. if m.Header.Type == AUDIT_LIST_RULES {
  792. b := m.Data[:]
  793. rules := (*AuditRuleData)(unsafe.Pointer(&b[0]))
  794. //Sizeof rules is 1064 > 1056
  795. //Error handling here ?
  796. // log.Println(len(b), h)
  797. // buf := bytes.NewBuffer(b)
  798. // var rules AuditRuleData
  799. // rules.Buf = make([]byte, 0)
  800. // err = binary.Read(buf, nativeEndian(), &rules)
  801. // if err != nil {
  802. // log.Println("Binary Read Failed !!", err)
  803. // return err
  804. // }
  805. err = AuditDeleteRuleData(s, rules, rules.Flags, rules.Action)
  806. if err != nil {
  807. return err
  808. }
  809. }
  810. }
  811. }
  812. return nil
  813. }
  814.  
  815. var _audit_permadded bool
  816. var _audit_syscalladded bool
  817.  
  818. // Load x86 map and fieldtab.json
  819. func loadSysMap_FieldTab(conf *Config, fieldmap *Field) error {
  820. content2, err := ioutil.ReadFile("netlinkAudit/audit_x86_64.json")
  821. if err != nil {
  822. return err
  823. }
  824. content3, err := ioutil.ReadFile("netlinkAudit/fieldtab.json")
  825. if err != nil {
  826. return err
  827. }
  828.  
  829. err = json.Unmarshal([]byte(content2), &conf)
  830. if err != nil {
  831. return err
  832. }
  833. err = json.Unmarshal([]byte(content3), &fieldmap)
  834. if err != nil {
  835. return err
  836. }
  837.  
  838. return nil
  839. }
  840.  
  841. //sets each rule after reading configuration file
  842. func SetRules(s *NetlinkSocket) error {
  843.  
  844. //var rule AuditRuleData
  845. //AuditWatchRuleData(s, &rule, []byte("/etc/passwd"))
  846.  
  847. // Load all rules
  848. content, err := ioutil.ReadFile("netlinkAudit/audit.rules.json")
  849. if err != nil {
  850. log.Print("Error:", err)
  851. return err
  852. }
  853.  
  854. var rules interface{}
  855. err = json.Unmarshal(content, &rules)
  856. if err != nil {
  857. log.Print("Error:", err)
  858. return err
  859. }
  860.  
  861. m := rules.(map[string]interface{})
  862.  
  863. if _, ok := m["delete"]; ok {
  864. //First Delete All rules and then add rules
  865. log.Println("Deleting all rules")
  866. err := DeleteAllRules(s)
  867. if err != nil {
  868. log.Println("Error Deleting Rules!")
  869. return err
  870. }
  871. }
  872. var conf Config
  873. var fieldmap Field
  874.  
  875. // Load x86 map and fieldtab.json
  876. err = loadSysMap_FieldTab(&conf, &fieldmap)
  877. if err != nil {
  878. log.Println("Error :", err)
  879. return err
  880. }
  881.  
  882. for k, v := range m {
  883. switch k {
  884. case "custom_rule":
  885. // Still Needed ?
  886. vi := v.([]interface{})
  887. for ruleNo := range vi {
  888. rule := vi[ruleNo].(map[string]interface{})
  889. for l, m := range rule {
  890. switch l {
  891. case "action":
  892. //TODO: handle actions case here
  893. action := m.([]interface{})
  894. log.Println("actions are : ", action[0])
  895. case "fields":
  896. //TODO: handle fields case here
  897. fields := m.([]interface{})
  898. for _, q := range fields {
  899. log.Println("fields are", q)
  900. }
  901. }
  902. }
  903. }
  904. case "syscall_rules":
  905. vi := v.([]interface{})
  906. for sruleNo := range vi {
  907. srule := vi[sruleNo].(map[string]interface{})
  908.  
  909. for l := range conf.Xmap {
  910. if conf.Xmap[l].Name == srule["name"] {
  911. // set rules
  912. log.Println("setting syscall rule", conf.Xmap[l].Name)
  913. var dd AuditRuleData
  914. dd.Buf = make([]byte, 0)
  915.  
  916. err = AuditRuleSyscallData(&dd, conf.Xmap[l].Id)
  917. if err == nil {
  918. _audit_syscalladded = true
  919. } else {
  920. return err
  921. }
  922. actions := srule["action"].([]interface{})
  923. //log.Println(actions)
  924.  
  925. //NOW APPLY ACTIONS ON SYSCALLS by separating the filters i.e exit from action i.e. always
  926. action := 0
  927. filter := 0
  928. //This part supposes that actions and filters are written as always,exit or never,exit not viceversa
  929. if actions[0] == "never" {
  930. action = AUDIT_NEVER
  931. } else if actions[0] == "possible" {
  932. action = AUDIT_POSSIBLE
  933. } else if actions[0] == "always" {
  934. action = AUDIT_ALWAYS
  935. } else {
  936. action = -1
  937. }
  938.  
  939. if actions[1] == "task" {
  940. filter = AUDIT_FILTER_TASK
  941. } else if actions[1] == "entry" {
  942. log.Println("Support for Entry Filter is Deprecated!! Switching back to Exit filter")
  943. filter = AUDIT_FILTER_EXIT
  944. } else if actions[1] == "exit" {
  945. filter = AUDIT_FILTER_EXIT
  946. } else if actions[1] == "user" {
  947. filter = AUDIT_FILTER_USER
  948. } else if actions[1] == "exclude" {
  949. filter = AUDIT_FILTER_EXCLUDE
  950. } else {
  951. filter = AUDIT_FILTER_UNSET
  952. }
  953.  
  954. for _, field := range srule["fields"].([]interface{}) {
  955. fieldval := field.(map[string]interface{})["value"]
  956. op := field.(map[string]interface{})["op"]
  957. fieldname := field.(map[string]interface{})["name"]
  958. //log.Println(fieldval, op, fieldname)
  959. var opval uint32
  960. if op == "nt_eq" {
  961. opval = AUDIT_NOT_EQUAL
  962. } else if op == "gt_or_eq" {
  963. opval = AUDIT_GREATER_THAN_OR_EQUAL
  964. } else if op == "lt_or_eq" {
  965. opval = AUDIT_LESS_THAN_OR_EQUAL
  966. } else if op == "and_eq" {
  967. opval = AUDIT_BIT_TEST
  968. } else if op == "eq" {
  969. opval = AUDIT_EQUAL
  970. } else if op == "gt" {
  971. opval = AUDIT_GREATER_THAN
  972. } else if op == "lt" {
  973. opval = AUDIT_LESS_THAN
  974. } else if op == "and" {
  975. opval = AUDIT_BIT_MASK
  976. }
  977. //Take appropriate action according to filters provided
  978. err = AuditRuleFieldPairData(&dd, fieldval, opval, fieldname.(string), fieldmap, filter) // &AUDIT_BIT_MASK
  979. if err != nil {
  980. return err
  981. }
  982. }
  983.  
  984. // foo.Fields[foo.Field_count] = AUDIT_ARCH
  985. // foo.Fieldflags[foo.Field_count] = AUDIT_EQUAL
  986. // foo.Values[foo.Field_count] = AUDIT_ARCH_X86_64
  987. // foo.Field_count++
  988. // AuditAddRuleData(s, &foo, AUDIT_FILTER_EXIT, AUDIT_ALWAYS)
  989.  
  990. if filter != AUDIT_FILTER_UNSET {
  991. AuditAddRuleData(s, &dd, filter, action)
  992. } else {
  993. return fmt.Errorf("Filters Not Set")
  994. }
  995.  
  996. }
  997. }
  998. }
  999. }
  1000. }
  1001. return nil
  1002. }
  1003.  
  1004. func AuditNameToFtype(name string, value *int) error {
  1005.  
  1006. content, err := ioutil.ReadFile("netlinkAudit/ftypetab.json")
  1007.  
  1008. if err != nil {
  1009. log.Print("Error:", err)
  1010. return err
  1011. }
  1012.  
  1013. var filemap interface{}
  1014. err = json.Unmarshal(content, &filemap)
  1015.  
  1016. if err != nil {
  1017. log.Print("Error:", err)
  1018. return err
  1019. }
  1020.  
  1021. m := filemap.(map[string]interface{})
  1022.  
  1023. for k, v := range m {
  1024. if k == name {
  1025. *value = int(v.(float64))
  1026. return nil
  1027. }
  1028. }
  1029.  
  1030. return fmt.Errorf("Filetype not found")
  1031. }
  1032.  
  1033. var (
  1034. errMaxField = errors.New("MAX Fields for AuditRuleData exceeded")
  1035. errNoStr = errors.New("No support for string values")
  1036. errUnset = errors.New("Unable to set value")
  1037. errNoExit = errors.New("Filter can only be used with AUDIT_EXIT")
  1038. errNoSys = errors.New("No syscall added")
  1039. errMaxLen = errors.New("MAX length Exceeded")
  1040. )
  1041.  
  1042. func AuditRuleFieldPairData(rule *AuditRuleData, fieldval interface{}, opval uint32, fieldname string, fieldmap Field, flags int) error {
  1043.  
  1044. if rule.Field_count >= (AUDIT_MAX_FIELDS - 1) {
  1045. log.Println("Max Fields Exceeded !!")
  1046. return errMaxField
  1047. }
  1048.  
  1049. var fieldid uint32
  1050. for f := range fieldmap.Fieldmap {
  1051. if fieldmap.Fieldmap[f].Name == fieldname {
  1052. //log.Println("Found :", fieldmap.Fieldmap[f])
  1053. fieldid = (uint32)(fieldmap.Fieldmap[f].Fieldid)
  1054. }
  1055. }
  1056.  
  1057. rule.Fields[rule.Field_count] = fieldid
  1058. rule.Fieldflags[rule.Field_count] = opval
  1059.  
  1060. log.Println("Going for", fieldname)
  1061. switch fieldid {
  1062. case AUDIT_UID, AUDIT_EUID, AUDIT_SUID, AUDIT_FSUID, AUDIT_LOGINUID, AUDIT_OBJ_UID, AUDIT_OBJ_GID:
  1063. if val, isInt := fieldval.(float64); isInt {
  1064.  
  1065. if val < 0 {
  1066. // For trimming "-" and evaluating th condition vlen >=2 (which is not needed)
  1067. valString := strconv.FormatInt((int64)(val), 10)
  1068. fieldvalUid := strings.Replace(valString, "-", "", -1)
  1069. a, err := strconv.Atoi(fieldvalUid)
  1070.  
  1071. if err != nil {
  1072. log.Println("Conversion not possible")
  1073. return err
  1074. } else {
  1075. rule.Values[rule.Field_count] = (uint32)(a)
  1076. }
  1077.  
  1078. } else {
  1079. rule.Values[rule.Field_count] = (uint32)(val)
  1080. }
  1081. } else if val, isString := fieldval.(string); isString {
  1082. if fieldval.(string) == "unset" {
  1083. rule.Values[rule.Field_count] = 4294967295
  1084. } else {
  1085. log.Println("No support for string values yet !", val)
  1086. return errNoStr
  1087. //Insert audit_name_to_uid(string,int * val)
  1088. }
  1089. } else {
  1090. log.Println("Error Setting Value:", fieldval)
  1091. return errUnset
  1092. }
  1093.  
  1094. case AUDIT_GID, AUDIT_EGID, AUDIT_SGID, AUDIT_FSGID:
  1095. //IF DIGITS THEN
  1096. if val, isInt := fieldval.(float64); isInt {
  1097. rule.Values[rule.Field_count] = (uint32)(val)
  1098. } else if val, isString := fieldval.(string); isString {
  1099. log.Println("No support for string values yet !", val)
  1100. return errNoStr
  1101. //audit_name_to_gid(string, sint*val)
  1102. } else {
  1103. log.Println("Error Setting Value:", fieldval)
  1104. return errUnset
  1105. }
  1106.  
  1107. case AUDIT_EXIT:
  1108.  
  1109. if flags != AUDIT_FILTER_EXIT {
  1110. return errNoExit
  1111. }
  1112. if val, isInt := fieldval.(float64); isInt {
  1113. if val < 0 {
  1114. // For trimming "-" and evaluating th condition vlen >=2 (which is not needed)
  1115. valString := strconv.FormatInt((int64)(val), 10)
  1116. fieldvalUid := strings.Replace(valString, "-", "", -1)
  1117. a, err := strconv.Atoi(fieldvalUid)
  1118.  
  1119. if err != nil {
  1120. return err
  1121. } else {
  1122. rule.Values[rule.Field_count] = (uint32)(a)
  1123. }
  1124.  
  1125. } else {
  1126. rule.Values[rule.Field_count] = (uint32)(val)
  1127. }
  1128.  
  1129. } else if val, isString := fieldval.(string); isString {
  1130. log.Println("No support for string values yet !", val)
  1131. return errNoStr
  1132. } else {
  1133. log.Println("Error Setting Value:", fieldval)
  1134. return errUnset
  1135. }
  1136.  
  1137. //TODO: String handling part
  1138. //else {
  1139. // rule->values[rule->field_count] = //SEE HERE
  1140. // audit_name_to_errno(v);
  1141. // if (rule->values[rule->field_count] == 0)
  1142. // return -15;
  1143. //}
  1144. //break;
  1145.  
  1146. case AUDIT_MSGTYPE:
  1147.  
  1148. if flags != AUDIT_FILTER_EXCLUDE && flags != AUDIT_FILTER_USER {
  1149. return fmt.Errorf("AUDIT_MSGTYPE can only be used with AUDIT_FILTER_EXCLUDE")
  1150. }
  1151. if val, isInt := fieldval.(float64); isInt {
  1152. rule.Values[rule.Field_count] = (uint32)(val)
  1153. } else if val, isString := fieldval.(string); isString {
  1154. log.Println("No support for string values yet !", val)
  1155. return errNoStr
  1156. } else {
  1157. log.Println("Error Setting Value:", fieldval)
  1158. return errUnset
  1159.  
  1160. }
  1161.  
  1162. //Strings
  1163. case AUDIT_OBJ_USER, AUDIT_OBJ_ROLE, AUDIT_OBJ_TYPE, AUDIT_OBJ_LEV_LOW, AUDIT_OBJ_LEV_HIGH, AUDIT_WATCH, AUDIT_DIR:
  1164. /* Watch & object filtering is invalid on anything
  1165. * but exit */
  1166.  
  1167. if flags != AUDIT_FILTER_EXIT {
  1168. return errNoExit
  1169. }
  1170. if fieldid == AUDIT_WATCH || fieldid == AUDIT_DIR {
  1171. _audit_permadded = true
  1172. }
  1173.  
  1174. fallthrough //IMP
  1175. case AUDIT_SUBJ_USER, AUDIT_SUBJ_ROLE, AUDIT_SUBJ_TYPE, AUDIT_SUBJ_SEN, AUDIT_SUBJ_CLR, AUDIT_FILTERKEY:
  1176. //IF And only if a syscall is added or a permisission is added then this field should be set
  1177. //MORE Debugging Required
  1178. if fieldid == AUDIT_FILTERKEY && !(_audit_syscalladded || _audit_permadded) {
  1179. return errNoSys
  1180. }
  1181. if val, isString := fieldval.(string); isString {
  1182. valbyte := []byte(val)
  1183. vlen := len(valbyte)
  1184. if fieldid == AUDIT_FILTERKEY && vlen > AUDIT_MAX_KEY_LEN {
  1185. return errMaxLen
  1186. } else if vlen > PATH_MAX {
  1187. return errMaxLen
  1188. }
  1189. rule.Values[rule.Field_count] = (uint32)(vlen)
  1190. rule.Buflen = rule.Buflen + (uint32)(vlen)
  1191. // log.Println(unsafe.Sizeof(*rule), vlen)
  1192. //Now append the key value with the rule buffer space
  1193. //May need to reallocate memory to rule.Buf i.e. the 0 size byte array, append will take care of that
  1194. rule.Buf = append(rule.Buf, valbyte[:]...)
  1195. // log.Println(int(unsafe.Sizeof(*rule)), *rule)
  1196. }
  1197.  
  1198. case AUDIT_ARCH:
  1199. if _audit_syscalladded == false {
  1200. return errNoSys
  1201. } else {
  1202. //AUDIT_ARCH_X86_64 is made specifically for Mozilla Heka purpose, please make changes as per required
  1203. if _, isInt := fieldval.(float64); isInt {
  1204. rule.Values[rule.Field_count] = AUDIT_ARCH_X86_64
  1205. } else if _, isString := fieldval.(string); isString {
  1206. return errNoStr
  1207. } else {
  1208. return errUnset
  1209. }
  1210. }
  1211.  
  1212. case AUDIT_PERM:
  1213. //DECIDE ON VARIOUS ERROR TYPES
  1214. if flags != AUDIT_FILTER_EXIT {
  1215. return errNoExit
  1216. } else if opval != AUDIT_EQUAL {
  1217. return fmt.Errorf("Operator can only be AUDIT_EQUAL in case of AUDIT_PERM")
  1218. } else {
  1219. if val, isString := fieldval.(string); isString {
  1220.  
  1221. var i, vallen int
  1222. vallen = len(val)
  1223. var permval uint32
  1224. if vallen > 4 {
  1225. return errMaxLen
  1226. }
  1227. lowerval := strings.ToLower(val)
  1228. for i = 0; i < vallen; i++ {
  1229. switch lowerval[i] {
  1230. case 'r':
  1231. permval |= AUDIT_PERM_READ
  1232. case 'w':
  1233. permval |= AUDIT_PERM_WRITE
  1234. case 'x':
  1235. permval |= AUDIT_PERM_EXEC
  1236. case 'a':
  1237. permval |= AUDIT_PERM_ATTR
  1238. default:
  1239. return fmt.Errorf(" %s is not found as permission", lowerval[i])
  1240. }
  1241. }
  1242. rule.Values[rule.Field_count] = permval
  1243. _audit_permadded = true
  1244. }
  1245. }
  1246. case AUDIT_FILETYPE:
  1247. if val, isString := fieldval.(string); isString {
  1248. if !(flags == AUDIT_FILTER_EXIT) && flags == AUDIT_FILTER_ENTRY {
  1249. return fmt.Errorf("Flag can only be AUDIT_EXIT in case of AUDIT_FILETYPE")
  1250. }
  1251. var fileval int
  1252. err := AuditNameToFtype(val, &fileval)
  1253. if err != nil {
  1254. return err
  1255. }
  1256. rule.Values[rule.Field_count] = uint32(fileval)
  1257. if (int)(rule.Values[rule.Field_count]) < 0 {
  1258. return syscall.EINVAL
  1259. }
  1260. } else {
  1261. return fmt.Errorf("Numbers as filetypes")
  1262. }
  1263.  
  1264. case AUDIT_ARG0, AUDIT_ARG1, AUDIT_ARG2, AUDIT_ARG3:
  1265. if val, isInt := fieldval.(float64); isInt {
  1266. if val < 0 {
  1267. // For trimming "-" and evaluating th condition vlen >=2 (which is not needed)
  1268. valString := strconv.FormatInt((int64)(val), 10)
  1269. fieldvalUid := strings.Replace(valString, "-", "", -1)
  1270. a, err := strconv.Atoi(fieldvalUid)
  1271.  
  1272. if err != nil {
  1273. return err
  1274. } else {
  1275. rule.Values[rule.Field_count] = (uint32)(a)
  1276. }
  1277. } else {
  1278. rule.Values[rule.Field_count] = (uint32)(val)
  1279. }
  1280. } else if _, isString := fieldval.(string); isString {
  1281. return errNoStr
  1282. } else {
  1283. log.Println("Error Setting Value:", fieldval)
  1284. return errUnset
  1285. }
  1286. case AUDIT_DEVMAJOR, AUDIT_INODE, AUDIT_SUCCESS:
  1287. if flags != AUDIT_FILTER_EXIT {
  1288. return errNoExit
  1289. }
  1290. fallthrough
  1291. default:
  1292. if fieldid == AUDIT_INODE {
  1293. if !(opval == AUDIT_NOT_EQUAL || opval == AUDIT_EQUAL) {
  1294. return fmt.Errorf("OP can only be AUDIT_NOT_EQUAL or AUDIT_EQUAL")
  1295. }
  1296. }
  1297.  
  1298. if fieldid == AUDIT_PPID && !(flags == AUDIT_FILTER_EXIT || flags == AUDIT_FILTER_ENTRY) {
  1299. return fmt.Errorf("Flags can only be EXIT or ENTRY in case of AUDIT_PPID")
  1300. }
  1301.  
  1302. if val, isInt := fieldval.(float64); isInt {
  1303.  
  1304. if fieldid == AUDIT_INODE {
  1305. rule.Values[rule.Field_count] = (uint32)(val)
  1306. } else {
  1307. rule.Values[rule.Field_count] = (uint32)(val)
  1308. }
  1309.  
  1310. } else {
  1311. log.Println("Error Setting Value:", fieldval)
  1312. return errUnset
  1313. }
  1314. }
  1315. rule.Field_count++
  1316. return nil
  1317. }
  1318.  
  1319. /*
  1320. If further needed
  1321. var ErrStrings = []string{"E2BIG", "EACCES", "EADDRINUSE", "EADDRNOTAVAIL", "EADV", "EAFNOSUPPORT", "EAGAIN", "EALREADY", "EBADE", "EBADF",
  1322. "EBADFD", "EBADMSG", "EBADR", "EBADRQC", "EBADSLT", "EBFONT", "EBUSY", "ECANCELED", "ECHILD", "ECHRNG",
  1323. "ECOMM", "ECONNABORTED", "ECONNREFUSED", "ECONNRESET", "EDEADLK", "EDEADLOCK", "EDESTADDRREQ", "EDOM", "EDOTDOT", "EDQUOT",
  1324. "EEXIST", "EFAULT", "EFBIG", "EHOSTDOWN", "EHOSTUNREACH", "EIDRM", "EILSEQ", "EINPROGRESS", "EINTR", "EINVAL",
  1325. "EIO", "EISCONN", "EISDIR", "EISNAM", "EKEYEXPIRED", "EKEYREJECTED", "EKEYREVOKED", "EL2HLT", "EL2NSYNC", "EL3HLT",
  1326. "EL3RST", "ELIBACC", "ELIBBAD", "ELIBEXEC", "ELIBMAX", "ELIBSCN", "ELNRNG", "ELOOP", "EMEDIUMTYPE", "EMFILE",
  1327. "EMLINK", "EMSGSIZE", "EMULTIHOP", "ENAMETOOLONG", "ENAVAIL", "ENETDOWN", "ENETRESET", "ENETUNREACH", "ENFILE", "ENOANO",
  1328. "ENOBUFS", "ENOCSI", "ENODATA", "ENODEV", "ENOENT", "ENOEXEC", "ENOKEY", "ENOLCK", "ENOLINK", "ENOMEDIUM",
  1329. "ENOMEM", "ENOMSG", "ENONET", "ENOPKG", "ENOPROTOOPT", "ENOSPC", "ENOSR", "ENOSTR", "ENOSYS", "ENOTBLK",
  1330. "ENOTCONN", "ENOTDIR", "ENOTEMPTY", "ENOTNAM", "ENOTRECOVERABLE", "ENOTSOCK", "ENOTTY", "ENOTUNIQ", "ENXIO", "EOPNOTSUPP",
  1331. "EOVERFLOW", "EOWNERDEAD", "EPERM", "EPFNOSUPPORT", "EPIPE", "EPROTO", "EPROTONOSUPPORT", "EPROTOTYPE", "ERANGE", "EREMCHG",
  1332. "EREMOTE", "EREMOTEIO", "ERESTART", "EROFS", "ESHUTDOWN", "ESOCKTNOSUPPORT", "ESPIPE", "ESRCH", "ESRMNT", "ESTALE",
  1333. "ESTRPIPE", "ETIME", "ETIMEDOUT", "ETOOMANYREFS", "ETXTBSY", "EUCLEAN", "EUNATCH", "EUSERS", "EWOULDBLOCK", "EXDEV",
  1334. "EXFULL"}
  1335.  
  1336. var ErrS2iI = []int{7, 13, 98, 99, 68, 97, 11, 114, 52, 9, 77, 74, 53, 56, 57, 59, 16, 125, 10, 44, 70, 103, 111, 104, 35, 35, 89, 33, 73, 122, 17, 14, 27, 112, 113, 43, 84, 115, 4, 22,
  1337. 5, 106, 21, 120, 127, 129, 128, 51, 45, 46, 47, 79, 80, 83, 82, 81, 48, 40, 124, 24, 31, 90, 72, 36, 119, 100, 102, 101, 23, 55, 105, 50, 61, 19, 2, 8, 126, 37, 67, 123, 12, 42, 64, 65, 92, 28, 63, 60, 38, 15,
  1338. 107, 20, 39, 118, 131, 88, 25, 76, 6, 95, 75, 130, 1, 96, 32, 71, 93, 91, 34, 78, 66, 121, 85, 30, 108, 94, 29, 3, 69, 116, 86, 62, 110, 109, 26, 117, 49, 87, 11, 18, 54}
  1339.  
  1340. var audit_elf uint = 0
  1341. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement