22 #include <libsyncml/syncml.h>
25 #include <libsyncml/syncml_internals.h>
26 #include "sml_auth_internals.h"
27 #include <libsyncml/sml_session_internals.h>
28 #include <libsyncml/sml_elements_internals.h>
29 #include <libsyncml/sml_command_internals.h>
30 #include "libsyncml/sml_error_internals.h"
40 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, status, userdata);
42 smlTrace(TRACE_EXIT,
"%s", __func__);
47 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p)", __func__, session, header, cred, userdata);
54 if (session->sessionType == SML_SESSION_TYPE_CLIENT) {
59 g_warning(
"This is an OMA DS client. An OMA DS client should not use this authentication callback.");
60 smlTrace(TRACE_INTERNAL,
"%s: This is an OMA DS client and so auth is not supported.", __func__);
61 auth->state = SML_NO_ERROR;
64 "%s: authentication is enabled but this is an OMA DS client.");
70 smlTrace(TRACE_INTERNAL,
"%s: Auth is disabled and no cred given", __func__);
71 auth->state = SML_NO_ERROR;
74 if (auth->state != SML_AUTH_ACCEPTED)
82 smlTrace(TRACE_INTERNAL,
"%s: Auth is required", __func__);
83 auth->state = SML_ERROR_AUTH_REQUIRED;
84 session->authenticate = TRUE;
89 smlTrace(TRACE_INTERNAL,
"%s: Auth is already accepted.", __func__);
90 auth->state = SML_AUTH_ACCEPTED;
95 smlTrace(TRACE_INTERNAL,
"%s: Cred is \"%s\"", __func__, VA_STRING(cred->data));
98 smlTrace(TRACE_INTERNAL,
"%s: Cred received but unwanted", __func__);
99 auth->state = SML_AUTH_ACCEPTED;
102 if (auth->verifyCallback)
109 if (auth->verifyCallback(session->chal, cred,
110 smlLocationGetName(session->source),
111 auth->verifyCallbackUserdata, &error))
113 auth->state = SML_AUTH_ACCEPTED;
116 "Auth rejected for username %s",
117 smlLocationGetName(session->source));
118 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error);
119 smlErrorDeref(&error);
120 auth->state = SML_ERROR_AUTH_REJECTED;
123 smlTrace(TRACE_INTERNAL,
"%s: No verify callback set", __func__);
124 auth->state = SML_ERROR_AUTH_REJECTED;
129 if (auth->state == SML_ERROR_AUTH_REJECTED) {
130 smlTrace(TRACE_INTERNAL,
"%s: Ending session due to wrong / missing creds", __func__);
134 reply = _smlAuthHeaderReply(session, auth->state, auth->type, &error);
139 smlStatusUnref(reply);
143 smlStatusUnref(reply);
145 if (!session->established && !session->end &&
146 !session->authenticate &&
147 session->sessionType == SML_SESSION_TYPE_SERVER)
149 session->established = TRUE;
150 smlSessionDispatchEvent(
151 session, SML_SESSION_EVENT_ESTABLISHED,
152 NULL, NULL, NULL, NULL);
155 smlTrace(TRACE_EXIT,
"%s", __func__);
158 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error);
160 smlErrorDeref(&error);
164 char *smlAuthGetCredString(
166 const char *username,
167 const char *password,
168 const char *b64_nonce,
171 smlTrace(TRACE_ENTRY,
"%s", __func__);
176 case SML_AUTH_TYPE_BASIC:
178 smlTrace(TRACE_INTERNAL,
"%s - SML_AUTH_TYPE_BASIC", __func__);
179 char *plain = g_strjoin(
":", username, password, NULL);
180 cred = g_base64_encode((
unsigned char *) plain, strlen(plain));
183 "The syncml:auth-basic credential cannot be base64 encoded.");
184 smlSafeCFree(&plain);
187 smlSafeCFree(&plain);
190 case SML_AUTH_TYPE_MD5:
192 smlTrace(TRACE_INTERNAL,
"%s - SML_AUTH_TYPE_MD5", __func__);
209 char *auth = g_strjoin (
":", username, password, NULL);
210 unsigned char digest[16];
211 smlMD5GetDigest (auth, strlen(auth), digest);
213 cred = g_base64_encode(digest, 16);
216 "The username:password part of the syncml:auth-md5 "\
217 "credential cannot be base64 encoded.");
220 auth = g_strjoin (
":", cred, b64_nonce, NULL);
222 smlMD5GetDigest (auth, strlen(auth), digest);
224 cred = g_base64_encode(digest, 16);
227 "The complete syncml:auth-md5 credential cannot be base64 encoded.");
233 smlTrace(TRACE_ERROR,
"%s - unknown authentication type", __func__);
234 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown auth format");
238 smlTrace(TRACE_EXIT,
"%s", __func__);
241 smlTrace(TRACE_EXIT_ERROR,
"%s - cannot create credential string");
243 smlErrorSet(error, SML_ERROR_GENERIC,
"Cannot create credential string for user %s.",
248 SmlBool smlAuthVerify(
SmlChal *chal,
SmlCred *cred,
const char *username,
const char *password,
SmlError **error)
250 smlTrace(TRACE_ENTRY,
"%s", __func__);
264 if (chal && chal->type != cred->type)
266 if (chal->type == SML_AUTH_TYPE_BASIC &&
267 cred->type == SML_AUTH_TYPE_MD5)
272 smlTrace(TRACE_INTERNAL,
"%s - replace syncml:auth-basic by syncml:auth-md5", __func__);
276 "The type of the authentication was changed to a lower security level.");
280 smlTrace(TRACE_INTERNAL,
"%s - authentication security policy ok", __func__);
283 switch (cred->type) {
284 case SML_AUTH_TYPE_BASIC:
285 smlTrace(TRACE_INTERNAL,
"%s - SML_AUTH_TYPE_BASIC", __func__);
286 wanted = smlAuthGetCredString(SML_AUTH_TYPE_BASIC, username, password, NULL, error);
288 case SML_AUTH_TYPE_MD5:
289 smlTrace(TRACE_INTERNAL,
"%s - SML_AUTH_TYPE_MD5", __func__);
291 wanted = smlAuthGetCredString(
294 chal->nonce_b64, error);
296 wanted = smlAuthGetCredString(
302 smlTrace(TRACE_ERROR,
"%s - unknown authentication type", __func__);
303 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown auth format");
306 smlTrace(TRACE_INTERNAL,
"%s - credential string calculated", __func__);
309 if (strcmp(wanted, cred->data))
311 smlTrace(TRACE_INTERNAL,
"%s - credentials mismatch", __func__);
312 smlSafeCFree(&wanted);
315 smlSafeCFree(&wanted);
317 smlTrace(TRACE_EXIT,
"%s", __func__);
320 smlTrace(TRACE_EXIT_ERROR,
"%s - auth rejected");
322 smlErrorSet(error, SML_ERROR_AUTH_REJECTED,
"Authentication rejected for username %s.",
329 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, error);
335 auth->enabled = TRUE;
336 auth->state = SML_ERROR_AUTH_REQUIRED;
338 smlTrace(TRACE_EXIT,
"%s: %p", __func__, auth);
349 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, auth);
352 smlSafeFree((gpointer *)&auth);
354 smlTrace(TRACE_EXIT,
"%s", __func__);
359 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, auth, manager, error);
364 smlManagerRegisterHeaderHandler(manager, _header_callback, _status_callback, auth);
366 smlTrace(TRACE_EXIT,
"%s", __func__);
372 smlTrace(TRACE_ENTRY,
"%s(%p, %i)", __func__, auth, type);
377 smlTrace(TRACE_EXIT,
"%s", __func__);
386 g_warning(
"SmlAuthType of smlAuthHeaderReply is used as SmlErrorType.");
387 return _smlAuthHeaderReply(session, (SmlErrorType) code, SML_AUTH_TYPE_BASIC, error);
396 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %i, %p)", __func__, session, code, auth, error);
403 smlTrace(TRACE_INTERNAL,
"%s: SourceRef: %s --> TargetRef: %s",
404 __func__, VA_STRING(session->target->locURI), VA_STRING(session->source->locURI));
405 SmlStatus *reply = smlStatusNew(code, 0, session->lastReceivedMessageID, session->target, session->source, SML_COMMAND_TYPE_HEADER, error);
409 if (code == SML_ERROR_AUTH_REJECTED ||
410 code == SML_ERROR_AUTH_REQUIRED) {
411 reply->chal = smlChalNew(auth, error);
413 goto error_free_reply;
414 session->chal = reply->chal;
415 smlChalRef(session->chal);
418 smlTrace(TRACE_EXIT,
"%s: %p", __func__, reply);
422 smlStatusUnref(reply);
428 void smlAuthSetVerifyCallback(
SmlAuthenticator *auth, SmlAuthVerifyCb callback,
void *userdata)
430 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, auth, callback, userdata);
432 auth->verifyCallback = callback;
433 auth->verifyCallbackUserdata = userdata;
434 smlTrace(TRACE_EXIT,
"%s", __func__);
439 smlTrace(TRACE_ENTRY,
"%s(%p, %i)", __func__, auth, enabled);
442 auth->enabled = enabled;
444 smlTrace(TRACE_EXIT,
"%s", __func__);
449 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, auth);
452 smlTrace(TRACE_EXIT,
"%s - %u", __func__, auth->enabled);
453 return auth->enabled;
458 smlTrace(TRACE_ENTRY,
"%s(%p, %i)", __func__, auth, type);
460 smlAssert(type != SML_AUTH_TYPE_UNKNOWN);
464 smlTrace(TRACE_EXIT,
"%s", __func__);