// Program compare-cap is a sanity check that Go's cap package is
// inter-operable with the C libcap.
package main

import (
	"log"
	"os"
	"syscall"
	"unsafe"

	"kernel.org/pub/linux/libs/security/libcap/cap"
)

// #include <stdlib.h>
// #include <sys/capability.h>
// #cgo CFLAGS: -I../libcap/include
// #cgo LDFLAGS: -L../libcap -lcap
import "C"

// tryFileCaps attempts to use the cap package to manipulate file
// capabilities. No reference to libcap in this function.
func tryFileCaps() {
	saved := cap.GetProc()

	// Capabilities we will place on a file.
	want := cap.NewSet()
	if err := want.SetFlag(cap.Permitted, true, cap.SETFCAP, cap.DAC_OVERRIDE); err != nil {
		log.Fatalf("failed to explore desired file capability: %v", err)
	}
	if err := want.SetFlag(cap.Effective, true, cap.SETFCAP, cap.DAC_OVERRIDE); err != nil {
		log.Fatalf("failed to raise the effective bits: %v", err)
	}

	if perm, err := saved.GetFlag(cap.Permitted, cap.SETFCAP); err != nil {
		log.Fatalf("failed to read capability: %v", err)
	} else if !perm {
		log.Printf("skipping file cap tests - insufficient privilege")
		return
	}

	if err := saved.ClearFlag(cap.Effective); err != nil {
		log.Fatalf("failed to drop effective: %v", err)
	}
	if err := saved.SetProc(); err != nil {
		log.Fatalf("failed to limit capabilities: %v", err)
	}

	// Failing attempt to remove capabilities.
	var empty *cap.Set
	if err := empty.SetFile(os.Args[0]); err != syscall.EPERM {
		log.Fatalf("failed to be blocked from removing filecaps: %v", err)
	}

	// The privilege we want (in the case we are root, we need the
	// DAC_OVERRIDE too).
	working, err := saved.Dup()
	if err != nil {
		log.Fatalf("failed to duplicate (%v): %v", saved, err)
	}
	if err := working.SetFlag(cap.Effective, true, cap.DAC_OVERRIDE, cap.SETFCAP); err != nil {
		log.Fatalf("failed to raise effective: %v", err)
	}

	// Critical (privilege using) section:
	if err := working.SetProc(); err != nil {
		log.Fatalf("failed to enable first effective privilege: %v", err)
	}
	// Delete capability
	if err := empty.SetFile(os.Args[0]); err != nil && err != syscall.ENODATA {
		log.Fatalf("blocked from removing filecaps: %v", err)
	}
	if got, err := cap.GetFile(os.Args[0]); err == nil {
		log.Fatalf("read deleted file caps: %v", got)
	}
	// Create file caps (this use employs the effective bit).
	if err := want.SetFile(os.Args[0]); err != nil {
		log.Fatalf("failed to set file capability: %v", err)
	}
	if err := saved.SetProc(); err != nil {
		log.Fatalf("failed to lower effective capability: %v", err)
	}
	// End of critical section.

	if got, err := cap.GetFile(os.Args[0]); err != nil {
		log.Fatalf("failed to read caps: %v", err)
	} else if is, was := got.String(), want.String(); is != was {
		log.Fatalf("read file caps do not match desired: got=%q want=%q", is, was)
	}

	// Now, do it all again but this time on an open file.
	f, err := os.Open(os.Args[0])
	if err != nil {
		log.Fatalf("failed to open %q: %v", os.Args[0], err)
	}
	defer f.Close()

	// Failing attempt to remove capabilities.
	if err := empty.SetFd(f); err != syscall.EPERM {
		log.Fatalf("failed to be blocked from fremoving filecaps: %v", err)
	}

	// For the next section, we won't set the effective bit on the file.
	want.ClearFlag(cap.Effective)

	// Critical (privilege using) section:
	if err := working.SetProc(); err != nil {
		log.Fatalf("failed to enable effective privilege: %v", err)
	}
	if err := empty.SetFd(f); err != nil && err != syscall.ENODATA {
		log.Fatalf("blocked from fremoving filecaps: %v", err)
	}
	if got, err := cap.GetFd(f); err == nil {
		log.Fatalf("read fdeleted file caps: %v", got)
	}
	// This one does not set the effective bit.
	if err := want.SetFd(f); err != nil {
		log.Fatalf("failed to fset file capability: %v", err)
	}
	if err := saved.SetProc(); err != nil {
		log.Fatalf("failed to lower effective capability: %v", err)
	}
	// End of critical section.

	if got, err := cap.GetFd(f); err != nil {
		log.Fatalf("failed to fread caps: %v", err)
	} else if is, was := got.String(), want.String(); is != was {
		log.Fatalf("fread file caps do not match desired: got=%q want=%q", is, was)
	}
}

// tryProcCaps performs a set of convenience functions and compares
// the results with those seen by libcap. At the end of this function,
// the running process has no privileges at all. So exiting the
// program is the only option.
func tryProcCaps() {
	c := cap.GetProc()
	if v, err := c.GetFlag(cap.Permitted, cap.SETPCAP); err != nil {
		log.Fatalf("failed to read permitted setpcap: %v", err)
	} else if !v {
		log.Printf("skipping proc cap tests - insufficient privilege")
		return
	}
	if err := cap.SetUID(99); err != nil {
		log.Fatalf("failed to set uid=99: %v", err)
	}
	if u := syscall.Getuid(); u != 99 {
		log.Fatal("uid=99 did not take: got=%d", u)
	}
	if err := cap.SetGroups(98, 100, 101); err != nil {
		log.Fatalf("failed to set groups=98 [100, 101]: %v", err)
	}
	if g := syscall.Getgid(); g != 98 {
		log.Fatalf("gid=98 did not take: got=%d", g)
	}
	if gs, err := syscall.Getgroups(); err != nil {
		log.Fatalf("error getting groups: %v", err)
	} else if len(gs) != 2 || gs[0] != 100 || gs[1] != 101 {
		log.Fatalf("wrong of groups: got=%v want=[100 l01]", gs)
	}

	if mode := cap.GetMode(); mode != cap.ModeUncertain {
		log.Fatalf("initial mode should be 0 (UNCERTAIN), got: %d (%v)", mode, mode)
	}

	// To distinguish PURE1E and PURE1E_INIT we need an inheritable capability set.
	working := cap.GetProc()
	if err := working.SetFlag(cap.Inheritable, true, cap.SETPCAP); err != nil {
		log.Fatalf("unable to raise inheritable bit: %v", err)
	}
	if err := working.SetProc(); err != nil {
		log.Fatalf("failed to add inheritable bit: %v", err)
	}

	for i, mode := range []cap.Mode{cap.ModePure1E, cap.ModePure1EInit, cap.ModeNoPriv} {
		if err := mode.Set(); err != nil {
			log.Fatalf("[%d] in mode=%v and failed to set mode to %d (%v): %v", i, cap.GetMode(), mode, mode, err)
		}
		if got := cap.GetMode(); got != mode {
			log.Fatalf("[%d] unable to recognise mode %d (%v), got: %d (%v)", i, mode, mode, got, got)
		}
		cM := C.cap_get_mode()
		if mode != cap.Mode(cM) {
			log.Fatalf("[%d] C and Go disagree on mode: %d vs %d", cM, mode)
		}
	}

	// The current process is now without any access to privelege.
}

func main() {
	// Use the C libcap to obtain a non-trivial capability in text form (from init).
	cC := C.cap_get_pid(1)
	if cC == nil {
		log.Fatal("basic c caps from init function failure")
	}
	defer C.cap_free(unsafe.Pointer(cC))
	var tCLen C.ssize_t
	tC := C.cap_to_text(cC, &tCLen)
	if tC == nil {
		log.Fatal("basic c init caps -> text failure")
	}
	defer C.cap_free(unsafe.Pointer(tC))

	importT := C.GoString(tC)
	if got, want := len(importT), int(tCLen); got != want {
		log.Fatalf("C string import failed: got=%d [%q] want=%d", got, importT, want)
	}

	// Validate that it can be decoded in Go.
	cGo, err := cap.FromText(importT)
	if err != nil {
		log.Fatalf("go parsing of c text import failed: %v", err)
	}

	// Validate that it matches the one directly loaded in Go.
	c, err := cap.GetPID(1)
	if err != nil {
		log.Fatalf("...failed to read init's capabilities:", err)
	}
	tGo := c.String()
	if got, want := tGo, cGo.String(); got != want {
		log.Fatalf("go text rep does not match c: got=%q, want=%q", got, want)
	}

	// Export it in text form again from Go.
	tForC := C.CString(tGo)
	defer C.free(unsafe.Pointer(tForC))

	// Validate it can be encoded in C.
	cC2 := C.cap_from_text(tForC)
	if cC2 == nil {
		log.Fatal("go text rep not parsable by c")
	}
	defer C.cap_free(unsafe.Pointer(cC2))

	// Validate that it can be exported in binary form in C
	const enoughForAnyone = 1000
	eC := make([]byte, enoughForAnyone)
	eCLen := C.cap_copy_ext(unsafe.Pointer(&eC[0]), cC2, C.ssize_t(len(eC)))
	if eCLen < 5 {
		log.Fatalf("c export yielded bad length: %d", eCLen)
	}

	// Validate that it can be imported from binary in Go
	iGo, err := cap.Import(eC[:eCLen])
	if err != nil {
		log.Fatalf("go import of c binary failed: %v", err)
	}
	if got, want := iGo.String(), importT; got != want {
		log.Fatalf("go import of c binary miscompare: got=%q want=%q", got, want)
	}

	// Validate that it can be exported in binary in Go
	iE, err := iGo.Export()
	if err != nil {
		log.Fatalf("go failed to export binary: %v", err)
	}

	// Validate that it can be imported in binary in C
	iC := C.cap_copy_int(unsafe.Pointer(&iE[0]))
	if iC == nil {
		log.Fatal("c failed to import go binary")
	}
	defer C.cap_free(unsafe.Pointer(iC))
	fC := C.cap_to_text(cC, &tCLen)
	if fC == nil {
		log.Fatal("basic c init caps -> text failure")
	}
	defer C.cap_free(unsafe.Pointer(fC))
	if got, want := C.GoString(fC), importT; got != want {
		log.Fatalf("c import from go yielded bad caps: got=%q want=%q", got, want)
	}

	// Validate that everyone agrees what all is:
	want := "=ep"
	all, err := cap.FromText("all=ep")
	if err != nil {
		log.Fatalf("unable to parse all=ep: %v", err)
	}
	if got := all.String(); got != want {
		log.Fatalf("all decode failed in Go: got=%q, want=%q", got, want)
	}

	// Validate some random values stringify consistently between
	// libcap.cap_to_text() and (*cap.Set).String().
	mb := cap.MaxBits()
	sample := cap.NewSet()
	for c := cap.Value(0); c < 7*mb; c += 3 {
		n := int(c)
		raise, f := c%mb, cap.Flag(c/mb)%3
		sample.SetFlag(f, true, raise)
		if v, err := cap.FromText(sample.String()); err != nil {
			log.Fatalf("[%d] cap to text for %q not reversible: %v", n, sample, err)
		} else if cf, err := v.Compare(sample); err != nil {
			log.Fatalf("[%d] FromText generated bad capability from %q: %v", n, sample, err)
		} else if cf != 0 {
			log.Fatalf("[%d] text import got=%q want=%q", n, v, sample)
		}
		e, err := sample.Export()
		if err != nil {
			log.Fatalf("[%d] failed to export %q: %v", n, sample, err)
		}
		i, err := cap.Import(e)
		if err != nil {
			log.Fatalf("[%d] failed to import %q: %v", n, sample, err)
		}
		if cf, err := i.Compare(sample); err != nil {
			log.Fatalf("[%d] failed to compare %q vs original:%q", n, i, sample)
		} else if cf != 0 {
			log.Fatalf("[%d] import got=%q want=%q", n, i, sample)
		}
		// Confirm that importing this portable binary
		// representation in libcap and converting to text,
		// generates the same text as Go generates. This was
		// broken prior to v0.2.41.
		cCap := C.cap_copy_int(unsafe.Pointer(&e[0]))
		if cCap == nil {
			log.Fatalf("[%d] C import failed for %q export", n, sample)
		}
		var tCLen C.ssize_t
		tC := C.cap_to_text(cCap, &tCLen)
		if tC == nil {
			log.Fatalf("[%d] basic c init caps -> text failure", n)
		}
		C.cap_free(unsafe.Pointer(cCap))
		importT := C.GoString(tC)
		C.cap_free(unsafe.Pointer(tC))
		if got, want := len(importT), int(tCLen); got != want {
			log.Fatalf("[%d] C text generated wrong length: Go=%d, C=%d", n, got, want)
		}
		if got, want := importT, sample.String(); got != want {
			log.Fatalf("[%d] C and Go text rep disparity: C=%q Go=%q", n, got, want)
		}
	}

	iab, err := cap.IABFromText("cap_chown,!cap_setuid,^cap_setgid")
	if err != nil {
		log.Fatalf("failed to initialize iab from text: %v", err)
	}
	cIAB := C.cap_iab_init()
	defer C.cap_free(unsafe.Pointer(cIAB))
	for c := cap.MaxBits(); c > 0; {
		c--
		if en, err := iab.GetVector(cap.Inh, c); err != nil {
			log.Fatalf("failed to read iab.i[%v]", c)
		} else if en {
			if C.cap_iab_set_vector(cIAB, C.CAP_IAB_INH, C.cap_value_t(int(c)), C.CAP_SET) != 0 {
				log.Fatalf("failed to set C's AIB.I %v: %v", c)
			}
		}
		if en, err := iab.GetVector(cap.Amb, c); err != nil {
			log.Fatalf("failed to read iab.a[%v]", c)
		} else if en {
			if C.cap_iab_set_vector(cIAB, C.CAP_IAB_AMB, C.cap_value_t(int(c)), C.CAP_SET) != 0 {
				log.Fatalf("failed to set C's AIB.A %v: %v", c)
			}
		}
		if en, err := iab.GetVector(cap.Bound, c); err != nil {
			log.Fatalf("failed to read iab.b[%v]", c)
		} else if en {
			if C.cap_iab_set_vector(cIAB, C.CAP_IAB_BOUND, C.cap_value_t(int(c)), C.CAP_SET) != 0 {
				log.Fatalf("failed to set C's AIB.B %v: %v", c)
			}
		}
	}
	iabC := C.cap_iab_to_text(cIAB)
	if iabC == nil {
		log.Fatalf("failed to get text from C for %q", iab)
	}
	defer C.cap_free(unsafe.Pointer(iabC))
	if got, want := C.GoString(iabC), iab.String(); got != want {
		log.Fatalf("IAB for Go and C differ: got=%q, want=%q", got, want)
	}

	// Next, we attempt to manipulate some file capabilities on
	// the running program.  These are optional, based on whether
	// the current program is capable enough and do not involve
	// any cgo calls to libcap.
	tryFileCaps()

	// Nothing left to do but exit after this one.
	tryProcCaps()
	log.Printf("compare-cap success!")
}
