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