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