1 
2 /*-
3  *
4  * New BSD License 2006
5  *
6  * Copyright (c) 2006, Jorgen Lundman
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are
11  * met:
12  *
13  * 1 Redistributions of source code must retain the above copyright
14  *   notice, this list of conditions and the following disclaimer.
15  * 2 Redistributions in binary form must reproduce the above
16  *   copyright notice, this list of conditions and the following
17  *   disclaimer in the documentation and/or other materials provided
18  *   with the distribution.
19  * 3 Neither the name of the stuff nor the names of its contributors
20  *   may be used to endorse or promote products derived from this
21  *   software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  */
36 
37 // $Id: tls.c,v 1.28 2006/06/30 01:22:58 lundman Exp $
38 // SSL/TLS Support Functions
39 // Jorgen Lundman October 17th, 2002.
40 
41 #ifdef WITH_SSL
42 
43 #include <stdio.h>
44 
45 // If you don't have these, have you installed openssl?
46 #ifdef WIN32
47 #define WINDOWS_LEAN_AND_MEAN
48 #include <winsock2.h>   // SSL below includes windows, that includes old winsock, so we do it first
49 #endif
50 
51 #include <openssl/ssl.h>
52 #include <openssl/rand.h>
53 #include <openssl/err.h>
54 
55 #include <string.h>
56 
57 #include "connections.h"
58 
59 #include "lion.h"
60 #include "tls.h"
61 #include "sockets.h"
62 
63 
64 //#define DEBUG
65 
66 __RCSID("$LiON: lundman/lion/tls.c,v 1.28 2006/06/30 01:22:58 lundman Exp $");
67 
68 
69 
70 
71 static char cfg_tlsciphers[] =
72 "RC4-SHA:RC4-MD5:DHE-DSS-RC4-SHA:DES-CBC3-SHA:DES-CBC3-MD5:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA";
73 
74 
75 // Master TLS context
76 static SSL_CTX *tls_ctx = NULL;
77 
78 // internal variables to remember which has been initialised
79 int net_client_SSL = 1;
80 int net_server_SSL = 1;
81 
82 char *ssl_tlsciphers = NULL;
83 char *ssl_tlsrsafile = NULL;
84 char *ssl_egdsocket = NULL;
85 
86 
tls_init(void)87 int tls_init( void )
88 {
89 	int egdbytes, status;
90 
91 
92 	// Do we even want SSL on?
93 	if (!net_client_SSL &&
94 		!net_server_SSL)
95 		return 0;
96 
97 	if (!ssl_tlsciphers)
98 		ssl_tlsciphers = strdup( cfg_tlsciphers );
99 	if (!ssl_egdsocket)
100 		ssl_egdsocket = strdup( "/var/run/egd-pool" );
101 	if (!ssl_tlsrsafile)
102 		ssl_tlsrsafile = strdup( "lion.pem" );
103 
104 #ifdef DEBUG
105 	printf("Using cipher list: %s\n", ssl_tlsciphers);
106 #endif
107 
108 	SSL_load_error_strings();                /* readable error messages */
109 	SSL_library_init();                      /* initialize library */
110 
111 	tls_ctx = SSL_CTX_new(SSLv23_method());
112 
113 
114 	// Did we get SSL?
115 
116 	if (!tls_ctx) {
117 
118 		net_server_SSL = 0;
119 		net_client_SSL = 0;
120 
121 		printf("SSL_CTX_new() %s\r\n",
122 			   (char *)ERR_error_string(ERR_get_error(), NULL));
123 
124 		tls_free();
125 
126 		return -1;
127 	}
128 
129 	// Do we have sufficient random?
130 
131 	if (RAND_status() != 1) {
132 
133 		if ( (egdbytes = RAND_egd(ssl_egdsocket)) == -1 ) {
134 
135 			net_server_SSL = 0;
136 			net_client_SSL = 0;
137 
138 			printf("ssl_init: RAND_egd failed\r\n");
139 
140 			tls_free();
141 
142 			return -2;
143 		}
144 
145 		if (RAND_status() != 1) {
146 
147 			net_server_SSL = 0;
148 			net_client_SSL = 0;
149 
150 			printf("ssl_init: System without entropy source, see TLS.ReadMeFirst\r\n");
151 
152 			tls_free();
153 
154 			return -3;
155 		}
156 	}
157 
158 
159 	// Set some options
160 	SSL_CTX_set_options(tls_ctx, SSL_OP_NO_SSLv2);
161 	//SSL_CTX_set_options(tls_ctx, SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1);
162 	//SSL_CTX_set_options(tls_ctx, SSL_OP_NO_TLSv1);
163 	SSL_CTX_set_default_verify_paths(tls_ctx);
164 
165 
166 
167 	SSL_CTX_set_session_cache_mode(tls_ctx, SSL_SESS_CACHE_CLIENT);
168 	SSL_CTX_set_session_id_context(tls_ctx, (const unsigned char *) "1", 1);
169 
170 	// That's sufficient for being a client (server communications)
171 	// but we also need to load up certificates etc to attempt to
172 	// allow clients to SSL with us.
173 
174 
175 	if (net_server_SSL) { // SSL is enabled for clients
176 
177 
178 		status = SSL_CTX_use_certificate_file(tls_ctx, ssl_tlsrsafile,
179 											  X509_FILETYPE_PEM);
180 
181 		if (status <= 0) {
182 			printf("SSL_CTX_use_certificate_file(%s) %s : %s\n", "",
183 				   (char *)ERR_error_string(ERR_get_error(), NULL),
184 				   ssl_tlsrsafile);
185 
186 			printf("Server SSL AUTH disabled (no certificate).\n");
187 
188 			net_server_SSL = 0;
189 
190 
191 		} else {
192 
193 			status = SSL_CTX_use_PrivateKey_file(tls_ctx,ssl_tlsrsafile,
194 												 X509_FILETYPE_PEM);
195 
196 			if (status <= 0) {
197 				printf("SSL_CTX_use_PrivateKey_file(%s) %s\n", "",
198 					   (char *)ERR_error_string(ERR_get_error(), NULL));
199 				printf("Server SSL AUTH disabled.\n");
200 				net_server_SSL = 0;
201 			}
202 
203 		}
204 
205 	}
206 
207 
208 
209 	return 0;
210 
211 }
212 
213 
tls_free(void)214 void tls_free(void)
215 {
216 
217 	if (tls_ctx) {
218 
219 #ifdef DEBUG
220 		printf("SSL Released.\n");
221 #endif
222 
223 		SSL_CTX_free(tls_ctx);
224 		tls_ctx = NULL;
225 
226 	}
227 
228 	net_server_SSL = 0;
229 	net_client_SSL = 0;
230 
231 }
232 
233 
tls_close(connection_t * node)234 void tls_close( connection_t *node )
235 {
236 
237 	if (node->trace)
238 		fprintf(trace_file, "%p: tls_close\n", node);
239 
240 	if (node->ctx) {
241 #ifdef DEBUG
242 		printf("Releasing SSL socket\n");
243 #endif
244 
245 		SSL_free( node->ctx );
246 		node->ctx = NULL;
247 	}
248 
249 	node->use_ssl = 0;
250 
251 
252 }
253 
254 
tls_auth(connection_t * node)255 int tls_auth( connection_t *node )
256 {
257 
258 #ifdef DEBUG
259 	printf("tls_auth(%p): %p\n", node, node->ctx);
260 #endif
261 
262 	if (node->trace)
263 		fprintf(trace_file, "%p: tls_auth\n", node);
264 
265 	node->ctx = SSL_new(tls_ctx);
266 
267 	if (!node->ctx) {
268 
269 		printf("SSL: Failed to create new context -- disabling\n");
270 		node->use_ssl = 0;
271 
272 		return -1;
273 
274 	}
275 
276 
277 	if (RAND_status() != 1) {
278 		printf("ssl_init: System without /dev/urandom, PRNG seeding must be done manually\n");
279 		node->use_ssl = 0;
280 
281 		return -2;
282 	}
283 
284 
285 	SSL_set_cipher_list(node->ctx, ssl_tlsciphers);
286 
287 #ifdef DEBUG
288 	printf("Setting fd %d\n", node->socket);
289 #endif
290 
291 	if (SSL_set_fd(node->ctx, node->socket ) != 1)
292 		printf("SSL_set_fd_error");
293 
294 
295 	// Experimental
296 	node->status = ST_SSL_NEG;
297 	node->auth_type = LION_SSL_SERVER;
298 
299 
300 #ifdef DEBUG
301 	printf("Status %d\n", node->status);
302 #endif
303 
304 	tls_cont_auth(node);
305 
306 	return 1;
307 }
308 
309 
310 
tls_cont_auth(connection_t * node)311 void tls_cont_auth( connection_t *node )
312 {
313 	int status, sslerr;
314 	char cipher_info[128];
315 	SSL_CIPHER *cipher;
316 
317 
318 	if (node->trace)
319 		fprintf(trace_file, "%p: tls_cont_auth\n", node);
320 
321 #ifdef DEBUG
322 	printf("tls_cont_auth: ... %p \n", node);
323 #endif
324 	//net_want_select( node->handle, NET_WANT_NONE);
325 	node->want_mode = NET_WANT_NONE;
326 
327 	status = SSL_accept(node->ctx);
328 	sslerr = SSL_get_error(node->ctx,status);
329 
330 
331 	//	printf("Status %d\n", status);
332 
333 
334 	if (status == 1) {
335 
336 		cipher = SSL_get_current_cipher(node->ctx);
337 		SSL_CIPHER_description(cipher, cipher_info, sizeof(cipher_info));
338 
339 #ifdef DEBUG
340 		printf("tls_auth_cont: connection %p switched to encryption! Protocol version: %s\n",node, SSL_get_version(node->ctx));
341 
342  		printf("tls_auth_cont: cipher %s\n", cipher_info);
343 #endif
344 
345 
346 		//printf("[tls] setting misc crap\n");
347 		//SSL_set_mode(node->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
348 		//SSL_set_mode(node->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
349 		SSL_set_mode(node->ctx,
350 					 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|SSL_MODE_ENABLE_PARTIAL_WRITE);
351 
352 
353 		node->use_ssl = 1;
354 		node->status  = ST_CONNECTED;
355 
356 		node->auth_type = LION_SSL_OFF;
357 
358 		// POST EVENT!
359 		_lion_userinput( node,
360 						node->user_data,
361 						LION_CONNECTION_SECURE_ENABLED,
362 						0, cipher_info);
363 
364 		// If we are in delay, we also need to issue connected now.
365 		// that is, if we are still connected
366 		if (node->want_ssl == LION_SSL_SERVER) {
367 
368 			node->want_ssl = LION_SSL_OFF;
369 
370 			if (node->status != ST_DISCONNECT)
371 				_lion_userinput( node,
372 								node->user_data,
373 								LION_CONNECTION_CONNECTED,
374 								0, NULL);
375 
376 		}
377 
378 		return;
379 
380 	} else {
381 
382 		//node->ssl_fd_mode = TLS_NONE;
383 
384 		switch (sslerr) {
385 		case SSL_ERROR_WANT_READ:
386 			node->want_mode = NET_WANT_READ;
387 #ifdef DEBUG
388 			printf("tls_auth_cont: Setting wantread - %d\n", node->status);
389 #endif
390 			//node->ssl_fd_mode = TLS_READ;
391 			break;
392 		case SSL_ERROR_WANT_WRITE:
393 #ifdef DEBUG
394 			printf("tls_auth_cont: Setting wantwrite - %d\n", node->status);
395 #endif
396 			node->want_mode = NET_WANT_WRITE;
397 			//printf("Setting wantwrite\n");
398 			//node->ssl_fd_mode = TLS_WRITE;
399 			break;
400 		default:
401 #ifdef DEBUG
402    			printf("tls_auth_cont: failed (%d, %d, %d)\n",
403 				   sslerr, status, errno);
404 #endif
405 
406 			if (node->trace)
407 				fprintf(trace_file, "%p: tls_auth_cont: failed (%d, %d, %d) => %s\n",
408 						node,
409 						sslerr, status, errno,
410 						(char *)ERR_error_string(ERR_get_error(), NULL));
411 
412 			node->use_ssl = 0;
413 			node->auth_type = LION_SSL_OFF;
414 			node->want_ssl  = LION_SSL_OFF;
415 			node->status = ST_CONNECTED;
416 
417 			// POST EVENT!
418 			_lion_userinput( node,
419 							node->user_data,
420 							LION_CONNECTION_SECURE_FAILED,
421 							0, NULL); // fixme, SSL_get_error
422 
423 
424 		}
425 	}
426 }
427 
428 
429 
430 
431 
432 
433 
434 
435 
tls_read(connection_t * node,void * buf,int num)436 int tls_read(connection_t *node, void *buf, int num)
437 {
438 	SSL *ssl;
439 	int status, sslerr;
440 
441 
442 	ssl = node->ctx;
443 
444 	status = SSL_read(ssl, (char *)buf, num);
445 	sslerr = SSL_get_error(ssl, status);
446 
447 #ifdef DEBUG_VERBOSE
448 	printf("tls_read: %d\n", status);
449 #endif
450 #ifdef DEBUG
451 	if (node->trace)
452 		fprintf(trace_file, "%p: lion_read(%d)\n", node,status);
453 #endif
454 
455 	if (status == -1) {
456 
457 		//ud->ssl_ctrl_func = TLS_READ;
458 
459 		switch (sslerr) {
460 
461 			// In READ mode, we get this "error" when we normally want more
462 			// to read, ie, EWOULDBLOCK. So it isn't really something we set
463 			// for read. We DO set it for write?
464 		case SSL_ERROR_WANT_READ:
465 			//node->want_mode = NET_WANT_READ;
466 #ifdef DEBUG
467 			//printf("tls_read: Setting wantread - %d\n", node->status);
468 #endif
469 			//			printf("tls_read: WANT_READ - do we deal with this?\n");
470 			//ud->ssl_ctrl_fd_mode = TLS_READ;
471 			return -2;
472 			break;
473 
474 			// Here, it is actually the same as "BUFFERFULL" status.
475 		case SSL_ERROR_WANT_WRITE:
476 #ifdef DEBUG
477 			printf("tls_read: Setting wantwrite - %d\n", node->status);
478 #endif
479 			//printf("tls_read: WANT_WRITE - do we deal with this?\n");
480 			node->want_mode = NET_WANT_WRITE;
481 			//ud->ssl_ctrl_fd_mode = TLS_WRITE;
482 			return -2;
483 			break;
484 		default:
485 #ifdef DEBUG
486 			printf("tls_read_error: %p %d,%d,%d\n", node, sslerr,
487 				   status, errno);
488 #endif
489 			return -1;
490 		}
491 
492 	} else {
493 
494 		node->want_mode = NET_WANT_NONE;
495 		//ud->ssl_ctrl_fd_mode = TLS_NONE;
496 
497 	}
498 
499 	return status;
500 }
501 
502 
tls_write(connection_t * node,void * buf,int num)503 int tls_write(connection_t *node, void *buf, int num)
504 {
505 	SSL *ssl;
506 	int status, sslerr;
507 
508 	ssl = node->ctx;
509 
510 	if (!node->ctx) {
511 		printf("[tls_write] ->ctx is NULL!?!\n");
512 		return -1;
513 	}
514 
515 #if 0
516 	int poo;
517 
518 	poo = fcntl(SSL_get_fd(ssl), F_GETFL);
519 	if (!(poo & O_NONBLOCK))
520 		printf("Warning, %d %d (%d)is blocking.\n",
521 			   SSL_get_fd(ssl), poo, poo & O_NONBLOCK);
522 #endif
523 
524 
525 
526 
527 	status = SSL_write(ssl, (char *)buf, num);
528 	sslerr = SSL_get_error(ssl, status);
529 
530 #if 0
531  {
532 	 time_t t;
533 	 time(&t);
534 	if (t - lion_global_time >= 2) {
535 		printf("SSL_write: operation took long time!\n");
536 		poo = fcntl(SSL_get_fd(ssl), F_GETFL);
537 		printf("Is nonblock: fd %d %d (%d)\n",
538 			   SSL_get_fd(ssl), poo, poo & O_NONBLOCK);
539 		sockets_setnonblocking(SSL_get_fd(ssl));
540 	}
541  }
542 #endif
543 
544 
545 
546 #ifdef DEBUG_VERBOSE
547 	printf("tls_write: %d - %s\n", status, (char *)buf);
548 #endif
549 #ifdef DEBUG
550 	if (node->trace)
551 		fprintf(trace_file, "%p: lion_write(%d)\n", node,status);
552 #endif
553 
554 
555 	if (status == -1) {
556 
557 		//ud->ssl_ctrl_func = TLS_READ;
558 
559 		switch (sslerr) {
560 
561 		case SSL_ERROR_WANT_READ:
562 			node->want_mode = NET_WANT_READ;
563 			//			printf("tls_write: WANT_READ - do we deal with this?\n");
564 			//ud->ssl_ctrl_fd_mode = TLS_READ;
565 			return -2;
566 			break;
567 		case SSL_ERROR_WANT_WRITE:
568 			//printf("tls_write: WANT_WRITE - do we deal with this?\n");
569 			//node->want_mode = NET_WANT_WRITE;
570 			//ud->ssl_ctrl_fd_mode = TLS_WRITE;
571 			return -2;
572 			break;
573 		default:
574 #ifdef DEBUG
575 			printf("tls_write_error: %p %d,%d,%d\n", node, sslerr,
576 				   status, errno);
577 #endif
578 			// This is often EAGAIN error, so return it as a real error
579 			// then we check against EAGAIN.
580 			return -1;
581 		}
582 
583 	} else {
584 
585 		node->want_mode = NET_WANT_NONE;
586 		//ud->ssl_ctrl_fd_mode = TLS_NONE;
587 
588 	}
589 
590 	return status;
591 }
592 
593 
594 
595 
596 
597 
598 
599 
600 
601 
602 
603 
tls_clauth(connection_t * node)604 int tls_clauth( connection_t *node )
605 {
606 
607 #ifdef DEBUG
608 	printf("tls_clauth(%p): %p\n", node, node->ctx);
609 #endif
610 
611 	if (node->trace)
612 		fprintf(trace_file, "%p: lion_clauth\n", node);
613 
614 	node->ctx = SSL_new(tls_ctx);
615 
616 	if (!node->ctx) {
617 
618 		printf("SSL: Failed to create new context -- disabling\n");
619 		node->use_ssl = 0;
620 
621 		return -1;
622 
623 	}
624 
625 
626 	if (RAND_status() != 1) {
627 		printf("ssl_init: System without /dev/urandom, PRNG seeding must be done manually\n");
628 		node->use_ssl = 0;
629 
630 		return -2;
631 	}
632 
633 
634 	SSL_set_cipher_list(node->ctx, ssl_tlsciphers);
635 
636 #ifdef DEBUG
637 	printf("Setting fd %d\n", node->socket);
638 #endif
639 
640 	if (SSL_set_fd(node->ctx, node->socket ) != 1)
641 		printf("SSL_set_fd_error");
642 
643 
644 	// Experimental
645 	node->status = ST_SSL_NEG;
646 	node->auth_type = LION_SSL_CLIENT;
647 
648 
649 #ifdef DEBUG
650 	printf("Status %d\n", node->status);
651 #endif
652 
653 	tls_cont_clauth(node);
654 
655 	return 1;
656 }
657 
658 
659 
tls_cont_clauth(connection_t * node)660 void tls_cont_clauth( connection_t *node )
661 {
662 	int status, sslerr;
663 	char cipher_info[128];
664 	SSL_CIPHER *cipher;
665 
666 	if (node->trace)
667 		fprintf(trace_file, "%p: tls_cont_clauth\n", node);
668 
669 #ifdef DEBUG
670 	printf("tls_cont_clauth: ... \n");
671 #endif
672 	//net_want_select( node->handle, NET_WANT_NONE);
673 	node->want_mode = NET_WANT_NONE;
674 
675 	status = SSL_connect(node->ctx);
676 	sslerr = SSL_get_error(node->ctx,status);
677 
678 
679 	//	printf("Status %d\n", status);
680 
681 
682 	if (status == 1) {
683 
684 		cipher = SSL_get_current_cipher(node->ctx);
685 		SSL_CIPHER_description(cipher, cipher_info, sizeof(cipher_info));
686 
687 #ifdef DEBUG
688 		printf("tls_clauth_cont: connection %p switched to encryption! Protocol version: %s\n",node, SSL_get_version(node->ctx));
689 
690  		printf("tls_clauth_cont: cipher %s\n", cipher_info);
691 #endif
692 
693 		node->use_ssl = 1;
694 
695 		node->status  = ST_CONNECTED;
696 
697 		node->auth_type = LION_SSL_OFF;
698 
699 		//SSL_set_mode(node->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
700 		SSL_set_mode(node->ctx,
701 					 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|SSL_MODE_ENABLE_PARTIAL_WRITE);
702 
703 		// POST EVENT!
704 		_lion_userinput( node,
705 						node->user_data,
706 						LION_CONNECTION_SECURE_ENABLED,
707 						0, cipher_info);
708 
709 		// If we are in delay, we also need to issue connected now.
710 		if (node->want_ssl == LION_SSL_CLIENT) {
711 
712 			node->want_ssl = LION_SSL_OFF;
713 
714 			_lion_userinput( node,
715 							node->user_data,
716 							LION_CONNECTION_CONNECTED,
717 							0, NULL);
718 		}
719 
720 		return;
721 
722 	} else {
723 
724 		//node->ssl_fd_mode = TLS_NONE;
725 
726 		switch (sslerr) {
727 		case SSL_ERROR_WANT_READ:
728 			node->want_mode = NET_WANT_READ;
729 #ifdef DEBUG
730 			printf("Setting wantread - %d\n", node->status);
731 #endif
732 			//node->ssl_fd_mode = TLS_READ;
733 			break;
734 		case SSL_ERROR_WANT_WRITE:
735 			node->want_mode = NET_WANT_WRITE;
736 			//printf("Setting wantwrite\n");
737 			//node->ssl_fd_mode = TLS_WRITE;
738 			break;
739 		default:
740 #ifdef DEBUG
741    			printf("tls_clauth_cont: failed (status,sslerr,errno) %d %d %d\n", status, sslerr, errno);
742 #endif
743 			if (node->trace)
744 				fprintf(trace_file, "%p: tls_clauth_cont: failed (%d, %d, %d) => %s\n",
745 						node,
746 						sslerr, status, errno,
747 						(char *)ERR_error_string(ERR_get_error(), NULL));
748 
749 			node->use_ssl = 0;
750 			node->want_ssl = LION_SSL_OFF;
751 			node->auth_type = LION_SSL_OFF;
752 
753 			// POST EVENT!
754 			_lion_userinput( node,
755 							node->user_data,
756 							LION_CONNECTION_SECURE_FAILED,
757 							0, NULL); // fixme
758 
759 			// if client haven't disconnected, we send connected_event
760 			if (node->status != ST_DISCONNECT) {
761 
762 				// If we are in delay, we also need to issue connected now.
763 				if (node->want_ssl == LION_SSL_CLIENT) {
764 
765 					node->status   = ST_CONNECTED;
766 
767 					_lion_userinput( node,
768 									node->user_data,
769 									LION_CONNECTION_CONNECTED,
770 									0, NULL);
771 
772 				}
773 			}
774 		}
775 	}
776 }
777 
778 
779 
780 
781 //
782 // return 0 - is SSL auth started - SSL_NEG status is set.
783 // return 1 - plain text input.
784 //
tls_peek(connection_t * node)785 int tls_peek(connection_t *node)
786 {
787 	char buffer;
788 	int ret;
789 
790 	// peek() ahead, check if its SSL handshake.
791 	// if it is, start authentication, if not, return.
792 
793 	ret = sockets_peek(node->socket, &buffer, 1);
794 
795 #ifdef DEBUG
796 	printf("SSL Autosensing %d:%x\n", ret, buffer);
797 #endif
798 
799 	if (ret == 1) {
800 
801 		// check for SSL handshake, currently, only v2 and v3 is known.
802 		if ((buffer == SSL3_RT_HANDSHAKE) ||
803 			(buffer & 0x80)) {
804 
805 #ifdef DEBUG
806 			printf("Autosensed SSL handshake\n");
807 #endif
808 
809 			return tls_auth(node);
810 
811 		}
812 
813 	}
814 
815 	// It is plain-text, we need to send sec_failed and connected events.
816 
817 	node->use_ssl   = 0;
818 	node->want_ssl  = LION_SSL_OFF;
819 	node->auth_type = LION_SSL_OFF;
820 
821 
822 	_lion_userinput( node,
823 					node->user_data,
824 					LION_CONNECTION_SECURE_FAILED,
825 					0, NULL); // fixme
826 
827 
828 	if (node->socket != ST_DISCONNECT) {
829 
830 		node->status   = ST_CONNECTED;
831 
832 		_lion_userinput( node,
833 						node->user_data,
834 						LION_CONNECTION_CONNECTED,
835 						0, NULL);
836 	}
837 
838 
839 	return 1;
840 
841 }
842 
843 
844 
845 
846 
847 
848 
849 #endif // WITH_SSL
850