Пример #1
0
// GETLayersVulnerabilities returns the complete list of vulnerabilities that
// a layer has if it exists.
func GETLayersVulnerabilities(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Get minumum priority parameter.
	minimumPriority := types.Priority(r.URL.Query().Get("minimumPriority"))
	if minimumPriority == "" {
		minimumPriority = "High" // Set default priority to High
	} else if !minimumPriority.IsValid() {
		jsonhttp.RenderError(w, 0, cerrors.NewBadRequestError("invalid priority"))
		return
	}

	// Find layer
	layer, err := database.FindOneLayerByID(p.ByName("id"), []string{database.FieldLayerParent, database.FieldLayerPackages})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Find layer's packages.
	packagesNodes, err := layer.AllPackages()
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Find vulnerabilities.
	vulnerabilities, err := getVulnerabilitiesFromLayerPackagesNodes(packagesNodes, minimumPriority, []string{database.FieldVulnerabilityID, database.FieldVulnerabilityLink, database.FieldVulnerabilityPriority, database.FieldVulnerabilityDescription})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	jsonhttp.Render(w, http.StatusOK, struct{ Vulnerabilities []*database.Vulnerability }{Vulnerabilities: vulnerabilities})
}
Пример #2
0
// GETLayersPackagesDiff returns the list of packages that a layer installs and
// removes if it exists.
func GETLayersPackagesDiff(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Find layer.
	layer, err := database.FindOneLayerByID(p.ByName("id"), []string{database.FieldLayerPackages})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Find layer's packages.
	installedPackages, removedPackages := make([]*database.Package, 0), make([]*database.Package, 0)
	if len(layer.InstalledPackagesNodes) > 0 {
		installedPackages, err = database.FindAllPackagesByNodes(layer.InstalledPackagesNodes, []string{database.FieldPackageOS, database.FieldPackageName, database.FieldPackageVersion})
		if err != nil {
			jsonhttp.RenderError(w, 0, err)
			return
		}
	}
	if len(layer.RemovedPackagesNodes) > 0 {
		removedPackages, err = database.FindAllPackagesByNodes(layer.RemovedPackagesNodes, []string{database.FieldPackageOS, database.FieldPackageName, database.FieldPackageVersion})
		if err != nil {
			jsonhttp.RenderError(w, 0, err)
			return
		}
	}

	jsonhttp.Render(w, http.StatusOK, struct{ InstalledPackages, RemovedPackages []*database.Package }{InstalledPackages: installedPackages, RemovedPackages: removedPackages})
}
Пример #3
0
// GETLayersPackages returns the complete list of packages that a layer has
// if it exists.
func GETLayersPackages(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Find layer
	layer, err := database.FindOneLayerByID(p.ByName("id"), []string{database.FieldLayerParent, database.FieldLayerPackages})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Find layer's packages.
	packagesNodes, err := layer.AllPackages()
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	packages := []*database.Package{}
	if len(packagesNodes) > 0 {
		packages, err = database.FindAllPackagesByNodes(packagesNodes, []string{database.FieldPackageOS, database.FieldPackageName, database.FieldPackageVersion})
		if err != nil {
			jsonhttp.RenderError(w, 0, err)
			return
		}
	}

	jsonhttp.Render(w, http.StatusOK, struct{ Packages []*database.Package }{Packages: packages})
}
Пример #4
0
// GETVulnerabilities returns a vulnerability identified by an ID if it exists.
func GETVulnerabilities(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Find vulnerability.
	vulnerability, err := database.FindOneVulnerability(p.ByName("id"), []string{database.FieldVulnerabilityID, database.FieldVulnerabilityLink, database.FieldVulnerabilityPriority, database.FieldVulnerabilityDescription, database.FieldVulnerabilityFixedIn})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	abstractVulnerability, err := vulnerability.ToAbstractVulnerability()
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	jsonhttp.Render(w, http.StatusOK, abstractVulnerability)
}
Пример #5
0
// POSTLayers analyzes a layer and returns the engine version that has been used
// for the analysis.
func POSTLayers(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var parameters POSTLayersParameters
	if s, err := jsonhttp.ParseBody(r, &parameters); err != nil {
		jsonhttp.RenderError(w, s, err)
		return
	}

	// Process data.
	if err := worker.Process(parameters.ID, parameters.ParentID, parameters.Path); err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Get engine version and return.
	jsonhttp.Render(w, http.StatusCreated, struct{ Version string }{Version: strconv.Itoa(worker.Version)})
}
Пример #6
0
// TimeOut wraps a http.HandlerFunc and ensure that a response is given under
// the specified duration.
//
// If the handler takes longer than the time limit, the wrapper responds with
// a Service Unavailable error, an error message and the handler response which
// may come later is ignored.
//
// After a timeout, any write the handler to its ResponseWriter will return
// ErrHandlerTimeout.
//
// If the duration is 0, the wrapper does nothing.
func TimeOut(d time.Duration, fn httprouter.Handle) httprouter.Handle {
	if d == 0 {
		fmt.Println("nope timeout")
		return fn
	}

	return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
		done := make(chan bool)
		tw := &timeoutWriter{ResponseWriter: w}

		go func() {
			fn(tw, r, p)
			done <- true
		}()

		select {
		case <-done:
			return
		case <-time.After(d):
			tw.mu.Lock()
			defer tw.mu.Unlock()
			if !tw.wroteHeader {
				jsonhttp.RenderError(tw.ResponseWriter, http.StatusServiceUnavailable, ErrHandlerTimeout)
			}
			tw.timedOut = true
		}
	}
}
Пример #7
0
// GETLayersOS returns the operating system of a layer if it exists.
// It uses not only the specified layer but also its parent layers if necessary.
// An empty OS string is returned if no OS has been detected.
func GETLayersOS(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Find layer.
	layer, err := database.FindOneLayerByID(p.ByName("id"), []string{database.FieldLayerParent, database.FieldLayerOS})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Get OS.
	os, err := layer.OperatingSystem()
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	jsonhttp.Render(w, http.StatusOK, struct{ OS string }{OS: os})
}
Пример #8
0
// GETLayersVulnerabilitiesDiff returns the list of vulnerabilities that a layer
// adds and removes if it exists.
func GETLayersVulnerabilitiesDiff(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Get minumum priority parameter.
	minimumPriority := types.Priority(r.URL.Query().Get("minimumPriority"))
	if minimumPriority == "" {
		minimumPriority = "High" // Set default priority to High
	} else if !minimumPriority.IsValid() {
		jsonhttp.RenderError(w, 0, cerrors.NewBadRequestError("invalid priority"))
		return
	}

	// Find layer.
	layer, err := database.FindOneLayerByID(p.ByName("id"), []string{database.FieldLayerPackages})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Selected fields for vulnerabilities.
	selectedFields := []string{database.FieldVulnerabilityID, database.FieldVulnerabilityLink, database.FieldVulnerabilityPriority, database.FieldVulnerabilityDescription}

	// Find vulnerabilities for installed packages.
	addedVulnerabilities, err := getVulnerabilitiesFromLayerPackagesNodes(layer.InstalledPackagesNodes, minimumPriority, selectedFields)
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Find vulnerabilities for removed packages.
	removedVulnerabilities, err := getVulnerabilitiesFromLayerPackagesNodes(layer.RemovedPackagesNodes, minimumPriority, selectedFields)
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Remove vulnerabilities which appears both in added and removed lists (eg. case of updated packages but still vulnerable).
	for ia, a := range addedVulnerabilities {
		for ir, r := range removedVulnerabilities {
			if a.ID == r.ID {
				addedVulnerabilities = append(addedVulnerabilities[:ia], addedVulnerabilities[ia+1:]...)
				removedVulnerabilities = append(removedVulnerabilities[:ir], removedVulnerabilities[ir+1:]...)
			}
		}
	}

	jsonhttp.Render(w, http.StatusOK, struct{ Adds, Removes []*database.Vulnerability }{Adds: addedVulnerabilities, Removes: removedVulnerabilities})
}
Пример #9
0
// DELVulnerabilities deletes a vulnerability if it exists.
func DELVulnerabilities(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	err := database.DeleteVulnerability(p.ByName("id"))
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	jsonhttp.Render(w, http.StatusNoContent, nil)
}
Пример #10
0
// PUTVulnerabilities updates a vulnerability if it exists.
func PUTVulnerabilities(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	var parameters *database.AbstractVulnerability
	if s, err := jsonhttp.ParseBody(r, &parameters); err != nil {
		jsonhttp.RenderError(w, s, err)
		return
	}
	parameters.ID = p.ByName("id")

	// Ensure that the vulnerability exists.
	_, err := database.FindOneVulnerability(parameters.ID, []string{})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Insert packages.
	packages := database.AbstractPackagesToPackages(parameters.AffectedPackages)
	err = database.InsertPackages(packages)
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}
	var pkgNodes []string
	for _, p := range packages {
		pkgNodes = append(pkgNodes, p.Node)
	}

	// Insert vulnerability.
	notifications, err := database.InsertVulnerabilities([]*database.Vulnerability{parameters.ToVulnerability(pkgNodes)})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Insert notifications.
	err = database.InsertNotifications(notifications, database.GetDefaultNotificationWrapper())
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	jsonhttp.Render(w, http.StatusCreated, nil)
}
Пример #11
0
// GETVulnerabilitiesIntroducingLayers returns the list of layers that
// introduces a given vulnerability, if it exists.
// To clarify, it does not return the list of every layers that have
// the vulnerability.
func GETVulnerabilitiesIntroducingLayers(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Find vulnerability to verify that it exists.
	_, err := database.FindOneVulnerability(p.ByName("id"), []string{})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	layers, err := database.FindAllLayersIntroducingVulnerability(p.ByName("id"), []string{database.FieldLayerID})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	layersIDs := []string{}
	for _, l := range layers {
		layersIDs = append(layersIDs, l.ID)
	}

	jsonhttp.Render(w, http.StatusOK, struct{ IntroducingLayersIDs []string }{IntroducingLayersIDs: layersIDs})
}
Пример #12
0
// GETLayersParent returns the parent ID of a layer if it exists.
// An empty ID string is returned if the layer has no parent.
func GETLayersParent(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Find layer
	layer, err := database.FindOneLayerByID(p.ByName("id"), []string{database.FieldLayerParent})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Get layer's parent.
	parent, err := layer.Parent([]string{database.FieldLayerID})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	ID := ""
	if parent != nil {
		ID = parent.ID
	}
	jsonhttp.Render(w, http.StatusOK, struct{ ID string }{ID: ID})
}
Пример #13
0
// POSTBatchLayersVulnerabilities returns the complete list of vulnerabilities
// that the provided layers have, if they all exist.
func POSTBatchLayersVulnerabilities(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Parse body
	var parameters POSTBatchLayersVulnerabilitiesParameters
	if s, err := jsonhttp.ParseBody(r, &parameters); err != nil {
		jsonhttp.RenderError(w, s, err)
		return
	}
	if len(parameters.LayersIDs) == 0 {
		jsonhttp.RenderError(w, http.StatusBadRequest, errors.New("at least one LayerID query parameter must be provided"))
		return
	}

	// Get minumum priority parameter.
	minimumPriority := types.Priority(r.URL.Query().Get("minimumPriority"))
	if minimumPriority == "" {
		minimumPriority = "High" // Set default priority to High
	} else if !minimumPriority.IsValid() {
		jsonhttp.RenderError(w, 0, cerrors.NewBadRequestError("invalid priority"))
		return
	}

	response := make(map[string]interface{})
	// For each LayerID parameter
	for _, layerID := range parameters.LayersIDs {
		// Find layer
		layer, err := database.FindOneLayerByID(layerID, []string{database.FieldLayerParent, database.FieldLayerPackages})
		if err != nil {
			jsonhttp.RenderError(w, 0, err)
			return
		}

		// Find layer's packages.
		packagesNodes, err := layer.AllPackages()
		if err != nil {
			jsonhttp.RenderError(w, 0, err)
			return
		}

		// Find vulnerabilities.
		vulnerabilities, err := getVulnerabilitiesFromLayerPackagesNodes(packagesNodes, minimumPriority, []string{database.FieldVulnerabilityID, database.FieldVulnerabilityLink, database.FieldVulnerabilityPriority, database.FieldVulnerabilityDescription})
		if err != nil {
			jsonhttp.RenderError(w, 0, err)
			return
		}

		response[layerID] = struct{ Vulnerabilities []*database.Vulnerability }{Vulnerabilities: vulnerabilities}
	}

	jsonhttp.Render(w, http.StatusOK, response)
}
Пример #14
0
// POSTVulnerabilitiesAffectedLayers returns whether the specified layers
// (by their IDs) are vulnerable to the given Vulnerability or not.
func POSTVulnerabilitiesAffectedLayers(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Parse body.
	var parameters POSTBatchLayersVulnerabilitiesParameters
	if s, err := jsonhttp.ParseBody(r, &parameters); err != nil {
		jsonhttp.RenderError(w, s, err)
		return
	}
	if len(parameters.LayersIDs) == 0 {
		jsonhttp.RenderError(w, http.StatusBadRequest, errors.New("getting the entire list of affected layers is not supported yet: at least one LayerID query parameter must be provided"))
		return
	}

	// Find vulnerability.
	vulnerability, err := database.FindOneVulnerability(p.ByName("id"), []string{database.FieldVulnerabilityFixedIn})
	if err != nil {
		jsonhttp.RenderError(w, 0, err)
		return
	}

	// Save the fixed in nodes into a map for fast check.
	fixedInPackagesMap := make(map[string]struct{})
	for _, fixedInNode := range vulnerability.FixedInNodes {
		fixedInPackagesMap[fixedInNode] = struct{}{}
	}

	response := make(map[string]interface{})
	// For each LayerID parameter.
	for _, layerID := range parameters.LayersIDs {
		// Find layer
		layer, err := database.FindOneLayerByID(layerID, []string{database.FieldLayerParent, database.FieldLayerPackages, database.FieldLayerPackages})
		if err != nil {
			jsonhttp.RenderError(w, 0, err)
			return
		}

		// Find layer's packages.
		packagesNodes, err := layer.AllPackages()
		if err != nil {
			jsonhttp.RenderError(w, 0, err)
			return
		}

		// Get successors packages of layer' packages.
		successors, err := getSuccessorsFromPackagesNodes(packagesNodes)
		if err != nil {
			jsonhttp.RenderError(w, 0, err)
			return
		}

		// Determine if the layer is vulnerable by verifying if one of the successors
		// of its packages are fixed by the vulnerability.
		vulnerable := false
		for _, p := range successors {
			if _, fixed := fixedInPackagesMap[p]; fixed {
				vulnerable = true
				break
			}
		}

		response[layerID] = struct{ Vulnerable bool }{Vulnerable: vulnerable}
	}

	jsonhttp.Render(w, http.StatusOK, response)
}