From patchwork Fri Mar 1 21:10:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1906903 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Tmgj84QM5z1yX7 for ; Sat, 2 Mar 2024 08:10:20 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id A80CD83BB9; Fri, 1 Mar 2024 21:10:18 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id o0J8ETj-D6-m; Fri, 1 Mar 2024 21:10:17 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 5ACFB83BA1 Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 5ACFB83BA1; Fri, 1 Mar 2024 21:10:17 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 19FD9C0DD4; Fri, 1 Mar 2024 21:10:17 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7501CC0037 for ; Fri, 1 Mar 2024 21:10:16 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 50B8341CBC for ; Fri, 1 Mar 2024 21:10:16 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cpticSV5JGIU for ; Fri, 1 Mar 2024 21:10:15 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=217.70.183.198; helo=relay6-d.mail.gandi.net; envelope-from=i.maximets@ovn.org; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org EFF0641CC2 Authentication-Results: smtp2.osuosl.org; dmarc=none (p=none dis=none) header.from=ovn.org DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org EFF0641CC2 Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by smtp2.osuosl.org (Postfix) with ESMTPS id EFF0641CC2 for ; Fri, 1 Mar 2024 21:10:14 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id 1D268C0003; Fri, 1 Mar 2024 21:10:12 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Fri, 1 Mar 2024 22:10:38 +0100 Message-ID: <20240301211045.3714106-3-i.maximets@ovn.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301211045.3714106-1-i.maximets@ovn.org> References: <20240301211045.3714106-1-i.maximets@ovn.org> MIME-Version: 1.0 X-GND-Sasl: i.maximets@ovn.org Cc: Ilya Maximets Subject: [ovs-dev] [PATCH v2 2/4] ovs-pki: Fix file permissions on Windows. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" There is no chmod or 'mkdir -m' support on Windows, so setting file permissions for keys and certificates doesn't actually work. Implementing them using icacls utility instead. ovs-pki script currently only uses 0700 and 0750 modes, so only those (and 0600) are implemented. NTFS ACLs on Windows are fairly different and more complex in comparison with Unix file permissions, so it's hard to implement these functions in a generic way. The script will fail if it will encounter an unknown mode. 0700 is implemented as a F (full access) for 'Creator Owner' with no other permissions. 0750 has an additional RX (read+execute) for the 'Creator Group'. 0600 is implemented the same as 0700, since it doesn't matter for this use case to have or not to have an executable or traversal permissions managed separately from everything else and it would be a little overly verbose to give all the permissions except for X. Inheritance rules are set to (OI)(CI), so the folder itself, subfolders and files in a folder inherit those ACEs. 'umask' also doesn't work on Windows. Instead, moving the private key output files to a temporary folder that has restricted access already configured. The file will inherit these restricted ACEs. It should not be necessary to set explicit permissions for these files since moving them within the same volume should preserve ACEs. However, it might be safer to chmod them directly as well, just in case. Windows administrators will still have to be careful with private keys, because file copies do not preserve permissions and moves to different volumes do not preserve them as well. 'robocopy' with flags to copy security should be used in these cases. We may want to re-implement 'mv' with 'robocopy' if that becomes a problem in the future. There is one more place where umask is used in the script for creation of a self-signed certificate, but it is not actually needed there since the resulted certificate doen't need to be private, so not changing this part for now. Tested with running an empty 'make check' in AppVeyor and examining permissions for files in tests/pki: Files | Linux | Windows ---------------------+------------+-------------------------------------- controllerca | drwxr-xr-x | NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F) switchca | | BUILTIN\Administrators:(I)(OI)(CI)(F) *ca\certs | | BUILTIN\Users:(I)(OI)(CI)(RX) *ca\crl | | BUILTIN\Users:(I)(CI)(AD) *ca\newcerts | | BUILTIN\Users:(I)(CI)(WD) | | APPVEYOR-VM\appveyor:(I)(F) | | CREATOR OWNER:(I)(OI)(CI)(IO)(F) ---------------------+------------+-------------------------------------- stamp | -rw-r--r-- | NT AUTHORITY\SYSTEM:(I)(F) test-cert.pem | | BUILTIN\Administrators:(I)(F) test-req.pem | | BUILTIN\Users:(I)(RX) test2-cert.pem | | APPVEYOR-VM\appveyor:(I)(F) test2-req.pem | | *ca\ca.cnf | | *ca\cacert.pem | | *ca\careq.pem | | *ca\crlnumber | | *ca\index.txt* | | *ca\serial* | | *ca\newcerts\*.pem | | ---------------------+------------+-------------------------------------- controllerca\private | drwx------ | APPVEYOR-VM\appveyor:(F) switchca\private | | CREATOR OWNER:(OI)(CI)(IO)(F) ---------------------+------------+-------------------------------------- test-privkey.pem | -rw------- | APPVEYOR-VM\appveyor:(F) test2-privkey.pem | | *ca\private\cakey.pem| | We can see that private folders and keys have only a full access from their owners. Other files and folders have some extra inherited ACEs from a containing folder. Acked-by: Simon Horman Signed-off-by: Ilya Maximets --- utilities/ovs-pki.in | 87 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/utilities/ovs-pki.in b/utilities/ovs-pki.in index b0c538903..3d2ef911c 100755 --- a/utilities/ovs-pki.in +++ b/utilities/ovs-pki.in @@ -57,6 +57,77 @@ FreeBSD|NetBSD|Darwin) ;; esac +case $(uname -s) in +MINGW*|MSYS*) + chmod() + { + local PERM=$1 + local FILE=$2 + local INH= + + if test -d "${FILE}"; then + # Inheritance rules for folders: apply to a folder itself, + # subfolders and files within. + INH='(OI)(CI)' + fi + + case "${PERM}" in + *700 | *600) + # Reset all own and inherited ACEs and grant full access to the + # "Creator Owner". We're giving full access even for 0600, + # because it doesn't matter for a use case of ovs-pki. + icacls "${FILE}" /inheritance:r /grant:r "*S-1-3-0:${INH}F" + ;; + *750) + # Reset all own and inherited ACEs, grant full access to the + # "Creator Owner" and a read+execute access to the "Creator Group". + icacls "${FILE}" /inheritance:r /grant:r \ + "*S-1-3-0:${INH}F" "*S-1-3-1:${INH}RX" + ;; + *) + echo >&2 "Unable to set ${PERM} mode for ${FILE}." + exit 1 + ;; + esac + } + + mkdir() + { + ARG_P= + PERM= + for arg; do + shift + case ${arg} in + -m?*) + PERM=${arg#??} + continue + ;; + -m) + PERM=$1 + shift + continue + ;; + -p) + ARG_P=-p + continue + ;; + *) + set -- "$@" "${arg}" + ;; + esac + done + + command mkdir ${ARG_P} $@ + if [ ${PERM} ]; then + for dir; do + shift + chmod ${PERM} ${dir} + done + fi + } + ;; +esac + for option; do # This option-parsing mechanism borrowed from a Autoconf-generated # configure script under the following license: @@ -466,14 +537,24 @@ CN = $cn [ v3_req ] subjectAltName = DNS:$cn EOF + # It is important to create private keys in $TMP because umask doesn't + # work on Windows and permissions there are inherited from the folder. + # umask itself is still needed though to ensure correct permissions + # on non-Windows platforms. if test $keytype = rsa; then - (umask 077 && openssl genrsa -out "$1-privkey.pem" $bits) 1>&3 2>&3 \ - || exit $? + (umask 077 && openssl genrsa -out "$TMP/privkey.pem" $bits) \ + 1>&3 2>&3 || exit $? else must_exist "$dsaparam" - (umask 077 && openssl gendsa -out "$1-privkey.pem" "$dsaparam") \ + (umask 077 && openssl gendsa -out "$TMP/privkey.pem" "$dsaparam") \ 1>&3 2>&3 || exit $? fi + # Windows: applying permissions (ACEs) to the file itself, just in case. + # 'mv' should technically preserve all the inherited ACEs from a TMP + # folder, but it's better to not rely on that. + chmod 0600 "$TMP/privkey.pem" + mv "$TMP/privkey.pem" "$1-privkey.pem" + openssl req -config "$TMP/req.cnf" -new -text \ -key "$1-privkey.pem" -out "$1-req.pem" 1>&3 2>&3 }