• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender / 1556388280

22 Nov 2024 02:02PM UTC coverage: 79.882% (+0.02%) from 79.861%
1556388280

push

gitlab-ci

web-flow
Merge pull request #1697 from mendersoftware/cherry-4.0.x-master-priv_key_perms

[Cherry 4.0.x]: Fix: Private key file permissions

35 of 40 new or added lines in 4 files covered. (87.5%)

2 existing lines in 1 file now uncovered.

7179 of 8987 relevant lines covered (79.88%)

12177.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.97
/src/common/path/platform/c++17/path.cpp
1
// Copyright 2023 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
#include <common/path.hpp>
16

17
#include <filesystem>
18
#include <string>
19
#include <unordered_set>
20

21
#include <common/error.hpp>
22

23
namespace mender {
24
namespace common {
25
namespace path {
26

27
using namespace std;
28
namespace fs = std::filesystem;
29

30
unordered_map<Perms, fs::perms> perm_map = {
31
        {Perms::Owner_exec, fs::perms::owner_exec},
32
        {Perms::Owner_read, fs::perms::owner_read},
33
        {Perms::Owner_write, fs::perms::owner_write},
34
        {Perms::Group_read, fs::perms::group_read},
35
        {Perms::Group_write, fs::perms::group_write},
36
        {Perms::Group_exec, fs::perms::group_exec},
37
        {Perms::Others_read, fs::perms::others_read},
38
        {Perms::Others_write, fs::perms::others_write},
39
        {Perms::Others_exec, fs::perms::others_exec},
40
};
41

42
string JoinOne(const string &prefix, const string &suffix) {
47,739✔
43
        return (fs::path(prefix) / suffix).string();
47,739✔
44
}
45

46
string BaseName(const string &path) {
11,945✔
47
        return fs::path(path).filename().string();
11,945✔
48
}
49

50
string DirName(const string &path) {
91✔
51
        return fs::path(path).parent_path().string();
91✔
52
}
53

54
bool IsAbsolute(const string &path) {
2,416✔
55
        return fs::path(path).is_absolute();
4,832✔
56
}
57

58
bool FileExists(const string &path) {
1,630✔
59
        try {
60
                return fs::exists(path);
1,630✔
61
        } catch (const fs::filesystem_error &e) {
×
62
                log::Error("Could not check file existence of '" + path + "': " + e.what());
×
63
                return false;
64
        }
65
}
66

67
error::Error FileDelete(const string &path) {
7✔
68
        error_code ec;
7✔
69
        bool deleted = fs::remove(fs::path(path), ec);
7✔
70
        if (not deleted) {
7✔
71
                return error::Error(
72
                        ec.default_error_condition(),
×
73
                        "Failed to remove the file: '" + path + "'. error: " + ec.message());
×
74
        }
75
        return error::NoError;
7✔
76
}
77

78
error::Error DeleteRecursively(const string &path) {
104✔
79
        error_code ec;
104✔
80
        fs::remove_all(path, ec);
104✔
81
        if (ec) {
104✔
82
                return error::Error(ec.default_error_condition(), "Could not remove path");
×
83
        }
84
        return error::NoError;
104✔
85
}
86

87
expected::ExpectedBool IsExecutable(const string &file_path, const bool warn) {
738✔
88
        try {
89
                fs::perms perms = fs::status(file_path).permissions();
738✔
90
                if ((perms & (fs::perms::owner_exec | fs::perms::group_exec | fs::perms::others_exec))
738✔
91
                        == fs::perms::none) {
92
                        if (warn) {
×
93
                                log::Warning("'" + file_path + "' is not executable");
×
94
                        }
95
                        return false;
96
                }
97
                return true;
98
        } catch (const fs::filesystem_error &e) {
×
99
                return expected::unexpected(error::Error(
×
100
                        e.code().default_error_condition(),
×
101
                        "Could not check executable status of '" + file_path + "'"));
×
102
        }
103
}
104

105
error::Error Permissions(
1,009✔
106
        const string &file_path, const vector<Perms> perms, WarnMode warn_on_change) {
107
        if (perms.size() == 0) {
1,009✔
108
                return error::NoError;
×
109
        }
110
        fs::perms old_perms {};
111
        try {
112
                old_perms = fs::status(file_path).permissions();
1,009✔
NEW
113
        } catch (const fs::filesystem_error &e) {
×
114
                return error::Error(
NEW
115
                        e.code().default_error_condition(),
×
NEW
116
                        "Could not check permissions on '" + file_path + "'");
×
117
        }
118

119
        fs::perms new_perms {};
1,009✔
120
        std::for_each(perms.cbegin(), perms.cend(), [&new_perms](const Perms perm) {
3,022✔
121
                new_perms |= perm_map.at(perm);
3,022✔
122
        });
1,009✔
123
        if (old_perms == new_perms) {
1,009✔
124
                return error::NoError;
3✔
125
        }
126
        if (warn_on_change == WarnMode::WarnOnChange) {
1,006✔
127
                log::Warning("Changing permissions on the '" + file_path + "' file");
10✔
128
        }
129
        try {
130
                fs::permissions(file_path, new_perms);
1,006✔
131
        } catch (const fs::filesystem_error &e) {
3✔
132
                return error::Error(
133
                        e.code().default_error_condition(), "Could not set permissions on '" + file_path + "'");
6✔
134
        }
135
        return error::NoError;
1,003✔
136
}
137

138
expected::ExpectedUnorderedSet<string> ListFiles(
1,344✔
139
        const string &in_directory, function<bool(string)> matcher) {
140
        try {
141
                unordered_set<string> matching_files {};
1,344✔
142
                fs::path dir_path(in_directory);
2,688✔
143
                if (!fs::exists(dir_path)) {
1,344✔
144
                        auto err {errno};
161✔
145
                        return expected::unexpected(error::Error(
161✔
146
                                generic_category().default_error_condition(err),
322✔
147
                                "No such file or directory: " + in_directory));
483✔
148
                }
149

150
                for (const auto &entry : fs::directory_iterator {dir_path}) {
15,514✔
151
                        fs::path file_path = entry.path();
23,930✔
152
                        if (!fs::is_regular_file(file_path)) {
11,965✔
153
                                log::Warning("'" + file_path.string() + "'" + " is not a regular file. Ignoring.");
×
154
                                continue;
×
155
                        }
156

157
                        if (matcher(file_path)) {
23,930✔
158
                                matching_files.insert(file_path);
848✔
159
                        }
160
                }
161

162
                return matching_files;
1,183✔
163
        } catch (const fs::filesystem_error &e) {
×
164
                return expected::unexpected(error::Error(
×
165
                        e.code().default_error_condition(), "Could not list files in '" + in_directory + "'"));
×
166
        }
167
}
168

169
error::Error CreateDirectory(const string &path) {
1✔
170
        try {
171
                fs::path fs_path {path};
2✔
172
                if (not fs::create_directory(fs_path)) {
1✔
173
                        auto err {errno};
×
174
                        return error::Error(
175
                                generic_category().default_error_condition(err),
×
176
                                "Failed to create the directory: " + path);
×
177
                }
178
        } catch (const fs::filesystem_error &e) {
×
179
                return error::Error(
180
                        e.code().default_error_condition(), "Failed to create directory: '" + path + "'");
×
181
        }
182
        return error::NoError;
1✔
183
}
184

185
error::Error CreateDirectories(const string &dir) {
462✔
186
        try {
187
                const fs::path p {dir};
924✔
188
                fs::create_directories(p);
462✔
189
        } catch (const fs::filesystem_error &e) {
×
190
                return error::Error(
191
                        e.code().default_error_condition(), "Failed to create directory: '" + dir + "'");
×
192
        }
193
        return error::NoError;
462✔
194
}
195

196
} // namespace path
197
} // namespace common
198
} // namespace mender
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc