go-tg-screenshot-bot
92 строки · 2.6 Кб
1// The UnixCredentials system call is currently only implemented on Linux
2// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
3// https://golang.org/s/go1.4-syscall
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 FreeBSD
7
8package dbus
9
10/*
11const int sizeofPtr = sizeof(void*);
12#define _WANT_UCRED
13#include <sys/types.h>
14#include <sys/ucred.h>
15*/
16import "C"
17
18import (
19"io"
20"os"
21"syscall"
22"unsafe"
23)
24
25// http://golang.org/src/pkg/syscall/ztypes_linux_amd64.go
26// https://golang.org/src/syscall/ztypes_freebsd_amd64.go
27type Ucred struct {
28Pid int32
29Uid uint32
30Gid uint32
31}
32
33// http://golang.org/src/pkg/syscall/types_linux.go
34// https://golang.org/src/syscall/types_freebsd.go
35// https://github.com/freebsd/freebsd/blob/master/sys/sys/ucred.h
36const (
37SizeofUcred = C.sizeof_struct_ucred
38)
39
40// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
41func cmsgAlignOf(salen int) int {
42salign := C.sizeofPtr
43
44return (salen + salign - 1) & ^(salign - 1)
45}
46
47// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
48func cmsgData(h *syscall.Cmsghdr) unsafe.Pointer {
49return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(syscall.SizeofCmsghdr)))
50}
51
52// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
53// UnixCredentials encodes credentials into a socket control message
54// for sending to another process. This can be used for
55// authentication.
56func UnixCredentials(ucred *Ucred) []byte {
57b := make([]byte, syscall.CmsgSpace(SizeofUcred))
58h := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
59h.Level = syscall.SOL_SOCKET
60h.Type = syscall.SCM_CREDS
61h.SetLen(syscall.CmsgLen(SizeofUcred))
62*((*Ucred)(cmsgData(h))) = *ucred
63return b
64}
65
66// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
67// ParseUnixCredentials decodes a socket control message that contains
68// credentials in a Ucred structure. To receive such a message, the
69// SO_PASSCRED option must be enabled on the socket.
70func ParseUnixCredentials(m *syscall.SocketControlMessage) (*Ucred, error) {
71if m.Header.Level != syscall.SOL_SOCKET {
72return nil, syscall.EINVAL
73}
74if m.Header.Type != syscall.SCM_CREDS {
75return nil, syscall.EINVAL
76}
77ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
78return &ucred, nil
79}
80
81func (t *unixTransport) SendNullByte() error {
82ucred := &Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())}
83b := UnixCredentials(ucred)
84_, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil)
85if err != nil {
86return err
87}
88if oobn != len(b) {
89return io.ErrShortWrite
90}
91return nil
92}
93