示例#1
0
func RemoteRecvCredentials(conn *net.UnixConn) (uint32, uint32, error) {
	err := syscall.SetsockoptInt(sysfd(conn), syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1)

	if err != nil {
		return 0, 0, err
	}

	oob := make([]byte, len(syscall.UnixCredentials(&syscall.Ucred{})))

	_, _, _, _, err = conn.ReadMsgUnix(nil, oob)

	if err != nil {
		return 0, 0, err
	}

	scm, err := syscall.ParseSocketControlMessage(oob)

	if err != nil {
		return 0, 0, err
	}

	ucred, err := syscall.ParseUnixCredentials(&scm[0])

	if err != nil {
		return 0, 0, err
	}

	return ucred.Uid, ucred.Gid, nil
}
示例#2
0
func (fd *Fd) readFrom(c *net.UnixConn) error {
	var b []byte
	oob := make([]byte, 16)
	_, oobn, _, _, err := c.ReadMsgUnix(b, oob)
	if err != nil {
		return err
	}
	if oobn == 0 {
		return errors.New("error reading oob")
	}
	oob = oob[:oobn]

	scms, err := syscall.ParseSocketControlMessage(oob)
	if err != nil {
		return err
	}
	if len(scms) != 1 {
		return fmt.Errorf("expected 1 SocketControlMessage, got %d", len(scms))
	}
	scm := scms[0]
	fds, err := syscall.ParseUnixRights(&scm)
	if err != nil {
		return nil
	}
	if len(fds) != 1 {
		return fmt.Errorf("expected 1 fd, got %d", len(fds))
	}
	*fd = Fd(fds[0])
	return nil
}
示例#3
0
文件: unix.go 项目: ChaosCloud/docker
func receiveUnix(conn *net.UnixConn) ([]byte, []int, error) {
	buf := make([]byte, 4096)
	oob := make([]byte, 4096)
	bufn, oobn, _, _, err := conn.ReadMsgUnix(buf, oob)
	if err != nil {
		return nil, nil, err
	}
	return buf[:bufn], extractFds(oob[:oobn]), nil
}
示例#4
0
func readRequest(c *net.UnixConn) (*Request, error) {
	var l uint32
	err := binary.Read(c, binary.BigEndian, &l)
	length := int(l)
	if err != nil {
		return nil, err
	}
	payload := make([]byte, length)
	n, err := c.Read(payload)
	if err != nil {
		return nil, err
	} else if n != length {
		return nil, fmt.Errorf("Payload was %d bytes rather than reported size of %d", n, length)
	}
	req := &Request{}
	err = json.Unmarshal(payload, req)
	if err != nil {
		return nil, err
	}
	if !req.HasFds {
		return req, nil
	}

	payload = make([]byte, 1)
	// TODO: does this buffer need to be configurable?
	oob := make([]byte, 8192)
	n, oobn, _, _, err := c.ReadMsgUnix(payload, oob)
	if err != nil && err != io.EOF {
		return nil, err
	}
	if n != 1 {
		return nil, fmt.Errorf("Error reading OOB filedescriptors")
	}
	oob = oob[0:oobn]
	scm, err := syscall.ParseSocketControlMessage(oob)
	if err != nil {
		return nil, fmt.Errorf("Error parsing socket control message: %v", err)
	}
	var fds []int
	for i := 0; i < len(scm); i++ {
		tfds, err := syscall.ParseUnixRights(&scm[i])
		if err == syscall.EINVAL {
			continue // Wasn't a UnixRights Control Message
		} else if err != nil {
			return nil, fmt.Errorf("Error parsing unix rights: %v", err)
		}
		fds = append(fds, tfds...)
	}
	if len(fds) == 0 {
		return nil, fmt.Errorf("Failed to receive any FDs on a request with HasFds == true")
	}
	req.ReceivedFds = fds
	return req, nil
}
示例#5
0
// Receive File from UnixConn
func RecvFD(conn *net.UnixConn) (file *os.File, err error) {
	cmsgb := make([]byte, CmsgSpace(unsafe.Sizeof(int(0))))

	cms := (*syscall.Cmsghdr)(unsafe.Pointer(&cmsgb[0]))
	cms.Len = CmsgLen(unsafe.Sizeof(int(0)))
	cms.Level = 1
	cms.Type = 1

	_, _, _, _, err = conn.ReadMsgUnix([]byte{}, cmsgb)
	if err != nil {
		return
	}

	fdArea := cmsgb[unsafe.Sizeof(syscall.Cmsghdr{}):]
	fdnum := uintptr(fdArea[0]) | uintptr(byte(fdArea[1]<<8)) | uintptr(byte(fdArea[2]<<16)) | uintptr(byte(fdArea[3]<<24))

	file = os.NewFile(fdnum, "")

	return
}
示例#6
0
func ReadWaylandMessage(conn *net.UnixConn) (*Message, error) {
	var buf [8]byte
	msg := Message{}
	control := make([]byte, 24)

	n, oobn, _, _, err := conn.ReadMsgUnix(buf[:], control)
	if err != nil {
		return nil, err
	}
	if n != 8 {
		return nil, errors.New("Unable to read message header.")
	}
	if oobn > 0 {
		if oobn > len(control) {
			panic("Unsufficient control msg buffer")
		}
		msg.control_msgs, err = syscall.ParseSocketControlMessage(control)
		if err != nil {
			panic(fmt.Sprintf("Control message parse error: %s", err.Error()))
		}
	}

	msg.Id = ProxyId(binary.LittleEndian.Uint32(buf[0:4]))
	msg.Opcode = uint32(binary.LittleEndian.Uint16(buf[4:6]))
	msg.size = uint32(binary.LittleEndian.Uint16(buf[6:8]))

	// subtract 8 bytes from header
	data := make([]byte, msg.size-8)

	n, err = conn.Read(data)
	if err != nil {
		return nil, err
	}
	if n != int(msg.size)-8 {
		return nil, errors.New("Invalid message size.")
	}
	msg.data = bytes.NewBuffer(data)

	return &msg, nil
}
示例#7
0
func ReadFile(c *net.UnixConn, timeout time.Duration) (*os.File, error) {
	oob := make([]byte, 64)

	if timeout > 0 {
		deadline := time.Now().Add(timeout)
		if err := c.SetReadDeadline(deadline); err != nil {
			return nil, err
		}
	}

	_, oobn, flags, _, err := c.ReadMsgUnix(nil, oob)
	if err != nil {
		return nil, err
	}
	if flags != 0 || oobn <= 0 {
		panic("ReadMsgUnix: flags != 0 || oobn <= 0")
	}

	// file descriptors are now open in this process

	scm, err := syscall.ParseSocketControlMessage(oob[:oobn])
	if err != nil {
		return nil, err
	}
	if len(scm) != 1 {
		panic("invalid scm message")
	}

	fds, err := syscall.ParseUnixRights(&scm[0])
	if err != nil {
		return nil, err
	}
	if len(fds) != 1 {
		panic("invalid scm message")
	}

	return os.NewFile(uintptr(fds[0]), ""), nil
}
示例#8
0
文件: fdpass.go 项目: kingpro/vitess
func RecvFd(conn *net.UnixConn) (*os.File, error) {
	buf := make([]byte, 32)
	oob := make([]byte, 32)
	_, oobn, _, _, err := conn.ReadMsgUnix(buf, oob)
	if err != nil {
		return nil, fmt.Errorf("recvfd: err %v", err)
	}
	scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
	if err != nil {
		return nil, fmt.Errorf("recvfd: ParseSocketControlMessage failed %v", err)
	}
	if len(scms) != 1 {
		return nil, fmt.Errorf("recvfd: SocketControlMessage count not 1: %v", len(scms))
	}
	scm := scms[0]
	fds, err := syscall.ParseUnixRights(&scm)
	if err != nil {
		return nil, fmt.Errorf("recvfd: ParseUnixRights failed %v", err)
	}
	if len(fds) != 1 {
		return nil, fmt.Errorf("recvfd: fd count not 1: %v", len(fds))
	}
	return os.NewFile(uintptr(fds[0]), "passed-fd"), nil
}