1 #include "server_credentials.h"
9 #include <archive_entry.h>
10 #include <boost/algorithm/string.hpp>
11 #include <boost/optional.hpp>
12 #include <boost/property_tree/json_parser.hpp>
13 #include <boost/property_tree/ptree.hpp>
15 #include "bootstrap/bootstrap.h"
16 #include "utilities/utils.h"
18 using boost::optional;
19 using boost::property_tree::ptree;
20 using boost::property_tree::json_parser::json_parser_error;
22 std::unique_ptr<std::stringstream> readArchiveFile(archive *a) {
24 const char *buff =
nullptr;
25 std::unique_ptr<std::stringstream>
result = std_::make_unique<std::stringstream>();
29 r = archive_read_data_block(a,
reinterpret_cast<const void **
>(&buff), &size, &offset);
30 if (r == ARCHIVE_EOF) {
33 if (r != ARCHIVE_OK) {
37 if (size > 0 && buff !=
nullptr) {
38 result->write(buff,
static_cast<std::streamsize
>(size));
44 ServerCredentials::ServerCredentials(
const boost::filesystem::path &credentials_path)
45 : method_(AuthMethod::kNone), credentials_path_(credentials_path) {
46 bool found_config =
false;
48 std::unique_ptr<std::stringstream> json_stream;
51 struct archive_entry *entry;
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);
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"));
74 archive_read_data_skip(a);
77 r = archive_read_free(a);
78 if (r != ARCHIVE_OK) {
79 throw BadCredentialsArchive(std::string(
"Error closing zipped credentials file: ") + credentials_path.string());
83 credentials_path.string());
93 read_json(*json_stream, pt);
95 read_json(credentials_path.string(), pt);
98 if (method_ == AuthMethod::kTls) {
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",
"");
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.");
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;
124 struct archive_entry *entry;
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) {
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;
144 archive_read_data_skip(a);
148 (void)archive_read_free(a);
149 return (found_root && found_targets_pub && found_targets_sec && found_tufrepo_url);