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)
51 LL_DELETE(amacl, amaclTmp1);
54 for (size_t i = 0; i < amaclTmp1->resourcesLen; i++)
56 OICFree(amaclTmp1->resources[i]);
58 OICFree(amaclTmp1->resources);
61 OICFree(amaclTmp1->amss);
64 OICFree(amaclTmp1->owners);
66 // Clean Amacl node itself
73 * This internal method converts AMACL data into JSON format.
75 * Note: Caller needs to invoke 'free' when finished using the return string.
77 char * BinToAmaclJSON(const OicSecAmacl_t * amacl)
79 cJSON *jsonRoot = NULL;
84 jsonRoot = cJSON_CreateObject();
85 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
87 cJSON *jsonAmaclArray = NULL;
88 cJSON_AddItemToObject (jsonRoot, OIC_JSON_AMACL_NAME, jsonAmaclArray = cJSON_CreateArray());
89 VERIFY_NON_NULL(TAG, jsonAmaclArray, ERROR);
93 char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
95 B64Result b64Ret = B64_OK;
97 cJSON *jsonAmacl = cJSON_CreateObject();
99 // Resources -- Mandatory
100 cJSON *jsonRsrcArray = NULL;
101 cJSON_AddItemToObject(jsonAmacl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray =
102 cJSON_CreateArray());
103 VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
104 for (unsigned int i = 0; i < amacl->resourcesLen; i++)
106 cJSON_AddItemToArray(jsonRsrcArray, cJSON_CreateString(amacl->resources[i]));
110 cJSON *jsonAmsArray = NULL;
111 cJSON_AddItemToObject(jsonAmacl, OIC_JSON_AMSS_NAME, jsonAmsArray =
112 cJSON_CreateArray());
113 VERIFY_NON_NULL(TAG, jsonAmsArray, ERROR);
114 for (unsigned int i = 0; i < amacl->amssLen; i++)
118 b64Ret = b64Encode(amacl->amss[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
119 sizeof(base64Buff), &outLen);
120 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
122 cJSON_AddItemToArray(jsonAmsArray, cJSON_CreateString(base64Buff));
125 // Owners -- Mandatory
126 cJSON *jsonOwnrArray = NULL;
127 cJSON_AddItemToObject(jsonAmacl, OIC_JSON_OWNERS_NAME, jsonOwnrArray =
128 cJSON_CreateArray());
129 VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
130 for (unsigned int i = 0; i < amacl->ownersLen; i++)
134 b64Ret = b64Encode(amacl->owners[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
135 sizeof(base64Buff), &outLen);
136 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
138 cJSON_AddItemToArray(jsonOwnrArray, cJSON_CreateString(base64Buff));
141 // Attach current amacl node to Amacl Array
142 cJSON_AddItemToArray(jsonAmaclArray, jsonAmacl);
146 jsonStr = cJSON_PrintUnformatted(jsonRoot);
152 cJSON_Delete(jsonRoot);
161 * This internal method converts JSON AMACL into binary AMACL.
163 OicSecAmacl_t * JSONToAmaclBin(const char * jsonStr)
165 OCStackResult ret = OC_STACK_ERROR;
166 OicSecAmacl_t * headAmacl = NULL;
167 OicSecAmacl_t * prevAmacl = NULL;
168 cJSON *jsonRoot = NULL;
169 cJSON *jsonAmaclArray = NULL;
171 VERIFY_NON_NULL(TAG, jsonStr, ERROR);
173 jsonRoot = cJSON_Parse(jsonStr);
174 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
176 jsonAmaclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
177 VERIFY_NON_NULL(TAG, jsonAmaclArray, INFO);
179 if (cJSON_Array == jsonAmaclArray->type)
181 int numAmacl = cJSON_GetArraySize(jsonAmaclArray);
184 VERIFY_SUCCESS(TAG, numAmacl > 0, INFO);
187 cJSON *jsonAmacl = cJSON_GetArrayItem(jsonAmaclArray, idx);
188 VERIFY_NON_NULL(TAG, jsonAmacl, ERROR);
190 OicSecAmacl_t *amacl = (OicSecAmacl_t*)OICCalloc(1, sizeof(OicSecAmacl_t));
191 VERIFY_NON_NULL(TAG, amacl, ERROR);
193 headAmacl = (headAmacl) ? headAmacl : amacl;
196 prevAmacl->next = amacl;
199 size_t jsonObjLen = 0;
200 cJSON *jsonObj = NULL;
202 // Resources -- Mandatory
203 jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_RESOURCES_NAME);
204 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
205 VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
207 amacl->resourcesLen = (size_t)cJSON_GetArraySize(jsonObj);
208 VERIFY_SUCCESS(TAG, amacl->resourcesLen > 0, ERROR);
209 amacl->resources = (char**)OICCalloc(amacl->resourcesLen, sizeof(char*));
210 VERIFY_NON_NULL(TAG, (amacl->resources), ERROR);
215 cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
216 VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
218 jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
219 amacl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
220 VERIFY_NON_NULL(TAG, (amacl->resources[idxx]), ERROR);
221 OICStrcpy(amacl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);
222 } while ( ++idxx < amacl->resourcesLen);
225 VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_AMSS_NAME,
226 &(amacl->amssLen), &(amacl->amss)), ERROR);
228 // Owners -- Mandatory
229 VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_OWNERS_NAME,
230 &(amacl->ownersLen), &(amacl->owners)), ERROR);
233 } while( ++idx < numAmacl);
239 cJSON_Delete(jsonRoot);
240 if (OC_STACK_OK != ret)
242 DeleteAmaclList(headAmacl);
248 static OCEntityHandlerResult HandleAmaclGetRequest (const OCEntityHandlerRequest * ehRequest)
250 // Convert Amacl data into JSON for transmission
251 char* jsonStr = BinToAmaclJSON(gAmacl);
253 OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
255 // Send response payload to request originator
256 SendSRMResponse(ehRequest, ehRet, jsonStr);
260 OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
264 static OCEntityHandlerResult HandleAmaclPostRequest (const OCEntityHandlerRequest * ehRequest)
266 OCEntityHandlerResult ehRet = OC_EH_ERROR;
268 // Convert JSON Amacl data into binary. This will also validate the Amacl data received.
269 OicSecAmacl_t* newAmacl = JSONToAmaclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
273 // Append the new Amacl to existing Amacl
274 LL_APPEND(gAmacl, newAmacl);
276 // Convert Amacl data into JSON for update to persistent storage
277 char *jsonStr = BinToAmaclJSON(gAmacl);
280 cJSON *jsonAmacl = cJSON_Parse(jsonStr);
284 (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_AMACL_NAME, jsonAmacl)))
286 ehRet = OC_EH_RESOURCE_CREATED;
288 cJSON_Delete(jsonAmacl);
292 // Send payload to request originator
293 SendSRMResponse(ehRequest, ehRet, NULL);
295 OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
300 * This internal method is the entity handler for Amacl resources and
301 * will handle REST request (GET/PUT/POST/DEL) for them.
303 OCEntityHandlerResult AmaclEntityHandler (OCEntityHandlerFlag flag,
304 OCEntityHandlerRequest * ehRequest,
305 void* callbackParameter)
307 (void) callbackParameter;
308 OCEntityHandlerResult ehRet = OC_EH_ERROR;
315 if (flag & OC_REQUEST_FLAG)
317 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
318 switch (ehRequest->method)
321 ehRet = HandleAmaclGetRequest(ehRequest);
325 ehRet = HandleAmaclPostRequest(ehRequest);
330 SendSRMResponse(ehRequest, ehRet, NULL);
338 * This internal method is used to create '/oic/sec/amacl' resource.
340 OCStackResult CreateAmaclResource()
344 ret = OCCreateResource(&gAmaclHandle,
345 OIC_RSRC_TYPE_SEC_AMACL,
352 if (OC_STACK_OK != ret)
354 OIC_LOG (FATAL, TAG, "Unable to instantiate Amacl resource");
355 DeInitAmaclResource();
361 * Initialize Amacl resource by loading data from persistent storage.
363 * @retval OC_STACK_OK for Success, otherwise some error value
365 OCStackResult InitAmaclResource()
367 OCStackResult ret = OC_STACK_ERROR;
369 // Read Amacl resource from PS
370 char* jsonSVRDatabase = GetSVRDatabase();
374 // Convert JSON Amacl into binary format
375 gAmacl = JSONToAmaclBin(jsonSVRDatabase);
376 OICFree(jsonSVRDatabase);
379 // Instantiate 'oic/sec/amacl' resource
380 ret = CreateAmaclResource();
382 if (OC_STACK_OK != ret)
384 DeInitAmaclResource();
390 * Perform cleanup for Amacl resources.
394 void DeInitAmaclResource()
396 OCDeleteResource(gAmaclHandle);
399 DeleteAmaclList(gAmacl);
404 OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsDeviceId)
406 OicSecAmacl_t *amacl = NULL;
408 VERIFY_NON_NULL(TAG, resource, ERROR);
409 VERIFY_NON_NULL(TAG, amsDeviceId, ERROR);
411 LL_FOREACH(gAmacl, amacl)
413 for(size_t i = 0; i < amacl->resourcesLen; i++)
415 if (strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])) == 0)
417 //Returning the ID of the first AMS service for the resource
418 memcpy(amsDeviceId, &amacl->amss[0], sizeof(*amsDeviceId));
425 return OC_STACK_ERROR;