GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/gateway_util.cc
Date: 2026-09-27 02:40:09
Exec Total Coverage
Lines: 29 53 54.7%
Branches: 39 94 41.5%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include "gateway_util.h"
6
7 #include <fcntl.h>
8 #include <unistd.h>
9
10 #include <algorithm>
11 #include <climits>
12 #include <vector>
13
14 #include "crypto/hash.h"
15 #include "util/posix.h"
16 #include "util/string.h"
17
18 namespace {
19
20 6444 bool BothAreSpaces(const char &c1, const char &c2) {
21
4/4
✓ Branch 0 taken 936 times.
✓ Branch 1 taken 5508 times.
✓ Branch 2 taken 360 times.
✓ Branch 3 taken 576 times.
6444 return c1 == ' ' && (c1 == c2);
22 }
23
24 } // namespace
25
26 namespace gateway {
27
28 // The publisher advertises the highest gateway API protocol version it can
29 // speak. It must be at least kApiVersionNonexistentPath for the gateway to
30 // echo back a negotiated version that enables --allow-nonexistent-path.
31 ✗ int APIVersion() { return kApiVersionNonexistentPath; }
32
33 ✗ std::string SessionTokenApiVersionPath(const std::string &token_path) {
34 ✗ return token_path + ".api_version";
35 }
36
37 36 std::string MakeSessionTokenApiVersionRecord(const int api_version,
38 const std::string &token) {
39 const shash::Md5 fingerprint(token.data(),
40
1/2
✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
36 static_cast<unsigned>(token.size()));
41
4/8
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 36 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 36 times.
✗ Branch 11 not taken.
72 return StringifyInt(api_version) + "\n" + fingerprint.ToString(false);
42 }
43
44 72 bool ParseSessionTokenApiVersionRecord(const std::string &record,
45 const std::string &token,
46 int *api_version) {
47
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (api_version == NULL)
48 ✗ return false;
49
50 72 const size_t separator = record.find('\n');
51 uint64_t version;
52 72 if (separator == std::string::npos
53
4/11
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 72 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 72 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 72 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
144 || !String2Uint64Parse(record.substr(0, separator), &version)
54
3/6
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 72 times.
✗ Branch 5 not taken.
144 || version > static_cast<uint64_t>(INT_MAX)) {
55 ✗ return false;
56 }
57
58 const shash::Md5 fingerprint(token.data(),
59
1/2
✓ Branch 3 taken 72 times.
✗ Branch 4 not taken.
72 static_cast<unsigned>(token.size()));
60
4/7
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 72 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 9 taken 36 times.
✓ Branch 10 taken 36 times.
72 if (record.substr(separator + 1) != fingerprint.ToString(false)) {
61 36 return false;
62 }
63
64 36 *api_version = static_cast<int>(version);
65 36 return true;
66 }
67
68 ✗ GatewayKey ReadGatewayKey(const std::string &key_file_name) {
69 ✗ std::string id;
70 ✗ std::string secret;
71 ✗ const bool retval = ReadKeys(key_file_name, &id, &secret);
72 ✗ if (!retval)
73 ✗ return GatewayKey();
74 ✗ return GatewayKey(id, secret);
75 }
76
77 ✗ bool ReadKeys(const std::string &key_file_name, std::string *key_id,
78 std::string *secret) {
79 ✗ if (!(key_id && secret)) {
80 ✗ return false;
81 }
82
83 ✗ const int key_file_fd = open(key_file_name.c_str(), O_RDONLY);
84 ✗ if (!key_file_fd) {
85 ✗ return false;
86 }
87
88 ✗ std::string body;
89 ✗ if (!SafeReadToString(key_file_fd, &body)) {
90 ✗ close(key_file_fd);
91 ✗ return false;
92 }
93
94 ✗ close(key_file_fd);
95
96 ✗ return ParseKey(body, key_id, secret);
97 }
98
99 288 bool ParseKey(const std::string &body, std::string *key_id,
100 std::string *secret) {
101
1/2
✓ Branch 3 taken 288 times.
✗ Branch 4 not taken.
288 const std::string line = GetLineMem(body.data(), body.size());
102
4/8
✓ Branch 2 taken 288 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 288 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 288 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 288 times.
✗ Branch 13 not taken.
576 std::string l = Trim(ReplaceAll(line, "\t", " "));
103
2/4
✓ Branch 5 taken 288 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 288 times.
✗ Branch 10 not taken.
288 l.erase(std::unique(l.begin(), l.end(), BothAreSpaces), l.end());
104
1/2
✓ Branch 1 taken 288 times.
✗ Branch 2 not taken.
288 std::vector<std::string> tokens = SplitString(l, ' ');
105
106
5/6
✓ Branch 1 taken 288 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 252 times.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 252 times.
288 if (tokens.size() < 2 || tokens.size() > 3) {
107 36 return false;
108 }
109
110
2/2
✓ Branch 2 taken 180 times.
✓ Branch 3 taken 72 times.
252 if (tokens[0] == "plain_text") {
111
1/2
✓ Branch 2 taken 180 times.
✗ Branch 3 not taken.
180 *key_id = tokens[1];
112
1/2
✓ Branch 2 taken 180 times.
✗ Branch 3 not taken.
180 *secret = tokens[2];
113 } else {
114 72 return false;
115 }
116
117 180 return true;
118 288 }
119
120 } // namespace gateway
121