go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/os_rootcertificates.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package resources
     5  
     6  import (
     7  	"errors"
     8  
     9  	"github.com/rs/zerolog/log"
    10  	"go.mondoo.com/cnquery/llx"
    11  	"go.mondoo.com/cnquery/providers-sdk/v1/plugin"
    12  	"go.mondoo.com/cnquery/providers/os/connection/shared"
    13  	"go.mondoo.com/cnquery/types"
    14  )
    15  
    16  var BsdCertFiles = []string{
    17  	"/usr/local/etc/ssl/cert.pem",            // FreeBSD
    18  	"/etc/ssl/cert.pem",                      // OpenBSD
    19  	"/usr/local/share/certs/ca-root-nss.crt", // DragonFly
    20  	"/etc/openssl/certs/ca-certificates.crt", // NetBSD
    21  }
    22  
    23  var LinuxCertFiles = []string{
    24  	"/etc/ssl/certs/ca-certificates.crt",                // Debian/Ubuntu/Gentoo etc.
    25  	"/etc/pki/tls/certs/ca-bundle.crt",                  // Fedora/RHEL 6
    26  	"/etc/ssl/ca-bundle.pem",                            // OpenSUSE
    27  	"/etc/pki/tls/cacert.pem",                           // OpenELEC
    28  	"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
    29  	"/etc/ssl/cert.pem",                                 // Alpine Linux
    30  }
    31  
    32  var LinuxCertDirectories = []string{
    33  	"/etc/ssl/certs",               // SLES10/SLES11, https://golang.org/issue/12139
    34  	"/system/etc/security/cacerts", // Android
    35  	"/usr/local/share/certs",       // FreeBSD
    36  	"/etc/pki/tls/certs",           // Fedora/RHEL
    37  	"/etc/openssl/certs",           // NetBSD
    38  	"/var/ssl/certs",               // AIX
    39  }
    40  
    41  func (s *mqlOsRootCertificates) id() (string, error) {
    42  	return "osrootcertificates", nil
    43  }
    44  
    45  func initOsRootCertificates(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) {
    46  	conn := runtime.Connection.(shared.Connection)
    47  	platform := conn.Asset().Platform
    48  
    49  	var paths []string
    50  	if platform.IsFamily("linux") {
    51  		paths = LinuxCertFiles
    52  	} else if platform.IsFamily("bsd") {
    53  		paths = BsdCertFiles
    54  	} else {
    55  		return nil, nil, errors.New("root certificates are not unsupported on this platform: " + platform.Name + " " + platform.Version)
    56  	}
    57  
    58  	// search the first file that exists, it mimics the behavior go is doing
    59  	files := []interface{}{}
    60  	for i := range paths {
    61  		f, err := CreateResource(runtime, "file", map[string]*llx.RawData{
    62  			"path": llx.StringData(paths[i]),
    63  		})
    64  		if err != nil {
    65  			return nil, nil, err
    66  		}
    67  
    68  		file := f.(*mqlFile)
    69  		if !file.GetExists().Data {
    70  			log.Trace().Err(err).Str("path", paths[i]).Msg("os.rootcertificates> file does not exist")
    71  			continue
    72  		}
    73  		perm := file.GetPermissions()
    74  		if perm.Error != nil {
    75  			log.Trace().Err(err).Str("path", paths[i]).Msg("os.rootcertificates> failed to get permissions")
    76  			continue
    77  		}
    78  		if !perm.Data.GetIsFile().Data {
    79  			continue
    80  		}
    81  
    82  		files = append(files, file)
    83  	}
    84  
    85  	args["files"] = llx.ArrayData(files, types.Resource("file"))
    86  
    87  	return args, nil, nil
    88  }
    89  
    90  func (s *mqlOsRootCertificates) content(files []interface{}) ([]interface{}, error) {
    91  	contents := []interface{}{}
    92  
    93  	for i := range files {
    94  		file := files[i].(*mqlFile)
    95  
    96  		content := file.GetContent()
    97  		if content.Error != nil {
    98  			return nil, content.Error
    99  		}
   100  		contents = append(contents, content.Data)
   101  	}
   102  
   103  	return contents, nil
   104  }
   105  
   106  func (p *mqlOsRootCertificates) list(contents []interface{}) ([]interface{}, error) {
   107  	var res []interface{}
   108  	for i := range contents {
   109  		certificates, err := p.MqlRuntime.CreateSharedResource("certificates", map[string]*llx.RawData{
   110  			"pem": llx.StringData(contents[i].(string)),
   111  		})
   112  		if err != nil {
   113  			return nil, err
   114  		}
   115  
   116  		list, err := p.MqlRuntime.GetSharedData("certificates", certificates.MqlID(), "list")
   117  		if err != nil {
   118  			return nil, err
   119  		}
   120  
   121  		res = append(res, list.Value.([]interface{})...)
   122  	}
   123  
   124  	return res, nil
   125  }