CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ssl.cc
Go to the documentation of this file.
1 
5 #include "ssl.h"
6 
7 #include <dirent.h>
8 
9 #include <cstdlib>
10 #include <string>
11 #include <vector>
12 
13 #include "duplex_curl.h"
14 #include "util/platform.h"
15 #include "util/posix.h"
16 #include "util/string.h"
17 
18 namespace {
19 
20 bool HasCertificates(const std::string &directory) {
21  DIR *dirp = opendir(directory.c_str());
22  if (!dirp)
23  return false;
24 
25  platform_dirent64 *dirent;
26  while ((dirent = platform_readdir(dirp))) {
27  const std::string filename(directory + "/" + std::string(dirent->d_name));
28 
29  platform_stat64 stat;
30  if (platform_stat(filename.c_str(), &stat) != 0)
31  continue;
32  if (!(S_ISREG(stat.st_mode) || S_ISLNK(stat.st_mode)))
33  continue;
34 
35  if (HasSuffix(filename, ".pem", /* ignore case = */ false)
36  || HasSuffix(filename, ".crt", /* ignore case = */ false)) {
37  closedir(dirp);
38  return true;
39  }
40  }
41 
42  closedir(dirp);
43  return false;
44 }
45 
46 } // namespace
47 
48 
50  const char *ca_path_env = getenv("X509_CERT_DIR");
51  if (ca_path_env && *ca_path_env)
52  ca_path_ = ca_path_env;
53  else
54  ca_path_ = "/etc/grid-security/certificates";
55  const char *ca_bundle_env = getenv("X509_CERT_BUNDLE");
56  if (ca_bundle_env && *ca_bundle_env)
57  ca_bundle_ = ca_bundle_env;
58 }
59 
60 
62  const CURLcode res1 =
63  curl_easy_setopt(handle, CURLOPT_CAPATH, ca_path_.c_str());
64  CURLcode res2 = CURLE_OK;
65  if (!ca_bundle_.empty())
66  res2 = curl_easy_setopt(handle, CURLOPT_CAINFO, ca_bundle_.c_str());
67 
68  return (res1 == CURLE_OK) && (res2 == CURLE_OK);
69 }
70 
71 
73  std::vector<std::string> candidates;
74 
75  candidates.push_back("/etc/ssl/certs");
76  candidates.push_back("/etc/pki/tls/certs");
77  candidates.push_back("/etc/ssl");
78  candidates.push_back("/etc/pki/tls");
79  candidates.push_back("/etc/pki/ca-trust/extracted/pem");
80  candidates.push_back("/etc/ssl");
81 
82  for (unsigned i = 0; i < candidates.size(); ++i) {
83  if (HasCertificates(candidates[i])) {
84  const std::string bundle_candidate = candidates[i] + "/ca-bundle.crt";
85  if (ca_bundle_.empty()
86  && (FileExists(bundle_candidate)
87  || SymlinkExists(bundle_candidate))) {
88  ca_bundle_ = bundle_candidate;
89  }
90  ca_path_ = candidates[i];
91  return;
92  }
93  }
94 
95  // fallback
96  ca_path_ = candidates[0];
97 }
struct stat64 platform_stat64
int platform_stat(const char *path, platform_stat64 *buf)
bool HasCertificates(const std::string &directory)
Definition: ssl.cc:20
bool SymlinkExists(const std::string &path)
Definition: posix.cc:833
bool FileExists(const std::string &path)
Definition: posix.cc:803
bool ApplySslCertificatePath(CURL *handle) const
Definition: ssl.cc:61
bool HasSuffix(const std::string &str, const std::string &suffix, const bool ignore_case)
Definition: string.cc:296
void UseSystemCertificatePath()
Definition: ssl.cc:72
std::string ca_bundle_
Definition: ssl.h:31
std::string ca_path_
Definition: ssl.h:30
platform_dirent64 * platform_readdir(DIR *dirp)
SslCertificateStore()
Definition: ssl.cc:49
struct dirent64 platform_dirent64