Merge tizen_5.0 codes into tizen_4.0
[platform/upstream/iotivity.git] / resource / csdk / security / src / secureresourcemanager.c
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 <string.h>
22 #include "ocstack.h"
23 #include "logger.h"
24 #include "cainterface.h"
25 #include "resourcemanager.h"
26 #include "credresource.h"
27 #include "doxmresource.h"
28 #include "pstatresource.h"
29 #include "policyengine.h"
30 #include "srmutility.h"
31 #include "psinterface.h"
32 #include "amsmgr.h"
33 #include "oic_string.h"
34 #include "oic_malloc.h"
35 #include "securevirtualresourcetypes.h"
36 #include "secureresourcemanager.h"
37 #include "srmresourcestrings.h"
38 #include "ocresourcehandler.h"
39
40 #if defined( __WITH_TLS__) || defined(__WITH_DTLS__)
41 #include "pkix_interface.h"
42 #endif //__WITH_TLS__ or __WITH_DTLS__
43 #define TAG  "OIC_SRM"
44
45 //Request Callback handler
46 static CARequestCallback gRequestHandler = NULL;
47 //Response Callback handler
48 static CAResponseCallback gResponseHandler = NULL;
49 //Error Callback handler
50 static CAErrorCallback gErrorHandler = NULL;
51 //Persistent Storage callback handler for open/read/write/close/unlink
52 static OCPersistentStorage *gPersistentStorageHandler =  NULL;
53 //Provisioning response callback
54 static SPResponseCallback gSPResponseHandler = NULL;
55
56 /**
57  * A single global Policy Engine context will suffice as long
58  * as SRM is single-threaded.
59  */
60 PEContext_t g_policyEngineContext;
61
62 /**
63  * Function to register provisioning API's response callback.
64  * @param respHandler response handler callback.
65  */
66 void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler)
67 {
68     gSPResponseHandler = respHandler;
69 }
70
71 void SetResourceRequestType(PEContext_t *context, const char *resourceUri)
72 {
73     context->resourceType = GetSvrTypeFromUri(resourceUri);
74 }
75
76 static void SRMSendUnAuthorizedAccessresponse(PEContext_t *context)
77 {
78     CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
79
80     if (NULL == context ||
81        NULL == context->amsMgrContext->requestInfo)
82     {
83         OIC_LOG_V(ERROR, TAG, "%s : NULL Parameter(s)",__func__);
84         return;
85     }
86
87     memcpy(&responseInfo.info, &(context->amsMgrContext->requestInfo->info),
88             sizeof(responseInfo.info));
89     responseInfo.info.payload = NULL;
90     responseInfo.result = CA_UNAUTHORIZED_REQ;
91     responseInfo.info.dataType = CA_RESPONSE_DATA;
92
93     if (CA_STATUS_OK == CASendResponse(context->amsMgrContext->endpoint, &responseInfo))
94     {
95         OIC_LOG(DEBUG, TAG, "Succeed in sending response to a unauthorized request!");
96     }
97     else
98     {
99         OIC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
100     }
101 }
102
103 void SRMSendResponse(SRMAccessResponse_t responseVal)
104 {
105     OIC_LOG(DEBUG, TAG, "Sending response to remote device");
106
107     if (IsAccessGranted(responseVal) && gRequestHandler)
108     {
109         OIC_LOG_V(INFO, TAG, "%s : Access granted. Passing Request to RI layer", __func__);
110         if (!g_policyEngineContext.amsMgrContext->endpoint ||
111             !g_policyEngineContext.amsMgrContext->requestInfo)
112         {
113             OIC_LOG_V(ERROR, TAG, "%s : Invalid arguments", __func__);
114             SRMSendUnAuthorizedAccessresponse(&g_policyEngineContext);
115             goto exit;
116         }
117         gRequestHandler(g_policyEngineContext.amsMgrContext->endpoint,
118                 g_policyEngineContext.amsMgrContext->requestInfo);
119     }
120     else
121     {
122         OIC_LOG_V(INFO, TAG, "%s : ACCESS_DENIED.", __func__);
123         SRMSendUnAuthorizedAccessresponse(&g_policyEngineContext);
124     }
125
126 exit:
127     //Resetting PE state to AWAITING_REQUEST
128     SetPolicyEngineState(&g_policyEngineContext, AWAITING_REQUEST);
129 }
130
131 /**
132  * Handle the request from the SRM.
133  *
134  * @param endPoint object from which the response is received.
135  * @param requestInfo contains information for the request.
136  */
137 void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requestInfo)
138 {
139     OIC_LOG_V(DEBUG, TAG, "%s:Received request from remote device", __func__);
140
141     bool isRequestOverSecureChannel = false;
142     if (!endPoint || !requestInfo)
143     {
144         OIC_LOG(ERROR, TAG, "Invalid arguments");
145         return;
146     }
147
148     // Copy the subjectID
149     OicUuid_t subjectId = {.id = {0}};
150     memcpy(subjectId.id, requestInfo->info.identity.id, sizeof(subjectId.id));
151     if (endPoint->flags & CA_SECURE)
152     {
153         OIC_LOG(INFO, TAG, "request over secure channel");
154         isRequestOverSecureChannel = true;
155     }
156
157     //Check the URI has the query and skip it before checking the permission
158     if (NULL == requestInfo->info.resourceUri)
159     {
160         OIC_LOG(ERROR, TAG, "Invalid resourceUri");
161         return;
162     }
163
164     char *uri = strstr(requestInfo->info.resourceUri, "?");
165     int position = 0;
166     if (uri)
167     {
168         //Skip query and pass the resource uri
169         position = uri - requestInfo->info.resourceUri;
170     }
171     else
172     {
173         position = strlen(requestInfo->info.resourceUri);
174     }
175     if (MAX_URI_LENGTH < position  || 0 > position)
176     {
177         OIC_LOG(ERROR, TAG, "Incorrect URI length");
178         return;
179     }
180     SRMAccessResponse_t response = ACCESS_DENIED;
181     char newUri[MAX_URI_LENGTH + 1];
182     OICStrcpyPartial(newUri, MAX_URI_LENGTH + 1, requestInfo->info.resourceUri, position);
183
184     SetResourceRequestType(&g_policyEngineContext, newUri);
185
186      // Form a 'Error', 'slow response' or 'access deny' response and send to peer
187     CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
188     memcpy(&responseInfo.info, &(requestInfo->info), sizeof(responseInfo.info));
189     responseInfo.info.payload = NULL;
190     responseInfo.info.dataType = CA_RESPONSE_DATA;
191
192     OCResource *resPtr = FindResourceByUri(newUri);
193     if (NULL != resPtr)
194     {
195         // All vertical secure resources and SVR resources other than DOXM & PSTAT should reject request
196         // over coap.
197         if ((((resPtr->resourceProperties) & OC_SECURE)
198                             && (g_policyEngineContext.resourceType == NOT_A_SVR_RESOURCE))
199                             || ((g_policyEngineContext.resourceType < OIC_SEC_SVR_TYPE_COUNT)
200                             &&  (g_policyEngineContext.resourceType != OIC_R_DOXM_TYPE)
201                             &&  (g_policyEngineContext.resourceType != OIC_R_PSTAT_TYPE)))
202         {
203            // if resource is secure and request is over insecure channel
204             if (!isRequestOverSecureChannel)
205             {
206                 // Reject all the requests over coap for secure resource.
207                 responseInfo.result = CA_FORBIDDEN_REQ;
208                 if (CA_STATUS_OK != CASendResponse(endPoint, &responseInfo))
209                 {
210                     OIC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
211                 }
212                 return;
213             }
214         }
215     }
216 #ifdef MULTIPLE_OWNER
217     /*
218      * In case of ACL and CRED, The payload required to verify the payload.
219      * Payload information will be used for subowner's permission verification.
220      */
221     g_policyEngineContext.payload = (uint8_t*)requestInfo->info.payload;
222     g_policyEngineContext.payloadSize = requestInfo->info.payloadSize;
223 #endif //MULTIPLE_OWNER
224
225     //New request are only processed if the policy engine state is AWAITING_REQUEST.
226     if (AWAITING_REQUEST == g_policyEngineContext.state)
227     {
228         OIC_LOG_V(DEBUG, TAG, "Processing request with uri, %s for method, %d",
229                 requestInfo->info.resourceUri, requestInfo->method);
230         response = CheckPermission(&g_policyEngineContext, &subjectId, newUri,
231                 GetPermissionFromCAMethod_t(requestInfo->method));
232     }
233     else
234     {
235         OIC_LOG_V(INFO, TAG, "PE state %d. Ignoring request with uri, %s for method, %d",
236                 g_policyEngineContext.state, requestInfo->info.resourceUri, requestInfo->method);
237     }
238
239     if (IsAccessGranted(response) && gRequestHandler)
240     {
241         gRequestHandler(endPoint, requestInfo);
242         return;
243     }
244
245     VERIFY_NON_NULL(TAG, gRequestHandler, ERROR);
246
247     if (ACCESS_WAITING_FOR_AMS == response)
248     {
249         OIC_LOG(INFO, TAG, "Sending slow response");
250
251         UpdateAmsMgrContext(&g_policyEngineContext, endPoint, requestInfo);
252         responseInfo.result = CA_EMPTY;
253         responseInfo.info.type = CA_MSG_ACKNOWLEDGE;
254     }
255     else
256     {
257         /*
258          * TODO Enhance this logic more to decide between
259          * CA_UNAUTHORIZED_REQ or CA_FORBIDDEN_REQ depending
260          * upon SRMAccessResponseReasonCode_t
261          */
262         OIC_LOG(INFO, TAG, "Sending for regular response");
263         responseInfo.result = CA_UNAUTHORIZED_REQ;
264     }
265
266     if (CA_STATUS_OK != CASendResponse(endPoint, &responseInfo))
267     {
268         OIC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
269     }
270     return;
271 exit:
272     responseInfo.result = CA_INTERNAL_SERVER_ERROR;
273     if (CA_STATUS_OK != CASendResponse(endPoint, &responseInfo))
274     {
275         OIC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
276     }
277 }
278
279 /**
280  * Handle the response from the SRM.
281  *
282  * @param endPoint points to the remote endpoint.
283  * @param responseInfo contains response information from the endpoint.
284  */
285 void SRMResponseHandler(const CAEndpoint_t *endPoint, const CAResponseInfo_t *responseInfo)
286 {
287     OIC_LOG_V(DEBUG, TAG, "%s:Received response from remote device", __func__);
288
289     // isProvResponse flag is to check whether response is catered by provisioning APIs or not.
290     // When token sent by CA response matches with token generated by provisioning request,
291     // gSPResponseHandler returns true and response is not sent to RI layer. In case
292     // gSPResponseHandler is null and isProvResponse is false response then the response is for
293     // RI layer.
294     bool isProvResponse = false;
295
296     if (gSPResponseHandler)
297     {
298         isProvResponse = gSPResponseHandler(endPoint, responseInfo);
299     }
300     if (!isProvResponse && gResponseHandler)
301     {
302         gResponseHandler(endPoint, responseInfo);
303     }
304 }
305
306 /**
307  * Handle the error from the SRM.
308  *
309  * @param endPoint is the remote endpoint.
310  * @param errorInfo contains error information from the endpoint.
311  */
312 void SRMErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
313 {
314     OIC_LOG_V(INFO, TAG, "%s:Received error from remote device with result, %d for request uri, %s",
315             __func__, errorInfo->result, errorInfo->info.resourceUri);
316     if (gErrorHandler)
317     {
318         gErrorHandler(endPoint, errorInfo);
319     }
320 }
321
322 OCStackResult SRMRegisterHandler(CARequestCallback reqHandler,
323                                  CAResponseCallback respHandler,
324                                  CAErrorCallback errHandler)
325 {
326     OIC_LOG(DEBUG, TAG, "SRMRegisterHandler !!");
327     if( !reqHandler || !respHandler || !errHandler)
328     {
329         OIC_LOG(ERROR, TAG, "Callback handlers are invalid");
330         return OC_STACK_INVALID_PARAM;
331     }
332     gRequestHandler = reqHandler;
333     gResponseHandler = respHandler;
334     gErrorHandler = errHandler;
335
336
337 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
338     CARegisterHandler(SRMRequestHandler, SRMResponseHandler, SRMErrorHandler);
339 #else
340     CARegisterHandler(reqHandler, respHandler, errHandler);
341 #endif /* __WITH_DTLS__ */
342     return OC_STACK_OK;
343 }
344
345 OCStackResult SRMRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler)
346 {
347     OIC_LOG(DEBUG, TAG, "SRMRegisterPersistentStorageHandler !!");
348     if(!persistentStorageHandler)
349     {
350         OIC_LOG(ERROR, TAG, "The persistent storage handler is invalid");
351         return OC_STACK_INVALID_PARAM;
352     }
353
354     gPersistentStorageHandler = persistentStorageHandler;
355
356     // Check validity of Persistent Storage
357     OCStackResult res = OC_STACK_SVR_DB_NOT_EXIST;
358     res = CheckPersistentStorage(persistentStorageHandler);
359     if (OC_STACK_OK != res)
360     {
361         OIC_LOG(ERROR, TAG, "Persistent storage is not normal");
362         gPersistentStorageHandler = NULL;
363     }
364     return res;
365 }
366
367 OCPersistentStorage* SRMGetPersistentStorageHandler()
368 {
369     return gPersistentStorageHandler;
370 }
371
372 OCStackResult SRMInitSecureResources()
373 {
374     // TODO: temporarily returning OC_STACK_OK every time until default
375     // behavior (for when SVR DB is missing) is settled.
376     InitSecureResources();
377     OCStackResult ret = OC_STACK_OK;
378 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
379     if (CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
380     {
381         OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
382         ret = OC_STACK_ERROR;
383     }
384     CAregisterPkixInfoHandler(GetPkixInfo);
385     CAregisterGetCredentialTypesHandler(InitCipherSuiteList);
386 #endif // __WITH_DTLS__ or __WITH_TLS__
387     return ret;
388 }
389
390 void SRMDeInitSecureResources()
391 {
392     DestroySecureResources();
393 }
394
395 OCStackResult SRMInitPolicyEngine()
396 {
397     return InitPolicyEngine(&g_policyEngineContext);
398 }
399
400 void SRMDeInitPolicyEngine()
401 {
402     DeInitPolicyEngine(&g_policyEngineContext);
403 }
404
405 bool SRMIsSecurityResourceURI(const char* uri)
406 {
407     if (!uri)
408     {
409         return false;
410     }
411
412     const char *rsrcs[] = {
413         OIC_RSRC_AMACL_URI,
414         OIC_RSRC_CRL_URI,
415         OIC_RSRC_CRED_URI,
416         OIC_RSRC_ACL_URI,
417         OIC_RSRC_DOXM_URI,
418         OIC_RSRC_PSTAT_URI,
419         OIC_RSRC_PCONF_URI,
420         OIC_RSRC_DPAIRING_URI,
421         OIC_RSRC_VER_URI,
422         OC_RSRVD_PROV_CRL_URL
423     };
424
425     // Remove query from Uri for resource string comparison
426     size_t uriLen = strlen(uri);
427     char *query = strchr (uri, '?');
428     if (query)
429     {
430         uriLen = query - uri;
431     }
432
433     for (size_t i = 0; i < sizeof(rsrcs)/sizeof(rsrcs[0]); i++)
434     {
435         size_t svrLen = strlen(rsrcs[i]);
436
437         if ((uriLen == svrLen) &&
438             (strncmp(uri, rsrcs[i], svrLen) == 0))
439         {
440             return true;
441         }
442     }
443
444     return false;
445 }
446
447 /**
448  * Check whether persistent storage is valid
449  * @return OC_STACK_OK if valid, other errors otherwise;
450  */
451 OCStackResult CheckPersistentStorage(OCPersistentStorage* ps)
452 {
453     OIC_LOG_V(INFO, TAG, "In %s", __func__);
454
455     FILE *fp = NULL;
456     OCStackResult ret = OC_STACK_SVR_DB_NOT_EXIST;
457     OicSecDoxm_t* doxm = NULL;
458     OicSecPstat_t* pstat = NULL;
459     uint8_t *data = NULL;
460     size_t size = 0;
461
462     if (NULL == ps)
463     {
464         OIC_LOG(ERROR, TAG, "NULL PersistentStorage Parameter");
465         ret = OC_STACK_INVALID_PARAM;
466         goto exit;
467     }
468
469     // Check whether the DB file exists
470     fp = ps->open(SVR_DB_DAT_FILE_NAME, "r+b");
471     if (NULL == fp)
472     {
473         OIC_LOG(ERROR, TAG, "DB file cannot be opened");
474         ret = OC_STACK_SVR_DB_NOT_EXIST;
475         SetPSStatus(PS_OPEN_FAIL);
476         goto exit;
477     }
478     ps->close(fp);
479
480     OIC_LOG(INFO, TAG, "Checking doxm resource...");
481     //Check DOXM resource
482     ret = GetSecureVirtualDatabaseFromPS2(ps, OIC_JSON_DOXM_NAME, &data, &size);
483     // If database read failed
484     if (OC_STACK_OK != ret)
485     {
486         OIC_LOG (ERROR, TAG, "Can not find the DOXM Resource in SVR DB.");
487         ret = OC_STACK_INCONSISTENT_DB;
488         SetPSStatus(PS_PARSE_FAIL);
489         goto exit;
490     }
491     if (data && 0 < size)
492     {
493         // Read DOXM resource from PS
494         ret = CBORPayloadToDoxm(data, size, &doxm);
495         if (OC_STACK_OK != ret)
496         {
497             OIC_LOG_V(ERROR, TAG, "Failed to Convert CBOR to Doxm bin : %d", ret);
498             ret = OC_STACK_INCONSISTENT_DB;
499             SetPSStatus(PS_PARSE_FAIL);
500             goto exit;
501         }
502     }
503     else
504     {
505         ret = OC_STACK_INCONSISTENT_DB;
506         SetPSStatus(PS_PARSE_FAIL);
507         goto exit;
508     }
509     if (data)
510     {
511         OICFree(data);
512         data = NULL;
513     }
514
515     OIC_LOG(INFO, TAG, "Checking pstat resource...");
516     //Check PSTAT resource
517     ret = GetSecureVirtualDatabaseFromPS2(ps, OIC_JSON_PSTAT_NAME, &data, &size);
518     // If database read failed
519     if (OC_STACK_OK != ret)
520     {
521         OIC_LOG (ERROR, TAG, "Can not find the PSTAT Resource in SVR DB.");
522         ret = OC_STACK_INCONSISTENT_DB;
523         SetPSStatus(PS_PARSE_FAIL);
524         goto exit;
525     }
526     if (data && 0 < size)
527     {
528         // Read ACL resource from PS
529         ret = CBORPayloadToPstat(data, size, &pstat);
530         if (OC_STACK_OK != ret)
531         {
532             OIC_LOG_V(ERROR, TAG, "Failed to Convert CBOR to PSTAT bin : %d", ret);
533             ret = OC_STACK_INCONSISTENT_DB;
534             SetPSStatus(PS_PARSE_FAIL);
535             goto exit;
536         }
537     }
538     else
539     {
540         ret = OC_STACK_INCONSISTENT_DB;
541         SetPSStatus(PS_PARSE_FAIL);
542         goto exit;
543     }
544     if (data)
545     {
546         OICFree(data);
547         data = NULL;
548     }
549
550     SetPSStatus(PS_NORMAL);
551
552     ret = OC_STACK_OK;
553     OIC_LOG(INFO, TAG, "All Secure Virtual Resources are fine.");
554
555 exit:
556     if (data)
557     {
558         OICFree(data);
559     }
560     if (doxm)
561     {
562         DeleteDoxmBinData(doxm);
563     }
564     if (pstat)
565     {
566         DeletePstatBinData(pstat);
567     }
568
569     OIC_LOG_V(INFO, TAG, "Out %s", __func__);
570
571     return ret;
572 }
573
574 /**
575  * Get the Secure Virtual Resource (SVR) type from the URI.
576  * @param   uri [IN] Pointer to URI in question.
577  * @return  The OicSecSvrType_t of the URI passed (note: if not a Secure Virtual
578             Resource, e.g. /a/light, will return "NOT_A_SVR_TYPE" enum value)
579  */
580 static const char URI_QUERY_CHAR = '?';
581 OicSecSvrType_t GetSvrTypeFromUri(const char* uri)
582 {
583     if (!uri)
584     {
585         return NOT_A_SVR_RESOURCE;
586     }
587
588     // Remove query from Uri for resource string comparison
589     size_t uriLen = strlen(uri);
590     char *query = strchr (uri, URI_QUERY_CHAR);
591     if (query)
592     {
593         uriLen = query - uri;
594     }
595
596     size_t svrLen = 0;
597
598     svrLen = strlen(OIC_RSRC_ACL_URI);
599     if(uriLen == svrLen)
600     {
601         if(0 == strncmp(uri, OIC_RSRC_ACL_URI, svrLen))
602         {
603             return OIC_R_ACL_TYPE;
604         }
605     }
606
607     svrLen = strlen(OIC_RSRC_AMACL_URI);
608     if(uriLen == svrLen)
609     {
610         if(0 == strncmp(uri, OIC_RSRC_AMACL_URI, svrLen))
611         {
612             return OIC_R_AMACL_TYPE;
613         }
614     }
615
616     svrLen = strlen(OIC_RSRC_CRED_URI);
617     if(uriLen == svrLen)
618     {
619         if(0 == strncmp(uri, OIC_RSRC_CRED_URI, svrLen))
620         {
621             return OIC_R_CRED_TYPE;
622         }
623     }
624
625     svrLen = strlen(OIC_RSRC_CRL_URI);
626     if(uriLen == svrLen)
627     {
628         if(0 == strncmp(uri, OIC_RSRC_CRL_URI, svrLen))
629         {
630             return OIC_R_CRL_TYPE;
631         }
632     }
633
634     svrLen = strlen(OIC_RSRC_DOXM_URI);
635     if(uriLen == svrLen)
636     {
637         if(0 == strncmp(uri, OIC_RSRC_DOXM_URI, svrLen))
638         {
639             return OIC_R_DOXM_TYPE;
640         }
641     }
642
643     svrLen = strlen(OIC_RSRC_DPAIRING_URI);
644     if(uriLen == svrLen)
645     {
646         if(0 == strncmp(uri, OIC_RSRC_DPAIRING_URI, svrLen))
647         {
648             return OIC_R_DPAIRING_TYPE;
649         }
650     }
651
652     svrLen = strlen(OIC_RSRC_PCONF_URI);
653     if(uriLen == svrLen)
654     {
655         if(0 == strncmp(uri, OIC_RSRC_PCONF_URI, svrLen))
656         {
657             return OIC_R_PCONF_TYPE;
658         }
659     }
660
661     svrLen = strlen(OIC_RSRC_PSTAT_URI);
662     if(uriLen == svrLen)
663     {
664         if(0 == strncmp(uri, OIC_RSRC_PSTAT_URI, svrLen))
665         {
666             return OIC_R_PSTAT_TYPE;
667         }
668     }
669
670     svrLen = strlen(OIC_RSRC_SACL_URI);
671     if(uriLen == svrLen)
672     {
673         if(0 == strncmp(uri, OIC_RSRC_SACL_URI, svrLen))
674         {
675             return OIC_R_SACL_TYPE;
676         }
677     }
678
679     return NOT_A_SVR_RESOURCE;
680 }