48d3529b2d91cb9940defc6ee5d5aab29efe66b5
[platform/core/security/cert-svc.git] / src / vcore / SignatureFinder.cpp
1 /*
2  * Copyright (c) 2016 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        SignatureFinder.cpp
18  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19  * @version     1.0
20  * @brief       Search for author-signature.xml and signatureN.xml files.
21  */
22 #include <vcore/SignatureFinder.h>
23 #include <dpl/log/log.h>
24
25 #include <dirent.h>
26 #include <errno.h>
27 #include <istream>
28 #include <sstream>
29
30 #include <pcrecpp.h>
31
32 namespace {
33
34 }
35
36 namespace ValidationCore {
37 static const char *SIGNATURE_AUTHOR = "author-signature.xml";
38 static const char *REGEXP_DISTRIBUTOR_SIGNATURE =
39         "^(signature)([1-9][0-9]*)(\\.xml)";
40
41 class SignatureFinder::Impl {
42 public:
43         Impl(const std::string &dir)
44                 : m_dir(dir)
45                 , m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
46         {}
47
48         virtual ~Impl() {}
49
50         Result find(SignatureFileInfoSet &set);
51
52 private:
53         std::string getFullPath(const std::string &file);
54
55         std::string m_dir;
56         pcrecpp::RE m_signatureRegexp;
57 };
58
59 std::string SignatureFinder::Impl::getFullPath(const std::string &file)
60 {
61         std::string fullPath = m_dir;
62
63         if (fullPath.back() != '/')
64                 fullPath += "/";
65
66         fullPath += file;
67         return fullPath;
68 }
69
70 SignatureFinder::Result SignatureFinder::Impl::find(SignatureFileInfoSet &set)
71 {
72         int ret;
73         DIR *dirp;
74         struct dirent entry;
75         struct dirent *result;
76
77         if ((dirp = opendir(m_dir.c_str())) == NULL) {
78                 LogError("Error opening directory: " << m_dir);
79                 return ERROR_OPENING_DIR;
80         }
81
82         for (ret = readdir_r(dirp, &entry, &result);
83                         ret == 0 && result != NULL;
84                         ret = readdir_r(dirp, &entry, &result)) {
85                 /* number for author signature is -1 */
86                 if (!strcmp(result->d_name, SIGNATURE_AUTHOR)) {
87                         std::string fullPath = getFullPath(std::string(result->d_name));
88                         LogDebug("Found author signature file full path : " << fullPath);
89                         set.insert(SignatureFileInfo(fullPath, -1));
90                         continue;
91                 }
92
93                 std::string sig;
94                 std::string num;
95                 std::string xml; /* just for cutting out .xml */
96
97                 if (m_signatureRegexp.FullMatch(result->d_name, &sig, &num, &xml)) {
98                         std::istringstream stream(num);
99                         int number;
100                         stream >> number;
101
102                         if (stream.fail()) {
103                                 closedir(dirp);
104                                 return ERROR_ISTREAM;
105                         }
106
107                         std::string fullPath = getFullPath(std::string(result->d_name));
108                         LogDebug("Found signature file full path : " << fullPath);
109                         set.insert(SignatureFileInfo(fullPath, number));
110                 }
111         }
112
113         if (ret != 0) {
114                 LogError("Error in readdir");
115                 closedir(dirp);
116                 return ERROR_READING_DIR;
117         }
118
119         closedir(dirp);
120         return NO_ERROR;
121 }
122
123 SignatureFinder::SignatureFinder(const std::string &dir)
124         : m_impl(new Impl(dir))
125 {}
126
127 SignatureFinder::~SignatureFinder()
128 {
129         delete m_impl;
130 }
131
132 SignatureFinder::Result SignatureFinder::find(SignatureFileInfoSet &set)
133 {
134         return m_impl->find(set);
135 }
136
137 } // namespace ValidationCore