From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id WvU7Owpa3V6/BAAA0tVLHw (envelope-from ) for ; Sun, 07 Jun 2020 21:20:10 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0 with LMTPS id GM2iNgpa3V6tWQAA1q6Kng (envelope-from ) for ; Sun, 07 Jun 2020 21:20:10 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 67D7E94051C for ; Sun, 7 Jun 2020 21:20:10 +0000 (UTC) Received: from localhost ([::1]:55066 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ji2i9-0003QA-Cu for larch@yhetil.org; Sun, 07 Jun 2020 17:20:09 -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 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: -1.4 (-) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-Spam-Score: -2.4 (--) X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Spam-Score: -1.01 X-TUID: qpyyXj8Q3GeE --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Ludovic Court=C3=A8s 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=3De78275608065ef073= 775fabb9f1a757da65851f2 Its effect is to prevent removal of =E2=80=98.guix-authorizations=E2=80=99 = since doing that would trivially force the authentication code to fall back to =E2=80=98default-authorizations=E2=80=99. Ludo=E2=80=99. --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable commit e78275608065ef073775fabb9f1a757da65851f2 Author: Ludovic Court=C3=A8s Date: Sun Jun 7 23:06:41 2020 +0200 git-authenticate: Prevent removal of '.guix-authorizations'. =20=20=20=20 * 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 rem= oved"): 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, base= d 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 i= ts + ;; 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-AUTHOR= IZATIONS." (open-bytevector-input-port (blob-content blob))))) (lambda (key error) (if (=3D (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))))) =20 (apply lset-intersection bytevector=3D? 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! =20 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")))))) =20 +(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=3D? (git-authentication-error-commit c) + (commit-id commit2)))) + (authenticate-commits repository + (list commit1 commit2 commit3) + #:keyring-reference "master") + 'failed))))))) + (test-end "git-authenticate") =20 --=-=-=--