From patchwork Tue Feb 13 19:40:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1898390 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::133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) (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 4TZBWJ1JGHz23j4 for ; Wed, 14 Feb 2024 06:40:28 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id BB25B416A4; Tue, 13 Feb 2024 19:40:25 +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 d8FdFjFLgKAD; Tue, 13 Feb 2024 19:40:23 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 079FA415D1 Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp2.osuosl.org (Postfix) with ESMTPS id 079FA415D1; Tue, 13 Feb 2024 19:40:22 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id C0AB2C0DCE; Tue, 13 Feb 2024 19:40:22 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3601BC0DCF for ; Tue, 13 Feb 2024 19:40:21 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 271F860DCB for ; Tue, 13 Feb 2024 19:40:21 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id U9ZdBfpxSvFU for ; Tue, 13 Feb 2024 19:40:20 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=217.70.183.200; helo=relay7-d.mail.gandi.net; envelope-from=i.maximets@ovn.org; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp3.osuosl.org D9A0960E17 Authentication-Results: smtp3.osuosl.org; dmarc=none (p=none dis=none) header.from=ovn.org DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org D9A0960E17 Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by smtp3.osuosl.org (Postfix) with ESMTPS id D9A0960E17 for ; Tue, 13 Feb 2024 19:40:19 +0000 (UTC) Received: by mail.gandi.net (Postfix) with ESMTPSA id C676520003; Tue, 13 Feb 2024 19:40:17 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Tue, 13 Feb 2024 20:40:16 +0100 Message-ID: <20240213194050.1590143-3-i.maximets@ovn.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240213194050.1590143-1-i.maximets@ovn.org> References: <20240213194050.1590143-1-i.maximets@ovn.org> MIME-Version: 1.0 X-GND-Sasl: i.maximets@ovn.org Cc: Ilya Maximets Subject: [ovs-dev] [PATCH 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. Signed-off-by: Ilya Maximets Acked-by: Simon Horman --- 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 e0ba910f9..285018e41 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 }