...

Source file src/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.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 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  }
    96  

View as plain text