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