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)
81 cJSON *jsonRoot = NULL;
86 jsonRoot = cJSON_CreateObject();
87 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
89 cJSON *jsonAmaclArray = NULL;
90 cJSON_AddItemToObject (jsonRoot, OIC_JSON_AMACL_NAME, jsonAmaclArray = cJSON_CreateArray());
91 VERIFY_NON_NULL(TAG, jsonAmaclArray, ERROR);
95 char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
97 B64Result b64Ret = B64_OK;
99 cJSON *jsonAmacl = cJSON_CreateObject();
101 // Resources -- Mandatory
102 cJSON *jsonRsrcArray = NULL;
103 cJSON_AddItemToObject(jsonAmacl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray =
104 cJSON_CreateArray());
105 VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
106 for (unsigned int i = 0; i < amacl->resourcesLen; i++)
108 cJSON_AddItemToArray(jsonRsrcArray, cJSON_CreateString(amacl->resources[i]));
112 cJSON *jsonAmsArray = NULL;
113 cJSON_AddItemToObject(jsonAmacl, OIC_JSON_AMSS_NAME, jsonAmsArray =
114 cJSON_CreateArray());
115 VERIFY_NON_NULL(TAG, jsonAmsArray, ERROR);
116 for (unsigned int i = 0; i < amacl->amssLen; i++)
120 b64Ret = b64Encode(amacl->amss[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
121 sizeof(base64Buff), &outLen);
122 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
124 cJSON_AddItemToArray(jsonAmsArray, cJSON_CreateString(base64Buff));
127 // Owners -- Mandatory
128 cJSON *jsonOwnrArray = NULL;
129 cJSON_AddItemToObject(jsonAmacl, OIC_JSON_OWNERS_NAME, jsonOwnrArray =
130 cJSON_CreateArray());
131 VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
132 for (unsigned int i = 0; i < amacl->ownersLen; i++)
136 b64Ret = b64Encode(amacl->owners[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
137 sizeof(base64Buff), &outLen);
138 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
140 cJSON_AddItemToArray(jsonOwnrArray, cJSON_CreateString(base64Buff));
143 // Attach current amacl node to Amacl Array
144 cJSON_AddItemToArray(jsonAmaclArray, jsonAmacl);
148 jsonStr = cJSON_PrintUnformatted(jsonRoot);
154 cJSON_Delete(jsonRoot);
163 * This internal method converts JSON AMACL into binary AMACL.
165 OicSecAmacl_t * JSONToAmaclBin(const char * jsonStr)
167 OCStackResult ret = OC_STACK_ERROR;
168 OicSecAmacl_t * headAmacl = NULL;
169 OicSecAmacl_t * prevAmacl = NULL;
170 cJSON *jsonRoot = NULL;
171 cJSON *jsonAmaclArray = NULL;
173 VERIFY_NON_NULL(TAG, jsonStr, ERROR);
175 jsonRoot = cJSON_Parse(jsonStr);
176 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
178 jsonAmaclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
179 VERIFY_NON_NULL(TAG, jsonAmaclArray, INFO);
181 if (cJSON_Array == jsonAmaclArray->type)
183 int numAmacl = cJSON_GetArraySize(jsonAmaclArray);
186 VERIFY_SUCCESS(TAG, numAmacl > 0, INFO);
189 cJSON *jsonAmacl = cJSON_GetArrayItem(jsonAmaclArray, idx);
190 VERIFY_NON_NULL(TAG, jsonAmacl, ERROR);
192 OicSecAmacl_t *amacl = (OicSecAmacl_t*)OICCalloc(1, sizeof(OicSecAmacl_t));
193 VERIFY_NON_NULL(TAG, amacl, ERROR);
195 headAmacl = (headAmacl) ? headAmacl : amacl;
198 prevAmacl->next = amacl;
201 size_t jsonObjLen = 0;
202 cJSON *jsonObj = NULL;
204 // Resources -- Mandatory
205 jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_RESOURCES_NAME);
206 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
207 VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
209 amacl->resourcesLen = cJSON_GetArraySize(jsonObj);
210 VERIFY_SUCCESS(TAG, amacl->resourcesLen > 0, ERROR);
211 amacl->resources = (char**)OICCalloc(amacl->resourcesLen, sizeof(char*));
212 VERIFY_NON_NULL(TAG, (amacl->resources), ERROR);
217 cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
218 VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
220 jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
221 amacl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
222 VERIFY_NON_NULL(TAG, (amacl->resources[idxx]), ERROR);
223 OICStrcpy(amacl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);
224 } while ( ++idxx < amacl->resourcesLen);
227 VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_AMSS_NAME,
228 &(amacl->amssLen), &(amacl->amss)), ERROR);
230 // Owners -- Mandatory
231 VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_OWNERS_NAME,
232 &(amacl->ownersLen), &(amacl->owners)), ERROR);
235 } while( ++idx < numAmacl);
241 cJSON_Delete(jsonRoot);
242 if (OC_STACK_OK != ret)
244 DeleteAmaclList(headAmacl);
250 static OCEntityHandlerResult HandleAmaclGetRequest (const OCEntityHandlerRequest * ehRequest)
252 // Convert Amacl data into JSON for transmission
253 char* jsonStr = BinToAmaclJSON(gAmacl);
255 OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
257 // Send response payload to request originator
258 SendSRMResponse(ehRequest, ehRet, jsonStr);
262 OC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
266 static OCEntityHandlerResult HandleAmaclPostRequest (const OCEntityHandlerRequest * ehRequest)
268 OCEntityHandlerResult ehRet = OC_EH_ERROR;
270 // Convert JSON Amacl data into binary. This will also validate the Amacl data received.
271 OicSecAmacl_t* newAmacl = JSONToAmaclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
275 // Append the new Amacl to existing Amacl
276 LL_APPEND(gAmacl, newAmacl);
278 // Convert Amacl data into JSON for update to persistent storage
279 char *jsonStr = BinToAmaclJSON(gAmacl);
282 cJSON *jsonAmacl = cJSON_Parse(jsonStr);
286 (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_AMACL_NAME, jsonAmacl)))
288 ehRet = OC_EH_RESOURCE_CREATED;
290 cJSON_Delete(jsonAmacl);
294 // Send payload to request originator
295 SendSRMResponse(ehRequest, ehRet, NULL);
297 OC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
302 * This internal method is the entity handler for Amacl resources and
303 * will handle REST request (GET/PUT/POST/DEL) for them.
305 OCEntityHandlerResult AmaclEntityHandler (OCEntityHandlerFlag flag,
306 OCEntityHandlerRequest * ehRequest,
307 void* callbackParameter)
309 (void) callbackParameter;
310 OCEntityHandlerResult ehRet = OC_EH_ERROR;
317 if (flag & OC_REQUEST_FLAG)
319 OC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
320 switch (ehRequest->method)
323 ehRet = HandleAmaclGetRequest(ehRequest);
327 ehRet = HandleAmaclPostRequest(ehRequest);
332 SendSRMResponse(ehRequest, ehRet, NULL);
340 * This internal method is used to create '/oic/sec/amacl' resource.
342 OCStackResult CreateAmaclResource()
346 ret = OCCreateResource(&gAmaclHandle,
347 OIC_RSRC_TYPE_SEC_AMACL,
354 if (OC_STACK_OK != ret)
356 OC_LOG (FATAL, TAG, "Unable to instantiate Amacl resource");
357 DeInitAmaclResource();
363 * Initialize Amacl resource by loading data from persistent storage.
365 * @retval OC_STACK_OK for Success, otherwise some error value
367 OCStackResult InitAmaclResource()
369 OCStackResult ret = OC_STACK_ERROR;
371 // Read Amacl resource from PS
372 char* jsonSVRDatabase = GetSVRDatabase();
376 // Convert JSON Amacl into binary format
377 gAmacl = JSONToAmaclBin(jsonSVRDatabase);
378 OICFree(jsonSVRDatabase);
381 // Instantiate 'oic/sec/amacl' resource
382 ret = CreateAmaclResource();
384 if (OC_STACK_OK != ret)
386 DeInitAmaclResource();
392 * Perform cleanup for Amacl resources.
396 void DeInitAmaclResource()
398 OCDeleteResource(gAmaclHandle);
401 DeleteAmaclList(gAmacl);
406 OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsDeviceId)
408 OicSecAmacl_t *amacl = NULL;
410 VERIFY_NON_NULL(TAG, resource, ERROR);
411 VERIFY_NON_NULL(TAG, amsDeviceId, ERROR);
413 LL_FOREACH(gAmacl, amacl)
415 for(size_t i = 0; i < amacl->resourcesLen; i++)
417 if (strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])) == 0)
419 //Returning the ID of the first AMS service for the resource
420 memcpy(amsDeviceId, &amacl->amss[0], sizeof(*amsDeviceId));
427 return OC_STACK_ERROR;