Преглед изворни кода

Conditionally disable SSL_VERIFY_FAIL_IF_NO_PEER_CERT

Alternative implementation of #443
bel2125 пре 8 година
родитељ
комит
a8a191ba7b
1 измењених фајлова са 41 додато и 12 уклоњено
  1. 41 12
      src/civetweb.c

+ 41 - 12
src/civetweb.c

@@ -1834,7 +1834,10 @@ static struct mg_option config_options[] = {
     {"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"},
     {"keep_alive_timeout_ms", CONFIG_TYPE_NUMBER, "500"},
     {"linger_timeout_ms", CONFIG_TYPE_NUMBER, NULL},
+
+    /* TODO(Feature): this is no longer a boolean, but yes/no/optional */
     {"ssl_verify_peer", CONFIG_TYPE_BOOLEAN, "no"},
+
     {"ssl_ca_path", CONFIG_TYPE_DIRECTORY, NULL},
     {"ssl_ca_file", CONFIG_TYPE_FILE, NULL},
     {"ssl_verify_depth", CONFIG_TYPE_NUMBER, "9"},
@@ -3282,6 +3285,7 @@ send_additional_header(struct mg_connection *conn)
 	(void)conn;
 
 #if 0
+	/* TODO (Feature): Configure additional response header */
 	i += mg_printf(conn, "Strict-Transport-Security: max-age=%u\r\n", 3600);
 	i += mg_printf(conn, "X-Some-Test-Header: %u\r\n", 42);
 #endif
@@ -3978,7 +3982,7 @@ mg_stat(const struct mg_connection *conn,
 
 		/* The "file in memory" feature is a candidate for deletion.
 		 * Please join the discussion at
-		 * https://groups.google.com/forum/#!topic/civetweb/h9HT4CmeYqI 
+		 * https://groups.google.com/forum/#!topic/civetweb/h9HT4CmeYqI
 		 */
 
 		filep->last_modified = time(NULL); /* TODO */
@@ -11122,7 +11126,7 @@ get_request_handler(struct mg_connection *conn,
 static int
 is_in_script_path(const struct mg_connection *conn, const char *path)
 {
-	/* TODO: Add config value for allowed script path.
+	/* TODO (Feature): Add config value for allowed script path.
 	 * Default: All allowed. */
 	(void)conn;
 	(void)path;
@@ -12278,10 +12282,16 @@ refresh_trust(struct mg_connection *conn)
 	if (data_check != t) {
 		data_check = t;
 
-		should_verify_peer =
-		    (conn->ctx->config[SSL_DO_VERIFY_PEER] != NULL)
-		    && (mg_strcasecmp(conn->ctx->config[SSL_DO_VERIFY_PEER], "yes")
-		        == 0);
+		should_verify_peer = 0;
+		if (conn->ctx->config[SSL_DO_VERIFY_PEER] != NULL) {
+			if (mg_strcasecmp(conn->ctx->config[SSL_DO_VERIFY_PEER], "yes")
+			    == 0) {
+				should_verify_peer = 1;
+			} else if (mg_strcasecmp(conn->ctx->config[SSL_DO_VERIFY_PEER],
+			                         "optional") == 0) {
+				should_verify_peer = 1;
+			}
+		}
 
 		if (should_verify_peer) {
 			char *ca_path = conn->ctx->config[SSL_CA_PATH];
@@ -12808,6 +12818,7 @@ set_ssl_option(struct mg_context *ctx)
 	const char *chain;
 	int callback_ret;
 	int should_verify_peer;
+	int peer_certificate_optional;
 	const char *ca_path;
 	const char *ca_file;
 	int use_default_verify_paths;
@@ -12925,9 +12936,22 @@ set_ssl_option(struct mg_context *ctx)
 		}
 	}
 
-	should_verify_peer =
-	    (ctx->config[SSL_DO_VERIFY_PEER] != NULL)
-	    && (mg_strcasecmp(ctx->config[SSL_DO_VERIFY_PEER], "yes") == 0);
+	/* Should we support client certificates? */
+	/* Default is "no". */
+	should_verify_peer = 0;
+	peer_certificate_optional = 0;
+	if (ctx->config[SSL_DO_VERIFY_PEER] != NULL) {
+		if (mg_strcasecmp(ctx->config[SSL_DO_VERIFY_PEER], "yes") == 0) {
+			/* Yes, they are mandatory */
+			should_verify_peer = 1;
+			peer_certificate_optional = 0;
+		} else if (mg_strcasecmp(ctx->config[SSL_DO_VERIFY_PEER], "optional")
+		           == 0) {
+			/* Yes, they are optional */
+			should_verify_peer = 1;
+			peer_certificate_optional = 1;
+		}
+	}
 
 	use_default_verify_paths =
 	    (ctx->config[SSL_DEFAULT_VERIFY_PATHS] != NULL)
@@ -12948,9 +12972,14 @@ set_ssl_option(struct mg_context *ctx)
 			return 0;
 		}
 
-		SSL_CTX_set_verify(ctx->ssl_ctx,
-		                   SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
-		                   NULL);
+		if (peer_certificate_optional) {
+			SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, NULL);
+		} else {
+			SSL_CTX_set_verify(ctx->ssl_ctx,
+			                   SSL_VERIFY_PEER
+			                       | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+			                   NULL);
+		}
 
 		if (use_default_verify_paths
 		    && SSL_CTX_set_default_verify_paths(ctx->ssl_ctx) != 1) {