CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
swissknife_lease_curl.cc
Go to the documentation of this file.
1 
6 
7 #include "cvmfs_config.h"
8 
9 #include "crypto/hash.h"
10 #include "gateway_util.h"
11 #include "json_document.h"
12 #include "ssl.h"
13 #include "util/logging.h"
14 #include "util/pointer.h"
15 #include "util/posix.h"
16 #include "util/string.h"
17 
18 namespace {
19 
20 CURL* PrepareCurl(const std::string& method) {
21  const char* user_agent_string = "cvmfs/" VERSION;
22 
23  CURL* h_curl = curl_easy_init();
24 
25  if (h_curl) {
26  curl_easy_setopt(h_curl, CURLOPT_NOPROGRESS, 1L);
27  curl_easy_setopt(h_curl, CURLOPT_USERAGENT, user_agent_string);
28  curl_easy_setopt(h_curl, CURLOPT_MAXREDIRS, 50L);
29  curl_easy_setopt(h_curl, CURLOPT_CUSTOMREQUEST, method.c_str());
30  }
31 
32  return h_curl;
33 }
34 
35 size_t RecvCB(void* buffer, size_t size, size_t nmemb, void* userp) {
36  CurlBuffer* my_buffer = static_cast<CurlBuffer*>(userp);
37 
38  if (size * nmemb < 1) {
39  return 0;
40  }
41 
42  my_buffer->data = static_cast<char*>(buffer);
43 
44  return my_buffer->data.size();
45 }
46 
47 } // namespace
48 
49 bool MakeAcquireRequest(const std::string& key_id, const std::string& secret,
50  const std::string& repo_path,
51  const std::string& repo_service_url,
52  CurlBuffer* buffer) {
53  CURLcode ret = static_cast<CURLcode>(0);
54 
55  CURL* h_curl = PrepareCurl("POST");
56  if (!h_curl) {
57  return false;
58  }
59 
60  const std::string payload = "{\"path\" : \"" + repo_path +
61  "\", \"api_version\" : \"" +
63  ", \"hostname\" : \"" + GetHostname() + "\"}";
64 
66  shash::HmacString(secret, payload, &hmac);
67 
70  cs.ApplySslCertificatePath(h_curl);
71 
72  const std::string header_str = std::string("Authorization: ") + key_id + " " +
73  Base64(hmac.ToString(false));
74  struct curl_slist* auth_header = NULL;
75  auth_header = curl_slist_append(auth_header, header_str.c_str());
76  curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
77 
78  // Make request to acquire lease from repo services
79  curl_easy_setopt(h_curl, CURLOPT_URL, (repo_service_url + "/leases").c_str());
80  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
81  static_cast<curl_off_t>(payload.length()));
82  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, payload.c_str());
83  curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION, RecvCB);
84  curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, buffer);
85 
86  ret = curl_easy_perform(h_curl);
87  if (ret) {
89  "Make lease acquire request failed: %d. Reply: %s", ret,
90  buffer->data.c_str());
91  }
92 
93  curl_easy_cleanup(h_curl);
94  h_curl = NULL;
95 
96  return !ret;
97 }
98 
99 bool MakeEndRequest(const std::string& method, const std::string& key_id,
100  const std::string& secret, const std::string& session_token,
101  const std::string& repo_service_url,
102  const std::string& request_payload, CurlBuffer* reply) {
103  CURLcode ret = static_cast<CURLcode>(0);
104 
105  CURL* h_curl = PrepareCurl(method);
106  if (!h_curl) {
107  return false;
108  }
109 
110  shash::Any hmac(shash::kSha1);
111  shash::HmacString(secret, session_token, &hmac);
112 
115  cs.ApplySslCertificatePath(h_curl);
116 
117  const std::string header_str = std::string("Authorization: ") + key_id + " " +
118  Base64(hmac.ToString(false));
119  struct curl_slist* auth_header = NULL;
120  auth_header = curl_slist_append(auth_header, header_str.c_str());
121  curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
122 
123  curl_easy_setopt(h_curl, CURLOPT_URL,
124  (repo_service_url + "/leases/" + session_token).c_str());
125  if (request_payload != "") {
126  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
127  static_cast<curl_off_t>(request_payload.length()));
128  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, request_payload.c_str());
129  } else {
130  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
131  static_cast<curl_off_t>(0));
132  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, NULL);
133  }
134  curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION, RecvCB);
135  curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, reply);
136 
137  ret = curl_easy_perform(h_curl);
138  if (ret) {
140  "Lease end request - curl_easy_perform failed: %d", ret);
141  }
142 
144  const JSON *reply_status =
145  JsonDocument::SearchInObject(reply_json->root(), "status", JSON_STRING);
146  const bool ok = (reply_status != NULL &&
147  std::string(reply_status->string_value) == "ok");
148  if (!ok) {
150  "Lease end request - error reply: %s",
151  reply->data.c_str());
152  }
153 
154  curl_easy_cleanup(h_curl);
155  h_curl = NULL;
156 
157  return ok && !ret;
158 }
int APIVersion()
Definition: gateway_util.cc:26
bool MakeEndRequest(const std::string &method, const std::string &key_id, const std::string &secret, const std::string &session_token, const std::string &repo_service_url, const std::string &request_payload, CurlBuffer *reply)
static JSON * SearchInObject(const JSON *json_object, const std::string &name, const json_type type)
std::string ToString(const bool with_suffix=false) const
Definition: hash.h:249
static CURL * PrepareCurl(const std::string &method)
std::string data
std::string GetHostname()
Definition: posix.cc:750
static JsonDocument * Create(const std::string &text)
bool ApplySslCertificatePath(CURL *handle) const
Definition: ssl.cc:58
void UseSystemCertificatePath()
Definition: ssl.cc:68
size_t RecvCB(void *buffer, size_t size, size_t nmemb, void *userp)
string StringifyInt(const int64_t value)
Definition: string.cc:78
string Base64(const string &data)
Definition: string.cc:504
static void MakeAcquireRequest(const gateway::GatewayKey &key, const std::string &repo_path, const std::string &repo_service_url, int llvl, CurlBuffer *buffer)
void HmacString(const std::string &key, const std::string &content, Any *any_digest)
Definition: hash.h:527
struct json_value JSON
Definition: helper_allow.cc:11
static void size_t size
Definition: smalloc.h:54
const JSON * root() const
Definition: json_document.h:25
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:528