void updatePermissibleFile(uid_t uid, int installationType, const std::vector<std::string> &labelsForUser) { std::string nameFile = getPerrmissibleFileLocation(uid, installationType); std::ofstream fstream; openAndLockNameFile(nameFile, fstream); markPermissibleFileValid(getFd(fstream), nameFile, false); for (auto &label : labelsForUser) { fstream << label << '\n'; if (fstream.bad()) { LogError("Unable to write to file " << nameFile << ": " << GetErrnoString(errno)); ThrowMsg(PermissibleSetException::PermissibleSetException::FileWriteError, "Unable to write to file"); } } if (fstream.flush().fail()) { LogError("Error at fflush " << nameFile << ": " << GetErrnoString(errno)); ThrowMsg(PermissibleSetException::FileWriteError, "Error at fflush"); } if (fsync(getFd(fstream)) == -1) { LogError("Error at fsync " << nameFile << ": " << GetErrnoString(errno)); ThrowMsg(PermissibleSetException::FileWriteError, "Error at fsync"); } markPermissibleFileValid(getFd(fstream), nameFile, true); }
void SmackRules::saveToFile(const std::string &path) const { int fd; fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644)); if (fd == -1) { LogError("Failed to create file: " << path); ThrowMsg(SmackException::FileError, "Failed to create file: " << path); } if (smack_accesses_save(m_handle, fd)) { LogError("Failed to save rules to file: " << path); unlink(path.c_str()); ThrowMsg(SmackException::LibsmackError, "Failed to save rules to file: " << path); } if (close(fd) == -1) { if (errno == EIO) { LogError("I/O Error occured while closing the file: " << path << ", error: " << strerror(errno)); unlink(path.c_str()); ThrowMsg(SmackException::FileError, "I/O Error occured while closing the file: " << path << ", error: " << strerror(errno)); } else { // non critical error // don't change the return code, the descriptor should be closed despite the error. LogWarning("Error while closing the file: " << path << ", error: " << strerror(errno)); } } }
void SmackRules::uninstallRules(const std::string &path) { if (access(path.c_str(), F_OK) == -1) { if (errno == ENOENT) { LogWarning("Smack rules not found in file: " << path); return; } LogWarning("Cannot access smack rules path: " << path); ThrowMsg(SmackException::FileError, "Cannot access smack rules path: " << path); } try { SmackRules rules; rules.loadFromFile(path); if (smack_smackfs_path()) rules.clear(); } catch (const SmackException::Base &e) { LogWarning("Failed to clear smack kernel rules from file: " << path); // don't stop uninstallation } if (unlink(path.c_str()) == -1) { LogWarning("Failed to remove smack rules file: " << path); ThrowMsg(SmackException::FileError, "Failed to remove smack rules file: " << path); } }
void removeUserPermissibleFile(uid_t uid) { std::string nameFile = getPerrmissibleFileLocation(uid, SM_APP_INSTALL_LOCAL); std::string nameDir = FS::dirName(nameFile); if (unlink(nameFile.c_str()) != 0 && errno != ENOENT) ThrowMsg(PermissibleSetException::FileRemoveError, "Unable to remove user permissible file:" << GetErrnoString(errno)); if (rmdir(nameFile.c_str()) != 0 && errno != ENOENT) ThrowMsg(PermissibleSetException::FileRemoveError, "Unable to remove directory for user permissible file:" << GetErrnoString(errno)); }
T try_catch(const std::function<T()> &func) { try { return func(); } catch (DB::SqlConnection::Exception::SyntaxError &e) { LogError("Syntax error in command: " << e.DumpToString()); ThrowMsg(PrivilegeDb::Exception::InternalError, "Syntax error in command: " << e.DumpToString()); } catch (DB::SqlConnection::Exception::InternalError &e) { LogError("Mysterious internal error in SqlConnection class" << e.DumpToString()); ThrowMsg(PrivilegeDb::Exception::InternalError, "Mysterious internal error in SqlConnection class: " << e.DumpToString()); } }
static void openAndLockNameFile(const std::string &nameFile, T &fstream) { fstream.open(nameFile); if (!fstream.is_open()) { LogError("Unable to open file" << nameFile << ": " << GetErrnoString(errno)); ThrowMsg(PermissibleSetException::FileOpenError, "Unable to open file "); } int ret = TEMP_FAILURE_RETRY(flock(getFd(fstream), LOCK_EX)); if (ret == -1) { LogError("Unable to lock file " << nameFile << ": " << GetErrnoString(errno)); ThrowMsg(PermissibleSetException::FileLockError, "Unable to lock file"); } }
void CynaraAdmin::UserInit(uid_t uid, security_manager_user_type userType) { Bucket bucket; std::vector<CynaraAdminPolicy> policies; switch (userType) { case SM_USER_TYPE_SYSTEM: bucket = Bucket::USER_TYPE_SYSTEM; break; case SM_USER_TYPE_ADMIN: bucket = Bucket::USER_TYPE_ADMIN; break; case SM_USER_TYPE_GUEST: bucket = Bucket::USER_TYPE_GUEST; break; case SM_USER_TYPE_NORMAL: bucket = Bucket::USER_TYPE_NORMAL; break; case SM_USER_TYPE_ANY: case SM_USER_TYPE_NONE: case SM_USER_TYPE_END: default: ThrowMsg(CynaraException::InvalidParam, "User type incorrect"); } policies.push_back(CynaraAdminPolicy(CYNARA_ADMIN_WILDCARD, std::to_string(static_cast<unsigned int>(uid)), CYNARA_ADMIN_WILDCARD, Buckets.at(bucket), Buckets.at(Bucket::MAIN))); CynaraAdmin::getInstance().SetPolicies(policies); }
bool PrivilegeInfo::hasAttribute(PrivilegeAttr attr) { privilege_manager_privilege_type_e type; int ret = privilege_info_get_privilege_type(m_uid, m_pkgId.c_str(), m_privilege.c_str(), &type); if (ret != PRVMGR_ERR_NONE) ThrowMsg(Exception::UnknownError, "Error while getting privilege type " << ret); switch (attr) { case PrivilegeAttr::PRIVACY: return (type == PRIVILEGE_MANAGER_PRIVILEGE_TYPE_PRIVACY); case PrivilegeAttr::BLACKLIST: return (type == PRIVILEGE_MANAGER_PRIVILEGE_TYPE_BLACKLIST); default: ThrowMsg(Exception::InvalidAttribute, "Invalid privilege attribute " << static_cast<int>(attr)); } }
void SmackRules::addFromTemplate(const std::vector<std::string> &templateRules, const std::string &appId, const std::string &pkgId) { for (auto rule : templateRules) { if (rule.empty()) continue; std::stringstream stream(rule); std::string subject, object, permissions; stream >> subject >> object >> permissions; if (stream.fail() || !stream.eof()) { LogError("Invalid rule template: " << rule); ThrowMsg(SmackException::FileError, "Invalid rule template: " << rule); } if (subject == SMACK_APP_LABEL_TEMPLATE) subject = SmackLabels::generateAppLabel(appId); if (subject == SMACK_PKG_LABEL_TEMPLATE) subject = SmackLabels::generatePkgLabel(pkgId); if (object == SMACK_APP_LABEL_TEMPLATE) object = SmackLabels::generateAppLabel(appId); if (object == SMACK_PKG_LABEL_TEMPLATE) object = SmackLabels::generatePkgLabel(pkgId); add(subject, object, permissions); } }
int SocketManager::GetSocketFromSystemD( const GenericSocketService::ServiceDescription &desc) { int fd; // TODO optimalization - do it once in object constructor // and remember all information path->sockfd int n = sd_listen_fds(0); LogInfo("sd_listen_fds returns: " << n); if (n < 0) { LogError("Error in sd_listend_fds"); ThrowMsg(Exception::InitFailed, "Error in sd_listend_fds"); } for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) { if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, desc.serviceHandlerPath.c_str(), 0)) { LogInfo("Useable socket " << desc.serviceHandlerPath << " was passed by SystemD under descriptor " << fd); return fd; } } LogError("No useable sockets were passed by systemd."); return -1; }
/**************************************************************************** * UpdateApp from a given url. The dol is downloaded and overwrites the old one. ***************************************************************************/ int UpdateTask::DownloadApp(const char *url) { if(!url) { ThrowMsg(tr("Error"), tr("URL is empty.")); return -1; } //! append slash if it is missing std::string destPath = Settings.UpdatePath; if(destPath.size() > 0 && destPath[destPath.size()-1] != '/') destPath += '/'; destPath += "boot.zip"; CreateSubfolder(Settings.UpdatePath); int res = DownloadFileToPath(url, destPath.c_str(), false); if(res < 102400) { RemoveFile(destPath.c_str()); ThrowMsg(tr("Update failed"), tr("Could not download file.")); return -1; } else { StartProgress(tr("Extracting file...")); ZipFile zip(destPath.c_str()); zip.ExtractAll(Settings.UpdatePath); RemoveFile(destPath.c_str()); StopProgress(); if(Settings.UpdateMetaxml) DownloadMetaXml(); if(Settings.UpdateIconpng) DownloadIconPNG(); } return 1; }
static bool checkCynaraError(int result, const std::string &msg) { switch (result) { case CYNARA_API_SUCCESS: case CYNARA_API_ACCESS_ALLOWED: return true; case CYNARA_API_ACCESS_DENIED: return false; case CYNARA_API_OUT_OF_MEMORY: ThrowMsg(CynaraException::OutOfMemory, msg); case CYNARA_API_INVALID_PARAM: ThrowMsg(CynaraException::InvalidParam, msg); case CYNARA_API_SERVICE_NOT_AVAILABLE: ThrowMsg(CynaraException::ServiceNotAvailable, msg); case CYNARA_API_BUCKET_NOT_FOUND: ThrowMsg(CynaraException::BucketNotFound, msg); default: ThrowMsg(CynaraException::UnknownError, msg); } }
PrivilegeInfo::PrivilegeInfo(uid_t uid, const std::string &label, const std::string &privilege) : m_uid(uid), m_privilege(privilege) { try { SmackLabels::generateAppPkgNameFromLabel(label, m_appId, m_pkgId); } catch(const SmackException::InvalidLabel&) { LogDebug("Not an application label " << label); ThrowMsg(Exception::NotApplication, "Not an application label"); } }
static void markPermissibleFileValid(int fd, const std::string &nameFile, bool valid) { int ret; if (valid) ret = TEMP_FAILURE_RETRY(fchmod(fd, 00444)); else ret = TEMP_FAILURE_RETRY(fchmod(fd, 00000)); if (ret == -1) { LogError("Error at fchmod " << nameFile << ": " << GetErrnoString(errno)); ThrowMsg(PermissibleSetException::FileWriteError, "Error at fchmod"); } }
void UpdateTask::Execute(void) { TaskBegin(this); if(bUpdateApp) { int res = CheckForUpdate(); if(!bSilent) { if(res == 0) ThrowMsg(tr("No new updates available"), 0); else if(res < 0) ThrowMsg(tr("Error:"), tr("Can't connect to update server")); } } if(bUpdateLang) UpdateLanguageFiles(); if(bAutoDelete) Application::Instance()->PushForDelete(this); }
void ResourceDecryptor::GetDecryptedChunk(unsigned char* inBuf, unsigned char* decBuf, size_t inBufSize) { Assert(decBuf); Assert(m_decKey); if (decBuf == NULL || m_decKey == NULL) { ThrowMsg(ResourceDecryptor::Exception::EncryptionFailed, "Failed to Get Decryption Chunk"); } unsigned char ivec[16] = {0, }; AES_cbc_encrypt(inBuf, decBuf, inBufSize, m_decKey, ivec, AES_DECRYPT); LogDebug("Success decryption"); }
PrivilegeDb::PrivilegeDb(const std::string &path) { try { mSqlConnection = new DB::SqlConnection(path, DB::SqlConnection::Flag::None, DB::SqlConnection::Flag::RW); initDataCommands(); } catch (DB::SqlConnection::Exception::Base &e) { LogError("Database initialization error: " << e.DumpToString()); ThrowMsg(PrivilegeDb::Exception::IOError, "Database initialization error:" << e.DumpToString()); }; }
void readLabelsFromPermissibleFile(const std::string &nameFile, std::vector<std::string> &appLabels) { std::ifstream fstream; openAndLockNameFile(nameFile, fstream); std::string line; while (std::getline(fstream, line)) appLabels.push_back(line); if (fstream.bad()) { LogError("Failure while reading file " << nameFile << ": " << GetErrnoString(errno)); ThrowMsg(PermissibleSetException::FileReadError, "Failure while reading file"); } }
void SmackRules::addFromTemplateFile(const std::string &appId, const std::string &pkgId) { std::vector<std::string> templateRules; std::string line; std::ifstream templateRulesFile(APP_RULES_TEMPLATE_FILE_PATH); if (!templateRulesFile.is_open()) { LogError("Cannot open rules template file: " << APP_RULES_TEMPLATE_FILE_PATH); ThrowMsg(SmackException::FileError, "Cannot open rules template file: " << APP_RULES_TEMPLATE_FILE_PATH); } while (std::getline(templateRulesFile, line)) { templateRules.push_back(line); } if (templateRulesFile.bad()) { LogError("Error reading template file: " << APP_RULES_TEMPLATE_FILE_PATH); ThrowMsg(SmackException::FileError, "Error reading template file: " << APP_RULES_TEMPLATE_FILE_PATH); } addFromTemplate(templateRules, appId, pkgId); }
void ResourceDecryptor::SetDecryptionKey(std::string userKey) { /* TODO : get key from secure storage */ std::string keyPath = GetDefaultEncryptKeyPath() + userKey + "_dec"; LogDebug("Description Key path : " << keyPath); FILE* fp = fopen(keyPath.c_str(), "rb"); if (fp == NULL) { ThrowMsg(ResourceDecryptor::Exception::GetDecKeyFailed, "Failed to get decryption key"); } m_decKey = new AES_KEY; fread(m_decKey, 1, sizeof(AES_KEY),fp); fclose(fp); }
void CryptoAlgorithmSerializable::Serialize(IStream &stream) const { Serializer<size_t>::Serialize(stream, m_params.size()); for (const auto& it : m_params) { Serializer<int>::Serialize(stream, static_cast<int>(it.first)); uint64_t integer; RawBuffer buffer; if (it.second->getInt(integer)) Serializer<uint64_t>::Serialize(stream, integer); else if (it.second->getBuffer(buffer)) Serializer<RawBuffer>::Serialize(stream, buffer); else ThrowMsg(UnsupportedParam, "Unsupported param type"); } }
void initializeUserPermissibleFile(uid_t uid) { std::string nameFile = getPerrmissibleFileLocation(uid, SM_APP_INSTALL_LOCAL); std::string nameDir = FS::dirName(nameFile); if (mkdir(nameDir.c_str(), 0755) != 0 && errno != EEXIST) ThrowMsg(PermissibleSetException::FileInitError, "Unable to create directory for user permissible file:" << GetErrnoString(errno)); std::ofstream fstream; openAndLockNameFile(nameFile, fstream); SmackLabels::setSmackLabelForFd(getFd(fstream), "_"); markPermissibleFileValid(getFd(fstream), nameFile, true); }
bool SqlConnection::DataCommand::Step() { // Notify all after potentially synchronized database connection access ScopedNotifyAll notifyAll( m_masterConnection->m_synchronizationObject.Get()); for (;;) { int ret = sqlite3_step(m_stmt); if (ret == SQLITE_ROW) { LogPedantic("SQL data command step ROW"); return true; } else if (ret == SQLITE_DONE) { LogPedantic("SQL data command step DONE"); return false; } else if (ret == SQLITE_BUSY) { LogPedantic("Collision occurred while executing SQL command"); // Synchronize if synchronization object is available if (m_masterConnection->m_synchronizationObject) { LogPedantic("Performing synchronization"); m_masterConnection-> m_synchronizationObject->Synchronize(); continue; } // No synchronization object defined. Fail. } // Fatal error const char *error = sqlite3_errmsg(m_masterConnection->m_connection); LogPedantic("SQL step data command failed"); LogPedantic(" Error: " << error); ThrowMsg(Exception::InternalError, error); } }
void ZipInput::ReadGlobalComment(void *masterFile) { ScopedArray<char> comment(new char[m_globalCommentSize + 1]); if (unzGetGlobalComment(static_cast<unzFile>(masterFile), comment.Get(), m_globalCommentSize + 1) != UNZ_OK) { LogPedantic("Failed to read zip global comment"); ThrowMsg(Exception::ReadGlobalCommentFailed, "Failed to read global comment"); } m_globalComment = comment.Get(); LogPedantic("Global comment: " << m_globalComment); }
void SqlConnection::Connect(const std::string &address, Flag::Type type, Flag::Option flag) { if (m_connection != NULL) { LogPedantic("Already connected."); return; } LogPedantic("Connecting to DB: " << address << "..."); // Connect to database int result; if (type & Flag::UseLucene) { result = db_util_open_with_options( address.c_str(), &m_connection, flag, NULL); m_usingLucene = true; LogPedantic("Lucene index enabled"); } else { result = sqlite3_open_v2( address.c_str(), &m_connection, flag, NULL); m_usingLucene = false; LogPedantic("Lucene index disabled"); } if (result == SQLITE_OK) { LogPedantic("Connected to DB"); } else { LogPedantic("Failed to connect to DB!"); ThrowMsg(Exception::ConnectionBroken, address); } // Enable foreign keys TurnOnForeignKeys(); }
void ZipInput::ReadGlobalInfo(void *masterFile) { // Read number of entries and global comment unz_global_info globalInfo; if (unzGetGlobalInfo(static_cast<unzFile>(masterFile), &globalInfo) != UNZ_OK) { LogPedantic("Failed to read zip global info"); ThrowMsg(Exception::ReadGlobalInfoFailed, "Failed to read global info"); } m_numberOfFiles = static_cast<size_t>(globalInfo.number_entry); m_globalCommentSize = static_cast<size_t>(globalInfo.size_comment); LogPedantic("Number of files: " << m_numberOfFiles); LogPedantic("Global comment size: " << m_globalCommentSize); }
Main::Main() #ifdef DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND // GLIB loop intergration workaround : m_oldEcoreSelect(NULL) #endif // DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND { // Late EFL event handling Assert(g_lateMain == NULL); g_lateMain = this; // Increment ECORE init count to ensure we have all // subsystems correctly set-up until main dispatcher dtor // This is especially important when MainEventDispatcher // is a global object destroyed no earlier than crt destroy routine ecore_init(); #ifdef DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND // GLIB loop intergration workaround union ConvertPointer { Ecore_Select_Function pointer; EcoreSelectType function; } convert; convert.pointer = ecore_main_loop_select_func_get(); m_oldEcoreSelect = convert.function; ecore_main_loop_select_func_set(&EcoreSelectInterceptor); #endif // DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND // Register event invoker m_invokerHandler = ecore_main_fd_handler_add(WaitableHandleWatchSupport::WaitableInvokerHandle(), ECORE_FD_READ, &StaticDispatchInvoker, this, NULL, NULL); if (m_invokerHandler == NULL) ThrowMsg(Exception::CreateFailed, "Failed to register invoker handler!"); // It is impossible that there exist watchers at this time // No need to add watchers LogPedantic("ECORE event handler registered"); }
CynaraAdminPolicy::CynaraAdminPolicy(const std::string &client, const std::string &user, const std::string &privilege, int operation, const std::string &bucket) { this->client = strdup(client.c_str()); this->user = strdup(user.c_str()); this->privilege = strdup(privilege.c_str()); this->bucket = strdup(bucket.c_str()); if (this->bucket == nullptr || this->client == nullptr || this->user == nullptr || this->privilege == nullptr) { free(this->bucket); free(this->client); free(this->user); free(this->privilege); ThrowMsg(CynaraException::OutOfMemory, std::string("Error in CynaraAdminPolicy allocation.")); } this->result = operation; this->result_extra = nullptr; }
CynaraAdminPolicy::CynaraAdminPolicy(const std::string &client, const std::string &user, const std::string &privilege, const std::string &goToBucket, const std::string &bucket) { this->bucket = strdup(bucket.c_str()); this->client = strdup(client.c_str()); this->user = strdup(user.c_str()); this->privilege = strdup(privilege.c_str()); this->result_extra = strdup(goToBucket.c_str()); this->result = CYNARA_ADMIN_BUCKET; if (this->bucket == nullptr || this->client == nullptr || this->user == nullptr || this->privilege == nullptr || this->result_extra == nullptr) { free(this->bucket); free(this->client); free(this->user); free(this->privilege); free(this->result_extra); ThrowMsg(CynaraException::OutOfMemory, std::string("Error in CynaraAdminPolicy allocation.")); } }
void SocketManager::CreateDomainSocket( GenericSocketService *service, const GenericSocketService::ServiceDescription &desc) { int sockfd = GetSocketFromSystemD(desc); if (-1 == sockfd) { if (desc.systemdOnly) { LogError("Socket " << desc.serviceHandlerPath << " not provided by systemd."); ThrowMsg(Exception::InitFailed, "Socket " << desc.serviceHandlerPath << " must be provided by systemd, but it was not."); } sockfd = CreateDomainSocketHelp(desc); } auto &description = CreateDefaultReadSocketDescription(sockfd, false); description.isListen = true; description.interfaceID = desc.interfaceID; description.useSendMsg = desc.useSendMsg; description.service = service; LogDebug("Listen on socket: " << sockfd << " Handler: " << desc.serviceHandlerPath.c_str()); }