Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
server_credentials.cc
1 #include "server_credentials.h"
2 
3 #include <cstring>
4 #include <iostream>
5 #include <sstream>
6 #include <stdexcept>
7 
8 #include <archive.h>
9 #include <archive_entry.h>
10 #include <boost/algorithm/string.hpp> // trim_if
11 #include <boost/optional.hpp>
12 #include <boost/property_tree/json_parser.hpp>
13 #include <boost/property_tree/ptree.hpp>
14 
15 #include "bootstrap/bootstrap.h"
16 #include "utilities/utils.h"
17 
18 using boost::optional;
19 using boost::property_tree::ptree;
20 using boost::property_tree::json_parser::json_parser_error;
21 
22 std::unique_ptr<std::stringstream> readArchiveFile(archive *a) {
23  int r;
24  const char *buff = nullptr;
25  std::unique_ptr<std::stringstream> result = std_::make_unique<std::stringstream>();
26  size_t size;
27  int64_t offset;
28  for (;;) {
29  r = archive_read_data_block(a, reinterpret_cast<const void **>(&buff), &size, &offset);
30  if (r == ARCHIVE_EOF) {
31  break;
32  }
33  if (r != ARCHIVE_OK) {
34  throw BadCredentialsArchive(archive_error_string(a));
35  break;
36  }
37  if (size > 0 && buff != nullptr) {
38  result->write(buff, static_cast<std::streamsize>(size));
39  }
40  }
41  return result;
42 }
43 
44 ServerCredentials::ServerCredentials(const boost::filesystem::path &credentials_path)
45  : method_(AuthMethod::kNone), credentials_path_(credentials_path) {
46  bool found_config = false;
47 
48  std::unique_ptr<std::stringstream> json_stream;
49 
50  struct archive *a;
51  struct archive_entry *entry;
52  int r;
53 
54  /* Try reading the file as an archive of any format. If that fails, try
55  * reading it as a json. */
56  a = archive_read_new();
57  archive_read_support_filter_all(a);
58  archive_read_support_format_all(a);
59  r = archive_read_open_filename(a, credentials_path_.c_str(), 1024);
60  if (r == ARCHIVE_OK) {
61  const char *filename = nullptr;
62  while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
63  filename = archive_entry_pathname(entry);
64  if (strcmp(filename, "treehub.json") == 0) {
65  json_stream = readArchiveFile(a);
66  found_config = true;
67  } else if (strcmp(filename, "client_auth.p12") == 0) {
68  client_p12_ = readArchiveFile(a)->str();
69  method_ = AuthMethod::kTls;
70  } else if (strcmp(filename, "tufrepo.url") == 0) {
71  repo_url_ = readArchiveFile(a)->str();
72  boost::trim_if(repo_url_, boost::is_any_of(" \t\r\n"));
73  } else {
74  archive_read_data_skip(a);
75  }
76  }
77  r = archive_read_free(a);
78  if (r != ARCHIVE_OK) {
79  throw BadCredentialsArchive(std::string("Error closing zipped credentials file: ") + credentials_path.string());
80  }
81  if (!found_config) {
82  throw BadCredentialsContent(std::string("treehub.json not found in zipped credentials file: ") +
83  credentials_path.string());
84  }
85  } else {
86  archive_read_free(a);
87  }
88 
89  try {
90  ptree pt;
91 
92  if (found_config) {
93  read_json(*json_stream, pt);
94  } else {
95  read_json(credentials_path.string(), pt);
96  }
97 
98  if (method_ == AuthMethod::kTls) {
99  // do nothing
100  } else if (optional<ptree &> ap_pt = pt.get_child_optional("oauth2")) {
101  method_ = AuthMethod::kOauth2;
102  auth_server_ = ap_pt->get<std::string>("server", "");
103  client_id_ = ap_pt->get<std::string>("client_id", "");
104  client_secret_ = ap_pt->get<std::string>("client_secret", "");
105  scope_ = ap_pt->get<std::string>("scope", "");
106  } else if (optional<ptree &> ba_pt = pt.get_child_optional("basic_auth")) {
107  method_ = AuthMethod::kBasic;
108  auth_user_ = ba_pt->get<std::string>("user", "");
109  auth_password_ = ba_pt->get<std::string>("password", "");
110  }
111  ostree_server_ = pt.get<std::string>("ostree.server", "");
112  } catch (const json_parser_error &e) {
113  throw BadCredentialsJson(std::string("Unable to read ") + credentials_path.string() + " as archive or json file.");
114  }
115 }
116 
117 bool ServerCredentials::CanSignOffline() const {
118  bool found_root = false;
119  bool found_targets_pub = false;
120  bool found_targets_sec = false;
121  bool found_tufrepo_url = false;
122 
123  struct archive *a;
124  struct archive_entry *entry;
125  int r;
126 
127  a = archive_read_new();
128  archive_read_support_filter_all(a);
129  archive_read_support_format_all(a);
130  r = archive_read_open_filename(a, credentials_path_.c_str(), 1024);
131  if (r == ARCHIVE_OK) {
132  const char *filename = nullptr;
133  while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
134  filename = archive_entry_pathname(entry);
135  if (strcmp(filename, "root.json") == 0) {
136  found_root = true;
137  } else if (strcmp(filename, "targets.pub") == 0) {
138  found_targets_pub = true;
139  } else if (strcmp(filename, "targets.sec") == 0) {
140  found_targets_sec = true;
141  } else if (strcmp(filename, "tufrepo.url") == 0) {
142  found_tufrepo_url = true;
143  } else {
144  archive_read_data_skip(a);
145  }
146  }
147  }
148  (void)archive_read_free(a);
149  return (found_root && found_targets_pub && found_targets_sec && found_tufrepo_url);
150 }
BadCredentialsJson
Definition: server_credentials.h:15
result
Results of libaktualizr API calls.
Definition: results.h:12
BadCredentialsContent
Definition: server_credentials.h:10
BadCredentialsArchive
Definition: server_credentials.h:20