1eda14cbcSMatt Macy#!/bin/ksh -p 2eda14cbcSMatt Macy# 3eda14cbcSMatt Macy# CDDL HEADER START 4eda14cbcSMatt Macy# 5eda14cbcSMatt Macy# This file and its contents are supplied under the terms of the 6eda14cbcSMatt Macy# Common Development and Distribution License ("CDDL"), version 1.0. 7eda14cbcSMatt Macy# You may only use this file in accordance with the terms of version 8eda14cbcSMatt Macy# 1.0 of the CDDL. 9eda14cbcSMatt Macy# 10eda14cbcSMatt Macy# A full copy of the text of the CDDL should have accompanied this 11eda14cbcSMatt Macy# source. A copy of the CDDL is also available via the Internet at 12eda14cbcSMatt Macy# http://www.illumos.org/license/CDDL. 13eda14cbcSMatt Macy# 14eda14cbcSMatt Macy# CDDL HEADER END 15eda14cbcSMatt Macy# 16eda14cbcSMatt Macy 17eda14cbcSMatt Macy# 18eda14cbcSMatt Macy# Copyright (c) 2018 by Datto Inc. All rights reserved. 19eda14cbcSMatt Macy# 20eda14cbcSMatt Macy 21eda14cbcSMatt Macy. $STF_SUITE/tests/functional/rsend/rsend.kshlib 22eda14cbcSMatt Macy 23eda14cbcSMatt Macy# 24eda14cbcSMatt Macy# DESCRIPTION: 25eda14cbcSMatt Macy# Verify that zfs properly handles encryption properties when receiving 26eda14cbcSMatt Macy# send streams. 27eda14cbcSMatt Macy# 28eda14cbcSMatt Macy# STRATEGY: 29eda14cbcSMatt Macy# 1. Create a few unencrypted and encrypted test datasets with some data 30eda14cbcSMatt Macy# 2. Take snapshots of these datasets in preparation for sending 31eda14cbcSMatt Macy# 3. Verify that 'zfs recv -o keylocation=prompt' fails 32eda14cbcSMatt Macy# 4. Verify that 'zfs recv -x <encryption prop>' fails on a raw send stream 33eda14cbcSMatt Macy# 5. Verify that encryption properties cannot be changed on incrementals 34eda14cbcSMatt Macy# 6. Verify that a simple send can be received as an encryption root 35eda14cbcSMatt Macy# 7. Verify that an unencrypted props send can be received as an 36eda14cbcSMatt Macy# encryption root 37eda14cbcSMatt Macy# 8. Verify that an unencrypted recursive send can be received as an 38eda14cbcSMatt Macy# encryption root 39eda14cbcSMatt Macy# 9. Verify that an unencrypted props send can be received as an 40eda14cbcSMatt Macy# encryption child 41eda14cbcSMatt Macy# 10. Verify that an unencrypted recursive send can be received as an 42eda14cbcSMatt Macy# encryption child 43eda14cbcSMatt Macy# 44eda14cbcSMatt Macy 45eda14cbcSMatt Macyverify_runnable "both" 46eda14cbcSMatt Macy 47eda14cbcSMatt Macyfunction cleanup 48eda14cbcSMatt Macy{ 49eda14cbcSMatt Macy destroy_dataset $TESTPOOL/recv "-r" 50eda14cbcSMatt Macy destroy_dataset $TESTPOOL/crypt "-r" 51eda14cbcSMatt Macy destroy_dataset $TESTPOOL/ds "-r" 52eda14cbcSMatt Macy [[ -f $sendfile ]] && log_must rm $sendfile 53eda14cbcSMatt Macy [[ -f $keyfile ]] && log_must rm $keyfile 54eda14cbcSMatt Macy} 55eda14cbcSMatt Macylog_onexit cleanup 56eda14cbcSMatt Macy 57eda14cbcSMatt Macylog_assert "'zfs recv' must properly handle encryption properties" 58eda14cbcSMatt Macy 59eda14cbcSMatt Macytypeset keyfile=/$TESTPOOL/pkey 60eda14cbcSMatt Macytypeset sendfile=/$TESTPOOL/sendfile 61eda14cbcSMatt Macytypeset snap=$TESTPOOL/ds@snap1 62eda14cbcSMatt Macytypeset snap2=$TESTPOOL/ds@snap2 63eda14cbcSMatt Macytypeset esnap=$TESTPOOL/crypt@snap1 64eda14cbcSMatt Macytypeset esnap2=$TESTPOOL/crypt@snap2 65eda14cbcSMatt Macy 66eda14cbcSMatt Macylog_must eval "echo 'password' > $keyfile" 67eda14cbcSMatt Macy 68eda14cbcSMatt Macylog_must zfs create $TESTPOOL/ds 69eda14cbcSMatt Macylog_must zfs create $TESTPOOL/ds/ds1 70eda14cbcSMatt Macy 71eda14cbcSMatt Macylog_must zfs create -o encryption=on -o keyformat=passphrase \ 72eda14cbcSMatt Macy -o keylocation=file://$keyfile $TESTPOOL/crypt 73eda14cbcSMatt Macylog_must zfs create $TESTPOOL/crypt/ds1 74eda14cbcSMatt Macylog_must zfs create -o keyformat=passphrase -o keylocation=file://$keyfile \ 75eda14cbcSMatt Macy $TESTPOOL/crypt/ds2 76eda14cbcSMatt Macy 77eda14cbcSMatt Macylog_must mkfile 1M /$TESTPOOL/ds/$TESTFILE0 78eda14cbcSMatt Macylog_must cp /$TESTPOOL/ds/$TESTFILE0 /$TESTPOOL/crypt/$TESTFILE0 79eda14cbcSMatt Macytypeset cksum=$(md5digest /$TESTPOOL/ds/$TESTFILE0) 80eda14cbcSMatt Macy 81eda14cbcSMatt Macylog_must zfs snap -r $snap 82eda14cbcSMatt Macylog_must zfs snap -r $snap2 83eda14cbcSMatt Macylog_must zfs snap -r $esnap 84eda14cbcSMatt Macylog_must zfs snap -r $esnap2 85eda14cbcSMatt Macy 86eda14cbcSMatt Macy# Embedded data is incompatible with encrypted datasets, so we cannot 87eda14cbcSMatt Macy# allow embedded streams to be received. 88eda14cbcSMatt Macylog_note "Must not be able to receive an embedded stream as encrypted" 89eda14cbcSMatt Macylog_mustnot eval "zfs send -e $TESTPOOL/crypt/ds1 | zfs recv $TESTPOOL/recv" 90eda14cbcSMatt Macy 91eda14cbcSMatt Macy# We currently don't have an elegant and secure way to pass the passphrase 92eda14cbcSMatt Macy# in via prompt because the send stream itself is using stdin. 93eda14cbcSMatt Macylog_note "Must not be able to use 'keylocation=prompt' on receive" 94eda14cbcSMatt Macylog_must eval "zfs send $snap > $sendfile" 95eda14cbcSMatt Macylog_mustnot eval "zfs recv -o encryption=on -o keyformat=passphrase" \ 96eda14cbcSMatt Macy "$TESTPOOL/recv < $sendfile" 97eda14cbcSMatt Macylog_mustnot eval "zfs recv -o encryption=on -o keyformat=passphrase" \ 98eda14cbcSMatt Macy "-o keylocation=prompt $TESTPOOL/recv < $sendfile" 99eda14cbcSMatt Macy 100eda14cbcSMatt Macy# Raw sends do not have access to the decrypted data so we cannot override 101eda14cbcSMatt Macy# the encryption settings without losing the data. 102eda14cbcSMatt Macylog_note "Must not be able to disable encryption properties on raw send" 103eda14cbcSMatt Macylog_must eval "zfs send -w $esnap > $sendfile" 104eda14cbcSMatt Macylog_mustnot eval "zfs recv -x encryption $TESTPOOL/recv < $sendfile" 105eda14cbcSMatt Macylog_mustnot eval "zfs recv -x keyformat $TESTPOOL/recv < $sendfile" 106eda14cbcSMatt Macylog_mustnot eval "zfs recv -x pbkdf2iters $TESTPOOL/recv < $sendfile" 107eda14cbcSMatt Macy 108eda14cbcSMatt Macy# Encryption properties are set upon creating the dataset. Changing them 109eda14cbcSMatt Macy# afterwards requires using 'zfs change-key' or an update from a raw send. 110eda14cbcSMatt Macylog_note "Must not be able to change encryption properties on incrementals" 111eda14cbcSMatt Macylog_must eval "zfs send $esnap | zfs recv -o encryption=on" \ 112eda14cbcSMatt Macy "-o keyformat=passphrase -o keylocation=file://$keyfile $TESTPOOL/recv" 113eda14cbcSMatt Macylog_mustnot eval "zfs send -i $esnap $esnap2 |" \ 114eda14cbcSMatt Macy "zfs recv -o encryption=aes-128-ccm $TESTPOOL/recv" 115eda14cbcSMatt Macylog_mustnot eval "zfs send -i $esnap $esnap2 |" \ 116eda14cbcSMatt Macy "zfs recv -o keyformat=hex $TESTPOOL/recv" 117eda14cbcSMatt Macylog_mustnot eval "zfs send -i $esnap $esnap2 |" \ 118eda14cbcSMatt Macy "zfs recv -o pbkdf2iters=100k $TESTPOOL/recv" 119eda14cbcSMatt Macylog_must zfs destroy -r $TESTPOOL/recv 120eda14cbcSMatt Macy 121eda14cbcSMatt Macy# Test that we can receive a simple stream as an encryption root. 122eda14cbcSMatt Macylog_note "Must be able to receive stream as encryption root" 123eda14cbcSMatt Macyds=$TESTPOOL/recv 124eda14cbcSMatt Macylog_must eval "zfs send $snap > $sendfile" 125eda14cbcSMatt Macylog_must eval "zfs recv -o encryption=on -o keyformat=passphrase" \ 126eda14cbcSMatt Macy "-o keylocation=file://$keyfile $ds < $sendfile" 127eda14cbcSMatt Macylog_must test "$(get_prop 'encryption' $ds)" == "aes-256-gcm" 128eda14cbcSMatt Macylog_must test "$(get_prop 'encryptionroot' $ds)" == "$ds" 129eda14cbcSMatt Macylog_must test "$(get_prop 'keyformat' $ds)" == "passphrase" 130eda14cbcSMatt Macylog_must test "$(get_prop 'keylocation' $ds)" == "file://$keyfile" 131eda14cbcSMatt Macylog_must test "$(get_prop 'mounted' $ds)" == "yes" 132eda14cbcSMatt Macyrecv_cksum=$(md5digest /$ds/$TESTFILE0) 133eda14cbcSMatt Macylog_must test "$recv_cksum" == "$cksum" 134eda14cbcSMatt Macylog_must zfs destroy -r $ds 135eda14cbcSMatt Macy 136*c7046f76SMartin Matuska# Test that we can override sharesmb property for encrypted raw stream. 137*c7046f76SMartin Matuskalog_note "Must be able to override sharesmb property for encrypted raw stream" 138*c7046f76SMartin Matuskads=$TESTPOOL/recv 139*c7046f76SMartin Matuskalog_must eval "zfs send -w $esnap > $sendfile" 140*c7046f76SMartin Matuskalog_must eval "zfs recv -o sharesmb=on $ds < $sendfile" 141*c7046f76SMartin Matuskalog_must test "$(get_prop 'sharesmb' $ds)" == "on" 142*c7046f76SMartin Matuskalog_must zfs destroy -r $ds 143*c7046f76SMartin Matuska 144eda14cbcSMatt Macy# Test that we can override encryption properties on a properties stream 145eda14cbcSMatt Macy# of an unencrypted dataset, turning it into an encryption root. 146eda14cbcSMatt Macylog_note "Must be able to receive stream with props as encryption root" 147eda14cbcSMatt Macyds=$TESTPOOL/recv 148eda14cbcSMatt Macylog_must eval "zfs send -p $snap > $sendfile" 149eda14cbcSMatt Macylog_must eval "zfs recv -o encryption=on -o keyformat=passphrase" \ 150eda14cbcSMatt Macy "-o keylocation=file://$keyfile $ds < $sendfile" 151eda14cbcSMatt Macylog_must test "$(get_prop 'encryption' $ds)" == "aes-256-gcm" 152eda14cbcSMatt Macylog_must test "$(get_prop 'encryptionroot' $ds)" == "$ds" 153eda14cbcSMatt Macylog_must test "$(get_prop 'keyformat' $ds)" == "passphrase" 154eda14cbcSMatt Macylog_must test "$(get_prop 'keylocation' $ds)" == "file://$keyfile" 155eda14cbcSMatt Macylog_must test "$(get_prop 'mounted' $ds)" == "yes" 156eda14cbcSMatt Macyrecv_cksum=$(md5digest /$ds/$TESTFILE0) 157eda14cbcSMatt Macylog_must test "$recv_cksum" == "$cksum" 158eda14cbcSMatt Macylog_must zfs destroy -r $ds 159eda14cbcSMatt Macy 160eda14cbcSMatt Macy# Test that we can override encryption properties on a recursive stream 161eda14cbcSMatt Macy# of an unencrypted dataset, turning it into an encryption root. The root 162eda14cbcSMatt Macy# dataset of the stream should become an encryption root with all children 163eda14cbcSMatt Macy# inheriting from it. 164eda14cbcSMatt Macylog_note "Must be able to receive recursive stream as encryption root" 165eda14cbcSMatt Macyds=$TESTPOOL/recv 166eda14cbcSMatt Macylog_must eval "zfs send -R $snap > $sendfile" 167eda14cbcSMatt Macylog_must eval "zfs recv -o encryption=on -o keyformat=passphrase" \ 168eda14cbcSMatt Macy "-o keylocation=file://$keyfile $ds < $sendfile" 169eda14cbcSMatt Macylog_must test "$(get_prop 'encryption' $ds)" == "aes-256-gcm" 170eda14cbcSMatt Macylog_must test "$(get_prop 'encryptionroot' $ds)" == "$ds" 171eda14cbcSMatt Macylog_must test "$(get_prop 'keyformat' $ds)" == "passphrase" 172eda14cbcSMatt Macylog_must test "$(get_prop 'keylocation' $ds)" == "file://$keyfile" 173eda14cbcSMatt Macylog_must test "$(get_prop 'mounted' $ds)" == "yes" 174eda14cbcSMatt Macyrecv_cksum=$(md5digest /$ds/$TESTFILE0) 175eda14cbcSMatt Macylog_must test "$recv_cksum" == "$cksum" 176eda14cbcSMatt Macylog_must zfs destroy -r $ds 177eda14cbcSMatt Macy 178eda14cbcSMatt Macy# Test that we can override an unencrypted properties stream's encryption 179eda14cbcSMatt Macy# settings, receiving it as an encrypted child. 180eda14cbcSMatt Macylog_note "Must be able to receive stream with props to encrypted child" 181eda14cbcSMatt Macyds=$TESTPOOL/crypt/recv 182eda14cbcSMatt Macylog_must eval "zfs send -p $snap > $sendfile" 183eda14cbcSMatt Macylog_must eval "zfs recv -x encryption $ds < $sendfile" 184eda14cbcSMatt Macylog_must test "$(get_prop 'encryptionroot' $ds)" == "$TESTPOOL/crypt" 185eda14cbcSMatt Macylog_must test "$(get_prop 'encryption' $ds)" == "aes-256-gcm" 186eda14cbcSMatt Macylog_must test "$(get_prop 'keyformat' $ds)" == "passphrase" 187eda14cbcSMatt Macylog_must test "$(get_prop 'mounted' $ds)" == "yes" 188eda14cbcSMatt Macyrecv_cksum=$(md5digest /$ds/$TESTFILE0) 189eda14cbcSMatt Macylog_must test "$recv_cksum" == "$cksum" 190eda14cbcSMatt Macylog_must zfs destroy -r $ds 191eda14cbcSMatt Macy 192eda14cbcSMatt Macy# Test that we can override an unencrypted recursive stream's encryption 193eda14cbcSMatt Macy# settings, receiving all datasets as encrypted children. 194eda14cbcSMatt Macylog_note "Must be able to receive recursive stream to encrypted child" 195eda14cbcSMatt Macyds=$TESTPOOL/crypt/recv 196eda14cbcSMatt Macylog_must eval "zfs send -R $snap > $sendfile" 197eda14cbcSMatt Macylog_must eval "zfs recv -x encryption $ds < $sendfile" 198eda14cbcSMatt Macylog_must test "$(get_prop 'encryptionroot' $ds)" == "$TESTPOOL/crypt" 199eda14cbcSMatt Macylog_must test "$(get_prop 'encryption' $ds)" == "aes-256-gcm" 200eda14cbcSMatt Macylog_must test "$(get_prop 'keyformat' $ds)" == "passphrase" 201eda14cbcSMatt Macylog_must test "$(get_prop 'mounted' $ds)" == "yes" 202eda14cbcSMatt Macyrecv_cksum=$(md5digest /$ds/$TESTFILE0) 203eda14cbcSMatt Macylog_must test "$recv_cksum" == "$cksum" 204eda14cbcSMatt Macylog_must zfs destroy -r $ds 205eda14cbcSMatt Macy 206eda14cbcSMatt Macy# Test that we can override an unencrypted, incremental, recursive stream's 207eda14cbcSMatt Macy# encryption settings, receiving all datasets as encrypted children. 208eda14cbcSMatt Macylog_note "Must be able to receive recursive stream to encrypted child" 209eda14cbcSMatt Macyds=$TESTPOOL/crypt/recv 210eda14cbcSMatt Macylog_must eval "zfs send -R $snap2 > $sendfile" 211eda14cbcSMatt Macylog_must eval "zfs recv -x encryption $ds < $sendfile" 212eda14cbcSMatt Macylog_must test "$(get_prop 'encryptionroot' $ds)" == "$TESTPOOL/crypt" 213eda14cbcSMatt Macylog_must test "$(get_prop 'encryption' $ds)" == "aes-256-gcm" 214eda14cbcSMatt Macylog_must test "$(get_prop 'keyformat' $ds)" == "passphrase" 215eda14cbcSMatt Macylog_must test "$(get_prop 'mounted' $ds)" == "yes" 216eda14cbcSMatt Macyrecv_cksum=$(md5digest /$ds/$TESTFILE0) 217eda14cbcSMatt Macylog_must test "$recv_cksum" == "$cksum" 218eda14cbcSMatt Macylog_must zfs destroy -r $ds 219eda14cbcSMatt Macy 220eda14cbcSMatt Macy# Check that we haven't printed the key to the zpool history log 221eda14cbcSMatt Macylog_mustnot eval "zpool history -i | grep -q 'wkeydata'" 222eda14cbcSMatt Macy 223eda14cbcSMatt Macylog_pass "'zfs recv' properly handles encryption properties" 224