Changes to PolicyEngine to support rowner and isop checks.
authorleechul <chuls.lee@samsung.com>
Mon, 28 Mar 2016 04:58:25 +0000 (13:58 +0900)
committerRandeep Singh <randeep.s@samsung.com>
Mon, 28 Mar 2016 06:18:38 +0000 (06:18 +0000)
Note that the pstat.isop must be set to "true" by the provisioning
tool after OTM is complete and provisioning is done!

patch #2 - added GetPstatIsop() function to pstatresource.h and .c.
Still needs to be properly provisioned by PT.

patch #3 - fixed unittest failure (workaround for now since proper
tests require device to be owned).  Also marked GetDeviceOwnerId()
function for fixing after schema updates are done.

patch #4 - change to Chul Lee's suggested design using function
array instead of case switch.  However it does not compile.  See
Reply comments please.

patch #5 - fixed compile error and also logic error (changed || to
&&)

patch #6 - implemented correct GetDoxmRownerId() in doxmresource.c.
Other entity handlers should follow this simple template after
schema update is done.

patch #7 - fixed build issue on other platforms (worked on Linux)

patch #8 - rebase

patch #9 - added correct functions for all resources with
rowner/rownerID vals.

patch #10 - changed behavior on SVRs without rownerID, since
devowner is already being checked.

patch #11 - rebase again

patch #12 - now that acl, amacl and cred have rownerID property,
added correct getRownerId() for those 3 resources

patch #13 - remove the unexpected condition in policyengine.c
            Please see my comments on line 465~473 in patch #12

Change-Id: If3c0a01f76260e10d3169fc0cfa79924175ca62d
Signed-off-by: Nathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Signed-off-by: Chul Lee <chuls.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/6185
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
18 files changed:
resource/csdk/security/include/internal/aclresource.h
resource/csdk/security/include/internal/amaclresource.h
resource/csdk/security/include/internal/credresource.h
resource/csdk/security/include/internal/doxmresource.h
resource/csdk/security/include/internal/dpairingresource.h
resource/csdk/security/include/internal/pconfresource.h
resource/csdk/security/include/internal/policyengine.h
resource/csdk/security/include/internal/pstatresource.h
resource/csdk/security/include/securevirtualresourcetypes.h
resource/csdk/security/src/aclresource.c
resource/csdk/security/src/amaclresource.c
resource/csdk/security/src/credresource.c
resource/csdk/security/src/doxmresource.c
resource/csdk/security/src/dpairingresource.c
resource/csdk/security/src/pconfresource.c
resource/csdk/security/src/policyengine.c
resource/csdk/security/src/pstatresource.c
resource/csdk/security/unittest/policyengine.cpp

index dc45d5c..5f1ac9d 100644 (file)
@@ -96,6 +96,15 @@ OCStackResult UpdateDefaultSecProvACL();
  */
 OCStackResult SetAclRownerId(const OicUuid_t* newROwner);
 
+
+/**
+ * Gets the OicUuid_t value for the rownerid of the acl resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetAclRownerId(OicUuid_t *rowneruuid);
+
 #ifdef __cplusplus
 }
 #endif
index 49b0dff..052b959 100644 (file)
@@ -73,7 +73,6 @@ OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsId);
 OCStackResult AmaclToCBORPayload(const OicSecAmacl_t *amacl, uint8_t **cborPayload,
                                  size_t *cborSize);
 
-
 /**
  * Internal function to update resource owner
  *
@@ -83,6 +82,14 @@ OCStackResult AmaclToCBORPayload(const OicSecAmacl_t *amacl, uint8_t **cborPaylo
  */
 OCStackResult SetAmaclRownerId(const OicUuid_t* newROwner);
 
+/**
+ * Gets the OicUuid_t value for the rownerid of the amacl resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetAmaclRownerId(OicUuid_t *rowneruuid);
+
 #ifdef __cplusplus
 }
 #endif
index f85d21f..7e12912 100644 (file)
@@ -169,6 +169,14 @@ void DeleteCredList(OicSecCred_t* cred);
  */
 OCStackResult SetCredRownerId(const OicUuid_t* newROwner);
 
+/**
+ * Gets the OicUuid_t value for the rownerid of the cred resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetCredRownerId(OicUuid_t *rowneruuid);
+
 #ifdef __cplusplus
 }
 #endif
index e9ce684..d6f98af 100644 (file)
@@ -88,9 +88,18 @@ OCStackResult GetDoxmDeviceID(OicUuid_t *deviceID);
 /**
  * Gets the OicUuid_t value for the owner of this device.
  *
- * @return ::OC_STACK_OK if devOwner is a valid UUID, otherwise ::OC_STACK_ERROR.
+ * @param devownerid a pointer to be assigned to the devownerid property
+ * @return ::OC_STACK_OK if devownerid is assigned correctly, else ::OC_STACK_ERROR.
  */
-OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner);
+OCStackResult GetDoxmDevOwnerId(OicUuid_t *devownerid);
+
+/**
+ * Gets the OicUuid_t value for the rowneruuid of the doxm resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid);
 
 /** This function deallocates the memory for OicSecDoxm_t .
  *
index 6769ed3..c69c5e6 100644 (file)
@@ -90,6 +90,13 @@ OCStackResult SavePairingPSK(OCDevAddr *endpoint,
             OicUuid_t *peerDevID, OicUuid_t *owner, bool isPairingServer);\r
 #endif // __WITH_DTLS__\r
 \r
+/**\r
+ * Gets the OicUuid_t value for the rownerid of the Dpairing resource.\r
+ *\r
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property\r
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.\r
+ */\r
+OCStackResult GetDpairingRownerId(OicUuid_t *rowneruuid);\r
 \r
 /**\r
  * Internal function to update resource owner\r
index 5494e62..4ad7baf 100644 (file)
@@ -126,6 +126,14 @@ void FreePdAclList(OicSecPdAcl_t* pdacls);
  */\r
 OCStackResult SetPconfRownerId(const OicUuid_t* newROwner);\r
 \r
+/**\r
+ * Gets the OicUuid_t value for the rownerid of the pconf resource.\r
+ *\r
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property\r
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.\r
+ */\r
+OCStackResult GetPconfRownerId(OicUuid_t *rowneruuid);\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
index c99849d..f28498e 100644 (file)
@@ -104,4 +104,6 @@ uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method);
  */
 void SetPolicyEngineState(PEContext_t *context, const PEState_t state);
 
+typedef OCStackResult (*GetSvrRownerId_t)(OicUuid_t *rowner);
+
 #endif //IOTVT_SRM_PE_H
index 90e5657..a36d142 100644 (file)
@@ -85,6 +85,21 @@ void RestorePstatToInitState();
  */
 OCStackResult SetPstatRownerId(const OicUuid_t* newROwner);
 
+/**
+ * Gets the OicUuid_t value for the rownerid of the pstat resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid);
+
+/**
+ * This function returns the "isop" status of the device.
+ *
+ * @return true iff pstat.isop == 1, else false
+ */
+bool GetPstatIsop();
+
 #ifdef __cplusplus
 }
 #endif
index 428f941..786658e 100644 (file)
@@ -239,8 +239,7 @@ typedef enum
 
 typedef enum
 {
-    NOT_A_SVR_RESOURCE = 0,
-    OIC_R_ACL_TYPE,
+    OIC_R_ACL_TYPE = 0,
     OIC_R_AMACL_TYPE,
     OIC_R_CRED_TYPE,
     OIC_R_CRL_TYPE,
@@ -249,7 +248,9 @@ typedef enum
     OIC_R_PCONF_TYPE,
     OIC_R_PSTAT_TYPE,
     OIC_R_SACL_TYPE,
-    OIC_R_SVC_TYPE
+    OIC_R_SVC_TYPE,
+    OIC_SEC_SVR_TYPE_COUNT, //define the value to number of SVR
+    NOT_A_SVR_RESOURCE = 99
 }OicSecSvrType_t;
 
 typedef enum
@@ -326,10 +327,6 @@ struct OicSecAcl
     char                **periods;       // 3:R:M*:N:String (<--M*; see Spec)
     char                **recurrences;   // 5:R:M:N:String
     OicUuid_t           rownerID;        // 8:R:S:Y:oic.uuid
-    // NOTE: we are using UUID for Owners instead of Svc type for mid-April
-    // SRM version only; this will change to Svc type for full implementation.
-    //TODO change Owners type to oic.sec.svc
-    //OicSecSvc_t         *Owners;        // 6:R:M:Y:oic.sec.svc
     OicSecAcl_t         *next;
 };
 
@@ -345,10 +342,6 @@ struct OicSecAmacl
     size_t              amssLen;        // the number of elts in Amss
     OicUuid_t           *amss;          // 1:R:M:Y:acl
     OicUuid_t           rownerID;        // 2:R:S:Y:oic.uuid
-    // NOTE: we are using UUID for Owners instead of Svc type for mid-April
-    // SRM version only; this will change to Svc type for full implementation.
-    //TODO change Owners type to oic.sec.svc
-    //OicSecSvc_t         *Owners;        // 2:R:M:Y:oic.sec.svc
     OicSecAmacl_t         *next;
 };
 
@@ -372,10 +365,6 @@ struct OicSecCred
     OicSecKey_t         privateData;    // 6:R:S:N:oic.sec.key
     char                *period;        // 7:R:S:N:String
     OicUuid_t           rownerID;        // 8:R:S:Y:oic.uuid
-    // NOTE: we are using UUID for Owners instead of Svc type for mid-April
-    // SRM version only; this will change to Svc type for full implementation.
-    //OicSecSvc_t         *Owners;        // 8:R:M:Y:oic.sec.svc
-    //TODO change Owners type to oic.sec.svc
     OicSecCred_t        *next;
 };
 
@@ -399,11 +388,6 @@ struct OicSecDoxm
     bool                dpc;            // 7:R:S:Y:Boolean
     OicUuid_t           owner;          // 8:R:S:Y:oic.uuid
     OicUuid_t           rownerID;       // 9:R:S:Y:oic.uuid
-    // NOTE: we are using UUID for Owner instead of Svc type for mid-April
-    // SRM version only; this will change to Svc type for full implementation.
-    //OicSecSvc_t       devOwner;        // 10:R:S:Y:oic.sec.svc
-    //OicSecSvc_t       rOwner;        // 11:R:S:Y:oic.sec.svc
-    //TODO change Owner type to oic.sec.svc
 };
 
 /**
@@ -423,8 +407,6 @@ struct OicSecPstat
     OicSecDpom_t        *sm;            // 5:R:M:Y:oic.sec.dpom
     uint16_t            commitHash;     // 6:R:S:Y:oic.sec.sha256
     OicUuid_t           rownerID;       // 7:R:S:Y:oic.uuid
-    //TODO: this is supposed to be a 256-bit uint; temporarily use uint16_t
-    //TODO: need to decide which 256 bit and 128 bit types to use... boost?
 };
 
 /**
index 4369e7b..8486834 100644 (file)
@@ -1486,3 +1486,14 @@ exit:
     memcpy(gAcl->rownerID.id, prevId.id, sizeof(prevId.id));
     return ret;
 }
+
+OCStackResult GetAclRownerId(OicUuid_t *rowneruuid)
+{
+    OCStackResult retVal = OC_STACK_ERROR;
+    if (gAcl)
+    {
+        *rowneruuid = gAcl->rownerID;
+        retVal = OC_STACK_OK;
+    }
+    return retVal;
+}
index 130ca00..eec1b2b 100644 (file)
@@ -630,7 +630,6 @@ exit:
     return OC_STACK_ERROR;
 }
 
-
 OCStackResult SetAmaclRownerId(const OicUuid_t* newROwner)
 {
     OCStackResult ret = OC_STACK_ERROR;
@@ -669,3 +668,13 @@ exit:
     return ret;
 }
 
+OCStackResult GetAmaclRownerId(OicUuid_t *rowneruuid)
+{
+    OCStackResult retVal = OC_STACK_ERROR;
+    if (gAmacl)
+    {
+        *rowneruuid = gAmacl->rownerID;
+        retVal = OC_STACK_OK;
+    }
+    return retVal;
+}
index 703ec90..070177c 100644 (file)
@@ -1441,3 +1441,13 @@ exit:
     return ret;
 }
 
+OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
+{
+    OCStackResult retVal = OC_STACK_ERROR;
+    if (gCred)
+    {
+        *rowneruuid = gCred->rownerID;
+        retVal = OC_STACK_OK;
+    }
+    return retVal;
+}
index 995dfb5..0ec3827 100644 (file)
@@ -1011,21 +1011,36 @@ OCStackResult GetDoxmDeviceID(OicUuid_t *deviceID)
     return OC_STACK_ERROR;
 }
 
-OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner)
+OCStackResult GetDoxmDevOwnerId(OicUuid_t *devownerid)
 {
     OCStackResult retVal = OC_STACK_ERROR;
     if (gDoxm)
     {
-        OIC_LOG_V(DEBUG, TAG, "gDoxm owned =  %d.", gDoxm->owned);
+        OIC_LOG_V(DEBUG, TAG, "GetDoxmDevOwnerId(): gDoxm owned =  %d.", \
+            gDoxm->owned);
         if (gDoxm->owned)
         {
-            *devOwner = gDoxm->owner; // TODO change to devOwner when available
+            *devownerid = gDoxm->owner;
             retVal = OC_STACK_OK;
         }
     }
     return retVal;
 }
 
+OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid)
+{
+    OCStackResult retVal = OC_STACK_ERROR;
+    if (gDoxm)
+    {
+        if( gDoxm->owned )
+        {
+            *rowneruuid = gDoxm->rownerID;
+                    retVal = OC_STACK_OK;
+        }
+    }
+    return retVal;
+}
+
 /**
  * Function to restore doxm resurce to initial status.
  * This function will use in case of error while ownership transfer
index 900509a..fdcf749 100644 (file)
@@ -748,3 +748,14 @@ exit:
     memcpy(gDpair->rownerID.id, prevId.id, sizeof(prevId.id));
     return ret;
 }
+
+OCStackResult GetDpairingRownerId(OicUuid_t *rowneruuid)
+{
+    OCStackResult retVal = OC_STACK_ERROR;
+    if (gDpair)
+    {
+        *rowneruuid = gDpair->rownerID;
+        retVal = OC_STACK_OK;
+    }
+    return retVal;
+}
index 016f513..c738d48 100644 (file)
@@ -1270,3 +1270,13 @@ exit:
     return ret;
 }
 
+OCStackResult GetPconfRownerId(OicUuid_t *rowneruuid)
+{
+    OCStackResult retVal = OC_STACK_ERROR;
+    if (gPconf)
+    {
+        *rowneruuid = gPconf->rownerID;
+        retVal = OC_STACK_OK;
+    }
+    return retVal;
+}
index c7faf10..8fc834c 100644 (file)
 #include "srmutility.h"
 #include "doxmresource.h"
 #include "iotvticalendar.h"
+#include "pstatresource.h"
+#include "dpairingresource.h"
+#include "pconfresource.h"
+#include "amaclresource.h"
+#include "credresource.h"
 
 #define TAG "SRM-PE"
 
@@ -108,16 +113,91 @@ void SetPolicyEngineState(PEContext_t *context, const PEState_t state)
 static bool IsRequestFromDevOwner(PEContext_t *context)
 {
     bool retVal = false;
-    OicUuid_t owner;
+    OicUuid_t ownerid;
 
     if(NULL == context)
     {
         return retVal;
     }
 
-    if(OC_STACK_OK == GetDoxmDevOwnerId(&owner))
+    if(OC_STACK_OK == GetDoxmDevOwnerId(&ownerid))
     {
-        retVal = UuidCmp(&context->subject, &owner);
+        retVal = UuidCmp(&context->subject, &ownerid);
+    }
+
+    return retVal;
+}
+
+// TODO - remove these function placeholders as they are implemented
+// in the resource entity handler code.
+// Note that because many SVRs do not have a rowner, in those cases we
+// just return "OC_STACK_ERROR" which results in a "false" return by
+// IsRequestFromResourceOwner().
+// As these SVRs are revised to have a rowner, these functions should be
+// replaced (see pstatresource.c for example of GetPstatRownerId).
+
+OCStackResult GetCrlRownerId(OicUuid_t *rowner)
+{
+    rowner = NULL;
+    return OC_STACK_ERROR;
+}
+
+OCStackResult GetSaclRownerId(OicUuid_t *rowner)
+{
+    rowner = NULL;
+    return OC_STACK_ERROR;
+}
+
+OCStackResult GetSvcRownerId(OicUuid_t *rowner)
+{
+    rowner = NULL;
+    return OC_STACK_ERROR;
+}
+
+static GetSvrRownerId_t GetSvrRownerId[OIC_SEC_SVR_TYPE_COUNT] = {
+    GetAclRownerId,
+    GetAmaclRownerId,
+    GetCredRownerId,
+    GetCrlRownerId,
+    GetDoxmRownerId,
+    GetDpairingRownerId,
+    GetPconfRownerId,
+    GetPstatRownerId,
+    GetSaclRownerId,
+    GetSvcRownerId
+};
+
+/**
+ * Compare the request's subject to resource.ROwner.
+ *
+ * @return true if context->subjectId equals SVR rowner id, else return false
+ */
+bool IsRequestFromResourceOwner(PEContext_t *context)
+{
+    bool retVal = false;
+    OicUuid_t resourceOwner;
+
+    if(NULL == context)
+    {
+        return false;
+    }
+
+    if((OIC_R_ACL_TYPE <= context->resourceType) && \
+        (OIC_SEC_SVR_TYPE_COUNT > context->resourceType))
+    {
+        if(OC_STACK_OK == GetSvrRownerId[(int)context->resourceType](&resourceOwner))
+        {
+            retVal = UuidCmp(&context->subject, &resourceOwner);
+        }
+    }
+
+    if(true == retVal)
+    {
+        OIC_LOG(INFO, TAG, "PE.IsRequestFromResourceOwner(): returning true");
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "PE.IsRequestFromResourceOwner(): returning false");
     }
 
     return retVal;
@@ -377,6 +457,12 @@ SRMAccessResponse_t CheckPermission(PEContext_t     *context,
         {
             context->retVal = ACCESS_GRANTED;
         }
+        // Then check if request is for a SVR and coming from rowner
+        else if (IsRequestFromResourceOwner(context))
+        {
+            context->retVal = ACCESS_GRANTED;
+        }
+        // Else request is a "normal" request that must be tested against ACL
         else
         {
             OicUuid_t saveSubject = {.id={}};
index f66b760..717eeb9 100644 (file)
@@ -47,7 +47,7 @@ static const uint8_t PSTAT_MAP_SIZE = 7;
 static OicSecDpom_t gSm = SINGLE_SERVICE_CLIENT_DRIVEN;
 static OicSecPstat_t gDefaultPstat =
 {
-    false,                                    // bool isOwned
+    false,                                    // bool isop
     (OicSecDpm_t)(BOOTSTRAP_SERVICE | SECURITY_MANAGEMENT_SERVICES |
     PROVISION_CREDENTIALS | PROVISION_ACLS),   // OicSecDpm_t cm
     (OicSecDpm_t)(TAKE_OWNER | BOOTSTRAP_SERVICE | SECURITY_MANAGEMENT_SERVICES |
@@ -598,3 +598,23 @@ exit:
     return ret;
 }
 
+/**
+ * This function returns the "isop" status of the device.
+ *
+ * @return true iff pstat.isop == 1, else false
+ */
+bool GetPstatIsop()
+{
+    return gPstat->isOp;
+}
+
+OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid)
+{
+    OCStackResult retVal = OC_STACK_ERROR;
+    if (gPstat)
+    {
+        *rowneruuid = gPstat->rownerID;
+        retVal = OC_STACK_OK;
+    }
+    return retVal;
+}
index 6890530..4806a96 100644 (file)
@@ -25,6 +25,7 @@
 #include "ocstack.h"
 #include "cainterface.h"
 #include "srmresourcestrings.h"
+#include "securevirtualresourcetypes.h"
 
 using namespace std;
 
@@ -50,22 +51,35 @@ OicUuid_t g_devOwner;
 char g_resource1[] = "Resource1";
 char g_resource2[] = "Resource2";
 
+extern OicSecDoxm_t *gDoxm;
+
 //Policy Engine Core Tests
 TEST(PolicyEngineCore, InitPolicyEngine)
 {
     EXPECT_EQ(OC_STACK_OK, InitPolicyEngine(&g_peContext));
 }
 
+// TODO - in order to unittest this we need InitDoxmResource() to put doxm
+// into Owned state with a known owner.  This will have to be done post v1.1.
 TEST(PolicyEngineCore, CheckPermissionNoAcls)
 {
-    EXPECT_EQ(ACCESS_DENIED_SUBJECT_NOT_FOUND,
-        CheckPermission(&g_peContext,
-                        &g_subjectIdA,
-                        g_resource1,
-                        PERMISSION_READ));
+    if(OC_STACK_OK == InitDoxmResource())
+    {
+        EXPECT_EQ(ACCESS_DENIED_SUBJECT_NOT_FOUND,
+            CheckPermission(&g_peContext,
+                            &g_subjectIdA,
+                            g_resource1,
+                            PERMISSION_READ));
+    }
+    else
+    {
+        printf("%s WARNING: InitDoxmResource() returned ERROR!\n", \
+            PE_UT_TAG);
+    }
 }
 
-//TODO This won't work until we figure out how to OcInit() or equivalent.
+// TODO - in order to unittest this we need InitDoxmResource() to put doxm
+// into Owned state with a known owner.  This will have to be done post v1.1.
 TEST(PolicyEngineCore, CheckDevOwnerRequest)
 {
     if(OC_STACK_OK == InitDoxmResource())
@@ -86,16 +100,15 @@ TEST(PolicyEngineCore, CheckDevOwnerRequest)
         }
         else
         {
-            printf("%s WARNING: InitDoxmResource() returned ERROR!\n", \
+            printf("%s WARNING: GetDoxmDevOwnerId() returned ERROR!\n", \
                 PE_UT_TAG);
         }
     }
     else
     {
-        printf("%s WARNING: GetDoxmDevOwnerId() returned ERROR!\n", PE_UT_TAG);
+        printf("%s WARNING: InitDoxmResource() returned ERROR!\n", \
+                PE_UT_TAG);
     }
-
-
 }
 
 TEST(PolicyEngineCore, DeInitPolicyEngine)