@@ -18,6 +18,19 @@ def initialize(
18
18
@logger = logger
19
19
end
20
20
21
+ # Writing certificates to the default system cert store requires
22
+ # superuser privilege. Instead, Conjur will use ${CONJUR_ROOT}/tmp/certs.
23
+ def self . default_cert_dir ( dir : Dir , fileutils : FileUtils )
24
+ if @default_cert_dir . blank?
25
+ conjur_root = __dir__ . slice ( 0 ..( __dir__ . index ( '/app' ) ) )
26
+ @default_cert_dir = File . join ( conjur_root , "tmp/certs" )
27
+ end
28
+
29
+ fileutils . mkdir_p ( @default_cert_dir ) unless dir . exist? ( @default_cert_dir . to_s )
30
+
31
+ @default_cert_dir
32
+ end
33
+
21
34
def oidc_client
22
35
@oidc_client ||= begin
23
36
issuer_uri = URI ( @authenticator . provider_uri )
@@ -99,7 +112,7 @@ def callback(code:, nonce:, code_verifier: nil)
99
112
100
113
# callback_with_temporary_cert wraps the callback method with commands
101
114
# to write & clean up a given certificate or cert chain in a given
102
- # directory. By default, Conjur's default cert store is used.
115
+ # directory. By default, ${CONJUR_ROOT}/tmp/certs is used.
103
116
#
104
117
# The temporary certificate file name is "x.n", where x is the hash of
105
118
# the certificate subject name, and n is incrememnted from 0 in case of
@@ -114,7 +127,7 @@ def callback_with_temporary_cert(
114
127
code :,
115
128
nonce :,
116
129
code_verifier : nil ,
117
- cert_dir : OpenSSL :: X509 :: DEFAULT_CERT_DIR ,
130
+ cert_dir : Authentication :: AuthnOidc :: V2 :: Client . default_cert_dir ,
118
131
cert_string : nil
119
132
)
120
133
c = -> { callback ( code : code , nonce : nonce , code_verifier : code_verifier ) }
@@ -148,6 +161,27 @@ def callback_with_temporary_cert(
148
161
symlink_a << symlink
149
162
end
150
163
164
+ if OpenIDConnect . http_config . nil? || OpenIDConnect . http_client . ssl . ca_path != cert_dir
165
+ config_proc = proc do |config |
166
+ config . ssl . ca_path = cert_dir
167
+ config . ssl . verify_mode = OpenSSL ::SSL ::VERIFY_PEER
168
+ end
169
+
170
+ # OpenIDConnect gem only accepts a single Faraday configuration
171
+ # through calls to its .http_config method, and future calls to
172
+ # the #http_config method return the first config instance.
173
+ #
174
+ # On the first call to OpenIDConnect.http_config, it will pass the
175
+ # new Faraday configuration to its dependency gems that also have
176
+ # nil configs. We can't be certain that each gem is configured
177
+ # with the same Faraday config and need them synchronized, so we
178
+ # inject them manually.
179
+ OpenIDConnect . class_variable_set ( :@@http_config , config_proc )
180
+ WebFinger . instance_variable_set ( :@http_config , config_proc )
181
+ SWD . class_variable_set ( :@@http_config , config_proc )
182
+ Rack ::OAuth2 . class_variable_set ( :@@http_config , config_proc )
183
+ end
184
+
151
185
c . call
152
186
ensure
153
187
symlink_a . each { |s | File . unlink ( s ) if s . present? && File . symlink? ( s ) }
@@ -174,7 +208,7 @@ def discovery_information(invalidate: false)
174
208
175
209
# discover wraps ::OpenIDConnect::Discovery::Provider::Config.discover!
176
210
# with commands to write & clean up a given certificate or cert chain in
177
- # a given directory. By default, Conjur's default cert store is used.
211
+ # a given directory. By default, ${CONJUR_ROOT}/tmp/certs is used.
178
212
#
179
213
# The temporary certificate file name is "x.n", where x is the hash of
180
214
# the certificate subject name, and n is incremented from 0 in case of
@@ -186,7 +220,7 @@ def discovery_information(invalidate: false)
186
220
def self . discover (
187
221
provider_uri :,
188
222
discovery_configuration : ::OpenIDConnect ::Discovery ::Provider ::Config ,
189
- cert_dir : OpenSSL :: X509 :: DEFAULT_CERT_DIR ,
223
+ cert_dir : default_cert_dir ,
190
224
cert_string : nil ,
191
225
jwks : false
192
226
)
@@ -226,6 +260,27 @@ def self.discover(
226
260
symlink_a << symlink
227
261
end
228
262
263
+ if OpenIDConnect . http_config . nil? || OpenIDConnect . http_client . ssl . ca_path != cert_dir
264
+ config_proc = proc do |config |
265
+ config . ssl . ca_path = cert_dir
266
+ config . ssl . verify_mode = OpenSSL ::SSL ::VERIFY_PEER
267
+ end
268
+
269
+ # OpenIDConnect gem only accepts a single Faraday configuration
270
+ # through calls to its .http_config method, and future calls to
271
+ # the #http_config method return the first config instance.
272
+ #
273
+ # On the first call to OpenIDConnect.http_config, it will pass the
274
+ # new Faraday configuration to its dependency gems that also have
275
+ # nil configs. We can't be certain that each gem is configured
276
+ # with the same Faraday config and need them synchronized, so we
277
+ # inject them manually.
278
+ OpenIDConnect . class_variable_set ( :@@http_config , config_proc )
279
+ WebFinger . instance_variable_set ( :@http_config , config_proc )
280
+ SWD . class_variable_set ( :@@http_config , config_proc )
281
+ Rack ::OAuth2 . class_variable_set ( :@@http_config , config_proc )
282
+ end
283
+
229
284
d . call
230
285
ensure
231
286
symlink_a . each { |s | File . unlink ( s ) if s . present? && File . symlink? ( s ) }
0 commit comments