Skip to content

Commit

Permalink
chanbackup: add rpc to verify emergency.recover file's data.
Browse files Browse the repository at this point in the history
  • Loading branch information
Aditya Sharma authored and Aditya Sharma committed Oct 14, 2023
1 parent e589192 commit 2b6feba
Showing 1 changed file with 94 additions and 0 deletions.
94 changes: 94 additions & 0 deletions plugins/chanbackup.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,92 @@ static struct command_result *json_restorefrompeer(struct command *cmd,
NULL);
}

/* Returns True if the backup data is correct and
* returns false with the reason in `fail` if it's incorrect.
* Instead of using `decrypt_scb()` we're using this because
* it shuts down the node in case of any discrepancy and that
* is not what we want to happen when someone runs `verifybackup`. */
static bool verify_bkp(struct command *cmd,
u8 *filedata,
char **fail) {

bk_crypto_state crypto_state;
u64 version;
u32 timestamp;
struct scb_chan **scb;

if (tal_bytelen(filedata) <
ABYTES + HEADER_LEN) {
*fail = "data is corrupted!";
return false;
}

u8 *decrypt_scb = tal_arr(tmpctx, u8, tal_bytelen(filedata) -
ABYTES -
HEADER_LEN);

/* The header part */
if (crypto_secretstream_xchacha20poly1305_init_pull(&crypto_state,
filedata,
(&secret)->data) != 0) {
*fail = "data is corrupted!";
return false;
}

if (crypto_secretstream_xchacha20poly1305_pull(&crypto_state, decrypt_scb,
NULL, 0,
filedata +
HEADER_LEN,
tal_bytelen(filedata)-
HEADER_LEN,
NULL, 0) != 0) {
*fail = "data is corrupted!";
return false;
}

if (!fromwire_static_chan_backup(cmd,
decrypt_scb,
&version,
&timestamp,
&scb)) {
*fail = "data is corrupted";
return false;
}

if (version != VERSION) {
*fail = "Incompatible emergency.recover file version on disk,"
"contact the admin or update the file asap!";
return false;
}
return true;
}


static struct command_result *json_verifybackup(struct command *cmd,
const char *buf,
const jsmntok_t *params)
{
struct json_stream *response;
char *fail;

if (!param(cmd, buf, params, NULL))
return command_param_failed();

u8 *filedata = get_file_data(tmpctx, cmd->plugin);

response = jsonrpc_stream_success(cmd);

if (!verify_bkp(cmd, filedata, &fail)) {
json_add_str_fmt(response, "emergency.recover", "%s, Kindly remove the file and restart the node.", fail);
}
else {
json_add_bool(response, "emergency.recover", true);
}

return command_finished(cmd, response);

}

static const char *init(struct plugin *p,
const char *buf UNUSED,
const jsmntok_t *config UNUSED)
Expand Down Expand Up @@ -834,6 +920,14 @@ static const struct plugin_command commands[] = {
"return channel-id's on completion",
json_restorefrompeer,
},
{
"verifybackup",
"recovery",
"Verifies your emergency.recover file and peer storage backup (if exists)."
"Also, gives out the channel IDs of the channels contained in the backup.",
"returns if the file is valid and the channel ID's contained in it",
json_verifybackup,
}
};

int main(int argc, char *argv[])
Expand Down

0 comments on commit 2b6feba

Please sign in to comment.