Beispiel #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
}
Beispiel #2
0
func (t *unixTransport) Auth() error {
	cred := syscall.UnixCredentials(&syscall.Ucred{
		Pid: int32(os.Getpid()),
		Uid: uint32(os.Getuid()),
		Gid: uint32(os.Getgid()),
	})
	_, _, err := t.WriteMsgUnix([]byte{0}, cred, nil)
	if err != nil {
		return err
	}

	if _, err := fmt.Fprintf(t, "AUTH EXTERNAL %x\r\n", fmt.Sprintf("%d", os.Getuid())); err != nil {
		return err
	}

	var code, cookie string
	if _, err := fmt.Fscanln(t, &code, &cookie); err != nil {
		return err
	}

	fmt.Println(code, cookie)

	if _, err := fmt.Fprintf(t, "BEGIN\r\n"); err != nil {
		return err
	}
	return nil
}
func (t *unixTransport) SendNullByte() error {
	ucred := &syscall.Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())}
	b := syscall.UnixCredentials(ucred)
	_, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil)
	if err != nil {
		return err
	}
	if oobn != len(b) {
		return io.ErrShortWrite
	}
	return nil
}
Beispiel #4
0
func RemoteSendCredentials(conn *net.UnixConn) error {
	ucred := &syscall.Ucred{
		Pid: int32(os.Getpid()),
		Uid: uint32(os.Getuid()),
		Gid: uint32(os.Getgid()),
	}

	oob := syscall.UnixCredentials(ucred)
	_, _, err := conn.WriteMsgUnix(nil, oob, nil)

	return err
}
Beispiel #5
0
// TestSCMCredentials tests the sending and receiving of credentials
// (PID, UID, GID) in an ancillary message between two UNIX
// sockets. The SO_PASSCRED socket option is enabled on the sending
// socket for this to work.
func TestSCMCredentials(t *testing.T) {
	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
	if err != nil {
		t.Fatalf("Socketpair: %v", err)
	}
	defer syscall.Close(fds[0])
	defer syscall.Close(fds[1])

	err = syscall.SetsockoptInt(fds[0], syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1)
	if err != nil {
		t.Fatalf("SetsockoptInt: %v", err)
	}

	srv, err := net.FileConn(os.NewFile(uintptr(fds[0]), ""))
	if err != nil {
		t.Errorf("FileConn: %v", err)
		return
	}
	defer srv.Close()

	cli, err := net.FileConn(os.NewFile(uintptr(fds[1]), ""))
	if err != nil {
		t.Errorf("FileConn: %v", err)
		return
	}
	defer cli.Close()

	var ucred syscall.Ucred
	if os.Getuid() != 0 {
		ucred.Pid = int32(os.Getpid())
		ucred.Uid = 0
		ucred.Gid = 0
		oob := syscall.UnixCredentials(&ucred)
		_, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
		if err.(*net.OpError).Err != syscall.EPERM {
			t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
		}
	}

	ucred.Pid = int32(os.Getpid())
	ucred.Uid = uint32(os.Getuid())
	ucred.Gid = uint32(os.Getgid())
	oob := syscall.UnixCredentials(&ucred)

	// this is going to send a dummy byte
	n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
	if err != nil {
		t.Fatalf("WriteMsgUnix: %v", err)
	}
	if n != 0 {
		t.Fatalf("WriteMsgUnix n = %d, want 0", n)
	}
	if oobn != len(oob) {
		t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
	}

	oob2 := make([]byte, 10*len(oob))
	n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
	if err != nil {
		t.Fatalf("ReadMsgUnix: %v", err)
	}
	if flags != 0 {
		t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
	}
	if n != 1 {
		t.Fatalf("ReadMsgUnix n = %d, want 1 (dummy byte)", n)
	}
	if oobn2 != oobn {
		// without SO_PASSCRED set on the socket, ReadMsgUnix will
		// return zero oob bytes
		t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
	}
	oob2 = oob2[:oobn2]
	if !bytes.Equal(oob, oob2) {
		t.Fatal("ReadMsgUnix oob bytes don't match")
	}

	scm, err := syscall.ParseSocketControlMessage(oob2)
	if err != nil {
		t.Fatalf("ParseSocketControlMessage: %v", err)
	}
	newUcred, err := syscall.ParseUnixCredentials(&scm[0])
	if err != nil {
		t.Fatalf("ParseUnixCredentials: %v", err)
	}
	if *newUcred != ucred {
		t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
	}
}