just a version number or ``git-checkout'', and should not have a
@code{file-name} declared (@pxref{origin Reference}).
+@item cve
+Report known vulnerabilities found in the Common Vulnerabilities and
+Exposures (CVE) database
+@uref{https://nvd.nist.gov/download.cfm#CVE_FEED, published by the US
+NIST}.
+
@item formatting
Warn about obvious source code formatting issues: trailing white space,
use of tabulations, etc.
#:use-module (guix scripts)
#:use-module (guix gnu-maintenance)
#:use-module (guix monads)
+ #:use-module (guix cve)
#:use-module (gnu packages)
#:use-module (ice-9 match)
#:use-module (ice-9 regex)
check-source
check-source-file-name
check-license
+ check-vulnerabilities
check-formatting
run-checkers
(emit-warning package (_ "invalid license field")
'license))))
+(define (package-name->cpe-name name)
+ "Do a basic conversion of NAME, a Guix package name, to the corresponding
+Common Platform Enumeration (CPE) name."
+ (match name
+ ("icecat" "firefox") ;or "firefox_esr"
+ ;; TODO: Add more.
+ (_ name)))
+
+(define package-vulnerabilities
+ (let ((lookup (delay (vulnerabilities->lookup-proc
+ (current-vulnerabilities)))))
+ (lambda (package)
+ "Return a list of vulnerabilities affecting PACKAGE."
+ ((force lookup)
+ (package-name->cpe-name (package-name package))
+ (package-version package)))))
+
+(define (check-vulnerabilities package)
+ "Check for known vulnerabilities for PACKAGE."
+ (match (package-vulnerabilities package)
+ (()
+ #t)
+ ((vulnerabilities ...)
+ (emit-warning package
+ (format #f (_ "probably vulnerable to ~a")
+ (string-join (map vulnerability-id vulnerabilities)
+ ", "))))))
+
\f
;;;
;;; Source code formatting.
(name 'synopsis)
(description "Validate package synopses")
(check check-synopsis-style))
+ (lint-checker
+ (name 'cve)
+ (description "Check the Common Vulnerabilities and Exposures\
+ (CVE) database")
+ (check check-vulnerabilities))
(lint-checker
(name 'formatting)
(description "Look for formatting issues in the source")
(check-source pkg))))
"not reachable: 404")))
+(test-assert "cve"
+ (mock ((guix scripts lint) package-vulnerabilities (const '()))
+ (string-null?
+ (with-warnings (check-vulnerabilities (dummy-package "x"))))))
+
+(test-assert "cve: one vulnerability"
+ (mock ((guix scripts lint) package-vulnerabilities
+ (lambda (package)
+ (list (make-struct (@@ (guix cve) <vulnerability>) 0
+ "CVE-2015-1234"
+ (list (cons (package-name package)
+ (package-version package)))))))
+ (string-contains
+ (with-warnings
+ (check-vulnerabilities (dummy-package "pi" (version "3.14"))))
+ "vulnerable to CVE-2015-1234")))
+
(test-assert "formatting: lonely parentheses"
(string-contains
(with-warnings