2 * Copyright (c) 2011-2012 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@dragonflybsd.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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
35 #include <sys/types.h>
36 #include <sys/queue.h>
43 #include <openssl/rsa.h> /* public/private key functions */
44 #include <openssl/pem.h> /* public/private key file load */
46 #include <openssl/err.h>
47 #include <openssl/evp.h> /* aes_256_cbc functions */
49 #define DMSG_DEFAULT_DIR "/etc/hammer2"
50 #define DMSG_PATH_REMOTE DMSG_DEFAULT_DIR "/remote"
52 #define DMSG_LISTEN_PORT 987
54 /***************************************************************************
56 ***************************************************************************
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:
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
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.
73 * (3) Additional configuration and additional random data.
75 * - The hammer2 message header magic for endian detect
77 * - The hammer2 protocol version. The two sides agree on the
80 * - All unused fields (junk*) are filled with random data.
82 * This structure must be exactly 512 bytes and expects to use 256-byte
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 */
98 typedef struct dmsg_handshake dmsg_handshake_t;
101 #define DMSG_CRYPTO_CHUNK_SIZE DMSG_ALIGN
102 #define DMSG_MAX_IV_SIZE 32
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
109 #define DMSG_CRYPTO_ALGO_GCM_IDX 0
111 #define DMSG_CRYPTO_ALGO DMSG_CRYPTO_ALGO_GCM_IDX
113 /***************************************************************************
114 * LOW LEVEL MESSAGING *
115 ***************************************************************************
117 * dmsg_msg - A standalone copy of a message, typically referenced by
118 * or embedded in other structures, or used with I/O queues.
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
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);
140 struct dmsg_circuit {
141 RB_ENTRY(dmsg_circuit) rbnode;
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 */
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
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 */
169 int refs; /* prevent destruction */
170 struct dmsg_msg *msg; /* msg creating orig state */
171 void (*func)(struct dmsg_msg *);
174 struct h2span_link *link;
175 struct h2span_conn *conn;
176 struct h2span_relay *relay;
177 struct dmsg_circuit *circ;
181 #define DMSG_STATE_INSERTED 0x0001
182 #define DMSG_STATE_DYNAMIC 0x0002
183 #define DMSG_STATE_NODEID 0x0004 /* manages a node id */
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.
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 */
200 dmsg_any_t any; /* must be last element */
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;
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);
214 * dmsg_ioq - An embedded component of dmsg_conn, holds state
215 * for the buffering and parsing of incoming and outgoing messages.
217 * cdx - beg - processed buffer data, encrypted or decrypted
218 * end - cdn - unprocessed buffer data not yet encrypted or decrypted
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 */
230 size_t hbytes; /* header size */
231 size_t abytes; /* aligned aux_data size */
232 size_t unaligned_aux_size; /* actual aux_data size */
234 int seq; /* salt sequencer */
237 char iv[DMSG_MAX_IV_SIZE]; /* encrypt or decrypt iv[] */
239 dmsg_msg_queue_t msgq;
240 char buf[DMSG_BUF_SIZE]; /* staging buffer */
243 typedef struct dmsg_ioq dmsg_ioq_t;
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 */
270 #define DMSG_IOQ_MAXIOVEC 16
273 * dmsg_iocom - governs a messaging stream connection
276 char *label; /* label for error reporting */
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 */
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 */
298 typedef struct dmsg_iocom dmsg_iocom_t;
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 */
313 * Crypto algorithm table and related typedefs.
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 *);
324 algo_enc_fn enc_chunk;
325 algo_dec_fn dec_chunk;
329 * Master service thread info
331 struct dmsg_master_service_info {
338 void (*dbgmsg_callback)(dmsg_msg_t *msg);
339 void (*exit_callback)(void *handle);
340 void (*altmsg_callback)(dmsg_iocom_t *);
343 typedef struct dmsg_master_service_info dmsg_master_service_info_t;
348 #define DMSG_NODEOP_ADD 1
349 #define DMSG_NODEOP_DEL 2
351 extern void (*dmsg_node_handler)(void **opaquep, struct dmsg_msg *msg, int op);
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);
363 const char *dmsg_basecmd_str(uint32_t cmd);
364 const char *dmsg_msg_str(dmsg_msg_t *msg);
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);
377 * Msg support functions
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);
403 void dmsg_msg_free(dmsg_msg_t *msg);
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);
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);
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);
419 int dmsg_circuit_route(dmsg_msg_t *msg);
422 * Msg protocol functions
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);
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);
441 * Service daemon functions
443 void *dmsg_master_service(void *data);
444 void dmsg_circuit_printf(dmsg_circuit_t *circuit, const char *ctl, ...)
447 extern int DMsgDebugOpt;