internal/hookd/peercred_linux.go

v1.37.0
gitbay/internal/hookd/peercred_linux.go history · blame · raw

38 lines · 754 bytes

 1//go:build linux
 2
 3package hookd
 4
 5import (
 6	"errors"
 7	"fmt"
 8	"net"
 9	"os"
10	"syscall"
11)
12
13// checkPeer refuses a connection from any uid but the daemon's: git,
14// and so every hook, runs as the daemon's user.
15func checkPeer(conn net.Conn) error {
16	uc, ok := conn.(*net.UnixConn)
17	if !ok {
18		return fmt.Errorf("not a unix socket connection")
19	}
20	raw, err := uc.SyscallConn()
21	if err != nil {
22		return err
23	}
24	var cred *syscall.Ucred
25	var credErr error
26	if err := raw.Control(func(fd uintptr) {
27		cred, credErr = syscall.GetsockoptUcred(int(fd), syscall.SOL_SOCKET, syscall.SO_PEERCRED)
28	}); err != nil {
29		return err
30	}
31	if credErr != nil {
32		return credErr
33	}
34	if int(cred.Uid) != os.Getuid() {
35		return errors.New("peer uid not permitted")
36	}
37	return nil
38}