Tizen 2.0 Release
[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                 _EXTERN_FUNC_EXIT;
229                 return ret;
230         }
231         len = g_strlcat(buffer, ":", BUF_SIZE);
232         len = g_strlcat(buffer, password, BUF_SIZE);
233         size = strlen(buffer);
234
235         _DEBUG_INFO("username:password: %s", buffer);
236         resultmd5 = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, (const char *)buffer, (int)size);
237         size = 16;
238
239         /* B64(H(username:password)) */
240         temp_result2 = g_base64_encode(resultmd5, size);
241         _DEBUG_INFO("B64(H(username:password)) %s", temp_result2);
242
243         /* B64(H(username:password)):nonce:B64(H(message body)) */
244         str_len = g_strlcpy(buffer, (const char *)temp_result2, (int)sizeof(buffer));
245         if (str_len >= sizeof(buffer)) {
246                 _DEBUG_INFO("buffer over flow");
247                 ret = COMMON_ERR_BUFFER_OVERFLOW;
248                 _EXTERN_FUNC_EXIT;
249                 return ret;
250         }
251
252         len = g_strlcat(buffer, ":", BUF_SIZE);
253
254         _DEBUG_INFO("B64(H(username:password)): =  %s", buffer);
255         size = strlen((const char *)temp_result2) + 1;
256         _DEBUG_INFO("buffer : %s, real size : %d , size : %d\n", buffer, strlen(buffer), size);
257
258         len = g_strlcat(buffer, (const char *)nonce, BUF_SIZE);
259
260         _DEBUG_INFO("B64(H(username:password)):nonce = %s", buffer);
261         size += strlen((const char *)nonce);
262         _DEBUG_INFO("buffer : %s, real size : %d , size : %d\n", buffer, strlen(buffer), size);
263
264         len = g_strlcat(buffer, ":", BUF_SIZE);
265
266         size++;
267         _DEBUG_INFO("buffer : %s, real size : %d , size : %d\n", buffer, strlen(buffer), size);
268
269         len = g_strlcat(buffer, temp_result1, BUF_SIZE);
270
271         size += strlen((const char *)temp_result1);
272         _DEBUG_INFO("B64(H(username:password)):nonce:B64(H(message body)): %s", buffer);
273
274         /* Interim Clean up */
275         str_free((char **)(&temp_result1));
276         str_free((char **)(&temp_result2));
277
278         if (str_len >= BUF_SIZE) {
279                 _DEBUG_INFO("buffer over flow");
280                 ret = COMMON_ERR_BUFFER_OVERFLOW;
281                 _EXTERN_FUNC_EXIT;
282                 return ret;
283         }
284
285         /*char *buffer1 = "wUN5aEY1cn4K1AhZnuSg6Q==:12345:stthIupGdabKGLdI7ezeBw==";
286            int size1 = strlen(buffer1);
287            printf("buffer1 : %s, size1 : %d\n", buffer1, size1);
288          */
289         /* H(B64(H(username:password)):nonce:B64(H(message body))) */
290         resultmd6 = sync_agent_encrypt_cryptograhic_hash(SYNC_AGENT_SA_CRYPTOGRAHIC_HASH_FUNTION_MD5, buffer, size);
291         size = 16;
292
293         i = 0;
294         printf("gener : ");
295         for (i = 0; i < size; ++i) {
296                 printf(" %02x", resultmd6[i]);
297         }
298         printf("\n");
299
300         /* Return the base 64 of digest */
301         temp_result3 = g_base64_encode(resultmd6, size);
302
303         /* Logging */
304         _DEBUG_INFO("B64(H(B64(H(username:password)):nonce:B64(H(message body)))): %s", temp_result3);
305
306         (*mac) = strdup((const char *)temp_result3);
307         str_free((char **)(&temp_result3));
308
309         _EXTERN_FUNC_EXIT;
310         return ret;
311
312 }
313
314 void set_xml_to_file(char *xml, const char *path)
315 {
316         _EXTERN_FUNC_ENTER;
317
318         FILE *pFile = NULL;
319
320         if (xml != NULL) {
321                 pFile = fopen(path, "a");
322         }
323
324         if (pFile == NULL) {
325                 _EXTERN_FUNC_EXIT;
326                 return;
327         }
328
329         fputs("==================================================================================", pFile);
330         fputs("\n", pFile);
331         fputs(xml, pFile);
332
333         fclose(pFile);
334
335         _EXTERN_FUNC_EXIT;
336 }
337
338 DM_ERROR findStgringValue(char *original, char *findParam, char *findSep, char **findValue)
339 {
340         _EXTERN_FUNC_ENTER;
341
342         DM_ERROR ret = DM_OK;
343
344         retvm_if((original) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "original is NULL!!");
345         retvm_if((findParam) == NULL, COMMON_ERR_INTERNAL_NOT_DEFINED, "findParam is NULL!!");
346
347         char *findOption = NULL;
348         char *findEnd = NULL;
349         char *findSepEnd = NULL;
350         int valueSize = 0;
351         /*int optionSize = 0;
352            int sepaSize = 0; */
353
354         /*mindt=10&dr=1&maclen=10 */
355         findOption = strstr(original, findParam);
356         if (findOption != NULL) {
357                 _DEBUG_INFO(" find Option : %s\n", findOption);
358
359                 /*=10&dr=1&maclen=10*/
360                 findEnd = strstr(findOption, findSep);
361                 if (findEnd != NULL) {
362                         /*&dr=1&maclen=10 */
363                         findSepEnd = strstr(findOption, UI_OP_SEPARATOR);
364                         if (findSepEnd != NULL) {
365                                 valueSize = strlen(findEnd) - strlen(findSepEnd) - 1;
366                         } else {
367                                 valueSize = strlen(findEnd);
368                         }
369                         _DEBUG_INFO(" findEnd : %s\n", findEnd);
370                         _DEBUG_INFO(" findSepEnd : %s\n", findSepEnd);
371                         _DEBUG_INFO(" value size : %d\n", valueSize);
372                 } else {
373                         _DEBUG_INFO("not found value");
374                         _EXTERN_FUNC_EXIT;
375                         return ret;
376                 }
377                 (*findValue) = calloc(1, valueSize + 1);
378                 if ((*findValue) == NULL) {
379                         _DEBUG_INFO("alloc fail");
380                         return COMMON_ERR_ALLOC;
381                 }
382                 memcpy((*findValue), findEnd + 1, valueSize);
383                 (*findValue)[valueSize] = '\0';
384
385                 _DEBUG_INFO(" find Value : %s : %d \n", (*findValue), valueSize);
386
387         } else {
388                 _DEBUG_INFO(" not found \n");
389         }
390
391         _EXTERN_FUNC_EXIT;
392         return ret;
393
394 }