Пример #1
0
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);
}
Пример #2
0
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));
        }
    }
}
Пример #3
0
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);
    }
}
Пример #4
0
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));
}
Пример #5
0
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());
    }
}
Пример #6
0
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");
    }
}
Пример #7
0
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);
}
Пример #8
0
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));
    }
}
Пример #9
0
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);
    }
}
Пример #10
0
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;
}
Пример #11
0
/****************************************************************************
 * 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;
}
Пример #12
0
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);
    }
}
Пример #13
0
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");
    }
}
Пример #14
0
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");
    }
}
Пример #15
0
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");
}
Пример #17
0
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());

    };
}
Пример #18
0
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");
    }
}
Пример #19
0
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);
}
Пример #21
0
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");
    }
}
Пример #22
0
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");
}
Пример #28
0
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;
}
Пример #29
0
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());
}