Changeset 432
- Timestamp:
- 04/29/08 19:08:46 (3 months ago)
- Files:
-
- trunk/libsyncml/objects/sml_auth.c (modified) (3 diffs)
- trunk/libsyncml/objects/sml_auth.h (modified) (2 diffs)
- trunk/libsyncml/objects/sml_auth_internals.h (modified) (2 diffs)
- trunk/libsyncml/parser/sml_xml_assm.c (modified) (7 diffs)
- trunk/libsyncml/parser/sml_xml_assm.h (modified) (1 diff)
- trunk/libsyncml/parser/sml_xml_assm_internals.h (modified) (1 diff)
- trunk/libsyncml/parser/sml_xml_parse.c (modified) (5 diffs)
- trunk/libsyncml/sml_elements.c (modified) (7 diffs)
- trunk/libsyncml/sml_elements.h (modified) (2 diffs)
- trunk/libsyncml/sml_elements_internals.h (modified) (2 diffs)
- trunk/libsyncml/sml_manager.c (modified) (1 diff)
- trunk/libsyncml/sml_parse.c (modified) (1 diff)
- trunk/libsyncml/sml_parse.h (modified) (2 diffs)
- trunk/libsyncml/sml_session.c (modified) (11 diffs)
- trunk/libsyncml/sml_session.h (modified) (1 diff)
- trunk/libsyncml/sml_session_internals.h (modified) (2 diffs)
- trunk/libsyncml/sml_transport.c (modified) (1 diff)
- trunk/libsyncml/transports/http_client.c (modified) (1 diff)
- trunk/tests/check_manager.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libsyncml/objects/sml_auth.c
r360 r432 54 54 unsigned int buffersize = 0; 55 55 56 if (!cred && !auth->enabled) { 57 smlTrace(TRACE_INTERNAL, "Auth is disabled and no cred given"); 58 auth->state = SML_NO_ERROR; 59 } else if (!cred && auth->enabled && auth->state != SML_AUTH_ACCEPTED) { 60 smlTrace(TRACE_INTERNAL, "Auth is required"); 61 auth->state = SML_ERROR_AUTH_REQUIRED; 56 if (!cred) 57 { 58 if (!auth->enabled) 59 { 60 smlTrace(TRACE_INTERNAL, "Auth is disabled and no cred given"); 61 auth->state = SML_NO_ERROR; 62 } else { 63 /* auth->enabled */ 64 if (auth->state != SML_AUTH_ACCEPTED) 65 { 66 smlTrace(TRACE_INTERNAL, "Auth is required"); 67 auth->state = SML_ERROR_AUTH_REQUIRED; 62 68 63 smlErrorSet(&error, SML_ERROR_AUTH_REQUIRED, "Auth required but not given"); 64 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error); 65 smlErrorDeref(&error); 66 } else if ((!cred && auth->enabled && auth->state == SML_AUTH_ACCEPTED) || \ 67 (cred && !auth->enabled)) { 68 smlTrace(TRACE_INTERNAL, "Auth is already accepted %i", auth->enabled); 69 auth->state = SML_AUTH_ACCEPTED; 69 smlErrorSet(&error, SML_ERROR_AUTH_REQUIRED, "Auth required but not given"); 70 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error); 71 smlErrorDeref(&error); 72 } 73 else 74 { 75 /* auth->state == SML_AUTH_ACCEPTED */ 76 smlTrace(TRACE_INTERNAL, "Auth is already accepted."); 77 auth->state = SML_AUTH_ACCEPTED; 78 } 79 } 70 80 } else { 71 smlTrace(TRACE_INTERNAL, "Input is \"%s\"", cred->data); 72 73 switch (cred->type) { 74 case SML_AUTH_TYPE_BASIC: 75 76 if (!smlBase64Decode(cred->data, &buffer, &buffersize, &error)) 77 goto error; 78 79 smlTrace(TRACE_INTERNAL, "After decode is \"%s\"", buffer); 80 81 char **arr = g_strsplit(buffer, ":", 2); 82 smlSafeCFree(&buffer); 83 84 smlTrace(TRACE_INTERNAL, "Username \"%s\", Password \"%s\"", arr[0], arr[1]); 85 86 if (auth->verifyCallback) { 87 auth->verifyCallback(auth, arr[0], arr[1], auth->verifyCallbackUserdata, &auth->state); 81 /* cred available */ 82 smlTrace(TRACE_INTERNAL, "Cred is \"%s\"", cred->data); 83 if (!auth->enabled) 84 { 85 smlTrace(TRACE_INTERNAL, "Cred received but unwanted"); 86 auth->state = SML_AUTH_ACCEPTED; 87 } else { 88 /* auth->enabled */ 89 if (auth->verifyCallback) 90 { 91 /* The callback needs the following stuff: 92 * Chal 93 * Cred 94 * LocName(username) 95 */ 96 if (auth->verifyCallback(session->chal, cred, 97 smlLocationGetName(session->source), 98 auth->verifyCallbackUserdata, &error)) 99 { 100 auth->state = SML_AUTH_ACCEPTED; 88 101 } else { 89 smlTrace(TRACE_INTERNAL, "No verify callback set"); 102 smlErrorSet(&error, SML_ERROR_AUTH_REJECTED, 103 "Auth rejected for username %s", 104 smlLocationGetName(session->source)); 105 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error); 106 smlErrorDeref(&error); 90 107 auth->state = SML_ERROR_AUTH_REJECTED; 91 108 } 92 93 if (auth->state == SML_ERROR_AUTH_REJECTED) { 94 smlErrorSet(&error, SML_ERROR_AUTH_REJECTED, "Auth rejected for username %s", arr[0]); 95 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error); 96 smlErrorDeref(&error); 97 } 98 99 g_strfreev(arr); 100 101 break; 102 case SML_AUTH_TYPE_MD5: 103 break; 104 default: 105 smlErrorSet(&error, SML_ERROR_GENERIC, "Unknown auth format"); 106 goto error; 109 } else { 110 smlTrace(TRACE_INTERNAL, "No verify callback set"); 111 auth->state = SML_ERROR_AUTH_REJECTED; 112 } 107 113 } 108 114 } … … 132 138 smlErrorDeref(&error); 133 139 return; 140 } 141 142 char *smlAuthGetCredString( 143 SmlAuthType type, 144 const char *username, 145 const char *password, 146 const char *b64_nonce, 147 SmlError **error) 148 { 149 smlTrace(TRACE_ENTRY, "%s", __func__); 150 char *cred = NULL; 151 152 switch (type) { 153 case SML_AUTH_TYPE_BASIC: 154 155 smlTrace(TRACE_INTERNAL, "%s - SML_AUTH_TYPE_BASIC", __func__); 156 char *plain = g_strjoin(":", username, password, NULL); 157 if (!smlBase64EncodeBinary(plain, strlen(plain), &cred, error)) 158 { 159 smlTrace(TRACE_INTERNAL, "%s - base64 failed", __func__); 160 smlSafeCFree(&plain); 161 goto error; 162 } 163 smlSafeCFree(&plain); 164 165 break; 166 case SML_AUTH_TYPE_MD5: 167 168 smlTrace(TRACE_INTERNAL, "%s - SML_AUTH_TYPE_MD5", __func__); 169 /* How does syncml:auth-md5 works? 170 * 171 * base64( 172 * md5( 173 * base64( 174 * md5( 175 * username + ":" + password 176 * ) 177 * ) + 178 * ":" + nonce 179 * ) 180 * ) 181 */ 182 183 /* Let's determine the string for the comparison. */ 184 ; 185 char *auth = g_strjoin (":", username, password, NULL); 186 unsigned char digest[16]; 187 smlMD5GetDigest (auth, strlen(auth), digest); 188 smlSafeCFree(&auth); 189 if (!smlBase64EncodeBinary(digest, 16, &cred, error)) 190 { 191 smlTrace(TRACE_INTERNAL, "%s - base64 failed", __func__); 192 if (cred) 193 smlSafeCFree(&cred); 194 goto error; 195 } 196 auth = g_strjoin (":", cred, b64_nonce, NULL); 197 smlSafeCFree(&cred); 198 smlMD5GetDigest (auth, strlen(auth), digest); 199 smlSafeCFree(&auth); 200 if (!smlBase64EncodeBinary(digest, 16, &cred, error)) 201 { 202 smlTrace(TRACE_INTERNAL, "%s - base64 failed %s", __func__, smlErrorPrint(error)); 203 if (cred) 204 smlSafeCFree(&cred); 205 goto error; 206 } 207 208 break; 209 default: 210 smlTrace(TRACE_ERROR, "%s - unknown authentication type", __func__); 211 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown auth format"); 212 goto error; 213 } 214 215 smlTrace(TRACE_EXIT, "%s", __func__); 216 return cred; 217 error: 218 smlTrace(TRACE_EXIT_ERROR, "%s - cannot create credential string"); 219 if (*error == NULL) 220 smlErrorSet(error, SML_ERROR_GENERIC, "Cannot create credential string for user %s.", 221 username); 222 return NULL; 223 } 224 225 SmlBool smlAuthVerify(SmlChal *chal, SmlCred *cred, const char *username, const char *password, SmlError **error) 226 { 227 smlTrace(TRACE_ENTRY, "%s", __func__); 228 229 /* If no Chal is send to the client but the client offers a Cred 230 * then we accept it. Theoretically this is not 100% perfect if 231 * syncml:auth-md5 is used but if the client offers it then we 232 * accept it because some implementations like UIQ 3 are broken 233 * and implemented the protocol in a wrong way if we answer with 234 * error 407 and a fresh nonce. 235 * 236 * SECURITY NOTE: This part of the code makes libsyncml vulnerable 237 * SECURITY NOTE: against replay attacks. 238 * 239 */ 240 if (chal && chal->type != cred->type) 241 { 242 if (chal->type == SML_AUTH_TYPE_BASIC && 243 cred->type == SML_AUTH_TYPE_MD5) 244 { 245 /* This is an upgrade to more security. 246 * So it is acceptable. 247 */ 248 smlTrace(TRACE_INTERNAL, "%s - replace syncml:auth-basic by syncml:auth-md5", __func__); 249 } else { 250 /* This is a security event. */ 251 smlErrorSet(error, SML_ERROR_AUTH_REJECTED, 252 "The type of the authentication was changed to a lower security level."); 253 goto error; 254 } 255 } 256 smlTrace(TRACE_INTERNAL, "%s - authentication security policy ok", __func__); 257 258 char *wanted = NULL; 259 switch (cred->type) { 260 case SML_AUTH_TYPE_BASIC: 261 smlTrace(TRACE_INTERNAL, "%s - SML_AUTH_TYPE_BASIC", __func__); 262 wanted = smlAuthGetCredString(SML_AUTH_TYPE_BASIC, username, password, NULL, error); 263 break; 264 case SML_AUTH_TYPE_MD5: 265 smlTrace(TRACE_INTERNAL, "%s - SML_AUTH_TYPE_MD5", __func__); 266 if (chal) 267 wanted = smlAuthGetCredString( 268 SML_AUTH_TYPE_MD5, 269 username, password, 270 chal->nonce_b64, error); 271 else 272 wanted = smlAuthGetCredString( 273 SML_AUTH_TYPE_MD5, 274 username, password, 275 "", error); 276 break; 277 default: 278 smlTrace(TRACE_ERROR, "%s - unknown authentication type", __func__); 279 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown auth format"); 280 goto error; 281 } 282 smlTrace(TRACE_INTERNAL, "%s - credential string calculated", __func__); 283 284 /* compare the authentication string */ 285 if (strcmp(wanted, cred->data)) 286 { 287 smlTrace(TRACE_INTERNAL, "%s - credentials mismatch", __func__); 288 smlSafeCFree(&wanted); 289 goto error; 290 } 291 smlSafeCFree(&wanted); 292 293 smlTrace(TRACE_EXIT, "%s", __func__); 294 return TRUE; 295 error: 296 smlTrace(TRACE_EXIT_ERROR, "%s - auth rejected"); 297 if (*error == NULL) 298 smlErrorSet(error, SML_ERROR_AUTH_REJECTED, "Authentication rejected for username %s.", 299 username); 300 return FALSE; 134 301 } 135 302 … … 210 377 211 378 if (code == SML_ERROR_AUTH_REJECTED || code == SML_ERROR_AUTH_REQUIRED) { 212 reply->chal = sml TryMalloc0(sizeof(SmlChal), error);379 reply->chal = smlChalNew(code, error); 213 380 if (!reply->chal) 214 381 goto error_free_reply; 215 216 reply->chal->format = SML_FORMAT_TYPE_BASE64; 217 reply->chal->type = SML_AUTH_TYPE_BASIC; 382 session->chal = reply->chal; 383 smlChalRef(session->chal); 218 384 } 219 385 trunk/libsyncml/objects/sml_auth.h
r101 r432 23 23 24 24 typedef struct SmlAuthenticator SmlAuthenticator; 25 typedef void (* SmlAuthVerifyCb)(SmlAuthenticator *auth, const char *username, const char *password, void *userdata, SmlErrorType *reply);25 typedef SmlBool (* SmlAuthVerifyCb)(SmlChal *chal, SmlCred *cred, const char *username, void *userdata, SmlError **error); 26 26 27 27 SmlAuthenticator *smlAuthNew(SmlError **error); … … 34 34 SmlBool smlAuthIsEnabled(SmlAuthenticator *auth); 35 35 36 /* This can be used from within the SmlAuthVerifyCb to do the authentication itself. */ 37 SmlBool smlAuthVerify(SmlChal *chal, SmlCred *cred, const char *username, const char *password, SmlError **error); 38 36 39 #endif //_SML_AUTH_H_ trunk/libsyncml/objects/sml_auth_internals.h
r68 r432 22 22 #define _SML_AUTH_INTERNALS_H_ 23 23 24 #include "sml_auth.h" 25 24 26 struct SmlAuthenticator { 25 27 SmlErrorType state; … … 29 31 }; 30 32 33 char *smlAuthGetCredString( 34 SmlAuthType type, 35 const char *username, 36 const char *password, 37 const char *b64_nonce, 38 SmlError **error); 39 31 40 #endif //_SML_AUTH_INTERNALS_H_ trunk/libsyncml/parser/sml_xml_assm.c
r427 r432 741 741 if (!smlLocationAssemble(session->source, assm, SML_ELEMENT_SOURCE, error)) 742 742 goto error_free_writer; 743 744 if (session->cred != NULL) { 743 744 /* The credentials must be present and calculated for the correct 745 * authentication schema (e.g. syncml:auth-basic or syncml:auth-md5). 746 */ 747 if (session->cred != NULL && session->cred->data != NULL) { 745 748 if (!smlCredAssemble(session->cred, assm, error)) 746 749 goto error_free_writer; … … 1171 1174 goto error; 1172 1175 1173 switch (status->c red->type) {1176 switch (status->chal->type) { 1174 1177 case SML_AUTH_TYPE_BASIC: 1175 1178 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF, SML_AUTH_BASIC, error)) … … 1178 1181 case SML_AUTH_TYPE_MD5: 1179 1182 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF, SML_AUTH_MD5, error)) 1183 goto error; 1184 if (status->chal->nonce_b64 && 1185 !_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_NEXTNONCE, SML_NAMESPACE_METINF, status->chal->nonce_b64, error)) 1180 1186 goto error; 1181 1187 break; … … 1287 1293 1288 1294 flush_list(assm->commands); 1295 flush_list(assm->last_commands); 1289 1296 1290 1297 g_mutex_free(assm->mutex); … … 1327 1334 g_list_free(s2); 1328 1335 1329 /* Remove all commands that are complete */ 1330 flush_list(assm->commands); 1336 /* Remove all commands that are complete 1337 * Perhaps more correct remove all commands from the last message. 1338 * The actual commands are cached to support error 407 handling. 1339 * (AUTHENTICATION_REQUIRED) 1340 */ 1341 if (assm->last_commands) 1342 flush_list(assm->last_commands); 1343 assm->last_commands = assm->commands; 1331 1344 assm->commands = NULL; 1332 1345 … … 1724 1737 functions->next_cmdref = (SmlAssemblerNextCmdRefFunction)smlXmlAssemblerNextCmdRef; 1725 1738 functions->flush = (SmlAssemblerFlushFunction)smlXmlAssemblerFlush; 1739 functions->restore_cmds = (SmlAssemblerRestoreCommandsFunction)smlXmlAssemblerRestoreCommands; 1726 1740 1727 1741 smlTrace(TRACE_EXIT, "%s: %p", __func__, assm); … … 2313 2327 } 2314 2328 2329 void smlXmlAssemblerRestoreCommands(SmlXmlAssembler *assm) 2330 { 2331 smlTrace(TRACE_ENTRY, "%s", __func__); 2332 smlAssert(assm->commands == NULL); 2333 2334 assm->commands = assm->last_commands; 2335 assm->last_commands = NULL; 2336 2337 smlTrace(TRACE_EXIT, "%s", __func__); 2338 } 2339 2315 2340 /*@}*/ trunk/libsyncml/parser/sml_xml_assm.h
r324 r432 40 40 SmlBool smlXmlDevInfAssemble(SmlDevInf *devinf, SmlDevInfVersion version, char **data, unsigned int *size, SmlError **error); 41 41 42 /* This is necessary if the first message results in an error 407. 43 * This error means authentication required. 44 * After such an error the previous commands must be sent again. 45 */ 46 void smlXmlAssemblerRestoreCommands(SmlXmlAssembler *assm); 47 42 48 #endif //_SML_XML_ASSM_H_ trunk/libsyncml/parser/sml_xml_assm_internals.h
r324 r432 62 62 GList *statuses; 63 63 GList *commands; 64 GList *last_commands; 64 65 GList *parent_commands; 65 66 GList *parent_buffers; trunk/libsyncml/parser/sml_xml_parse.c
r427 r432 819 819 char *format = NULL; 820 820 char *type = NULL; 821 822 SmlChal *chal = smlTryMalloc0(sizeof(SmlChal), error); 823 if (!chal) 824 goto error; 821 char *nonce = NULL; 825 822 826 823 while (1) { 827 824 if (!_smlXmlParserStep(parser)) { 828 825 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes"); 829 goto error _free_chal;826 goto error; 830 827 } 831 828 … … 835 832 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) { 836 833 smlErrorSet(error, SML_ERROR_GENERIC, "Not a start node"); 837 goto error _free_chal;834 goto error; 838 835 } 839 836 840 837 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META)) { 841 if (!_smlChalMetaParse(parser, &format, &type, & chal->nonce, error))842 goto error _free_chal;838 if (!_smlChalMetaParse(parser, &format, &type, &nonce, error)) 839 goto error; 843 840 } else { 844 841 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node %s", xmlTextReaderConstName(parser->reader)); 845 goto error_free_chal; 846 } 847 } 848 849 if (!format || !strcmp(format, SML_BASE64)) { 850 chal->format = SML_FORMAT_TYPE_BASE64; 851 } else { 842 goto error; 843 } 844 } 845 846 if (format && strcmp(format, SML_BASE64)) { 852 847 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown format"); 853 goto error_free_chal; 854 } 855 848 goto error; 849 } 850 851 SmlAuthType auth; 856 852 if (!type || !strcmp(type, SML_AUTH_BASIC)) { 857 chal->type= SML_AUTH_TYPE_BASIC;853 auth = SML_AUTH_TYPE_BASIC; 858 854 } else if (!strcmp(type, SML_AUTH_MD5)) { 859 chal->type= SML_AUTH_TYPE_MD5;855 auth = SML_AUTH_TYPE_MD5; 860 856 } else { 861 857 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown type"); 862 goto error _free_chal;863 } 864 858 goto error; 859 } 860 865 861 if (format) 866 862 smlSafeCFree(&format); 867 863 if (type) 868 864 smlSafeCFree(&type); 869 865 866 SmlChal *chal = NULL; 867 if (nonce || auth == SML_AUTH_TYPE_MD5) 868 chal = smlChalNewFromBase64(auth, nonce, error); 869 else 870 chal = smlChalNew(auth, error); 871 if (!chal) 872 goto error; 873 874 if (nonce) 875 smlSafeCFree(&nonce); 876 870 877 smlTrace(TRACE_EXIT, "%s: %p", __func__, chal); 871 878 return chal; 872 879 873 error_free_chal:874 smlChalFree(chal);875 880 error: 876 881 if (format) … … 878 883 if (type) 879 884 smlSafeCFree(&type); 885 if (nonce) 886 smlSafeCFree(&nonce); 880 887 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error)); 881 888 return NULL; … … 1759 1766 char *locURI = NULL; 1760 1767 SmlItem *item = NULL; 1761 SmlChal *chal = NULL;1762 1768 1763 1769 /* Lets check if the next node is a command node */ … … 1884 1890 goto error_free_status; 1885 1891 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CHAL)) { 1886 chal = _smlChalParse(parser, error);1887 if (! chal)1892 (*status)->chal = _smlChalParse(parser, error); 1893 if (!(*status)->chal) 1888 1894 goto error_free_status; 1889 1895 } else { trunk/libsyncml/sml_elements.c
r412 r432 581 581 { 582 582 smlTrace(TRACE_ENTRY, "%s(%d, %s, %p)", __func__, type, username, error); 583 char *data = NULL; 584 SmlFormatType format = SML_FORMAT_TYPE_BASE64; 585 586 // build plain data 587 if (type == SML_AUTH_TYPE_BASIC) { 588 char *plain = g_strjoin(":", username, password, NULL); 589 data = g_base64_encode((const unsigned char *) plain, strlen(plain)); 590 smlSafeCFree(&plain); 591 } else if (type == SML_AUTH_TYPE_MD5) { 592 char *plain = g_strjoin(":", username, password, NULL); 593 unsigned char digest[16]; 594 smlMD5GetDigest(plain, strlen(plain), digest); 595 smlSafeCFree(&plain); 596 data = smlMD5ToString(digest, NULL); 597 // digest must not be freed because it is a char array 598 } else { 599 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown type - %s (%s).", type, __func__); 600 goto error; 601 } 602 603 // the username is sometimes required as location name in the source 604 // the username is readable from data => OPTIONAL (e.g. syncml:auth-basic) 605 // the username is not readable from data => REQUIRED (e.g. syncml:auth-md5) 606 SmlCred *cred = smlCredNew(type, format, data, username, error); 607 smlSafeCFree(&data); 583 584 SmlCred *cred = smlTryMalloc0(sizeof(SmlCred), error); 585 if (!cred) 586 goto error; 587 588 cred->format = SML_FORMAT_TYPE_BASE64; 589 cred->type = type; 590 cred->username = g_strdup(username); 591 cred->password = g_strdup(password); 608 592 609 593 smlTrace(TRACE_EXIT, "%s", __func__); 610 594 return cred; 611 595 error: 612 if ( data)613 smlSafe CFree(&data);596 if (cred) 597 smlSafeFree((gpointer *)&cred); 614 598 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error)); 615 599 return NULL; … … 632 616 cred->data = g_strdup(data); 633 617 if (username) 634 cred-> locName = g_strdup(username);618 cred->username = g_strdup(username); 635 619 else 636 cred-> locName = NULL;620 cred->username = NULL; 637 621 cred->refCount = 1; 638 622 … … 642 626 if (cred->data) 643 627 smlSafeCFree(&(cred->data)); 644 if (cred-> locName)645 smlSafeCFree(&(cred-> locName));628 if (cred->username) 629 smlSafeCFree(&(cred->username)); 646 630 if (cred) 647 631 smlSafeFree((gpointer *)&cred); … … 650 634 } 651 635 652 SmlCred *smlCredRef(SmlCred *cred)636 void smlCredRef(SmlCred *cred) 653 637 { 654 638 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, cred); … … 658 642 659 643 smlTrace(TRACE_EXIT, "%s: New refcount: %i", __func__, cred->refCount); 660 return cred;661 644 } 662 645 … … 671 654 if (cred->data) 672 655 smlSafeCFree(&(cred->data)); 673 if (cred->locName) 674 smlSafeCFree(&(cred->locName)); 656 if (cred->username) 657 smlSafeCFree(&(cred->username)); 658 if (cred->password) 659 smlSafeCFree(&(cred->password)); 675 660 676 661 smlSafeFree((gpointer *)&cred); … … 686 671 } 687 672 673 SmlChal *smlChalNew(SmlAuthType type, SmlError **error) 674 { 675 smlTrace(TRACE_ENTRY, "%s", __func__); 676 SmlChal *chal = NULL; 677 678 /* allocate memory */ 679 smlAssert(type != SML_AUTH_TYPE_UNKNOWN); 680 chal = smlTryMalloc0(sizeof(SmlChal), error); 681 if (!chal) 682 goto error; 683 chal->refCount = 1; 684 chal->type = type; 685 chal->format = SML_FORMAT_TYPE_BASE64; 686 687 if (type == SML_AUTH_TYPE_MD5) 688 { 689 /* A nonce must be generated for this type. 690 * minimum strength: 2^128 691 * strength per byte: 2^6 - 2 > 2^5 692 * needed bytes: 128 / 5 < 130 / 5 = 26 693 */ 694 chal->nonce_plain = smlRandStr(26, TRUE); 695 chal->nonce_length = 26; 696 if (!smlBase64EncodeBinary(chal->nonce_plain, chal->nonce_length, 697 &(chal->nonce_b64), error)) 698 goto error; 699 } 700 701 smlTrace(TRACE_EXIT, "%s", __func__); 702 return chal; 703 error: 704 if (chal->nonce_plain) 705 smlSafeCFree(&(chal->nonce_plain)); 706 if (chal->nonce_b64) 707 smlSafeCFree(&(chal->nonce_b64)); 708 if (chal) 709 smlSafeFree((gpointer *)&chal); 710 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error)); 711 return NULL; 712 } 713 714 SmlChal *smlChalNewFromBinary( 715 SmlAuthType type, 716 const char *nonce, 717 size_t length, 718 SmlError **error) 719 { 720 smlTrace(TRACE_ENTRY, "%s", __func__); 721 SmlChal *chal = NULL; 722 723 /* only syncml:auth-md5 needs a nonce */ 724 smlAssert(type == SML_AUTH_TYPE_MD5); 725 726 /* allocate memory */ 727 chal = smlTryMalloc0(sizeof(SmlChal), error); 728 if (!chal) 729 goto error; 730 chal->refCount = 1; 731 732 /* copy nonce */ 733 chal->type = SML_AUTH_TYPE_MD5; 734 chal->format = SML_FORMAT_TYPE_BASE64; 735 chal->nonce_plain = g_strndup(nonce, length); 736 chal->nonce_length = length; 737 738 /* create base64 nonce */ 739 if (!smlBase64EncodeBinary(nonce, length, &(chal->nonce_b64), error)) 740 goto error; 741 742 smlTrace(TRACE_EXIT, "%s", __func__); 743 return chal; 744 error: 745 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error)); 746 return NULL; 747 } 748 749 SmlChal *smlChalNewFromBase64( 750 SmlAuthType type, 751 const char *nonce, 752 SmlError **error) 753 { 754 smlTrace(TRACE_ENTRY, "%s", __func__); 755 SmlChal *chal = NULL; 756 757 /* only syncml:auth-md5 needs a nonce */ 758 smlAssert(type == SML_AUTH_TYPE_MD5); 759 760 /* allocate memory */ 761 chal = smlTryMalloc0(sizeof(SmlChal), error); 762 if (!chal) 763 goto error; 764 chal->refCount = 1; 765 766 /* copy nonce */ 767 chal->type = SML_AUTH_TYPE_MD5; 768 chal->format = SML_FORMAT_TYPE_BASE64; 769 chal->nonce_b64 = g_strdup(nonce); 770 771 /* create binary nonce */ 772 if (!smlBase64Decode(nonce, &(chal->nonce_plain), &(chal->nonce_length), error)) 773 goto error; 774 775 smlTrace(TRACE_EXIT, "%s", __func__); 776 return chal; 777 error: 778 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error)); 779 return NULL; 780 } 781 782 void smlChalRef(SmlChal *chal) 783 { 784 smlTrace(TRACE_ENTRY, "%s", __func__); 785 smlAssert(chal); 786 787 g_atomic_int_inc(&(chal->refCount)); 788 789 smlTrace(TRACE_EXIT, "%s: New refcount: %i", __func__, chal->refCount); 790 } 791 792 void smlChalUnref(SmlChal *chal) 793 { 794 smlTrace(TRACE_ENTRY, "%s", __func__); 795 smlAssert(chal); 796 797 if (g_atomic_int_dec_and_test(&(chal->refCount))) { 798 smlTrace(TRACE_INTERNAL, "Refcount == 0!"); 799 800 if (chal->nonce_plain) 801 smlSafeCFree(&(chal->nonce_plain)); 802 803 if (chal->nonce_b64) 804 smlSafeCFree(&(chal->nonce_b64)); 805 806 smlSafeFree((gpointer *)&chal); 807 } 808 809 smlTrace(TRACE_EXIT, "%s", __func__); 810 } 811 812 /* FIXME: DEPRECATED */ 688 813 void smlChalFree(SmlChal *chal) 689 814 { 690 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, chal); 691 smlAssert(chal); 692 693 if (chal->nonce) 694 smlSafeCFree(&(chal->nonce)); 695 696 smlSafeFree((gpointer *)&chal); 697 698 smlTrace(TRACE_EXIT, "%s", __func__); 815 smlChalUnref(chal); 699 816 } 700 817 trunk/libsyncml/sml_elements.h
r338 r432 37 37 SmlCred *smlCredNewAuth(SmlAuthType type, const char *username, const char *password, SmlError **error); 38 38 SmlCred *smlCredNew(SmlAuthType type, SmlFormatType format, const char *data, const char*username, SmlError **error); 39 SmlCred *smlCredRef(SmlCred *cred);39 void smlCredRef(SmlCred *cred); 40 40 void smlCredUnref(SmlCred *cred); 41 41 void smlCredFree(SmlCred *cred) LIBSYNCML_DEPRECATED; /* expire date: 20090120 */ … … 62 62 void smlHeade
