Browse Source

hsmtool: Make the backup copy in the same directory as the original

TIL: `rename` doesn't like its source and target to be on different
partitions. This was causing the `hsmtool` tests to fail whenever we ran them
on a different partition than the lightning-dir (e.g., `/dev/shm` for faster
testing), because we made the backup copy in the current working directory.

This changes this and creates the backup next to the original file, which has
a reasonable chance to be on the same partition.

Changelog-Changed: hsmtool: The `hsmtool` now creates its backup copy in the same directory as the original `hsm_secret` file.
travis-debug
Christian Decker 5 years ago
committed by ZmnSCPxj, ZmnSCPxj jxPCSmnZ
parent
commit
2d45b13088
  1. 24
      tools/hsmtool.c

24
tools/hsmtool.c

@ -152,11 +152,15 @@ static int decrypt_hsm(const char *hsm_secret_path, const char *passwd)
int fd; int fd;
struct stat st; struct stat st;
struct secret hsm_secret; struct secret hsm_secret;
const char *dir, *backup;
if (sodium_init() == -1) if (sodium_init() == -1)
err(ERROR_LIBSODIUM, err(ERROR_LIBSODIUM,
"Could not initialize libsodium. Not enough entropy ?"); "Could not initialize libsodium. Not enough entropy ?");
dir = path_dirname(NULL, hsm_secret_path);
backup = path_join(dir, dir, "hsm_secret.backup");
if (stat(hsm_secret_path, &st) != 0) if (stat(hsm_secret_path, &st) != 0)
err(ERROR_HSM_FILE, "Could not stat hsm_secret"); err(ERROR_HSM_FILE, "Could not stat hsm_secret");
if (st.st_size <= 32) if (st.st_size <= 32)
@ -164,7 +168,7 @@ static int decrypt_hsm(const char *hsm_secret_path, const char *passwd)
get_encrypted_hsm_secret(&hsm_secret, hsm_secret_path, passwd); get_encrypted_hsm_secret(&hsm_secret, hsm_secret_path, passwd);
/* Create a backup file, "just in case". */ /* Create a backup file, "just in case". */
rename(hsm_secret_path, "hsm_secret.backup"); rename(hsm_secret_path, backup);
fd = open(hsm_secret_path, O_CREAT|O_EXCL|O_WRONLY, 0400); fd = open(hsm_secret_path, O_CREAT|O_EXCL|O_WRONLY, 0400);
if (fd < 0) if (fd < 0)
err(ERROR_HSM_FILE, "Could not open new hsm_secret"); err(ERROR_HSM_FILE, "Could not open new hsm_secret");
@ -180,11 +184,12 @@ static int decrypt_hsm(const char *hsm_secret_path, const char *passwd)
/* Be as paranoïd as in hsmd with the file state on disk. */ /* Be as paranoïd as in hsmd with the file state on disk. */
if (!ensure_hsm_secret_exists(fd, hsm_secret_path)) { if (!ensure_hsm_secret_exists(fd, hsm_secret_path)) {
unlink_noerr(hsm_secret_path); unlink_noerr(hsm_secret_path);
rename("hsm_secret.backup", hsm_secret_path); rename(backup, hsm_secret_path);
err(ERROR_HSM_FILE, err(ERROR_HSM_FILE,
"Could not ensure hsm_secret existence."); "Could not ensure hsm_secret existence.");
} }
unlink_noerr("hsm_secret.backup"); unlink_noerr(backup);
tal_free(dir);
printf("Succesfully decrypted hsm_secret, be careful now :-).\n"); printf("Succesfully decrypted hsm_secret, be careful now :-).\n");
return 0; return 0;
@ -200,6 +205,10 @@ static int encrypt_hsm(const char *hsm_secret_path, const char *passwd)
u8 header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; u8 header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
/* The cipher size is static with xchacha20poly1305. */ /* The cipher size is static with xchacha20poly1305. */
u8 cipher[sizeof(struct secret) + crypto_secretstream_xchacha20poly1305_ABYTES]; u8 cipher[sizeof(struct secret) + crypto_secretstream_xchacha20poly1305_ABYTES];
const char *dir, *backup;
dir = path_dirname(NULL, hsm_secret_path);
backup = path_join(dir, dir, "hsm_secret.backup");
if (sodium_init() == -1) if (sodium_init() == -1)
err(ERROR_LIBSODIUM, err(ERROR_LIBSODIUM,
@ -228,7 +237,7 @@ static int encrypt_hsm(const char *hsm_secret_path, const char *passwd)
err(ERROR_LIBSODIUM, "Could not encrypt the seed."); err(ERROR_LIBSODIUM, "Could not encrypt the seed.");
/* Create a backup file, "just in case". */ /* Create a backup file, "just in case". */
rename(hsm_secret_path, "hsm_secret.backup"); rename(hsm_secret_path, backup);
fd = open(hsm_secret_path, O_CREAT|O_EXCL|O_WRONLY, 0400); fd = open(hsm_secret_path, O_CREAT|O_EXCL|O_WRONLY, 0400);
if (fd < 0) if (fd < 0)
err(ERROR_HSM_FILE, "Could not open new hsm_secret"); err(ERROR_HSM_FILE, "Could not open new hsm_secret");
@ -238,17 +247,18 @@ static int encrypt_hsm(const char *hsm_secret_path, const char *passwd)
|| !write_all(fd, cipher, sizeof(cipher))) { || !write_all(fd, cipher, sizeof(cipher))) {
unlink_noerr(hsm_secret_path); unlink_noerr(hsm_secret_path);
close(fd); close(fd);
rename("hsm_secret.backup", hsm_secret_path); rename(backup, hsm_secret_path);
err(ERROR_HSM_FILE, "Failure writing cipher to hsm_secret."); err(ERROR_HSM_FILE, "Failure writing cipher to hsm_secret.");
} }
/* Be as paranoïd as in hsmd with the file state on disk. */ /* Be as paranoïd as in hsmd with the file state on disk. */
if (!ensure_hsm_secret_exists(fd, hsm_secret_path)) { if (!ensure_hsm_secret_exists(fd, hsm_secret_path)) {
unlink_noerr(hsm_secret_path); unlink_noerr(hsm_secret_path);
rename("hsm_secret.backup", hsm_secret_path); rename(backup, hsm_secret_path);
err(ERROR_HSM_FILE, "Could not ensure hsm_secret existence."); err(ERROR_HSM_FILE, "Could not ensure hsm_secret existence.");
} }
unlink_noerr("hsm_secret.backup"); unlink_noerr(backup);
tal_free(dir);
printf("Succesfully encrypted hsm_secret. You'll now have to pass the " printf("Succesfully encrypted hsm_secret. You'll now have to pass the "
"--encrypted-hsm startup option.\n"); "--encrypted-hsm startup option.\n");

Loading…
Cancel
Save