@@ -182,17 +182,17 @@ extension _EasyHandle {
182
182
_config = config
183
183
}
184
184
185
- /// Set allowed protocols
185
+ /// Set the CA bundle path automatically if it isn't set
186
186
///
187
- /// - Note: This has security implications. Not limiting this, someone could
188
- /// redirect a HTTP request into one of the many other protocols that libcurl
189
- /// supports.
190
- /// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html
191
- /// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_REDIR_PROTOCOLS.html
192
- func setAllowedProtocolsToHTTPAndHTTPS ( ) {
193
- let protocols = ( CFURLSessionProtocolHTTP | CFURLSessionProtocolHTTPS )
194
- try ! CFURLSession_easy_setopt_long ( rawHandle , CFURLSessionOptionPROTOCOLS , protocols ) . asError ( )
195
- try ! CFURLSession_easy_setopt_long ( rawHandle , CFURLSessionOptionREDIR_PROTOCOLS , protocols ) . asError ( )
187
+ /// Curl does not necessarily know where to find the CA root bundle,
188
+ /// and in that case we need to specify where it is. There was a hack
189
+ /// to do this automatically for Android but allowing an environment
190
+ /// variable to control the location of the CA root bundle seems like
191
+ /// a security issue in general.
192
+ ///
193
+ /// Rather than doing that, we have a list of places we might expect
194
+ /// to find it, and search those until we locate a suitable file.
195
+ func setCARootBundlePath ( ) {
196
196
#if os(Android)
197
197
// See https://curl.haxx.se/docs/sslcerts.html
198
198
// For SSL on Android you need a "cacert.pem" to be
@@ -205,8 +205,58 @@ extension _EasyHandle {
205
205
else {
206
206
try ! CFURLSession_easy_setopt_ptr ( rawHandle, CFURLSessionOptionCAINFO, caInfo) . asError ( )
207
207
}
208
+ return
208
209
}
209
210
#endif
211
+
212
+ #if !NS_CURL_MISSING_CURLINFO_CAINFO
213
+ #if !os(Windows) && !os(macOS) && !os(iOS) && !os(watchOS) && !os(tvOS)
214
+ // Check if there is a default path; if there is, it will already
215
+ // be set, so leave things alone
216
+ var p : UnsafeMutablePointer < Int8 > ? = nil
217
+
218
+ try ! CFURLSession_easy_getinfo_charp ( rawHandle, CFURLSessionInfoCAINFO, & p) . asError ( )
219
+
220
+ if p != nil {
221
+ return
222
+ }
223
+
224
+ // Otherwise, search a list of known paths
225
+ let paths = [
226
+ " /etc/ssl/certs/ca-certificates.crt " ,
227
+ " /etc/pki/tls/certs/ca-bundle.crt " ,
228
+ " /usr/share/ssl/certs/ca-bundle.crt " ,
229
+ " /usr/local/share/certs/ca-root-nss.crt " ,
230
+ " /etc/ssl/cert.pem "
231
+ ]
232
+
233
+ for path in paths {
234
+ var isDirectory : ObjCBool = false
235
+ if FileManager . default. fileExists ( atPath: path,
236
+ isDirectory: & isDirectory)
237
+ && !isDirectory. boolValue {
238
+ path. withCString { pathPtr in
239
+ try ! CFURLSession_easy_setopt_ptr ( rawHandle, CFURLSessionOptionCAINFO, UnsafeMutablePointer ( mutating: pathPtr) ) . asError ( )
240
+ }
241
+ return
242
+ }
243
+ }
244
+ #endif // !os(Windows) && !os(macOS) && !os(iOS) && !os(watchOS) && !os(tvOS)
245
+ #endif // !NS_CURL_MISSING_CURLINFO_CAINFO
246
+ }
247
+
248
+ /// Set allowed protocols
249
+ ///
250
+ /// - Note: This has security implications. Not limiting this, someone could
251
+ /// redirect a HTTP request into one of the many other protocols that libcurl
252
+ /// supports.
253
+ /// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html
254
+ /// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_REDIR_PROTOCOLS.html
255
+ func setAllowedProtocolsToHTTPAndHTTPS( ) {
256
+ let protocols = ( CFURLSessionProtocolHTTP | CFURLSessionProtocolHTTPS)
257
+ try ! CFURLSession_easy_setopt_long ( rawHandle, CFURLSessionOptionPROTOCOLS, protocols) . asError ( )
258
+ try ! CFURLSession_easy_setopt_long ( rawHandle, CFURLSessionOptionREDIR_PROTOCOLS, protocols) . asError ( )
259
+ setCARootBundlePath ( )
210
260
//TODO: Added in libcurl 7.45.0
211
261
//TODO: Set default protocol for schemeless URLs
212
262
//CURLOPT_DEFAULT_PROTOCOL available only in libcurl 7.45.0
@@ -217,6 +267,7 @@ extension _EasyHandle {
217
267
let redirectProtocols = ( CFURLSessionProtocolHTTP | CFURLSessionProtocolHTTPS)
218
268
try ! CFURLSession_easy_setopt_long ( rawHandle, CFURLSessionOptionPROTOCOLS, protocols) . asError ( )
219
269
try ! CFURLSession_easy_setopt_long ( rawHandle, CFURLSessionOptionREDIR_PROTOCOLS, redirectProtocols) . asError ( )
270
+ setCARootBundlePath ( )
220
271
}
221
272
222
273
//TODO: Proxy setting, namely CFURLSessionOptionPROXY, CFURLSessionOptionPROXYPORT,
0 commit comments