lxcpp: provisioning implementation (part 2)
[platform/core/security/vasum.git] / server / host-dbus-connection.cpp
1 /*
2  *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Piotr Bartosiewicz <p.bartosiewi@partner.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 /**
20  * @file
21  * @author  Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
22  * @brief   Implementation of a class for communication with server
23  */
24
25 #ifdef DBUS_CONNECTION
26 #include "config.hpp"
27
28 #include "host-dbus-connection.hpp"
29 #include "host-dbus-definitions.hpp"
30 #include "exception.hpp"
31 #include "api/dbus-method-result-builder.hpp"
32 #include "api/messages.hpp"
33
34 #include "logger/logger.hpp"
35 #include "config/manager.hpp"
36 #include "zones-manager.hpp"
37
38 namespace vasum {
39
40 namespace {
41
42 // Timeout in ms for waiting for dbus name.
43 // Can happen if glib loop is busy or not present.
44 // TODO: this should be in host's configuration file
45 const unsigned int NAME_ACQUIRED_TIMEOUT = 5 * 1000;
46 const std::string EMPTY_CALLER = "";
47
48 } // namespace
49
50
51 HostDbusConnection::HostDbusConnection(ZonesManager* zonesManagerPtr)
52     : mNameAcquired(false)
53     , mNameLost(false)
54     , mZonesManagerPtr(zonesManagerPtr)
55 {
56     LOGT("Connecting to host system DBUS");
57     mDbusConnection = dbus::DbusConnection::createSystem();
58
59     LOGT("Setting DBUS name");
60     mDbusConnection->setName(api::dbus::BUS_NAME,
61                              std::bind(&HostDbusConnection::onNameAcquired, this),
62                              std::bind(&HostDbusConnection::onNameLost, this));
63
64     if (!waitForName(NAME_ACQUIRED_TIMEOUT)) {
65         const std::string msg = "Could not acquire dbus name: " + api::dbus::BUS_NAME;
66         LOGE(msg);
67         throw HostConnectionException(msg);
68     }
69
70     LOGT("Registering DBUS interface");
71     using namespace std::placeholders;
72     mDbusConnection->registerObject(api::dbus::OBJECT_PATH,
73                                     api::dbus::DEFINITION,
74                                     std::bind(&HostDbusConnection::onMessageCall,
75                                               this, _1, _2, _3, _4, _5),
76                                     std::bind(&HostDbusConnection::onClientVanished,
77                                               this, _1));
78
79     mSubscriptionId = mDbusConnection->signalSubscribe(std::bind(&HostDbusConnection::onSignalCall,
80                                                                  this, _1, _2, _3, _4, _5),
81                                                        std::string(),
82                                                        api::dbus::INTERFACE);
83     LOGD("Connected");
84 }
85
86 HostDbusConnection::~HostDbusConnection()
87 {
88     mDbusConnection->signalUnsubscribe(mSubscriptionId);
89 }
90
91 bool HostDbusConnection::waitForName(const unsigned int timeoutMs)
92 {
93     std::unique_lock<std::mutex> lock(mNameMutex);
94     mNameCondition.wait_for(lock,
95                             std::chrono::milliseconds(timeoutMs),
96     [this] {
97         return mNameAcquired || mNameLost;
98     });
99
100     return mNameAcquired;
101 }
102
103 void HostDbusConnection::onNameAcquired()
104 {
105     std::unique_lock<std::mutex> lock(mNameMutex);
106     mNameAcquired = true;
107     mNameCondition.notify_one();
108 }
109
110 void HostDbusConnection::onNameLost()
111 {
112     std::unique_lock<std::mutex> lock(mNameMutex);
113     mNameLost = true;
114     mNameCondition.notify_one();
115
116     if (mNameAcquired) {
117         // TODO implement reconnecting
118         LOGE("TODO Reconnect !!!");
119     }
120 }
121
122 void HostDbusConnection::setProxyCallCallback(const ProxyCallCallback& callback)
123 {
124     mProxyCallCallback = callback;
125 }
126
127 void HostDbusConnection::onMessageCall(const std::string& objectPath,
128                                    const std::string& interface,
129                                    const std::string& methodName,
130                                    GVariant* parameters,
131                                    dbus::MethodResultBuilder::Pointer result)
132 {
133     if (objectPath != api::dbus::OBJECT_PATH || interface != api::dbus::INTERFACE) {
134         return;
135     }
136
137     if (methodName == api::dbus::METHOD_SET_ACTIVE_ZONE) {
138         api::ZoneId zoneId;
139         config::loadFromGVariant(parameters, zoneId);
140
141         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
142         mZonesManagerPtr->handleSetActiveZoneCall(zoneId, rb);
143         return;
144     }
145
146     if (methodName == api::dbus::METHOD_PROXY_CALL) {
147         const gchar* target = NULL;
148         const gchar* targetBusName = NULL;
149         const gchar* targetObjectPath = NULL;
150         const gchar* targetInterface = NULL;
151         const gchar* targetMethod = NULL;
152         GVariant* rawArgs = NULL;
153         g_variant_get(parameters,
154                       "(&s&s&s&s&sv)",
155                       &target,
156                       &targetBusName,
157                       &targetObjectPath,
158                       &targetInterface,
159                       &targetMethod,
160                       &rawArgs);
161         dbus::GVariantPtr args(rawArgs, g_variant_unref);
162
163         if (mProxyCallCallback) {
164             mProxyCallCallback(target,
165                                targetBusName,
166                                targetObjectPath,
167                                targetInterface,
168                                targetMethod,
169                                args.get(),
170                                result);
171         }
172         return;
173     }
174
175     if (methodName == api::dbus::METHOD_LOCK_QUEUE) {
176         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
177         mZonesManagerPtr->handleLockQueueCall(rb);
178         return;
179     }
180
181     if (methodName == api::dbus::METHOD_UNLOCK_QUEUE) {
182         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
183         mZonesManagerPtr->handleUnlockQueueCall(rb);
184         return;
185     }
186
187     if (methodName == api::dbus::METHOD_GET_ZONE_ID_LIST) {
188         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::ZoneIds>>(result);
189         mZonesManagerPtr->handleGetZoneIdsCall(rb);
190         return;
191     }
192
193     if (methodName == api::dbus::METHOD_GET_ACTIVE_ZONE_ID) {
194         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::ZoneId>>(result);
195         mZonesManagerPtr->handleGetActiveZoneIdCall(rb);
196         return;
197     }
198
199     if (methodName == api::dbus::METHOD_GET_ZONE_INFO) {
200         api::ZoneId zoneId;
201         config::loadFromGVariant(parameters, zoneId);
202
203         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::ZoneInfoOut>>(result);
204         mZonesManagerPtr->handleGetZoneInfoCall(zoneId, rb);
205         return;
206     }
207
208     if (methodName == api::dbus::METHOD_SET_NETDEV_ATTRS) {
209         api::SetNetDevAttrsIn data;
210         config::loadFromGVariant(parameters, data);
211
212         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
213         mZonesManagerPtr->handleSetNetdevAttrsCall(data, rb);
214         return;
215     }
216
217     if (methodName == api::dbus::METHOD_GET_NETDEV_ATTRS) {
218         api::GetNetDevAttrsIn data;
219         config::loadFromGVariant(parameters, data);
220
221         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::GetNetDevAttrs>>(result);
222         mZonesManagerPtr->handleGetNetdevAttrsCall(data, rb);
223         return;
224     }
225
226     if (methodName == api::dbus::METHOD_GET_NETDEV_LIST) {
227         api::ZoneId data;
228         config::loadFromGVariant(parameters, data);
229
230         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::NetDevList>>(result);
231         mZonesManagerPtr->handleGetNetdevListCall(data, rb);
232         return;
233     }
234
235     if (methodName == api::dbus::METHOD_CREATE_NETDEV_VETH) {
236         api::CreateNetDevVethIn data;
237         config::loadFromGVariant(parameters, data);
238
239         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
240         mZonesManagerPtr->handleCreateNetdevVethCall(data, rb);
241         return;
242     }
243
244     if (methodName == api::dbus::METHOD_CREATE_NETDEV_MACVLAN) {
245         api::CreateNetDevMacvlanIn data;
246         config::loadFromGVariant(parameters, data);
247
248         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
249         mZonesManagerPtr->handleCreateNetdevMacvlanCall(data, rb);
250         return;
251     }
252
253     if (methodName == api::dbus::METHOD_CREATE_NETDEV_PHYS) {
254         api::CreateNetDevPhysIn data;
255         config::loadFromGVariant(parameters, data);
256
257         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
258         mZonesManagerPtr->handleCreateNetdevPhysCall(data, rb);
259         return;
260     }
261
262     if (methodName == api::dbus::METHOD_DESTROY_NETDEV) {
263         api::DestroyNetDevIn data;
264         config::loadFromGVariant(parameters, data);
265
266         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
267         mZonesManagerPtr->handleDestroyNetdevCall(data, rb);
268         return;
269     }
270
271     if (methodName == api::dbus::METHOD_DELETE_NETDEV_IP_ADDRESS) {
272         api::DeleteNetdevIpAddressIn data;
273         config::loadFromGVariant(parameters, data);
274
275         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
276         mZonesManagerPtr->handleDeleteNetdevIpAddressCall(data, rb);
277         return;
278     }
279
280     if (methodName == api::dbus::METHOD_DECLARE_FILE) {
281         api::DeclareFileIn data;
282         config::loadFromGVariant(parameters, data);
283
284         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Declaration>>(result);
285         mZonesManagerPtr->handleDeclareFileCall(data, rb);
286         return;
287     }
288
289     if (methodName == api::dbus::METHOD_DECLARE_MOUNT) {
290         api::DeclareMountIn data;
291         config::loadFromGVariant(parameters, data);
292
293         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Declaration>>(result);
294         mZonesManagerPtr->handleDeclareMountCall(data, rb);
295         return;
296     }
297
298     if (methodName == api::dbus::METHOD_DECLARE_LINK) {
299         api::DeclareLinkIn data;
300         config::loadFromGVariant(parameters, data);
301
302         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Declaration>>(result);
303         mZonesManagerPtr->handleDeclareLinkCall(data, rb);
304         return;
305     }
306
307     if (methodName == api::dbus::METHOD_GET_DECLARATIONS) {
308         api::ZoneId data;
309         config::loadFromGVariant(parameters, data);
310
311         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Declarations>>(result);
312         mZonesManagerPtr->handleGetDeclarationsCall(data, rb);
313         return;
314     }
315
316     if (methodName == api::dbus::METHOD_REMOVE_DECLARATION) {
317         api::RemoveDeclarationIn data;
318         config::loadFromGVariant(parameters, data);
319
320         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
321         mZonesManagerPtr->handleRemoveDeclarationCall(data, rb);
322         return;
323     }
324
325     if (methodName == api::dbus::METHOD_CREATE_ZONE) {
326         api::CreateZoneIn data;
327         config::loadFromGVariant(parameters, data);
328
329         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
330         mZonesManagerPtr->handleCreateZoneCall(data, rb);
331         return;
332     }
333
334     if (methodName == api::dbus::METHOD_DESTROY_ZONE) {
335         api::ZoneId data;
336         config::loadFromGVariant(parameters, data);
337
338         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
339         mZonesManagerPtr->handleDestroyZoneCall(data, rb);
340         return;
341     }
342
343     if (methodName == api::dbus::METHOD_SHUTDOWN_ZONE) {
344         api::ZoneId data;
345         config::loadFromGVariant(parameters, data);
346
347         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
348         mZonesManagerPtr->handleShutdownZoneCall(data, rb);
349         return;
350     }
351
352     if (methodName == api::dbus::METHOD_START_ZONE) {
353         api::ZoneId data;
354         config::loadFromGVariant(parameters, data);
355
356         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
357         mZonesManagerPtr->handleStartZoneCall(data, rb);
358     }
359
360     if (methodName == api::dbus::METHOD_LOCK_ZONE) {
361         api::ZoneId data;
362         config::loadFromGVariant(parameters, data);
363
364         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
365         mZonesManagerPtr->handleLockZoneCall(data, rb);
366         return;
367     }
368
369     if (methodName == api::dbus::METHOD_UNLOCK_ZONE) {
370         api::ZoneId data;
371         config::loadFromGVariant(parameters, data);
372
373         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
374         mZonesManagerPtr->handleUnlockZoneCall(data, rb);
375         return;
376     }
377
378     if (methodName == api::dbus::METHOD_GRANT_DEVICE) {
379         api::GrantDeviceIn data;
380         config::loadFromGVariant(parameters, data);
381
382         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
383         mZonesManagerPtr->handleGrantDeviceCall(data, rb);
384         return;
385     }
386
387     if (methodName == api::dbus::METHOD_REVOKE_DEVICE) {
388         api::RevokeDeviceIn data;
389         config::loadFromGVariant(parameters, data);
390
391         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
392         mZonesManagerPtr->handleRevokeDeviceCall(data, rb);
393         return;
394     }
395
396     if (methodName == api::dbus::METHOD_CREATE_FILE) {
397         api::CreateFileIn data;
398         config::loadFromGVariant(parameters, data);
399
400         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::CreateFileOut>>(result);
401         mZonesManagerPtr->handleCreateFileCall(data, rb);
402         return;
403     }
404
405     if (methodName == api::dbus::METHOD_SWITCH_TO_DEFAULT) {
406         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
407         mZonesManagerPtr->handleSwitchToDefaultCall(EMPTY_CALLER, rb);
408         return;
409     }
410
411     if (methodName == api::dbus::METHOD_CLEAN_UP_ZONES_ROOT) {
412         auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
413         mZonesManagerPtr->handleCleanUpZonesRootCall(rb);
414         return;
415     }
416 }
417
418 void HostDbusConnection::onClientVanished(const std::string& name)
419 {
420     const std::string id = api::DBUS_CONNECTION_PREFIX + name;
421     mZonesManagerPtr->disconnectedCallback(id);
422 }
423
424 void HostDbusConnection::onSignalCall(const std::string& /* senderBusName */,
425                                       const std::string& objectPath,
426                                       const std::string& interface,
427                                       const std::string& /* signalName */,
428                                       GVariant* /* parameters */) const
429 {
430     (void)this; // satisfy cpp-check
431     if (objectPath != api::dbus::OBJECT_PATH || interface != api::dbus::INTERFACE) {
432         return;
433     }
434 }
435
436 void HostDbusConnection::proxyCallAsync(const std::string& busName,
437                                     const std::string& objectPath,
438                                     const std::string& interface,
439                                     const std::string& method,
440                                     GVariant* parameters,
441                                     const dbus::DbusConnection::AsyncMethodCallCallback& callback)
442 {
443     mDbusConnection->callMethodAsync(busName,
444                                      objectPath,
445                                      interface,
446                                      method,
447                                      parameters,
448                                      std::string(),
449                                      callback);
450 }
451
452 } // namespace vasum
453 #endif //DBUS_CONNECTION