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 #include <sys/select.h>
20 #include "common.h"
21 #include "encode.h"
22 #include "crypt.h"
23 
24 /* buf must be at least 5 bytes */
add_len(uint8_t * buf,uint32_t len)25 static int add_len (uint8_t *buf, uint32_t len)
26 {
27 	uint8_t *p = buf;
28 	uint32_t tmp = len;
29 	uint32_t offset = 0;
30 	int d;
31 	int c = 0;
32 
33 	do {
34 		++c;
35 		offset = offset * 128 + 1;
36 		tmp = (tmp - 1) / 128;
37 	} while (tmp != 0);
38 
39 	len -= offset;
40 	d = c - 1;
41 
42 	do {
43 		p[--c] = (uint8_t) (len % 128);
44 		len /= 128;
45 	} while (c != 0);
46 
47 	p += d;
48 
49 	*p++ |= 128;
50 
51 	return p - buf;
52 }
53 
54 /* buf must be at least 11 bytes */
add_header(uint8_t * buf,uint16_t mref,uint64_t insref)55 static int add_header (uint8_t *buf, uint16_t mref, uint64_t insref)
56 {
57 	uint8_t *p = buf;
58 	uint8_t *attr = buf;
59 
60 	if (mref <= 256) {
61 		*p++ = 0;
62 		*p++ = (uint8_t) mref;
63 	} else {
64 		*p++ = 128;
65 		*((uint16_t *)p) = cpu_to_le16 (mref);
66 		p += 2;
67 	}
68 
69 	if (insref <= 8191) {
70 		*attr |= (uint8_t) (insref >> 8);
71 		*p++ = (uint8_t) (insref & __UINT64_C (0x00000000000000FF));
72 	} else if (insref <= 2105343) {
73 		insref -= 8192;
74 		*attr |= 32 | (uint8_t) (insref >> 16);
75 		*((uint16_t *)p) = cpu_to_le16 ((uint16_t)(insref & __UINT64_C (0x000000000000FFFF)));
76 		p += 2;
77 	} else if (insref <= __UINT64_C (137441058815)) {
78 		insref -= 2105344;
79 		*attr |= 64 | (uint8_t) (insref >> 32);
80 		*((uint32_t *)p) = cpu_to_le32 ((uint32_t)(insref & __UINT64_C (0x00000000FFFFFFFF)));
81 		p += 4;
82 	} else {
83 		*attr |= 96;
84 		*((uint64_t *)p) = cpu_to_le64 (insref);
85 		p += 8;
86 	}
87 
88 	return p - buf;
89 }
90 
compare_tags(const void * A,const void * B)91 static int compare_tags (const void *A, const void *B)
92 {
93 	return (((const struct msg_field *)A)->tag - ((const struct msg_field *)B)->tag);
94 }
95 
mdf_int_rebalance_templates(struct msg_template * const templates,const int templates_num)96 void mdf_int_rebalance_templates (struct msg_template * const templates, const int templates_num)
97 {
98 	int i, j;
99 	for (i = 0; i < templates_num; i++) {
100 		free (templates[i].fields);
101 
102 		if (templates[i].tags_num == 0) {
103 			templates[i].fields = NULL;
104 			continue;
105 		}
106 
107 		templates[i].fields = (struct msg_field *) malloc ((sizeof *templates[i].fields) * templates[i].tags_num);
108 
109 		for (j = 0; j < templates[i].tags_num; j++) {
110 			templates[i].fields[j].pos = j;
111 			templates[i].fields[j].tag = templates[i].tags[j];
112 		}
113 
114 		qsort (templates[i].fields, templates[i].tags_num, sizeof *templates[i].fields, compare_tags);
115 	}
116 }
117 
mdf_create()118 mdf_t mdf_create ()
119 {
120 	struct mdf_s *handle;
121 #if defined (HAVE_SIGACTION) && defined (SIGPIPE)
122 	struct sigaction act;
123 #endif
124 #if defined _WIN32 || defined _WIN64
125 	WSADATA	wsaData;
126 
127 	if (WSAStartup (MAKEWORD (2,2), &wsaData) != 0)
128 		return NULL;
129 #endif
130 	handle = (struct mdf_s *) calloc (1, sizeof *handle);
131 
132 	if (handle == NULL) {
133 #if defined _WIN32 || defined _WIN64
134 		WSACleanup ();
135 #endif
136 		return NULL;
137 	}
138 
139 	handle->data_size = 10240;
140 	handle->data = (uint8_t *) malloc (handle->data_size);
141 	handle->timediff = 0;
142 	handle->vlen = 1024;
143 	handle->value = (uint8_t *) malloc (handle->vlen);
144 	handle->fstatus = 2;
145 	handle->error = MDF_ERR_NO_ERROR;
146 	handle->fd = INVALID_SOCKET;
147 	handle->connect_timeout = 5;
148 	handle->heartbeat_interval = 30;
149 	handle->max_missed_heartbeats = 2;
150 	handle->cstate = CSTATE_INVALID;
151 
152 	if (handle->data == NULL || handle->value == NULL) {
153 #if defined _WIN32 || defined _WIN64
154 		WSACleanup ();
155 #endif
156 		free (handle->data);
157 		handle->data = NULL;
158 
159 		free (handle->value);
160 		handle->value = NULL;
161 
162 		free (handle);
163 		return NULL;
164 	}
165 
166 	/* setup version #0 of the message templates, this is enough to
167 	 * be able to receive the message templates message, to create
168 	 * a logon message and to receive a possible logoff message */
169 	handle->templates_num = 3;
170 	handle->templates = (struct msg_template *) calloc (handle->templates_num, sizeof *handle->templates);
171 
172 	handle->templates[MDF_M_MESSAGESREFERENCE].mclass = MDF_MC_UNDEF;
173 	handle->templates[MDF_M_MESSAGESREFERENCE].tags_num = 1;
174 	handle->templates[MDF_M_MESSAGESREFERENCE].tags = (uint32_t *) malloc (sizeof (uint32_t) * handle->templates[MDF_M_MESSAGESREFERENCE].tags_num);
175 	handle->templates[MDF_M_MESSAGESREFERENCE].tags[0] = 0xffffffff;
176 
177 	handle->templates[MDF_M_LOGON].mclass = MDF_MC_UNDEF;
178 	handle->templates[MDF_M_LOGON].tags_num = 3;
179 	handle->templates[MDF_M_LOGON].tags = (uint32_t *) malloc (sizeof (uint32_t) * handle->templates[MDF_M_LOGON].tags_num);
180 	handle->templates[MDF_M_LOGON].tags[0] = MDF_F_USERNAME;
181 	handle->templates[MDF_M_LOGON].tags[1] = MDF_F_PASSWORD;
182 	handle->templates[MDF_M_LOGON].tags[2] = MDF_F_EXTRACREDENTIAL;
183 
184 	handle->templates[MDF_M_LOGOFF].mclass = MDF_MC_UNDEF;
185 	handle->templates[MDF_M_LOGOFF].tags_num = 1;
186 	handle->templates[MDF_M_LOGOFF].tags = (uint32_t *) malloc (sizeof (uint32_t) * handle->templates[MDF_M_LOGOFF].tags_num);
187 	handle->templates[MDF_M_LOGOFF].tags[0] = MDF_F_LOGOFFREASON;
188 
189 	mdf_int_rebalance_templates (handle->templates, handle->templates_num);
190 
191 #if defined (HAVE_SIGACTION) && defined (SIGPIPE)
192 	memset (&act, 0, sizeof act);
193 	act.sa_handler = SIG_IGN;
194 	sigaction (SIGPIPE, &act, NULL);
195 #elif defined (HAVE_SIGNAL) && defined (SIGPIPE)
196 	signal (SIGPIPE, SIG_IGN);
197 #endif
198 	return handle;
199 }
200 
mdf_destroy(mdf_t handle)201 void mdf_destroy (mdf_t handle)
202 {
203 	int i;
204 
205 	if (handle == NULL)
206 		return;
207 
208 	mdf_disconnect (handle);
209 
210 	free (handle->data);
211 	handle->data = NULL;
212 
213 	free (handle->value);
214 	handle->value = NULL;
215 
216 	free (handle->connected_host);
217 	handle->connected_host = NULL;
218 
219 	free (handle->connected_ip);
220 	handle->connected_ip = NULL;
221 
222 	for (i = 0; i < handle->templates_num; i++) {
223 		free (handle->templates[i].tags);
224 		free (handle->templates[i].fields);
225 	}
226 
227 	free (handle->templates);
228 	handle->templates = NULL;
229 
230 	free (handle->sendfields);
231 	handle->sendfields = NULL;
232 
233 	free (handle->sendtags);
234 	handle->sendtags = NULL;
235 
236 	free (handle->sendbuf);
237 	handle->sendbuf = NULL;
238 
239 	free (handle);
240 
241 #if defined _WIN32 || defined _WIN64
242 	WSACleanup ();
243 #endif
244 }
245 
call_status_callback(mdf_t handle,MDF_CONN_STATUS status,const char * host,const char * ip)246 static void call_status_callback (mdf_t handle, MDF_CONN_STATUS status, const char *host, const char *ip)
247 {
248 	if (handle->callbacks.func_status == NULL)
249 		return;
250 
251 	handle->callbacks.func_status (handle->callbacks.udata_status, status, host, ip);
252 }
253 
disconnect(mdf_t handle)254 static void disconnect (mdf_t handle)
255 {
256 	if (handle->master_secret != NULL) {
257 		memset (handle->master_secret, 0x00, handle->digest_length);
258 		free (handle->master_secret);
259 		handle->master_secret = NULL;
260 	}
261 
262 	free (handle->client_iv);
263 	handle->client_iv = NULL;
264 
265 	free (handle->server_iv);
266 	handle->server_iv = NULL;
267 
268 	free (handle->client_enc);
269 	handle->client_enc = NULL;
270 
271 	free (handle->server_enc);
272 	handle->server_enc = NULL;
273 
274 	if (handle->client_hmac != NULL) {
275 #if OPENSSL_VERSION_NUMBER < 0x10100000L
276 		HMAC_CTX_cleanup (handle->client_hmac);
277 		OPENSSL_free (handle->client_hmac);
278 #else
279 		HMAC_CTX_free (handle->client_hmac);
280 #endif
281 		handle->client_hmac = NULL;
282 	}
283 
284 	if (handle->server_hmac != NULL) {
285 #if OPENSSL_VERSION_NUMBER < 0x10100000L
286 		HMAC_CTX_cleanup (handle->server_hmac);
287 		OPENSSL_free (handle->server_hmac);
288 #else
289 		HMAC_CTX_free (handle->server_hmac);
290 #endif
291 		handle->server_hmac = NULL;
292 	}
293 
294 	handle->data_pos = 0;
295 	handle->data_used = 0;
296 	handle->fstatus = 2;
297 	handle->error = MDF_ERR_NO_ERROR;
298 
299 #if defined _WIN32 || defined _WIN64
300 	closesocket (handle->fd);
301 #else
302 	close (handle->fd);
303 #endif
304 	handle->fd = INVALID_SOCKET;
305 
306 	call_status_callback (handle, MDF_STATUS_DISCONNECTED, handle->connected_host, handle->connected_ip);
307 }
308 
read_int_msg(mdf_t handle,uint8_t * buf,ssize_t * restrict len,int * restrict pos,const size_t maxlen)309 static int read_int_msg (mdf_t handle, uint8_t *buf, ssize_t * restrict len, int * restrict pos, const size_t maxlen)
310 {
311 	size_t offset = 0;
312 	size_t toread = 0;
313 
314 	do {
315 		ssize_t ret;
316 		fd_set fdset;
317 		struct timeval tv;
318 
319 		FD_ZERO (&fdset);
320 		FD_SET (handle->fd, &fdset);
321 
322 		tv.tv_sec = 10;
323 		tv.tv_usec = 0;
324 
325 		ret = select (handle->fd + 1, &fdset, NULL, NULL, &tv);
326 
327 		if (ret != 1)
328 			return -1;
329 
330 		ret = recv (handle->fd, (char *) (buf + offset), maxlen - offset, 0);
331 
332 		if (ret < 1)
333 			return -1;
334 
335 		handle->bytes_read += ret;
336 		offset += ret;
337 
338 		if (offset < 5)
339 			continue;
340 
341 		if (toread == 0) {
342 			int i = 0;
343 
344 			do {
345 				toread *= 128;
346 				toread += (buf[i] & 127) + 1;
347 			} while ((buf[i++] & 128) == 0 && i < 5);
348 
349 			*len = toread + i;
350 			*pos = i;
351 
352 			toread += i;
353 
354 			if (toread > maxlen)
355 				return -1;
356 
357 			toread -= offset;
358 		} else
359 			toread -= ret;
360 	} while (toread != 0);
361 
362 	return 0;
363 }
364 
send_greeting(mdf_t handle)365 static int send_greeting (mdf_t handle)
366 {
367 	int used = 5;
368 	int offset;
369 	int msg1_len;
370 	int msg2_len;
371 	int msg2_offset;
372 	ssize_t len;
373 	ssize_t hostlen;
374 	int64_t expiry;
375 	uint32_t tmp_u32;
376 	uint8_t *msg1;
377 	uint8_t *buf;
378 	uint8_t *Na;
379 	uint8_t *Nb = NULL;
380 	uint8_t *master_key;
381 	BIGNUM *X = NULL;
382 	union digest_ctx ctx1;
383 	union digest_ctx ctx2;
384 	unsigned char md[MAX_DIGEST_LENGTH];
385 	DH *dh;
386 	RSA *rsa_master = NULL;
387 	RSA *rsa_server = NULL;
388 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
389 	BIGNUM *bn1 = NULL;
390 	BIGNUM *bn2 = NULL;
391 #endif
392 
393 	/* As part of setting up the connection with the server, the client
394 	 * must initiate a crypto handshake with the server. The first
395 	 * message from the client will contain the mdf version (for book-
396 	 * keeping), a random nonce (Na), the minimum number of bytes that
397 	 * the client accepts for the DH p parameter, and a list of the
398 	 * digests and encryptions that we support. */
399 	len = sizeof (MDF_VERSION) - 1;
400 
401 	if (len > 255) {
402 		disconnect (handle);
403 		return 0;
404 	}
405 
406 	hostlen = sizeof (MDF_BUILD_HOST) - 1;
407 
408 	if (hostlen > 255) {
409 		disconnect (handle);
410 		return 0;
411 	}
412 
413 	msg1 = malloc (5 + 11 + sizeof (uint64_t) + sizeof (uint8_t) + len + sizeof (uint32_t) + sizeof md + sizeof (uint32_t) + mdf_int_sizeof_cryptmethods () + sizeof (uint8_t) + hostlen);
414 	Na = malloc (sizeof md);
415 
416 	used += add_header (msg1 + used, 0, 0);
417 
418 	*((uint64_t *)(msg1 + used)) = cpu_to_le64 (handle->template_version);
419 	used += sizeof (uint64_t);
420 
421 	msg1[used++] = (uint8_t) len;
422 
423 	memcpy (msg1 + used, MDF_VERSION, len);
424 	used += len;
425 
426 	/* we send the largest Na that we can produce */
427 	if (RAND_bytes (Na, sizeof md) != 1) {
428 		free (Na);
429 		free (msg1);
430 		disconnect (handle);
431 		return 0;
432 	}
433 
434 	*((uint32_t *)(msg1 + used)) = cpu_to_le32 (sizeof md);
435 	used += sizeof (uint32_t);
436 	memcpy (msg1 + used, Na, sizeof md);
437 	used += sizeof md;
438 
439 	*((uint32_t *)(msg1 + used)) = cpu_to_le32 (MIN_DH_LENGTH);
440 	used += sizeof (uint32_t);
441 
442 	/* we add the list of supported digest and encryption methods */
443 	mdf_int_populate_cryptmethods (msg1, &used);
444 
445 	/* add the MDF_BUILD_HOST info */
446 	msg1[used++] = (uint8_t) hostlen;
447 	memcpy (msg1 + used, MDF_BUILD_HOST, hostlen);
448 	used += hostlen;
449 
450 	msg1_len = used - 5;
451 
452 	offset = 5 - add_len (msg1, msg1_len);
453 
454 	if (offset != 0) {
455 		memmove (msg1 + offset, msg1, 5 - offset);
456 		used -= offset;
457 	}
458 
459 	len = send (handle->fd, (void *)(msg1 + offset), used, 0);
460 
461 	if (len != used) {
462 		free (Na);
463 		free (msg1);
464 		disconnect (handle);
465 		return 0;
466 	}
467 
468 	handle->bytes_written += len;
469 
470 	/* We should now receive the first message from the server. This
471 	 * message will contain the public DH parameters (g, p), the
472 	 * server public DH key (X), a random nonce (Nb), the server
473 	 * public RSA key (e,n) and a signature from the "master" to
474 	 * authenticate the public RSA key, the hostname etc.
475 	 * Last in the message is a RSA signature created with the
476 	 * server key of all bytes exchanged so far (by both parties).
477 	 *
478 	 * Since the signature covers the random nonce (Na) that the
479 	 * client generated, the client now knows two things:
480 	 *	1. The server has seen the first message from the client,
481 	 *	   so there was no man-in-the-middle fiddling with the
482 	 *	   message trying to impersonate as the client.
483 	 *
484 	 *	2. This message does indeed come from the server, it
485 	 *	   carries the servers signature and it is not part in
486 	 *	   any reply attack since Na was randomly chosen.
487 	*/
488 	buf = malloc (201728);
489 
490 	if (read_int_msg (handle, buf, &len, &offset, 201728) == -1) {
491 		free (Na);
492 		free (buf);
493 		free (msg1);
494 		disconnect (handle);
495 		return 0;
496 	}
497 
498 	msg2_len = len - offset;
499 
500 	dh = DH_new ();
501 
502 	if (len < 100)
503 		goto exit_in_error;
504 
505 	msg2_offset = offset;
506 
507 	if (buf[offset] != 0x00 || buf[offset + 1] != 0x00 || buf[offset + 2] != 0x03)
508 		goto exit_in_error;
509 
510 	offset += 3;
511 
512 	/* do we support the suggested encryption method? */
513 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
514 	offset += sizeof (uint32_t);
515 
516 	if (mdf_int_encryptions_verify (used, &handle->encryption_method) == 0)
517 		goto exit_in_error;
518 
519 	/* do we support the suggested digest method? */
520 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
521 	offset += sizeof (uint32_t);
522 
523 	if (mdf_int_digests_verify (used, &handle->digest_method, &handle->digest_length) == 0)
524 		goto exit_in_error;
525 
526 	/* since we now know the digest method of choice we can calculate what the
527 	 * digest of our first message should have been! */
528 	mdf_int_digest_init (handle->digest_method, &ctx1);
529 
530 	tmp_u32 = cpu_to_le32 (1); /* message no 1 */
531 	mdf_int_digest_update (handle->digest_method, &ctx1, &tmp_u32, sizeof tmp_u32);
532 
533 	tmp_u32 = cpu_to_le32 (msg1_len);
534 	mdf_int_digest_update (handle->digest_method, &ctx1, &tmp_u32, sizeof tmp_u32);
535 	mdf_int_digest_update (handle->digest_method, &ctx1, msg1 + 5, msg1_len);
536 
537 	free (msg1);
538 	msg1 = NULL;
539 
540 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
541 	offset += sizeof (uint32_t);
542 
543 	/* do we have room for g and p-len? */
544 	if (offset + used + (int)sizeof (uint32_t) > len)
545 		goto exit_in_error;
546 
547 #if OPENSSL_VERSION_NUMBER < 0x10100000L
548 	dh->g = BN_bin2bn (buf + offset, used, NULL);
549 #else
550 	bn1 = BN_bin2bn (buf + offset, used, NULL);
551 #endif
552 	offset += used;
553 
554 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
555 	offset += sizeof (uint32_t);
556 
557 	/* do we have room for p and X-len? */
558 	if (offset + used + (int)sizeof (uint32_t) > len)
559 		goto exit_in_error;
560 
561 	/* make sure that p is within limits */
562 	if (used < MIN_DH_LENGTH || used > MAX_DH_LENGTH)
563 		goto exit_in_error;
564 
565 #if OPENSSL_VERSION_NUMBER < 0x10100000L
566 	dh->p = BN_bin2bn (buf + offset, used, NULL);
567 #else
568 	bn2 = BN_bin2bn (buf + offset, used, NULL);
569 
570 	if (DH_set0_pqg (dh, bn2, NULL, bn1) == 0)
571 		goto exit_in_error;
572 
573 	/* clear these so that we don't do a double free on exit */
574 	bn1 = NULL;
575 	bn2 = NULL;
576 #endif
577 
578 	offset += used;
579 
580 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
581 	offset += sizeof (uint32_t);
582 
583 	/* do we have room for X and Nb-len? */
584 	if (offset + used + (int)sizeof (uint32_t) > len)
585 		goto exit_in_error;
586 
587 	X = BN_bin2bn (buf + offset, used, NULL);
588 	offset += used;
589 
590 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
591 	offset += sizeof (uint32_t);
592 
593 	/* do we have room for Nb and master siglen? */
594 	if (offset + used + (int)sizeof (uint32_t) > len || used != handle->digest_length)
595 		goto exit_in_error;
596 
597 	Nb = malloc (used);
598 	memcpy (Nb, buf + offset, used);
599 	offset += used;
600 
601 	rsa_master = mdf_int_load_rsapublickey ();
602 
603 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
604 
605 	/* do we have room for the master signature block? */
606 	if (offset + used + 1 > len || used <= RSA_size (rsa_master))
607 		goto exit_in_error;
608 
609 	/* verify the master signature */
610 	mdf_int_digest_init (handle->digest_method, &ctx2);
611 	mdf_int_digest_update (handle->digest_method, &ctx2, buf + offset, used - RSA_size (rsa_master));
612 	mdf_int_digest_final (handle->digest_method, md, &ctx2);
613 
614 	if (mdf_int_digest_verify (handle->digest_method, md, buf + offset + (used - RSA_size (rsa_master)), RSA_size (rsa_master), rsa_master) == 0)
615 		goto exit_in_error;
616 
617 	offset += sizeof (uint32_t);
618 
619 	/* verify the hostname from the master signature */
620 	used = 0;
621 	for (tmp_u32 = buf[offset++]; tmp_u32 != 0; tmp_u32--) {
622 		if (offset + buf[offset] + 1 > len)
623 			goto exit_in_error;
624 
625 		if (buf[offset] == strlen (handle->connected_host) && memcmp (buf + offset + 1, handle->connected_host, buf[offset]) == 0)
626 			used = 1;
627 		else if (buf[offset] == strlen (handle->connected_ip) && memcmp (buf + offset + 1, handle->connected_ip, buf[offset]) == 0)
628 			used = 1;
629 
630 		offset += buf[offset] + 1;
631 	}
632 
633 	if (used == 0)
634 		goto exit_in_error;
635 
636 	/* do we have room for the expiry time and e-len? */
637 	if (offset + (int)(sizeof (int64_t) + sizeof (uint32_t)) > len)
638 		goto exit_in_error;
639 
640 	/* has the signature expired? */
641 	expiry = le64_to_cpu (*((int64_t *)(buf + offset)));
642 
643 	if (time (NULL) >= expiry)
644 		goto exit_in_error;
645 
646 	offset += sizeof (int64_t);
647 
648 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
649 	offset += sizeof (uint32_t);
650 
651 	/* do we have room for e, n-len and is e of the appropiate size? */
652 	if (offset + used + (int)sizeof (uint32_t) > len || used > OPENSSL_RSA_MAX_PUBEXP_BITS * 8 || used < 1)
653 		goto exit_in_error;
654 
655 	rsa_server = RSA_new ();
656 
657 #if OPENSSL_VERSION_NUMBER < 0x10100000L
658 	rsa_server->e = BN_bin2bn (buf + offset, used, NULL);
659 #else
660 	bn1 = BN_bin2bn (buf + offset, used, NULL);
661 #endif
662 	offset += used;
663 
664 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
665 	offset += sizeof (uint32_t);
666 
667 	/* do we have room for n, signature-len and is n of the appropiate size? */
668 	if (offset + used + (int)sizeof (uint32_t) > len || used > OPENSSL_RSA_MAX_MODULUS_BITS * 8 || used < 256)
669 		goto exit_in_error;
670 
671 #if OPENSSL_VERSION_NUMBER < 0x10100000L
672 	rsa_server->n = BN_bin2bn (buf + offset, used, NULL);
673 #else
674 	bn2 = BN_bin2bn (buf + offset, used, NULL);
675 
676 	if (RSA_set0_key (rsa_server, bn2, bn1, NULL) == 0)
677 		goto exit_in_error;
678 
679 	/* clear these so that we don't do a double free on exit */
680 	bn1 = NULL;
681 	bn2 = NULL;
682 #endif
683 	offset += used;
684 
685 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
686 	offset += sizeof (uint32_t);
687 
688 	/* do we have room for the signature and the sig-len, and is the signature of the correct size? */
689 	if (offset + used + (int)sizeof (uint32_t) > len || used != RSA_size (rsa_master))
690 		goto exit_in_error;
691 
692 	/* ok, come this far we have now verified that we have got a valid RSA key from the server.
693 	 * We know that it hasn't expired, that it's hostname matches that to which we are connected to,
694 	 * and that the master signature was valid. */
695 
696 	offset += used;
697 	RSA_free (rsa_master);
698 	rsa_master = NULL;
699 
700 	/* let's look at the server's signature */
701 	used = le32_to_cpu (*((uint32_t *)(buf + offset)));
702 	offset += sizeof (uint32_t);
703 
704 	tmp_u32 = cpu_to_le32 (2); /* message no 2 */
705 	mdf_int_digest_update (handle->digest_method, &ctx1, &tmp_u32, sizeof tmp_u32);
706 
707 	tmp_u32 = cpu_to_le32 (msg2_len);
708 	mdf_int_digest_update (handle->digest_method, &ctx1, &tmp_u32, sizeof tmp_u32);
709 	mdf_int_digest_update (handle->digest_method, &ctx1, buf + msg2_offset, offset - msg2_offset);
710 
711 	/* do we have room for the signature, and is the signature the correct size? */
712 	if (offset + used > len || used != RSA_size (rsa_server))
713 		goto exit_in_error;
714 
715 	/* we make a copy of the CTX since we need to send an AUTH for the
716 	 * client as well and mdf_int_digest_final() will destroy the context */
717 	memcpy (&ctx2, &ctx1, sizeof ctx2);
718 	mdf_int_digest_final (handle->digest_method, md, &ctx1);
719 
720 	/* is the signature valid? */
721 	if (mdf_int_digest_verify (handle->digest_method, md, buf + offset, used, rsa_server) == 0)
722 		goto exit_in_error;
723 
724 	RSA_free (rsa_server);
725 	rsa_server = NULL;
726 
727 	/* the signature is included in the clients AUTH */
728 	mdf_int_digest_update (handle->digest_method, &ctx2, buf + offset, used);
729 
730 	/* we check that p is a safe prime and that g is a suitable generator,
731 	 * since we wouldn't want to be catched with our pants down. And also
732 	 * we do this _after_ we checked the RSA signatures so we have at least
733 	 * some guarantees that we haven't received values that will keep us up
734 	 * all night performing the check, or whatever nasty ugliness that could
735 	 * have happened. */
736 	if (DH_check (dh, &used) == 0)
737 		goto exit_in_error;
738 
739 	if (DH_generate_key (dh) == 0)
740 		goto exit_in_error;
741 
742 	master_key = malloc (DH_size (dh));
743 
744 	used = DH_compute_key (master_key, X, dh);
745 
746 	if (used == -1) {
747 		free (master_key);
748 		goto exit_in_error;
749 	}
750 
751 	BN_free (X);
752 	X = NULL;
753 
754 	handle->master_secret = malloc (handle->digest_length);
755 	mdf_int_digest_init (handle->digest_method, &ctx1);
756 	mdf_int_digest_update (handle->digest_method, &ctx1, master_key, used);
757 	mdf_int_digest_final (handle->digest_method, handle->master_secret, &ctx1);
758 
759 	memset (master_key, 0x00, used);
760 	free (master_key);
761 
762 	mdf_int_set_keys (handle, Na, sizeof md, &handle->client_enc, &handle->client_hmac, &handle->client_iv);
763 	mdf_int_set_keys (handle, Nb, handle->digest_length, &handle->server_enc, &handle->server_hmac, &handle->server_iv);
764 
765 	free (Na);
766 	Na = NULL;
767 
768 	free (Nb);
769 	Nb = NULL;
770 
771 	/* Now we construct the final packet in our crypto handshake,
772 	 * this message will contain the clients public DH key and the
773 	 * client AUTH encrypted with the client encryption key.
774 	 *
775 	 * This AUTH will not authenticate the client as such (the server
776 	 * does not know which client it is until the client sends the
777 	 * username/password credentials, and the client lacks a RSA key.
778 	 *
779 	 * No, the reason for the AUTH is to complete the handshake and to
780 	 * make sure that the server has a secure channel open with "someone"
781 	 * and that this "someone" was the very same entity who sent the very
782 	 * first message in the handshake. This is not as bad as it sounds,
783 	 * this is exactly like secure web browsing (aka SSL/TLS).
784 	 *
785 	 * The client on the other had does know that it is communicating
786 	 * with the server due to the RSA signature, and this is what is
787 	 * really important since it is the client who will have to send
788 	 * its password over the wire, and we better make sure it's to no
789 	 * stranger. */
790 	used = 5;
791 
792 	used += add_header (buf + used, 0, 4);
793 
794 #if OPENSSL_VERSION_NUMBER < 0x10100000L
795 	len = BN_bn2bin (dh->pub_key, buf + used + sizeof (uint32_t));
796 #else
797 	const BIGNUM *dh_pub, *dh_priv;
798 	DH_get0_key (dh, &dh_pub, &dh_priv);
799 	len = BN_bn2bin (dh_pub, buf + used + sizeof (uint32_t));
800 #endif
801 
802 	*((uint32_t *)(buf + used)) = cpu_to_le32 (len);
803 	used += sizeof (uint32_t) + len;
804 
805 	DH_free (dh);
806 	dh = NULL;
807 
808 	*((uint32_t *)(buf + used)) = cpu_to_le32 (handle->digest_length);
809 	used += sizeof (uint32_t);
810 
811 	/* len is now as far as we have to calculate AUTH, we have to
812 	 * perform this little tap dance since we need the message length
813 	 * attached to be able to calculate the correct message digest */
814 	len = used;
815 	used += handle->digest_length;
816 
817 	tmp_u32 = cpu_to_le32 (3); /* message no 3 */
818 	mdf_int_digest_update (handle->digest_method, &ctx2, &tmp_u32, sizeof tmp_u32);
819 
820 	tmp_u32 = cpu_to_le32 (used - 5);
821 	mdf_int_digest_update (handle->digest_method, &ctx2, &tmp_u32, sizeof tmp_u32);
822 	mdf_int_digest_update (handle->digest_method, &ctx2, buf + 5, len - 5);
823 
824 	offset = 5 - add_len (buf, used - 5);
825 
826 	if (offset != 0) {
827 		memmove (buf + offset, buf, 5 - offset);
828 		used -= offset;
829 	}
830 
831 	mdf_int_digest_final (handle->digest_method, buf + len, &ctx2);
832 
833 	mdf_int_encrypt_aes_ctr (buf + len, handle->digest_length, handle->client_enc, handle->client_iv);
834 	len = send (handle->fd, (void *)(buf + offset), used, 0);
835 
836 	if (len != used)
837 		goto exit_in_error;
838 
839 	handle->bytes_written += len;
840 	handle->cstate = CSTATE_ENCRYPT | CSTATE_DECRYPT;
841 	free (buf);
842 	return 1;
843 
844 exit_in_error:
845 	disconnect (handle);
846 
847 	if (rsa_master != NULL)
848 		RSA_free (rsa_master);
849 
850 	if (rsa_server != NULL)
851 		RSA_free (rsa_server);
852 
853 	if (dh != NULL)
854 		DH_free (dh);
855 
856 	if (X != NULL)
857 		BN_free (X);
858 
859 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
860 	if (bn1 != NULL)
861 		BN_free (bn1);
862 
863 	if (bn2 != NULL)
864 		BN_free (bn2);
865 #endif
866 
867 	free (Na);
868 	free (Nb);
869 	free (buf);
870 	free (msg1);
871 	return 0;
872 }
873 
mdf_int_send_rekey(mdf_t handle)874 void mdf_int_send_rekey (mdf_t handle)
875 {
876 	ssize_t written;
877 	int len;
878 	uint8_t buf[5 + 11 + sizeof (uint32_t) + MAX_DIGEST_LENGTH + MAX_DIGEST_LENGTH];
879 	uint8_t *p = buf;
880 	uint8_t *Na = NULL;
881 	uint8_t *first_pos;
882 	uint32_t tmp_u32;
883 
884 	/* we don't support rekeyings on non encryption tunnels */
885 	if ((handle->cstate & CSTATE_ENCRYPT) != CSTATE_ENCRYPT)
886 		return;
887 
888 	if (handle->no_encryption == 1)
889 		len = 3 + sizeof (uint32_t);
890 	else
891 		len = 3 + sizeof (uint32_t) + handle->digest_length;
892 
893 	p += add_len (p, len);
894 	first_pos = p;
895 
896 	p += add_header (p, 0, 5);
897 
898 	if (handle->no_encryption == 1) {
899 		memset (p, 0, sizeof (uint32_t));
900 		p += sizeof (uint32_t);
901 	} else {
902 		*((uint32_t *)(p)) = cpu_to_le32 (handle->digest_length);
903 		p += sizeof (uint32_t);
904 
905 		Na = malloc (handle->digest_length);
906 
907 		if (RAND_bytes (Na, handle->digest_length) != 1) {
908 			free (Na);
909 			return;
910 		}
911 
912 		memcpy (p, Na, handle->digest_length);
913 		p += handle->digest_length;
914 	}
915 
916 	tmp_u32 = cpu_to_le32 ((p - buf) + handle->digest_length);
917 
918 	HMAC_Init_ex (handle->client_hmac, NULL, 0, NULL, NULL);
919 	HMAC_Update (handle->client_hmac, handle->client_iv, sizeof (uint64_t));
920 	HMAC_Update (handle->client_hmac, (unsigned char *) &tmp_u32, sizeof tmp_u32);
921 	HMAC_Update (handle->client_hmac, buf, p - buf);
922 	HMAC_Final (handle->client_hmac, p, NULL);
923 	p += handle->digest_length;
924 
925 	mdf_int_encrypt_aes_ctr (first_pos, p - first_pos, handle->client_enc, handle->client_iv);
926 
927 	written = send (handle->fd, (void *)buf, p - buf, 0);
928 
929 	if (written == -1) {
930 		free (Na);
931 		disconnect (handle);
932 		return;
933 	}
934 
935 	handle->bytes_written += written;
936 
937 	if (handle->no_encryption == 1) {
938 		handle->cstate &= ~CSTATE_ENCRYPT;
939 		return;
940 	}
941 
942 	mdf_int_set_keys (handle, Na, handle->digest_length, &handle->client_enc, &handle->client_hmac, &handle->client_iv);
943 	free (Na);
944 }
945 
should_we_rekey(mdf_t handle)946 static void should_we_rekey (mdf_t handle)
947 {
948 	if ((handle->cstate & CSTATE_ENCRYPT) != CSTATE_ENCRYPT)
949 		return;
950 
951 	if (le64_to_cpu (*((uint64_t *) handle->client_iv)) < MAX_ENCRYPTED_MESSAGES_PER_KEY)
952 		return;
953 
954 	mdf_int_send_rekey (handle);
955 }
956 
mdf_int_send_heartbeat(mdf_t handle)957 int mdf_int_send_heartbeat (mdf_t handle)
958 {
959 	ssize_t written;
960 	uint8_t buf[12 + MAX_DIGEST_LENGTH];
961 	uint8_t *p = buf;
962 	uint8_t *first_pos;
963 
964 	p += add_len (p, 11);
965 	first_pos = p;
966 
967 	p += add_header (p, 0, 2);
968 
969 	(*(uint64_t *)p) = cpu_to_le64 (time (NULL));
970 	p += 8;
971 
972 	if ((handle->cstate & CSTATE_ENCRYPT) == CSTATE_ENCRYPT) {
973 		uint32_t tmp_u32 = cpu_to_le32 ((p - buf) + handle->digest_length);
974 
975 		HMAC_Init_ex (handle->client_hmac, NULL, 0, NULL, NULL);
976 		HMAC_Update (handle->client_hmac, handle->client_iv, sizeof (uint64_t));
977 		HMAC_Update (handle->client_hmac, (unsigned char *) &tmp_u32, sizeof tmp_u32);
978 		HMAC_Update (handle->client_hmac, buf, p - buf);
979 		HMAC_Final (handle->client_hmac, p, NULL);
980 		p += handle->digest_length;
981 
982 		mdf_int_encrypt_aes_ctr (first_pos, p - first_pos, handle->client_enc, handle->client_iv);
983 	}
984 
985 	written = send (handle->fd, (void *)buf, p - buf, 0);
986 
987 	if (written == -1) {
988 		disconnect (handle);
989 		handle->error = MDF_ERR_DISCONNECTED;
990 		return -1;
991 	}
992 
993 	handle->bytes_written += written;
994 	should_we_rekey (handle);
995 	return 0;
996 }
997 
request_heartbeat(mdf_t handle)998 static int request_heartbeat (mdf_t handle)
999 {
1000 	ssize_t written;
1001 	uint8_t buf[5 + 11 + MAX_DIGEST_LENGTH];
1002 	uint8_t *p = buf;
1003 	uint8_t *first_pos;
1004 
1005 	p += add_len (p, 3);
1006 	first_pos = p;
1007 
1008 	p += add_header (p, 0, 1);
1009 
1010 	if ((handle->cstate & CSTATE_ENCRYPT) == CSTATE_ENCRYPT) {
1011 		uint32_t tmp_u32 = cpu_to_le32 ((p - buf) + handle->digest_length);
1012 
1013 		HMAC_Init_ex (handle->client_hmac, NULL, 0, NULL, NULL);
1014 		HMAC_Update (handle->client_hmac, handle->client_iv, sizeof (uint64_t));
1015 		HMAC_Update (handle->client_hmac, (unsigned char *) &tmp_u32, sizeof tmp_u32);
1016 		HMAC_Update (handle->client_hmac, buf, p - buf);
1017 		HMAC_Final (handle->client_hmac, p, NULL);
1018 		p += handle->digest_length;
1019 
1020 		mdf_int_encrypt_aes_ctr (first_pos, p - first_pos, handle->client_enc, handle->client_iv);
1021 	}
1022 
1023 	written = send (handle->fd, (void *)buf, p - buf, 0);
1024 
1025 	if (written == -1) {
1026 		disconnect (handle);
1027 		handle->error = MDF_ERR_DISCONNECTED;
1028 		return -1;
1029 	}
1030 
1031 	handle->bytes_written += written;
1032 	should_we_rekey (handle);
1033 	return 0;
1034 }
1035 
1036 #if defined _WIN32 || defined _WIN64
is_connected(SOCKET fd,fd_set * rdevents,fd_set * wrevents,fd_set * exevents)1037 static int is_connected (SOCKET fd, fd_set *rdevents, fd_set *wrevents, fd_set *exevents)
1038 {
1039 	WSASetLastError (0);
1040 
1041 	if (!FD_ISSET (fd, rdevents) && !FD_ISSET (fd, wrevents))
1042 		return 0;
1043 
1044 	if (FD_ISSET (fd, exevents))
1045 		return 0;
1046 
1047 	return 1;
1048 }
1049 #else
is_connected(int fd,fd_set * rdevents,fd_set * wrevents,fd_set * exevents)1050 static int is_connected (int fd, fd_set *rdevents, fd_set *wrevents, fd_set *exevents)
1051 {
1052 	int err;
1053 	socklen_t len = sizeof err;
1054 
1055 	(void)exevents;
1056 
1057 	errno = 0;
1058 
1059 	if (!FD_ISSET (fd, rdevents) && !FD_ISSET (fd, wrevents))
1060 		return 0;
1061 
1062 	if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
1063 		return 0;
1064 
1065 	errno = err;
1066 
1067 	return err == 0 ? 1 : 0;
1068 }
1069 #endif
1070 
try_connect(mdf_t handle,struct addrinfo * addr)1071 static int try_connect (mdf_t handle, struct addrinfo *addr)
1072 {
1073 	fd_set rdevents;
1074 	fd_set wrevents;
1075 	fd_set exevents;
1076 	struct timeval tv;
1077 	int ret;
1078 
1079 #if defined _WIN32 || defined _WIN64
1080 	unsigned long val = 1;
1081 #else
1082 	int val;
1083 #endif
1084 
1085 	handle->fd = socket (addr->ai_family, addr->ai_socktype | SOCK_CLOEXEC, addr->ai_protocol);
1086 
1087 	if (handle->fd == INVALID_SOCKET)
1088 		return 0;
1089 
1090 	/* set non-blocking */
1091 #if defined _WIN32 || defined _WIN64
1092 	if (ioctlsocket (handle->fd, FIONBIO, &val) == SOCKET_ERROR) {
1093 		closesocket (handle->fd);
1094 		handle->fd = INVALID_SOCKET;
1095 		return 0;
1096 	}
1097 #else
1098 	val = fcntl (handle->fd, F_GETFL, 0);
1099 
1100 	if (val == -1) {
1101 		close (handle->fd);
1102 		handle->fd = INVALID_SOCKET;
1103 		return 0;
1104 	}
1105 
1106 	if (fcntl (handle->fd, F_SETFL, val | O_NONBLOCK) == -1) {
1107 		close (handle->fd);
1108 		handle->fd = INVALID_SOCKET;
1109 		return 0;
1110 	}
1111 #endif
1112 	ret = connect (handle->fd, addr->ai_addr, addr->ai_addrlen);
1113 
1114 #if defined _WIN32 || defined _WIN64
1115 	if (ret == SOCKET_ERROR) {
1116 		if (WSAGetLastError () != WSAEWOULDBLOCK) {
1117 			closesocket (handle->fd);
1118 			handle->fd = INVALID_SOCKET;
1119 			return 0;
1120 		}
1121 #else
1122 	if (ret == -1) {
1123 		if (errno != EINPROGRESS) {
1124 			close (handle->fd);
1125 			handle->fd = INVALID_SOCKET;
1126 			return 0;
1127 		}
1128 #endif
1129 		FD_ZERO (&rdevents);
1130 		FD_SET (handle->fd, &rdevents);
1131 
1132 		wrevents = rdevents;
1133 		exevents = rdevents;
1134 
1135 		tv.tv_sec = handle->connect_timeout;
1136 		tv.tv_usec = 0;
1137 
1138 		if (select (handle->fd + 1, &rdevents, &wrevents, &exevents, &tv) < 1) {
1139 #if defined _WIN32 || defined _WIN64
1140 			closesocket (handle->fd);
1141 #else
1142 			close (handle->fd);
1143 #endif
1144 			handle->fd = INVALID_SOCKET;
1145 			return 0;
1146 		}
1147 
1148 		if (is_connected (handle->fd, &rdevents, &wrevents, &exevents) == 0) {
1149 #if defined _WIN32 || defined _WIN64
1150 			closesocket (handle->fd);
1151 #else
1152 			close (handle->fd);
1153 #endif
1154 			handle->fd = INVALID_SOCKET;
1155 			return 0;
1156 		}
1157 	}
1158 
1159 	/* set socket back to blocking */
1160 #if defined _WIN32 || defined _WIN64
1161 	val = 0;
1162 	ioctlsocket (handle->fd, FIONBIO, &val);
1163 #else
1164 	fcntl (handle->fd, F_SETFL, val);
1165 #endif
1166 
1167 	return 1;
1168 }
1169 
1170 static int try_host (mdf_t handle, const char * restrict host, const char * restrict port)
1171 {
1172 	struct addrinfo hint;
1173 	struct addrinfo *res;
1174 	struct addrinfo *r;
1175 
1176 	memset (&hint, 0, sizeof hint);
1177 
1178 #ifdef AI_ADDRCONFIG
1179 	hint.ai_flags = AI_ADDRCONFIG;
1180 #endif
1181 #ifdef AI_NUMERICSERV
1182 	hint.ai_flags |= AI_NUMERICSERV;
1183 #endif
1184 
1185 	hint.ai_family = AF_UNSPEC;
1186 	hint.ai_socktype = SOCK_STREAM;
1187 	hint.ai_protocol = IPPROTO_TCP;
1188 
1189 	call_status_callback (handle, MDF_STATUS_LOOKUP, host, NULL);
1190 
1191 	if (getaddrinfo (host, port, &hint, &res) != 0)
1192 		return 0;
1193 
1194 	for (r = res; r != NULL; r = r->ai_next) {
1195 		char buf[50];
1196 		char *ip = NULL;
1197 
1198 		if (getnameinfo (r->ai_addr, r->ai_addrlen, buf, sizeof buf, NULL, 0, NI_NUMERICHOST) == 0)
1199 			ip = buf;
1200 
1201 		call_status_callback (handle, MDF_STATUS_CONNECTING, host, ip);
1202 
1203 		if (try_connect (handle, r) == 1) {
1204 			call_status_callback (handle, MDF_STATUS_CONNECTED, host, ip);
1205 			freeaddrinfo (res);
1206 
1207 			free (handle->connected_host);
1208 			handle->connected_host = strdup (host);
1209 
1210 			free (handle->connected_ip);
1211 			handle->connected_ip = strdup (ip);
1212 			return 1;
1213 		}
1214 	}
1215 
1216 	freeaddrinfo (res);
1217 
1218 	return 0;
1219 }
1220 
1221 #ifdef HAVE_SYS_UN_H
1222 static int try_unix (mdf_t handle, const char *path)
1223 {
1224 	union { struct sockaddr_un un; struct sockaddr addr; } addr;
1225 	int ret;
1226 
1227 	if (strlen (path) + 1 > sizeof addr.un.sun_path)
1228 		return 0;
1229 
1230 	handle->fd = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1231 
1232 	if (handle->fd == INVALID_SOCKET)
1233 		return 0;
1234 
1235 	memset (&addr.un, 0, sizeof addr.un);
1236 
1237 	addr.un.sun_family = AF_UNIX;
1238 	strcpy (addr.un.sun_path, path);
1239 
1240 	ret = connect (handle->fd, &addr.addr, sizeof addr.un);
1241 
1242 	if (ret == -1) {
1243 		close (handle->fd);
1244 		handle->fd = INVALID_SOCKET;
1245 		return 0;
1246 	}
1247 
1248 	call_status_callback (handle, MDF_STATUS_CONNECTED, path, path);
1249 
1250 	free (handle->connected_host);
1251 	handle->connected_host = strdup (path);
1252 
1253 	free (handle->connected_ip);
1254 	handle->connected_ip = strdup (path);
1255 
1256 	handle->cstate = 0; /* No need to encrypt data on AF_UNIX */
1257 	return 1;
1258 }
1259 #endif
1260 
1261 int mdf_connect (mdf_t handle, const char *servers)
1262 {
1263 	char *s, *p, *e, *port;
1264 
1265 	if (handle == NULL)
1266 		return 0;
1267 
1268 	if (servers == NULL) {
1269 		handle->error = MDF_ERR_ARGUMENT;
1270 		return 0;
1271 	}
1272 
1273 	/* if we already are connected we must fail */
1274 	if (handle->fd != INVALID_SOCKET) {
1275 		handle->error = MDF_ERR_CONNECTED;
1276 		return 0;
1277 	}
1278 
1279 	handle->cstate = CSTATE_INVALID;
1280 
1281 	s = strdup (servers);
1282 
1283 	/* parse the servers string */
1284 	for (p = s; *p != '\0'; p = e) {
1285 		while (isspace ((unsigned char) *p) != 0 || *p == ',')
1286 			++p;
1287 
1288 		/* IPv6 */
1289 		if (*p == '[') {
1290 			++p;
1291 
1292 			port = strchr (p, ']');
1293 
1294 			if (port == NULL) {
1295 				free (s);
1296 				handle->error = MDF_ERR_ARGUMENT;
1297 				return 0;
1298 			}
1299 
1300 			*port++ = '\0';
1301 #ifdef HAVE_SYS_UN_H
1302 		} else if (*p == '/') { /* Unix Domain Sockets */
1303 			e = strchr (p, ',');
1304 
1305 			if (e != NULL)
1306 				*e++ = '\0';
1307 
1308 			if (try_unix (handle, p) == 1) {
1309 				free (s);
1310 				handle->time_lastupdate = time (NULL);
1311 				handle->heartbeats_sent = 0;
1312 				return 1;
1313 			}
1314 
1315 			if (e == NULL)
1316 				break;
1317 
1318 			continue;
1319 #endif
1320 		} else { /* IPv4 or DNS name */
1321 			port = strchr (p, ':');
1322 
1323 			if (port == NULL) {
1324 				free (s);
1325 				handle->error = MDF_ERR_ARGUMENT;
1326 				return 0;
1327 			}
1328 		}
1329 
1330 		/* the format must be host:port */
1331 		if (*port != ':') {
1332 			free (s);
1333 			handle->error = MDF_ERR_ARGUMENT;
1334 			return 0;
1335 		}
1336 
1337 		*port++ = '\0';
1338 
1339 		/* scan to the end of the port, yes this code does not perform
1340 		 * all the checks that it could do, i.e we do not check if the port
1341 		 * was written like host:1234newhost, but it is futile to try every
1342 		 * possible error, we should just be happy that we at least do not
1343 		 * crash ;) */
1344 		for (e = port; isdigit ((unsigned char) *e) != 0; e++)
1345 			;
1346 
1347 		/* do not increase the end pointer if we are at the last byte in the string */
1348 		if (*e != '\0')
1349 			*e++ = '\0';
1350 
1351 		/* we found one, try it! */
1352 		if (try_host (handle, p, port) != 0) {
1353 			setsockopt (handle->fd, SOL_TCP, TCP_NODELAY, (char *) &handle->tcp_nodelay, sizeof handle->tcp_nodelay);
1354 
1355 			if (send_greeting (handle) == 1) {
1356 				free (s);
1357 				handle->time_lastupdate = time (NULL);
1358 				handle->heartbeats_sent = 0;
1359 				call_status_callback (handle, MDF_STATUS_READYTOLOGON, handle->connected_host, handle->connected_ip);
1360 				return 1;
1361 			}
1362 		}
1363 	}
1364 
1365 	free (s);
1366 	handle->error = MDF_ERR_CONNECT;
1367 	return 0;
1368 }
1369 
1370 void mdf_disconnect (mdf_t handle)
1371 {
1372 	if (handle == NULL || handle->fd == INVALID_SOCKET)
1373 		return;
1374 
1375 	disconnect (handle);
1376 }
1377 
1378 int mdf_get_property (mdf_t handle, MDF_OPTION option, ...)
1379 {
1380 	va_list ap;
1381 
1382 	if (handle == NULL)
1383 		return 0;
1384 
1385 	va_start (ap, option);
1386 
1387 	switch (option) {
1388 		case MDF_OPT_FD : {
1389 #if defined _WIN32 || defined _WIN64
1390 			SOCKET *value = va_arg (ap, SOCKET *);
1391 #else
1392 			int *value = va_arg (ap, int *);
1393 #endif
1394 			if (value == NULL)
1395 				return 0;
1396 
1397 			*value = handle->fd;
1398 			return 1;
1399 		}
1400 
1401 		case MDF_OPT_ERROR : {
1402 			MDF_ERROR *value = va_arg (ap, MDF_ERROR *);
1403 
1404 			if (value == NULL)
1405 				return 0;
1406 
1407 			*value = handle->error;
1408 			return 1;
1409 		}
1410 
1411 		case MDF_OPT_RCV_BYTES : {
1412 			uint64_t *value = va_arg (ap, uint64_t *);
1413 
1414 			if (value == NULL)
1415 				return 0;
1416 
1417 			*value = handle->bytes_read;
1418 			return 1;
1419 		}
1420 
1421 		case MDF_OPT_SENT_BYTES : {
1422 			uint64_t *value = va_arg (ap, uint64_t *);
1423 
1424 			if (value == NULL)
1425 				return 0;
1426 
1427 			*value = handle->bytes_written;
1428 			return 1;
1429 		}
1430 
1431 		case MDF_OPT_DATA_CALLBACK_FUNCTION : {
1432 			mdf_data_callback *value = va_arg (ap, mdf_data_callback *);
1433 
1434 			if (value == NULL)
1435 				return 0;
1436 
1437 			*value = handle->callbacks.func_data;
1438 			return 1;
1439 		}
1440 
1441 		case MDF_OPT_DATA_CALLBACK_USERDATA : {
1442 			char **value = va_arg (ap, char **);
1443 
1444 			if (value == NULL)
1445 				return 0;
1446 
1447 			*value = (char *) handle->callbacks.udata_data;
1448 			return 1;
1449 		}
1450 
1451 		case MDF_OPT_STATUS_CALLBACK_FUNCTION : {
1452 			mdf_status_callback *value = va_arg (ap, mdf_status_callback *);
1453 
1454 			if (value == NULL)
1455 				return 0;
1456 
1457 			*value = handle->callbacks.func_status;
1458 			return 1;
1459 		}
1460 
1461 		case MDF_OPT_STATUS_CALLBACK_USERDATA : {
1462 			char **value = va_arg (ap, char **);
1463 
1464 			if (value == NULL)
1465 				return 0;
1466 
1467 			*value = (char *) handle->callbacks.udata_status;
1468 			return 1;
1469 		}
1470 
1471 		case MDF_OPT_CONNECT_TIMEOUT : {
1472 			int *value = va_arg (ap, int *);
1473 
1474 			if (value == NULL)
1475 				return 0;
1476 
1477 			*value = handle->connect_timeout;
1478 			return 1;
1479 		}
1480 
1481 		case MDF_OPT_HEARTBEAT_INTERVAL : {
1482 			int *value = va_arg (ap, int *);
1483 
1484 			if (value == NULL)
1485 				return 0;
1486 
1487 			*value = handle->heartbeat_interval;
1488 			return 1;
1489 		}
1490 
1491 		case MDF_OPT_HEARTBEAT_MAX_MISSED : {
1492 			int *value = va_arg (ap, int *);
1493 
1494 			if (value == NULL)
1495 				return 0;
1496 
1497 			*value = handle->max_missed_heartbeats;
1498 			return 1;
1499 		}
1500 
1501 		case MDF_OPT_TCP_NODELAY : {
1502 			int *value = va_arg (ap, int *);
1503 
1504 			if (value == NULL)
1505 				return 0;
1506 
1507 			*value = handle->tcp_nodelay;
1508 			return 1;
1509 		}
1510 
1511 		case MDF_OPT_NO_ENCRYPTION : {
1512 			int *value = va_arg (ap, int *);
1513 
1514 			if (value == NULL)
1515 				return 0;
1516 
1517 			*value = handle->no_encryption;
1518 			return 1;
1519 		}
1520 
1521 		case MDF_OPT_TIME_DIFFERENCE : {
1522 			int *value = va_arg (ap, int *);
1523 
1524 			if (value == NULL)
1525 				return 0;
1526 
1527 			*value = handle->timediff;
1528 			return 1;
1529 		}
1530 	}
1531 
1532 	va_end (ap);
1533 
1534 	return 0;
1535 }
1536 
1537 int mdf_set_property (mdf_t handle, MDF_OPTION option, void *value)
1538 {
1539 	if (handle == NULL)
1540 		return 0;
1541 
1542 	switch (option) {
1543 		case MDF_OPT_DATA_CALLBACK_FUNCTION :
1544 			handle->callbacks.func_data = (mdf_data_callback) value;
1545 			return 1;
1546 
1547 		case MDF_OPT_DATA_CALLBACK_USERDATA :
1548 			handle->callbacks.udata_data = value;
1549 			return 1;
1550 
1551 		case MDF_OPT_STATUS_CALLBACK_FUNCTION :
1552 			handle->callbacks.func_status = (mdf_status_callback) value;
1553 			return 1;
1554 
1555 		case MDF_OPT_STATUS_CALLBACK_USERDATA :
1556 			handle->callbacks.udata_status = value;
1557 			return 1;
1558 
1559 		case MDF_OPT_CONNECT_TIMEOUT : {
1560 			int *val = (int *) value;
1561 
1562 			if (*val < 1 || *val > 60)
1563 				return 0;
1564 
1565 			handle->connect_timeout = *val;
1566 			return 1;
1567 		}
1568 
1569 		case MDF_OPT_RCV_BYTES :
1570 			handle->bytes_read = *((uint64_t *) value);
1571 			return 1;
1572 
1573 		case MDF_OPT_SENT_BYTES :
1574 			handle->bytes_written = *((uint64_t *) value);
1575 			return 1;
1576 
1577 		case MDF_OPT_ERROR :
1578 			handle->error = *((MDF_ERROR *) value);
1579 			return 1;
1580 
1581 		case MDF_OPT_FD :
1582 			return 0;
1583 
1584 		case MDF_OPT_HEARTBEAT_INTERVAL : {
1585 			int *val = (int *) value;
1586 
1587 			if (*val < 1 || *val > 86400)
1588 				return 0;
1589 
1590 			handle->heartbeat_interval = *val;
1591 			return 1;
1592 		}
1593 
1594 		case MDF_OPT_HEARTBEAT_MAX_MISSED : {
1595 			int *val = (int *) value;
1596 
1597 			if (*val < 1 || *val > 100)
1598 				return 0;
1599 
1600 			handle->max_missed_heartbeats = *val;
1601 			return 1;
1602 		}
1603 
1604 		case MDF_OPT_TCP_NODELAY : {
1605 			int *val = (int *) value;
1606 
1607 			if (*val < 0 || *val > 1)
1608 				return 0;
1609 
1610 			handle->tcp_nodelay = *val;
1611 
1612 			if (handle->fd != INVALID_SOCKET)
1613 				setsockopt (handle->fd, SOL_TCP, TCP_NODELAY, (char *) &handle->tcp_nodelay, sizeof handle->tcp_nodelay);
1614 
1615 			return 1;
1616 		}
1617 
1618 		case MDF_OPT_NO_ENCRYPTION : {
1619 			int *val = (int *) value;
1620 
1621 			if (*val < 0 || *val > 1)
1622 				return 0;
1623 
1624 			handle->no_encryption = *val;
1625 			return 1;
1626 		}
1627 
1628 		case MDF_OPT_TIME_DIFFERENCE :
1629 			return 0;
1630 	}
1631 
1632 	return 0;
1633 }
1634 
1635 int mdf_consume (mdf_t handle, const int timeout)
1636 {
1637 	fd_set rdset;
1638 	struct timeval tv;
1639 	int ret;
1640 	int flags = 0;
1641 	int pos;
1642 	size_t tlen;
1643 
1644 	if (handle == NULL)
1645 		return -1;
1646 
1647 	if (handle->fd == INVALID_SOCKET) {
1648 		handle->error = MDF_ERR_NOT_CONNECTED;
1649 		return -1;
1650 	}
1651 
1652 	if ((handle->cstate & CSTATE_INVALID) == CSTATE_INVALID)
1653 		return 0;
1654 
1655 #ifdef MSG_DONTWAIT
1656 	flags = MSG_DONTWAIT;
1657 
1658 	/* if we are on a real POSIX system and timeout is zero
1659 	 * we can skip the whole select() call saving us some cs */
1660 	if (timeout != 0) {
1661 #endif
1662 
1663 	FD_ZERO (&rdset);
1664 	FD_SET (handle->fd, &rdset);
1665 
1666 	if (timeout < 0)
1667 		tv.tv_sec = 1;
1668 	else if (timeout > 60 * 60)
1669 		tv.tv_sec = 60 * 60;
1670 	else
1671 		tv.tv_sec = timeout;
1672 
1673 	tv.tv_usec = 0;
1674 
1675 	ret = select (handle->fd + 1, &rdset, NULL, NULL, &tv);
1676 
1677 	if (ret == 0) {
1678 		/* is it time to send a heartbeat */
1679 		time_t now = time (NULL);
1680 
1681 		if (difftime (now, handle->time_lastupdate) >= handle->heartbeat_interval) {
1682 			if (handle->heartbeats_sent++ == handle->max_missed_heartbeats) {
1683 				disconnect (handle);
1684 				handle->error = MDF_ERR_CONNECTION_IDLE;
1685 				return -1;
1686 			}
1687 
1688 			handle->time_lastupdate = now;
1689 			return request_heartbeat (handle);
1690 		}
1691 
1692 		return 0;
1693 	}
1694 
1695 	if (ret < 0) {
1696 #ifdef HAVE_ERRNO_H
1697 		if (errno == EINTR)
1698 			return 0;
1699 #endif
1700 		disconnect (handle);
1701 		handle->error = MDF_ERR_DISCONNECTED;
1702 		return -1;
1703 	}
1704 #ifdef MSG_DONTWAIT
1705 	}
1706 #endif
1707 
1708 #ifdef MSG_DONTWAIT
1709 try_read_again:
1710 #endif
1711 	ret = recv (handle->fd, (char *) (handle->data + handle->data_used), handle->data_size - handle->data_used, flags);
1712 
1713 	if (ret == 0) {
1714 		disconnect (handle);
1715 		handle->error = MDF_ERR_DISCONNECTED;
1716 		return -1;
1717 	}
1718 
1719 	if (ret < 0) {
1720 #ifdef MSG_DONTWAIT
1721 		if (errno == EAGAIN) {
1722 			/* is it time to send a heartbeat */
1723 			time_t now = time (NULL);
1724 
1725 			if (difftime (now, handle->time_lastupdate) >= handle->heartbeat_interval) {
1726 				if (handle->heartbeats_sent++ == handle->max_missed_heartbeats) {
1727 					disconnect (handle);
1728 					handle->error = MDF_ERR_CONNECTION_IDLE;
1729 					return -1;
1730 				}
1731 
1732 				handle->time_lastupdate = now;
1733 				return request_heartbeat (handle);
1734 			}
1735 
1736 			return 0;
1737 		}
1738 
1739 		if (errno == EINTR)
1740 			goto try_read_again;
1741 #endif
1742 		disconnect (handle);
1743 		handle->error = MDF_ERR_DISCONNECTED;
1744 		return -1;
1745 	}
1746 
1747 	handle->time_lastupdate = time (NULL);
1748 	handle->bytes_read += ret;
1749 	handle->data_used += ret;
1750 	handle->heartbeats_sent = 0;
1751 
1752 	/* in case we get called before the client has decoded all the data in the buffer */
1753 	if (handle->fstatus != 2) {
1754 		if (handle->data_used - ret == handle->message_end)
1755 			handle->oldval = handle->data[handle->message_end];
1756 
1757 		if (handle->callbacks.func_data == NULL)
1758 			return 1;
1759 
1760 		do {
1761 			handle->callbacks.func_data (handle->callbacks.udata_data, handle);
1762 		} while (handle->fstatus != 2);
1763 
1764 		return 0;
1765 	}
1766 
1767 	pos = 0;
1768 	tlen = 0;
1769 
1770 	do {
1771 		tlen *= 128;
1772 		tlen += (handle->data[handle->data_pos + pos] & 127) + 1;
1773 	} while ((handle->data[handle->data_pos + pos++] & 128) == 0 && handle->data_pos + pos < handle->data_used);
1774 
1775 	if (pos > 5) {
1776 		disconnect (handle);
1777 		handle->error = MDF_ERR_MSG_OOB;
1778 		return -1;
1779 	}
1780 
1781 	/* we have not yet received a full header */
1782 	if (pos == 0 || (handle->data[handle->data_pos + pos - 1] & 128) == 0) {
1783 		if (handle->data_pos != 0) {
1784 			handle->data_used -= handle->data_pos;
1785 			memmove (handle->data, handle->data + handle->data_pos, handle->data_used);
1786 			handle->data_pos = 0;
1787 		}
1788 
1789 		return 0;
1790 	}
1791 
1792 	handle->message_len = tlen + pos;
1793 	handle->message_end = handle->data_pos + handle->message_len;
1794 	handle->pos = pos;
1795 	handle->fpos = handle->data_pos + pos;
1796 
1797 	if ((handle->cstate & CSTATE_DECRYPT) == CSTATE_DECRYPT)
1798 		handle->message_len += handle->digest_length;
1799 
1800 	if (handle->data_pos + handle->message_len + 12 > handle->data_size) {
1801 		void *tmp = realloc (handle->data, handle->data_pos + handle->message_len + 12);
1802 
1803 		if (tmp == NULL) {
1804 			disconnect (handle);
1805 			handle->error = MDF_ERR_NO_MEM;
1806 			return -1;
1807 		}
1808 
1809 		handle->data = (uint8_t *) tmp;
1810 		handle->data_size = handle->data_pos + handle->message_len + 12;
1811 	}
1812 
1813 	if (handle->message_len + handle->data_pos > handle->data_used) {
1814 		if (handle->data_pos != 0) {
1815 			handle->data_used -= handle->data_pos;
1816 			memmove (handle->data, handle->data + handle->data_pos, handle->data_used);
1817 			handle->data_pos = 0;
1818 		}
1819 
1820 		return 0;
1821 	}
1822 
1823 	handle->fstatus = 1;
1824 
1825 	if (handle->callbacks.func_data == NULL)
1826 		return 1;
1827 
1828 	do {
1829 		handle->callbacks.func_data (handle->callbacks.udata_data, handle);
1830 	} while (handle->fstatus != 2);
1831 
1832 	return 0;
1833 }
1834 
1835 int mdf_message_send (mdf_t handle, mdf_message_t message)
1836 {
1837 	unsigned int i;
1838 	struct field *field;
1839 
1840 	if (handle == NULL || message == NULL)
1841 		return 0;
1842 
1843 	if (handle->fd == INVALID_SOCKET)
1844 		return 0;
1845 
1846 	if ((handle->cstate & CSTATE_INVALID) == CSTATE_INVALID)
1847 		return 0;
1848 
1849 	if (message->current_message == -1)
1850 		return 0;
1851 
1852 #ifdef TCP_CORK
1853 	i = 1;
1854 	setsockopt (handle->fd, IPPROTO_TCP, TCP_CORK, &i, sizeof (i));
1855 #endif
1856 
1857 	field = message->fields;
1858 
1859 	for (i = 0; i < (unsigned int)(message->current_message + 1); i++) {
1860 		uint8_t *p, *pmap_pos;
1861 		unsigned int j;
1862 		unsigned int tags_used = 0;
1863 		unsigned int maxpos = 0;
1864 		int hlen, offset;
1865 		size_t len = 0;
1866 		struct msg_template *template;
1867 		ssize_t written;
1868 
1869 		if (message->messages[i].fields == 0 && message->messages[i].mref != MDF_M_INSTRUMENTRESET && message->messages[i].mref != MDF_M_INSTRUMENTDELETE && message->messages[i].mref != MDF_M_ORDERBOOKFLUSH && message->messages[i].mref != MDF_M_LOGOFF)
1870 			continue;
1871 
1872 		if (message->messages[i].mref > 0 && message->messages[i].mref < handle->templates_num) {
1873 			template = &(handle->templates[message->messages[i].mref]);
1874 
1875 			if (template->tags_num > handle->sendfields_num) {
1876 				free (handle->sendfields);
1877 				handle->sendfields = malloc (sizeof *handle->sendfields * template->tags_num);
1878 				handle->sendfields_num = template->tags_num;
1879 
1880 				if (handle->sendfields == NULL) {
1881 #ifdef TCP_CORK
1882 					i = 0;
1883 					setsockopt (handle->fd, IPPROTO_TCP, TCP_CORK, &i, sizeof (i));
1884 #endif
1885 					handle->sendfields_num = 0;
1886 					handle->error = MDF_ERR_NO_MEM;
1887 					return 0;
1888 				}
1889 			}
1890 
1891 			memset (handle->sendfields, 0, sizeof *handle->sendfields * template->tags_num);
1892 		} else {
1893 			template = NULL;
1894 		}
1895 
1896 		/* create one list of the tags in positional order and one list of the
1897 		 * tags that we must send as "tagged" */
1898 		for (j = 0; j < (unsigned int)(message->messages[i].fields); j++) {
1899 			/* perform binary search for the field position */
1900 			int high = template == NULL ? -1 : template->tags_num - 1;
1901 			int pos = -1;
1902 			int low = 0;
1903 
1904 			while (high >= low) {
1905 				const int mid = (low + high) / 2;
1906 
1907 				if (template->fields[mid].tag == field->tag) {
1908 					pos = template->fields[mid].pos;
1909 					break;
1910 				}
1911 
1912 				if (template->fields[mid].tag > field->tag)
1913 					high = mid - 1;
1914 				else
1915 					low = mid + 1;
1916 			}
1917 
1918 			if (pos != -1) {
1919 				if (handle->sendfields[pos] != NULL)
1920 					len -= handle->sendfields[pos]->len;
1921 
1922 				handle->sendfields[pos] = field;
1923 
1924 				if (pos > (int)maxpos)
1925 					maxpos = pos;
1926 			} else {
1927 				if (tags_used + 1 > handle->sendtags_num) {
1928 					struct field **tmp = handle->sendtags;
1929 					handle->sendtags = realloc (handle->sendtags, sizeof *handle->sendtags * (tags_used + 1));
1930 					handle->sendtags_num = tags_used + 1;
1931 
1932 					if (handle->sendtags == NULL) {
1933 #ifdef TCP_CORK
1934 						i = 0;
1935 						setsockopt (handle->fd, IPPROTO_TCP, TCP_CORK, &i, sizeof (i));
1936 #endif
1937 						free (tmp);
1938 						handle->sendtags_num = 0;
1939 						handle->error = MDF_ERR_NO_MEM;
1940 						return 0;
1941 					}
1942 				}
1943 
1944 				handle->sendtags[tags_used++] = field;
1945 
1946 				if (field->tag <= 255)
1947 					len += 2;
1948 				else if (field->tag <= 65535)
1949 					len += 3;
1950 				else
1951 					len += 5;
1952 			}
1953 
1954 			len += field->len;
1955 			field++;
1956 		}
1957 
1958 		/* the number of pmap:s that we will use */
1959 		len += (maxpos / 8) + 1;
1960 
1961 		if (len + 5 + 11 + handle->digest_length > (size_t) handle->sendbuf_size) {
1962 			free (handle->sendbuf);
1963 			handle->sendbuf = malloc (len + 5 + 11 + handle->digest_length);
1964 			handle->sendbuf_size = len + 5 + 11 + handle->digest_length;
1965 
1966 			if (handle->sendbuf == NULL) {
1967 #ifdef TCP_CORK
1968 				i = 0;
1969 				setsockopt (handle->fd, IPPROTO_TCP, TCP_CORK, &i, sizeof (i));
1970 #endif
1971 				handle->sendbuf_size = 0;
1972 				handle->error = MDF_ERR_NO_MEM;
1973 				return 0;
1974 			}
1975 		}
1976 
1977 		p = handle->sendbuf + 5;
1978 		hlen = add_header (p, (uint16_t) (message->messages[i].mref + 1), message->messages[i].insref);
1979 		len += hlen;
1980 		p += hlen;
1981 
1982 		hlen = add_len (handle->sendbuf, len);
1983 		offset = 5 - hlen;
1984 
1985 		if (offset != 0)
1986 			memmove (handle->sendbuf + offset, handle->sendbuf, hlen);
1987 
1988 		if (template != NULL) {
1989 			int pmap = 0;
1990 
1991 			for (j = 0; j < maxpos + 1; j++) {
1992 				if (pmap == 0) {
1993 					pmap = 128;
1994 					pmap_pos = p;
1995 					*p++ = 0;
1996 				}
1997 
1998 				if (handle->sendfields[j] != NULL) {
1999 					*pmap_pos |= pmap;
2000 
2001 					if (tags_used != 0) {
2002 						unsigned int k;
2003 
2004 						for (k = 0; k < tags_used; k++) {
2005 							if (handle->sendtags[k]->tag <= 255) {
2006 								*p++ = 251;
2007 								*p++ = (uint8_t) handle->sendtags[k]->tag;
2008 							} else if (handle->sendtags[k]->tag <= 65535) {
2009 								*p++ = 252;
2010 								*((uint16_t *) p) = cpu_to_le16 ((uint16_t) handle->sendtags[k]->tag);
2011 								p += 2;
2012 							} else {
2013 								*p++ = 253;
2014 								*((uint32_t *) p) = cpu_to_le32 ((uint32_t) handle->sendtags[k]->tag);
2015 								p += 4;
2016 							}
2017 
2018 							memcpy (p, message->data + handle->sendtags[k]->offset, handle->sendtags[k]->len);
2019 							p += handle->sendtags[k]->len;
2020 						}
2021 
2022 						tags_used = 0;
2023 					}
2024 
2025 					memcpy (p, message->data + handle->sendfields[j]->offset, handle->sendfields[j]->len);
2026 					p += handle->sendfields[j]->len;
2027 				}
2028 
2029 				pmap /= 2;
2030 			}
2031 		} else if (tags_used == 0) {
2032 			*p++ = 0;
2033 		}
2034 
2035 		/* apparently we had only tagged data today... */
2036 		if (tags_used != 0) {
2037 			if (template == NULL)
2038 				*p++ = 128;
2039 			else
2040 				*pmap_pos = 128;
2041 
2042 			for (j = 0; j < tags_used; j++) {
2043 				if (handle->sendtags[j]->tag <= 255) {
2044 					*p++ = 251;
2045 					*p++ = (uint8_t) handle->sendtags[j]->tag;
2046 				} else if (handle->sendtags[j]->tag <= 65535) {
2047 					*p++ = 252;
2048 					*((uint16_t *) p) = cpu_to_le16 ((uint16_t) handle->sendtags[j]->tag);
2049 					p += 2;
2050 				} else {
2051 					*p++ = 253;
2052 					*((uint32_t *) p) = cpu_to_le32 ((uint32_t) handle->sendtags[j]->tag);
2053 					p += 4;
2054 				}
2055 
2056 				memcpy (p, message->data + handle->sendtags[j]->offset, handle->sendtags[j]->len);
2057 				p += handle->sendtags[j]->len;
2058 			}
2059 		}
2060 
2061 		if ((handle->cstate & CSTATE_ENCRYPT) == CSTATE_ENCRYPT) {
2062 			unsigned int length;
2063 			uint32_t tmp_u32 = cpu_to_le32 (hlen + len + handle->digest_length);
2064 
2065 			HMAC_Init_ex (handle->client_hmac, NULL, 0, NULL, NULL);
2066 			HMAC_Update (handle->client_hmac, handle->client_iv, sizeof (uint64_t));
2067 			HMAC_Update (handle->client_hmac, (unsigned char *) &tmp_u32, sizeof tmp_u32);
2068 			HMAC_Update (handle->client_hmac, handle->sendbuf + offset, hlen + len);
2069 			HMAC_Final (handle->client_hmac, p, &length);
2070 
2071 			len += length;
2072 
2073 			mdf_int_encrypt_aes_ctr (handle->sendbuf + 5, len, handle->client_enc, handle->client_iv);
2074 		}
2075 
2076 		len += hlen;
2077 
2078 send_again:
2079 		written = send (handle->fd, (void *)(handle->sendbuf + offset), len, 0);
2080 
2081 		if ((size_t)written == len) {
2082 			handle->bytes_written += written;
2083 			continue;
2084 		}
2085 
2086 #ifdef HAVE_ERRNO_H
2087 		if (written == -1 && errno == EINTR)
2088 			goto send_again;
2089 #endif
2090 		handle->error = MDF_ERR_DISCONNECTED;
2091 		disconnect (handle);
2092 		return 0;
2093 	}
2094 
2095 #ifdef TCP_CORK
2096 	i = 0;
2097 	setsockopt (handle->fd, IPPROTO_TCP, TCP_CORK, &i, sizeof (i));
2098 #endif
2099 
2100 	should_we_rekey (handle);
2101 	return 1;
2102 }
2103 
2104