From 381cbf2dc135a79c3626ce405fa89da0b7182793 Mon Sep 17 00:00:00 2001
From: Andy Green <andy@warmcat.com>
Date: Tue, 3 May 2016 08:08:32 +0800
Subject: [PATCH] client fix reaction to tls failure

https://github.com/warmcat/libwebsockets/issues/508

Signed-off-by: Andy Green <andy@warmcat.com>
---
 README.test-apps.md       | 10 ++++++++++
 lib/client-handshake.c    |  3 +++
 lib/client.c              | 10 +++++++---
 lib/service.c             |  4 ++++
 test-server/test-client.c | 10 +++++++++-
 5 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/README.test-apps.md b/README.test-apps.md
index 60308dae..5f4d3479 100644
--- a/README.test-apps.md
+++ b/README.test-apps.md
@@ -78,6 +78,16 @@ same time as drawing random circles in the mirror protocol;
 if you connect to the test server using a browser at the
 same time you will be able to see the circles being drawn.
 
+The test client supports SSL too, use
+
+```bash
+$ libwebsockets-test-client localhost --ssl -s
+```
+
+the -s tells it to accept the default selfsigned cert from the server,
+otherwise it will strictly fail the connection if there is no CA cert to
+validate the server's certificate.
+
 
 Testing simple echo
 -------------------
diff --git a/lib/client-handshake.c b/lib/client-handshake.c
index cdc49d57..01a74d78 100644
--- a/lib/client-handshake.c
+++ b/lib/client-handshake.c
@@ -171,6 +171,9 @@ lws_client_connect_2(struct lws *wsi)
 		 * past here, we can't simply free the structs as error
 		 * handling as oom4 does.  We have to run the whole close flow.
 		 */
+		if (!wsi->protocol)
+			wsi->protocol = &wsi->context->protocols[0];
+
 		wsi->protocol->callback(wsi, LWS_CALLBACK_WSI_CREATE,
 					wsi->user_space, NULL, 0);
 		lws_set_timeout(wsi,
diff --git a/lib/client.c b/lib/client.c
index b4cd3361..e8b65ac8 100644
--- a/lib/client.c
+++ b/lib/client.c
@@ -264,7 +264,7 @@ some_wait:
 				if (n != SSL_ERROR_NONE) {
 					lwsl_err("SSL connect error %lu: %s\n",
 						n, ERR_error_string(n, sb));
-					return 0;
+					goto bail3;
 				}
 			}
 		} else
@@ -318,7 +318,7 @@ some_wait:
 					if (n != SSL_ERROR_NONE) {
 						lwsl_err("SSL connect error %lu: %s\n",
 							 n, ERR_error_string(n, sb));
-						return 0;
+						goto bail3;
 					}
 				}
 			}
@@ -343,7 +343,7 @@ some_wait:
 						 n, ERR_error_string(n, sb));
 					lws_close_free_wsi(wsi,
 						LWS_CLOSE_STATUS_NOSTATUS);
-					return 0;
+					return -1;
 				}
 			}
 #endif /* USE_WOLFSSL */
@@ -462,6 +462,10 @@ some_wait:
 
 bail3:
 		lwsl_info("closing conn at LWS_CONNMODE...SERVER_REPLY\n");
+		wsi->context->protocols[0].callback(wsi,
+				LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
+				wsi->user_space, NULL, 0);
+
 		lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
 		return -1;
 
diff --git a/lib/service.c b/lib/service.c
index c0820c69..ceab37a6 100644
--- a/lib/service.c
+++ b/lib/service.c
@@ -325,6 +325,10 @@ lws_service_timeout_check(struct lws *wsi, unsigned int sec)
 		 * cleanup like flush partials.
 		 */
 		wsi->socket_is_permanently_unusable = 1;
+		if (wsi->mode == LWSCM_WSCL_WAITING_SSL)
+			wsi->context->protocols[0].callback(wsi,
+					LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
+					wsi->user_space, NULL, 0);
 		lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
 
 		return 1;
diff --git a/test-server/test-client.c b/test-server/test-client.c
index 2f6ea10e..c26be7f2 100644
--- a/test-server/test-client.c
+++ b/test-server/test-client.c
@@ -335,7 +335,15 @@ int main(int argc, char **argv)
 	if (!strcmp(prot, "http") || !strcmp(prot, "ws"))
 		use_ssl = 0;
 	if (!strcmp(prot, "https") || !strcmp(prot, "wss"))
-		use_ssl = 1;
+		if (!use_ssl)
+			use_ssl = 1;
+
+	if (use_ssl) {
+		if (use_ssl == 1)
+			lwsl_notice(" Cert must validate correctly (use -s to allow selfsigned)\n");
+		else
+			lwsl_notice(" Selfsigned certs allowed\n");
+	}
 
 	/*
 	 * create the websockets context.  This tracks open connections and
-- 
GitLab