diff options
author | Krzysztof Jackiewicz <k.jackiewicz@samsung.com> | 2017-03-15 10:15:28 +0100 |
---|---|---|
committer | Krzysztof Jackiewicz <k.jackiewicz@samsung.com> | 2017-03-30 09:39:04 +0200 |
commit | 197e8e6d9e6684828eab8999f5b770fe187e16b8 (patch) | |
tree | ee27dc3663a787bfaae6b8c3102a61c11062fe57 | |
parent | 5e855486b8116d422a65c5a73e0f62a2b012bf78 (diff) | |
download | security-manager-app_encryption.tar.gz security-manager-app_encryption.tar.bz2 security-manager-app_encryption.zip |
Add password popup and adjust encryption test binaries to tizenapp_encryption
- Separate process for password popup (efl leaves 3 running threads which don't
like credential synchronisation -> SIGSEGV)
- Apply environmental variables required to show EFL popup
- Apply owner's supplementary groups required to show EFL popup
- Remove password related command line arguments from test binaries
- Better error description in case of no FEK support
Change-Id: I6cf910a32a8501287965da98ec8e425c697094e1
-rw-r--r-- | packaging/security-manager-with-ckm.spec | 10 | ||||
-rw-r--r-- | packaging/security-manager.spec | 11 | ||||
-rw-r--r-- | test/app_encryption/CMakeLists.txt | 5 | ||||
-rw-r--r-- | test/app_encryption/common/CMakeLists.txt | 1 | ||||
-rw-r--r-- | test/app_encryption/common/common.cpp | 34 | ||||
-rw-r--r-- | test/app_encryption/common/common.h | 17 | ||||
-rw-r--r-- | test/app_encryption/common/popup_proxy.cpp | 172 | ||||
-rw-r--r-- | test/app_encryption/common/popup_proxy.h | 79 | ||||
-rw-r--r-- | test/app_encryption/encryption_setting/encryption_setting.cpp | 72 | ||||
-rw-r--r-- | test/app_encryption/launcher/launcher_user.cpp | 54 | ||||
-rw-r--r-- | test/app_encryption/popup/CMakeLists.txt | 47 | ||||
-rw-r--r-- | test/app_encryption/popup/popup.cpp | 179 | ||||
-rw-r--r-- | test/app_encryption/popup/popup.h | 53 | ||||
-rw-r--r-- | test/app_encryption/popup/popup_server.cpp | 118 | ||||
-rw-r--r-- | test/app_encryption/popup/popup_server.h | 79 | ||||
-rw-r--r-- | test/app_encryption/popup/res/CMakeLists.txt | 28 | ||||
-rw-r--r-- | test/app_encryption/popup/res/popup_custom.edc | 48 |
17 files changed, 890 insertions, 117 deletions
diff --git a/packaging/security-manager-with-ckm.spec b/packaging/security-manager-with-ckm.spec index f7158d59..0d2f1210 100644 --- a/packaging/security-manager-with-ckm.spec +++ b/packaging/security-manager-with-ckm.spec @@ -82,6 +82,9 @@ Set of security rules that constitute security policy in the system Summary: Security manager unit test binaries Group: Security/Development Requires: boost-test +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(capi-ui-efl-util) +BuildRequires: edje-tools %description -n security-manager-tests Internal test for security manager implementation. @@ -197,6 +200,7 @@ fi chsmack -a System %{db_test_dir}/.security-manager-test.db chsmack -a System %{db_test_dir}/.security-manager-test.db-journal chsmack -e User %{_datadir}/app_encryption/launcher_user +chsmack -e User %{_datadir}/app_encryption/popup_server /sbin/ldconfig %postun -n security-manager-tests @@ -267,6 +271,10 @@ echo "User::Pkg::org.tizen.encryption-setting" > /sys/fs/smackfs/revoke-subject %attr(0600,root,root) %{db_test_dir}/.security-manager-test.db %attr(0600,root,root) %{db_test_dir}/.security-manager-test.db-journal %dir %{_datadir}/app_encryption -%attr(755,-,-) %{_datadir}/app_encryption/* +%{_datadir}/app_encryption/res +%attr(755,-,-) %{_datadir}/app_encryption/*.sh +%attr(755,-,-) %{_datadir}/app_encryption/popup_server +%attr(755,-,-) %{_datadir}/app_encryption/launcher +%attr(755,-,-) %{_datadir}/app_encryption/libencryption_common.so %attr(755,-,-) %caps(cap_setgid=ei) %{_datadir}/app_encryption/launcher_user %attr(755,-,-) %caps(cap_setgid=ei) %{_datadir}/app_encryption/encryption_setting diff --git a/packaging/security-manager.spec b/packaging/security-manager.spec index 72a66a55..a62d4385 100644 --- a/packaging/security-manager.spec +++ b/packaging/security-manager.spec @@ -81,6 +81,10 @@ Set of security rules that constitute security policy in the system Summary: Security manager unit test binaries Group: Security/Development Requires: boost-test +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(capi-ui-efl-util) +BuildRequires: coregl %description -n security-manager-tests Internal test for security manager implementation. @@ -195,6 +199,7 @@ fi chsmack -a System %{db_test_dir}/.security-manager-test.db chsmack -a System %{db_test_dir}/.security-manager-test.db-journal chsmack -e User %{_datadir}/app_encryption/launcher_user +chsmack -e User %{_datadir}/app_encryption/popup_server /sbin/ldconfig %postun -n security-manager-tests @@ -265,6 +270,10 @@ echo "User::Pkg::org.tizen.encryption-setting" > /sys/fs/smackfs/revoke-subject %attr(0600,root,root) %{db_test_dir}/.security-manager-test.db %attr(0600,root,root) %{db_test_dir}/.security-manager-test.db-journal %dir %{_datadir}/app_encryption -%attr(755,-,-) %{_datadir}/app_encryption/* +%{_datadir}/app_encryption/res +%attr(755,-,-) %{_datadir}/app_encryption/*.sh +%attr(755,-,-) %{_datadir}/app_encryption/popup_server +%attr(755,-,-) %{_datadir}/app_encryption/launcher +%attr(755,-,-) %{_datadir}/app_encryption/libencryption_common.so %attr(755,-,-) %caps(cap_setgid=ei) %{_datadir}/app_encryption/launcher_user %attr(755,-,-) %caps(cap_setgid=ei) %{_datadir}/app_encryption/encryption_setting diff --git a/test/app_encryption/CMakeLists.txt b/test/app_encryption/CMakeLists.txt index b86dd454..3af0e276 100644 --- a/test/app_encryption/CMakeLists.txt +++ b/test/app_encryption/CMakeLists.txt @@ -20,15 +20,20 @@ SET(APP_ENCRYPTION_DIR ${DATA_ROOT_DIR}/app_encryption) SET(TARGET_ENCRYPTION_COMMON "encryption_common") +SET(TARGET_POPUP_SERVER "popup_server") + +ADD_DEFINITIONS("-DPOPUP_SERVER=\"${APP_ENCRYPTION_DIR}/${TARGET_POPUP_SERVER}\"") SET(ENCRYPTION_COMMON_LDFLAGS "-Wl,--rpath=${APP_ENCRYPTION_DIR}") INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/include/ ${CMAKE_CURRENT_SOURCE_DIR}/common/ + ${CMAKE_CURRENT_SOURCE_DIR}/popup/ ) ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(launcher) ADD_SUBDIRECTORY(encryption_setting) ADD_SUBDIRECTORY(scripts) +ADD_SUBDIRECTORY(popup) diff --git a/test/app_encryption/common/CMakeLists.txt b/test/app_encryption/common/CMakeLists.txt index 4b645008..3644b8d1 100644 --- a/test/app_encryption/common/CMakeLists.txt +++ b/test/app_encryption/common/CMakeLists.txt @@ -19,6 +19,7 @@ SET(ENCRYPTION_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/common.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/popup_proxy.cpp ) ADD_LIBRARY(${TARGET_ENCRYPTION_COMMON} SHARED ${ENCRYPTION_COMMON_SOURCES}) diff --git a/test/app_encryption/common/common.cpp b/test/app_encryption/common/common.cpp index 048ab0e1..229105a2 100644 --- a/test/app_encryption/common/common.cpp +++ b/test/app_encryption/common/common.cpp @@ -29,29 +29,10 @@ #include <unistd.h> #include <tzplatform-config.h> +#include <security-manager.h> using namespace SecurityManager; -// TODO remove it when EFL popup is ready -const char* gPasswords[] = { NULL, NULL, NULL }; -bool gTimeout = false; - -std::string Popup::getPassword(const std::string &, PasswordType type) -{ - // TODO replace it with real EFL popup - - if (gTimeout) - throw std::runtime_error("Popup timeout"); - - if(type < PasswordType::OLD || type > PasswordType::CURRENT) - throw std::runtime_error("Unexpected password type"); - - if (gPasswords[type] == NULL) - return std::string(); - - return gPasswords[type]; -} - uid_t getDefaultUser() { static uid_t uid = TizenPlatformConfig::getUid(TZ_SYS_DEFAULT_USER); @@ -101,3 +82,16 @@ int switchToDefaultUser() } return 0; } + +int getEncryptionStatus(const char* app, app_encryption_status& status) +{ + int ret = security_manager_app_get_encryption_status(app, &status); + if (ret != SECURITY_MANAGER_SUCCESS) { + std::cerr << "Getting app encryption status failed " << ret << "."; + if (ret == SECURITY_MANAGER_ERROR_SERVER_ERROR) + std::cerr << " Have security-manager been built with FEK support?"; + std::cerr << std::endl; + return 1; + } + return 0; +} diff --git a/test/app_encryption/common/common.h b/test/app_encryption/common/common.h index d345bdaf..727185f9 100644 --- a/test/app_encryption/common/common.h +++ b/test/app_encryption/common/common.h @@ -23,21 +23,8 @@ #include <sys/types.h> -#include <string> - -extern const char* gPasswords[]; - -class Popup { -public: - enum PasswordType { - OLD, - NEW, - CURRENT - }; - - // empty password = user canceled the popup - std::string getPassword(const std::string &app, PasswordType type); -}; +#include <security-manager-types.h> uid_t getDefaultUser(); int switchToDefaultUser(); +int getEncryptionStatus(const char* app, app_encryption_status& status); diff --git a/test/app_encryption/common/popup_proxy.cpp b/test/app_encryption/common/popup_proxy.cpp new file mode 100644 index 00000000..d500e02f --- /dev/null +++ b/test/app_encryption/common/popup_proxy.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/* + * @file popup_proxy.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "popup_proxy.h" + +#include <stdexcept> +#include <iostream> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <cassert> + +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> + +namespace { +const char* ENVP[] = { + "TIZEN_WAYLAND_SHM_DIR=/run/.efl", + "EVAS_FONT_DPI=72", + "WAYLAND_DISPLAY=wayland-0", + "ECORE_INPUT_CANCEL=1", + "TERM=xterm", + "ELM_ENGINE=wayland_egl", + "USER=owner", + "ECORE_IMF_MODULE=wayland", + "PATH=/bin:/usr/bin:/sbin:/usr/sbin", + "ECTOR_BACKEND=default", + "ELM_ATSPI_MODE=1", + "EVAS_SHM_FLUSH=1", + "HOME=/opt/usr/home/owner", + "ECORE_ANIMATOR_SKIP=1", + "ECORE_IMF_INPUT_PANEL_ENABLED=1", + "EVAS_GL_NO_BLACKLIST=1", + "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/5001/dbus/user_bus_socket", + "XDG_RUNTIME_DIR=/run/user/5001", + "ELM_DISPLAY=wl", + "GTK_IM_MODULE=scim", + "ELM_PROFILE=mobile", +}; +} // anonymous namespace + + +PopupProxy::Pipe::Pipe() +{ + if (0 != ::pipe(m_fd)) + throw std::runtime_error("pipe() failed"); +} + +PopupProxy::Pipe::~Pipe() +{ + close(IN); + close(OUT); +} + +void PopupProxy::Pipe::close(End end) +{ + assert(end >= IN && end <= OUT); + + if (m_fd[end] == INVALID) + return; + + ::close(m_fd[end]); + m_fd[end] = INVALID; +} + +int PopupProxy::Pipe::get(End end) +{ + assert(end >= IN && end <= OUT); + + return m_fd[end]; +} + +PopupProxy::PopupProxy() +{ + pid_t child = fork(); + if (child < 0) + throw std::runtime_error("fork() failed"); + + if (child == 0) { + m_toChild.close(Pipe::OUT); + m_fromChild.close(Pipe::IN); + + char password_popup[] = POPUP_SERVER; + + const size_t MAX_INT_STR = 10; + char toChildStr[MAX_INT_STR]; + char toParentStr[MAX_INT_STR]; + + if (0 > snprintf(toChildStr, MAX_INT_STR, "%d", m_toChild.get(Pipe::IN))) { + std::cerr << "snprintf() failed for " << m_toChild.get(Pipe::IN) << std::endl; + exit(1); + } + if (0 > snprintf(toParentStr, MAX_INT_STR, "%d", m_fromChild.get(Pipe::OUT))) { + std::cerr << "snprintf() failed for " << m_fromChild.get(Pipe::OUT) << std::endl; + exit(1); + } + char* argv[] = { password_popup, toChildStr, toParentStr, NULL }; + + size_t envLen = sizeof(ENVP)/sizeof(ENVP[0]); + char** envp = new char*[envLen + 1]; + for (size_t i = 0; i < envLen; i++) + envp[i] = strdup(ENVP[i]); + envp[envLen] = NULL; + + execve(password_popup, argv, envp); + + std::cerr << "execve() failed" << std::endl; + exit(1); + } else { + m_toChild.close(Pipe::IN); + m_fromChild.close(Pipe::OUT); + m_child = child; + } +} + +PopupProxy::~PopupProxy() +{ + m_toChild.write(MAGIC); + m_toChild.write(QUIT); + + int status; + int child; + do + child = waitpid(m_child, &status, 0); + while (child != m_child); + + if (WEXITSTATUS(status) != 0) + std::cerr << "Child returned an error " << WEXITSTATUS(status) << std::endl; +} + +std::string PopupProxy::getPassword(const std::string &app, enum PasswordType type) +{ + m_toChild.write(MAGIC); + m_toChild.write(GET_PW); + m_toChild.write(type); + m_toChild.write(app.size() + 1); + m_toChild.write(app.c_str(), app.size() + 1); + + PopupResult res; + size_t len; + m_fromChild.read(res); + m_fromChild.read(len); + char description[len] = {'\0'}; + m_fromChild.read(description, len); + + if (res == ERROR) + throw std::runtime_error(description); + + if (description[0] == '\0') + throw std::runtime_error("No password was entered."); + + return description; +} diff --git a/test/app_encryption/common/popup_proxy.h b/test/app_encryption/common/popup_proxy.h new file mode 100644 index 00000000..8d51e8d4 --- /dev/null +++ b/test/app_encryption/common/popup_proxy.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/* + * @file popup_proxy.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#pragma once + +#include <string> + +#include "popup_server.h" + +class PopupProxy { +public: + PopupProxy(); + ~PopupProxy(); + + std::string getPassword(const std::string &app, enum PasswordType type); + +private: + class Pipe { + public: + enum End { + IN, + OUT + }; + + Pipe(); + ~Pipe(); + + void close(End end); + int get(End end); + + template <typename T> + void write(const T* data, size_t size) { + Fd::write(m_fd[OUT], data, size); + } + + template <typename T> + void write(const T& data) { + Fd::write(m_fd[OUT], data); + } + + template <typename T> + void read(T* data, size_t size) { + Fd::read(m_fd[IN], data, size); + } + + template <typename T> + void read(T& data) { + Fd::read(m_fd[IN], data); + } + + private: + const int INVALID = -1; + int m_fd[2]; + }; + + pid_t m_child; + Pipe m_toChild; + Pipe m_fromChild; +}; + +void forkAndWait(); diff --git a/test/app_encryption/encryption_setting/encryption_setting.cpp b/test/app_encryption/encryption_setting/encryption_setting.cpp index 11bb69d0..1207d4c4 100644 --- a/test/app_encryption/encryption_setting/encryption_setting.cpp +++ b/test/app_encryption/encryption_setting/encryption_setting.cpp @@ -30,19 +30,17 @@ #include "smack-rules.h" #include "common.h" +#include "popup_proxy.h" const char* const LABEL = "User::Pkg::org.tizen.encryption-setting"; void usage() { - std::cerr << "Usage: encryption_setting app_id action [-o old_password] [-n new_password]" << std::endl << std::endl << + std::cerr << "Usage: encryption_setting app_id action" << std::endl << std::endl << " Actions:" << std::endl << - " -e Enable encryption. Requires -n option." << std::endl << - " -d Disable encryption. Requires -o option." << std::endl << - " -c Change encryption password. Requires both -n and -o option." << std::endl << std::endl << - " Options:" << std::endl << - " -o old_password Password that is currently set. Don't use this option if you want to enable encryption." << std::endl << - " -n new_password New password to be set. Don't use this option if you want to disable encryption." << std::endl; + " -e Enable encryption." << std::endl << + " -d Disable encryption." << std::endl << + " -c Change encryption password." << std::endl; } enum class Action { @@ -53,7 +51,7 @@ enum class Action { int main(int argc, char* argv[]) { - if (argc < 4) { + if (argc != 3) { usage(); return 1; } @@ -83,11 +81,8 @@ int main(int argc, char* argv[]) if (0 != switchToDefaultUser()) return 1; - ret = security_manager_app_get_encryption_status(app, &status); - if (ret != SECURITY_MANAGER_SUCCESS) { - std::cerr << "Getting app encryption status failed " << ret << std::endl; + if (0 != getEncryptionStatus(app, status)) return 1; - } Action act; if (strcmp(argv[2],"-e") == 0) { @@ -120,43 +115,30 @@ int main(int argc, char* argv[]) return 1; } - for (int i=3; i<argc; i++) { - if ((act == Action::DISABLE_ENCRYPTION || act == Action::CHANGE_PASSWORD) && - strcmp(argv[i], "-o") == 0 && argc > i+1) { - i++; - gPasswords[Popup::PasswordType::OLD] = argv[i]; - } else if ((act == Action::ENABLE_ENCRYPTION || act == Action::CHANGE_PASSWORD) && - strcmp(argv[i], "-n") == 0 && argc > i+1) { - i++; - gPasswords[Popup::PasswordType::NEW] = argv[i]; - } else { - usage(); - return 1; - } - } - std::string old_password; std::string new_password; - Popup p; - try { - switch (act) { - case Action::DISABLE_ENCRYPTION: - old_password = p.getPassword(app, Popup::PasswordType::OLD); - break; - case Action::ENABLE_ENCRYPTION: - new_password = p.getPassword(app, Popup::PasswordType::NEW); - break; - case Action::CHANGE_PASSWORD: - old_password = p.getPassword(app, Popup::PasswordType::OLD); - new_password = p.getPassword(app, Popup::PasswordType::NEW); - break; - default: - std::cerr << "Unexpected action " << static_cast<int>(act) << std::endl; + { + PopupProxy p; + try { + switch (act) { + case Action::DISABLE_ENCRYPTION: + old_password = p.getPassword(app, PasswordType::OLD); + break; + case Action::ENABLE_ENCRYPTION: + new_password = p.getPassword(app, PasswordType::NEW); + break; + case Action::CHANGE_PASSWORD: + old_password = p.getPassword(app, PasswordType::OLD); + new_password = p.getPassword(app, PasswordType::NEW); + break; + default: + std::cerr << "Unexpected action " << static_cast<int>(act) << std::endl; + return 1; + } + } catch (std::runtime_error& exc) { + std::cerr << exc.what() << std::endl; return 1; } - } catch (std::runtime_error& exc) { - std::cerr << exc.what() << std::endl; - return 1; } ret = security_manager_app_change_password( diff --git a/test/app_encryption/launcher/launcher_user.cpp b/test/app_encryption/launcher/launcher_user.cpp index 5b0bcf17..e7feec0e 100644 --- a/test/app_encryption/launcher/launcher_user.cpp +++ b/test/app_encryption/launcher/launcher_user.cpp @@ -24,6 +24,7 @@ #include <stdexcept> #include <sstream> #include <fstream> +#include <memory> #include <cstring> #include <unistd.h> @@ -34,14 +35,14 @@ #include "security-manager.h" #include "common.h" +#include "popup_proxy.h" #include "tzplatform-config.h" using namespace SecurityManager; void usage() { - std::cerr << "Usage: launcher app_id [-p password] [-f]" << std::endl << std::endl << - " -p password Password used for encryption/decryption." << std::endl << + std::cerr << "Usage: launcher app_id [-f]" << std::endl << std::endl << " -f First application launch.\n" << std::endl; } @@ -71,15 +72,15 @@ int validate_caller() int prepare_app(const char* app, bool first) { app_encryption_status status; - int ret = security_manager_app_get_encryption_status(app, &status); - if (ret != SECURITY_MANAGER_SUCCESS) { - std::cerr << "Geting app encryption status failed " << ret << std::endl; - return 1; - } - std::string pass; + int ret; + + if (0 != getEncryptionStatus(app, status)) + return 1; try { + std::unique_ptr<PopupProxy> p; + // first run if (first) { if ((status & SM_APP_ENCR_HAS_PASSWORD) != 0) { @@ -90,8 +91,8 @@ int prepare_app(const char* app, bool first) // suggest encryption if app has any sensitive dirs if ((status & SM_APP_ENCR_HAS_SENSITIVE_DIRS) != 0) { - Popup p; - pass = p.getPassword(app, Popup::PasswordType::NEW); + p.reset(new PopupProxy()); + pass = p->getPassword(app, PasswordType::NEW); // user doesn't want to encrypt the app if (!pass.empty()) { @@ -104,26 +105,13 @@ int prepare_app(const char* app, bool first) } } } else if ((status & SM_APP_ENCR_HAS_PASSWORD) != 0) { - Popup p; - pass = p.getPassword(app, Popup::PasswordType::CURRENT); + p.reset(new PopupProxy()); + pass = p->getPassword(app, PasswordType::CURRENT); if (pass.empty()) { std::cerr << "Empty password given. Aborting." << std::endl; return 1; } - } else { - /* - * Not a first launch and app has no password. - * - * TODO This has to be removed. When EFL popup is implemented and app - * has no password there will be no possibility to pass it because the - * popup won't be shown to the user. - */ - if (gPasswords[Popup::PasswordType::CURRENT] != NULL) { - std::cerr << "Application has no password but it was given. Aborting." - << std::endl; - return 1; - } } } catch (const std::runtime_error &exc) { // user did not respond -> abort the launch @@ -141,8 +129,9 @@ int prepare_app(const char* app, bool first) } // prepare application - if (SECURITY_MANAGER_SUCCESS != security_manager_prepare_app(app)) { - std::cerr << "App preparation failed" << std::endl; + ret = security_manager_prepare_app(app); + if (ret != SECURITY_MANAGER_SUCCESS) { + std::cerr << "App preparation failed " << ret << std::endl; return 1; } @@ -160,6 +149,7 @@ int wait_for_key() newSettings.c_lflag &= (~ICANON & ~ECHO); if (tcsetattr( fileno( stdin ), TCSANOW, &newSettings ) != 0) { std::cerr << "tcsetattr() failed" << std::endl; + return 1; } @@ -211,6 +201,7 @@ int run_app(const std::string& pkgName) std::cout << "Press Enter to close it." << std::endl; std::cin.get(); } + return 0; } @@ -229,11 +220,7 @@ int main(int argc, char* argv[]) const char* app = argv[1]; for (int i = 2; i < argc; i++) { - if (strcmp(argv[i], "-p") == 0 && argc > i+1) { - // TODO remove when EFL popup is ready - i++; - gPasswords[Popup::PasswordType::CURRENT] = argv[i]; - } else if (strcmp(argv[i], "-f") == 0) { + if (strcmp(argv[i], "-f") == 0) { first = true; } else { usage(); @@ -241,9 +228,6 @@ int main(int argc, char* argv[]) } } - if (first) - gPasswords[Popup::PasswordType::NEW] = gPasswords[Popup::PasswordType::CURRENT]; - if (prepare_app(app, first) != 0) return 1; diff --git a/test/app_encryption/popup/CMakeLists.txt b/test/app_encryption/popup/CMakeLists.txt new file mode 100644 index 00000000..df726d54 --- /dev/null +++ b/test/app_encryption/popup/CMakeLists.txt @@ -0,0 +1,47 @@ +# Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz <k.jackiewicz@samsung.com> +# @brief Cmake for app encryption popup +# + +SET(APP_ENCRYPTION_RES_DIR ${APP_ENCRYPTION_DIR}/res/) +ADD_DEFINITIONS("-DRES_DIR=\"${APP_ENCRYPTION_RES_DIR}\"") + +FIND_PACKAGE(PkgConfig REQUIRED) +PKG_CHECK_MODULES(EFL_POPUP + REQUIRED + elementary + capi-ui-efl-util +) + +SET(POPUP_SERVER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/popup_server.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/popup.cpp +) + +INCLUDE_DIRECTORIES(${EFL_POPUP_INCLUDE_DIRS}) + +ADD_EXECUTABLE(${TARGET_POPUP_SERVER} ${POPUP_SERVER_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_POPUP_SERVER} + ${EFL_POPUP_LIBRARIES} +) + +SET_TARGET_PROPERTIES(${TARGET_POPUP_SERVER} PROPERTIES INSTALL_RPATH ${APP_ENCRYPTION_DIR}) + +INSTALL(TARGETS ${TARGET_POPUP_SERVER} DESTINATION ${APP_ENCRYPTION_DIR}) + +ADD_SUBDIRECTORY(res)
\ No newline at end of file diff --git a/test/app_encryption/popup/popup.cpp b/test/app_encryption/popup/popup.cpp new file mode 100644 index 00000000..9f48af59 --- /dev/null +++ b/test/app_encryption/popup/popup.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/* + * @file popup.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @author Mateusz Forc (m.forc@samsung.com) + * @version 1.0 + */ + +#include "popup.h" + +#include <stdexcept> + +#include <efl_util.h> + +namespace { +const float TIMEOUT = 300.0f; +const char* POPUP_TITLE = "App encryption"; +} // anonymous namespace + +Popup::Popup() +{ + initialize(); +} + +Popup::~Popup() +{ + evas_object_del(m_win); + m_win = nullptr; + elm_shutdown(); +} + +void Popup::hideCb(void *popup, Evas_Object *, void *) +{ + Popup *pop = static_cast<Popup*>(popup); //thank you EFL + evas_object_hide(pop->m_win); + elm_exit(); +} + +void Popup::changedCb(void *popup, Evas_Object *, void *) +{ + Popup *pop = static_cast<Popup*>(popup); //thank you EFL + elm_popup_timeout_set(pop->m_popup, TIMEOUT); + + elm_object_disabled_set(pop->m_okButton, elm_entry_is_empty(pop->m_entry)); +} + +void Popup::initialize() +{ + if (1 != elm_init(0, nullptr)) + throw std::runtime_error("elm_init() failed"); + + m_win = elm_win_add(nullptr, POPUP_TITLE, ELM_WIN_NOTIFICATION); + if (m_win == NULL) + throw std::runtime_error("elm_win_add() failed"); + + if (EFL_UTIL_ERROR_NONE != efl_util_set_notification_window_level( + m_win, + EFL_UTIL_NOTIFICATION_LEVEL_3)) + throw std::runtime_error("efl_util_set_notification_window_level() failed"); + + elm_win_autodel_set(m_win, EINA_TRUE); + elm_win_override_set(m_win, EINA_TRUE); + elm_win_alpha_set(m_win, EINA_TRUE); + + // popup + m_popup = elm_popup_add(m_win); + if (m_popup == NULL) + throw std::runtime_error("elm_popup_add() failed"); + + elm_popup_align_set(m_popup, ELM_NOTIFY_ALIGN_FILL, 0.0); + elm_object_part_text_set(m_popup, "title,text", POPUP_TITLE); + elm_popup_timeout_set(m_popup, TIMEOUT); + evas_object_smart_callback_add(m_popup, "timeout", &Popup::hideCb, this); + + // layout + m_layout = elm_layout_add(m_popup); + if (m_layout == NULL) + throw std::runtime_error("elm_layout_add() failed"); + + if (EINA_TRUE != elm_layout_file_set(m_layout, RES_DIR"/popup_custom.edj", "entry_layout")) + throw std::runtime_error("elm_layout_file_set() failed"); + + // content + m_content = elm_label_add(m_layout); + if (m_content == NULL) + throw std::runtime_error("elm_label_add() failed"); + + elm_label_line_wrap_set(m_content, ELM_WRAP_MIXED); + if (EINA_TRUE != elm_object_style_set(m_content, "popup/default")) + throw std::runtime_error("elm_object_style_set() failed"); + + elm_object_part_content_set(m_layout, "content", m_content); + evas_object_show(m_content); + + // entry + m_entry = elm_entry_add(m_layout); + if (m_entry == NULL) { + throw std::runtime_error("elm_entry_add() failed"); + } + elm_entry_password_set(m_entry, EINA_TRUE); + elm_entry_single_line_set(m_entry, EINA_TRUE); + elm_object_part_content_set(m_layout, "entry", m_entry); + elm_entry_input_panel_return_key_type_set(m_entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE); + evas_object_show(m_entry); + evas_object_smart_callback_add(m_entry, "changed", &Popup::changedCb, this); + + // buttons + m_cancelButton = elm_button_add(m_popup); + if (m_cancelButton == NULL) { + throw std::runtime_error("elm_button_add() failed for cancel button"); + } + elm_object_part_content_set(m_popup, "button1", m_cancelButton); + elm_object_text_set(m_cancelButton, "Cancel"); + + m_okButton = elm_button_add(m_popup); + if (m_okButton == NULL) { + throw std::runtime_error("elm_button_add() failed for ok button"); + } + elm_object_part_content_set(m_popup, "button2", m_okButton); + elm_object_text_set(m_okButton, "Ok"); + elm_object_disabled_set(m_okButton, EINA_TRUE); + + elm_object_content_set(m_popup, m_layout); + evas_object_show(m_popup); + + evas_object_smart_callback_add(m_okButton, "clicked", &Popup::hideCb, this); + evas_object_smart_callback_add(m_cancelButton, "clicked", &Popup::hideCb, this); +} + +void Popup::show() +{ + evas_object_show(m_win); + elm_run(); +} + +void Popup::prepare(const std::string &app, enum PasswordType type) +{ + elm_entry_entry_set(m_entry, NULL); + + std::string description; + + switch (type) { + case OLD: + description = "Enter old password for "; + break; + case NEW: + description = "Enter new password for "; + break; + case CURRENT: + description = "Enter current password for "; + break; + } + + description.append(app); + + elm_object_text_set(m_content, description.c_str()); +} + +std::string Popup::getPassword(const std::string &app, enum PasswordType type) +{ + prepare(app, type); + show(); + + return std::string(elm_object_text_get(m_entry)); +} diff --git a/test/app_encryption/popup/popup.h b/test/app_encryption/popup/popup.h new file mode 100644 index 00000000..4be0d30d --- /dev/null +++ b/test/app_encryption/popup/popup.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/* + * @file popup.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @author Mateusz Forc (m.forc@samsung.com) + * @version 1.0 + */ + +#pragma once + +#include "popup_server.h" + +#include <Elementary.h> + +#include <string> + +class Popup { +public: + Popup(); + ~Popup(); + + std::string getPassword(const std::string &app, enum PasswordType type); + +private: + static void hideCb(void *, Evas_Object *, void *); + static void changedCb(void *, Evas_Object *, void *); + + void initialize(); + void show(); + void prepare(const std::string &app, enum PasswordType type); + + Evas_Object *m_win = nullptr; + Evas_Object *m_popup = nullptr; + Evas_Object *m_cancelButton = nullptr; + Evas_Object *m_okButton = nullptr; + Evas_Object *m_layout = nullptr; + Evas_Object *m_content = nullptr; + Evas_Object *m_entry = nullptr; +}; diff --git a/test/app_encryption/popup/popup_server.cpp b/test/app_encryption/popup/popup_server.cpp new file mode 100644 index 00000000..64607051 --- /dev/null +++ b/test/app_encryption/popup/popup_server.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/* + * @file popup_server.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "popup_server.h" +#include "popup.h" + +#include <string> +#include <iostream> +#include <sstream> +#include <stdexcept> +#include <memory> + +void writeResult(int fd, PopupResult result, const std::string &description) +{ + Fd::write(fd, result); + Fd::write(fd, description.size() + 1); + Fd::write(fd, description.c_str(), description.size() + 1); +} + +void writeError(int fd, const std::string &description) +{ + writeResult(fd, ERROR, description); +} + +void writeSuccess(int fd, const std::string &password) +{ + writeResult(fd, SUCCESS, password); +} + +int main(int argc, char* argv[]) +{ + if (argc != 3) { + std::cerr << "Wrong arguments (in & out descriptor)" << std::endl; + return 1; + } + + try { + std::stringstream ss1(argv[1]); + int input; + ss1 >> input; + std::unique_ptr<int, void(*)(int*)> inputPtr(&input, [](int* fd){ ::close(*fd); }); + + std::stringstream ss2(argv[2]); + int output; + ss2 >> output; + std::unique_ptr<int, void(*)(int*)> outputPtr(&output, [](int* fd){ ::close(*fd); }); + + Popup p; + + bool quit = false; + while(!quit) { + int magic; + do + Fd::read(input, magic); + while(magic != MAGIC); + + PopupCommand cmd; + Fd::read(input, cmd); + + switch (cmd) { + case GET_PW: + { + PasswordType type; + Fd::read(input, type); + + if (type < OLD || type > CURRENT) { + writeError(output, "Wrong popup type"); + break; + } + size_t len; + Fd::read(input, len); + char app[len]; + Fd::read(input, app, len); + + try { + writeSuccess(output, p.getPassword(app, type)); + } catch (const std::exception& e) { + writeError(output, e.what()); + } catch (...) { + writeError(output, "Unknown exception"); + } + break; + } + case QUIT: + quit = true; + break; + default: + writeError(output, "Wrong command"); + } + } + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + return 1; + } catch (...) { + std::cerr << "Unknown exception" << std::endl; + return 1; + } + + return 0; +} diff --git a/test/app_encryption/popup/popup_server.h b/test/app_encryption/popup/popup_server.h new file mode 100644 index 00000000..d84e1947 --- /dev/null +++ b/test/app_encryption/popup/popup_server.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/* + * @file popup_server.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#pragma once + +#include <stdexcept> +#include <unistd.h> + +enum PopupResult : char{ + SUCCESS = 0, + ERROR, +}; + +enum PasswordType : char { + OLD = 0, + NEW, + CURRENT, +}; + +enum PopupCommand : char { + GET_PW = 0, + QUIT, +}; + +const int MAGIC = 0xB16B00B5; + +namespace Fd { + +template <typename T> +void write(int fd, const T* data, size_t size) { + size_t left = size; + while (left > 0) { + auto written = TEMP_FAILURE_RETRY(::write(fd, data + size - left, size)); + if (written <= 0) + throw std::runtime_error("write() failed"); + left -= written; + } +} + +template <typename T> +void write(int fd, const T& data) { + write(fd, &data, sizeof(data)); +} + +template <typename T> +void read(int fd, T* data, size_t size) { + size_t left = size; + while (left > 0) { + auto read = TEMP_FAILURE_RETRY(::read(fd, data + size - left, size)); + if (read <= 0) + throw std::runtime_error("read() failed"); + left -= read; + } +} + +template <typename T> +void read(int fd, T& data) { + read(fd, &data, sizeof(data)); +} + +} // namespace Pipe diff --git a/test/app_encryption/popup/res/CMakeLists.txt b/test/app_encryption/popup/res/CMakeLists.txt new file mode 100644 index 00000000..8f3e13ad --- /dev/null +++ b/test/app_encryption/popup/res/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz <k.jackiewicz@samsung.com> +# @brief Cmake for app encryption popup edj file +# + +SET(OUTPUT_POPUP_EDJ ${CMAKE_CURRENT_BINARY_DIR}/popup_custom.edj) + +ADD_CUSTOM_COMMAND(OUTPUT ${OUTPUT_POPUP_EDJ} + COMMAND edje_cc -no-save ${CMAKE_CURRENT_SOURCE_DIR}/popup_custom.edc ${OUTPUT_POPUP_EDJ} +) + +ADD_CUSTOM_TARGET(PRODUCE_EDJ_FILE ALL DEPENDS ${OUTPUT_POPUP_EDJ}) + +INSTALL(FILES ${OUTPUT_POPUP_EDJ} DESTINATION ${APP_ENCRYPTION_RES_DIR}) diff --git a/test/app_encryption/popup/res/popup_custom.edc b/test/app_encryption/popup/res/popup_custom.edc new file mode 100644 index 00000000..8c7660d3 --- /dev/null +++ b/test/app_encryption/popup/res/popup_custom.edc @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +collections { +group { name: "entry_layout"; + parts { + part { name: "content"; + type: SWALLOW; + scale: 1; + description { state: "default" 0.0; + rel1.relative: 0.00 0.00; + rel2.relative: 1.00 0.50; + } + } + part { name: "bg"; + type: RECT; + scale: 1; + description { state: "default" 0.0; + color: 220 220 220 255; + rel1.relative: 0.10 0.50; + rel2.relative: 0.90 1.00; + } + } + part { name: "entry"; + type: SWALLOW; + scale: 1; + description { state: "default" 0.0; + rel1.to: "bg"; + rel2.to: "bg"; + } + } + } +} +} |