Fix T9050_yaca_rsa_encryption_paddings test
[platform/core/test/security-tests.git] / src / common / scoped_process_label.cpp
1 /*
2  *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 /*
17  * @file       scoped_process_label.cpp
18  * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
19  * @version    1.0
20  * @brief
21  */
22
23 #include <scoped_process_label.h>
24
25 #include <stdlib.h>
26 #include <sys/smack.h>
27
28 #include <utility>
29 #include <memory>
30 #include <fstream>
31
32 #include <dpl/test/test_runner.h>
33
34 namespace {
35
36 const std::string& getOnlycapPath()
37 {
38         static std::string onlycapPath;
39
40         if (onlycapPath.empty()) {
41                 const char* smackfs = smack_smackfs_path();
42                 if (smackfs != nullptr) {
43                         onlycapPath.assign(smackfs);
44                         onlycapPath.append("/onlycap");
45                 }
46         }
47         return onlycapPath;
48 }
49
50 const char* SEPARATORS = " ";
51
52 OnlycapSet smackGetOnlycap()
53 {
54         std::ifstream ifs(getOnlycapPath());
55
56         RUNNER_ASSERT_MSG(ifs, "Opening " << getOnlycapPath() << " failed.");
57
58         std::string onlycap((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
59         ifs.close();
60
61         OnlycapSet onlycapSet;
62
63         size_t first = 0;
64         size_t last = 0;
65         while (last != std::string::npos) {
66                 first = onlycap.find_first_not_of(SEPARATORS, last);
67                 if (first == std::string::npos)
68                         break;
69
70                 last = onlycap.find_first_of(SEPARATORS, first + 1);
71                 onlycapSet.insert(onlycap.substr(first, last - first));
72         }
73         return onlycapSet;
74 }
75
76 void smackSetOnlycap(const OnlycapSet& onlycapSet)
77 {
78         if (onlycapSet.empty()) {
79                 int ret = smack_set_onlycap(NULL, 0);
80                 RUNNER_ASSERT_MSG(ret == 0, "Error in smack_set_onlycap():" << ret);
81                 return;
82         }
83
84         const char* labels[onlycapSet.size()];
85         size_t i = 0;
86         for (const auto& label : onlycapSet) {
87                 labels[i] = label.c_str();
88                 i++;
89         }
90
91         int ret = smack_set_onlycap(labels, i);
92         RUNNER_ASSERT_MSG(ret == 0, "Error in smack_set_onlycap():" << ret);
93 }
94
95 void smackSetLabelForSelf(const std::string& label)
96 {
97         int ret = smack_set_label_for_self(label.c_str());
98         RUNNER_ASSERT_MSG(ret == 0, "Error in smack_set_label_for_self('" << label << "'): " << ret);
99 }
100
101 } // namespace anonymous
102
103 ScopedProcessLabel::ScopedProcessLabel(std::string label, bool restore) :
104                 m_label(std::move(label))
105 {
106         if (restore) {
107                 // store the current process label
108                 char* originalLabel = NULL;
109                 ssize_t size = smack_new_label_from_self(&originalLabel);
110                 RUNNER_ASSERT_MSG(size > 0 || originalLabel != nullptr,
111                                   "Error in smack_new_label_from_self():" << size);
112
113                 std::unique_ptr<char, decltype(&free)> originalLabelPtr(originalLabel, free);
114                 m_originalLabel.assign(originalLabel, size);
115
116                 m_originalOnlycap = smackGetOnlycap();
117
118                 // add new label to onlycap so that it's able to restore the label
119                 if (!m_originalOnlycap.empty()
120                         && m_originalOnlycap.find(m_label) == m_originalOnlycap.end()) {
121                         OnlycapSet newOnlycap = m_originalOnlycap;
122                         newOnlycap.insert(m_label);
123                         smackSetOnlycap(newOnlycap);
124                 } else {
125                         m_originalLabel.clear();
126                         m_originalOnlycap.clear();
127                 }
128         }
129         smackSetLabelForSelf(m_label);
130 }
131
132 ScopedProcessLabel::~ScopedProcessLabel()
133 {
134         // it has to be restored
135         if (!m_originalLabel.empty()) {
136                 try {
137                         smackSetLabelForSelf(m_originalLabel);
138                         smackSetOnlycap(m_originalOnlycap);
139                 } catch (const DPL::Test::TestException& e) {
140                         RUNNER_ERROR_MSG("Test exception occurred: " << e.GetMessage());
141                 } catch (const std::exception& e) {
142                         RUNNER_ERROR_MSG("Std exception occurred: " << e.what());
143                 } catch (...) {
144                         RUNNER_ERROR_MSG("Unknown exception occurred.");
145                 }
146         }
147 }