Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / provisioningclient.c
1 /******************************************************************
2 *
3 * Copyright 2015 Samsung Electronics 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 <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <getopt.h>
25 #include "logger.h"
26 #include "oic_malloc.h"
27 #include "utlist.h"
28 #include "securevirtualresourcetypes.h"
29 #include "provisioningmanager.h"
30
31 #define MAX_URI_LENGTH (64)
32 #define MAX_PERMISSION_LENGTH (5)
33 #define MAX_INPUT_ID_LENGTH (16)
34 #define PREDEFINED_TIMEOUT (10)
35 #define CREATE (1)
36 #define READ (2)
37 #define UPDATE (4)
38 #define DELETE (8)
39 #define NOTIFY (16)
40 #define DASH '-'
41 #define TAG  "provisioningclient"
42
43 static OicSecAcl_t        *gAcl = NULL;
44 static char PROV_TOOL_DB_FILE[] = "oic_svr_db_prov_tool.json";
45
46 /**
47  * Perform cleanup for ACL list
48  *
49  * @param[in]    ACL list
50  */
51 static void DeleteACLList(OicSecAcl_t *acl)
52 {
53     if (acl)
54     {
55         OicSecAcl_t *aclTmp1 = NULL;
56         OicSecAcl_t *aclTmp2 = NULL;
57         LL_FOREACH_SAFE(acl, aclTmp1, aclTmp2)
58         {
59             LL_DELETE(acl, aclTmp1);
60
61             /* Clean Resources */
62             for (int i = 0; i < aclTmp1->resourcesLen; i++)
63             {
64                 OICFree(aclTmp1->resources[i]);
65             }
66             OICFree(aclTmp1->resources);
67
68             /* Clean Owners */
69             OICFree(aclTmp1->owners);
70
71             /* Clean ACL node itself */
72             OICFree(aclTmp1);
73         }
74         acl = NULL;
75     }
76 }
77
78 /**
79  * Calculate ACL permission from string to bit
80  *
81  * @param[in] temp_psm    Input data of ACL permission string
82  * @param[in,out] pms    The pointer of ACL permission value
83  * @return  0 on success otherwise a positive error value
84  * @retval  SP_RESULT_SUCCESS    Successful
85  * @retval  SP_RESULT_INVALID_PARAM    Invaild input arguments
86  */
87 static SPResult CalculateAclPermission(const char *temp_pms, uint16_t *pms)
88 {
89     int i = 0;
90
91     if (NULL == temp_pms || NULL == pms)
92     {
93         return SP_RESULT_INVALID_PARAM;
94     }
95     *pms = 0;
96     while (temp_pms[i] != '\0')
97     {
98         switch (temp_pms[i])
99         {
100             case 'C':
101                 {
102                     *pms += CREATE;
103                     i++;
104                     break;
105                 }
106             case 'R':
107                 {
108                     *pms += READ;
109                     i++;
110                     break;
111                 }
112             case 'U':
113                 {
114                     *pms += UPDATE;
115                     i++;
116                     break;
117                 }
118             case 'D':
119                 {
120                     *pms += DELETE;
121                     i++;
122                     break;
123                 }
124             case 'N':
125                 {
126                     *pms += NOTIFY;
127                     i++;
128                     break;
129                 }
130             case '_':
131                 {
132                     i++;
133                     break;
134                 }
135             default:
136                 {
137                     return SP_RESULT_INVALID_PARAM;
138                 }
139         }
140     }
141     return SP_RESULT_SUCCESS;
142 }
143
144 /**
145  * Get the ACL property from user
146  *
147  * @param[in]    ACL Datastructure to save user inputs
148  * @return  0 on success otherwise a positive error value
149  * @retval  SP_RESULT_SUCCESS    Successful
150  * @retval  SP_RESULT_MEM_ALLOCATION_FAIL    Memmory allocation failure
151  */
152 static SPResult InputACL(OicSecAcl_t *acl)
153 {
154     int unused __attribute__((unused));
155     char temp_id [MAX_INPUT_ID_LENGTH + 4] = {0,};
156     char temp_rsc[MAX_URI_LENGTH + 1] = {0,};
157     char temp_pms[MAX_PERMISSION_LENGTH + 1] = {0,};
158     printf("******************************************************************************\n");
159     printf("-Set ACL policy for target device\n");
160     printf("******************************************************************************\n");
161     //Set Subject.
162     printf("-URN identifying the subject\n");
163     printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
164     printf("Subject : ");
165     unused = scanf("%19s", temp_id);
166     int j = 0;
167     for (int i = 0; temp_id[i] != '\0'; i++)
168     {
169         if (DASH != temp_id[i])
170             acl->subject.id[j++] = temp_id[i];
171     }
172
173     //Set Resource.
174     printf("Num. of Resource : ");
175     unused = scanf("%zu", &acl->resourcesLen);
176     printf("-URI of resource\n");
177     printf("ex)/oic/sh/temp/0 (Max_URI_Length: 64 Byte )\n");
178     acl->resources = (char **)OICMalloc(acl->resourcesLen * sizeof(char *));
179     if (NULL == acl->resources)
180     {
181         OC_LOG(ERROR, TAG, "Error while memory allocation");
182         return SP_RESULT_MEM_ALLOCATION_FAIL;
183     }
184     for (int i = 0; i < acl->resourcesLen; i++)
185     {
186         printf("[%d]Resource : ", i + 1);
187         unused = scanf("%64s", temp_rsc);
188         acl->resources[i] = (char *)OICMalloc((strlen(temp_rsc) + 1) * sizeof(char));
189         if (NULL == acl->resources[i])
190         {
191             OC_LOG(ERROR, TAG, "Error while memory allocation");
192             return SP_RESULT_MEM_ALLOCATION_FAIL;
193         }
194         strncpy(acl->resources[i], temp_rsc, strlen(temp_rsc));
195         acl->resources[i][strlen(temp_rsc)] = '\0';
196     }
197     // Set Permission
198     do
199     {
200         printf("-Set the permission(C,R,U,D,N)\n");
201         printf("ex) CRUDN, CRU_N,..(5 Charaters)\n");
202         printf("Permission : ");
203         unused = scanf("%5s", temp_pms);
204     }
205     while (SP_RESULT_SUCCESS != CalculateAclPermission(temp_pms, &(acl->permission)) );
206     // Set Rowner
207     printf("Num. of Rowner : ");
208     unused = scanf("%zu", &acl->ownersLen);
209     printf("-URN identifying the rowner\n");
210     printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
211     acl->owners = (OicUuid_t *)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
212     if (NULL == acl->owners)
213     {
214         OC_LOG(ERROR, TAG, "Error while memory allocation");
215         return SP_RESULT_MEM_ALLOCATION_FAIL;
216     }
217     for (int i = 0; i < acl->ownersLen; i++)
218     {
219         printf("[%d]Rowner : ", i + 1);
220         unused = scanf("%19s", temp_id);
221         j = 0;
222         for (int k = 0; temp_id[k] != '\0'; k++)
223         {
224             if (DASH != temp_id[k])
225             {
226                 acl->owners[i].id[j++] = temp_id[k];
227             }
228         }
229     }
230     return SP_RESULT_SUCCESS;
231 }
232
233 FILE* client_fopen(const char *path, const char *mode)
234 {
235     (void)path;
236     return fopen(PROV_TOOL_DB_FILE, mode);
237 }
238
239 /**
240  * Provisioning client sample using ProvisioningAPI on provisioningmanager.c
241  * To change network type use command line option -w for Wifi and -e for Ethernet
242  */
243 int main(int argc, char **argv)
244 {
245     SPResult res = SP_RESULT_SUCCESS;
246     SPTargetDeviceInfo_t *pDeviceList = NULL;
247     gAcl = (OicSecAcl_t *)OICMalloc(sizeof(OicSecAcl_t));
248
249     // Initialize Persistent Storage for SVR database
250     OCPersistentStorage ps = {};
251     ps.open = client_fopen;
252     ps.read = fread;
253     ps.write = fwrite;
254     ps.close = fclose;
255     ps.unlink = unlink;
256     OCRegisterPersistentStorageHandler(&ps);
257
258     if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
259     {
260         OC_LOG(ERROR, TAG, "OCStack init error");
261         return 0;
262     }
263
264     if (NULL == gAcl)
265     {
266         OC_LOG(ERROR, TAG, "Error while memory allocation");
267         return SP_RESULT_MEM_ALLOCATION_FAIL;
268     }
269
270     res = SPProvisioningDiscovery(PREDEFINED_TIMEOUT, &pDeviceList);
271     if (SP_RESULT_SUCCESS == res)
272     {
273         while (pDeviceList != NULL)
274         {
275             printf("-Provisioning device ID : ");
276             for (int i = 0; i < MAX_INPUT_ID_LENGTH; i++)
277             {
278                 if (pDeviceList->doxm->deviceID.id[i] == '\0')
279                 {
280                      break;
281                 }
282                 printf("%c", pDeviceList->doxm->deviceID.id[i]);
283             }
284             printf("\n");
285             res = SPInitProvisionContext(PREDEFINED_TIMEOUT, pDeviceList);
286             if (SP_RESULT_SUCCESS != res)
287             {
288                 OC_LOG(ERROR, TAG, "Error while init provisioning Context");
289                 goto error;
290             }
291             res = InputACL(gAcl);
292             if (SP_RESULT_SUCCESS != res)
293             {
294                 OC_LOG(ERROR, TAG, "Error while user ACL input ");
295                 goto error;
296             }
297             res = SPProvisionACL(PREDEFINED_TIMEOUT, pDeviceList, gAcl);
298             if (SP_RESULT_SUCCESS != res)
299             {
300                 OC_LOG(ERROR, TAG, "Error while provisioning ACL");
301                 goto error;
302             }
303             res = SPFinalizeProvisioning(PREDEFINED_TIMEOUT, pDeviceList);
304             if (SP_RESULT_SUCCESS == res)
305             {
306                 printf("Provisioning Success~!!\n");
307             }
308             else if (SP_RESULT_SUCCESS != res)
309             {
310                 OC_LOG(ERROR, TAG, "Error while Finalize Provisioning");
311                 goto error;
312             }
313             pDeviceList = pDeviceList->next;
314         }
315     }
316     else
317     {
318         OC_LOG(ERROR, TAG, "Error while Provisioning Discovery");
319         goto error;
320     }
321
322 error:
323     DeleteACLList(gAcl);
324     SPTerminateProvisioning();
325     return 0;
326 }