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 CHANGE_APP_PERMISSIONS = 0;
59 const SecurityServer::InterfaceID CHECK_APP_PRIVILEGE = 1;
61 } // namespace anonymous
63 namespace SecurityServer {
65 GenericSocketService::ServiceDescriptionVector AppPermissionsService::GetServiceDescription() {
66 return ServiceDescriptionVector {
67 { SERVICE_SOCKET_APP_PERMISSIONS,
68 "security-server::api-app-permissions",
69 CHANGE_APP_PERMISSIONS },
70 { SERVICE_SOCKET_APP_PRIVILEGE_BY_NAME,
71 "security-server::api-app-privilege-by-name",
76 void AppPermissionsService::accept(const AcceptEvent &event) {
77 LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
78 << " ConnectionID.counter: " << event.connectionID.counter
79 << " ServiceID: " << event.interfaceID);
80 auto &info = m_connectionInfoMap[event.connectionID.counter];
81 info.interfaceID = event.interfaceID;
84 void AppPermissionsService::write(const WriteEvent &event) {
85 LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
86 " Size: " << event.size << " Left: " << event.left);
88 m_serviceManager->Close(event.connectionID);
91 void AppPermissionsService::process(const ReadEvent &event) {
92 LogDebug("Read event for counter: " << event.connectionID.counter);
93 auto &info = m_connectionInfoMap[event.connectionID.counter];
94 info.buffer.Push(event.rawBuffer);
96 // We can get several requests in one package.
97 // Extract and process them all
98 while(processOne(event.connectionID, info.buffer, info.interfaceID));
101 void AppPermissionsService::close(const CloseEvent &event) {
102 LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
103 m_connectionInfoMap.erase(event.connectionID.counter);
106 bool AppPermissionsService::processOne(const ConnectionID &conn,
107 MessageBuffer &buffer,
108 InterfaceID interfaceID)
110 LogDebug("Begin of an iteration");
112 //waiting for all data
113 if (!buffer.Ready()) {
117 LogDebug("Entering app_permissions server side handler");
119 switch(interfaceID) {
121 case CHECK_APP_PRIVILEGE:
122 return processCheckAppPrivilege(conn, buffer);
125 LogDebug("Unknown interfaceId. Closing socket.");
126 m_serviceManager->Close(conn);
131 bool AppPermissionsService::processCheckAppPrivilege(const ConnectionID &conn, MessageBuffer &buffer)
134 std::string privilege_name;
136 int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
138 bool has_permission = false;
139 PrivilegeCheckHdrs checkType = PrivilegeCheckHdrs::CHECK_GIVEN_APP;
141 LogDebug("Processing app privilege check request");
143 //receive data from buffer
146 Deserialization::Deserialize(buffer, temp); // call type
147 checkType = static_cast<PrivilegeCheckHdrs>(temp);
148 LogDebug("App privilege check call type: "
149 << (checkType == PrivilegeCheckHdrs::CHECK_GIVEN_APP ?
150 "CHECK_GIVEN_APP":"CHECK_CALLER_APP"));
151 if (checkType == PrivilegeCheckHdrs::CHECK_GIVEN_APP) { //app_id present only in this case
152 Deserialization::Deserialize(buffer, app_id); //get app id
154 Deserialization::Deserialize(buffer, temp); //get app type
155 app_type = static_cast<app_type_t>(temp);
157 Deserialization::Deserialize(buffer, privilege_name); //get privilege name
158 } Catch (MessageBuffer::Exception::Base) {
159 LogDebug("Broken protocol. Closing socket.");
160 m_serviceManager->Close(conn);
164 if (checkType == PrivilegeCheckHdrs::CHECK_CALLER_APP) { //get sender app_id in this case
166 if (smack_new_label_from_socket(conn.sock, &label) < 0) {
167 LogDebug("Error in smack_new_label_from_socket(): "
168 "client label is unknown. Sending error response.");
169 Serialization::Serialize(send, SECURITY_SERVER_API_ERROR_GETTING_SOCKET_LABEL_FAILED);
170 m_serviceManager->Write(conn, send.Pop());
178 //print received data
179 LogDebug("app_id: " << app_id);
180 LogDebug("app_type: " << static_cast<int>(app_type));
181 LogDebug("privilege_name: " << privilege_name);
183 LogDebug("Calling perm_app_has_permission()");
184 result = perm_app_has_permission(app_id.c_str(), app_type, privilege_name.c_str(), &has_permission);
185 LogDebug("perm_app_has_permission() returned: " << result << " , permission enabled: " << has_permission);
188 Serialization::Serialize(send, privilegeToSecurityServerError(result));
189 Serialization::Serialize(send, static_cast<int>(has_permission));
190 m_serviceManager->Write(conn, send.Pop());
194 } // namespace SecurityServer