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 #define dm_printf(level, ctl, ...) \
55 if (DMsgDebugOpt >= (level)) \
56 fprintf(stderr, "libdmsg: " ctl, __VA_ARGS__)
57 #define dmx_printf(level, ctl, ...) \
58 if (DMsgDebugOpt >= (level)) \
59 fprintf(stderr, ctl, __VA_ARGS__)
60 #define dmio_printf(iocom, level, ctl, ...) \
61 if (DMsgDebugOpt >= (level)) \
62 fprintf(stderr, "libdmsg: " ctl, __VA_ARGS__)
65 /***************************************************************************
67 ***************************************************************************
69 * The initial public-key exchange is implementing by transmitting a
70 * 512-byte buffer to the other side in a symmetrical fashion. This
71 * buffer contains the following:
73 * (1) A random session key. 512 bits is specified. We use aes_256_cbc()
74 * and initialize the key with the first 256 bits and the iv[] with
75 * the second. Note that the transmitted and received session
76 * keys are XOR'd together to create the session key used for
77 * communications (so even if the verifier is compromised the session
78 * will still be gobbly gook if the public key has not been completely
81 * (2) A verifier to determine that the decode was successful. It encodes
82 * an XOR of each group of 4 bytes from the session key.
84 * (3) Additional configuration and additional random data.
86 * - The hammer2 message header magic for endian detect
88 * - The hammer2 protocol version. The two sides agree on the
91 * - All unused fields (junk*) are filled with random data.
93 * This structure must be exactly 512 bytes and expects to use 256-byte
96 struct dmsg_handshake
{
97 char pad1
[8]; /* 000 */
98 uint16_t magic
; /* 008 DMSG_HDR_MAGIC for endian detect */
99 uint16_t version
; /* 00A hammer2 protocol version */
100 uint32_t flags
; /* 00C protocol extension flags */
101 uint8_t sess
[64]; /* 010 512-bit session key */
102 uint8_t verf
[16]; /* 050 verifier = ~sess */
103 char quickmsg
[32]; /* 060 reason for connecting */
104 char junk080
[128]; /* 080-0FF */
105 char pad2
[8]; /* 100-107 */
106 char junk100
[256-8]; /* 108-1FF */
109 typedef struct dmsg_handshake dmsg_handshake_t
;
112 #define DMSG_CRYPTO_CHUNK_SIZE DMSG_ALIGN
113 #define DMSG_MAX_IV_SIZE 32
115 #define DMSG_CRYPTO_GCM_IV_FIXED_SIZE 4
116 #define DMSG_CRYPTO_GCM_IV_SIZE 12
117 #define DMSG_CRYPTO_GCM_KEY_SIZE 32
118 #define DMSG_CRYPTO_GCM_TAG_SIZE 16
120 #define DMSG_CRYPTO_ALGO_GCM_IDX 0
122 #define DMSG_CRYPTO_ALGO DMSG_CRYPTO_ALGO_GCM_IDX
124 /***************************************************************************
125 * LOW LEVEL MESSAGING *
126 ***************************************************************************
128 * dmsg_msg - A standalone copy of a message, typically referenced by
129 * or embedded in other structures, or used with I/O queues.
131 * These structures are strictly temporary, so they do not have to be
132 * particularly optimized for size. All possible message headers are
133 * directly embedded (any), and the message may contain a reference
134 * to allocated auxillary data. The structure is recycled quite often
141 TAILQ_HEAD(dmsg_state_queue
, dmsg_state
);
142 TAILQ_HEAD(dmsg_msg_queue
, dmsg_msg
);
143 RB_HEAD(dmsg_state_tree
, dmsg_state
);
150 * This represents a media, managed by LNK_CONN connection state
152 TAILQ_HEAD(dmsg_media_queue
, dmsg_media
);
155 TAILQ_ENTRY(dmsg_media
) entry
;
161 typedef struct dmsg_media dmsg_media_t
;
164 * The state structure is ref-counted. The iocom cannot go away while
165 * state structures are active. However, the related h2span_* linkages
166 * can be destroyed and NULL'd out if the state is terminated in both
170 RB_ENTRY(dmsg_state
) rbnode
; /* by state->msgid */
171 struct dmsg_state
*scan
; /* scan check */
172 TAILQ_HEAD(, dmsg_state
) subq
; /* active stacked states */
173 TAILQ_ENTRY(dmsg_state
) entry
; /* on parent subq */
174 struct dmsg_iocom
*iocom
;
175 struct dmsg_state
*parent
; /* transaction stacking */
176 struct dmsg_state
*relay
; /* routing */
177 uint32_t icmd
; /* command creating state */
178 uint32_t txcmd
; /* mostly for CMDF flags */
179 uint32_t rxcmd
; /* mostly for CMDF flags */
183 int refs
; /* prevent destruction */
184 void (*func
)(struct dmsg_msg
*);
187 struct h2span_link
*link
;
188 struct h2span_conn
*conn
;
189 struct h2span_relay
*relay
;
194 #define DMSG_STATE_SUBINSERTED 0x0001
195 #define DMSG_STATE_DYNAMIC 0x0002
196 #define DMSG_STATE_UNUSED0004 0x0004
197 #define DMSG_STATE_ABORTING 0x0008
198 #define DMSG_STATE_OPPOSITE 0x0010 /* initiated by other end */
199 #define DMSG_STATE_CIRCUIT 0x0020 /* LNK_SPAN special case */
200 #define DMSG_STATE_DYING 0x0040 /* indicates circuit failure */
201 #define DMSG_STATE_RBINSERTED 0x0080
202 #define DMSG_STATE_NEW 0x0400 /* defer abort processing */
203 #define DMSG_STATE_ROOT 0x8000 /* iocom->state0 */
206 * This is the core in-memory representation of a message structure.
207 * state is the local representation of the transactional state and
208 * will point to &iocom->state0 for non-transactional messages.
210 * Message headers are embedded while auxillary data is separately allocated.
211 * The 'any' portion of the message is allocated dynamically based on
215 TAILQ_ENTRY(dmsg_msg
) qentry
;
216 struct dmsg_state
*state
; /* message state */
220 uint32_t tcmd
; /* easy-switch cmd */
221 dmsg_any_t any
; /* must be last element */
224 typedef struct dmsg_state dmsg_state_t
;
225 typedef struct dmsg_msg dmsg_msg_t
;
226 typedef struct dmsg_msg_queue dmsg_msg_queue_t
;
228 int dmsg_state_cmp(dmsg_state_t
*state1
, dmsg_state_t
*state2
);
229 RB_PROTOTYPE(dmsg_state_tree
, dmsg_state
, rbnode
, dmsg_state_cmp
);
232 * dmsg_ioq - An embedded component of dmsg_conn, holds state
233 * for the buffering and parsing of incoming and outgoing messages.
235 * cdx - beg - processed buffer data, encrypted or decrypted
236 * end - cdn - unprocessed buffer data not yet encrypted or decrypted
239 enum { DMSG_MSGQ_STATE_HEADER1
,
240 DMSG_MSGQ_STATE_HEADER2
,
241 DMSG_MSGQ_STATE_AUXDATA1
,
242 DMSG_MSGQ_STATE_AUXDATA2
,
243 DMSG_MSGQ_STATE_ERROR
} state
;
244 size_t fifo_beg
; /* buffered data */
245 size_t fifo_cdx
; /* cdx-beg processed */
246 size_t fifo_cdn
; /* end-cdn unprocessed */
248 size_t hbytes
; /* header size */
249 size_t abytes
; /* aligned aux_data size */
250 size_t unaligned_aux_size
; /* actual aux_data size */
252 int seq
; /* salt sequencer */
255 char iv
[DMSG_MAX_IV_SIZE
]; /* encrypt or decrypt iv[] */
257 dmsg_msg_queue_t msgq
;
258 char buf
[DMSG_BUF_SIZE
]; /* staging buffer */
261 typedef struct dmsg_ioq dmsg_ioq_t
;
263 #define DMSG_IOQ_ERROR_SYNC 1 /* bad magic / out of sync */
264 #define DMSG_IOQ_ERROR_EOF 2 /* unexpected EOF */
265 #define DMSG_IOQ_ERROR_SOCK 3 /* read() error on socket */
266 #define DMSG_IOQ_ERROR_FIELD 4 /* invalid field */
267 #define DMSG_IOQ_ERROR_HCRC 5 /* core header crc bad */
268 #define DMSG_IOQ_ERROR_XCRC 6 /* ext header crc bad */
269 #define DMSG_IOQ_ERROR_ACRC 7 /* aux data crc bad */
270 #define DMSG_IOQ_ERROR_STATE 8 /* bad state */
271 #define DMSG_IOQ_ERROR_NOPEER 9 /* bad socket peer */
272 #define DMSG_IOQ_ERROR_NORKEY 10 /* no remote keyfile found */
273 #define DMSG_IOQ_ERROR_NOLKEY 11 /* no local keyfile found */
274 #define DMSG_IOQ_ERROR_KEYXCHGFAIL 12 /* key exchange failed */
275 #define DMSG_IOQ_ERROR_KEYFMT 13 /* key file format problem */
276 #define DMSG_IOQ_ERROR_BADURANDOM 14 /* /dev/urandom is bad */
277 #define DMSG_IOQ_ERROR_MSGSEQ 15 /* message sequence error */
278 #define DMSG_IOQ_ERROR_EALREADY 16 /* ignore this message */
279 #define DMSG_IOQ_ERROR_TRANS 17 /* state transaction issue */
280 #define DMSG_IOQ_ERROR_IVWRAP 18 /* IVs exhaused */
281 #define DMSG_IOQ_ERROR_MACFAIL 19 /* MAC of encr alg failed */
282 #define DMSG_IOQ_ERROR_ALGO 20 /* Misc. encr alg error */
283 #define DMSG_IOQ_ERROR_UNUSED21 21
284 #define DMSG_IOQ_ERROR_BAD_CIRCUIT 22 /* unconfigured circuit */
285 #define DMSG_IOQ_ERROR_UNUSED23 23
286 #define DMSG_IOQ_ERROR_ASSYM 24 /* Assymetric path */
288 #define DMSG_IOQ_MAXIOVEC 16
291 * dmsg_iocom - governs a messaging stream connection
294 char *label
; /* label for error reporting */
297 dmsg_state_t state0
; /* root state for stacking */
298 struct dmsg_state_tree staterd_tree
; /* active transactions */
299 struct dmsg_state_tree statewr_tree
; /* active transactions */
300 int sock_fd
; /* comm socket or pipe */
301 int alt_fd
; /* thread signal, tty, etc */
302 int wakeupfds
[2]; /* pipe wakes up iocom thread */
306 void (*signal_callback
)(struct dmsg_iocom
*);
307 void (*altmsg_callback
)(struct dmsg_iocom
*);
308 void (*rcvmsg_callback
)(dmsg_msg_t
*msg
);
309 void (*usrmsg_callback
)(dmsg_msg_t
*msg
, int unmanaged
);
310 dmsg_msg_queue_t txmsgq
; /* tx msgq from remote */
311 struct h2span_conn
*conn
; /* if LNK_CONN active */
312 uint64_t conn_msgid
; /* LNK_CONN circuit */
313 pthread_mutex_t mtx
; /* mutex for state*tree/rmsgq */
316 typedef struct dmsg_iocom dmsg_iocom_t
;
318 #define DMSG_IOCOMF_EOF 0x00000001 /* EOF or ERROR on desc */
319 #define DMSG_IOCOMF_RREQ 0x00000002 /* request read-data event */
320 #define DMSG_IOCOMF_WREQ 0x00000004 /* request write-avail event */
321 #define DMSG_IOCOMF_RWORK 0x00000008 /* immediate work pending */
322 #define DMSG_IOCOMF_WWORK 0x00000010 /* immediate work pending */
323 #define DMSG_IOCOMF_PWORK 0x00000020 /* immediate work pending */
324 #define DMSG_IOCOMF_ARWORK 0x00000040 /* immediate work pending */
325 #define DMSG_IOCOMF_AWWORK 0x00000080 /* immediate work pending */
326 #define DMSG_IOCOMF_SWORK 0x00000100 /* immediate work pending */
327 #define DMSG_IOCOMF_CRYPTED 0x00000200 /* encrypt enabled */
328 #define DMSG_IOCOMF_CLOSEALT 0x00000400 /* close alt_fd */
331 * Crypto algorithm table and related typedefs.
333 typedef int (*algo_init_fn
)(dmsg_ioq_t
*, char *, int, char *, int, int);
334 typedef int (*algo_enc_fn
)(dmsg_ioq_t
*, char *, char *, int, int *);
335 typedef int (*algo_dec_fn
)(dmsg_ioq_t
*, char *, char *, int, int *);
342 algo_enc_fn enc_chunk
;
343 algo_dec_fn dec_chunk
;
347 * Master service thread info
349 struct dmsg_master_service_info
{
356 void (*altmsg_callback
)(dmsg_iocom_t
*iocom
);
357 void (*usrmsg_callback
)(dmsg_msg_t
*msg
, int unmanaged
);
358 void (*exit_callback
)(void *handle
);
361 typedef struct dmsg_master_service_info dmsg_master_service_info_t
;
366 #define DMSG_NODEOP_ADD 1
367 #define DMSG_NODEOP_DEL 2
372 uint32_t dmsg_icrc32(const void *buf
, size_t size
);
373 uint32_t dmsg_icrc32c(const void *buf
, size_t size
, uint32_t crc
);
378 const char *dmsg_basecmd_str(uint32_t cmd
);
379 const char *dmsg_msg_str(dmsg_msg_t
*msg
);
384 void *dmsg_alloc(size_t bytes
);
385 void dmsg_free(void *ptr
);
386 const char *dmsg_uuid_to_str(uuid_t
*uuid
, char **strp
);
387 const char *dmsg_peer_type_to_str(uint8_t type
);
388 int dmsg_connect(const char *hostname
);
391 * Msg support functions
393 void dmsg_bswap_head(dmsg_hdr_t
*head
);
394 void dmsg_ioq_init(dmsg_iocom_t
*iocom
, dmsg_ioq_t
*ioq
);
395 void dmsg_ioq_done(dmsg_iocom_t
*iocom
, dmsg_ioq_t
*ioq
);
396 void dmsg_iocom_init(dmsg_iocom_t
*iocom
, int sock_fd
, int alt_fd
,
397 void (*state_func
)(dmsg_iocom_t
*iocom
),
398 void (*rcvmsg_func
)(dmsg_msg_t
*msg
),
399 void (*usrmsg_func
)(dmsg_msg_t
*msg
, int unmanaged
),
400 void (*altmsg_func
)(dmsg_iocom_t
*iocom
));
401 void dmsg_iocom_restate(dmsg_iocom_t
*iocom
,
402 void (*state_func
)(dmsg_iocom_t
*iocom
),
403 void (*rcvmsg_func
)(dmsg_msg_t
*msg
));
404 void dmsg_iocom_label(dmsg_iocom_t
*iocom
, const char *ctl
, ...);
405 void dmsg_iocom_signal(dmsg_iocom_t
*iocom
);
406 void dmsg_iocom_done(dmsg_iocom_t
*iocom
);
407 dmsg_msg_t
*dmsg_msg_alloc(dmsg_state_t
*state
, size_t aux_size
,
409 void (*func
)(dmsg_msg_t
*), void *data
);
410 dmsg_msg_t
*dmsg_msg_alloc_locked(dmsg_state_t
*state
, size_t aux_size
,
412 void (*func
)(dmsg_msg_t
*), void *data
);
413 void dmsg_msg_reply(dmsg_msg_t
*msg
, uint32_t error
);
414 void dmsg_msg_result(dmsg_msg_t
*msg
, uint32_t error
);
415 void dmsg_state_reply(dmsg_state_t
*state
, uint32_t error
);
416 void dmsg_state_result(dmsg_state_t
*state
, uint32_t error
);
418 void dmsg_msg_free(dmsg_msg_t
*msg
);
420 void dmsg_iocom_core(dmsg_iocom_t
*iocom
);
421 dmsg_msg_t
*dmsg_ioq_read(dmsg_iocom_t
*iocom
);
422 void dmsg_msg_write(dmsg_msg_t
*msg
);
424 void dmsg_iocom_drain(dmsg_iocom_t
*iocom
);
425 void dmsg_iocom_flush1(dmsg_iocom_t
*iocom
);
426 void dmsg_iocom_flush2(dmsg_iocom_t
*iocom
);
428 void dmsg_state_relay(dmsg_msg_t
*msg
);
429 void dmsg_state_cleanuprx(dmsg_iocom_t
*iocom
, dmsg_msg_t
*msg
);
430 void dmsg_state_hold(dmsg_state_t
*state
);
431 void dmsg_state_drop(dmsg_state_t
*state
);
434 * Msg protocol functions
436 void dmsg_msg_lnk_signal(dmsg_iocom_t
*iocom
);
437 void dmsg_msg_lnk(dmsg_msg_t
*msg
);
438 void dmsg_msg_dbg(dmsg_msg_t
*msg
);
439 void dmsg_shell_tree(dmsg_iocom_t
*iocom
, char *cmdbuf __unused
);
440 int dmsg_debug_findspan(uint64_t msgid
, dmsg_state_t
**statep
);
441 dmsg_state_t
*dmsg_findspan(const char *label
);
447 void dmsg_crypto_setup(void);
448 void dmsg_crypto_negotiate(dmsg_iocom_t
*iocom
);
449 void dmsg_crypto_decrypt(dmsg_iocom_t
*iocom
, dmsg_ioq_t
*ioq
);
450 int dmsg_crypto_encrypt(dmsg_iocom_t
*iocom
, dmsg_ioq_t
*ioq
,
451 struct iovec
*iov
, int n
, size_t *nactp
);
454 * Service daemon functions
456 void *dmsg_master_service(void *data
);
457 void dmsg_printf(dmsg_iocom_t
*iocom
, const char *ctl
, ...) __printflike(2, 3);
459 extern int DMsgDebugOpt
;