0c27a26e2b05f6cb54f58e8955106c4d65729dab
[platform/core/test/security-tests.git] / src / cynara-tests / common / cynara_test_file_operations.cpp
1 /*
2  * Copyright (c) 2015 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 #include <cstdlib>
18 #include <dirent.h>
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <ftw.h>
22 #include <pwd.h>
23 #include <sys/sendfile.h>
24 #include <sys/smack.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28
29 #include <cynara_test_commons.h>
30 #include <dpl/test/test_runner.h>
31 #include <memory.h>
32
33 #include <cynara_test_file_operations.h>
34
35 namespace FileOperations
36 {
37
38 static int removeFile(const char *fpath, const struct stat * /*sb*/,
39                           int tflag, struct FTW * /*ftwbuf*/)
40 {
41     if (tflag == FTW_F)
42         RUNNER_ASSERT_ERRNO_MSG(!unlink(fpath), "Unable to unlink " << fpath << " file");
43     else
44         RUNNER_ASSERT_MSG(tflag == FTW_DP, "Visited file should not exist. Path: " << fpath);
45     return 0;
46 }
47
48 bool dirExists(const std::string &directory)
49 {
50     struct stat st;
51     int ret = stat(directory.c_str(), &st);
52     if (ret == -1 && errno == ENOENT) {
53         return false;
54     } else if (ret == -1) {
55         RUNNER_ASSERT_ERRNO_MSG(false, "Cannot stat " << directory
56                                           << " not due to its nonexistence");
57     }
58     RUNNER_ASSERT_MSG(st.st_mode & S_IFDIR, directory << " is not a directory");
59     return true;
60 }
61
62 void copyCynaraFile(const std::string &src, const std::string &dst)
63 {
64     using PwBufPtr = CStringPtr;
65     int inFd = TEMP_FAILURE_RETRY(open(src.c_str(), O_RDONLY));
66     RUNNER_ASSERT_ERRNO_MSG(inFd > 0, "Opening " << src << " file failed");
67     FdUniquePtr inFdPtr(&inFd);
68
69     int outFd = TEMP_FAILURE_RETRY(creat(dst.c_str(), 0700));
70     RUNNER_ASSERT_ERRNO_MSG(outFd > 0, "Creating " << dst << " file failed");
71     FdUniquePtr outFdPtr(&outFd);
72
73     long int len = sysconf(_SC_GETPW_R_SIZE_MAX);
74     RUNNER_ASSERT_MSG(len != -1, "No suggested buflen");
75     size_t buflen = len;
76     char *buf = static_cast<char*>(malloc(buflen));
77
78     PwBufPtr pwBufPtr(buf);
79
80     struct passwd pwbuf, *pwbufp = nullptr;
81     int ret = TEMP_FAILURE_RETRY(getpwnam_r(CynaraTestConsts::USER.c_str(),
82                                             &pwbuf, buf, buflen, &pwbufp));
83     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "getpwnam_r failed on " << CynaraTestConsts::USER << " user");
84     RUNNER_ASSERT_MSG(pwbufp, "User " << CynaraTestConsts::USER << " does not exist");
85
86     ret = fchown(outFd, pwbufp->pw_uid, pwbufp->pw_gid);
87     RUNNER_ASSERT_ERRNO_MSG(ret != -1, "fchown failed");
88
89     ret = smack_fsetlabel(outFd, CynaraTestConsts::LABEL.c_str(), SMACK_LABEL_ACCESS);
90     RUNNER_ASSERT_MSG(ret == 0, "Setting smack label failed");
91
92     struct stat statSrc;
93     ret = fstat(inFd, &statSrc);
94     RUNNER_ASSERT_ERRNO_MSG(ret != -1, "fstat failed");
95
96     ret = sendfile(outFd, inFd, 0, statSrc.st_size);
97     RUNNER_ASSERT_ERRNO_MSG(ret != -1, "sendfile failed");
98 }
99
100 void copyCynaraFiles(const std::string &source, const std::string &destination)
101 {
102     DIR *dirPtr = nullptr;
103     struct dirent *direntPtr;
104
105     RUNNER_ASSERT_ERRNO_MSG(dirPtr = opendir(source.c_str()),
106                                "opening " << source << " dir failed");
107     DirPtr dirScopedPtr(dirPtr);
108
109     while((direntPtr = readdir(dirPtr)) != nullptr) {
110         if (!strcmp(direntPtr->d_name, ".")
111          || !strcmp(direntPtr->d_name, ".."))
112             continue;
113         std::string tempDest = destination + "/" + direntPtr->d_name;
114         std::string tempSrc = source + "/" + direntPtr->d_name;
115         copyCynaraFile(tempSrc, tempDest);
116     }
117 }
118
119 void makeDir(const std::string &directory)
120 {
121     RUNNER_ASSERT_ERRNO_MSG(!mkdir(directory.c_str(), S_IRWXU | S_IRWXG | S_IRWXO),
122                                "Unable to make " << directory << " test directory");
123 }
124
125 void removeDirFiles(const std::string &dir)
126 {
127     int ret = nftw(dir.c_str(), removeFile, 2, FTW_DEPTH | FTW_PHYS);
128     if (ret == -1)
129         RUNNER_ASSERT_ERRNO_MSG(errno == ENOENT, "nftw failed");
130 }
131
132 void removeDirIfExists(const std::string &dir)
133 {
134     RUNNER_ASSERT_ERRNO_MSG(!rmdir(dir.c_str()) || errno == ENOENT,
135                                "Removing " << dir << " dir failed");
136 }
137
138 } // namespace FileOperations