348 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			348 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2007 The Android Open Source Project
 | 
						|
 *
 | 
						|
 * 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.
 | 
						|
 */
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <string.h>
 | 
						|
#undef NDEBUG
 | 
						|
#include <assert.h>
 | 
						|
#include "permissions.h"
 | 
						|
 | 
						|
static int
 | 
						|
test_permission_list()
 | 
						|
{
 | 
						|
    PermissionRequestList list;
 | 
						|
    int ret;
 | 
						|
    int numRequests;
 | 
						|
 | 
						|
    /* Bad parameter
 | 
						|
     */
 | 
						|
    ret = initPermissionRequestList(NULL);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    /* Good parameter
 | 
						|
     */
 | 
						|
    ret = initPermissionRequestList(&list);
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    /* Bad parameters
 | 
						|
     */
 | 
						|
    ret = addPermissionRequestToList(NULL, NULL, false, 0);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    ret = addPermissionRequestToList(&list, NULL, false, 0);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    /* Good parameters
 | 
						|
     */
 | 
						|
    numRequests = 0;
 | 
						|
 | 
						|
    ret = addPermissionRequestToList(&list, "one", false, 1);
 | 
						|
    assert(ret == 0);
 | 
						|
    numRequests++;
 | 
						|
 | 
						|
    ret = addPermissionRequestToList(&list, "two", false, 2);
 | 
						|
    assert(ret == 0);
 | 
						|
    numRequests++;
 | 
						|
 | 
						|
    ret = addPermissionRequestToList(&list, "three", false, 3);
 | 
						|
    assert(ret == 0);
 | 
						|
    numRequests++;
 | 
						|
 | 
						|
    ret = addPermissionRequestToList(&list, "recursive", true, 55);
 | 
						|
    assert(ret == 0);
 | 
						|
    numRequests++;
 | 
						|
 | 
						|
    /* Validate the list
 | 
						|
     */
 | 
						|
    assert(list.requests != NULL);
 | 
						|
    assert(list.numRequests == numRequests);
 | 
						|
    assert(list.numRequests <= list.requestsAllocated);
 | 
						|
    bool sawOne = false;
 | 
						|
    bool sawTwo = false;
 | 
						|
    bool sawThree = false;
 | 
						|
    bool sawRecursive = false;
 | 
						|
    int i;
 | 
						|
    for (i = 0; i < list.numRequests; i++) {
 | 
						|
        PermissionRequest *req = &list.requests[i];
 | 
						|
        assert(req->allowed == 0);
 | 
						|
 | 
						|
        /* Order isn't guaranteed, so we have to switch every time.
 | 
						|
         */
 | 
						|
        if (strcmp(req->path, "one") == 0) {
 | 
						|
            assert(!sawOne);
 | 
						|
            assert(req->requested == 1);
 | 
						|
            assert(!req->recursive);
 | 
						|
            sawOne = true;
 | 
						|
        } else if (strcmp(req->path, "two") == 0) {
 | 
						|
            assert(!sawTwo);
 | 
						|
            assert(req->requested == 2);
 | 
						|
            assert(!req->recursive);
 | 
						|
            sawTwo = true;
 | 
						|
        } else if (strcmp(req->path, "three") == 0) {
 | 
						|
            assert(!sawThree);
 | 
						|
            assert(req->requested == 3);
 | 
						|
            assert(!req->recursive);
 | 
						|
            sawThree = true;
 | 
						|
        } else if (strcmp(req->path, "recursive") == 0) {
 | 
						|
            assert(!sawRecursive);
 | 
						|
            assert(req->requested == 55);
 | 
						|
            assert(req->recursive);
 | 
						|
            sawRecursive = true;
 | 
						|
        } else {
 | 
						|
            assert(false);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    assert(sawOne);
 | 
						|
    assert(sawTwo);
 | 
						|
    assert(sawThree);
 | 
						|
    assert(sawRecursive);
 | 
						|
 | 
						|
    /* Smoke test the teardown
 | 
						|
     */
 | 
						|
    freePermissionRequestListElements(&list);
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
test_permission_table()
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    /* Test the global permissions table.
 | 
						|
     * Try calling functions without initializing first.
 | 
						|
     */
 | 
						|
    ret = registerPermissionSet(0, NULL);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    ret = countPermissionConflicts((PermissionRequestList *)16, false);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    ret = getPermissionCount();
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    const Permission *p;
 | 
						|
    p = getPermissionAt(0);
 | 
						|
    assert(p == NULL);
 | 
						|
 | 
						|
    /* Initialize.
 | 
						|
     */
 | 
						|
    ret = permissionInit();
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    /* Make sure we can't initialize twice.
 | 
						|
     */
 | 
						|
    ret = permissionInit();
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    /* Test the inspection functions.
 | 
						|
     */
 | 
						|
    ret = getPermissionCount();
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    p = getPermissionAt(-1);
 | 
						|
    assert(p == NULL);
 | 
						|
 | 
						|
    p = getPermissionAt(0);
 | 
						|
    assert(p == NULL);
 | 
						|
 | 
						|
    p = getPermissionAt(1);
 | 
						|
    assert(p == NULL);
 | 
						|
 | 
						|
    /* Test registerPermissionSet().
 | 
						|
     * Try some bad parameter values.
 | 
						|
     */
 | 
						|
    ret = registerPermissionSet(-1, NULL);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    ret = registerPermissionSet(1, NULL);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    /* Register some permissions.
 | 
						|
     */
 | 
						|
    Permission p1;
 | 
						|
    p1.path = "one";
 | 
						|
    p1.allowed = 1;
 | 
						|
    ret = registerPermissionSet(1, &p1);
 | 
						|
    assert(ret == 0);
 | 
						|
    ret = getPermissionCount();
 | 
						|
    assert(ret == 1);
 | 
						|
 | 
						|
    Permission p2[2];
 | 
						|
    p2[0].path = "two";
 | 
						|
    p2[0].allowed = 2;
 | 
						|
    p2[1].path = "three";
 | 
						|
    p2[1].allowed = 3;
 | 
						|
    ret = registerPermissionSet(2, p2);
 | 
						|
    assert(ret == 0);
 | 
						|
    ret = getPermissionCount();
 | 
						|
    assert(ret == 3);
 | 
						|
 | 
						|
    ret = registerPermissionSet(0, NULL);
 | 
						|
    assert(ret == 0);
 | 
						|
    ret = getPermissionCount();
 | 
						|
    assert(ret == 3);
 | 
						|
 | 
						|
    p1.path = "four";
 | 
						|
    p1.allowed = 4;
 | 
						|
    ret = registerPermissionSet(1, &p1);
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    /* Make sure the table looks correct.
 | 
						|
     * Order is important;  more-recent additions
 | 
						|
     * should appear at higher indices.
 | 
						|
     */
 | 
						|
    ret = getPermissionCount();
 | 
						|
    assert(ret == 4);
 | 
						|
 | 
						|
    int i;
 | 
						|
    for (i = 0; i < ret; i++) {
 | 
						|
        const Permission *p;
 | 
						|
        p = getPermissionAt(i);
 | 
						|
        assert(p != NULL);
 | 
						|
        assert(p->allowed == (unsigned int)(i + 1));
 | 
						|
        switch (i) {
 | 
						|
        case 0:
 | 
						|
            assert(strcmp(p->path, "one") == 0);
 | 
						|
            break;
 | 
						|
        case 1:
 | 
						|
            assert(strcmp(p->path, "two") == 0);
 | 
						|
            break;
 | 
						|
        case 2:
 | 
						|
            assert(strcmp(p->path, "three") == 0);
 | 
						|
            break;
 | 
						|
        case 3:
 | 
						|
            assert(strcmp(p->path, "four") == 0);
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            assert(!"internal error");
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    p = getPermissionAt(ret);
 | 
						|
    assert(p == NULL);
 | 
						|
 | 
						|
    /* Smoke test the teardown
 | 
						|
     */
 | 
						|
    permissionCleanup();
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
test_allowed_permissions()
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
    int numPerms;
 | 
						|
 | 
						|
    /* Make sure these fail before initialization.
 | 
						|
     */
 | 
						|
    ret = countPermissionConflicts((PermissionRequestList *)1, false);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    ret = getAllowedPermissions((const char *)1, false, (unsigned int *)1);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    /* Initialize.
 | 
						|
     */
 | 
						|
    ret = permissionInit();
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    /* Make sure countPermissionConflicts() fails with bad parameters.
 | 
						|
     */
 | 
						|
    ret = countPermissionConflicts(NULL, false);
 | 
						|
    assert(ret < 0);
 | 
						|
 | 
						|
    /* Register a set of permissions.
 | 
						|
     */
 | 
						|
    Permission perms[] = {
 | 
						|
        { "/", PERM_NONE },
 | 
						|
        { "/stat", PERM_STAT },
 | 
						|
        { "/read", PERMSET_READ },
 | 
						|
        { "/write", PERMSET_WRITE },
 | 
						|
        { "/.stat", PERM_STAT },
 | 
						|
        { "/.stat/.read", PERMSET_READ },
 | 
						|
        { "/.stat/.read/.write", PERMSET_WRITE },
 | 
						|
        { "/.stat/.write", PERMSET_WRITE },
 | 
						|
    };
 | 
						|
    numPerms = sizeof(perms) / sizeof(perms[0]);
 | 
						|
    ret = registerPermissionSet(numPerms, perms);
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    /* Build a permission request list.
 | 
						|
     */
 | 
						|
    PermissionRequestList list;
 | 
						|
    ret = initPermissionRequestList(&list);
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    ret = addPermissionRequestToList(&list, "/stat", false, PERM_STAT);
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    ret = addPermissionRequestToList(&list, "/read", false, PERM_READ);
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    ret = addPermissionRequestToList(&list, "/write", false, PERM_WRITE);
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    //TODO: cover more cases once the permission stuff has been implemented
 | 
						|
 | 
						|
    /* All of the requests in the list should be allowed.
 | 
						|
     */
 | 
						|
    ret = countPermissionConflicts(&list, false);
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    /* Add a request that will be denied.
 | 
						|
     */
 | 
						|
    ret = addPermissionRequestToList(&list, "/stat", false, 1<<31 | PERM_STAT);
 | 
						|
    assert(ret == 0);
 | 
						|
 | 
						|
    ret = countPermissionConflicts(&list, false);
 | 
						|
    assert(ret == 1);
 | 
						|
 | 
						|
    //TODO: more tests
 | 
						|
 | 
						|
    permissionCleanup();
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
test_permissions()
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    ret = test_permission_list();
 | 
						|
    if (ret != 0) {
 | 
						|
        fprintf(stderr, "test_permission_list() failed: %d\n", ret);
 | 
						|
        return ret;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = test_permission_table();
 | 
						|
    if (ret != 0) {
 | 
						|
        fprintf(stderr, "test_permission_table() failed: %d\n", ret);
 | 
						|
        return ret;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = test_allowed_permissions();
 | 
						|
    if (ret != 0) {
 | 
						|
        fprintf(stderr, "test_permission_table() failed: %d\n", ret);
 | 
						|
        return ret;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 |