#include <sys/xattr.h>
#include <sys/smack.h>
#include <privilege-control.h>
+#include <fstream>
#define SMACK_RULES_DIR "/etc/smack/accesses.d/"
{ "test_subject_6", APPID_REVOKE, "wx" },
{ "test_subject_7", APPID_REVOKE, "rwx" }};
+namespace {
+
+const char* OSP_BLAHBLAH = "/usr/share/privilege-control/OSP_blahblah.smack";
+const char* WRT_BLAHBLAH = "/usr/share/privilege-control/WGT_blahblah.smack";
+const char* OTHER_BLAHBLAH = "/usr/share/privilege-control/blahblah.smack";
+const char* BLAHBLAH_FEATURE = "http://feature/blah/blahblah";
+
/**
* Check if every rule is true.
* @return 1 if ALL rules in SMACK, 0 if ANY rule isn't
RUNNER_TEST_GROUP_INIT(libprivilegecontrol)
-static int nftw_remove_labels(const char *fpath, const struct stat *sb,
+int nftw_remove_labels(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf)
{
smack_lsetlabel(fpath, NULL, SMACK_LABEL_ACCESS);
return 0;
}
-static int nftw_set_labels_non_app_dir(const char *fpath, const struct stat *sb,
+int nftw_set_labels_non_app_dir(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf)
{
smack_lsetlabel(fpath, CANARY_LABEL, SMACK_LABEL_ACCESS);
return 0;
}
-static int nftw_check_labels_non_app_dir(const char *fpath, const struct stat *sb,
+int nftw_check_labels_non_app_dir(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf)
{
int result;
return 0;
}
-static int nftw_check_labels_app_dir(const char *fpath, const struct stat *sb,
+int nftw_check_labels_app_dir(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf)
{
int result;
return 0;
}
-static int nftw_check_labels_app_shared_dir(const char *fpath, const struct stat *sb,
+int nftw_check_labels_app_shared_dir(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf)
{
int result;
return 0;
}
+int file_exists(const char* path)
+{
+ FILE* file = fopen(path, "r");
+ if (file) {
+ fclose(file);
+ return 0;
+ }
+ return -1;
+}
+
+void osp_blahblah_check(int line_no, const std::vector<std::string>& rules)
+{
+ std::ifstream smack_file(OSP_BLAHBLAH);
+ RUNNER_ASSERT_MSG(smack_file, "Line: " << line_no << " Failed to create " << OSP_BLAHBLAH);
+
+ auto it = rules.begin();
+ std::string line;
+ while(std::getline(smack_file,line)) {
+ RUNNER_ASSERT_MSG(it != rules.end(), "Line: " << line_no << "Additional line in file: " << line);
+ RUNNER_ASSERT_MSG(*it == line, "Line: " << line_no << " " << *it << "!=" << line);
+ it++;
+ }
+
+ RUNNER_ASSERT_MSG(it == rules.end(), "Line: " << line_no << " Missing line in file: " << *it);
+
+ smack_file.close();
+}
+
+void remove_smack_files()
+{
+ unlink(OSP_BLAHBLAH);
+ unlink(WRT_BLAHBLAH);
+ unlink(OTHER_BLAHBLAH);
+}
+
+} // namespace
+
/**
* Test setting labels for all files and folders in given path.
*/
RUNNER_ASSERT(0 == smack_accesses_add(smack.get(), subject, object, "-"));
RUNNER_ASSERT(0 == smack_accesses_apply(smack.get()));
}
+
+/**
+ * Add new API feature
+ */
+RUNNER_TEST(privilege_control07_add_api_feature)
+{
+ int result;
+
+ remove_smack_files();
+
+
+ // argument validation
+ result = add_api_feature(APP_TYPE_OSP, NULL, NULL, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+
+ result = add_api_feature(APP_TYPE_OSP,"" , NULL, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+
+
+ // already existing features
+ result = add_api_feature(APP_TYPE_OSP,"messaging" , NULL, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+
+ result = add_api_feature(APP_TYPE_OSP,"blahblah/messaging" , NULL, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+
+ result = add_api_feature(APP_TYPE_WGT,"blahblahblah/messaging" , NULL, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+
+ result = add_api_feature(APP_TYPE_OTHER,"blah/messaging" , NULL, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+
+
+ // empty features
+ result = add_api_feature(APP_TYPE_OSP,"blahblah" , NULL, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+
+ result = add_api_feature(APP_TYPE_WGT,"blahblah" , NULL, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+
+ result = add_api_feature(APP_TYPE_OTHER,"blahblah" , NULL, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+
+
+ // smack files existence
+ result = file_exists(OSP_BLAHBLAH);
+ RUNNER_ASSERT(result == -1);
+
+ result = file_exists(WRT_BLAHBLAH);
+ RUNNER_ASSERT(result == -1);
+
+ result = file_exists(OTHER_BLAHBLAH);
+ RUNNER_ASSERT(result == -1);
+
+
+ // empty rules
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , { NULL }, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+ result = file_exists(OSP_BLAHBLAH);
+ RUNNER_ASSERT(result == -1);
+
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){ "", NULL }, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+ result = file_exists(OSP_BLAHBLAH);
+ RUNNER_ASSERT(result == 0);
+ remove_smack_files();
+
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){ " \t\n", "\t \n", "\n\t ", NULL }, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+ result = file_exists(OSP_BLAHBLAH);
+ RUNNER_ASSERT(result == 0);
+ remove_smack_files();
+
+
+ // malformed rules
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){ "malformed", NULL }, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+ result = file_exists(OSP_BLAHBLAH);
+ RUNNER_ASSERT(result == -1);
+
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){ "malformed malformed", NULL }, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+ result = file_exists(OSP_BLAHBLAH);
+ RUNNER_ASSERT(result == -1);
+
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){ "-malformed malformed rwxat", NULL }, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+ result = file_exists(OSP_BLAHBLAH);
+ RUNNER_ASSERT(result == -1);
+
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){ "~/\"\\\ malformed rwxat", NULL }, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+ result = file_exists(OSP_BLAHBLAH);
+ RUNNER_ASSERT(result == -1);
+
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){ "subject object rwxat something else", NULL }, NULL);
+ RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
+ result = file_exists(OSP_BLAHBLAH);
+ RUNNER_ASSERT(result == -1);
+
+
+ // correct rules
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){ "malformed malformed maaaaaalformed", NULL }, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+ osp_blahblah_check(__LINE__, { "malformed malformed r--a-" });
+ remove_smack_files();
+
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){ "subject object foo", NULL }, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+ osp_blahblah_check(__LINE__, { "subject object -----" });
+ remove_smack_files();
+
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){
+ "subject object\t rwxat",
+ " \t \n",
+ "subject2\tobject2 txarw",
+ "",
+ NULL }, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+ osp_blahblah_check(__LINE__, { "subject object rwxat", "subject2 object2 rwxat"});
+ remove_smack_files();
+
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){
+ "Sub::jE,ct object a-RwX",
+ NULL }, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+ osp_blahblah_check(__LINE__, { "Sub::jE,ct object rwxa-"});
+ remove_smack_files();
+
+ // TODO For now identical/complementary rules are not merged.
+ result = add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE , (const char*[]){
+ "subject object rwxat",
+ " \t \n",
+ "subject object txarw",
+ "",
+ NULL }, NULL);
+ RUNNER_ASSERT(result == PC_OPERATION_SUCCESS);
+ osp_blahblah_check(__LINE__, { "subject object rwxat", "subject object rwxat"});
+ remove_smack_files();
+
+
+ // TODO database group ids
+}