Update secure resource related modules(SRM,OTM,SRP,CKM,unit tests,samples)
[platform/upstream/iotivity.git] / resource / csdk / security / unittest / aclresourcetest.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "gtest/gtest.h"
22 #include <pwd.h>
23 #include <grp.h>
24 #include <linux/limits.h>
25 #include <sys/stat.h>
26 #include "ocstack.h"
27 #include "ocpayload.h"
28 #include "oic_malloc.h"
29 #include "oic_string.h"
30 #include "cJSON.h"
31 #include "cainterface.h"
32 #include "secureresourcemanager.h"
33 #include "securevirtualresourcetypes.h"
34 #include "srmresourcestrings.h"
35 #include "aclresource.h"
36 #include "srmtestcommon.h"
37 #include "srmutility.h"
38 #include "logger.h"
39
40 using namespace std;
41
42 #define TAG  "SRM-ACL-UT"
43
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47
48 extern char * BinToAclJSON(const OicSecAcl_t * acl, const bool isIncResName);
49 extern OicSecAcl_t * JSONToAclBin(const char * jsonStr, const bool isIncResName);
50 extern void DeleteACLList(OicSecAcl_t* acl);
51 OCStackResult  GetDefaultACL(OicSecAcl_t** defaultAcl);
52 OCEntityHandlerResult ACLEntityHandler (OCEntityHandlerFlag flag,
53                                         OCEntityHandlerRequest * ehRequest);
54 #ifdef __cplusplus
55 }
56 #endif
57
58 const char* JSON_FILE_NAME = "oic_unittest.json";
59 const char* DEFAULT_ACL_JSON_FILE_NAME = "oic_unittest_default_acl.json";
60 const char* ACL1_JSON_FILE_NAME = "oic_unittest_acl1.json";
61 const char* ACL_JSON_PAYLOAD_FILE_NAME = "oic_unittest_acl_payload.json";
62
63
64 #define NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON (2)
65
66 // JSON Marshalling Tests
67 TEST(ACLResourceTest, JSONMarshallingTests)
68 {
69     char *jsonStr1 = ReadFile(ACL1_JSON_FILE_NAME);
70     if (jsonStr1)
71     {
72         cJSON_Minify(jsonStr1);
73         /* Workaround : cJSON_Minify does not remove all the unwanted characters
74          from the end. Here is an attempt to remove those characters */
75         int len = strlen(jsonStr1);
76         while (len > 0)
77         {
78             if (jsonStr1[--len] == '}')
79             {
80                 break;
81             }
82         }
83         jsonStr1[len + 1] = 0;
84
85         OicSecAcl_t * acl = JSONToAclBin(jsonStr1, true);
86         EXPECT_TRUE(NULL != acl);
87
88         char * jsonStr2 = BinToAclJSON(acl, true);
89         EXPECT_TRUE(NULL != jsonStr2);
90
91         EXPECT_STREQ(jsonStr1, jsonStr2);
92
93         OICFree(jsonStr1);
94         OICFree(jsonStr2);
95         DeleteACLList(acl);
96     }
97 }
98
99 // Default ACL tests
100 TEST(ACLResourceTest, GetDefaultACLTests)
101 {
102     // Read default ACL from the file
103     char *jsonStr = ReadFile(DEFAULT_ACL_JSON_FILE_NAME);
104     if (jsonStr)
105     {
106         OicSecAcl_t * acl = JSONToAclBin(jsonStr, true);
107         EXPECT_TRUE(NULL != acl);
108
109         // Invoke API to generate default ACL
110         OicSecAcl_t * defaultAcl = NULL;
111         OCStackResult ret = GetDefaultACL(&defaultAcl);
112         EXPECT_TRUE(NULL == defaultAcl);
113
114         EXPECT_TRUE(OC_STACK_ERROR == ret);
115
116         // Verify if the SRM generated default ACL matches with unit test default
117         if (acl && defaultAcl)
118         {
119             EXPECT_TRUE(memcmp(&(acl->subject), &(defaultAcl->subject), sizeof(OicUuid_t)) == 0);
120             EXPECT_EQ(acl->resourcesLen, defaultAcl->resourcesLen);
121             for (size_t i = 0; i < acl->resourcesLen; i++)
122             {
123                 EXPECT_EQ(strlen(acl->resources[i]), strlen(defaultAcl->resources[i]));
124                 EXPECT_TRUE(
125                         memcmp(acl->resources[i], defaultAcl->resources[i],
126                                 strlen(acl->resources[i])) == 0);
127             }
128             EXPECT_EQ(acl->permission, defaultAcl->permission);
129         }
130
131         // Perform cleanup
132         DeleteACLList(acl);
133         DeleteACLList(defaultAcl);
134         OICFree(jsonStr);
135     }
136 }
137
138
139 // 'POST' ACL tests
140 TEST(ACLResourceTest, ACLPostTest)
141 {
142     OCEntityHandlerRequest ehReq =  OCEntityHandlerRequest();
143
144     // Read an ACL from the file
145     char *jsonStr = ReadFile(ACL_JSON_PAYLOAD_FILE_NAME);
146     if (jsonStr)
147     {
148         static OCPersistentStorage ps = OCPersistentStorage();
149
150         SetPersistentHandler(&ps, true);
151
152         // Create Entity Handler POST request payload
153         ehReq.method = OC_REST_POST;
154         ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
155
156         OCEntityHandlerResult ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
157         EXPECT_TRUE(OC_EH_ERROR == ehRet);
158
159         // Convert JSON into OicSecAcl_t for verification
160         OicSecAcl_t * acl = JSONToAclBin(jsonStr, false);
161         EXPECT_TRUE(NULL != acl);
162
163         // Verify if SRM contains ACL for the subject
164         OicSecAcl_t* savePtr = NULL;
165         const OicSecAcl_t* subjectAcl = GetACLResourceData(&(acl->subject), &savePtr);
166         EXPECT_TRUE(NULL != subjectAcl);
167
168         // Perform cleanup
169         DeleteACLList(acl);
170         DeInitACLResource();
171         OCPayloadDestroy(ehReq.payload);
172         OICFree(jsonStr);
173     }
174 }
175
176
177 // GetACLResource tests
178 TEST(ACLResourceTest, GetACLResourceTests)
179 {
180     // gAcl is a pointer to the the global ACL used by SRM
181     extern OicSecAcl_t  *gAcl;
182
183     // Read an ACL from the file
184     char *jsonStr = ReadFile(ACL_JSON_PAYLOAD_FILE_NAME);
185     if (jsonStr)
186     {
187         gAcl = JSONToAclBin(jsonStr, false);
188         EXPECT_TRUE(NULL != gAcl);
189
190         // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
191         const OicSecAcl_t* acl = NULL;
192         OicSecAcl_t* savePtr = NULL;
193         OicUuid_t subject = WILDCARD_SUBJECT_ID;
194         int count = 0;
195
196         do
197         {
198             acl = GetACLResourceData(&subject, &savePtr);
199             count = (NULL != acl) ? count + 1 : count;
200         } while (acl != NULL);
201
202         EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON);
203
204         /* Perform cleanup */
205         DeleteACLList(gAcl);
206         gAcl = NULL;
207         OICFree(jsonStr);
208     }
209 }
210
211 static OCStackResult  populateAcl(OicSecAcl_t *acl,  int numRsrc)
212 {
213     OCStackResult ret = OC_STACK_ERROR;
214     memcpy(acl->subject.id, "2222222222222222", sizeof(acl->subject.id));
215     acl->resourcesLen = numRsrc;
216     acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
217     VERIFY_NON_NULL(TAG, acl->resources, ERROR);
218     acl->resources[0] = (char*)OICMalloc(strlen("/a/led")+1);
219     VERIFY_NON_NULL(TAG, acl->resources[0], ERROR);
220     OICStrcpy(acl->resources[0], sizeof(acl->resources[0]), "/a/led");
221     if(numRsrc == 2)
222     {
223         acl->resources[1] = (char*)OICMalloc(strlen("/a/fan")+1);
224         VERIFY_NON_NULL(TAG, acl->resources[1], ERROR);
225         OICStrcpy(acl->resources[1], sizeof(acl->resources[1]), "/a/fan");
226     }
227     acl->permission = 6;
228     acl->ownersLen = 1;
229     acl->owners = (OicUuid_t*)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
230     VERIFY_NON_NULL(TAG, acl->owners, ERROR);
231     memcpy(acl->owners->id, "1111111111111111", sizeof(acl->owners->id));
232
233     ret = OC_STACK_OK;
234 exit:
235     return ret;
236
237 }
238
239 //'DELETE' ACL test
240 TEST(ACLResourceTest, ACLDeleteWithSingleResourceTest)
241 {
242     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
243     static OCPersistentStorage ps = OCPersistentStorage();
244     char *jsonStr = NULL;
245     OicSecAcl_t acl = OicSecAcl_t();
246     OicSecAcl_t* savePtr = NULL;
247     const OicSecAcl_t* subjectAcl1 = NULL;
248     const OicSecAcl_t* subjectAcl2 = NULL;
249     OCEntityHandlerResult ehRet = OC_EH_ERROR;
250     char query[] = "sub=MjIyMjIyMjIyMjIyMjIyMg==;rsrc=/a/led";
251
252     SetPersistentHandler(&ps, true);
253
254     //Populate ACL
255     VERIFY_SUCCESS(TAG, (OC_STACK_OK == populateAcl(&acl, 1)), ERROR);
256
257     //GET json POST payload
258     jsonStr = BinToAclJSON(&acl, false);
259     VERIFY_NON_NULL(TAG, jsonStr, ERROR);
260
261     // Create Entity Handler POST request payload
262     ehReq.method = OC_REST_POST;
263     ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
264     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
265     EXPECT_TRUE(OC_EH_ERROR == ehRet);
266
267     // Verify if SRM contains ACE for the subject
268     savePtr = NULL;
269     subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
270     EXPECT_TRUE(NULL != subjectAcl1);
271
272     // Create Entity Handler DELETE request
273     ehReq.method = OC_REST_DELETE;
274     ehReq.query = (char*)OICMalloc(strlen(query)+1);
275     VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
276     OICStrcpy(ehReq.query, strlen(query)+1, query);
277     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
278     EXPECT_TRUE(OC_EH_ERROR == ehRet);
279
280     // Verify if SRM has deleted ACE for the subject
281     savePtr = NULL;
282     subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
283     EXPECT_TRUE(NULL == subjectAcl2);
284
285 exit:
286     // Perform cleanup
287     if(NULL != subjectAcl1)
288     {
289         DeInitACLResource();
290     }
291     OCPayloadDestroy(ehReq.payload);
292     OICFree(ehReq.query);
293     OICFree(jsonStr);
294
295 }
296
297 TEST(ACLResourceTest, ACLDeleteWithMultiResourceTest)
298 {
299     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
300     static OCPersistentStorage ps = OCPersistentStorage();
301     OicSecAcl_t acl = OicSecAcl_t();
302     char *jsonStr = NULL;
303     OicSecAcl_t* savePtr = NULL;
304     const OicSecAcl_t* subjectAcl1 = NULL;
305     const OicSecAcl_t* subjectAcl2 = NULL;
306     OCEntityHandlerResult ehRet = OC_EH_ERROR;
307     char query[] = "sub=MjIyMjIyMjIyMjIyMjIyMg==;rsrc=/a/led";
308
309     SetPersistentHandler(&ps, true);
310
311     //Populate ACL
312     VERIFY_SUCCESS(TAG, (OC_STACK_OK == populateAcl(&acl, 2)), ERROR);
313
314     //GET json POST payload
315     jsonStr = BinToAclJSON(&acl, false);
316     VERIFY_NON_NULL(TAG, jsonStr, ERROR);
317
318     // Create Entity Handler POST request payload
319     ehReq.method = OC_REST_POST;
320     ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
321     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
322     EXPECT_TRUE(OC_EH_ERROR == ehRet);
323
324     // Verify if SRM contains ACE for the subject with two resources
325     savePtr = NULL;
326     subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
327     EXPECT_TRUE(NULL != subjectAcl1);
328     EXPECT_TRUE(subjectAcl1->resourcesLen == 2);
329
330     // Create Entity Handler DELETE request
331     ehReq.method = OC_REST_DELETE;
332     ehReq.query = (char*)OICMalloc(strlen(query)+1);
333     VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
334     OICStrcpy(ehReq.query, strlen(query)+1, query);
335
336     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
337     EXPECT_TRUE(OC_EH_ERROR == ehRet);
338
339 exit:
340     // Perform cleanup
341     if(NULL != subjectAcl1)
342     {
343         DeInitACLResource();
344     }
345     OCPayloadDestroy(ehReq.payload);
346     OICFree(ehReq.query);
347     OICFree(jsonStr);
348 }
349
350 //'GET' with query ACL test
351
352 TEST(ACLResourceTest, ACLGetWithQueryTest)
353 {
354     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
355     static OCPersistentStorage ps = OCPersistentStorage();
356     OicSecAcl_t acl = OicSecAcl_t();
357     char *jsonStr = NULL;
358     OCEntityHandlerResult ehRet = OC_EH_ERROR;
359     char query[] = "sub=MjIyMjIyMjIyMjIyMjIyMg==;rsrc=/a/led";
360
361     SetPersistentHandler(&ps, true);
362
363     //Populate ACL
364     VERIFY_SUCCESS(TAG, (OC_STACK_OK == populateAcl(&acl, 1)), ERROR);
365
366     //GET json POST payload
367     jsonStr = BinToAclJSON(&acl, false);
368     VERIFY_NON_NULL(TAG, jsonStr, ERROR);
369
370     //Create Entity Handler POST request payload
371     ehReq.method = OC_REST_POST;
372     ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
373     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
374     EXPECT_TRUE(OC_EH_ERROR == ehRet);
375
376     //Create Entity Handler GET request wit query
377     ehReq.method =  OC_REST_GET;
378     ehReq.query = (char*)OICMalloc(strlen(query)+1);
379     VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
380     OICStrcpy(ehReq.query, strlen(query)+1, query);
381
382     ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
383     EXPECT_TRUE(OC_EH_OK == ehRet);
384
385 exit:
386     // Perform cleanup
387     OCPayloadDestroy(ehReq.payload);
388     OICFree(ehReq.query);
389     OICFree(jsonStr);
390 }