CernVM-FS  2.13.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 "crypto/hash.h"
8 #include "gateway_util.h"
9 #include "json_document.h"
10 #include "json_document_write.h"
11 #include "ssl.h"
12 #include "util/logging.h"
13 #include "util/pointer.h"
14 #include "util/posix.h"
15 #include "util/string.h"
16 
17 #include <unistd.h>
18 
19 
20 namespace {
21 
22 CURL *PrepareCurl(const std::string &method) {
23  const char *user_agent_string = "cvmfs/" CVMFS_VERSION;
24 
25  CURL *h_curl = curl_easy_init();
26 
27  if (h_curl) {
28  curl_easy_setopt(h_curl, CURLOPT_NOPROGRESS, 1L);
29  curl_easy_setopt(h_curl, CURLOPT_USERAGENT, user_agent_string);
30  curl_easy_setopt(h_curl, CURLOPT_MAXREDIRS, 50L);
31  curl_easy_setopt(h_curl, CURLOPT_CUSTOMREQUEST, method.c_str());
32  }
33 
34  return h_curl;
35 }
36 
37 size_t RecvCB(void *buffer, size_t size, size_t nmemb, void *userp) {
38  CurlBuffer *my_buffer = static_cast<CurlBuffer *>(userp);
39 
40  if (size * nmemb < 1) {
41  return 0;
42  }
43 
44  my_buffer->data = my_buffer->data
45  + std::string(static_cast<char *>(buffer), nmemb);
46 
47  return nmemb;
48 }
49 
50 } // namespace
51 
52 bool MakeAcquireRequest(const std::string& key_id, const std::string& secret,
53  const std::string& repo_path,
54  const std::string& repo_service_url,
55  CurlBuffer* buffer,
56  const std::string& metadata) {
57  CURLcode ret = static_cast<CURLcode>(0);
58 
59  CURL *h_curl = PrepareCurl("POST");
60  if (!h_curl) {
61  return false;
62  }
63 
64  JsonStringGenerator payloadJson;
65  payloadJson.Add("path", repo_path);
66  payloadJson.Add("api_version", StringifyInt(gateway::APIVersion()));
67  payloadJson.Add("hostname", GetHostname());
68  if (!metadata.empty()) {
69  payloadJson.AddJsonObject("metadata", metadata);
70  }
71  const std::string payload = payloadJson.GenerateString();
72 
74  shash::HmacString(secret, payload, &hmac);
75 
78  cs.ApplySslCertificatePath(h_curl);
79 
80  const std::string header_str = std::string("Authorization: ") + key_id + " "
81  + Base64(hmac.ToString(false));
82  struct curl_slist *auth_header = NULL;
83  auth_header = curl_slist_append(auth_header, header_str.c_str());
84  curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
85 
86  // Make request to acquire lease from repo services
87  curl_easy_setopt(h_curl, CURLOPT_URL, (repo_service_url + "/leases").c_str());
88  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
89  static_cast<curl_off_t>(payload.length()));
90  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, payload.c_str());
91  curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION, RecvCB);
92  curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, buffer);
93 
94  ret = curl_easy_perform(h_curl);
95  if (ret) {
97  "Make lease acquire request failed: %d. Reply: %s", ret,
98  buffer->data.c_str());
99  }
100 
101  curl_easy_cleanup(h_curl);
102  h_curl = NULL;
103 
104  return !ret;
105 }
106 
107 bool MakeEndRequest(const std::string& method, const std::string& key_id,
108  const std::string& secret, const std::string& session_token,
109  const std::string& repo_service_url,
110  const std::string& request_payload, CurlBuffer* reply, bool expect_final_revision) {
111  CURLcode ret = static_cast<CURLcode>(0);
112 
113  CURL *h_curl = PrepareCurl(method);
114  if (!h_curl) {
115  return false;
116  }
117 
118  shash::Any hmac(shash::kSha1);
119  shash::HmacString(secret, session_token, &hmac);
120 
123  cs.ApplySslCertificatePath(h_curl);
124 
125  const std::string header_str = std::string("Authorization: ") + key_id + " "
126  + Base64(hmac.ToString(false));
127  struct curl_slist *auth_header = NULL;
128  auth_header = curl_slist_append(auth_header, header_str.c_str());
129  curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);
130 
131  curl_easy_setopt(h_curl, CURLOPT_URL,
132  (repo_service_url + "/leases/" + session_token).c_str());
133  if (request_payload != "") {
134  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
135  static_cast<curl_off_t>(request_payload.length()));
136  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, request_payload.c_str());
137  } else {
138  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
139  static_cast<curl_off_t>(0));
140  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, NULL);
141  }
142  curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION, RecvCB);
143  curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, reply);
144 
145  ret = curl_easy_perform(h_curl);
146  if (ret) {
148  "Lease end request - curl_easy_perform failed: %d", ret);
149  }
150 
151  JsonDocument *doc = JsonDocument::Create(reply->data);
152  bool ok = true;
153  if (!doc ) {
154  ok=false;
155  }
156  else {
157  UniquePtr<JsonDocument> const reply_json(doc);
158  const JSON *reply_status =
159  JsonDocument::SearchInObject(reply_json->root(), "status", JSON_STRING);
160  ok = (reply_status != NULL &&
161  std::string(reply_status->string_value) == "ok");
162  if (!ok) {
164  "Lease end request - error reply: %s",
165  reply->data.c_str());
166  }
167  }
168 
169  curl_easy_cleanup(h_curl);
170  h_curl = NULL;
171 
172  return ok && !ret;
173 }
174 
void Add(const std::string &key, const std::string &val)
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, bool expect_final_revision)
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:241
static CURL * PrepareCurl(const std::string &method)
std::string GetHostname()
Definition: posix.cc:762
static JsonDocument * Create(const std::string &text)
bool ApplySslCertificatePath(CURL *handle) const
Definition: ssl.cc:61
void UseSystemCertificatePath()
Definition: ssl.cc:72
size_t RecvCB(void *buffer, size_t size, size_t nmemb, void *userp)
std::string data
string StringifyInt(const int64_t value)
Definition: string.cc:77
string Base64(const string &data)
Definition: string.cc:537
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:515
std::string GenerateString() const
void AddJsonObject(const std::string &key, const std::string &json)
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:545