require matching live tcpdump before real call
This commit is contained in:
@@ -201,9 +201,28 @@ func verifyCallEvidence(root, id, trunk, target string) error {
|
||||
if end == -1 || len(state) <= end+2 || state[end+2] == 'Z' || state[end+2] == 'X' {
|
||||
return errors.New("real call capture process has ended")
|
||||
}
|
||||
// /proc/<pid>/exe is not readable by the unprivileged Agent when
|
||||
// the host evidence script starts tcpdump as root.
|
||||
comm, err := os.ReadFile(filepath.Join("/proc", fields[0], "comm"))
|
||||
if err != nil || strings.TrimSpace(string(comm)) != "tcpdump" {
|
||||
return errors.New("real call capture process is not tcpdump")
|
||||
}
|
||||
args, err := os.ReadFile(filepath.Join("/proc", fields[0], "cmdline"))
|
||||
if err != nil || !capturesCall(strings.Split(string(args), "\x00"), id) {
|
||||
return errors.New("real call capture process does not record this call")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func capturesCall(args []string, id string) bool {
|
||||
for i := 0; i+1 < len(args); i++ {
|
||||
if args[i] == "-w" && filepath.IsAbs(args[i+1]) && filepath.Base(args[i+1]) == "capture.pcap" && filepath.Base(filepath.Dir(args[i+1])) == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *ApprovedRecordedRealCall) Run(ctx context.Context, approved ApprovedExecution) error {
|
||||
if ctx == nil {
|
||||
return errors.New("real call requires a context")
|
||||
|
||||
@@ -33,8 +33,8 @@ func TestRealCallRequiresLiveCaptureBoundToSignedIdentity(t *testing.T) {
|
||||
if err := os.WriteFile(marker, []byte(fmt.Sprintf("%d\t%s\t%s\n", os.Getpid(), trunk, target)), 0640); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := verifyCallEvidence(root, id, trunk, target); err != nil {
|
||||
t.Fatal(err)
|
||||
if err := verifyCallEvidence(root, id, trunk, target); err == nil {
|
||||
t.Fatal("a live process other than tcpdump must not arm real dialing")
|
||||
}
|
||||
if err := verifyCallEvidence(root, id, trunk, "15830461047"); err == nil {
|
||||
t.Fatal("capture bound to a different callee cannot authorize a real call")
|
||||
@@ -50,6 +50,24 @@ func TestRealCallRequiresLiveCaptureBoundToSignedIdentity(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCaptureProcessMustWriteThisCall(t *testing.T) {
|
||||
id := "event-1"
|
||||
args := []string{"/usr/bin/tcpdump", "-i", "any", "-nn", "-s0", "-U", "-w", "/var/lib/sip-go-agent/evidence/event-1/capture.pcap", "udp port 5060 or (udp portrange 10000-20000)"}
|
||||
if !capturesCall(args, id) {
|
||||
t.Fatal("the host script's tcpdump command must be recognized")
|
||||
}
|
||||
for _, bad := range [][]string{
|
||||
{"/usr/bin/tcpdump", "-w", "/var/lib/sip-go-agent/evidence/other/capture.pcap"},
|
||||
{"/usr/bin/tcpdump", "-w", "/var/lib/sip-go-agent/evidence/event-1/other.pcap"},
|
||||
{"/usr/bin/tcpdump", "-w", "event-1/capture.pcap"},
|
||||
{"/usr/bin/tcpdump", "/var/lib/sip-go-agent/evidence/event-1/capture.pcap"},
|
||||
} {
|
||||
if capturesCall(bad, id) {
|
||||
t.Fatalf("unrelated capture command accepted: %q", bad)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestApprovedRecordedRealCallReportsOnlyEndedObservedCall(t *testing.T) {
|
||||
fixture, stub, puts, _, approved := recordedMockFixture(t, nil, time.Second)
|
||||
approved.CallerID, approved.DialedCallee, approved.RingTimeout = "BD93205882", "7089"+approved.Callee, time.Second
|
||||
|
||||
Reference in New Issue
Block a user