Skip to content

Commit 68003e5

Browse files
committed
Add UnixCredentials system call for DragonFly BSD
1 parent de1441e commit 68003e5

File tree

2 files changed

+99
-1
lines changed

2 files changed

+99
-1
lines changed

transport_unixcred_dragonfly.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// The UnixCredentials system call is currently only implemented on Linux
2+
// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
3+
// https://groups.google.com/forum/#!topic/golang-dev/z7VbyqR1s78
4+
// http://code.google.com/p/go/source/browse/unix/sockcmsg_linux.go?repo=sys
5+
6+
// Local implementation of the UnixCredentials system call for DragonFly BSD
7+
8+
package dbus
9+
10+
/*
11+
#include <sys/ucred.h>
12+
*/
13+
import "C"
14+
15+
import (
16+
"io"
17+
"os"
18+
"syscall"
19+
"unsafe"
20+
)
21+
22+
// http://golang.org/src/pkg/syscall/ztypes_linux_amd64.go
23+
// http://golang.org/src/pkg/syscall/ztypes_dragonfly_amd64.go
24+
type Ucred struct {
25+
Pid int32
26+
Uid uint32
27+
Gid uint32
28+
}
29+
30+
// http://golang.org/src/pkg/syscall/types_linux.go
31+
// http://golang.org/src/pkg/syscall/types_dragonfly.go
32+
// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/ucred.h
33+
const (
34+
SizeofUcred = C.sizeof_struct_ucred
35+
)
36+
37+
// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
38+
func cmsgAlignOf(salen int) int {
39+
// From http://golang.org/src/pkg/syscall/sockcmsg_unix.go
40+
//salign := sizeofPtr
41+
// NOTE: It seems like 64-bit Darwin and DragonFly BSD kernels
42+
// still require 32-bit aligned access to network subsystem.
43+
//if darwin64Bit || dragonfly64Bit {
44+
// salign = 4
45+
//}
46+
salign := 4
47+
return (salen + salign - 1) & ^(salign - 1)
48+
}
49+
50+
// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
51+
func cmsgData(h *syscall.Cmsghdr) unsafe.Pointer {
52+
return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(syscall.SizeofCmsghdr)))
53+
}
54+
55+
// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
56+
// UnixCredentials encodes credentials into a socket control message
57+
// for sending to another process. This can be used for
58+
// authentication.
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+
// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
70+
// ParseUnixCredentials decodes a socket control message that contains
71+
// credentials in a Ucred structure. To receive such a message, the
72+
// SO_PASSCRED option must be enabled on the socket.
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+
}

transport_unixcred.go renamed to transport_unixcred_linux.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// +build !darwin,!windows
1+
// The UnixCredentials system call is currently only implemented on Linux
2+
// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
3+
// https://groups.google.com/forum/#!topic/golang-dev/z7VbyqR1s78
4+
// http://code.google.com/p/go/source/browse/unix/sockcmsg_linux.go?repo=sys
25

36
package dbus
47

0 commit comments

Comments
 (0)