replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / tool / svrdbeditor_src / svrdbeditorpstat.c
1 /* *****************************************************************
2  *
3  * Copyright 2017 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 "octypes.h"
22 #include "oic_malloc.h"
23
24 #include "securevirtualresourcetypes.h"
25 #include "srmresourcestrings.h"
26 #include "psinterface.h"
27
28 #include "pstatresource.h"
29 #include "svrdbeditorpstat.h"
30
31 #define DPM_CNT (6)
32 #define DPOM_CNT (3)
33
34 static OicSecPstat_t *g_pstat = NULL;
35
36 typedef enum PstatModifyType
37 {
38     PSTAT_EDIT_ISOP = 1,
39     PSTAT_EDIT_CM,
40     PSTAT_EDIT_TM,
41     PSTAT_EDIT_OM,
42     PSTAT_EDIT_SM,
43     PSTAT_EDIT_ROWNERID = 6
44 } PstatModifyType_t;
45
46 void DeInitPstat(void)
47 {
48     DeletePstatBinData(g_pstat);
49     g_pstat = NULL;
50 }
51
52 void RefreshPstat(void)
53 {
54     OCStackResult ocResult = OC_STACK_ERROR;
55     OicSecPstat_t *tmpPstat = NULL;
56     uint8_t *secPayload = NULL;
57     size_t payloadSize = 0;
58
59     ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_PSTAT_NAME, &secPayload, &payloadSize);
60     if (OC_STACK_OK != ocResult)
61     {
62         PRINT_WARN("GetSecureVirtualDatabaseFromPS : %d", ocResult);
63         return;
64     }
65
66     ocResult = CBORPayloadToPstat(secPayload, payloadSize, &tmpPstat);
67     if (OC_STACK_OK != ocResult)
68     {
69         PRINT_ERR("CBORPayloadToPstat : %d", ocResult);
70         OICFree(secPayload);
71         return;
72     }
73     OICFree(secPayload);
74
75     if (g_pstat)
76     {
77         DeInitPstat();
78     }
79     g_pstat = tmpPstat;
80 }
81
82 static void UpdatePstat(void)
83 {
84     OCStackResult pstatResult = OC_STACK_ERROR;
85     uint8_t *pstatPayload = NULL;
86     size_t pstatPayloadSize = 0;
87
88     pstatResult = PstatToCBORPayload(g_pstat, &pstatPayload, &pstatPayloadSize, false);
89     if (OC_STACK_OK != pstatResult)
90     {
91         PRINT_ERR("PstatToCBORPayload error : %d", pstatResult);
92         return;
93     }
94     pstatResult = UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, pstatPayload, pstatPayloadSize);
95     if (OC_STACK_OK != pstatResult)
96     {
97         PRINT_ERR("UpdateSecureResourceInPS error : %d", pstatResult);
98         OICFree(pstatPayload);
99         return;
100     }
101     OICFree(pstatPayload);
102 }
103
104 static void PrintDpm(const OicSecDpm_t dpm)
105 {
106     PRINT_DATA("%d (", dpm);
107
108     if (NORMAL == dpm)
109     {
110         PRINT_DATA(" NORMAL ");
111     }
112     if (dpm & RESET)
113     {
114         PRINT_DATA(" RESET ");
115     }
116     if (dpm & TAKE_OWNER)
117     {
118         PRINT_DATA(" TAKE_OWNER ");
119     }
120     if (dpm & BOOTSTRAP_SERVICE)
121     {
122         PRINT_DATA(" BOOTSTRAP_SERVICE ");
123     }
124     if (dpm & SECURITY_MANAGEMENT_SERVICES)
125     {
126         PRINT_DATA(" SECURITY_MANAGEMENT_SERVICES ");
127     }
128     if (dpm & PROVISION_CREDENTIALS)
129     {
130         PRINT_DATA(" PROVISION_CREDENTIALS ");
131     }
132     if (dpm & PROVISION_ACLS)
133     {
134         PRINT_DATA(" PROVISION_ACLS ");
135     }
136
137     PRINT_DATA(") \n");
138 }
139
140 static void PrintDpom(const OicSecDpom_t dpom)
141 {
142     PRINT_DATA("%d (", dpom);
143
144     if (dpom & MULTIPLE_SERVICE_SERVER_DRIVEN)
145     {
146         PRINT_DATA(" MULTIPLE_SERVICE_SERVER_DRIVEN ");
147     }
148     if (dpom & SINGLE_SERVICE_SERVER_DRIVEN)
149     {
150         PRINT_DATA(" SINGLE_SERVICE_SERVER_DRIVEN ");
151     }
152     if (dpom & SINGLE_SERVICE_CLIENT_DRIVEN)
153     {
154         PRINT_DATA(" SINGLE_SERVICE_CLIENT_DRIVEN ");
155     }
156     PRINT_DATA(") \n");
157 }
158
159 void PrintPstat(void)
160 {
161     PRINT_INFO("\n\n********************* [%-20s] *********************",
162                "PSTAT Resource");
163     if (g_pstat)
164     {
165         PRINT_PROG("%15s : ", OIC_JSON_ISOP_NAME);
166         (g_pstat->isOp ? PrintString("True") : PrintString("False"));
167
168         //cm
169         PRINT_PROG("%15s : ", OIC_JSON_CM_NAME);
170         PrintDpm(g_pstat->cm);
171
172         //tm
173         PRINT_PROG("%15s : ", OIC_JSON_TM_NAME);
174         PrintDpm(g_pstat->tm);
175
176         //om
177         PRINT_PROG("%15s : ", OIC_JSON_OM_NAME);
178         PrintDpom(g_pstat->om);
179
180         //sm
181         PRINT_PROG("%15s : \n", OIC_JSON_SM_NAME);
182         for (size_t i = 0; i < g_pstat->smLen; i++)
183         {
184             PRINT_DATA("supported mode #%zu : ", i + 1);
185             PrintDpom(g_pstat->sm[i]);
186         }
187
188         PRINT_PROG("%15s : ", OIC_JSON_ROWNERID_NAME);
189         PrintUuid(&(g_pstat->rownerID));
190     }
191     else
192     {
193         PRINT_PROG("pstat is empty.\n");
194     }
195     PRINT_INFO("********************* [%-20s] *********************",
196                "PSTAT Resource");
197 }
198
199 static unsigned int InputDpm(void)
200 {
201     unsigned int dpm = 0;
202     unsigned int dpm_msk = 1;  //default mask
203     const char *Operation_Mode[DPM_CNT] =
204     {
205         "RESET", "TAKE_OWNER", "BOOTSTRAP_SERVICE", "SECURITY_MANAGEMENT_SERVICES",
206         "PROVISION_CREDENTIALS", "PROVISION_ACLS"
207     };
208
209     for (int i = 0; i < DPM_CNT; i++)
210     {
211         char ans = 0;
212         for (;;)
213         {
214             PRINT_NORMAL("\tEnter %s Mode (y/n): ", Operation_Mode[i]);
215             for (int ret = 0; 1 != ret; )
216             {
217                 ret = scanf("%c", &ans);
218                 for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
219                 // '0x20<=code' is character region
220             }
221             if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
222             {
223                 ans &= ~0x20;  // for masking lower case, 'y/n'
224                 break;
225             }
226             PRINT_NORMAL("\tEntered Wrong Answer. Please Enter 'y/n' Again\n");
227         }
228         if ('Y' == ans)
229         {
230             dpm |= dpm_msk;
231         }
232         dpm_msk <<= 1;
233     }
234     return dpm;
235 }
236
237 static unsigned int InputDpom()
238 {
239     unsigned int dpom = 0;
240     unsigned int dpom_msk = 1;  //default mask
241     const char *Operation_Mode[DPOM_CNT] =
242     {
243         "MULTIPLE_SERVICE_SERVER_DRIVEN", "SINGLE_SERVICE_SERVER_DRIVEN",
244         "SINGLE_SERVICE_CLIENT_DRIVEN"
245     };
246
247     PRINT_PROG("SINGLE_SERVICE_CLIENT_DRIVEN is the only mode IoTivity supports currently\n");
248
249     for (int i = 0; i < DPOM_CNT; i++)
250     {
251         char ans = 0;
252         for (;;)
253         {
254             PRINT_NORMAL("\tEnter %s Mode (y/n): ", Operation_Mode[i]);
255             for (int ret = 0; 1 != ret; )
256             {
257                 ret = scanf("%c", &ans);
258                 for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
259                 // '0x20<=code' is character region
260             }
261             if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
262             {
263                 ans &= ~0x20;  // for masking lower case, 'y/n'
264                 break;
265             }
266             PRINT_NORMAL("\tEntered Wrong Answer. Please Enter 'y/n' Again\n");
267         }
268         if ('Y' == ans)
269         {
270             dpom |= dpom_msk;
271         }
272         dpom_msk <<= 1;
273     }
274     return dpom;
275 }
276
277 static OicSecPstat_t *InputPstatData(void)
278 {
279     OicSecPstat_t *pstat = NULL;
280     int isop = 0;
281
282     pstat = (OicSecPstat_t *)OICCalloc(1, sizeof(OicSecPstat_t));
283     if (NULL == pstat)
284     {
285         PRINT_ERR("Failed to allocate memory");
286         return NULL;
287     }
288
289     PRINT_PROG("\n\nPlease input the each entity of new pstat.\n");
290
291     isop = InputNumber("Input the isop value ( 0.False, 1.True ) : ");
292     if (isop < 0 || 1 < isop)
293     {
294         PRINT_ERR("Invalid input");
295         OICFree(pstat);
296         return NULL;
297     }
298     else
299     {
300         pstat->isOp = (1 == isop ? true : false);
301     }
302
303     PRINT_PROG("Input Current Mode\n");
304     pstat->cm = InputDpm();
305     PRINT_PROG("Input Target Mode\n");
306     pstat->tm = InputDpm();
307     PRINT_PROG("Input Operational Mode\n");
308
309     pstat->om = InputDpom();
310     pstat->smLen = 1; // supported only one dpom mode in current iotivity
311     pstat->sm = (OicSecDpom_t *)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
312     if (NULL == pstat->sm)
313     {
314         PRINT_ERR("InputPstatData : Failed to allocate memory");
315         OICFree(pstat);
316         return NULL;
317     }
318     for (size_t i = 0; i < pstat->smLen; i++)
319     {
320         PRINT_PROG("Input dpom #%zu", i);
321         pstat->sm[i] = InputDpom();
322     }
323
324     PRINT_PROG(
325         "\tInput the ROWNER UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
326     if (0 != InputUuid(&(pstat->rownerID)))
327     {
328         PRINT_ERR("InputUuid error");
329         OICFree(pstat->sm);
330         OICFree(pstat);
331         return NULL;
332     }
333     return pstat;
334 }
335
336 static int ModifyPstat(void)
337 {
338     int ret = 0;
339     int modifyMenu = 0;
340     if (NULL == g_pstat)
341     {
342         PRINT_ERR("pstat is NULL");
343         return -1;
344     }
345
346     PRINT_PROG("\n\nPlease input the attribute you want to modify\n");
347     PRINT_DATA("\t%2d. Edit isop\n", PSTAT_EDIT_ISOP);
348     PRINT_DATA("\t%2d. Edit cm\n", PSTAT_EDIT_CM);
349     PRINT_DATA("\t%2d. Edit tm\n", PSTAT_EDIT_TM);
350     PRINT_DATA("\t%2d. Edit om\n", PSTAT_EDIT_OM);
351     PRINT_DATA("\t%2d. Edit sm\n", PSTAT_EDIT_SM);
352     PRINT_DATA("\t%2d. Edit rownerID\n", PSTAT_EDIT_ROWNERID);
353     PRINT_DATA("\t%2d. Back to the previous\n", BACK);
354     modifyMenu = InputNumber("Select the menu : ");
355     switch (modifyMenu)
356     {
357         case PSTAT_EDIT_ISOP:
358             {
359                 int isop = InputNumber("Input the isop value ( 0.False, 1.True ) : ");
360                 if (isop < 0 || 1 < isop)
361                 {
362                     PRINT_ERR("Invalid input");
363                     return -1;
364                 }
365                 else
366                 {
367                     g_pstat->isOp = (1 == isop ? true : false);
368                 }
369                 break;
370             }
371         case PSTAT_EDIT_CM :
372             PRINT_PROG("Input Current Mode\n");
373             g_pstat->cm = InputDpm();
374             break;
375         case PSTAT_EDIT_TM:
376             PRINT_PROG("Input Target Mode\n");
377             g_pstat->tm = InputDpm();
378             break;
379         case PSTAT_EDIT_OM:
380             PRINT_PROG("Input Operational Mode\n");
381             g_pstat->om = InputDpom();
382             break;
383         case PSTAT_EDIT_SM:
384             {
385                 OicSecDpom_t *sm = NULL;
386                 size_t smLen = 1;
387
388                 sm = (OicSecDpom_t *)OICCalloc(smLen, sizeof(OicSecDpom_t));
389                 if (NULL == sm)
390                 {
391                     PRINT_ERR("Failed to allocate memory");
392                     return -1;
393                 }
394                 for (size_t i = 0; i < smLen; i++)
395                 {
396                     PRINT_PROG("Input dpom #%zu", i);
397                     sm[i] = InputDpom();
398                 }
399                 if (g_pstat->sm)
400                 {
401                     OICFree(g_pstat->sm);
402                 }
403                 g_pstat->smLen = smLen;
404                 g_pstat->sm = sm;
405                 break;
406             }
407         case PSTAT_EDIT_ROWNERID:
408             PRINT_PROG(
409                 "\tInput the ROWNER UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
410             ret = InputUuid(&(g_pstat->rownerID));
411             if (0 != ret)
412             {
413                 PRINT_ERR("InputUuid error");
414                 return ret;
415             }
416             break;
417         case BACK:
418             PRINT_INFO("Back to the previous menu.");
419             break;
420         default:
421             PRINT_ERR("Wrong type Number");
422             ret = -1;
423             break;
424     }
425     return ret;
426 }
427
428 void HandlePstatOperation(const SubOperationType_t cmd)
429 {
430     OCStackResult pstatResult = OC_STACK_ERROR;
431
432     if (SVR_EDIT_IDX_SIZE <= cmd)
433     {
434         PRINT_ERR("Invalid menu for pstat");
435         return;
436     }
437     switch (cmd)
438     {
439         case SVR_PRINT:
440             PrintPstat();
441             break;
442         case SVR_ADD:
443             if (g_pstat)
444             {
445                 PRINT_ERR("Already exist");
446                 return;
447             }
448             else
449             {
450                 g_pstat = InputPstatData();
451                 if (NULL == g_pstat)
452                 {
453                     PRINT_ERR("Failed to InputPstatData");
454                     return;
455                 }
456                 UpdatePstat();
457             }
458             break;
459         case SVR_REMOVE:
460             if (g_pstat)
461             {
462                 DeInitPstat();
463                 pstatResult = UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, NULL, 0);
464                 if (OC_STACK_OK != pstatResult)
465                 {
466                     PRINT_ERR("UpdateSecureResourceInPS error : %d", pstatResult);
467                     return;
468                 }
469             }
470             else
471             {
472                 PRINT_ERR("pstat is NULL");
473                 return;
474             }
475             break;
476         case SVR_MODIFY:
477             if (0 != ModifyPstat())
478             {
479                 PRINT_ERR("Failed Modify");
480                 return;
481             }
482             PRINT_INFO("\n\nPstat Modified");
483             PrintPstat();
484             UpdatePstat();
485             break;
486         default:
487             PRINT_ERR("Invalid menu for pstat");
488             break;
489     }
490 }