1
+ /* ******************************************************************************
2
+ * Copyright (c) 2023 Red Hat, Inc.
3
+ * Distributed under license by Red Hat, Inc. All rights reserved.
4
+ * This program is made available under the terms of the
5
+ * Eclipse Public License v2.0 which accompanies this distribution,
6
+ * and is available at http://www.eclipse.org/legal/epl-v20.html
7
+ *
8
+ * Contributors:
9
+ * Red Hat, Inc. - initial API and implementation
10
+ ******************************************************************************/
11
+ package com.redhat.devtools.intellij.kubernetes.model.client.ssl
12
+
13
+ import com.intellij.openapi.diagnostic.logger
14
+ import com.intellij.util.net.ssl.CertificateManager
15
+ import com.intellij.util.net.ssl.ConfirmingTrustManager
16
+ import javax.net.ssl.X509ExtendedTrustManager
17
+ import javax.net.ssl.X509TrustManager
18
+ import org.apache.commons.lang3.reflect.FieldUtils
19
+
20
+ object IDEATrustManager {
21
+
22
+ fun configure (clientTrustManagers : Array <X509ExtendedTrustManager >): ConfirmingTrustManager {
23
+ val ideTrustManager = CertificateManager .getInstance().trustManager
24
+ try {
25
+ if (hasSystemManagerField()) {
26
+ // < IC-2022.2
27
+ setCompositeManager(clientTrustManagers, ideTrustManager)
28
+ } else {
29
+ // >= IC-2022.2
30
+ addCompositeManager(clientTrustManagers, ideTrustManager)
31
+ }
32
+ } catch (e: RuntimeException ) {
33
+ logger<IDEATrustManager >().warn(" Could not configure IDEA trust manager." , e)
34
+ }
35
+ return ideTrustManager
36
+ }
37
+
38
+ /* *
39
+ * Returns `true` if [ConfirmingTrustManager] has a private field `mySystemManager`.
40
+ * Returns `false` otherwise.
41
+ * IDEA < IC-2022.2 manages a single [X509TrustManager] in a private field called `mySystemManager`.
42
+ * IDEA >= IC-2022.2 manages a list of [X509TrustManager]s in a private list called `mySystemManagers`.
43
+ */
44
+ private fun hasSystemManagerField (): Boolean {
45
+ return FieldUtils .getDeclaredField(
46
+ ConfirmingTrustManager ::class .java, " mySystemManager" , true ) != null
47
+ }
48
+
49
+ private fun setCompositeManager (
50
+ clientTrustManagers : Array <X509ExtendedTrustManager >,
51
+ ideTrustManager : ConfirmingTrustManager
52
+ ): Boolean {
53
+ val systemManagerField = FieldUtils .getDeclaredField(
54
+ ConfirmingTrustManager ::class .java, " mySystemManager" , true ) ? : return false
55
+ val systemManager = systemManagerField.get(ideTrustManager) as ? X509ExtendedTrustManager ? : return false
56
+ val compositeTrustManager = createCompositeTrustManager(systemManager, clientTrustManagers)
57
+ systemManagerField.set(ideTrustManager, compositeTrustManager)
58
+ return true
59
+ }
60
+
61
+ private fun addCompositeManager (
62
+ clientTrustManagers : Array <X509ExtendedTrustManager >,
63
+ ideTrustManager : ConfirmingTrustManager
64
+ ) {
65
+ val systemManagersField =
66
+ FieldUtils .getDeclaredField(ideTrustManager::class .java, " mySystemManagers" , true )
67
+ val managers = systemManagersField.get(ideTrustManager) as ? MutableList <X509TrustManager > ? : return
68
+ val nonCompositeManagers = managers.filterNot { it is CompositeX509ExtendedTrustManager }
69
+ val clientTrustManager = CompositeX509ExtendedTrustManager (clientTrustManagers.asList())
70
+ managers.clear()
71
+ managers.addAll(nonCompositeManagers)
72
+ managers.add(clientTrustManager)
73
+ }
74
+
75
+ private fun createCompositeTrustManager (
76
+ systemManager : X509ExtendedTrustManager ,
77
+ clientTrustManagers : Array <X509ExtendedTrustManager >
78
+ ): X509ExtendedTrustManager {
79
+ val compositeTrustManager = if (systemManager is CompositeX509ExtendedTrustManager ) {
80
+ // already patched CertificateManager, re-create composite manager
81
+ CompositeX509ExtendedTrustManager (
82
+ mutableListOf (systemManager.innerTrustManagers[0 ])
83
+ .plus(clientTrustManagers)
84
+ )
85
+ } else {
86
+ // 1st time we patch CertificateManager, create composite manager
87
+ CompositeX509ExtendedTrustManager (
88
+ mutableListOf (systemManager)
89
+ .plus(clientTrustManagers)
90
+ )
91
+ }
92
+ return compositeTrustManager
93
+ }
94
+
95
+ }
0 commit comments