Skip to content

Commit 113a29b

Browse files
committed
CDRIVER-2000 Implement sasl logger and fail early on unsupported mechanism
1 parent 844d288 commit 113a29b

File tree

4 files changed

+78
-13
lines changed

4 files changed

+78
-13
lines changed

src/mongoc/mongoc-cluster-sasl.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ _mongoc_cluster_auth_node_sasl (mongoc_cluster_t *cluster,
174174
_mongoc_sasl_init (&sasl);
175175

176176
if ((mechanism = mongoc_uri_get_auth_mechanism (cluster->uri))) {
177-
_mongoc_sasl_set_mechanism (&sasl, mechanism);
177+
if (!_mongoc_sasl_set_mechanism (&sasl, mechanism, error)) {
178+
goto failure;
179+
}
178180
}
179181

180182
_mongoc_sasl_set_pass (&sasl, mongoc_uri_get_password (cluster->uri));

src/mongoc/mongoc-init.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
#ifdef MONGOC_ENABLE_SASL_CYRUS
4747
#include <sasl/sasl.h>
48+
#include "mongoc-sasl-private.h"
4849

4950
static void *
5051
mongoc_sasl_mutex_alloc (void)
@@ -88,6 +89,12 @@ mongoc_sasl_mutex_free (void *mutex)
8889

8990
static MONGOC_ONCE_FUN (_mongoc_do_init)
9091
{
92+
#ifdef MONGOC_ENABLE_SASL_CYRUS
93+
int status;
94+
sasl_callback_t callbacks[] = {
95+
{SASL_CB_LOG, SASL_CALLBACK_FN (_mongoc_sasl_log), NULL},
96+
{SASL_CB_LIST_END}};
97+
#endif
9198
#ifdef MONGOC_ENABLE_SSL_OPENSSL
9299
_mongoc_openssl_init ();
93100
#elif defined(MONGOC_ENABLE_SSL_LIBRESSL)
@@ -106,8 +113,8 @@ static MONGOC_ONCE_FUN (_mongoc_do_init)
106113
mongoc_sasl_mutex_unlock,
107114
mongoc_sasl_mutex_free);
108115

109-
/* TODO: logging callback? */
110-
sasl_client_init (NULL);
116+
status = sasl_client_init (callbacks);
117+
BSON_ASSERT (status == SASL_OK);
111118
#endif
112119

113120
_mongoc_counters_init ();

src/mongoc/mongoc-sasl-private.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,28 @@ struct _mongoc_sasl_t {
4848
};
4949

5050

51+
#ifndef SASL_CALLBACK_FN
52+
#define SASL_CALLBACK_FN(_f) ((int (*) (void)) (_f))
53+
#endif
54+
5155
void
5256
_mongoc_sasl_init (mongoc_sasl_t *sasl);
5357
void
5458
_mongoc_sasl_set_pass (mongoc_sasl_t *sasl, const char *pass);
5559
void
5660
_mongoc_sasl_set_user (mongoc_sasl_t *sasl, const char *user);
57-
void
58-
_mongoc_sasl_set_mechanism (mongoc_sasl_t *sasl, const char *mechanism);
61+
bool
62+
_mongoc_sasl_set_mechanism (mongoc_sasl_t *sasl,
63+
const char *mechanism,
64+
bson_error_t *error);
5965
void
6066
_mongoc_sasl_set_service_name (mongoc_sasl_t *sasl, const char *service_name);
6167
void
6268
_mongoc_sasl_set_service_host (mongoc_sasl_t *sasl, const char *service_host);
6369
void
6470
_mongoc_sasl_set_properties (mongoc_sasl_t *sasl, const mongoc_uri_t *uri);
71+
int
72+
_mongoc_sasl_log (mongoc_sasl_t *sasl, int level, const char *message);
6573
void
6674
_mongoc_sasl_destroy (mongoc_sasl_t *sasl);
6775
bool

src/mongoc/mongoc-sasl.c

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,54 @@
2525
#include "mongoc-util-private.h"
2626
#include "mongoc-trace-private.h"
2727

28+
#undef MONGOC_LOG_DOMAIN
29+
#define MONGOC_LOG_DOMAIN "CYRUS-SASL"
2830

29-
#ifndef SASL_CALLBACK_FN
30-
#define SASL_CALLBACK_FN(_f) ((int (*) (void)) (_f))
31-
#endif
31+
int
32+
_mongoc_sasl_log (mongoc_sasl_t *sasl, int level, const char *message)
33+
{
34+
TRACE ("SASL Log; level=%d: message=%s", level, message);
35+
return SASL_OK;
36+
}
3237

33-
void
34-
_mongoc_sasl_set_mechanism (mongoc_sasl_t *sasl, const char *mechanism)
38+
bool
39+
_mongoc_sasl_set_mechanism (mongoc_sasl_t *sasl,
40+
const char *mechanism,
41+
bson_error_t *error)
3542
{
43+
bson_string_t *str = bson_string_new ("");
44+
const char **mechs = sasl_global_listmech ();
45+
int i = 0;
46+
bool ok = false;
47+
3648
BSON_ASSERT (sasl);
3749

38-
bson_free (sasl->mechanism);
39-
sasl->mechanism = mechanism ? bson_strdup (mechanism) : NULL;
50+
for (i = 0; mechs[i]; i++) {
51+
if (!strcmp (mechs[i], mechanism)) {
52+
ok = true;
53+
break;
54+
}
55+
bson_string_append (str, mechs[i]);
56+
if (mechs[i + 1]) {
57+
bson_string_append (str, ",");
58+
}
59+
}
60+
61+
if (ok) {
62+
bson_free (sasl->mechanism);
63+
sasl->mechanism = mechanism ? bson_strdup (mechanism) : NULL;
64+
} else {
65+
bson_set_error (error,
66+
MONGOC_ERROR_SASL,
67+
SASL_NOMECH,
68+
"SASL Failure: Unsupported mechanism by client: %s. "
69+
"Available mechanisms: %s",
70+
mechanism,
71+
str->str);
72+
}
73+
74+
bson_string_free (str, 0);
75+
return ok;
4076
}
4177

4278

@@ -73,7 +109,7 @@ _mongoc_sasl_set_pass (mongoc_sasl_t *sasl, const char *pass)
73109

74110
static int
75111
_mongoc_sasl_canon_user (sasl_conn_t *conn,
76-
void *context,
112+
mongoc_sasl_t *sasl,
77113
const char *in,
78114
unsigned inlen,
79115
unsigned flags,
@@ -246,6 +282,11 @@ _mongoc_sasl_is_failure (int status, bson_error_t *error)
246282
{
247283
bool ret = (status < 0);
248284

285+
TRACE ("Got status: %d ok is %d, continue=%d interact=%d\n",
286+
status,
287+
SASL_OK,
288+
SASL_CONTINUE,
289+
SASL_INTERACT);
249290
if (ret) {
250291
switch (status) {
251292
case SASL_NOMEM:
@@ -323,12 +364,16 @@ _mongoc_sasl_start (mongoc_sasl_t *sasl,
323364

324365
status = sasl_client_new (
325366
service_name, service_host, NULL, NULL, sasl->callbacks, 0, &sasl->conn);
367+
TRACE ("Created new sasl client %s",
368+
status == SASL_OK ? "successfully" : "UNSUCCESSFULLY");
326369
if (_mongoc_sasl_is_failure (status, error)) {
327370
return false;
328371
}
329372

330373
status = sasl_client_start (
331374
sasl->conn, sasl->mechanism, &sasl->interact, &raw, &raw_len, &mechanism);
375+
TRACE ("Started the sasl client %s",
376+
status == SASL_CONTINUE ? "successfully" : "UNSUCCESSFULLY");
332377
if (_mongoc_sasl_is_failure (status, error)) {
333378
return false;
334379
}
@@ -400,8 +445,11 @@ _mongoc_sasl_step (mongoc_sasl_t *sasl,
400445
return false;
401446
}
402447

448+
TRACE ("%s", "Running client_step");
403449
status = sasl_client_step (
404450
sasl->conn, (char *) outbuf, *outbuflen, &sasl->interact, &raw, &rawlen);
451+
TRACE ("%s sent a client step",
452+
status == SASL_OK ? "Successfully" : "UNSUCCESSFULLY");
405453
if (_mongoc_sasl_is_failure (status, error)) {
406454
return false;
407455
}

0 commit comments

Comments
 (0)