...
1
2
3
4
5
6
7
8 package dbus
9
10
13 import "C"
14
15 import (
16 "io"
17 "os"
18 "syscall"
19 "unsafe"
20 )
21
22
23
24 type Ucred struct {
25 Pid int32
26 Uid uint32
27 Gid uint32
28 }
29
30
31
32
33 const (
34 SizeofUcred = C.sizeof_struct_ucred
35 )
36
37
38 func cmsgAlignOf(salen int) int {
39
40
41
42
43
44
45
46 salign := 4
47 return (salen + salign - 1) & ^(salign - 1)
48 }
49
50
51 func cmsgData(h *syscall.Cmsghdr) unsafe.Pointer {
52 return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(syscall.SizeofCmsghdr)))
53 }
54
55
56
57
58
59 func UnixCredentials(ucred *Ucred) []byte {
60 b := make([]byte, syscall.CmsgSpace(SizeofUcred))
61 h := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
62 h.Level = syscall.SOL_SOCKET
63 h.Type = syscall.SCM_CREDS
64 h.SetLen(syscall.CmsgLen(SizeofUcred))
65 *((*Ucred)(cmsgData(h))) = *ucred
66 return b
67 }
68
69
70
71
72
73 func ParseUnixCredentials(m *syscall.SocketControlMessage) (*Ucred, error) {
74 if m.Header.Level != syscall.SOL_SOCKET {
75 return nil, syscall.EINVAL
76 }
77 if m.Header.Type != syscall.SCM_CREDS {
78 return nil, syscall.EINVAL
79 }
80 ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
81 return &ucred, nil
82 }
83
84 func (t *unixTransport) SendNullByte() error {
85 ucred := &Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())}
86 b := UnixCredentials(ucred)
87 _, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil)
88 if err != nil {
89 return err
90 }
91 if oobn != len(b) {
92 return io.ErrShortWrite
93 }
94 return nil
95 }
96
View as plain text