diff --git a/common/hsm_version.h b/common/hsm_version.h index 7d3f8fb80..44927bd30 100644 --- a/common/hsm_version.h +++ b/common/hsm_version.h @@ -23,6 +23,7 @@ * v5 with hsmd_revoke_commitment_tx: 5742538f87ef5d5bf55b66dc19e52c8683cfeb1b887d3e64ba530ba9a4d8e638 * v5 with sign_any_cannouncement: 5fdb9068c43a21887dc03f7dce410d2e3eeff6277f0d49b4fc56595a798fd4a4 * v5 drop init v2: 5024454532fe5a78bb7558000cb344190888b9915360d3d56ddca22eaba9b872 + * v5 with dev_preinit: b93e18534a468a4aa9f7015db42e9c363c32aeee5f9146b36dc953ebbdc3d33c */ #define HSM_MIN_VERSION 5 #define HSM_MAX_VERSION 5 diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index e41033c19..6599f777d 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -425,6 +425,24 @@ static void load_hsm(const struct secret *encryption_key) close(fd); } +/*~ We have a pre-init call in developer mode, to set dev flags */ +static struct io_plan *preinit_hsm(struct io_conn *conn, + struct client *c, + const u8 *msg_in) +{ + struct tlv_hsmd_dev_preinit_tlvs *tlv; + assert(developer); + + if (!fromwire_hsmd_dev_preinit(tmpctx, msg_in, &tlv)) + return bad_req(conn, c, msg_in); + + if (tlv->fail_preapprove) + dev_fail_preapprove = *tlv->fail_preapprove; + + /* We don't send a reply, just read next */ + return client_read_next(conn, c); +} + /*~ This is the response to lightningd's HSM_INIT request, which is the first * thing it sends. */ static struct io_plan *init_hsm(struct io_conn *conn, @@ -634,6 +652,9 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c) /* Now actually go and do what the client asked for */ switch (t) { + case WIRE_HSMD_DEV_PREINIT: + return preinit_hsm(conn, c, c->msg_in); + case WIRE_HSMD_INIT: return init_hsm(conn, c, c->msg_in); diff --git a/hsmd/hsmd_wire.csv b/hsmd/hsmd_wire.csv index cd7583562..f92a16af1 100644 --- a/hsmd/hsmd_wire.csv +++ b/hsmd/hsmd_wire.csv @@ -5,6 +5,14 @@ msgdata,hsmstatus_client_bad_request,description,wirestring, msgdata,hsmstatus_client_bad_request,len,u16, msgdata,hsmstatus_client_bad_request,msg,u8,len +# We use this to set dev flags (before init!). It's a TLV, so we can +# extend easily. Normal TLV rules apply: ignore odd fields you don't +# understand. +msgtype,hsmd_dev_preinit,99 +msgdata,hsmd_dev_preinit,tlvs,hsmd_dev_preinit_tlvs, +tlvtype,hsmd_dev_preinit_tlvs,fail_preapprove,1 +tlvdata,hsmd_dev_preinit_tlvs,fail_preapprove,fail,bool, + #include # Start the HSM. msgtype,hsmd_init,11 diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index c90edc7e1..522e67c52 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -33,6 +33,9 @@ struct { /* Have we initialized the secretstuff? */ bool initialized = false; +/* Do we fail all preapprove requests? */ +bool dev_fail_preapprove = false; + struct hsmd_client *hsmd_client_new_main(const tal_t *ctx, u64 capabilities, void *extra) { @@ -117,6 +120,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client, return (client->capabilities & HSM_PERM_LOCK_OUTPOINT) != 0; case WIRE_HSMD_INIT: + case WIRE_HSMD_DEV_PREINIT: case WIRE_HSMD_NEW_CHANNEL: case WIRE_HSMD_FORGET_CHANNEL: case WIRE_HSMD_CLIENT_HSMFD: @@ -774,8 +778,8 @@ static u8 *handle_preapprove_invoice(struct hsmd_client *c, const u8 *msg_in) if (!fromwire_hsmd_preapprove_invoice(tmpctx, msg_in, &invstring)) return hsmd_status_malformed_request(c, msg_in); - /* This stub always approves */ - approved = true; + /* This stub always approves unless overridden */ + approved = !dev_fail_preapprove; return towire_hsmd_preapprove_invoice_reply(NULL, approved); } @@ -792,8 +796,8 @@ static u8 *handle_preapprove_keysend(struct hsmd_client *c, const u8 *msg_in) if (!fromwire_hsmd_preapprove_keysend(msg_in, &destination, &payment_hash, &amount_msat)) return hsmd_status_malformed_request(c, msg_in); - /* This stub always approves */ - approved = true; + /* This stub always approves unless overridden */ + approved = !dev_fail_preapprove; return towire_hsmd_preapprove_keysend_reply(NULL, approved); } @@ -2012,6 +2016,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client, /* Now actually go and do what the client asked for */ switch (t) { + case WIRE_HSMD_DEV_PREINIT: case WIRE_HSMD_INIT: case WIRE_HSMD_CLIENT_HSMFD: /* Not implemented yet. Should not have been passed here yet. */ diff --git a/hsmd/libhsmd.h b/hsmd/libhsmd.h index 756c6c2f5..a722926cf 100644 --- a/hsmd/libhsmd.h +++ b/hsmd/libhsmd.h @@ -93,5 +93,6 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client, extern struct privkey *dev_force_privkey; /* If they specify --dev-force-bip32-seed it ends up in here. */ extern struct secret *dev_force_bip32_seed; - +/* If they specify --dev-hsmd-fail-preapprove it ends up in here. */ +extern bool dev_fail_preapprove; #endif /* LIGHTNING_HSMD_LIBHSMD_H */