Skip to content

Commit c727570

Browse files
MB-68227: Fix /forceEncryptionAtRest endpoint...
... when called while encryption is disabled This endpoint normally is supposed to just set force_encryption_date in config, but this value doesn't matter when encryption is disabled. Forcing decryption when encryption is off basically means getting rid of all DEKs, which is exactly what dek_drop_datetime is for. Hence the fix: if encryption is disabled, just set dek_drop_datetime to the same value as force_encryption_date. Change-Id: I1369f874ba71df4616da64002b83faebc6513097 Reviewed-on: https://review.couchbase.org/c/ns_server/+/232739 Well-Formed: Build Bot <[email protected]> Tested-by: Build Bot <[email protected]> Reviewed-by: Navdeep S Boparai <[email protected]> Tested-by: Timofey Barmin <[email protected]>
1 parent 708c0d9 commit c727570

File tree

2 files changed

+74
-28
lines changed

2 files changed

+74
-28
lines changed

apps/ns_server/src/menelaus_web_encr_at_rest.erl

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,28 @@ handle_post(Path, Req) ->
332332
settings_to_list(AlreadyDefined), settings_to_list(defaults()), Req).
333333

334334
handle_bucket_drop_keys(Bucket, Req) ->
335-
handle_bucket_drop_keys(Bucket, dek_drop_datetime, dropKeysDate, Req).
335+
ApplySettings = fun (_Enabled, Settings, Time) ->
336+
Settings#{dek_drop_datetime => Time}
337+
end,
338+
AuditProps = fun (_Enabled,ISOTime) -> [{dropKeysDate, ISOTime}] end,
339+
handle_bucket_drop_keys(Bucket, ApplySettings, AuditProps, Req).
336340

337341
handle_bucket_force_encr(Bucket, Req) ->
338-
handle_bucket_drop_keys(Bucket, force_encryption_datetime,
339-
forceEncryptionDate, Req).
342+
ApplySettings = fun (false, Settings, Time) ->
343+
Settings#{force_encryption_datetime => Time,
344+
dek_drop_datetime => Time};
345+
(true, Settings, Time) ->
346+
Settings#{force_encryption_datetime => Time}
347+
end,
348+
AuditProps = fun (false, ISOTime) ->
349+
[{forceEncryptionDate, ISOTime},
350+
{dropKeysDate, ISOTime}];
351+
(true, ISOTime) ->
352+
[{forceEncryptionDate, ISOTime}]
353+
end,
354+
handle_bucket_drop_keys(Bucket, ApplySettings, AuditProps, Req).
340355

341-
handle_bucket_drop_keys(Bucket, DropDeksTimeKey, AuditKey, Req) ->
356+
handle_bucket_drop_keys(Bucket, ApplySettings, AuditPropsFun, Req) ->
342357
menelaus_util:assert_is_enterprise(),
343358
handle_set_drop_time(
344359
fun (Time) ->
@@ -350,25 +365,29 @@ handle_bucket_drop_keys(Bucket, DropDeksTimeKey, AuditKey, Req) ->
350365
true ->
351366
CurVal = chronicle_compat:get(Snapshot, Key,
352367
#{default => #{}}),
353-
NewVal = CurVal#{DropDeksTimeKey => Time},
354-
{commit, [{set, Key, NewVal}]};
368+
{ok, BCfg} = ns_bucket:get_bucket(Bucket,
369+
Snapshot),
370+
Enabled = ns_bucket:is_encryption_enabled(BCfg),
371+
NewVal = ApplySettings(Enabled, CurVal, Time),
372+
ResProps = AuditPropsFun(Enabled,
373+
iso8601:format(Time)),
374+
{commit, [{set, Key, NewVal}], ResProps};
355375
false ->
356376
menelaus_util:web_exception(
357377
404, "Requested resource not found.\r\n")
358378
end
359379
end),
360380
case Res of
361-
ok ->
381+
{ok, ToReturn} ->
362382
AuditProps = [{dekType, "bucket"},
363-
{bucketName, Bucket},
364-
{AuditKey, iso8601:format(Time)}],
383+
{bucketName, Bucket}] ++ ToReturn,
365384
ns_audit:encryption_at_rest_drop_deks(Req, AuditProps),
366-
ok;
385+
ToReturn;
367386
{error, no_quorum = R} ->
368387
menelaus_util:web_exception(
369388
503, menelaus_web_secrets:format_error(R))
370389
end
371-
end, AuditKey, Req).
390+
end, Req).
372391

373392
build_bucket_encr_at_rest_info(BucketUUID, BucketConfig) ->
374393
NodesInfo = ns_doctor:get_nodes(),
@@ -391,13 +410,28 @@ format_encr_at_rest_info(Info) ->
391410
end, Info)}.
392411

393412
handle_drop_keys(TypeName, Req) ->
394-
handle_drop_keys(TypeName, dek_drop_datetime, dropKeysDate, Req).
413+
ApplySettings = fun (_Enabled, Settings, Time) ->
414+
Settings#{dek_drop_datetime => {set, Time}}
415+
end,
416+
AuditProps = fun (_Enabled, ISOTime) -> [{dropKeysDate, ISOTime}] end,
417+
handle_drop_keys(TypeName, ApplySettings, AuditProps, Req).
395418

396419
handle_force_encr(TypeName, Req) ->
397-
handle_drop_keys(TypeName, force_encryption_datetime,
398-
forceEncryptionDate, Req).
420+
ApplySettings = fun (false, Settings, Time) ->
421+
Settings#{force_encryption_datetime => {set, Time},
422+
dek_drop_datetime => {set, Time}};
423+
(true, Settings, Time) ->
424+
Settings#{force_encryption_datetime => {set, Time}}
425+
end,
426+
AuditProps = fun (false, ISOTime) ->
427+
[{forceEncryptionDate, ISOTime},
428+
{dropKeysDate, ISOTime}];
429+
(true, ISOTime) ->
430+
[{forceEncryptionDate, ISOTime}]
431+
end,
432+
handle_drop_keys(TypeName, ApplySettings, AuditProps, Req).
399433

400-
handle_drop_keys(TypeName, DropDeksTimeKey, AuditKey, Req) ->
434+
handle_drop_keys(TypeName, ApplySettings, AuditPropsFun, Req) ->
401435
menelaus_util:assert_is_enterprise(),
402436
handle_set_drop_time(
403437
fun (Time) ->
@@ -416,26 +450,26 @@ handle_drop_keys(TypeName, DropDeksTimeKey, AuditKey, Req) ->
416450
?CHRONICLE_ENCR_AT_REST_SETTINGS_KEY,
417451
#{default => #{}}),
418452
SubSettings = maps:get(TypeKey, AllSettings, #{}),
419-
NewSubSetting = SubSettings#{DropDeksTimeKey =>
420-
{set, Time}},
453+
Enabled = is_encryption_enabled(TypeKey, Snapshot),
454+
NewSubSetting = ApplySettings(Enabled, SubSettings, Time),
421455
NewSettings = AllSettings#{TypeKey => NewSubSetting},
456+
ResProps = AuditPropsFun(Enabled, iso8601:format(Time)),
422457
{commit,
423458
[{set, ?CHRONICLE_ENCR_AT_REST_SETTINGS_KEY,
424-
NewSettings}]}
459+
NewSettings}], ResProps}
425460
end),
426461
case Res of
427-
ok ->
428-
AuditProps = [{dekType, TypeName},
429-
{AuditKey, iso8601:format(Time)}],
462+
{ok, ToReturn} ->
463+
AuditProps = [{dekType, TypeName}] ++ ToReturn,
430464
ns_audit:encryption_at_rest_drop_deks(Req, AuditProps),
431-
ok;
465+
ToReturn;
432466
{error, no_quorum = R} ->
433467
menelaus_util:web_exception(
434468
503, menelaus_web_secrets:format_error(R))
435469
end
436-
end, AuditKey, Req).
470+
end, Req).
437471

438-
handle_set_drop_time(SetTimeFun, AuditKey, Req) ->
472+
handle_set_drop_time(SetTimeFun, Req) ->
439473
%% We need to sync with all node monitors to make sure that all nodes
440474
%% have generated DEKs that they have to be generated by this moment.
441475
%% This is needed to make sure dek drop time doesn't match the time of
@@ -469,8 +503,8 @@ handle_set_drop_time(SetTimeFun, AuditKey, Req) ->
469503
undefined -> calendar:universal_time();
470504
DT -> DT
471505
end,
472-
ok = SetTimeFun(Time),
473-
Reply = {[{AuditKey, iso8601:format(Time)}]},
506+
ResPropList = SetTimeFun(Time),
507+
Reply = {ResPropList},
474508
menelaus_util:reply_json(Req, Reply)
475509
end, Req, form, [validator:iso_8601_parsed(datetime, _),
476510
validator:unsupported(_)]).
@@ -676,4 +710,11 @@ get_dek_kinds_by_type(Type) ->
676710
#{required_usage := Type} -> [Kind];
677711
#{required_usage := _} -> []
678712
end
679-
end, cb_deks:dek_cluster_kinds_list(direct)).
713+
end, cb_deks:dek_cluster_kinds_list(direct)).
714+
715+
%% Caution: This function assumes that Type exists in the settings.
716+
is_encryption_enabled(Type, Snapshot) ->
717+
case get_settings(Snapshot) of
718+
#{Type := #{encryption := disabled}} -> false;
719+
#{Type := #{encryption := _}} -> true
720+
end.

apps/ns_server/src/ns_bucket.erl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@
217217
get_dek_rotation_interval/2,
218218
get_drop_keys_timestamp/2,
219219
get_force_encryption_timestamp/2,
220-
validate_encryption_secret/3]).
220+
validate_encryption_secret/3,
221+
is_encryption_enabled/1]).
221222

222223
%% fusion
223224
-export([is_fusion/1,
@@ -3972,3 +3973,7 @@ upgrade_to_79_test() ->
39723973
meck:unload().
39733974

39743975
-endif.
3976+
3977+
is_encryption_enabled(BucketConfig) ->
3978+
proplists:get_value(encryption_secret_id, BucketConfig,
3979+
?SECRET_ID_NOT_SET) /= ?SECRET_ID_NOT_SET.

0 commit comments

Comments
 (0)