558406a6921de51d3d1005c97bb2d135c0e4f282
[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 "psinterface.h"
28 #include "ocpayload.h"
29 #include "oic_malloc.h"
30 #include "oic_string.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 #include "doxmresource.h"
40 #include "ocpayload.h"
41 #include "ocpayloadcbor.h"
42 #include "payload_logging.h"
43 #include "security_internals.h"
44
45 using namespace std;
46
47 #define TAG  "SRM-ACL-UT"
48
49 // These paths match jenkins build configuration.
50 const char* DEFAULT_ACL_FILE_NAME = "/oic_unittest_default_acl.dat";
51 const char* ACL1_FILE_NAME = "/oic_unittest_acl1.dat";
52
53 #define NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT (1)
54
55 TEST(ACLResourceTest, CBORDefaultACLConversion)
56 {
57     OicSecAcl_t *defaultAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
58     ASSERT_TRUE(defaultAcl != NULL);
59     uint8_t defaultAclSub[] = { 0x2a };
60     memcpy(defaultAcl->subject.id, defaultAclSub, sizeof(defaultAclSub));
61     defaultAcl->permission = 2;
62     const char *defaulAclRsrc[] = { "/oic/res", "/oic/d", "/oic/p", "/oic/res/types/d",
63             "/oic/ad", "/oic/sec/acl", "/oic/sec/doxm", "/oic/sec/pstat"};
64     defaultAcl->resourcesLen = 8;
65     defaultAcl->resources = (char **)OICCalloc(defaultAcl->resourcesLen, sizeof(char *));
66     ASSERT_TRUE(defaultAcl->resources != NULL);
67     for (size_t i = 0 ; i < defaultAcl->resourcesLen; i++)
68     {
69         defaultAcl->resources[i] = OICStrdup(defaulAclRsrc[i]);
70         ASSERT_TRUE(defaultAcl->resources[i] != NULL);
71     }
72     uint8_t defaultAclOwnrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
73         0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
74     memcpy(defaultAcl->rownerID.id, defaultAclOwnrs, sizeof(defaultAclOwnrs));
75
76     size_t defaultAclSize = 0;
77     uint8_t *defaultPsStorage = NULL;
78     OCStackResult convRet = AclToCBORPayload(defaultAcl, &defaultPsStorage, &defaultAclSize);
79     EXPECT_EQ(OC_STACK_OK, convRet);
80     ASSERT_TRUE(defaultPsStorage != NULL);
81     EXPECT_NE(0, defaultAclSize);
82
83     OicSecAcl_t* convertedAcl = CBORPayloadToAcl(defaultPsStorage, defaultAclSize);
84     ASSERT_TRUE(convertedAcl != NULL);
85
86     EXPECT_EQ(defaultAcl->resourcesLen, convertedAcl->resourcesLen);
87     for(int i = 0; i < convertedAcl->resourcesLen; i++)
88     {
89         EXPECT_EQ(0, strcmp(defaultAcl->resources[i], convertedAcl->resources[i]));
90     }
91
92     DeleteACLList(convertedAcl);
93     DeleteACLList(defaultAcl);
94     OICFree(defaultPsStorage);
95 }
96
97 TEST(ACLResourceTest, CBORACLConversion)
98 {
99     OicSecAcl_t *secAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
100     ASSERT_TRUE(secAcl != NULL);
101     uint8_t subjectBytes[] = { 0x2a };
102     memcpy(secAcl->subject.id, subjectBytes, sizeof(subjectBytes));
103     secAcl->permission = 2;
104     const char *rsrc[] = { "/oic/res", "/oic/d", "/oic/p", "/oic/res/types/d",
105                            "/oic/ad", "/oic/sec/acl"};
106     secAcl->resourcesLen = 6;
107     secAcl->resources = (char **)OICCalloc(secAcl->resourcesLen, sizeof(char *));
108     ASSERT_TRUE(secAcl->resources != NULL);
109     for (size_t i = 0 ; i < secAcl->resourcesLen; i++)
110     {
111         secAcl->resources[i] = OICStrdup(rsrc[i]);
112         ASSERT_TRUE(secAcl->resources[i] != NULL);
113
114     }
115
116     uint8_t ownrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
117         0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
118     memcpy(secAcl->rownerID.id, ownrs, sizeof(ownrs));
119
120     OicSecAcl_t *secAcl1 = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
121     ASSERT_TRUE(secAcl1 != NULL);
122     memcpy(secAcl1->subject.id, subjectBytes, sizeof(subjectBytes));
123     secAcl1->permission = 6;
124     const char *rsrc1[] = { "/oic/sec/doxm", "/oic/sec/pstat"};
125     secAcl1->resourcesLen = 2;
126     secAcl1->resources = (char **)OICCalloc(secAcl1->resourcesLen, sizeof(char *));
127     ASSERT_TRUE(secAcl1->resources != NULL);
128     for (size_t i = 0 ; i < secAcl1->resourcesLen; i++)
129     {
130         secAcl1->resources[i] = OICStrdup(rsrc1[i]);
131         ASSERT_TRUE(secAcl1->resources[i] != NULL);
132     }
133     memcpy(secAcl1->rownerID.id, ownrs, sizeof(ownrs));
134     secAcl->next = secAcl1;
135
136     OicSecAcl_t *secAcl2 = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
137     ASSERT_TRUE(secAcl2 != NULL);
138     uint8_t subjectBytes1[] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
139         0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
140     memcpy(secAcl2->subject.id, subjectBytes1, sizeof(subjectBytes1));
141     secAcl2->permission = 255;
142     const char *rsrc2[] = {"/oic/light", "/oic/fan" };
143     secAcl2->resourcesLen = 2;
144     secAcl2->resources = (char **)OICCalloc(secAcl2->resourcesLen, sizeof(char *));
145     ASSERT_TRUE(secAcl2->resources != NULL);
146     for (size_t i = 0 ; i < secAcl2->resourcesLen; i++)
147     {
148         secAcl2->resources[i] = OICStrdup(rsrc2[i]);
149         ASSERT_TRUE(secAcl2->resources[i] != NULL);
150     }
151     memcpy(secAcl2->rownerID.id, ownrs, sizeof(ownrs));
152     secAcl1->next = secAcl2;
153
154     OicSecAcl_t *secAcl3 = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
155     ASSERT_TRUE(secAcl3 != NULL);
156     uint8_t subjectBytes2[] = {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
157                                0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33};
158     memcpy(secAcl3->subject.id, subjectBytes2, sizeof(subjectBytes2));
159     secAcl3->permission = 255;
160     const char *rsrc3[] = {"/oic/light", "/oic/garage" };
161     secAcl3->resourcesLen = 2;
162     secAcl3->resources = (char **)OICCalloc(secAcl3->resourcesLen, sizeof(char *));
163     ASSERT_TRUE(secAcl3->resources != NULL);
164     for (size_t i = 0 ; i < secAcl3->resourcesLen; i++)
165     {
166         secAcl3->resources[i] = OICStrdup(rsrc3[i]);
167         ASSERT_TRUE(secAcl3->resources[i] != NULL);
168     }
169     memcpy(secAcl3->rownerID.id, ownrs, sizeof(ownrs));
170     secAcl2->next = secAcl3;
171     secAcl3->next = NULL;
172
173     size_t size = 0;
174     uint8_t *psStorage = NULL;
175     EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(secAcl, &psStorage, &size));
176     ASSERT_TRUE(NULL != psStorage);
177     OicSecAcl_t *acl = CBORPayloadToAcl(psStorage, size);
178     ASSERT_TRUE(NULL != acl);
179     EXPECT_EQ(2, acl->permission);
180     EXPECT_EQ(6 , acl->resourcesLen);
181     EXPECT_STREQ("/oic/res", acl->resources[0]);
182     DeleteACLList(acl);
183     OICFree(psStorage);
184     DeleteACLList(secAcl);
185 }
186
187 //InitResource Tests
188 TEST(ACLResourceTest, InitAclResource)
189 {
190     EXPECT_EQ(OC_STACK_INVALID_PARAM, InitACLResource());
191     EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitACLResource());
192 }
193
194 // Default ACL tests
195 TEST(ACLResourceTest, GetDefaultACLTests)
196 {
197     uint8_t *payload = NULL;
198     size_t size = 0;
199
200     ASSERT_TRUE(ReadCBORFile(DEFAULT_ACL_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
201     ASSERT_TRUE(payload != NULL);
202
203     OicSecAcl_t *psAcl = CBORPayloadToAcl(payload, size);
204     ASSERT_TRUE(psAcl != NULL);
205
206     OicSecAcl_t *acl = NULL;
207     EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl));
208     ASSERT_TRUE(acl != NULL);
209
210     // Verify if the SRM generated default ACL matches with unit test default
211     if (acl && psAcl)
212     {
213         EXPECT_TRUE(strcmp((char*)acl->subject.id, (char*)psAcl->subject.id) == 0);
214         EXPECT_EQ(acl->resourcesLen, psAcl->resourcesLen);
215         for (size_t i = 0; i < acl->resourcesLen; i++)
216         {
217             EXPECT_EQ(strlen(acl->resources[i]), strlen(psAcl->resources[i]));
218             EXPECT_TRUE(memcmp(acl->resources[i], psAcl->resources[i],
219                             strlen(acl->resources[i])) == 0);
220         }
221         EXPECT_EQ(acl->permission, psAcl->permission);
222     }
223
224     DeleteACLList(psAcl);
225     DeleteACLList(acl);
226     DeInitACLResource();
227     OICFree(payload);
228 }
229
230 // 'POST' ACL tests
231 TEST(ACLResourceTest, ACLPostTest)
232 {
233     // Read an ACL from the file
234     uint8_t *payload = NULL;
235     size_t size = 0;
236
237     ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
238     ASSERT_TRUE(NULL != payload);
239
240     OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
241     ASSERT_TRUE(NULL != securityPayload);
242
243     static OCPersistentStorage ps = OCPersistentStorage();
244     SetPersistentHandler(&ps, true);
245
246     // Create Entity Handler POST request payload
247     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
248     ehReq.method = OC_REST_POST;
249     ehReq.payload = (OCPayload *) securityPayload;
250
251     ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
252
253     OicSecAcl_t *acl = CBORPayloadToAcl(payload, size);
254     ASSERT_TRUE(NULL != acl);
255
256     // Verify if SRM contains ACL for the subject
257     OicSecAcl_t *savePtr = NULL;
258     const OicSecAcl_t* subjectAcl = GetACLResourceData(&(acl->subject), &savePtr);
259     ASSERT_TRUE(NULL != subjectAcl);
260
261     // Perform cleanup
262     OICFree(payload);
263     OCPayloadDestroy((OCPayload *) securityPayload);
264     DeInitACLResource();
265     DeleteACLList(acl);
266 }
267
268 // GetACLResource tests
269 TEST(ACLResourceTest, GetACLResourceTests)
270 {
271     // Read an ACL from the file
272     static OCPersistentStorage ps = OCPersistentStorage();
273     SetPersistentHandler(&ps, true);
274
275     uint8_t *payload = NULL;
276     size_t size = 0;
277
278     ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
279     ASSERT_TRUE(payload != NULL);
280
281     OicSecAcl_t *defaultPsAcl = CBORPayloadToAcl(payload, size);
282     ASSERT_TRUE(defaultPsAcl != NULL);
283
284     OicSecAcl_t *acl1 = NULL;
285     EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl1));
286     ASSERT_TRUE(acl1 != NULL);
287     EXPECT_EQ(OC_STACK_OK, SetDefaultACL(acl1));
288
289     // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
290     const OicSecAcl_t *acl = NULL;
291     OicSecAcl_t *savePtr = NULL;
292     OicUuid_t subject = WILDCARD_SUBJECT_ID;
293     int count = 0;
294
295     do
296     {
297         acl = GetACLResourceData(&subject, &savePtr);
298         count = (NULL != acl) ? count + 1 : count;
299     } while (acl != NULL);
300
301     EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT);
302
303     /* Perform cleanup */
304     OICFree(payload);
305     DeleteACLList(defaultPsAcl);
306     DeInitACLResource();
307 }
308
309 static OCStackResult  populateAcl(OicSecAcl_t *acl,  int numRsrc)
310 {
311      OCStackResult ret = OC_STACK_ERROR;
312     memcpy(acl->subject.id, "2222222222222222", sizeof(acl->subject.id));
313     acl->resourcesLen = (size_t)numRsrc;
314     acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
315     VERIFY_NON_NULL(TAG, acl->resources, ERROR);
316     acl->resources[0] = (char*)OICMalloc(strlen("/a/led")+1);
317     VERIFY_NON_NULL(TAG, acl->resources[0], ERROR);
318     OICStrcpy(acl->resources[0], strlen("/a/led")+1, "/a/led");
319     if(numRsrc == 2)
320     {
321         acl->resources[1] = (char*)OICMalloc(strlen("/a/fan")+1);
322         VERIFY_NON_NULL(TAG, acl->resources[1], ERROR);
323         OICStrcpy(acl->resources[1], strlen("/a/fan")+1, "/a/fan");
324     }
325     acl->permission = 6;
326     memcpy(acl->rownerID.id, "1111111111111111", sizeof(acl->rownerID.id));
327
328     ret = OC_STACK_OK;
329 exit:
330     return ret;
331
332 }
333
334 //'DELETE' ACL test
335 TEST(ACLResourceTest, ACLDeleteWithSingleResourceTest)
336 {
337     //Populate ACL
338     OicSecAcl_t acl = OicSecAcl_t();
339     EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
340
341     //GET CBOR POST payload
342     size_t size = 0;
343     uint8_t  *payload = NULL;
344     EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
345     ASSERT_TRUE(NULL != payload);
346
347     // Security Payload
348     OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
349     ASSERT_TRUE(NULL != securityPayload);
350
351     static OCPersistentStorage ps = OCPersistentStorage();
352     SetPersistentHandler(&ps, true);
353
354     // Create Entity Handler POST request payload
355     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
356     ehReq.payload = (OCPayload *) securityPayload;
357     ehReq.method = OC_REST_POST;
358     ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
359
360     // Verify if SRM contains ACE for the subject
361     OicSecAcl_t* savePtr = NULL;
362     const OicSecAcl_t* subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
363     ASSERT_TRUE(NULL != subjectAcl1);
364
365     // Create Entity Handler DELETE request
366     ehReq.method = OC_REST_DELETE;
367     char query[] = "subjectuuid=2222222222222222;resources=/a/led";
368     ehReq.query = (char *)OICMalloc(strlen(query)+1);
369     ASSERT_TRUE(NULL !=  ehReq.query);
370     OICStrcpy(ehReq.query, strlen(query)+1, query);
371     ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
372
373     // Verify if SRM has deleted ACE for the subject
374     savePtr = NULL;
375     const OicSecAcl_t* subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
376     ASSERT_TRUE(NULL == subjectAcl2);
377
378     // Perform cleanup
379     DeInitACLResource();
380     OICFree(ehReq.query);
381     OCPayloadDestroy((OCPayload *)securityPayload);
382     OICFree(payload);
383 }
384
385 TEST(ACLResourceTest, ACLDeleteWithMultiResourceTest)
386 {
387     //Populate ACL
388     OicSecAcl_t acl = OicSecAcl_t();
389     EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 2));
390
391     //GET CBOR POST payload
392     size_t size = 0;
393     uint8_t *payload = NULL;
394     EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
395     ASSERT_TRUE(NULL != payload);
396
397     // Security Payload
398     OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
399     ASSERT_TRUE(NULL!= securityPayload);
400
401     static OCPersistentStorage ps = OCPersistentStorage();
402     SetPersistentHandler(&ps, true);
403
404     // Create Entity Handler POST request payload
405     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
406     ehReq.method = OC_REST_POST;
407     ehReq.payload = (OCPayload *)securityPayload;
408     ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
409
410     // Verify if SRM contains ACE for the subject with two resources
411     OicSecAcl_t* savePtr = NULL;
412     const OicSecAcl_t* subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
413     ASSERT_TRUE(NULL != subjectAcl1);
414     EXPECT_EQ(2, subjectAcl1->resourcesLen);
415
416     // Create Entity Handler DELETE request
417     ehReq.method = OC_REST_DELETE;
418     char query[] = "subjectuuid=2222222222222222;resources=/a/led";
419     ehReq.query = (char *)OICMalloc(strlen(query)+1);
420     ASSERT_TRUE(NULL != ehReq.query);
421     OICStrcpy(ehReq.query, strlen(query)+1, query);
422
423     ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
424
425     // Verify if SRM contains ACL for the subject but only with one resource
426     savePtr = NULL;
427     const OicSecAcl_t* subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
428     ASSERT_TRUE(NULL != subjectAcl2);
429     EXPECT_EQ(1, subjectAcl2->resourcesLen);
430
431     // Perform cleanup
432     OCPayloadDestroy((OCPayload *)securityPayload);
433     DeInitACLResource();
434     OICFree(ehReq.query);
435     OICFree(payload);
436 }
437
438 //'GET' with query ACL test
439 TEST(ACLResourceTest, ACLGetWithQueryTest)
440 {
441     //Populate ACL
442     OicSecAcl_t acl = OicSecAcl_t();
443     EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
444
445     //GET CBOR POST payload
446     size_t size = 0;
447     uint8_t *payload = NULL;
448     EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
449     ASSERT_TRUE(NULL != payload);
450
451     // Security Payload
452     OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
453     ASSERT_TRUE(NULL != securityPayload);
454
455     static OCPersistentStorage ps = OCPersistentStorage();
456     SetPersistentHandler(&ps, true);
457
458     //Create Entity Handler POST request payload
459     OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
460     ehReq.method = OC_REST_POST;
461     ehReq.payload = (OCPayload *)securityPayload;
462     ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
463
464     //Create Entity Handler GET request wit query
465     ehReq.method = OC_REST_GET;
466     char query[] = "subjectuuid=2222222222222222;resources=/a/led";
467     ehReq.query = (char*)OICMalloc(strlen(query)+1);
468     ASSERT_TRUE(NULL != ehReq.query);
469     OICStrcpy(ehReq.query, strlen(query)+1, query);
470
471     ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
472
473     // Perform cleanup
474     OCPayloadDestroy((OCPayload *)securityPayload);
475     DeInitACLResource();
476     OICFree(ehReq.query);
477     OICFree(payload);
478 }