Initialize Tizen 2.3
[framework/system/oma-dm-agent.git] / src / agent / serviceadapter / sa_util.c
1 /*
2  * oma-dm-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /*lib*/
19 #include <glib.h>
20 #include <glib/gprintf.h>
21
22 /*sync-agent*/
23 #include <sync_agent.h>
24
25 /*dm-agent*/
26 #include "common/dm_common.h"
27 #include "common/util/util.h"
28 #include "serviceadapter/sa_util.h"
29
30 #ifndef OMADM_AGENT_LOG
31 #undef LOG_TAG
32 #define LOG_TAG "OMA_DM_SA"
33 #endif
34
35 #define BUF_SIZE 300
36 #define MAX_BUFFER 50
37
38 void putCmdIntoList(GList ** commands, GList ** commands_last, void *pCommand)
39 {
40         _EXTERN_FUNC_ENTER;
41
42         GList *temp = NULL;
43         if (*commands_last == NULL) {
44                 *commands_last = *commands = g_list_append(*commands, pCommand);
45         } else {
46                 temp = g_list_append(*commands_last, pCommand);
47                 if(temp == NULL) {
48                         _DEBUG_ERROR("g_list_append return value NULL!!");
49                 }
50                 *commands_last = g_list_next(*commands_last);
51         }
52
53         _EXTERN_FUNC_EXIT;
54 }
55
56 DM_ERROR create_auth_credString(AuthType type, const char *username, const char *password, const unsigned char *nonce, const unsigned int nonce_size, char **pCred)
57 {
58         _EXTERN_FUNC_ENTER;
59
60         retvm_if((username) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "username is NULL!!");
61         retvm_if((password) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "password is NULL!!");
62
63         _DEBUG_INFO(" type : [%d] username :[%s], password :[%s] , nonce : [%s],nonce_size : [%d]", type, username, password, nonce, nonce_size);
64
65         DM_ERROR ret = DM_OK;
66
67         switch (type) {
68         case AUTH_TYPE_BASIC:
69                 {
70                         char *plain = g_strjoin(":", username, password, NULL);
71                         *pCred = g_base64_encode((unsigned char *)plain, strlen(plain));
72                         if (*pCred == NULL) {
73                                 free(plain);
74                                 ret = COMMON_ERR_INTERNAL_NO_MEMORY;
75                                 goto error;
76                         }
77                         free(plain);
78
79                         break;
80                 }
81         case AUTH_TYPE_MD5:
82                 {
83                         /* How does syncml:auth-md5 works?
84                          *
85                          * base64(
86                          *        md5(
87                          *            base64(
88                          *                   md5(
89                          *                       username + ":" + password
90                          *                      )
91                          *                  ) +
92                          *            ":" + nonce
93                          *           )
94                          *       )
95                          */
96
97                         /* Let's determine the string for the comparison. */
98                         char *auth = NULL;
99                         auth = g_strjoin(":", username, password, NULL);
100                         _DEBUG_INFO("[username:password] = %s\n", auth);
101
102                         unsigned char *digest = NULL;
103                         digest = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, auth, strlen(auth));
104                         free(auth);
105                         *pCred = g_base64_encode(digest, 16);
106                         if (*pCred == NULL) {
107                                 ret = COMMON_ERR_INTERNAL_NO_MEMORY;
108                                 goto error;
109                         }
110
111                         _DEBUG_INFO("nonce = %s", nonce);
112                         _DEBUG_INFO("nonce_size = %d", nonce_size);
113                         int auth_size = strlen(*pCred) + nonce_size + 1;
114                         auth = (char *)calloc(strlen(*pCred) + nonce_size + 1 + 1, sizeof(char));
115                         if (auth == NULL) {
116                                 _DEBUG_INFO("alloc fail");
117                                 _EXTERN_FUNC_EXIT;
118                                 return COMMON_ERR_ALLOC;
119                         }
120                         memcpy(auth, *pCred, strlen(*pCred));
121                         auth[strlen(*pCred)] = ':';
122                         memcpy(auth + strlen(*pCred) + 1, nonce, nonce_size);
123                         _DEBUG_INFO("base64[md5[username:password]] = %s\n", *pCred);
124                         _DEBUG_INFO("before last base64 encoding = %s\n", auth);
125                         free(*pCred);
126
127                         digest = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, auth, auth_size);
128                         _DEBUG_INFO("md5[base64[md5[username:password]]:nonce] = %s\n", digest);
129
130                         free(auth);
131                         *pCred = g_base64_encode(digest, 16);
132                         free(digest);
133                         _DEBUG_INFO("base64[md5[base64[md5[username:password]]:nonce]] = %s", *pCred);
134                         if (*pCred == NULL) {
135                                 ret = COMMON_ERR_INTERNAL_NO_MEMORY;
136                                 goto error;
137                         }
138                         break;
139                 }
140         case AUTH_TYPE_HMAC:
141                 {
142                         /*do not use cred element */
143                 }
144                 break;
145         case AUTH_TYPE_UNKNOWN:
146         case AUTH_TYPE_HTTP_BASIC:
147         case AUTH_TYPE_HTTP_DIGEST:
148         case AUTH_TYPE_X509:
149         case AUTH_TYPE_SECURID:
150         case AUTH_TYPE_SAFEWORD:
151         case AUTH_TYPE_DIGIPASS:
152         case AUTH_TYPE_TRANSPORT:
153                 _DEBUG_INFO("not support auth type");
154                 ret = DM_ERR_FORBIDDEN;
155                 goto error;
156                 break;
157         default:
158                 break;
159         }
160
161         _EXTERN_FUNC_EXIT;
162         return ret;
163
164  error:
165         _DEBUG_INFO("error : %d\n", ret);
166         _EXTERN_FUNC_EXIT;
167         return ret;
168 }
169
170 DM_ERROR gemerate_hmac(char *username, char *password, unsigned char *nonce, unsigned int nonce_size, char *msg, unsigned int msg_size, char **mac)
171 {
172         _EXTERN_FUNC_ENTER;
173
174         DM_ERROR ret = DM_OK;
175
176         retvm_if((msg) == NULL, COMMON_ERR_IS_NULL, "session is NULL!!");
177         retvm_if((username) == NULL, COMMON_ERR_IS_NULL, "username is NULL!!");
178         retvm_if((password) == NULL, COMMON_ERR_IS_NULL, "password is NULL!!");
179         retvm_if((nonce) == NULL, COMMON_ERR_IS_NULL, "nonce is NULL!!");
180
181         char *resultmd = NULL;
182         unsigned char *resultmd5 = NULL;
183         unsigned char *resultmd6 = NULL;
184         //char md5Digest[16];
185         char buffer[BUF_SIZE];
186         char *temp_result1 = NULL;
187         char *temp_result2 = NULL;
188         char *temp_result3 = NULL;
189         unsigned int size;
190         int len = 0;
191         int str_len = 0;
192 /*      if (nonce  == NULL|| username  == NULL|| password  == NULL|| msg == NULL)
193                 return 0;*/
194
195         /* Logging */
196         _DEBUG_INFO("generate HMAC");
197         //resultmd5 = (unsigned char *)calloc(1, sizeof(char)*17);
198
199         /* H(messageBody) */
200         resultmd = (char *)sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, (const char *)msg, (int)msg_size);
201         resultmd5 = (unsigned char *)strdup(resultmd);
202
203         size = 16;
204
205         int i = 0;
206         char *digest_msg = (char *)calloc(MAX_BUFFER, sizeof(char));
207         if (digest_msg == NULL) {
208                 _DEBUG_INFO("alloc fail");
209                 _EXTERN_FUNC_EXIT;
210                 return COMMON_ERR_ALLOC;
211         }
212         for (i = 0; i < 16; i++) {
213                 snprintf(digest_msg + (i * 2), MAX_BUFFER, "%02x", resultmd5[i]);
214         }
215         _DEBUG_INFO("MD 5 = %s", digest_msg);
216         /* B64(H(messageBody) */
217         temp_result1 = g_base64_encode(resultmd5, size);
218         msg_size = size;
219
220         /* Logging */
221         _DEBUG_INFO("B64(H(messageBody)) : %s", temp_result1);
222
223         /* H(username:password) */
224         str_len = g_strlcpy(buffer, username, (int)sizeof(buffer));
225         if (str_len >= sizeof(buffer)) {
226                 _DEBUG_INFO("buffer over flow");
227                 ret = COMMON_ERR_BUFFER_OVERFLOW;
228
229                 if(digest_msg != NULL) {
230                         free(digest_msg);
231                         digest_msg = NULL;
232                 }
233
234                 _EXTERN_FUNC_EXIT;
235                 return ret;
236         }
237         len = g_strlcat(buffer, ":", BUF_SIZE);
238         len = g_strlcat(buffer, password, BUF_SIZE);
239         size = strlen(buffer);
240
241         _DEBUG_INFO("username:password: %s", buffer);
242         resultmd5 = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, (const char *)buffer, (int)size);
243         size = 16;
244
245         /* B64(H(username:password)) */
246         temp_result2 = g_base64_encode(resultmd5, size);
247         _DEBUG_INFO("B64(H(username:password)) %s", temp_result2);
248
249         /* B64(H(username:password)):nonce:B64(H(message body)) */
250         str_len = g_strlcpy(buffer, (const char *)temp_result2, (int)sizeof(buffer));
251         if (str_len >= sizeof(buffer)) {
252                 _DEBUG_INFO("buffer over flow");
253                 ret = COMMON_ERR_BUFFER_OVERFLOW;
254
255                 if(digest_msg != NULL) {
256                         free(digest_msg);
257                         digest_msg = NULL;
258                 }
259
260                 _EXTERN_FUNC_EXIT;
261                 return ret;
262         }
263
264         len = g_strlcat(buffer, ":", BUF_SIZE);
265
266         _DEBUG_INFO("B64(H(username:password)): =  %s", buffer);
267         size = strlen((const char *)temp_result2) + 1;
268         _DEBUG_INFO("buffer : %s, real size : %d , size : %d\n", buffer, strlen(buffer), size);
269
270         len = g_strlcat(buffer, (const char *)nonce, BUF_SIZE);
271
272         _DEBUG_INFO("B64(H(username:password)):nonce = %s", buffer);
273         size += strlen((const char *)nonce);
274         _DEBUG_INFO("buffer : %s, real size : %d , size : %d\n", buffer, strlen(buffer), size);
275
276         len = g_strlcat(buffer, ":", BUF_SIZE);
277
278         size++;
279         _DEBUG_INFO("buffer : %s, real size : %d , size : %d\n", buffer, strlen(buffer), size);
280
281         len = g_strlcat(buffer, temp_result1, BUF_SIZE);
282
283         size += strlen((const char *)temp_result1);
284         _DEBUG_INFO("B64(H(username:password)):nonce:B64(H(message body)): %s", buffer);
285
286         /* Interim Clean up */
287         str_free((char **)(&temp_result1));
288         str_free((char **)(&temp_result2));
289
290         if (str_len >= BUF_SIZE) {
291                 _DEBUG_INFO("buffer over flow");
292                 ret = COMMON_ERR_BUFFER_OVERFLOW;
293                 _EXTERN_FUNC_EXIT;
294                 return ret;
295         }
296
297         /*char *buffer1 = "wUN5aEY1cn4K1AhZnuSg6Q==:12345:stthIupGdabKGLdI7ezeBw==";
298            int size1 = strlen(buffer1);
299            printf("buffer1 : %s, size1 : %d\n", buffer1, size1);
300          */
301         /* H(B64(H(username:password)):nonce:B64(H(message body))) */
302         resultmd6 = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, buffer, size);
303         size = 16;
304
305         i = 0;
306         _DEBUG_INFO("gener : ");
307         for (i = 0; i < size; ++i) {
308                 _DEBUG_INFO(" %02x", resultmd6[i]);
309         }
310         //_DEBUG_INFO("\n");
311
312         /* Return the base 64 of digest */
313         temp_result3 = g_base64_encode(resultmd6, size);
314
315         /* Logging */
316         _DEBUG_INFO("B64(H(B64(H(username:password)):nonce:B64(H(message body)))): %s", temp_result3);
317
318         (*mac) = strdup((const char *)temp_result3);
319         str_free((char **)(&temp_result3));
320
321         if(digest_msg != NULL) {
322                 free(digest_msg);
323                 digest_msg = NULL;
324         }
325         _EXTERN_FUNC_EXIT;
326         return ret;
327
328 }
329
330 void set_xml_to_file(char *xml, const char *path)
331 {
332         _EXTERN_FUNC_ENTER;
333
334         FILE *pFile = NULL;
335
336         if (xml != NULL) {
337                 pFile = fopen(path, "a");
338         }
339
340         if (pFile == NULL) {
341                 _EXTERN_FUNC_EXIT;
342                 return;
343         }
344
345         fputs("==================================================================================", pFile);
346         fputs("\n", pFile);
347         fputs(xml, pFile);
348
349         fclose(pFile);
350
351         _EXTERN_FUNC_EXIT;
352 }
353
354 DM_ERROR findStgringValue(char *original, char *findParam, char *findSep, char **findValue)
355 {
356         _EXTERN_FUNC_ENTER;
357
358         DM_ERROR ret = DM_OK;
359
360         retvm_if((original) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "original is NULL!!");
361         retvm_if((findParam) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "findParam is NULL!!");
362
363         char *findOption = NULL;
364         char *findEnd = NULL;
365         char *findSepEnd = NULL;
366         int valueSize = 0;
367         /*int optionSize = 0;
368            int sepaSize = 0; */
369
370         /*mindt=10&dr=1&maclen=10 */
371         findOption = strstr(original, findParam);
372         if (findOption != NULL) {
373                 _DEBUG_INFO(" find Option : %s\n", findOption);
374
375                 /*=10&dr=1&maclen=10*/
376                 findEnd = strstr(findOption, findSep);
377                 if (findEnd != NULL) {
378                         /*&dr=1&maclen=10 */
379                         findSepEnd = strstr(findOption, UI_OP_SEPARATOR);
380                         if (findSepEnd != NULL) {
381                                 valueSize = strlen(findEnd) - strlen(findSepEnd) - 1;
382                         } else {
383                                 valueSize = strlen(findEnd);
384                         }
385                         _DEBUG_INFO(" findEnd : %s\n", findEnd);
386                         _DEBUG_INFO(" findSepEnd : %s\n", findSepEnd);
387                         _DEBUG_INFO(" value size : %d\n", valueSize);
388                 } else {
389                         _DEBUG_INFO("not found value");
390                         _EXTERN_FUNC_EXIT;
391                         return ret;
392                 }
393                 (*findValue) = calloc(1, valueSize + 1);
394                 if ((*findValue) == NULL) {
395                         _DEBUG_INFO("alloc fail");
396                         return COMMON_ERR_ALLOC;
397                 }
398                 memcpy((*findValue), findEnd + 1, valueSize);
399                 (*findValue)[valueSize] = '\0';
400
401                 _DEBUG_INFO(" find Value : %s : %d \n", (*findValue), valueSize);
402
403         } else {
404                 _DEBUG_INFO(" not found \n");
405         }
406
407         _EXTERN_FUNC_EXIT;
408         return ret;
409
410 }