2 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Bumjin Im <bj.im@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
19 * @file cookie-jar.cpp
20 * @author Pawel Polawski (p.polawski@partner.samsung.com)
22 * @brief This function contain implementation of CookieJar class which holds cookies structures
25 #include <cookie-jar.h>
26 #include <protocols.h>
27 #include <dpl/log/log.h>
28 #include <dpl/exception.h>
32 #include <smack-check.h>
33 #include <privilege-control.h>
36 #include <sys/types.h>
37 #include <sys/smack.h>
39 #include <linux/limits.h>
41 namespace SecurityServer {
43 CookieJar::CookieJar(void)
45 LogDebug("Created CookieJar for handling cookies");
48 CookieJar::~CookieJar(void)
50 LogDebug("Deleted CookieJar");
53 const Cookie * CookieJar::GenerateCookie(int pid)
55 char key[COOKIE_SIZE];
58 LogDebug("Cookie creation called");
60 //create empty cookie class
64 //check if there is no cookie for specified PID
65 const Cookie *searchResult = SearchCookie(newCookie, CompareType::PID);
66 if (searchResult != NULL) {
67 LogDebug("Cookie exist for specified PID");
71 searchResult = &newCookie; //only for searchResult != NULL
72 while(searchResult != NULL) {
74 std::ifstream urandom("/dev/urandom", std::ifstream::binary);
75 urandom.read(key, COOKIE_SIZE);
76 newCookie.cookieId.assign(key, key + COOKIE_SIZE);
78 //check if key is unique
79 searchResult = SearchCookie(newCookie, CompareType::COOKIE_ID);
80 if (searchResult != NULL)
81 LogDebug("Key is not unique");
88 snprintf(link, PATH_MAX, "/proc/%d/exe", pid);
89 retval = readlink(link, path, PATH_MAX);
91 LogDebug("Unable to get process path");
95 newCookie.binaryPath = path;
97 //get smack label if smack enabled
99 char label[SMACK_LABEL_LEN + 1];
100 retval = get_smack_label_from_process(pid, label);
101 if (retval != PC_OPERATION_SUCCESS) {
102 LogDebug("Unable to get smack label of process");
105 newCookie.smackLabel = label;
107 newCookie.smackLabel = "smack_disabled";
111 const int LINE_LEN = 128;
112 const int NAME_SIZE = 64;
113 char line[LINE_LEN]; //for storing parsed lines
114 char filename[NAME_SIZE];
116 snprintf(filename, NAME_SIZE, "/proc/%d/status", pid);
117 std::ifstream status(filename, std::ifstream::binary);
119 while (status.getline(line, LINE_LEN)) { //read line from file
120 if (strncmp(line, "Groups:", 7) == 0)
124 char delim[] = ": "; //separators for strtok: ' ' and ':'
125 char *token = strtok(line, delim); //1st string is "Group:"
126 while ((token = strtok(NULL, delim))) {
127 int gid = atoi(token);
128 newCookie.permissions.push_back(gid);
132 //print info about cookie
133 LogDebug("Cookie created");
134 LogDebug("PID: " << newCookie.pid);
135 LogDebug("PATH: " << newCookie.binaryPath);
136 LogDebug("LABEL: " << newCookie.smackLabel);
137 for (size_t k = 0; k < newCookie.permissions.size(); k++)
138 LogDebug("GID: " << newCookie.permissions[k]);
140 m_cookieList.push_back(newCookie);
141 return &m_cookieList[m_cookieList.size() - 1];
144 void CookieJar::DeleteCookie(const Cookie &pattern, CompareType criterion)
146 if (m_cookieList.size() == 0) {
147 LogDebug("Cookie list empty");
151 //for each cookie in list
152 for (size_t i = 0; i < m_cookieList.size();) {
153 if (CompareCookies(pattern, m_cookieList[i], criterion)) {
154 LogDebug("Deleting cookie");
155 if (i != m_cookieList.size() - 1)
156 m_cookieList[i] = *m_cookieList.rbegin();
157 m_cookieList.pop_back();
163 const Cookie * CookieJar::SearchCookie(const Cookie &pattern, CompareType criterion) const
165 LogDebug("Searching for cookie");
167 if (m_cookieList.size() == 0) {
168 LogDebug("Cookie list empty");
172 //for each cookie in list
173 for (size_t i = 0; i < m_cookieList.size(); i++) {
174 if (CompareCookies(pattern, m_cookieList[i], criterion)) {
175 LogDebug("Cookie found");
176 return &(m_cookieList[i]);
180 LogDebug("Cookie not found");
184 bool CookieJar::CompareCookies(const Cookie &c1, const Cookie &c2, CompareType criterion) const
186 size_t permSize1 = c1.permissions.size();
187 size_t permSize2 = c2.permissions.size();
190 case CompareType::COOKIE_ID:
191 return (c1.cookieId == c2.cookieId);
193 case CompareType::PID:
194 return (c1.pid == c2.pid);
196 case CompareType::PATH:
197 return (c1.binaryPath == c2.binaryPath);
199 case CompareType::SMACKLABEL:
200 return (c1.smackLabel == c2.smackLabel);
202 case CompareType::PERMISSIONS:
203 //we search for at least one the same GID
204 for(size_t i = 0; i < permSize1; i++)
205 for (size_t k = 0; k < permSize2; k++)
206 if (c1.permissions[i] == c2.permissions[k])
211 LogDebug("Wrong function parameters");
216 } // namespace SecurityServer