namespace {
+const std::string SUBSCRIBER_REGISTER = "Server::registerNotificationSubscriber";
+const std::string SUBSCRIBER_UNREGISTER = "Server::unregisterNotificationSubscriber";
+
+
const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.sock";
} // namespace
{
client.reset();
}
+
+int ODEContext::subscribeSignal(const std::string& name,
+ const SignalListener& listener,
+ void* data)
+{
+ auto listenerDispatcher = [listener, data](std::string name) {
+ listener(data);
+ };
+
+ try {
+ return client->subscribe<std::string>
+ (SUBSCRIBER_REGISTER, name, listenerDispatcher);
+ } catch (runtime::Exception& e) {
+ std::cout << e.what() << std::endl;
+ return -1;
+ }
+}
+
+int ODEContext::unsubscribeSignal(int subscriberId)
+{
+ return client->unsubscribe(SUBSCRIBER_UNREGISTER, subscriberId);
+}
#include <klay/rmi/client.h>
+typedef std::function<void(void*)> SignalListener;
+
class ODEContext final {
public:
typedef std::unique_ptr<rmi::Client> ODEControlContext;
int connect(const std::string& address) noexcept;
void disconnect() noexcept;
+ int subscribeSignal(const std::string& name, const SignalListener& listener, void* data);
+ int unsubscribeSignal(int subscriberId);
+
template<typename Interface, typename... Args>
Interface createInterface(Args&&... args) noexcept
{
*options = external.getSupportedOptions();
return ODE_ERROR_NONE;
}
+
+static void _ode_external_event_listener(void *user_data) {
+ std::mutex *pMtx = (std::mutex*)user_data;
+ pMtx->unlock();
+}
+
+int ode_external_encryption_wait_for_mount()
+{
+ ODEContext client;
+ RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+
+ std::mutex mtx;
+ mtx.lock();
+
+ int ret = client.subscribeSignal("ExternalEncryption::mount", _ode_external_event_listener, &mtx);
+ RET_ON_FAILURE(ret >= 0, ODE_ERROR_INVALID_PARAMETER);
+
+ mtx.lock();
+
+ return ODE_ERROR_NONE;
+}
ODE_API int ode_external_encryption_get_supported_options(unsigned int* options);
/**
+ * @brief Wait for mount of external storage
+ * @details Services can use this API to wait for mount of external storage.
+ * @since_tizen 3.0
+ * @return #ODE_ERROR_NONE on success, otherwise a negative value
+ * @retval #ODE_ERROR_NONE Successful
+ * @retval #ODE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #ODE_ERROR_TIMED_OUT Time out
+ * @retval #ODE_ERROR_PERMISSION_DENIED The application does not have
+ * the privilege to call this API
+ * @see ode_external_encryption_mount()
+ */
+ODE_API int ode_external_encryption_wait_for_mount();
+
+/**
* @}
*/
*options = internal.getSupportedOptions();
return ODE_ERROR_NONE;
}
+
+static void _ode_internal_event_listener(void *user_data) {
+ std::mutex *pMtx = (std::mutex*)user_data;
+ pMtx->unlock();
+}
+
+int ode_internal_encryption_wait_for_mount()
+{
+ ODEContext client;
+ RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+
+ std::mutex mtx;
+ mtx.lock();
+
+ int ret = client.subscribeSignal("InternalEncryption::mount", _ode_internal_event_listener, &mtx);
+ RET_ON_FAILURE(ret >= 0, ODE_ERROR_INVALID_PARAMETER);
+
+ mtx.lock();
+
+ return ODE_ERROR_NONE;
+}
*/
ODE_API int ode_internal_encryption_get_supported_options(unsigned int* options);
+/**
+ * @brief Wait for mount of internal storage
+ * @details Services can use this API to wait for mount of internal storage.
+ * @since_tizen 3.0
+ * @return #ODE_ERROR_NONE on success, otherwise a negative value
+ * @retval #ODE_ERROR_NONE Successful
+ * @retval #ODE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #ODE_ERROR_TIMED_OUT Time out
+ * @retval #ODE_ERROR_PERMISSION_DENIED The application does not have
+ * the privilege to call this API
+ * @see ode_internal_encryption_mount()
+ */
+ODE_API int ode_internal_encryption_wait_for_mount();
/*
* @}
*/
context.expose(this, "", (int)(ExternalEncryption::getState)());
context.expose(this, "", (unsigned int)(ExternalEncryption::getSupportedOptions)());
+ context.createNotification("ExternalEncryption::mount");
+
engine.reset(new EXTERNAL_ENGINE(
EXTERNAL_PATH, EXTERNAL_PATH,
ProgressBar([](int v) {
}
engine->mount(keyManager.getMasterKey(data), getOptions());
+ context.notify("ExternalEncryption::mount");
+
return 0;
}
context.expose(this, "", (int)(InternalEncryption::getState)());
context.expose(this, "", (unsigned int)(InternalEncryption::getSupportedOptions)());
+ context.createNotification("InternalEncryption::mount");
+
engine.reset(new INTERNAL_ENGINE(
INTERNAL_DEV, INTERNAL_PATH,
ProgressBar([](int v) {
}
engine->mount(keyManager.getMasterKey(pwData), getOptions());
+ context.notify("InternalEncryption::mount");
+
return 0;
}
service->setPrivilegeChecker(std::bind(&Server::checkPeerPrivilege, this, _1, _2));
+ service->expose(this, "", (runtime::FileDescriptor)(Server::registerNotificationSubscriber)(std::string));
+ service->expose(this, "", (int)(Server::unregisterNotificationSubscriber)(std::string, int));
+
secureErase.reset(new ode::SecureErase(*this));
internalEncryption.reset(new ode::InternalEncryption(*this));
externalEncryption.reset(new ode::ExternalEncryption(*this));
return true;
}
+
+runtime::FileDescriptor Server::registerNotificationSubscriber(const std::string& name)
+{
+ INFO("registerNotificationSubscriber");
+ INFO(name);
+ return runtime::FileDescriptor(service->subscribeNotification(name), true);
+}
+
+int Server::unregisterNotificationSubscriber(const std::string& name, int id)
+{
+ return service->unsubscribeNotification(name, id);
+}
service->setMethodHandler<Type, Args...>(privilege, method, handler);
}
+ template <typename... Args>
+ void notify(const std::string& name, Args&&... args)
+ {
+ service->notify<Args...>(name, std::forward<Args>(args)...);
+ }
+
uid_t getPeerUid() const
{
return service->getPeerUid();
bool checkPeerPrivilege(const rmi::Credentials& cred, const std::string& privilege);
+
+ void createNotification(const std::string& name)
+ {
+ service->createNotification(name);
+ }
+
+ runtime::FileDescriptor registerNotificationSubscriber(const std::string& name);
+ int unregisterNotificationSubscriber(const std::string& name, int id);
+
private:
std::string securityLabel;
std::unique_ptr<rmi::Service> service;
<< " -d, --decrypt=internal|external decrypt" << std::endl
<< " -p, --changepw=internal|external change password" << std::endl
<< " -s, --state=internal|external get state" << std::endl
+ << " -w, --waitmnt=internal|external wait for mount"<< std::endl
<< " -r, --erase=FILE|DIRECTORY secure-erase" << std::endl
<< " -c, --clean=DIRECTORY secure-clean" << std::endl
<< " -h, --help show this" << std::endl
return ret;
}
+static inline int wait_for_mount(const std::string name)
+{
+ int ret;
+
+ if (name == "internal") {
+ std::cout << "Wait for internal storage mount..." << std::endl;
+ ret = ode_internal_encryption_wait_for_mount();
+ } else if (name == "external") {
+ std::cout << "Wait for external storage mount..." << std::endl;
+ ret = ode_external_encryption_wait_for_mount();
+ } else {
+ printSelectableStorage();
+ return -1;
+ }
+
+ if (ret != 0) {
+ std::cerr << "Error : " << ret <<std::endl;
+ return -1;
+ }
+ std::cout << "Mount is completed"<< std::endl;
+
+ return ret;
+}
static inline int erase(const std::string name)
{
int ret;
{"encrypt", required_argument, 0, 'e'},
{"decrypt", required_argument, 0, 'd'},
{"state", required_argument, 0, 's'},
+ {"waitmnt", required_argument, 0, 'w'},
{"erase", required_argument, 0, 'r'},
{"clean", required_argument, 0, 'c'},
{0, 0, 0, 0}
return EXIT_SUCCESS;
}
- while ((opt = getopt_long(argc, argv, "m:u:e:d:p:s:r:c:h", options, &index)) != -1) {
+ while ((opt = getopt_long(argc, argv, "m:u:e:d:p:s:w:r:c:h", options, &index)) != -1) {
switch (opt) {
case 'm':
ret = mount(optarg);
case 'p':
ret = change_password(optarg);
break;
+ case 'w':
+ ret = wait_for_mount(optarg);
+ break;
case 's':
ret = get_state(optarg);
break;