Merge branch 'jb49488' into 'master'

[booster] Expose privilege values for use. JB#49488

See merge request mer-core/mapplauncherd!18
pull/1/head
Andrew Branson 6 years ago
commit 02bba3a3c6

@ -20,7 +20,10 @@
#include "appdata.h"
#include "protocol.h"
#include <stdint.h>
#include <stdio.h>
#include <sys/types.h>
#include <fstream>
#include <dirent.h>
AppData::AppData() :
m_options(0),
@ -99,6 +102,7 @@ const string & AppData::appName() const
void AppData::setFileName(const string & newFileName)
{
m_fileName = newFileName;
checkPrivileges();
}
const string & AppData::fileName() const
@ -162,6 +166,83 @@ gid_t AppData::groupId() const
return m_gid;
}
string AppData::getPrivileges(const char *path)
{
/*
Returns string of the declared privileges for this app.
The privileges file has the following format:
/full/path/to/app,<permissions_list>
where the permissions_list is a string of characters
defining different categories of permissions
eg: p = people/contacts data
example:
/usr/bin/vcardconverter,p
Currently, permission means both read+write permission.
Comment lines start with # and are ignored.
*/
std::ifstream infile(path);
if (infile) {
std::string line;
while (std::getline(infile, line)) {
if (line.find('#') == 0) {
// Comment line
continue;
}
size_t pos = line.find(',');
if (pos != std::string::npos) {
std::string filename = line.substr(0, pos);
std::string permissions = line.substr(pos+1);
if (filename == m_fileName) {
return permissions;
}
}
}
}
return "";
}
void AppData::checkPrivileges()
{
/*
This function checks the standard paths to find privileges definition file
and sets the m_privileges string.
First it will check
/usr/share/mapplauncherd/privileges
And then, any file in
/usr/share/mapplauncherd/privileges.d/
*/
static const char *BOOSTER_APP_PRIVILEGES_LIST = "/usr/share/mapplauncherd/privileges";
static const char *BOOSTER_APP_PRIVILEGES_DIR = "/usr/share/mapplauncherd/privileges.d";
m_privileges = getPrivileges(BOOSTER_APP_PRIVILEGES_LIST);
DIR *privilegesDir = opendir(BOOSTER_APP_PRIVILEGES_DIR);
if (privilegesDir) {
dirent *dir = NULL;
while ((dir = readdir(privilegesDir))) {
std::string privilegesFile (BOOSTER_APP_PRIVILEGES_DIR);
privilegesFile += "/";
privilegesFile += dir->d_name;
m_privileges += getPrivileges(privilegesFile.c_str());
}
closedir(privilegesDir);
}
}
bool AppData::isPrivileged() const
{
return m_privileges.length() > 0;
}
string AppData::privileges() const
{
return m_privileges;
}
AppData::~AppData()
{
}

@ -120,10 +120,18 @@ public:
//! Get group ID of calling process
gid_t groupId() const;
//! Returns true if the child process should be privileged
bool isPrivileged() const;
//! Get privilege string for this app
string privileges() const;
private:
AppData(const AppData & r);
AppData & operator= (const AppData & r);
string getPrivileges(const char *path);
void checkPrivileges();
uint32_t m_options;
int m_argc;
@ -136,6 +144,7 @@ private:
vector<int> m_ioDescriptors;
gid_t m_gid;
uid_t m_uid;
string m_privileges;
};
#endif // APPDATA_H

@ -334,79 +334,6 @@ void Booster::renameProcess(int parentArgc, char** parentArgv,
}
}
static bool isPrivileged(AppData *appData, const char *path)
{
/*
Returns true if privileged, false if not privileged.
The privileges file has the following format:
/full/path/to/app,<permissions_list>
where the permissions_list is a string of characters
defining different categories of permissions
eg: p = people/contacts data
example:
/usr/bin/vcardconverter,p
Currently, permission means both read+write permission.
Comment lines start with # and are ignored.
*/
std::ifstream infile(path);
if (infile) {
std::string line;
while (std::getline(infile, line)) {
if (line.find('#') == 0) {
// Comment line
continue;
}
size_t pos = line.find(',');
if (pos != std::string::npos) {
std::string filename = line.substr(0, pos);
std::string permissions = line.substr(pos+1);
// TODO: Actually do something with "permissions"
if (filename == appData->fileName()) {
return true;
}
}
}
}
return false;
}
static bool isPrivileged(AppData *appData)
{
/*
Return true if privileged, false if not privileged.
This function checks the standard paths to find privileges definition file.
First it will check
/usr/share/mapplauncherd/privileges
And then, any file in
/usr/share/mapplauncherd/privileges.d/
*/
static const char *BOOSTER_APP_PRIVILEGES_LIST = "/usr/share/mapplauncherd/privileges";
static const char *BOOSTER_APP_PRIVILEGES_DIR = "/usr/share/mapplauncherd/privileges.d";
if (isPrivileged(appData, BOOSTER_APP_PRIVILEGES_LIST))
return true;
DIR *privilegesDir = opendir(BOOSTER_APP_PRIVILEGES_DIR);
if (!privilegesDir)
return false;
bool privileged = false;
dirent *dir = NULL;
while ((dir = readdir(privilegesDir)) && !privileged) {
std::string privilegesFile (BOOSTER_APP_PRIVILEGES_DIR);
privilegesFile += "/";
privilegesFile += dir->d_name;
privileged = isPrivileged(appData, privilegesFile.c_str());
}
closedir(privilegesDir);
return privileged;
}
struct NotCharacter {
char c;
@ -507,11 +434,7 @@ void Booster::setEnvironmentBeforeLaunch()
setCgroup(m_appData->fileName());
// Currently, we only have two levels of privileges:
// privileged and non-privileged.
// Going forward, this could be improved to support
// a larger range of privileges via ACLs.
if (!isPrivileged(m_appData)) {
if (!m_appData->isPrivileged()) {
// The application is not privileged. Drop group ID
// inherited from the booster executable.
gid_t gid = getgid();

@ -213,6 +213,8 @@ private:
//! True, if being run in boot mode.
bool m_bootMode;
std::string m_privileges;
#ifdef UNIT_TEST
friend class Ut_Booster;
#endif

Loading…
Cancel
Save