Skip to content

Commit

Permalink
Add ability to dump the content of the cryptocache.
Browse files Browse the repository at this point in the history
For tape encryption the storage daemon keeps a cache of recently used
data it needs when loading a crypto enabled volume and it doesn't have
a connection to the director (e.g. when starting the SD). The bscrypto
tool already had support for populating the cache with data which is
used when a Disaster Recovery is needed but it would be nice if you
could also dump the content of the cache using the bscrypto tool. There
is no real security risk as you still need read access to the cache file
and the data dumped is the wrapped/encrypted version of the key for
which you need the KeyEncryptionKey to be able to translate it to the
actual key loaded into the drive.
  • Loading branch information
Marco van Wieringen committed Feb 17, 2015
1 parent 9355be4 commit c4daee2
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
38 changes: 38 additions & 0 deletions src/lib/crypto_cache.c
Expand Up @@ -311,6 +311,44 @@ char *lookup_crypto_cache_entry(const char *VolumeName)
return NULL;
}

/*
* Dump the content of the crypto cache to a filedescriptor.
*/
void dump_crypto_cache(int fd)
{
int len;
const char *header;
crypto_cache_entry_t *cce;
char dt1[MAX_TIME_LENGTH],
dt2[MAX_TIME_LENGTH];
POOL_MEM msg(PM_MESSAGE);

if (!cached_crypto_keys) {
return;
}

/*
* Default header
*/
header = _("Volumename EncryptionKey Added Expires\n");

/*
* Lock the cache.
*/
P(crypto_cache_lock);

write(fd, header, strlen(header));
foreach_dlist(cce, cached_crypto_keys) {
bstrutime(dt1, sizeof(dt1), cce->added);
bstrutime(dt2, sizeof(dt2), cce->added + CRYPTO_CACHE_MAX_AGE);
len = Mmsg(msg, "%-16s %-32s %-20s %-20s\n", cce->VolumeName, cce->EncryptionKey, dt1, dt2);

write(fd, msg.c_str(), len);
}

V(crypto_cache_lock);
}

/*
* Flush the date from the internal cache.
*/
Expand Down
1 change: 1 addition & 0 deletions src/lib/crypto_cache.h
Expand Up @@ -48,6 +48,7 @@ void write_crypto_cache(const char *dir, const char *progname, int port);
void write_crypto_cache(const char *cache_file);
bool update_crypto_cache(const char *VolumeName, const char *EncryptionKey);
char *lookup_crypto_cache_entry(const char *VolumeName);
void dump_crypto_cache(int fd);
void flush_crypto_cache(void);

#endif /* _CRYPTO_CACHE_H */
29 changes: 27 additions & 2 deletions src/tools/bscrypto.c
Expand Up @@ -37,6 +37,7 @@ static void usage()
"Usage: bscrypto <options> [<device_name>]\n"
" -b Perform base64 encoding of keydata\n"
" -c Clear encryption key\n"
" -D <cachefile> Dump content of given cachefile\n"
" -d <nn> Set debug level to <nn>\n"
" -e Show drive encryption status\n"
" -g <keyfile> Generate new encryption passphrase in keyfile\n"
Expand All @@ -58,6 +59,7 @@ int main(int argc, char *const *argv)
int ch, kfd, length;
bool base64_transform = false,
clear_encryption = false,
dump_cache = false,
drive_encryption_status = false,
generate_passphrase = false,
populate_cache = false,
Expand All @@ -75,7 +77,7 @@ int main(int argc, char *const *argv)
bindtextdomain("bareos", LOCALEDIR);
textdomain("bareos");

while ((ch = getopt(argc, argv, "bcd:eg:k:p:s:vw:?")) != -1) {
while ((ch = getopt(argc, argv, "bcD:d:eg:k:p:s:vw:?")) != -1) {
switch (ch) {
case 'b':
base64_transform = true;
Expand All @@ -85,6 +87,11 @@ int main(int argc, char *const *argv)
clear_encryption = true;
break;

case 'D':
dump_cache = true;
cache_file = bstrdup(optarg);
break;

case 'd':
debug_level = atoi(optarg);
if (debug_level <= 0) {
Expand Down Expand Up @@ -148,7 +155,7 @@ int main(int argc, char *const *argv)
argc -= optind;
argv += optind;

if (!generate_passphrase && !show_keydata && !populate_cache && argc < 1) {
if (!generate_passphrase && !show_keydata && !dump_cache && !populate_cache && argc < 1) {
fprintf(stderr, _("Missing device_name argument for this option\n"));
usage();
retval = 1;
Expand Down Expand Up @@ -182,6 +189,7 @@ int main(int argc, char *const *argv)
volume_encryption_status) &&
(generate_passphrase ||
show_keydata ||
dump_cache ||
populate_cache)) {
fprintf(stderr, _("Don't mix operations which are incompatible "
"e.g. generate/show vs set/clear etc.\n"));
Expand All @@ -192,6 +200,21 @@ int main(int argc, char *const *argv)
OSDependentInit();
init_msg(NULL, NULL);

if (dump_cache) {
/*
* Load any keys currently in the cache.
*/
read_crypto_cache(cache_file);

/*
* Dump the content of the cache.
*/
dump_crypto_cache(1);

flush_crypto_cache();
goto bail_out;
}

if (populate_cache) {
char *VolumeName, *EncrKey;
char new_cache_entry[256];
Expand Down Expand Up @@ -227,6 +250,8 @@ int main(int argc, char *const *argv)
* Write out the new cache entries.
*/
write_crypto_cache(cache_file);

flush_crypto_cache();
goto bail_out;
}

Expand Down

0 comments on commit c4daee2

Please sign in to comment.