github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/monitor/extractors/windows.go (about)

     1  // +build windows
     2  
     3  package extractors
     4  
     5  import (
     6  	"encoding/hex"
     7  	"fmt"
     8  	"os/user"
     9  	"strconv"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/shirou/gopsutil/process"
    14  	"go.aporeto.io/enforcerd/trireme-lib/common"
    15  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    16  	"go.aporeto.io/enforcerd/trireme-lib/utils/cgnetcls"
    17  	portspec "go.aporeto.io/enforcerd/trireme-lib/utils/portspec"
    18  )
    19  
    20  // WindowsMetadataExtractorType is a type of Windows metadata extractors
    21  type WindowsMetadataExtractorType func(event *common.EventInfo) (*policy.PURuntime, error)
    22  
    23  // WindowsServiceEventMetadataExtractor is a windows service based metadata extractor
    24  func WindowsServiceEventMetadataExtractor(event *common.EventInfo) (*policy.PURuntime, error) {
    25  
    26  	runtimeTags := policy.NewTagStore()
    27  
    28  	for _, tag := range event.Tags {
    29  		parts := strings.SplitN(tag, "=", 2)
    30  		if len(parts) != 2 {
    31  			return nil, fmt.Errorf("invalid tag: %s", tag)
    32  		}
    33  		key, value := parts[0], parts[1]
    34  
    35  		if strings.HasPrefix(key, "@app:windows:") {
    36  			runtimeTags.AppendKeyValue(key, value)
    37  			continue
    38  		}
    39  
    40  		runtimeTags.AppendKeyValue("@usr:"+key, value)
    41  	}
    42  
    43  	userdata := WinProcessInfo(event.PID)
    44  
    45  	for _, u := range userdata {
    46  		runtimeTags.AppendKeyValue("@app:windows:"+u, "true")
    47  	}
    48  
    49  	runtimeTags.AppendKeyValue("@os:hostname", findFQDN(time.Second))
    50  
    51  	if fileMd5, err := ComputeFileMd5(event.Executable); err == nil {
    52  		runtimeTags.AppendKeyValue("@app:windows:filechecksum", hex.EncodeToString(fileMd5))
    53  	}
    54  
    55  	depends := getDllImports(event.Name)
    56  	for _, lib := range depends {
    57  		runtimeTags.AppendKeyValue("@app:windows:lib:"+lib, "true")
    58  	}
    59  
    60  	options := policy.OptionsType{}
    61  	for index, s := range event.Services {
    62  		if s.Port != 0 && s.Ports == nil {
    63  			pspec, err := portspec.NewPortSpec(s.Port, s.Port, nil)
    64  			if err != nil {
    65  				return nil, fmt.Errorf("Invalid Port Spec %s", err)
    66  			}
    67  			event.Services[index].Ports = pspec
    68  			event.Services[index].Port = 0
    69  		}
    70  	}
    71  	options.Services = event.Services
    72  	options.UserID, _ = runtimeTags.Get("@usr:originaluser")
    73  	options.CgroupMark = strconv.FormatUint(cgnetcls.MarkVal(), 10)
    74  	options.AutoPort = event.AutoPort
    75  
    76  	runtimeIps := policy.ExtendedMap{"bridge": "0.0.0.0/0"}
    77  
    78  	return policy.NewPURuntime(event.Name, int(event.PID), "", runtimeTags, runtimeIps, event.PUType, policy.None, &options), nil
    79  }
    80  
    81  // WinProcessInfo returns all metadata captured by a Windows process
    82  func WinProcessInfo(pid int32) []string {
    83  	userdata := []string{}
    84  
    85  	p, err := process.NewProcess(pid)
    86  	if err != nil {
    87  		return userdata
    88  	}
    89  
    90  	// TODO(windows): do equivalent of uids and gids (using GetNamedSecurityInfo and LookupAccountSid, eg)
    91  	uids, err := p.Uids()
    92  	if err != nil {
    93  		return userdata
    94  	}
    95  
    96  	groups, err := p.Gids()
    97  	if err != nil {
    98  		return userdata
    99  	}
   100  
   101  	username, err := p.Username()
   102  	if err != nil {
   103  		return userdata
   104  	}
   105  
   106  	for _, uid := range uids {
   107  		userdata = append(userdata, "uid:"+strconv.Itoa(int(uid)))
   108  	}
   109  
   110  	for _, gid := range groups {
   111  		userdata = append(userdata, "gid:"+strconv.Itoa(int(gid)))
   112  	}
   113  
   114  	userdata = append(userdata, "username:"+username)
   115  
   116  	userid, err := user.Lookup(username)
   117  	if err != nil {
   118  		return userdata
   119  	}
   120  
   121  	gids, err := userid.GroupIds()
   122  	if err != nil {
   123  		return userdata
   124  	}
   125  
   126  	for i := 0; i < len(gids); i++ {
   127  		userdata = append(userdata, "gids:"+gids[i])
   128  		group, err := user.LookupGroupId(gids[i])
   129  		if err != nil {
   130  			continue
   131  		}
   132  		userdata = append(userdata, "groups:"+group.Name)
   133  	}
   134  
   135  	return userdata
   136  }
   137  
   138  // getDllImports returns the list of dynamic library dependencies of an executable
   139  // TODO(windows): debug/pe File.ImportedLibraries is not implemented currently
   140  func getDllImports(binpath string) []string {
   141  	return []string{}
   142  }