Module Name:    src
Committed By:   riastradh
Date:           Mon Aug 28 22:25:50 UTC 2023

Modified Files:
        src: UPDATING
        src/tests/usr.sbin/certctl: t_certctl.sh
        src/usr.sbin/certctl: certctl.sh

Log Message:
certctl(8): Avoid clobbering prepopulated /etc/openssl/certs.

Also avoid clobbering some other edge cases like symlinks or
non-directories there.

This way, we have the following transitions on system updates:

- If /etc/openssl/certs is empty (as in default NetBSD<10 installs):
  quietly populated on rehash.

- If /etc/openssl/certs is nonempty (you've added things to it,
  e.g. by hand or with mozilla-rootcerts) and has never been managed
  by certctl(8): left alone on rehash, with an error message to
  explain what you need to do.

- If /etc/openssl/certs has been managed by certctl(8): quietly
  updated on rehash.

Note: This means current installations made since certctl(8) was
added will be treated like /etc/openssl/certs is nonempty and has
never been managed by certctl(8).  To work around this, you can just
delete /etc/openssl/certs and rerun `certctl rehash'.


To generate a diff of this commit:
cvs rdiff -u -r1.342 -r1.343 src/UPDATING
cvs rdiff -u -r1.4 -r1.5 src/tests/usr.sbin/certctl/t_certctl.sh
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/certctl/certctl.sh

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/UPDATING
diff -u src/UPDATING:1.342 src/UPDATING:1.343
--- src/UPDATING:1.342	Wed Jul 19 17:49:40 2023
+++ src/UPDATING	Mon Aug 28 22:25:49 2023
@@ -1,4 +1,4 @@
-$NetBSD: UPDATING,v 1.342 2023/07/19 17:49:40 martin Exp $
+$NetBSD: UPDATING,v 1.343 2023/08/28 22:25:49 riastradh Exp $
 
 This file (UPDATING) is intended to be a brief reference to recent
 changes that might cause problems in the build process, and a guide for
@@ -19,6 +19,21 @@ See also: BUILDING, build.sh, Makefile.
 Recent changes:
 ^^^^^^^^^^^^^^^
 
+20230828:
+	If:
+        - you updated to current and ran postinstall between 20230826
+	  and 20230828 inclusive, and
+        - you are not using anything outside the base system to
+	  populate /etc/openssl/certs (e.g., manually adding
+	  certificates or using ca-certificates or mozilla-rootcerts or
+	  mozilla-rootcerts-openssl from pkgsrc),
+	delete /etc/openssl/certs and rerun postinstall or just
+	`certctl rehash'.
+
+	Otherwise, certctl(8) will think someone else has left
+	/etc/openssl/certs in the way and will avoid clobbering it on
+	upgrade from older NetBSD.
+
 20230718:
 	build.sh will use mk.conf in the same directory as build.sh instead
 	of /etc/mk.conf, unless MAKECONF is already defined in the environment.

Index: src/tests/usr.sbin/certctl/t_certctl.sh
diff -u src/tests/usr.sbin/certctl/t_certctl.sh:1.4 src/tests/usr.sbin/certctl/t_certctl.sh:1.5
--- src/tests/usr.sbin/certctl/t_certctl.sh:1.4	Mon Aug 28 22:25:41 2023
+++ src/tests/usr.sbin/certctl/t_certctl.sh	Mon Aug 28 22:25:49 2023
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-#	$NetBSD: t_certctl.sh,v 1.4 2023/08/28 22:25:41 riastradh Exp $
+#	$NetBSD: t_certctl.sh,v 1.5 2023/08/28 22:25:49 riastradh Exp $
 #
 # Copyright (c) 2023 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -358,7 +358,6 @@ symlinkcertsdir_body()
 	mkdir empty
 	ln -sfn empty certs
 
-	atf_expect_fail "certctl clobbers symlink at /etc/openssl/certs"
 	atf_check -s not-exit:0 -e match:symlink $CERTCTL -n rehash
 	atf_check -s not-exit:0 -e match:symlink $CERTCTL rehash
 	atf_check -s exit:0 rmdir empty
@@ -375,7 +374,6 @@ regularfilecertsdir_body()
 	rmdir certs
 	echo 'hello world' >certs
 
-	atf_expect_fail "certctl clobbers file at /etc/openssl/certs"
 	atf_check -s not-exit:0 -e match:directory $CERTCTL -n rehash
 	atf_check -s not-exit:0 -e match:directory $CERTCTL rehash
 	atf_check -s exit:0 rm certs
@@ -393,7 +391,6 @@ prepopulatedcerts_body()
 	setupconf certs1
 	ln -sfn "$(atf_get_srcdir)/certs2"/*.pem certs/
 
-	atf_expect_fail "certctl clobbers prepopulated /etc/openssl/certs"
 	atf_check -s not-exit:0 -e match:manual $CERTCTL -n rehash
 	atf_check -s not-exit:0 -e match:manual $CERTCTL rehash
 	for cert in "$(atf_get_srcdir)/certs2"/*.pem; do

Index: src/usr.sbin/certctl/certctl.sh
diff -u src/usr.sbin/certctl/certctl.sh:1.2 src/usr.sbin/certctl/certctl.sh:1.3
--- src/usr.sbin/certctl/certctl.sh:1.2	Mon Aug 28 22:25:32 2023
+++ src/usr.sbin/certctl/certctl.sh	Mon Aug 28 22:25:50 2023
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-#	$NetBSD: certctl.sh,v 1.2 2023/08/28 22:25:32 riastradh Exp $
+#	$NetBSD: certctl.sh,v 1.3 2023/08/28 22:25:50 riastradh Exp $
 #
 # Copyright (c) 2023 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -427,9 +427,40 @@ rehash()
 		return
 	fi
 
-	# Delete the active certificates symlink cache.
-	run rm -rf "$certsdir"
+	# Delete the active certificates symlink cache, if either it is
+	# empty or nonexistent, or it is tagged for use by certctl.
+	if [ -f "$certsdir/.certctl" ]; then
+		# Directory exists and is managed by certctl(8).
+		# Safe to delete it and everything in it.
+		run rm -rf "$certsdir"
+	elif [ -h "$certsdir" ]; then
+		# Paranoia: refuse to chase a symlink.  (Caveat: this
+		# is not secure against an adversary who can recreate
+		# the symlink at any time.  Just a helpful check for
+		# mistakes.)
+		error "certificates directory is a symlink"
+		return 1
+	elif [ ! -e "$certsdir" ]; then
+		# Directory doesn't exist at all.  Nothing to do!
+	elif [ ! -d "$certsdir" ]; then
+		error "certificates directory is not a directory"
+		return 1
+	elif ! find "$certsdir" -maxdepth 0 -type d -empty -exit 1; then
+		# certsdir exists, is a directory, and is empty.  Safe
+		# to delete it with rmdir and take it over.
+		run rmdir "$certsdir"
+	else
+		error "existing certificates; set manual or move them"
+		return 1
+	fi
 	run mkdir "$certsdir"
+	if $vflag; then
+		printf '# initialize %s\n' "$certsdir"
+	fi
+	if ! $nflag; then
+		printf 'This directory is managed by certctl(8).\n' \
+		    >$certsdir/.certctl
+	fi
 
 	# Create a temporary file for the single-file bundle.  This
 	# will be automatically deleted on normal exit or

Reply via email to