2 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Bartlomiej Grzelewski <b.grzelewski@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 app-permissions.cpp
20 * @author Pawel Polawski (pawel.polawski@partner.samsung.com)
22 * @brief This file contains implementation of security_server_app_has_permission
27 #include <dpl/log/log.h>
28 #include <dpl/serialization.h>
29 #include <privilege-control.h>
31 #include <sys/smack.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
35 #include <app-permissions.h>
36 #include <protocols.h>
37 #include <security-server.h>
38 #include <privilege-control.h>
42 int privilegeToSecurityServerError(int error) {
44 case PC_OPERATION_SUCCESS: return SECURITY_SERVER_API_SUCCESS;
45 case PC_ERR_FILE_OPERATION: return SECURITY_SERVER_API_ERROR_UNKNOWN;
46 case PC_ERR_MEM_OPERATION: return SECURITY_SERVER_API_ERROR_OUT_OF_MEMORY;
47 case PC_ERR_NOT_PERMITTED: return SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
48 case PC_ERR_INVALID_PARAM: return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
49 case PC_ERR_INVALID_OPERATION:
50 case PC_ERR_DB_OPERATION:
54 return SECURITY_SERVER_API_ERROR_UNKNOWN;
58 const SecurityServer::InterfaceID CHECK_APP_PRIVILEGE = 1;
60 } // namespace anonymous
62 namespace SecurityServer {
64 GenericSocketService::ServiceDescriptionVector AppPermissionsService::GetServiceDescription() {
65 return ServiceDescriptionVector {
66 { SERVICE_SOCKET_APP_PRIVILEGE_BY_NAME,
67 "security-server::api-app-privilege-by-name",
72 void AppPermissionsService::accept(const AcceptEvent &event) {
73 LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
74 << " ConnectionID.counter: " << event.connectionID.counter
75 << " ServiceID: " << event.interfaceID);
76 auto &info = m_connectionInfoMap[event.connectionID.counter];
77 info.interfaceID = event.interfaceID;
80 void AppPermissionsService::write(const WriteEvent &event) {
81 LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
82 " Size: " << event.size << " Left: " << event.left);
84 m_serviceManager->Close(event.connectionID);
87 void AppPermissionsService::process(const ReadEvent &event) {
88 LogDebug("Read event for counter: " << event.connectionID.counter);
89 auto &info = m_connectionInfoMap[event.connectionID.counter];
90 info.buffer.Push(event.rawBuffer);
92 // We can get several requests in one package.
93 // Extract and process them all
94 while(processOne(event.connectionID, info.buffer, info.interfaceID));
97 void AppPermissionsService::close(const CloseEvent &event) {
98 LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
99 m_connectionInfoMap.erase(event.connectionID.counter);
102 bool AppPermissionsService::processOne(const ConnectionID &conn,
103 MessageBuffer &buffer,
104 InterfaceID interfaceID)
106 LogDebug("Begin of an iteration");
108 //waiting for all data
109 if (!buffer.Ready()) {
113 LogDebug("Entering app_permissions server side handler");
115 switch(interfaceID) {
117 case CHECK_APP_PRIVILEGE:
118 return processCheckAppPrivilege(conn, buffer);
121 LogDebug("Unknown interfaceId. Closing socket.");
122 m_serviceManager->Close(conn);
127 bool AppPermissionsService::processCheckAppPrivilege(const ConnectionID &conn, MessageBuffer &buffer)
130 std::string privilege_name;
131 std::string app_label;
132 int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
134 bool has_permission = false;
135 PrivilegeCheckHdrs checkType = PrivilegeCheckHdrs::CHECK_GIVEN_APP;
137 LogDebug("Processing app privilege check request");
139 //receive data from buffer
142 Deserialization::Deserialize(buffer, temp); // call type
143 checkType = static_cast<PrivilegeCheckHdrs>(temp);
144 LogDebug("App privilege check call type: "
145 << (checkType == PrivilegeCheckHdrs::CHECK_GIVEN_APP ?
146 "CHECK_GIVEN_APP":"CHECK_CALLER_APP"));
147 if (checkType == PrivilegeCheckHdrs::CHECK_GIVEN_APP) { //app_label present only in this case
148 Deserialization::Deserialize(buffer, app_label); //get app_label
150 Deserialization::Deserialize(buffer, temp); //get app type
151 app_type = static_cast<app_type_t>(temp);
153 Deserialization::Deserialize(buffer, privilege_name); //get privilege name
154 } Catch (MessageBuffer::Exception::Base) {
155 LogDebug("Broken protocol. Closing socket.");
156 m_serviceManager->Close(conn);
160 //print received data
161 LogDebug("app_label: " << app_label);
162 LogDebug("app_type: " << static_cast<int>(app_type));
163 LogDebug("privilege_name: " << privilege_name);
165 LogDebug("Calling perm_app_has_permission()");
166 result = perm_app_has_permission(app_label.c_str(), app_type, privilege_name.c_str(), &has_permission);
167 LogDebug("perm_app_has_permission() returned: " << result << " , permission enabled: " << has_permission);
170 Serialization::Serialize(send, privilegeToSecurityServerError(result));
171 Serialization::Serialize(send, static_cast<int>(has_permission));
172 m_serviceManager->Write(conn, send.Pop());
176 } // namespace SecurityServer