xref: /dragonfly/lib/libdmsg/dmsg.h (revision ae071d8d)
1 /*
2  * Copyright (c) 2011-2012 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@dragonflybsd.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #include <sys/types.h>
36 #include <sys/queue.h>
37 #include <sys/tree.h>
38 #include <sys/dmsg.h>
39 
40 #include <pthread.h>
41 
42 #if 0
43 #include <openssl/rsa.h>	/* public/private key functions */
44 #include <openssl/pem.h>	/* public/private key file load */
45 #endif
46 #include <openssl/err.h>
47 #include <openssl/evp.h>	/* aes_256_cbc functions */
48 
49 #define DMSG_DEFAULT_DIR	"/etc/hammer2"
50 #define DMSG_PATH_REMOTE	DMSG_DEFAULT_DIR "/remote"
51 
52 #define DMSG_LISTEN_PORT	987
53 
54 /***************************************************************************
55  *				CRYPTO HANDSHAKE			   *
56  ***************************************************************************
57  *
58  * The initial public-key exchange is implementing by transmitting a
59  * 512-byte buffer to the other side in a symmetrical fashion.  This
60  * buffer contains the following:
61  *
62  * (1) A random session key.  512 bits is specified.  We use aes_256_cbc()
63  *     and initialize the key with the first 256 bits and the iv[] with
64  *     the second.  Note that the transmitted and received session
65  *     keys are XOR'd together to create the session key used for
66  *     communications (so even if the verifier is compromised the session
67  *     will still be gobbly gook if the public key has not been completely
68  *     broken).
69  *
70  * (2) A verifier to determine that the decode was successful.  It encodes
71  *     an XOR of each group of 4 bytes from the session key.
72  *
73  * (3) Additional configuration and additional random data.
74  *
75  *     - The hammer2 message header magic for endian detect
76  *
77  *     - The hammer2 protocol version.  The two sides agree on the
78  *	 smaller of the two.
79  *
80  *     - All unused fields (junk*) are filled with random data.
81  *
82  * This structure must be exactly 512 bytes and expects to use 256-byte
83  * RSA keys.
84  */
85 struct dmsg_handshake {
86 	char pad1[8];		/* 000 */
87 	uint16_t magic;		/* 008 DMSG_HDR_MAGIC for endian detect */
88 	uint16_t version;	/* 00A hammer2 protocol version */
89 	uint32_t flags;		/* 00C protocol extension flags */
90 	uint8_t sess[64];	/* 010 512-bit session key */
91 	uint8_t verf[16];	/* 050 verifier = ~sess */
92 	char quickmsg[32];	/* 060 reason for connecting */
93 	char junk080[128];	/* 080-0FF */
94 	char pad2[8];		/* 100-107 */
95 	char junk100[256-8];	/* 108-1FF */
96 };
97 
98 typedef struct dmsg_handshake dmsg_handshake_t;
99 
100 
101 #define DMSG_CRYPTO_CHUNK_SIZE		DMSG_ALIGN
102 #define DMSG_MAX_IV_SIZE		32
103 
104 #define DMSG_CRYPTO_GCM_IV_FIXED_SIZE	4
105 #define DMSG_CRYPTO_GCM_IV_SIZE		12
106 #define DMSG_CRYPTO_GCM_KEY_SIZE	32
107 #define DMSG_CRYPTO_GCM_TAG_SIZE	16
108 
109 #define DMSG_CRYPTO_ALGO_GCM_IDX	0
110 
111 #define DMSG_CRYPTO_ALGO		DMSG_CRYPTO_ALGO_GCM_IDX
112 
113 /***************************************************************************
114  *				LOW LEVEL MESSAGING			   *
115  ***************************************************************************
116  *
117  * dmsg_msg - A standalone copy of a message, typically referenced by
118  *		 or embedded in other structures, or used with I/O queues.
119  *
120  * These structures are strictly temporary, so they do not have to be
121  * particularly optimized for size.  All possible message headers are
122  * directly embedded (any), and the message may contain a reference
123  * to allocated auxillary data.  The structure is recycled quite often
124  * by a connection.
125  */
126 struct dmsg_iocom;
127 struct dmsg_circuit;
128 struct dmsg_state;
129 struct dmsg_msg;
130 
131 TAILQ_HEAD(dmsg_state_queue, dmsg_state);
132 TAILQ_HEAD(dmsg_msg_queue, dmsg_msg);
133 RB_HEAD(dmsg_state_tree, dmsg_state);
134 RB_HEAD(dmsg_circuit_tree, dmsg_circuit);
135 
136 struct h2span_link;
137 struct h2span_relay;
138 struct h2span_conn;
139 
140 struct dmsg_circuit {
141 	RB_ENTRY(dmsg_circuit)	rbnode;
142 	uint64_t		msgid;
143 	struct dmsg_iocom	*iocom;
144 	struct dmsg_state_tree	staterd_tree;	/* active transactions */
145 	struct dmsg_state_tree	statewr_tree;	/* active transactions */
146 	struct dmsg_circuit	*peer;		/* (if circuit relay) */
147 	struct dmsg_state	*state;		/* open VC transaction state */
148 	struct dmsg_state	*span_state;	/* span, relay or link */
149 	int			is_relay;	/* span is h2span_relay */
150 	int			refs;
151 };
152 
153 /*
154  * The state structure is ref-counted.  The iocom cannot go away while
155  * state structures are active.  However, the related h2span_* linkages
156  * can be destroyed and NULL'd out if the state is terminated in both
157  * directions.
158  */
159 struct dmsg_state {
160 	RB_ENTRY(dmsg_state) rbnode;		/* indexed by msgid */
161 	struct dmsg_iocom *iocom;
162 	struct dmsg_circuit *circuit;		/* associated circuit */
163 	uint32_t	icmd;			/* command creating state */
164 	uint32_t	txcmd;			/* mostly for CMDF flags */
165 	uint32_t	rxcmd;			/* mostly for CMDF flags */
166 	uint64_t	msgid;			/* {spanid,msgid} uniq */
167 	int		flags;
168 	int		error;
169 	int		refs;			/* prevent destruction */
170 	struct dmsg_msg *msg;			/* msg creating orig state */
171 	void (*func)(struct dmsg_msg *);
172 	union {
173 		void *any;
174 		struct h2span_link *link;
175 		struct h2span_conn *conn;
176 		struct h2span_relay *relay;
177 		struct dmsg_circuit *circ;
178 	} any;
179 };
180 
181 #define DMSG_STATE_INSERTED	0x0001
182 #define DMSG_STATE_DYNAMIC	0x0002
183 #define DMSG_STATE_NODEID	0x0004		/* manages a node id */
184 
185 /*
186  * This is the core in-memory representation of a message structure.
187  * The iocom represents the incoming or outgoing iocom.  Various state
188  * pointers are calculated based on the message's raw source and target
189  * fields, and will ref the underlying state.  Message headers are embedded
190  * while auxillary data is separately allocated.
191  */
192 struct dmsg_msg {
193 	TAILQ_ENTRY(dmsg_msg) qentry;
194 	struct dmsg_iocom *iocom;		/* incoming/outgoing iocom */
195 	struct dmsg_circuit *circuit;		/* associated circuit */
196 	struct dmsg_state *state;		/* message state */
197 	size_t		hdr_size;
198 	size_t		aux_size;
199 	char		*aux_data;
200 	dmsg_any_t 	any;			/* must be last element */
201 };
202 
203 typedef struct dmsg_circuit dmsg_circuit_t;
204 typedef struct dmsg_state dmsg_state_t;
205 typedef struct dmsg_msg dmsg_msg_t;
206 typedef struct dmsg_msg_queue dmsg_msg_queue_t;
207 
208 int dmsg_state_cmp(dmsg_state_t *state1, dmsg_state_t *state2);
209 RB_PROTOTYPE(dmsg_state_tree, dmsg_state, rbnode, dmsg_state_cmp);
210 int dmsg_circuit_cmp(dmsg_circuit_t *circuit1, dmsg_circuit_t *circuit2);
211 RB_PROTOTYPE(dmsg_circuit_tree, dmsg_circuit, rbnode, dmsg_circuit_cmp);
212 
213 /*
214  * dmsg_ioq - An embedded component of dmsg_conn, holds state
215  * for the buffering and parsing of incoming and outgoing messages.
216  *
217  * cdx - beg  - processed buffer data, encrypted or decrypted
218  * end - cdn  - unprocessed buffer data not yet encrypted or decrypted
219  */
220 struct dmsg_ioq {
221 	enum { DMSG_MSGQ_STATE_HEADER1,
222 	       DMSG_MSGQ_STATE_HEADER2,
223 	       DMSG_MSGQ_STATE_AUXDATA1,
224 	       DMSG_MSGQ_STATE_AUXDATA2,
225 	       DMSG_MSGQ_STATE_ERROR } state;
226 	size_t		fifo_beg;		/* buffered data */
227 	size_t		fifo_cdx;		/* cdx-beg processed */
228 	size_t		fifo_cdn;		/* end-cdn unprocessed */
229 	size_t		fifo_end;
230 	size_t		hbytes;			/* header size */
231 	size_t		abytes;			/* aligned aux_data size */
232 	size_t		unaligned_aux_size;	/* actual aux_data size */
233 	int		error;
234 	int		seq;			/* salt sequencer */
235 	int		msgcount;
236 	EVP_CIPHER_CTX	ctx;
237 	char		iv[DMSG_MAX_IV_SIZE]; /* encrypt or decrypt iv[] */
238 	dmsg_msg_t	*msg;
239 	dmsg_msg_queue_t msgq;
240 	char		buf[DMSG_BUF_SIZE];	/* staging buffer */
241 };
242 
243 typedef struct dmsg_ioq dmsg_ioq_t;
244 
245 #define DMSG_IOQ_ERROR_SYNC		1	/* bad magic / out of sync */
246 #define DMSG_IOQ_ERROR_EOF		2	/* unexpected EOF */
247 #define DMSG_IOQ_ERROR_SOCK		3	/* read() error on socket */
248 #define DMSG_IOQ_ERROR_FIELD		4	/* invalid field */
249 #define DMSG_IOQ_ERROR_HCRC		5	/* core header crc bad */
250 #define DMSG_IOQ_ERROR_XCRC		6	/* ext header crc bad */
251 #define DMSG_IOQ_ERROR_ACRC		7	/* aux data crc bad */
252 #define DMSG_IOQ_ERROR_STATE		8	/* bad state */
253 #define DMSG_IOQ_ERROR_NOPEER		9	/* bad socket peer */
254 #define DMSG_IOQ_ERROR_NORKEY		10	/* no remote keyfile found */
255 #define DMSG_IOQ_ERROR_NOLKEY		11	/* no local keyfile found */
256 #define DMSG_IOQ_ERROR_KEYXCHGFAIL	12	/* key exchange failed */
257 #define DMSG_IOQ_ERROR_KEYFMT		13	/* key file format problem */
258 #define DMSG_IOQ_ERROR_BADURANDOM	14	/* /dev/urandom is bad */
259 #define DMSG_IOQ_ERROR_MSGSEQ		15	/* message sequence error */
260 #define DMSG_IOQ_ERROR_EALREADY		16	/* ignore this message */
261 #define DMSG_IOQ_ERROR_TRANS		17	/* state transaction issue */
262 #define DMSG_IOQ_ERROR_IVWRAP		18	/* IVs exhaused */
263 #define DMSG_IOQ_ERROR_MACFAIL		19	/* MAC of encr alg failed */
264 #define DMSG_IOQ_ERROR_ALGO		20	/* Misc. encr alg error */
265 #define DMSG_IOQ_ERROR_ROUTED		21	/* ignore routed message */
266 #define DMSG_IOQ_ERROR_BAD_CIRCUIT	22	/* unconfigured circuit */
267 #define DMSG_IOQ_ERROR_UNUSED23		23
268 #define DMSG_IOQ_ERROR_ASSYM		24	/* Assymetric path */
269 
270 #define DMSG_IOQ_MAXIOVEC    16
271 
272 /*
273  * dmsg_iocom - governs a messaging stream connection
274  */
275 struct dmsg_iocom {
276 	char		*label;			/* label for error reporting */
277 	dmsg_ioq_t	ioq_rx;
278 	dmsg_ioq_t	ioq_tx;
279 	dmsg_msg_queue_t freeq;			/* free msgs hdr only */
280 	dmsg_msg_queue_t freeq_aux;		/* free msgs w/aux_data */
281 	int	sock_fd;			/* comm socket or pipe */
282 	int	alt_fd;				/* thread signal, tty, etc */
283 	int	wakeupfds[2];			/* pipe wakes up iocom thread */
284 	int	flags;
285 	int	rxmisc;
286 	int	txmisc;
287 	void	(*signal_callback)(struct dmsg_iocom *);
288 	void	(*rcvmsg_callback)(struct dmsg_msg *);
289 	void	(*altmsg_callback)(struct dmsg_iocom *);
290 	void	(*dbgmsg_callback)(dmsg_msg_t *msg);
291 	struct dmsg_circuit_tree circuit_tree;	/* active circuits */
292 	struct dmsg_circuit	circuit0;	/* embedded circuit0 */
293 	dmsg_msg_queue_t txmsgq;		/* tx msgq from remote */
294 	struct h2span_conn *conn;		/* if LNK_CONN active */
295 	pthread_mutex_t mtx;			/* mutex for state*tree/rmsgq */
296 };
297 
298 typedef struct dmsg_iocom dmsg_iocom_t;
299 
300 #define DMSG_IOCOMF_EOF		0x00000001	/* EOF or ERROR on desc */
301 #define DMSG_IOCOMF_RREQ	0x00000002	/* request read-data event */
302 #define DMSG_IOCOMF_WREQ	0x00000004	/* request write-avail event */
303 #define DMSG_IOCOMF_RWORK	0x00000008	/* immediate work pending */
304 #define DMSG_IOCOMF_WWORK	0x00000010	/* immediate work pending */
305 #define DMSG_IOCOMF_PWORK	0x00000020	/* immediate work pending */
306 #define DMSG_IOCOMF_ARWORK	0x00000040	/* immediate work pending */
307 #define DMSG_IOCOMF_AWWORK	0x00000080	/* immediate work pending */
308 #define DMSG_IOCOMF_SWORK	0x00000100	/* immediate work pending */
309 #define DMSG_IOCOMF_CRYPTED	0x00000200	/* encrypt enabled */
310 #define DMSG_IOCOMF_CLOSEALT	0x00000400	/* close alt_fd */
311 
312 /*
313  * Crypto algorithm table and related typedefs.
314  */
315 typedef int (*algo_init_fn)(dmsg_ioq_t *, char *, int, char *, int, int);
316 typedef int (*algo_enc_fn)(dmsg_ioq_t *, char *, char *, int, int *);
317 typedef int (*algo_dec_fn)(dmsg_ioq_t *, char *, char *, int, int *);
318 
319 struct crypto_algo {
320 	const char	*name;
321 	int		keylen;
322 	int		taglen;
323 	algo_init_fn	init;
324 	algo_enc_fn	enc_chunk;
325 	algo_dec_fn	dec_chunk;
326 };
327 
328 /*
329  * Master service thread info
330  */
331 struct dmsg_master_service_info {
332 	int	fd;
333 	int	altfd;
334 	int	noclosealt;
335 	int	detachme;
336 	char	*label;
337 	void	*handle;
338 	void	(*dbgmsg_callback)(dmsg_msg_t *msg);
339 	void	(*exit_callback)(void *handle);
340 	void	(*altmsg_callback)(dmsg_iocom_t *);
341 };
342 
343 typedef struct dmsg_master_service_info dmsg_master_service_info_t;
344 
345 /*
346  * node callbacks
347  */
348 #define DMSG_NODEOP_ADD		1
349 #define DMSG_NODEOP_DEL		2
350 
351 extern void (*dmsg_node_handler)(void **opaquep, struct dmsg_msg *msg, int op);
352 
353 
354 /*
355  * icrc
356  */
357 uint32_t dmsg_icrc32(const void *buf, size_t size);
358 uint32_t dmsg_icrc32c(const void *buf, size_t size, uint32_t crc);
359 
360 /*
361  * debug
362  */
363 const char *dmsg_basecmd_str(uint32_t cmd);
364 const char *dmsg_msg_str(dmsg_msg_t *msg);
365 
366 /*
367  * subs
368  */
369 void *dmsg_alloc(size_t bytes);
370 void dmsg_free(void *ptr);
371 const char *dmsg_uuid_to_str(uuid_t *uuid, char **strp);
372 const char *dmsg_peer_type_to_str(uint8_t type);
373 const char *dmsg_pfs_type_to_str(uint8_t type);
374 int dmsg_connect(const char *hostname);
375 
376 /*
377  * Msg support functions
378  */
379 void dmsg_bswap_head(dmsg_hdr_t *head);
380 void dmsg_ioq_init(dmsg_iocom_t *iocom, dmsg_ioq_t *ioq);
381 void dmsg_ioq_done(dmsg_iocom_t *iocom, dmsg_ioq_t *ioq);
382 void dmsg_iocom_init(dmsg_iocom_t *iocom, int sock_fd, int alt_fd,
383 			void (*state_func)(dmsg_iocom_t *),
384 			void (*rcvmsg_func)(dmsg_msg_t *),
385 			void (*dbgmsg_func)(dmsg_msg_t *),
386 			void (*altmsg_func)(dmsg_iocom_t *));
387 void dmsg_iocom_restate(dmsg_iocom_t *iocom,
388 			void (*state_func)(dmsg_iocom_t *),
389 			void (*rcvmsg_func)(dmsg_msg_t *),
390 			void (*altmsg_func)(dmsg_iocom_t *));
391 void dmsg_iocom_label(dmsg_iocom_t *iocom, const char *ctl, ...);
392 void dmsg_iocom_signal(dmsg_iocom_t *iocom);
393 void dmsg_iocom_done(dmsg_iocom_t *iocom);
394 void dmsg_circuit_init(dmsg_iocom_t *iocom, dmsg_circuit_t *circuit);
395 dmsg_msg_t *dmsg_msg_alloc(dmsg_circuit_t *circuit,
396 			size_t aux_size, uint32_t cmd,
397 			void (*func)(dmsg_msg_t *), void *data);
398 void dmsg_msg_reply(dmsg_msg_t *msg, uint32_t error);
399 void dmsg_msg_result(dmsg_msg_t *msg, uint32_t error);
400 void dmsg_state_reply(dmsg_state_t *state, uint32_t error);
401 void dmsg_state_result(dmsg_state_t *state, uint32_t error);
402 
403 void dmsg_msg_free(dmsg_msg_t *msg);
404 
405 void dmsg_iocom_core(dmsg_iocom_t *iocom);
406 dmsg_msg_t *dmsg_ioq_read(dmsg_iocom_t *iocom);
407 void dmsg_msg_write(dmsg_msg_t *msg);
408 
409 void dmsg_iocom_drain(dmsg_iocom_t *iocom);
410 void dmsg_iocom_flush1(dmsg_iocom_t *iocom);
411 void dmsg_iocom_flush2(dmsg_iocom_t *iocom);
412 
413 void dmsg_state_cleanuprx(dmsg_iocom_t *iocom, dmsg_msg_t *msg);
414 void dmsg_state_free(dmsg_state_t *state);
415 void dmsg_circuit_hold(dmsg_circuit_t *circuit);
416 void dmsg_circuit_drop(dmsg_circuit_t *circuit);
417 void dmsg_circuit_drop_locked(dmsg_circuit_t *circuit);
418 
419 int dmsg_circuit_route(dmsg_msg_t *msg);
420 
421 /*
422  * Msg protocol functions
423  */
424 void dmsg_msg_lnk_signal(dmsg_iocom_t *iocom);
425 void dmsg_msg_lnk(dmsg_msg_t *msg);
426 void dmsg_msg_dbg(dmsg_msg_t *msg);
427 void dmsg_shell_tree(dmsg_circuit_t *circuit, char *cmdbuf __unused);
428 int dmsg_debug_findspan(uint64_t msgid, dmsg_state_t **statep);
429 
430 
431 /*
432  * Crypto functions
433  */
434 void dmsg_crypto_setup(void);
435 void dmsg_crypto_negotiate(dmsg_iocom_t *iocom);
436 void dmsg_crypto_decrypt(dmsg_iocom_t *iocom, dmsg_ioq_t *ioq);
437 int dmsg_crypto_encrypt(dmsg_iocom_t *iocom, dmsg_ioq_t *ioq,
438 			struct iovec *iov, int n, size_t *nactp);
439 
440 /*
441  * Service daemon functions
442  */
443 void *dmsg_master_service(void *data);
444 void dmsg_circuit_printf(dmsg_circuit_t *circuit, const char *ctl, ...)
445 	__printflike(2, 3);
446 
447 extern int DMsgDebugOpt;
448