Add the check routine of certificate
[platform/framework/native/channel-service.git] / src / FIo_MessagePortService.cpp
1 // // Open Service Platform
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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 /**
18  * @file        FIo_MessagePortService.cpp
19  * @brief       This is the implementation file for the _MessagePortService class.
20  *
21  */
22
23 #include <unique_ptr.h>
24
25 #include <bundle.h>
26 #include <message-port.h>
27 #include <package_manager.h>
28
29 #include <FBaseStringComparer.h>
30 #include <FBaseSysLog.h>
31 #include <FBase_StringConverter.h>
32
33 #include "FIo_MessagePortStub.h"
34 #include "FIo_MessagePortService.h"
35
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Collection;
38 using namespace Tizen::Io;
39 using namespace Tizen::App;
40
41 using namespace std;
42
43 static const char LOCAL_APPID[] = "LOCAL_APPID";
44 static const char LOCAL_PORT[] = "LOCAL_PORT";
45 static const char TRUSTED_LOCAL[] = "TRUSTED_LOCAL";
46
47 static const char REMOTE_APPID[] = "REMOTE_APPID";
48 static const char REMOTE_PORT[] = "REMOTE_PORT";
49 static const char TRUSTED_REMOTE[] = "TRUSTED_REMOTE";
50 static const char TRUSTED_MESSAGE[] = "TRUSTED_MESSAGE";
51
52 _MessagePortService::_MessagePortService(void)
53         : __pStub(null)
54 {
55
56 }
57
58 _MessagePortService::~_MessagePortService(void)
59 {
60
61 }
62
63 result
64 _MessagePortService::Construct(_MessagePortStub& stub)
65 {
66         static _StringHashProvider hashProvider;
67         static _StringComparer stringComparer;
68
69         __pPorts = new HashMapT <String, int>();
70         __pPorts->Construct(0, 0, hashProvider, stringComparer);
71
72         __pTrustedPorts = new HashMapT <String, int>();
73         __pTrustedPorts->Construct(0, 0, hashProvider, stringComparer);
74
75         __pStub = &stub;
76
77         return E_SUCCESS;
78 }
79
80 int
81 _MessagePortService::RegisterMessagePort(int clientId, const BundleBuffer& buffer)
82 {
83         bundle* b = buffer.b;
84
85         String key = GetKey(buffer);
86         String trusted(bundle_get_val(b, TRUSTED_LOCAL));
87
88         SysLog(NID_IO, "Register a message port: [%ls], client id = %d", key.GetPointer(), clientId);
89
90         bool out = false;
91
92         if (trusted.Equals(L"TRUE", false))
93         {
94                 __pTrustedPorts->ContainsKey(key, out);
95         }
96         else
97         {
98                 __pPorts->ContainsKey(key, out);
99         }
100
101         SysTryReturn(NID_IO, !out, MESSAGEPORT_ERROR_IO_ERROR, E_SYSTEM, 
102                         "[E_SYSTEM] The local message port (%ls) has already registered", key.GetPointer());
103
104         if (trusted.Equals(L"TRUE", false))
105         {
106                 __pTrustedPorts->Add(key, clientId);
107         }
108         else
109         {
110                 __pPorts->Add(key, clientId);
111         }
112
113         return 0;
114 }
115
116 int
117 _MessagePortService::CheckRemotePort(const BundleBuffer& buffer)
118 {
119         bundle* b = buffer.b;
120
121         String key = GetKey(buffer, false);
122         String trusted(bundle_get_val(b, TRUSTED_REMOTE));
123
124         SysLog(NID_IO, "Check a remote message port: [%ls]", key.GetPointer());
125
126         bool out = false;
127
128         if (trusted.Equals(L"TRUE", false))
129         {
130                 __pTrustedPorts->ContainsKey(key, out);
131         }
132         else
133         {
134                 __pPorts->ContainsKey(key, out);
135         }
136
137         SysTryReturn(NID_IO, out == true, MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND, E_OBJ_NOT_FOUND,
138                         "[E_OBJ_NOT_FOUND] The remote message port (%ls) is not found.", key.GetPointer());
139
140         if (trusted.Equals(L"TRUE", false))
141         {
142                 String localAppId = bundle_get_val(buffer.b, LOCAL_APPID);
143                 String remoteAppId = bundle_get_val(buffer.b, REMOTE_APPID);
144
145                 // Check the preloaded
146                 if (!IsPreloaded(localAppId, remoteAppId))
147                 {
148                         // Check the certificate
149                         return CheckCertificate(localAppId, remoteAppId);
150                 }
151         }
152
153         return 0;
154 }
155
156 result
157 _MessagePortService::UnregisterMessagePort(int clientId)
158 {
159         result r = E_OBJ_NOT_FOUND;
160
161         int value = 0;
162         int count = __pPorts->GetCount();
163
164         String key;
165         IListT<String>* pKeys = __pPorts->GetKeysN();
166         SysTryReturnResult(NID_IO, pKeys != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
167
168         for (int i = 0; i < count; i++)
169         {
170                 pKeys->GetAt(i, key);
171                 __pPorts->GetValue(key, value);
172                 if (value == clientId)
173                 {
174                         SysLog(NID_IO, "Unregister - key = %ls", key.GetPointer());
175
176                         __pPorts->Remove(key);
177
178                         r = E_SUCCESS;
179                 }
180         }
181
182         delete pKeys;
183
184         count = __pTrustedPorts->GetCount();
185         pKeys = __pTrustedPorts->GetKeysN();
186         SysTryReturnResult(NID_IO, pKeys != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
187
188         for (int i = 0; i < count; i++)
189         {
190                 pKeys->GetAt(i, key);
191                 __pTrustedPorts->GetValue(key, value);
192                 if (value == clientId)
193                 {
194                         SysLog(NID_IO, "Unregister - key = %ls", key.GetPointer());
195
196                         __pTrustedPorts->Remove(key);
197
198                         r = E_SUCCESS;
199                 }
200         }
201
202         delete pKeys;
203
204         return r;
205 }
206
207 int
208 _MessagePortService::SendMessage(const BundleBuffer& buffer)
209 {
210         result r = E_SUCCESS;
211         int clientId = 0;
212
213         bundle* b = buffer.b;
214
215         String key = GetKey(buffer, false);
216         SysLog(NID_IO, "Sends a message to a remote message port [%ls]", key.GetPointer());
217
218         String trustedMessage(bundle_get_val(b, TRUSTED_MESSAGE));
219         if (trustedMessage.Equals(L"TRUE", false))
220         {
221                 r = __pTrustedPorts->GetValue(key, clientId);
222         }
223         else
224         {
225                 r = __pPorts->GetValue(key, clientId);
226         }
227
228         SysTryReturn(NID_IO, r == E_SUCCESS, MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND, E_OBJ_NOT_FOUND,
229                                 "[E_OBJ_NOT_FOUND] The destination message port (%ls) is not found.", key.GetPointer());
230
231         if (trustedMessage.Equals(L"TRUE", false))
232         {
233                 String localAppId = bundle_get_val(buffer.b, LOCAL_APPID);
234                 String remoteAppId = bundle_get_val(buffer.b, REMOTE_APPID);
235
236                 // Check the preloaded
237                 if (!IsPreloaded(localAppId, remoteAppId))
238                 {
239                         // Check the certificate
240                         int ret = CheckCertificate(localAppId, remoteAppId);
241                         if (ret < 0)
242                         {
243                                 return ret;
244                         }
245                 }
246         }
247
248         r = __pStub->SendMessage(clientId, buffer);
249         SysTryReturn(NID_IO, r == E_SUCCESS, MESSAGEPORT_ERROR_IO_ERROR, E_SYSTEM,
250                                 "[E_SYSTEM] Failed to send a message.");
251
252         return E_SUCCESS;
253 }
254
255 String 
256 _MessagePortService::GetKey(const BundleBuffer& buffer, bool local) const
257 {
258         const char* pAppId = null; 
259         const char* pPortName = null; 
260
261         if (local)
262         {
263                 pAppId = bundle_get_val(buffer.b, LOCAL_APPID);
264                 pPortName = bundle_get_val(buffer.b, LOCAL_PORT);
265         }
266         else
267         {
268                 pAppId = bundle_get_val(buffer.b, REMOTE_APPID);
269                 pPortName = bundle_get_val(buffer.b, REMOTE_PORT);
270         }
271
272         String key(pAppId);
273         key.Append(L':');
274         key.Append(pPortName);
275
276         return key;
277 }
278
279 bool
280 _MessagePortService::IsPreloaded(const String& localAppId, const String& remoteAppId) const
281 {
282         bool preload_local = false;
283         bool preload_remote = false;
284
285         unique_ptr<char[]> pLocalAppId(_StringConverter::CopyToCharArrayN(localAppId));
286         unique_ptr<char[]> pRemoteAppId(_StringConverter::CopyToCharArrayN(remoteAppId));
287
288         int ret = package_manager_is_preload_package_by_app_id(pLocalAppId.get(), &preload_local);
289         if (ret == 0)
290         {
291                 ret = package_manager_is_preload_package_by_app_id(pRemoteAppId.get(), &preload_remote);
292                 if (ret == 0)
293                 {
294                         if (preload_local && preload_remote)
295                         {
296                                 return true;
297                         }
298                 }
299                 else
300                 {
301                         SysLog(NID_IO, "Failed to check the preloaded application. %d", ret);
302                 }
303         }
304         else
305         {
306                 SysLog(NID_IO, "Failed to check the preloaded application. %d", ret);
307         }
308
309         return false;
310 }
311
312 int
313 _MessagePortService::CheckCertificate(const String& localAppId, const String& remoteAppId) const
314 {
315         package_manager_compare_result_type_e res;
316
317         unique_ptr<char[]> pLocalAppId(_StringConverter::CopyToCharArrayN(localAppId));
318         unique_ptr<char[]> pRemoteAppId(_StringConverter::CopyToCharArrayN(remoteAppId));
319
320         int ret = package_manager_compare_app_cert_info(pLocalAppId.get(), pRemoteAppId.get(), &res);
321         SysTryReturn(NID_IO, ret == 0, MESSAGEPORT_ERROR_IO_ERROR, E_SYSTEM,
322                                 "[E_SYSTEM] Failed to check the certificate: %d", ret);
323
324         SysTryReturn(NID_IO, res == PACAKGE_MANAGER_COMPARE_MATCH, MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH, E_CERTIFICATE_VERIFICATION_FAILED,
325                                 "[E_CERTIFICATE_VERIFICATION_FAILED] Both applications are not signed with the same certificate: %d", res);
326
327         return 0;
328 }
329