...

Source file src/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go

Documentation: github.com/godbus/dbus/v5

     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  
     8  package dbus
     9  
    10  /*
    11  const int sizeofPtr = sizeof(void*);
    12  #define _WANT_UCRED
    13  #include <sys/types.h>
    14  #include <sys/ucred.h>
    15  */
    16  import "C"
    17  
    18  import (
    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
    27  type Ucred struct {
    28  	Pid int32
    29  	Uid uint32
    30  	Gid 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
    36  const (
    37  	SizeofUcred = C.sizeof_struct_ucred
    38  )
    39  
    40  // http://golang.org/src/pkg/syscall/sockcmsg_unix.go
    41  func cmsgAlignOf(salen int) int {
    42  	salign := C.sizeofPtr
    43  
    44  	return (salen + salign - 1) & ^(salign - 1)
    45  }
    46  
    47  // http://golang.org/src/pkg/syscall/sockcmsg_unix.go
    48  func cmsgData(h *syscall.Cmsghdr) unsafe.Pointer {
    49  	return 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.
    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  // 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.
    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