From patchwork Sun Jun 7 21:19:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 22601 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 666FC27BBE3; Sun, 7 Jun 2020 22:20:09 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTP id D00BC27BBE1 for ; Sun, 7 Jun 2020 22:20:08 +0100 (BST) Received: from localhost ([::1]:55066 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ji2i8-0003QA-E0 for patchwork@mira.cbaines.net; Sun, 07 Jun 2020 17:20:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43516) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ji2i2-0003Pn-8I for guix-patches@gnu.org; Sun, 07 Jun 2020 17:20:02 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:43574) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1ji2i1-0006t3-Tv for guix-patches@gnu.org; Sun, 07 Jun 2020 17:20:01 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1ji2i1-0005Zi-Pk for guix-patches@gnu.org; Sun, 07 Jun 2020 17:20:01 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#41653] [PATCH 0/4] Add (guix git-authenticate) with tests Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 07 Jun 2020 21:20:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 41653 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch fixed To: 41653@debbugs.gnu.org Received: via spool by 41653-submit@debbugs.gnu.org id=B41653.159156477721393 (code B ref 41653); Sun, 07 Jun 2020 21:20:01 +0000 Received: (at 41653) by debbugs.gnu.org; 7 Jun 2020 21:19:37 +0000 Received: from localhost ([127.0.0.1]:55120 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ji2hd-0005Yy-C8 for submit@debbugs.gnu.org; Sun, 07 Jun 2020 17:19:37 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35344) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ji2hc-0005Ym-9P for 41653@debbugs.gnu.org; Sun, 07 Jun 2020 17:19:36 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:58864) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ji2hX-0006lN-2v for 41653@debbugs.gnu.org; Sun, 07 Jun 2020 17:19:31 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=40392 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1ji2hW-0007IX-16 for 41653@debbugs.gnu.org; Sun, 07 Jun 2020 17:19:30 -0400 From: Ludovic =?utf-8?q?Court=C3=A8s?= References: <20200601212957.3056-1-ludo@gnu.org> Date: Sun, 07 Jun 2020 23:19:25 +0200 In-Reply-To: <20200601212957.3056-1-ludo@gnu.org> ("Ludovic \=\?utf-8\?Q\?Cour\?\= \=\?utf-8\?Q\?t\=C3\=A8s\=22's\?\= message of "Mon, 1 Jun 2020 23:29:57 +0200") Message-ID: <87img2r2ua.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches Ludovic Courtès skribis: > Add (guix git-authenticate). > git-authenticate: Don't hard-code "origin/" for keyring reference. > git-authenticate: Raise proper SRFI-35 conditions. > git-authenticate: Add tests. As a followup, I pushed this patch: https://git.savannah.gnu.org/cgit/guix.git/commit/?id=e78275608065ef073775fabb9f1a757da65851f2 Its effect is to prevent removal of ‘.guix-authorizations’ since doing that would trivially force the authentication code to fall back to ‘default-authorizations’. Ludo’. commit e78275608065ef073775fabb9f1a757da65851f2 Author: Ludovic Courtès Date: Sun Jun 7 23:06:41 2020 +0200 git-authenticate: Prevent removal of '.guix-authorizations'. * guix/git-authenticate.scm (commit-authorized-keys) [parents-have-authorizations-file?, assert-parents-lack-authorizations]: New procedures. Use the latter before returning DEFAULT-AUTHORIZATIONS. * guix/git.scm (false-if-git-not-found): Export. * guix/tests/git.scm (populate-git-repository): Add 'remove' clause. * tests/git-authenticate.scm ("signed commits, .guix-authorizations removed"): New test. diff --git a/guix/git-authenticate.scm b/guix/git-authenticate.scm index b73f957105..00d22ef479 100644 --- a/guix/git-authenticate.scm +++ b/guix/git-authenticate.scm @@ -19,6 +19,7 @@ (define-module (guix git-authenticate) #:use-module (git) #:use-module (guix base16) + #:use-module ((guix git) #:select (false-if-git-not-found)) #:use-module (guix i18n) #:use-module (guix openpgp) #:use-module ((guix utils) @@ -145,6 +146,27 @@ return a list of authorized fingerprints." "Return the list of OpenPGP fingerprints authorized to sign COMMIT, based on authorizations listed in its parent commits. If one of the parent commits does not specify anything, fall back to DEFAULT-AUTHORIZATIONS." + (define (parents-have-authorizations-file? commit) + ;; Return true if at least one of the parents of COMMIT has the + ;; '.guix-authorizations' file. + (find (lambda (commit) + (false-if-git-not-found + (tree-entry-bypath (commit-tree commit) + ".guix-authorizations"))) + (commit-parents commit))) + + (define (assert-parents-lack-authorizations commit) + ;; If COMMIT removes the '.guix-authorizations' file found in one of its + ;; parents, raise an error. + (when (parents-have-authorizations-file? commit) + (raise (condition + (&unauthorized-commit-error (commit (commit-id commit)) + (signing-key #f)) + (&message + (message (format #f (G_ "commit ~a attempts \ +to remove '.guix-authorizations' file") + (oid->string (commit-id commit))))))))) + (define (commit-authorizations commit) (catch 'git-error (lambda () @@ -155,7 +177,11 @@ does not specify anything, fall back to DEFAULT-AUTHORIZATIONS." (open-bytevector-input-port (blob-content blob))))) (lambda (key error) (if (= (git-error-code error) GIT_ENOTFOUND) - default-authorizations + (begin + ;; Prevent removal of '.guix-authorizations' since it would make + ;; it trivial to force a fallback to DEFAULT-AUTHORIZATIONS. + (assert-parents-lack-authorizations commit) + default-authorizations) (throw key error))))) (apply lset-intersection bytevector=? diff --git a/guix/git.scm b/guix/git.scm index 1c45afa050..1671f57d9f 100644 --- a/guix/git.scm +++ b/guix/git.scm @@ -39,6 +39,7 @@ honor-system-x509-certificates! with-repository + false-if-git-not-found update-cached-checkout url+commit->name latest-repository-commit diff --git a/guix/tests/git.scm b/guix/tests/git.scm index 5d7056bb53..b8e5f7e643 100644 --- a/guix/tests/git.scm +++ b/guix/tests/git.scm @@ -76,6 +76,9 @@ Return DIRECTORY on success." port))) (git "add" file) (loop rest))) + ((('remove file) rest ...) + (git "rm" "-f" file) + (loop rest)) ((('commit text) rest ...) (git "commit" "-m" text) (loop rest)) diff --git a/tests/git-authenticate.scm b/tests/git-authenticate.scm index 5937c37ee6..84689d628e 100644 --- a/tests/git-authenticate.scm +++ b/tests/git-authenticate.scm @@ -282,5 +282,46 @@ merge master3) #:keyring-reference "master")))))) +(unless (gpg+git-available?) (test-skip 1)) +(test-assert "signed commits, .guix-authorizations removed" + (with-fresh-gnupg-setup (list %ed25519-public-key-file + %ed25519-secret-key-file) + (with-temporary-git-repository directory + `((add "signer.key" ,(call-with-input-file %ed25519-public-key-file + get-string-all)) + (add ".guix-authorizations" + ,(object->string + `(authorizations (version 0) + ((,(key-fingerprint + %ed25519-public-key-file) + (name "Charlie")))))) + (commit "zeroth commit") + (add "a.txt" "A") + (commit "first commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (remove ".guix-authorizations") + (commit "second commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (add "b.txt" "B") + (commit "third commit" + (signer ,(key-fingerprint %ed25519-public-key-file)))) + (with-repository directory repository + (let ((commit1 (find-commit repository "first")) + (commit2 (find-commit repository "second")) + (commit3 (find-commit repository "third"))) + ;; COMMIT1 and COMMIT2 are fine. + (and (authenticate-commits repository (list commit1 commit2) + #:keyring-reference "master") + + ;; COMMIT3 is rejected because COMMIT2 removes + ;; '.guix-authorizations'. + (guard (c ((unauthorized-commit-error? c) + (oid=? (git-authentication-error-commit c) + (commit-id commit2)))) + (authenticate-commits repository + (list commit1 commit2 commit3) + #:keyring-reference "master") + 'failed))))))) + (test-end "git-authenticate")