mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 01:43:36 +01:00
connectd: do decryption for peers.
We temporarily hack to sync_crypto_write/sync_crypto_read functions to not do any crypto, and do it all in connectd. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
71f736678f
commit
a2b3d335bb
@ -12,6 +12,8 @@
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <wire/wire.h>
|
||||
#include <wire/wire_io.h>
|
||||
#include <wire/wire_sync.h>
|
||||
|
||||
void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES)
|
||||
{
|
||||
@ -19,10 +21,8 @@ void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES)
|
||||
bool post_sabotage = false, post_close;
|
||||
int type = fromwire_peektype(msg);
|
||||
#endif
|
||||
u8 *enc;
|
||||
|
||||
status_peer_io(LOG_IO_OUT, NULL, msg);
|
||||
enc = cryptomsg_encrypt_msg(NULL, &pps->cs, msg);
|
||||
|
||||
#if DEVELOPER
|
||||
switch (dev_disconnect(type)) {
|
||||
@ -44,9 +44,8 @@ void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (!write_all(pps->peer_fd, enc, tal_count(enc)))
|
||||
if (!wire_sync_write(pps->peer_fd, msg))
|
||||
peer_failed_connection_lost();
|
||||
tal_free(enc);
|
||||
|
||||
#if DEVELOPER
|
||||
if (post_sabotage)
|
||||
@ -101,31 +100,10 @@ void sync_crypto_write_no_delay(struct per_peer_state *pps,
|
||||
|
||||
u8 *sync_crypto_read(const tal_t *ctx, struct per_peer_state *pps)
|
||||
{
|
||||
u8 hdr[18], *enc, *dec;
|
||||
u16 len;
|
||||
|
||||
if (!read_all(pps->peer_fd, hdr, sizeof(hdr))) {
|
||||
status_debug("Failed reading header: %s", strerror(errno));
|
||||
peer_failed_connection_lost();
|
||||
}
|
||||
|
||||
if (!cryptomsg_decrypt_header(&pps->cs, hdr, &len)) {
|
||||
status_debug("Failed hdr decrypt with rn=%"PRIu64,
|
||||
pps->cs.rn-1);
|
||||
peer_failed_connection_lost();
|
||||
}
|
||||
|
||||
enc = tal_arr(ctx, u8, len + 16);
|
||||
if (!read_all(pps->peer_fd, enc, tal_count(enc))) {
|
||||
status_debug("Failed reading body: %s", strerror(errno));
|
||||
peer_failed_connection_lost();
|
||||
}
|
||||
|
||||
dec = cryptomsg_decrypt_body(ctx, &pps->cs, enc);
|
||||
tal_free(enc);
|
||||
u8 *dec = wire_sync_read(ctx, pps->peer_fd);
|
||||
if (!dec)
|
||||
peer_failed_connection_lost();
|
||||
else
|
||||
|
||||
status_peer_io(LOG_IO_IN, NULL, dec);
|
||||
|
||||
return dec;
|
||||
|
@ -452,7 +452,6 @@ static struct peer *new_peer(struct daemon *daemon,
|
||||
peer->final_msg = NULL;
|
||||
peer->subd_in = NULL;
|
||||
peer->peer_in = NULL;
|
||||
peer->sent_to_subd = NULL;
|
||||
peer->sent_to_peer = NULL;
|
||||
peer->peer_outq = msg_queue_new(peer);
|
||||
peer->subd_outq = msg_queue_new(peer);
|
||||
@ -1988,7 +1987,6 @@ static void peer_final_msg(struct io_conn *conn,
|
||||
if (peer) {
|
||||
/* Log and encrypt message for peer. */
|
||||
status_peer_io(LOG_IO_OUT, &id, finalmsg);
|
||||
finalmsg = cryptomsg_encrypt_msg(NULL, &pps->cs, take(finalmsg));
|
||||
multiplex_final_msg(peer, take(finalmsg));
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,20 @@
|
||||
#include "config.h"
|
||||
#include <assert.h>
|
||||
#include <ccan/io/io.h>
|
||||
#include <common/cryptomsg.h>
|
||||
#include <common/per_peer_state.h>
|
||||
#include <common/status.h>
|
||||
#include <common/utils.h>
|
||||
#include <connectd/multiplex.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <wire/wire_io.h>
|
||||
|
||||
void queue_peer_msg(struct peer *peer, const u8 *msg TAKES)
|
||||
{
|
||||
msg_enqueue(peer->peer_outq, msg);
|
||||
}
|
||||
|
||||
/* These four function handle subd->peer */
|
||||
static struct io_plan *after_final_msg(struct io_conn *peer_conn,
|
||||
@ -24,25 +32,39 @@ static struct io_plan *after_final_msg(struct io_conn *peer_conn,
|
||||
return io_close(peer_conn);
|
||||
}
|
||||
|
||||
static struct io_plan *encrypt_and_send(struct peer *peer,
|
||||
const u8 *msg TAKES,
|
||||
struct io_plan *(*next)
|
||||
(struct io_conn *peer_conn,
|
||||
struct peer *peer))
|
||||
{
|
||||
/* We free this and the encrypted version in next write_to_peer */
|
||||
peer->sent_to_peer = cryptomsg_encrypt_msg(peer, &peer->pps->cs, msg);
|
||||
return io_write(peer->to_peer,
|
||||
peer->sent_to_peer,
|
||||
tal_bytelen(peer->sent_to_peer),
|
||||
next, peer);
|
||||
}
|
||||
|
||||
static struct io_plan *write_to_peer(struct io_conn *peer_conn,
|
||||
struct peer *peer)
|
||||
{
|
||||
const u8 *msg;
|
||||
assert(peer->to_peer == peer_conn);
|
||||
|
||||
/* Free last sent one (if any) */
|
||||
tal_free(peer->sent_to_peer);
|
||||
peer->sent_to_peer = tal_free(peer->sent_to_peer);
|
||||
|
||||
/* Pop tail of send queue */
|
||||
peer->sent_to_peer = msg_dequeue(peer->peer_outq);
|
||||
msg = msg_dequeue(peer->peer_outq);
|
||||
|
||||
/* Nothing to send? */
|
||||
if (!peer->sent_to_peer) {
|
||||
if (!msg) {
|
||||
/* Send final once subd is not longer connected */
|
||||
if (peer->final_msg && !peer->to_subd) {
|
||||
return io_write(peer_conn,
|
||||
return encrypt_and_send(peer,
|
||||
peer->final_msg,
|
||||
tal_bytelen(peer->final_msg),
|
||||
after_final_msg, peer);
|
||||
after_final_msg);
|
||||
}
|
||||
/* Tell them to read again, */
|
||||
io_wake(&peer->subd_in);
|
||||
@ -52,10 +74,7 @@ static struct io_plan *write_to_peer(struct io_conn *peer_conn,
|
||||
write_to_peer, peer);
|
||||
}
|
||||
|
||||
return io_write(peer_conn,
|
||||
peer->sent_to_peer,
|
||||
tal_bytelen(peer->sent_to_peer),
|
||||
write_to_peer, peer);
|
||||
return encrypt_and_send(peer, take(msg), write_to_peer);
|
||||
}
|
||||
|
||||
static struct io_plan *read_from_subd(struct io_conn *subd_conn,
|
||||
@ -63,15 +82,10 @@ static struct io_plan *read_from_subd(struct io_conn *subd_conn,
|
||||
static struct io_plan *read_from_subd_done(struct io_conn *subd_conn,
|
||||
struct peer *peer)
|
||||
{
|
||||
size_t len = ((size_t *)peer->subd_in)[1023];
|
||||
assert(peer->to_subd == subd_conn);
|
||||
|
||||
/* Trim to length */
|
||||
tal_resize(&peer->subd_in, len);
|
||||
|
||||
/* Tell them to write. */
|
||||
msg_enqueue(peer->peer_outq, take(peer->subd_in));
|
||||
/* Tell them to encrypt & write. */
|
||||
queue_peer_msg(peer, take(peer->subd_in));
|
||||
peer->subd_in = NULL;
|
||||
|
||||
/* Wait for them to wake us */
|
||||
return io_wait(subd_conn, &peer->subd_in, read_from_subd, peer);
|
||||
}
|
||||
@ -79,14 +93,7 @@ static struct io_plan *read_from_subd_done(struct io_conn *subd_conn,
|
||||
static struct io_plan *read_from_subd(struct io_conn *subd_conn,
|
||||
struct peer *peer)
|
||||
{
|
||||
/* We stash the length at the end */
|
||||
size_t *buf = tal_arr(peer, size_t, 1024);
|
||||
assert(peer->to_subd == subd_conn);
|
||||
|
||||
peer->subd_in = (u8 *)buf;
|
||||
return io_read_partial(subd_conn, peer->subd_in,
|
||||
sizeof(size_t) * 1023,
|
||||
&buf[1023],
|
||||
return io_read_wire(subd_conn, peer, &peer->subd_in,
|
||||
read_from_subd_done, peer);
|
||||
}
|
||||
|
||||
@ -94,17 +101,15 @@ static struct io_plan *read_from_subd(struct io_conn *subd_conn,
|
||||
static struct io_plan *write_to_subd(struct io_conn *subd_conn,
|
||||
struct peer *peer)
|
||||
{
|
||||
const u8 *msg;
|
||||
assert(peer->to_subd == subd_conn);
|
||||
|
||||
/* Free last sent one (if any) */
|
||||
tal_free(peer->sent_to_subd);
|
||||
|
||||
/* Pop tail of send queue */
|
||||
peer->sent_to_subd = msg_dequeue(peer->subd_outq);
|
||||
msg = msg_dequeue(peer->subd_outq);
|
||||
|
||||
/* Nothing to send? */
|
||||
if (!peer->sent_to_subd) {
|
||||
/* Tell them to read again, */
|
||||
if (!msg) {
|
||||
/* Tell them to read again. */
|
||||
io_wake(&peer->peer_in);
|
||||
|
||||
/* Wait for them to wake us */
|
||||
@ -112,42 +117,59 @@ static struct io_plan *write_to_subd(struct io_conn *subd_conn,
|
||||
write_to_subd, peer);
|
||||
}
|
||||
|
||||
return io_write(subd_conn,
|
||||
peer->sent_to_subd,
|
||||
tal_bytelen(peer->sent_to_subd),
|
||||
write_to_subd, peer);
|
||||
return io_write_wire(subd_conn, take(msg), write_to_subd, peer);
|
||||
}
|
||||
|
||||
static struct io_plan *read_from_peer(struct io_conn *peer_conn,
|
||||
static struct io_plan *read_hdr_from_peer(struct io_conn *peer_conn,
|
||||
struct peer *peer);
|
||||
static struct io_plan *read_from_peer_done(struct io_conn *peer_conn,
|
||||
static struct io_plan *read_body_from_peer_done(struct io_conn *peer_conn,
|
||||
struct peer *peer)
|
||||
{
|
||||
size_t len = ((size_t *)peer->peer_in)[1023];
|
||||
assert(peer->to_peer == peer_conn);
|
||||
u8 *decrypted;
|
||||
|
||||
/* Trim to length */
|
||||
tal_resize(&peer->peer_in, len);
|
||||
decrypted = cryptomsg_decrypt_body(NULL, &peer->pps->cs,
|
||||
peer->peer_in);
|
||||
if (!decrypted)
|
||||
return io_close(peer_conn);
|
||||
tal_free(peer->peer_in);
|
||||
|
||||
/* Tell them to write. */
|
||||
msg_enqueue(peer->subd_outq, take(peer->peer_in));
|
||||
peer->peer_in = NULL;
|
||||
msg_enqueue(peer->subd_outq, take(decrypted));
|
||||
|
||||
/* Wait for them to wake us */
|
||||
return io_wait(peer_conn, &peer->peer_in, read_from_peer, peer);
|
||||
return io_wait(peer_conn, &peer->peer_in, read_hdr_from_peer, peer);
|
||||
}
|
||||
|
||||
static struct io_plan *read_from_peer(struct io_conn *peer_conn,
|
||||
static struct io_plan *read_body_from_peer(struct io_conn *peer_conn,
|
||||
struct peer *peer)
|
||||
{
|
||||
u16 len;
|
||||
|
||||
if (!cryptomsg_decrypt_header(&peer->pps->cs, peer->peer_in, &len))
|
||||
return io_close(peer_conn);
|
||||
|
||||
tal_resize(&peer->peer_in, (u32)len + CRYPTOMSG_BODY_OVERHEAD);
|
||||
return io_read(peer_conn, peer->peer_in, tal_count(peer->peer_in),
|
||||
read_body_from_peer_done, peer);
|
||||
}
|
||||
|
||||
static struct io_plan *read_hdr_from_peer(struct io_conn *peer_conn,
|
||||
struct peer *peer)
|
||||
{
|
||||
/* We stash the length at the end */
|
||||
size_t *buf = tal_arr(peer, size_t, 1024);
|
||||
assert(peer->to_peer == peer_conn);
|
||||
|
||||
peer->peer_in = (u8 *)buf;
|
||||
return io_read_partial(peer_conn, peer->peer_in,
|
||||
sizeof(size_t) * 1023,
|
||||
&buf[1023],
|
||||
read_from_peer_done, peer);
|
||||
/* BOLT #8:
|
||||
*
|
||||
* ### Receiving and Decrypting Messages
|
||||
*
|
||||
* In order to decrypt the _next_ message in the network
|
||||
* stream, the following steps are completed:
|
||||
*
|
||||
* 1. Read _exactly_ 18 bytes from the network buffer.
|
||||
*/
|
||||
peer->peer_in = tal_arr(peer, u8, CRYPTOMSG_HDR_SIZE);
|
||||
return io_read(peer_conn, peer->peer_in, CRYPTOMSG_HDR_SIZE,
|
||||
read_body_from_peer, peer);
|
||||
}
|
||||
|
||||
static struct io_plan *subd_conn_init(struct io_conn *subd_conn, struct peer *peer)
|
||||
@ -200,7 +222,7 @@ struct io_plan *multiplex_peer_setup(struct io_conn *peer_conn,
|
||||
tal_add_destructor2(peer_conn, destroy_peer_conn, peer);
|
||||
|
||||
return io_duplex(peer_conn,
|
||||
read_from_peer(peer_conn, peer),
|
||||
read_hdr_from_peer(peer_conn, peer),
|
||||
write_to_peer(peer_conn, peer));
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,8 @@ struct peer {
|
||||
/* Output buffers. */
|
||||
struct msg_queue *subd_outq, *peer_outq;
|
||||
|
||||
/* Sent buffers (for freeing after sending) */
|
||||
const u8 *sent_to_subd, *sent_to_peer;
|
||||
/* Peer sent buffer (for freeing after sending) */
|
||||
const u8 *sent_to_peer;
|
||||
};
|
||||
|
||||
/* Set up peer->to_subd; sets fd_for_subd to pass to lightningd. */
|
||||
@ -38,4 +38,8 @@ struct io_plan *multiplex_peer_setup(struct io_conn *peer_conn,
|
||||
/* Send this message to peer and disconnect. */
|
||||
void multiplex_final_msg(struct peer *peer,
|
||||
const u8 *final_msg TAKES);
|
||||
|
||||
/* Inject a message into the output stream */
|
||||
void queue_peer_msg(struct peer *peer, const u8 *msg TAKES);
|
||||
|
||||
#endif /* LIGHTNING_CONNECTD_MULTIPLEX_H */
|
||||
|
@ -27,7 +27,7 @@ struct io_plan *io_read_wire_(struct io_conn *conn,
|
||||
|
||||
/* Write message from data (tal_count(data) gives length). data can be take() */
|
||||
struct io_plan *io_write_wire_(struct io_conn *conn,
|
||||
const u8 *data,
|
||||
const u8 *data TAKES,
|
||||
struct io_plan *(*next)(struct io_conn *, void *),
|
||||
void *next_arg);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user