From 50410604985fd804ce7df999e1f87469bfba6ec3 Mon Sep 17 00:00:00 2001 From: Gary Date: Thu, 20 Aug 2020 11:10:25 -0400 Subject: [PATCH 1/5] Update to support insecure SSL validation Signed-off-by: Gary --- src/clj_http/lite/core.clj | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/clj_http/lite/core.clj b/src/clj_http/lite/core.clj index 5bdc6b05..9d3147fb 100644 --- a/src/clj_http/lite/core.clj +++ b/src/clj_http/lite/core.clj @@ -2,7 +2,9 @@ "Core HTTP request/response implementation." (:require [clojure.java.io :as io]) (:import (java.io ByteArrayOutputStream InputStream IOException) - (java.net URI URL HttpURLConnection))) + (java.net URI URL HttpURLConnection) + (javax.net.ssl SSLContext X509TrustManager TrustManager HttpsURLConnection HostnameVerifier SSLSession) + (java.security SecureRandom))) (set! *warn-on-reflection* true) @@ -41,6 +43,19 @@ (.flush baos) (.toByteArray baos))))) +(defn my-host-verifier [] + (proxy [HostnameVerifier] [] + (verify [^String hostname ^SSLSession session] true))) + +(defn trust-invalid-manager [] + "This allows the ssl socket to connect with invalid/self-signed SSL certs." + (reify X509TrustManager + (getAcceptedIssuers [this] nil) + (checkClientTrusted [this certs authType]) + (checkServerTrusted [this certs authType]) + ) + ) + (defn request "Executes the HTTP request corresponding to the given Ring request map and returns the Ring response map corresponding to the resulting HTTP response. @@ -55,7 +70,11 @@ (when server-port (str ":" server-port)) uri (when query-string (str "?" query-string))) - ^HttpURLConnection conn (.openConnection ^URL (URL. http-url))] + ^HttpURLConnection conn (.openConnection ^URL (URL. http-url)) + ssl-context (doto (SSLContext/getInstance "SSL") + (.init nil (into-array TrustManager [(trust-invalid-manager)]) (new SecureRandom)))] + (when insecure? (HttpsURLConnection/setDefaultSSLSocketFactory (.getSocketFactory ssl-context)) + (HttpsURLConnection/setDefaultHostnameVerifier (my-host-verifier))) (when (and content-type character-encoding) (.setRequestProperty conn "Content-Type" (str content-type "; charset=" From f549627b7b9bdb8739e3b5592e72ffe091b7c51f Mon Sep 17 00:00:00 2001 From: Gary Date: Thu, 20 Aug 2020 20:24:03 -0400 Subject: [PATCH 2/5] Update to support Self-signed Cert and auth Signed-off-by: Gary --- src/clj_http/lite/core.clj | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/clj_http/lite/core.clj b/src/clj_http/lite/core.clj index 9d3147fb..68fd3ce9 100644 --- a/src/clj_http/lite/core.clj +++ b/src/clj_http/lite/core.clj @@ -70,11 +70,14 @@ (when server-port (str ":" server-port)) uri (when query-string (str "?" query-string))) - ^HttpURLConnection conn (.openConnection ^URL (URL. http-url)) - ssl-context (doto (SSLContext/getInstance "SSL") - (.init nil (into-array TrustManager [(trust-invalid-manager)]) (new SecureRandom)))] - (when insecure? (HttpsURLConnection/setDefaultSSLSocketFactory (.getSocketFactory ssl-context)) - (HttpsURLConnection/setDefaultHostnameVerifier (my-host-verifier))) + _ (when insecure? + (do (HttpsURLConnection/setDefaultSSLSocketFactory + (.getSocketFactory + (doto (SSLContext/getInstance "TLS") + (.init nil (into-array TrustManager [(trust-invalid-manager)]) + (new SecureRandom))))) + (HttpsURLConnection/setDefaultHostnameVerifier (my-host-verifier)))) + ^HttpURLConnection conn (.openConnection ^URL (URL. http-url))] (when (and content-type character-encoding) (.setRequestProperty conn "Content-Type" (str content-type "; charset=" @@ -99,9 +102,9 @@ (with-open [out (.getOutputStream conn)] (io/copy body out))) (merge {:headers (parse-headers conn) - :status (.getResponseCode conn) - :body (when-not (= request-method :head) - (coerce-body-entity req conn))} + :status (.getResponseCode conn) + :body (when-not (= request-method :head) + (coerce-body-entity req conn))} (when save-request? {:request (assoc (dissoc req :save-request?) :http-url http-url)})))) From 714ecab9fc0df7fc1747ad6ed7433a6314078f41 Mon Sep 17 00:00:00 2001 From: Gary Berger <58652+gaberger@users.noreply.github.com> Date: Mon, 24 Aug 2020 12:12:02 -0400 Subject: [PATCH 3/5] Update src/clj_http/lite/core.clj Co-authored-by: Martin Klepsch --- src/clj_http/lite/core.clj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/clj_http/lite/core.clj b/src/clj_http/lite/core.clj index 68fd3ce9..f399f597 100644 --- a/src/clj_http/lite/core.clj +++ b/src/clj_http/lite/core.clj @@ -52,9 +52,7 @@ (reify X509TrustManager (getAcceptedIssuers [this] nil) (checkClientTrusted [this certs authType]) - (checkServerTrusted [this certs authType]) - ) - ) + (checkServerTrusted [this certs authType]))) (defn request "Executes the HTTP request corresponding to the given Ring request map and From 40634dc62d2e9d0b15c8f8ca793032b5a53b8426 Mon Sep 17 00:00:00 2001 From: Gary Date: Mon, 24 Aug 2020 12:35:34 -0400 Subject: [PATCH 4/5] Update for PR Signed-off-by: Gary --- CHANGELOG.md | 3 +++ Readme.md | 1 - deps.edn | 3 +-- src/clj_http/lite/core.clj | 10 ++++------ 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22845686..ed54f0dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### unreleased +Update to support self-signed certificates via insecure? option + ### 0.4.3 - **Feature:** Parse link headers from response and put them under `:links` ([#1](https://github.com/martinklepsch/clj-http-lite/pull/1)) diff --git a/Readme.md b/Readme.md index 53ac177f..dbe0a6d3 100644 --- a/Readme.md +++ b/Readme.md @@ -22,7 +22,6 @@ A Clojure HTTP library similar to [clj-http](http://github.com/dakrone/clj-http) - No proxy-ing DELETEs with body - No multipart form uploads - No persistent connection support -- No support for insecure HTTPS connection (yet) - namespace rename clj-http.* -> clj-http.lite.* ## Usage diff --git a/deps.edn b/deps.edn index 2c567bea..934123d7 100644 --- a/deps.edn +++ b/deps.edn @@ -1,3 +1,2 @@ {:paths ["src"] - :deps {org.clojure/clojure {:mvn/version "1.6.0"} - slingshot {:mvn/version "0.12.1"}}} + :deps {org.clojure/clojure {:mvn/version "1.10.0"}}} diff --git a/src/clj_http/lite/core.clj b/src/clj_http/lite/core.clj index 68fd3ce9..f0c2f4f4 100644 --- a/src/clj_http/lite/core.clj +++ b/src/clj_http/lite/core.clj @@ -2,8 +2,8 @@ "Core HTTP request/response implementation." (:require [clojure.java.io :as io]) (:import (java.io ByteArrayOutputStream InputStream IOException) - (java.net URI URL HttpURLConnection) - (javax.net.ssl SSLContext X509TrustManager TrustManager HttpsURLConnection HostnameVerifier SSLSession) + (java.net URL HttpURLConnection) + (javax.net.ssl HttpsURLConnection SSLContext TrustManager X509TrustManager HostnameVerifier SSLSession) (java.security SecureRandom))) (set! *warn-on-reflection* true) @@ -52,9 +52,7 @@ (reify X509TrustManager (getAcceptedIssuers [this] nil) (checkClientTrusted [this certs authType]) - (checkServerTrusted [this certs authType]) - ) - ) + (checkServerTrusted [this certs authType]))) (defn request "Executes the HTTP request corresponding to the given Ring request map and @@ -73,7 +71,7 @@ _ (when insecure? (do (HttpsURLConnection/setDefaultSSLSocketFactory (.getSocketFactory - (doto (SSLContext/getInstance "TLS") + (doto (SSLContext/getInstance "SSL") (.init nil (into-array TrustManager [(trust-invalid-manager)]) (new SecureRandom))))) (HttpsURLConnection/setDefaultHostnameVerifier (my-host-verifier)))) From 49849a6d79d94a7edd8d57f2d5ee19186146d258 Mon Sep 17 00:00:00 2001 From: Martin Klepsch Date: Mon, 31 Aug 2020 13:11:25 +0200 Subject: [PATCH 5/5] undo whitespace changes --- src/clj_http/lite/core.clj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clj_http/lite/core.clj b/src/clj_http/lite/core.clj index f0c2f4f4..a002df1f 100644 --- a/src/clj_http/lite/core.clj +++ b/src/clj_http/lite/core.clj @@ -100,9 +100,9 @@ (with-open [out (.getOutputStream conn)] (io/copy body out))) (merge {:headers (parse-headers conn) - :status (.getResponseCode conn) - :body (when-not (= request-method :head) - (coerce-body-entity req conn))} + :status (.getResponseCode conn) + :body (when-not (= request-method :head) + (coerce-body-entity req conn))} (when save-request? {:request (assoc (dissoc req :save-request?) :http-url http-url)}))))