Adjust security_server_app_has_privilege to Tizen 3.0 model.
[platform/core/security/security-manager.git] / src / server / service / app-permissions.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Bartlomiej Grzelewski <b.grzelewski@samsung.com>
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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
17  */
18 /*
19  * @file        app-permissions.cpp
20  * @author      Pawel Polawski (pawel.polawski@partner.samsung.com)
21  * @version     1.0
22  * @brief       This file contains implementation of security_server_app_has_permission
23  *              on server side
24  */
25
26 #include <memory>
27 #include <dpl/log/log.h>
28 #include <dpl/serialization.h>
29 #include <privilege-control.h>
30
31 #include <sys/smack.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34
35 #include <app-permissions.h>
36 #include <protocols.h>
37 #include <security-server.h>
38 #include <privilege-control.h>
39
40 namespace {
41
42 int privilegeToSecurityServerError(int error) {
43     switch (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:
51     default:
52         ;
53     }
54     return SECURITY_SERVER_API_ERROR_UNKNOWN;
55 }
56
57 // interface ids
58 const SecurityServer::InterfaceID CHECK_APP_PRIVILEGE = 1;
59
60 } // namespace anonymous
61
62 namespace SecurityServer {
63
64 GenericSocketService::ServiceDescriptionVector AppPermissionsService::GetServiceDescription() {
65     return ServiceDescriptionVector {
66         { SERVICE_SOCKET_APP_PRIVILEGE_BY_NAME,
67           "security-server::api-app-privilege-by-name",
68           CHECK_APP_PRIVILEGE }
69     };
70 }
71
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;
78 }
79
80 void AppPermissionsService::write(const WriteEvent &event) {
81     LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
82         " Size: " << event.size << " Left: " << event.left);
83     if (event.left == 0)
84         m_serviceManager->Close(event.connectionID);
85 }
86
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);
91
92     // We can get several requests in one package.
93     // Extract and process them all
94     while(processOne(event.connectionID, info.buffer, info.interfaceID));
95 }
96
97 void AppPermissionsService::close(const CloseEvent &event) {
98     LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
99     m_connectionInfoMap.erase(event.connectionID.counter);
100 }
101
102 bool AppPermissionsService::processOne(const ConnectionID &conn,
103                                        MessageBuffer &buffer,
104                                        InterfaceID interfaceID)
105 {
106     LogDebug("Begin of an iteration");
107
108     //waiting for all data
109     if (!buffer.Ready()) {
110         return false;
111     }
112
113     LogDebug("Entering app_permissions server side handler");
114
115     switch(interfaceID) {
116
117     case CHECK_APP_PRIVILEGE:
118         return processCheckAppPrivilege(conn, buffer);
119
120     default:
121         LogDebug("Unknown interfaceId. Closing socket.");
122         m_serviceManager->Close(conn);
123         return false;
124     }
125 }
126
127 bool AppPermissionsService::processCheckAppPrivilege(const ConnectionID &conn, MessageBuffer &buffer)
128 {
129     MessageBuffer send;
130     std::string privilege_name;
131     std::string app_label;
132     int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
133     app_type_t app_type;
134     bool has_permission = false;
135     PrivilegeCheckHdrs checkType = PrivilegeCheckHdrs::CHECK_GIVEN_APP;
136
137     LogDebug("Processing app privilege check request");
138
139     //receive data from buffer
140     Try {
141         int temp;
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
149         }
150         Deserialization::Deserialize(buffer, temp); //get app type
151         app_type = static_cast<app_type_t>(temp);
152
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);
157         return false;
158     }
159
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);
164
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);
168
169     //send response
170     Serialization::Serialize(send, privilegeToSecurityServerError(result));
171     Serialization::Serialize(send, static_cast<int>(has_permission));
172     m_serviceManager->Write(conn, send.Pop());
173     return true;
174 }
175
176 } // namespace SecurityServer