xref: /dragonfly/lib/libdmsg/dmsg.h (revision a988b43e78629a379190205ccd368b35bf4fb239)
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 #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__)
63 
64 
65 /***************************************************************************
66  *                                      CRYPTO HANDSHAKE                           *
67  ***************************************************************************
68  *
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:
72  *
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
79  *     broken).
80  *
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.
83  *
84  * (3) Additional configuration and additional random data.
85  *
86  *     - The hammer2 message header magic for endian detect
87  *
88  *     - The hammer2 protocol version.  The two sides agree on the
89  *         smaller of the two.
90  *
91  *     - All unused fields (junk*) are filled with random data.
92  *
93  * This structure must be exactly 512 bytes and expects to use 256-byte
94  * RSA keys.
95  */
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 */
107 };
108 
109 typedef struct dmsg_handshake dmsg_handshake_t;
110 
111 
112 #define DMSG_CRYPTO_CHUNK_SIZE                    DMSG_ALIGN
113 #define DMSG_MAX_IV_SIZE                32
114 
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 
119 #define DMSG_CRYPTO_ALGO_GCM_IDX        0
120 
121 #define DMSG_CRYPTO_ALGO                DMSG_CRYPTO_ALGO_GCM_IDX
122 
123 /***************************************************************************
124  *                                      LOW LEVEL MESSAGING                        *
125  ***************************************************************************
126  *
127  * dmsg_msg - A standalone copy of a message, typically referenced by
128  *                   or embedded in other structures, or used with I/O queues.
129  *
130  * These structures are strictly temporary, so they do not have to be
131  * particularly optimized for size.  All possible message headers are
132  * directly embedded (any), and the message may contain a reference
133  * to allocated auxillary data.  The structure is recycled quite often
134  * by a connection.
135  */
136 struct dmsg_iocom;
137 struct dmsg_state;
138 struct dmsg_msg;
139 
140 TAILQ_HEAD(dmsg_state_queue, dmsg_state);
141 TAILQ_HEAD(dmsg_msg_queue, dmsg_msg);
142 RB_HEAD(dmsg_state_tree, dmsg_state);
143 
144 struct h2span_link;
145 struct h2span_relay;
146 struct h2span_conn;
147 
148 /*
149  * This represents a media, managed by LNK_CONN connection state
150  */
151 TAILQ_HEAD(dmsg_media_queue, dmsg_media);
152 
153 struct dmsg_media {
154           TAILQ_ENTRY(dmsg_media) entry;
155           uuid_t  media_id;
156           int     refs;
157           void      *usrhandle;
158 };
159 
160 typedef struct dmsg_media dmsg_media_t;
161 
162 /*
163  * The state structure is ref-counted.  The iocom cannot go away while
164  * state structures are active.  However, the related h2span_* linkages
165  * can be destroyed and NULL'd out if the state is terminated in both
166  * directions.
167  */
168 struct dmsg_state {
169           RB_ENTRY(dmsg_state) rbnode;            /* by state->msgid */
170           struct dmsg_state   *scan;              /* scan check */
171           TAILQ_HEAD(, dmsg_state) subq;                    /* active stacked states */
172           TAILQ_ENTRY(dmsg_state) entry;                    /* on parent subq */
173           struct dmsg_iocom *iocom;
174           struct dmsg_state *parent;              /* transaction stacking */
175           struct dmsg_state *relay;               /* routing */
176           uint32_t  icmd;                         /* command creating state */
177           uint32_t  txcmd;                        /* mostly for CMDF flags */
178           uint32_t  rxcmd;                        /* mostly for CMDF flags */
179           uint64_t  msgid;
180           int                 flags;
181           int                 error;
182           unsigned int        refs;                         /* prevent destruction */
183           void (*func)(struct dmsg_msg *);
184           union {
185                     void *any;
186                     struct h2span_link *link;
187                     struct h2span_conn *conn;
188                     struct h2span_relay *relay;
189           } any;
190           dmsg_media_t        *media;
191 };
192 
193 #define DMSG_STATE_SUBINSERTED          0x0001
194 #define DMSG_STATE_DYNAMIC    0x0002
195 #define DMSG_STATE_UNUSED0004 0x0004
196 #define DMSG_STATE_ABORTING   0x0008
197 #define DMSG_STATE_OPPOSITE   0x0010              /* initiated by other end */
198 #define DMSG_STATE_CIRCUIT    0x0020              /* LNK_SPAN special case */
199 #define DMSG_STATE_DYING      0x0040              /* indicates circuit failure */
200 #define DMSG_STATE_RBINSERTED 0x0080
201 #define DMSG_STATE_NEW                  0x0400              /* defer abort processing */
202 #define DMSG_STATE_ROOT                 0x8000              /* iocom->state0 */
203 
204 /*
205  * This is the core in-memory representation of a message structure.
206  * state is the local representation of the transactional state and
207  * will point to &iocom->state0 for non-transactional messages.
208  *
209  * Message headers are embedded while auxillary data is separately allocated.
210  * The 'any' portion of the message is allocated dynamically based on
211  * hdr_size.
212  */
213 struct dmsg_msg {
214           TAILQ_ENTRY(dmsg_msg) qentry;
215           struct dmsg_state *state;               /* message state */
216           size_t              hdr_size;
217           size_t              aux_size;
218           char                *aux_data;
219           uint32_t  tcmd;                         /* easy-switch cmd */
220           dmsg_any_t          any;                          /* must be last element */
221 };
222 
223 typedef struct dmsg_state dmsg_state_t;
224 typedef struct dmsg_msg dmsg_msg_t;
225 typedef struct dmsg_msg_queue dmsg_msg_queue_t;
226 
227 int dmsg_state_cmp(dmsg_state_t *state1, dmsg_state_t *state2);
228 RB_PROTOTYPE(dmsg_state_tree, dmsg_state, rbnode, dmsg_state_cmp);
229 
230 /*
231  * dmsg_ioq - An embedded component of dmsg_conn, holds state
232  * for the buffering and parsing of incoming and outgoing messages.
233  *
234  * cdx - beg  - processed buffer data, encrypted or decrypted
235  * end - cdn  - unprocessed buffer data not yet encrypted or decrypted
236  */
237 struct dmsg_ioq {
238           enum { DMSG_MSGQ_STATE_HEADER1,
239                  DMSG_MSGQ_STATE_HEADER2,
240                  DMSG_MSGQ_STATE_AUXDATA1,
241                  DMSG_MSGQ_STATE_AUXDATA2,
242                  DMSG_MSGQ_STATE_ERROR } state;
243           size_t              fifo_beg;           /* buffered data */
244           size_t              fifo_cdx;           /* cdx-beg processed */
245           size_t              fifo_cdn;           /* end-cdn unprocessed */
246           size_t              fifo_end;
247           size_t              hbytes;                       /* header size */
248           size_t              abytes;                       /* aligned aux_data size */
249           size_t              unaligned_aux_size; /* actual aux_data size */
250           int                 error;
251           int                 seq;                          /* salt sequencer */
252           int                 msgcount;
253           EVP_CIPHER_CTX      *ctx;
254           char                iv[DMSG_MAX_IV_SIZE]; /* encrypt or decrypt iv[] */
255           dmsg_msg_t          *msg;
256           dmsg_msg_queue_t msgq;
257           char                buf[DMSG_BUF_SIZE]; /* staging buffer */
258 };
259 
260 typedef struct dmsg_ioq dmsg_ioq_t;
261 
262 #define DMSG_IOQ_ERROR_SYNC             1         /* bad magic / out of sync */
263 #define DMSG_IOQ_ERROR_EOF              2         /* unexpected EOF */
264 #define DMSG_IOQ_ERROR_SOCK             3         /* read() error on socket */
265 #define DMSG_IOQ_ERROR_FIELD            4         /* invalid field */
266 #define DMSG_IOQ_ERROR_HCRC             5         /* core header crc bad */
267 #define DMSG_IOQ_ERROR_XCRC             6         /* ext header crc bad */
268 #define DMSG_IOQ_ERROR_ACRC             7         /* aux data crc bad */
269 #define DMSG_IOQ_ERROR_STATE            8         /* bad state */
270 #define DMSG_IOQ_ERROR_NOPEER           9         /* bad socket peer */
271 #define DMSG_IOQ_ERROR_NORKEY           10        /* no remote keyfile found */
272 #define DMSG_IOQ_ERROR_NOLKEY           11        /* no local keyfile found */
273 #define DMSG_IOQ_ERROR_KEYXCHGFAIL      12        /* key exchange failed */
274 #define DMSG_IOQ_ERROR_KEYFMT           13        /* key file format problem */
275 #define DMSG_IOQ_ERROR_BADURANDOM       14        /* /dev/urandom is bad */
276 #define DMSG_IOQ_ERROR_MSGSEQ           15        /* message sequence error */
277 #define DMSG_IOQ_ERROR_EALREADY                   16        /* ignore this message */
278 #define DMSG_IOQ_ERROR_TRANS            17        /* state transaction issue */
279 #define DMSG_IOQ_ERROR_IVWRAP           18        /* IVs exhaused */
280 #define DMSG_IOQ_ERROR_MACFAIL                    19        /* MAC of encr alg failed */
281 #define DMSG_IOQ_ERROR_ALGO             20        /* Misc. encr alg error */
282 #define DMSG_IOQ_ERROR_UNUSED21                   21
283 #define DMSG_IOQ_ERROR_BAD_CIRCUIT      22        /* unconfigured circuit */
284 #define DMSG_IOQ_ERROR_UNUSED23                   23
285 #define DMSG_IOQ_ERROR_ASSYM            24        /* Assymetric path */
286 
287 #define DMSG_IOQ_MAXIOVEC    16
288 
289 /*
290  * dmsg_iocom - governs a messaging stream connection
291  */
292 struct dmsg_iocom {
293           char                *label;                       /* label for error reporting */
294           dmsg_ioq_t          ioq_rx;
295           dmsg_ioq_t          ioq_tx;
296           dmsg_state_t        state0;                       /* root state for stacking */
297           struct dmsg_state_tree  staterd_tree;   /* active transactions */
298           struct dmsg_state_tree  statewr_tree;   /* active transactions */
299           int       sock_fd;                      /* comm socket or pipe */
300           int       alt_fd;                                 /* thread signal, tty, etc */
301           int       wakeupfds[2];                           /* pipe wakes up iocom thread */
302           unsigned int        flags;
303           int       rxmisc;
304           int       txmisc;
305           void      (*signal_callback)(struct dmsg_iocom *);
306           void      (*altmsg_callback)(struct dmsg_iocom *);
307           void      (*rcvmsg_callback)(dmsg_msg_t *msg);
308           void      (*usrmsg_callback)(dmsg_msg_t *msg, int unmanaged);
309           dmsg_msg_queue_t txmsgq;                /* tx msgq from remote */
310           struct h2span_conn *conn;               /* if LNK_CONN active */
311           uint64_t  conn_msgid;                   /* LNK_CONN circuit */
312           pthread_mutex_t     mtx;                          /* mutex for state*tree/rmsgq */
313 };
314 
315 typedef struct dmsg_iocom dmsg_iocom_t;
316 
317 #define DMSG_IOCOMF_EOF                 0x00000001          /* EOF or ERROR on desc */
318 #define DMSG_IOCOMF_RREQ      0x00000002          /* request read-data event */
319 #define DMSG_IOCOMF_WREQ      0x00000004          /* request write-avail event */
320 #define DMSG_IOCOMF_RWORK     0x00000008          /* immediate work pending */
321 #define DMSG_IOCOMF_WWORK     0x00000010          /* immediate work pending */
322 #define DMSG_IOCOMF_PWORK     0x00000020          /* immediate work pending */
323 #define DMSG_IOCOMF_ARWORK    0x00000040          /* immediate work pending */
324 #define DMSG_IOCOMF_AWWORK    0x00000080          /* immediate work pending */
325 #define DMSG_IOCOMF_SWORK     0x00000100          /* immediate work pending */
326 #define DMSG_IOCOMF_CRYPTED   0x00000200          /* encrypt enabled */
327 #define DMSG_IOCOMF_CLOSEALT  0x00000400          /* close alt_fd */
328 
329 /*
330  * Crypto algorithm table and related typedefs.
331  */
332 typedef int (*algo_init_fn)(dmsg_ioq_t *, char *, int, char *, int, int);
333 typedef void (*algo_uninit_fn)(dmsg_ioq_t *);
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 *);
336 
337 struct crypto_algo {
338           const char          *name;
339           int                 keylen;
340           int                 unused01;
341           algo_init_fn        init;
342           algo_uninit_fn      uninit;
343           algo_enc_fn         enc_chunk;
344           algo_dec_fn         dec_chunk;
345 };
346 
347 /*
348  * Master service thread info
349  */
350 struct dmsg_master_service_info {
351           int       fd;
352           int       altfd;
353           int       noclosealt;
354           int       detachme;
355           char      *label;
356           void      *handle;
357           void      (*altmsg_callback)(dmsg_iocom_t *iocom);
358           void      (*usrmsg_callback)(dmsg_msg_t *msg, int unmanaged);
359           void      (*exit_callback)(void *handle);
360 };
361 
362 typedef struct dmsg_master_service_info dmsg_master_service_info_t;
363 
364 struct iovec;       /* forward decl for dmsg_crypto_encrypt() prototype */
365 
366 /*
367  * node callbacks
368  */
369 #define DMSG_NODEOP_ADD                 1
370 #define DMSG_NODEOP_DEL                 2
371 
372 /*
373  * icrc
374  */
375 #define dmsg_icrc32(buf, size)                    iscsi_crc32((buf), (size))
376 #define dmsg_icrc32c(buf, size, crc)    iscsi_crc32_ext((buf), (size), (crc))
377 
378 /*
379  * debug
380  */
381 const char *dmsg_basecmd_str(uint32_t cmd);
382 const char *dmsg_msg_str(dmsg_msg_t *msg);
383 
384 /*
385  * subs
386  */
387 void *dmsg_alloc(size_t bytes);
388 void dmsg_free(void *ptr);
389 const char *dmsg_uuid_to_str(uuid_t *uuid, char **strp);
390 const char *dmsg_peer_type_to_str(uint8_t type);
391 int dmsg_connect(const char *hostname);
392 
393 /*
394  * Msg support functions
395  */
396 void dmsg_bswap_head(dmsg_hdr_t *head);
397 void dmsg_ioq_init(dmsg_iocom_t *iocom, dmsg_ioq_t *ioq);
398 void dmsg_ioq_done(dmsg_iocom_t *iocom, dmsg_ioq_t *ioq);
399 void dmsg_iocom_init(dmsg_iocom_t *iocom, int sock_fd, int alt_fd,
400                               void (*state_func)(dmsg_iocom_t *iocom),
401                               void (*rcvmsg_func)(dmsg_msg_t *msg),
402                               void (*usrmsg_func)(dmsg_msg_t *msg, int unmanaged),
403                               void (*altmsg_func)(dmsg_iocom_t *iocom));
404 void dmsg_iocom_restate(dmsg_iocom_t *iocom,
405                               void (*state_func)(dmsg_iocom_t *iocom),
406                               void (*rcvmsg_func)(dmsg_msg_t *msg));
407 void dmsg_iocom_label(dmsg_iocom_t *iocom, const char *ctl, ...);
408 void dmsg_iocom_signal(dmsg_iocom_t *iocom);
409 void dmsg_iocom_done(dmsg_iocom_t *iocom);
410 dmsg_msg_t *dmsg_msg_alloc(dmsg_state_t *state, size_t aux_size,
411                               uint32_t cmd,
412                               void (*func)(dmsg_msg_t *), void *data);
413 dmsg_msg_t *dmsg_msg_alloc_locked(dmsg_state_t *state, size_t aux_size,
414                               uint32_t cmd,
415                               void (*func)(dmsg_msg_t *), void *data);
416 void dmsg_msg_reply(dmsg_msg_t *msg, uint32_t error);
417 void dmsg_msg_result(dmsg_msg_t *msg, uint32_t error);
418 void dmsg_state_reply(dmsg_state_t *state, uint32_t error);
419 void dmsg_state_result(dmsg_state_t *state, uint32_t error);
420 
421 void dmsg_msg_free(dmsg_msg_t *msg);
422 
423 void dmsg_iocom_core(dmsg_iocom_t *iocom);
424 dmsg_msg_t *dmsg_ioq_read(dmsg_iocom_t *iocom);
425 void dmsg_msg_write(dmsg_msg_t *msg);
426 
427 void dmsg_iocom_drain(dmsg_iocom_t *iocom);
428 void dmsg_iocom_flush1(dmsg_iocom_t *iocom);
429 void dmsg_iocom_flush2(dmsg_iocom_t *iocom);
430 
431 void dmsg_state_relay(dmsg_msg_t *msg);
432 void dmsg_state_cleanuprx(dmsg_iocom_t *iocom, dmsg_msg_t *msg);
433 void dmsg_state_hold(dmsg_state_t *state);
434 void dmsg_state_drop(dmsg_state_t *state);
435 
436 /*
437  * Msg protocol functions
438  */
439 void dmsg_msg_lnk_signal(dmsg_iocom_t *iocom);
440 void dmsg_msg_lnk(dmsg_msg_t *msg);
441 void dmsg_msg_dbg(dmsg_msg_t *msg);
442 void dmsg_shell_tree(dmsg_iocom_t *iocom, char *cmdbuf __unused);
443 int dmsg_debug_findspan(uint64_t msgid, dmsg_state_t **statep);
444 dmsg_state_t *dmsg_findspan(const char *label);
445 
446 
447 /*
448  * Crypto functions
449  */
450 void dmsg_crypto_setup(void);
451 void dmsg_crypto_negotiate(dmsg_iocom_t *iocom);
452 void dmsg_crypto_terminate(dmsg_iocom_t *iocom);
453 void dmsg_crypto_decrypt(dmsg_iocom_t *iocom, dmsg_ioq_t *ioq);
454 int dmsg_crypto_encrypt(dmsg_iocom_t *iocom, dmsg_ioq_t *ioq,
455                               struct iovec *iov, int n, size_t *nactp);
456 
457 /*
458  * Service daemon functions
459  */
460 void *dmsg_master_service(void *data);
461 void dmsg_printf(dmsg_iocom_t *iocom, const char *ctl, ...) __printflike(2, 3);
462 
463 extern int DMsgDebugOpt;
464