github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/monitor/remoteapi/server/server_nonwindows.go (about)

     1  // +build !windows
     2  
     3  package server
     4  
     5  import (
     6  	"fmt"
     7  	"net"
     8  	"net/http"
     9  	"os"
    10  	"strconv"
    11  	"strings"
    12  
    13  	"github.com/shirou/gopsutil/process"
    14  	"go.aporeto.io/enforcerd/trireme-lib/common"
    15  )
    16  
    17  func cleanupPipe(address string) error {
    18  	// Cleanup the socket first.
    19  	if _, err := os.Stat(address); err == nil {
    20  		if err := os.Remove(address); err != nil {
    21  			return fmt.Errorf("Cannot create clean up socket: %s", err)
    22  		}
    23  	}
    24  	return nil
    25  }
    26  
    27  func (e *EventServer) makePipe() (net.Listener, error) {
    28  	// Start a custom listener
    29  	addr, _ := net.ResolveUnixAddr("unix", e.socketPath)
    30  	nl, err := net.ListenUnix("unix", addr)
    31  
    32  	if err != nil {
    33  		return nil, fmt.Errorf("Unable to start API server: %s", err)
    34  	}
    35  
    36  	// We make the socket accesible to all users of the system.
    37  	// TODO: create a trireme group for this
    38  	if err := os.Chmod(addr.String(), 0766); err != nil {
    39  		return nil, fmt.Errorf("Cannot make the socket accessible to all users: %s", err)
    40  	}
    41  
    42  	return &UIDListener{nl}, nil
    43  }
    44  
    45  // validateUser validates that the originating user is not sending a request
    46  // for a process that they don't own. Root users are allowed to send
    47  // any event.
    48  func validateUser(r *http.Request, event *common.EventInfo) error {
    49  
    50  	// Find the calling user.
    51  	parts := strings.Split(r.RemoteAddr, ":")
    52  	if len(parts) != 3 {
    53  		return fmt.Errorf("Invalid user context")
    54  	}
    55  
    56  	// Accept all requests from root users
    57  	if parts[0] == "0" {
    58  		return nil
    59  	}
    60  
    61  	// The target process must be valid.
    62  	p, err := process.NewProcess(event.PID)
    63  	if err != nil {
    64  		return fmt.Errorf("Process not found")
    65  	}
    66  
    67  	// The UID of the calling process must match the UID of the target process.
    68  	uids, err := p.Uids()
    69  	if err != nil {
    70  		return fmt.Errorf("Unknown user ID")
    71  	}
    72  
    73  	match := false
    74  	for _, uid := range uids {
    75  		if strconv.Itoa(int(uid)) == parts[0] {
    76  			match = true
    77  		}
    78  	}
    79  
    80  	if !match {
    81  		return fmt.Errorf("Invalid user - no access to this process: %+v PARTS: %+v", event, parts)
    82  	}
    83  
    84  	return nil
    85  }