1 /*
2     Copyright (C) 2008-2017, Millistream Market Data <support@millistream.com>
3 
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the GNU Lesser General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU Lesser General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 
17 */
18 
19 #ifndef MDFCOMMON_H
20 # define MDFCOMMON_H 1
21 
22 # ifdef HAVE_CONFIG_H
23 #  include "../config.h"
24 # endif
25 # ifdef HAVE_STDLIB_H
26 #  include <stdlib.h>
27 # endif
28 # ifdef HAVE_UNISTD_H
29 #  include <unistd.h>
30 # endif
31 # include <stdio.h>
32 # ifdef HAVE_STDINT_H
33 #  include <stdint.h>
34 # elif _MSC_VER >= 1600
35 #  include <stdint.h>
36 #  define _STDINT_H 1 /* so we ignore the check in mdf.h */
37 # elif _MSC_VER
38 #  define uint8_t unsigned __int8
39 #  define uint16_t unsigned __int16
40 #  define uint32_t unsigned __int32
41 #  define uint64_t unsigned __int64
42 #  define int64_t __int64
43 #  define _STDINT_H 1 /* so we ignore the check in mdf.h */
44 # else
45 #  define uint8_t unsigned char
46 #  define uint16_t unsigned short
47 #  define uint32_t unsigned int
48 #  define uint64_t unsigned long long
49 #  define int64_t long long
50 #  define _STDINT_H 1 /* so we ignore the check in mdf.h */
51 # endif
52 
53 # ifdef HAVE_INTTYPES_H
54 #  include <inttypes.h>
55 # elif _MSC_VER
56 #  define PRIu64 "I64u"
57 # else
58 #  define PRIu64 "llu"
59 # endif
60 
61 # ifndef __UINT64_C
62 #  ifdef UINT64_C
63 #   define __UINT64_C(c) UINT64_C(c)
64 #  elif _MSC_VER
65 #   define __UINT64_C(c) c##ui64
66 #  else
67 #   define __UINT64_C(c) c##ULL
68 #  endif
69 # endif
70 
71 # ifndef HAVE_STRTOULL
72 #  if _MSC_VER >= 1300
73 #   define strtoull(a,b,c) _strtoui64(a,b,c)
74 #  elif HAVE_STRTOQ
75 #   define strtoull(a,b,c) strtoq(a,b,c)
76 #  else
77 #   define strtoull(a,b,c) strtoul(a,b,c)
78 #  endif
79 # endif
80 
81 # ifdef HAVE_STRING_H
82 #  include <string.h>
83 # endif
84 # ifdef HAVE_SYS_IOCTL_H
85 #  include <sys/ioctl.h>
86 # endif
87 # ifdef HAVE_SYS_FILIO_H
88 #  include <sys/filio.h>
89 # endif
90 # ifdef HAVE_SYS_TYPES_H
91 #  include <sys/types.h>
92 # endif
93 # ifdef HAVE_SYS_SOCKET_H
94 #  include <sys/socket.h>
95 # endif
96 # ifdef HAVE_SYS_UN_H
97 #  include <sys/un.h>
98 # endif
99 # ifdef HAVE_NETINET_IN_H
100 #  include <netinet/in.h>
101 # endif
102 # ifdef HAVE_NETINET_TCP_H
103 #  include <netinet/tcp.h>
104 # endif
105 # ifdef HAVE_NETDB_H
106 #  include <netdb.h>
107 # endif
108 # ifdef HAVE_FCNTL_H
109 #  include <fcntl.h>
110 # endif
111 # ifdef HAVE_ERRNO_H
112 #  include <errno.h>
113 # endif
114 # ifdef HAVE_SIGNAL_H
115 #  include <signal.h>
116 # endif
117 # ifdef HAVE_TIME_H
118 #  include <time.h>
119 # endif
120 # if defined _WIN32 || defined _WIN64
121 #  include <stddef.h>
122 #  include <time.h>
123 #  include <limits.h>
124 #  include <winsock2.h>
125 #  include <ws2tcpip.h>
126 #  define MSG_NOSIGNAL 0
127 # else
128 #  define INVALID_SOCKET -1
129 # endif
130 # include <ctype.h>
131 # include <stdarg.h>
132 # include <zlib.h>
133 # include <openssl/opensslv.h>
134 # include <openssl/objects.h>
135 # include <openssl/rand.h>
136 # include <openssl/bio.h>
137 # include <openssl/dh.h>
138 # include <openssl/rsa.h>
139 # include <openssl/hmac.h>
140 # include <openssl/pem.h>
141 # include <openssl/aes.h>
142 # if defined HAVE_OPENSSL_MD5_H && !defined OPENSSL_NO_MD5
143 #  include <openssl/md5.h>
144 # endif
145 # if defined HAVE_OPENSSL_SHA_H && !defined OPENSSL_NO_SHA
146 #  include <openssl/sha.h>
147 # endif
148 # if defined HAVE_OPENSSL_RIPEMD_H && !defined OPENSSL_NO_RIPEMD
149 #  include <openssl/ripemd.h>
150 # endif
151 # if defined HAVE_OPENSSL_WHRLPOOL_H && !defined OPENSSL_NO_WHIRLPOOL
152 #  include <openssl/whrlpool.h>
153 # endif
154 # include "mdf_byteswap.h"
155 # include "mdf.h"
156 # include "mdf_fields.h"
157 # include "version.h"
158 # if _MSC_VER >= 1300
159 #  define strdup(s) _strdup(s)
160 # endif
161 # ifndef SOL_TCP
162 #  define SOL_TCP IPPROTO_TCP
163 # endif
164 # ifndef SOCK_CLOEXEC
165 #  define SOCK_CLOEXEC 0
166 # endif
167 
168 # if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)
169 #  undef OPENSSL_VERSION_NUMBER
170 #  define OPENSSL_VERSION_NUMBER 0x1000107fL
171 # endif
172 
173 #define NELEMS(x) ((int)(sizeof x/sizeof x[0]))
174 #define MAX_RECORDLENGTH (64 * 1024 * 1024)
175 
176 #define CSTATE_ENCRYPT 1
177 #define CSTATE_DECRYPT 2
178 #define CSTATE_INVALID 4 /* prevents mdf_consume() and mdf_message_send() to do anything until the handshake is completed */
179 
180 struct msg_field {
181 	int pos;
182 	uint32_t tag;
183 };
184 
185 struct msg_template {
186 	int mclass;
187 	int tags_num;
188 	uint32_t *tags;
189 	struct msg_field *fields;
190 };
191 
192 struct callbacks {
193 	void *udata_data;
194 	void *udata_status;
195 	mdf_data_callback func_data;
196 	mdf_status_callback func_status;
197 };
198 
199 struct mdf_s {
200 	uint64_t insref;
201 	uint64_t bytes_read;
202 	uint64_t bytes_written;
203 	uint64_t template_version;
204 	uint8_t *data;
205 	uint8_t *value;
206 	uint8_t *master_secret;
207 	uint8_t *client_iv;
208 	uint8_t *server_iv;
209 	AES_KEY *client_enc;
210 	AES_KEY *server_enc;
211 	HMAC_CTX *client_hmac;
212 	HMAC_CTX *server_hmac;
213 	struct msg_template *templates;
214 	struct field **sendfields;
215 	struct field **sendtags;
216 	uint8_t *sendbuf;
217 	char *connected_host;
218 	char *connected_ip;
219 	struct callbacks callbacks;
220 	time_t time_lastupdate;
221 	size_t pos; /* points at the current pmap */
222 	size_t fpos; /* points at the current field */
223 	size_t vlen; /* length of value in bytes */
224 	size_t data_pos; /* current decoding position in the data buffer */
225 	size_t data_used; /* current read position in the data buffer */
226 	size_t data_size; /* total size of the data buffer */
227 	size_t message_len; /* the total message length including any message digest */
228 	size_t message_end; /* points to the last byte of the message (not including the digest) */
229 	int templates_num;
230 	int sendfields_num;
231 	unsigned int sendtags_num;
232 	int sendbuf_size;
233 	int in_pmap_pos; /* bit position in the current pmap, 128,96,64,32,16,8,4,1 */
234 	int field_pmap_pos; /* current field position */
235 	int fstatus;
236 	int connect_timeout;
237 	int heartbeats_sent;
238 	int heartbeat_interval;
239 	int max_missed_heartbeats;
240 	int cstate;
241 	int encryption_method;
242 	int digest_method;
243 	int digest_length;
244 	int tcp_nodelay;
245 	int no_encryption;
246 	int timediff;
247 	MDF_ERROR error;
248 # if defined _WIN32 || defined _WIN64
249 	SOCKET fd;
250 # else
251 	int fd;
252 # endif
253 	uint16_t msgref;
254 	uint8_t oldval; /* carries the byte that we zero out when reading messages */
255 };
256 
257 void mdf_int_send_rekey (mdf_t handle);
258 void mdf_int_encrypt_aes_ctr (uint8_t * restrict out, const size_t len, AES_KEY *key, uint8_t * restrict iv);
259 int mdf_int_decrypt_data (mdf_t handle, uint8_t *data, const uint32_t len, const int pos);
260 int mdf_int_send_heartbeat (mdf_t handle);
261 void mdf_int_rebalance_templates (struct msg_template * const templates, const int templates_num);
262 
263 #endif
264