1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
26 #include "oic_malloc.h"
27 #include "oic_string.h"
30 #include "resourcemanager.h"
31 #include "psinterface.h"
33 #include "srmresourcestrings.h"
34 #include "amaclresource.h"
35 #include "srmutility.h"
39 #define TAG "SRM-AMACL"
41 OicSecAmacl_t *gAmacl = NULL;
42 static OCResourceHandle gAmaclHandle = NULL;
44 void DeleteAmaclList(OicSecAmacl_t* amacl)
48 OicSecAmacl_t *amaclTmp1 = NULL, *amaclTmp2 = NULL;
49 LL_FOREACH_SAFE(amacl, amaclTmp1, amaclTmp2)
53 LL_DELETE(amacl, amaclTmp1);
56 for (i = 0; i < amaclTmp1->resourcesLen; i++)
58 OICFree(amaclTmp1->resources[i]);
60 OICFree(amaclTmp1->resources);
63 OICFree(amaclTmp1->amss);
66 OICFree(amaclTmp1->owners);
68 // Clean Amacl node itself
75 * This internal method converts AMACL data into JSON format.
77 * Note: Caller needs to invoke 'free' when finished using the return string.
79 char * BinToAmaclJSON(const OicSecAmacl_t * amacl, const bool isIncResName)
81 cJSON *jsonRoot = NULL;
86 cJSON *jsonAmaclArray = NULL;
89 jsonRoot = cJSON_CreateObject();
90 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
91 cJSON_AddItemToObject(jsonRoot, OIC_JSON_AMACL_NAME,
92 jsonAmaclArray = cJSON_CreateArray());
96 jsonAmaclArray = cJSON_CreateArray();
97 jsonRoot = jsonAmaclArray;
99 VERIFY_NON_NULL(TAG, jsonAmaclArray, ERROR);
103 char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
105 B64Result b64Ret = B64_OK;
107 cJSON *jsonAmacl = cJSON_CreateObject();
109 // Resources -- Mandatory
110 cJSON *jsonRsrcArray = NULL;
111 cJSON_AddItemToObject(jsonAmacl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray =
112 cJSON_CreateArray());
113 VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
114 for (unsigned int i = 0; i < amacl->resourcesLen; i++)
116 cJSON_AddItemToArray(jsonRsrcArray, cJSON_CreateString(amacl->resources[i]));
120 cJSON *jsonAmsArray = NULL;
121 cJSON_AddItemToObject(jsonAmacl, OIC_JSON_AMSS_NAME, jsonAmsArray =
122 cJSON_CreateArray());
123 VERIFY_NON_NULL(TAG, jsonAmsArray, ERROR);
124 for (unsigned int i = 0; i < amacl->amssLen; i++)
128 b64Ret = b64Encode(amacl->amss[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
129 sizeof(base64Buff), &outLen);
130 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
132 cJSON_AddItemToArray(jsonAmsArray, cJSON_CreateString(base64Buff));
135 // Owners -- Mandatory
136 cJSON *jsonOwnrArray = NULL;
137 cJSON_AddItemToObject(jsonAmacl, OIC_JSON_OWNERS_NAME, jsonOwnrArray =
138 cJSON_CreateArray());
139 VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
140 for (unsigned int i = 0; i < amacl->ownersLen; i++)
144 b64Ret = b64Encode(amacl->owners[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
145 sizeof(base64Buff), &outLen);
146 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
148 cJSON_AddItemToArray(jsonOwnrArray, cJSON_CreateString(base64Buff));
151 // Attach current amacl node to Amacl Array
152 cJSON_AddItemToArray(jsonAmaclArray, jsonAmacl);
156 jsonStr = cJSON_PrintUnformatted(jsonRoot);
162 cJSON_Delete(jsonRoot);
171 * This internal method converts JSON AMACL into binary AMACL.
173 OicSecAmacl_t * JSONToAmaclBin(const char * jsonStr, const bool isIncResName)
175 OCStackResult ret = OC_STACK_ERROR;
176 OicSecAmacl_t * headAmacl = NULL;
177 OicSecAmacl_t * prevAmacl = NULL;
178 cJSON *jsonRoot = NULL;
179 cJSON *jsonAmaclArray = NULL;
181 VERIFY_NON_NULL(TAG, jsonStr, ERROR);
183 jsonRoot = cJSON_Parse(jsonStr);
184 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
188 jsonAmaclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
192 jsonAmaclArray = jsonRoot;
194 VERIFY_NON_NULL(TAG, jsonAmaclArray, INFO);
196 if (cJSON_Array == jsonAmaclArray->type)
198 int numAmacl = cJSON_GetArraySize(jsonAmaclArray);
201 VERIFY_SUCCESS(TAG, numAmacl > 0, INFO);
204 cJSON *jsonAmacl = cJSON_GetArrayItem(jsonAmaclArray, idx);
205 VERIFY_NON_NULL(TAG, jsonAmacl, ERROR);
207 OicSecAmacl_t *amacl = (OicSecAmacl_t*)OICCalloc(1, sizeof(OicSecAmacl_t));
208 VERIFY_NON_NULL(TAG, amacl, ERROR);
210 headAmacl = (headAmacl) ? headAmacl : amacl;
213 prevAmacl->next = amacl;
216 size_t jsonObjLen = 0;
217 cJSON *jsonObj = NULL;
219 // Resources -- Mandatory
220 jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_RESOURCES_NAME);
221 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
222 VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
224 amacl->resourcesLen = cJSON_GetArraySize(jsonObj);
225 VERIFY_SUCCESS(TAG, amacl->resourcesLen > 0, ERROR);
226 amacl->resources = (char**)OICCalloc(amacl->resourcesLen, sizeof(char*));
227 VERIFY_NON_NULL(TAG, (amacl->resources), ERROR);
232 cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
233 VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
235 jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
236 amacl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
237 VERIFY_NON_NULL(TAG, (amacl->resources[idxx]), ERROR);
238 OICStrcpy(amacl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);
239 } while ( ++idxx < amacl->resourcesLen);
242 VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_AMSS_NAME,
243 &(amacl->amssLen), &(amacl->amss)), ERROR);
245 // Owners -- Mandatory
246 VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_OWNERS_NAME,
247 &(amacl->ownersLen), &(amacl->owners)), ERROR);
250 } while( ++idx < numAmacl);
256 cJSON_Delete(jsonRoot);
257 if (OC_STACK_OK != ret)
259 DeleteAmaclList(headAmacl);
265 static OCEntityHandlerResult HandleAmaclGetRequest (const OCEntityHandlerRequest * ehRequest)
267 // Convert Amacl data into JSON for transmission
268 char* jsonStr = BinToAmaclJSON(gAmacl, false);
270 OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
272 // Send response payload to request originator
273 SendSRMResponse(ehRequest, ehRet, jsonStr);
277 OC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
281 static OCEntityHandlerResult HandleAmaclPostRequest (const OCEntityHandlerRequest * ehRequest)
283 OCEntityHandlerResult ehRet = OC_EH_ERROR;
285 // Convert JSON Amacl data into binary. This will also validate the Amacl data received.
286 OicSecAmacl_t* newAmacl = JSONToAmaclBin(((OCSecurityPayload*)ehRequest->payload)->securityData, false);
290 // Append the new Amacl to existing Amacl
291 LL_APPEND(gAmacl, newAmacl);
293 // Convert Amacl data into JSON for update to persistent storage
294 char *jsonStr = BinToAmaclJSON(gAmacl, true);
297 cJSON *jsonAmacl = cJSON_Parse(jsonStr);
301 (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_AMACL_NAME, jsonAmacl)))
303 ehRet = OC_EH_RESOURCE_CREATED;
305 cJSON_Delete(jsonAmacl);
309 // Send payload to request originator
310 SendSRMResponse(ehRequest, ehRet, NULL);
312 OC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
317 * This internal method is the entity handler for Amacl resources and
318 * will handle REST request (GET/PUT/POST/DEL) for them.
320 OCEntityHandlerResult AmaclEntityHandler (OCEntityHandlerFlag flag,
321 OCEntityHandlerRequest * ehRequest,
322 void* callbackParameter)
324 (void) callbackParameter;
325 OCEntityHandlerResult ehRet = OC_EH_ERROR;
332 if (flag & OC_REQUEST_FLAG)
334 OC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
335 switch (ehRequest->method)
338 ehRet = HandleAmaclGetRequest(ehRequest);
342 ehRet = HandleAmaclPostRequest(ehRequest);
347 SendSRMResponse(ehRequest, ehRet, NULL);
355 * This internal method is used to create '/oic/sec/amacl' resource.
357 OCStackResult CreateAmaclResource()
361 ret = OCCreateResource(&gAmaclHandle,
362 OIC_RSRC_TYPE_SEC_AMACL,
369 if (OC_STACK_OK != ret)
371 OC_LOG (FATAL, TAG, "Unable to instantiate Amacl resource");
372 DeInitAmaclResource();
378 * Initialize Amacl resource by loading data from persistent storage.
380 * @retval OC_STACK_OK for Success, otherwise some error value
382 OCStackResult InitAmaclResource()
384 OCStackResult ret = OC_STACK_ERROR;
386 // Read Amacl resource from PS
387 char* jsonSVRDatabase = GetSVRDatabase();
391 // Convert JSON Amacl into binary format
392 gAmacl = JSONToAmaclBin(jsonSVRDatabase, true);
393 OICFree(jsonSVRDatabase);
396 // Instantiate 'oic/sec/amacl' resource
397 ret = CreateAmaclResource();
399 if (OC_STACK_OK != ret)
401 DeInitAmaclResource();
407 * Perform cleanup for Amacl resources.
411 void DeInitAmaclResource()
413 OCDeleteResource(gAmaclHandle);
416 DeleteAmaclList(gAmacl);
421 OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsDeviceId)
423 OicSecAmacl_t *amacl = NULL;
425 VERIFY_NON_NULL(TAG, resource, ERROR);
426 VERIFY_NON_NULL(TAG, amsDeviceId, ERROR);
428 LL_FOREACH(gAmacl, amacl)
430 for(size_t i = 0; i < amacl->resourcesLen; i++)
432 if (strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])) == 0)
434 //Returning the ID of the first AMS service for the resource
435 memcpy(amsDeviceId, &amacl->amss[0], sizeof(*amsDeviceId));
442 return OC_STACK_ERROR;