Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
treehub_server.cc
1 #include "treehub_server.h"
2 
3 #include <assert.h>
4 
5 #include <iostream>
6 
7 #include <boost/algorithm/string.hpp>
8 
9 using std::string;
10 
11 TreehubServer::TreehubServer() {
12  auth_header_.data = const_cast<char*>(auth_header_contents_.c_str());
13  auth_header_.next = &force_header_;
14  force_header_contents_ = "x-ats-ostree-force: true";
15  force_header_.data = const_cast<char*>(force_header_contents_.c_str());
16  force_header_.next = &content_type_header_;
17  content_type_header_.data = const_cast<char*>(content_type_header_contents_.c_str());
18  content_type_header_.next = nullptr;
19 }
20 
21 void TreehubServer::SetToken(const string& token) {
22  assert(auth_header_.next == &force_header_);
23  assert(force_header_.next == &content_type_header_);
24  assert(content_type_header_.next == nullptr);
25 
26  auth_header_contents_ = "Authorization: Bearer " + token;
27  auth_header_.data = const_cast<char*>(auth_header_contents_.c_str());
28  method_ = AuthMethod::kOauth2;
29 }
30 
31 void TreehubServer::SetContentType(const string& content_type) {
32  assert(auth_header_.next == &force_header_);
33  assert(force_header_.next == &content_type_header_);
34  assert(content_type_header_.next == nullptr);
35 
36  content_type_header_contents_ = content_type;
37  content_type_header_.data = const_cast<char*>(content_type_header_contents_.c_str());
38 }
39 
40 void TreehubServer::SetCerts(const std::string& client_p12) {
41  method_ = AuthMethod::kTls;
42  client_p12_path_.PutContents(client_p12);
43 }
44 
45 void TreehubServer::SetAuthBasic(const std::string& username, const std::string& password) {
46  method_ = AuthMethod::kBasic;
47  username_ = username;
48  password_ = password;
49 }
50 
51 // Note that this method creates a reference from curl_handle to this. Keep
52 // this TreehubServer object alive until the curl request has been completed
53 void TreehubServer::InjectIntoCurl(const string& url_suffix, CURL* curl_handle, const bool tufrepo) const {
54  // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
55  std::string url = (tufrepo ? repo_url_ : root_url_);
56 
57  if (*url.rbegin() != '/' && *url_suffix.begin() != '/') {
58  url += "/";
59  } else if (*url.rbegin() == '/' && *url_suffix.begin() == '/') {
60  url.erase(url.length() - 1);
61  }
62 
63  boost::trim_if(url, boost::is_any_of(" \t\r\n"));
64 
65  curlEasySetoptWrapper(curl_handle, CURLOPT_URL, (url + url_suffix).c_str());
66 
67  curlEasySetoptWrapper(curl_handle, CURLOPT_HTTPHEADER, &auth_header_);
68  // If we need authentication but don't have an OAuth2 token or TLS
69  // credentials, fall back to legacy username/password.
70  if (method_ == AuthMethod::kBasic) {
71  curlEasySetoptWrapper(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
72  curlEasySetoptWrapper(curl_handle, CURLOPT_USERNAME, username_.c_str());
73  curlEasySetoptWrapper(curl_handle, CURLOPT_PASSWORD, password_.c_str());
74  }
75 
76  if (method_ == AuthMethod::kTls) {
77  curlEasySetoptWrapper(curl_handle, CURLOPT_SSLCERT, client_p12_path_.PathString().c_str());
78  curlEasySetoptWrapper(curl_handle, CURLOPT_SSLCERTTYPE, "P12");
79  curlEasySetoptWrapper(curl_handle, CURLOPT_SSL_VERIFYPEER, 1);
80  curlEasySetoptWrapper(curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
81  curlEasySetoptWrapper(curl_handle, CURLOPT_USE_SSL, CURLUSESSL_ALL);
82  }
83 
84  if (!ca_certs_.empty()) {
85  curlEasySetoptWrapper(curl_handle, CURLOPT_CAINFO, ca_certs_.c_str());
86  curlEasySetoptWrapper(curl_handle, CURLOPT_CAPATH, NULL);
87  }
88 }
89 
90 // Set the url of the treehub server, this should be something like
91 // "https://treehub-staging.atsgarage.com/api/v2/"
92 // The trailing slash is optional, and will be appended if required
93 void TreehubServer::root_url(const std::string& _root_url) {
94  root_url_ = _root_url;
95  if (root_url_.size() > 0 && root_url_[root_url_.size() - 1] != '/') {
96  root_url_.append("/");
97  }
98 }
99 
100 void TreehubServer::repo_url(const std::string& _repo_url) {
101  repo_url_ = _repo_url;
102  if (repo_url_.size() > 0 && repo_url_[repo_url_.size() - 1] != '/') {
103  repo_url_.append("/");
104  }
105 }
106 
107 // vim: set tabstop=2 shiftwidth=2 expandtab: