bson_bool_t _mongoc_sasl_step (mongoc_sasl_t *sasl, const bson_uint8_t *inbuf, bson_uint32_t inbuflen, bson_uint8_t *outbuf, bson_uint32_t outbufmax, bson_uint32_t *outbuflen, bson_error_t *error) { const char *raw = NULL; unsigned rawlen = 0; int status; BSON_ASSERT (sasl); BSON_ASSERT (inbuf); BSON_ASSERT (outbuf); BSON_ASSERT (outbuflen); BSON_ASSERT (*outbuflen); sasl->step++; if (sasl->step == 1) { return _mongoc_sasl_start (sasl, outbuf, outbufmax, outbuflen, error); } else if (sasl->step >= 10) { bson_set_error (error, MONGOC_ERROR_SASL, SASL_NOTDONE, "SASL Failure: maximum steps detected"); return FALSE; } if (!inbuflen) { bson_set_error (error, MONGOC_ERROR_SASL, MONGOC_ERROR_CLIENT_AUTHENTICATE, "SASL Failure: no payload provided from server."); return FALSE; } status = sasl_decode64 ((char *)inbuf, inbuflen, (char *)outbuf, outbufmax, outbuflen); if (_mongoc_sasl_is_failure (status, error)) { return FALSE; } status = sasl_client_step (sasl->conn, (char *)outbuf, *outbuflen, &sasl->interact, &raw, &rawlen); if (_mongoc_sasl_is_failure (status, error)) { return FALSE; } status = sasl_encode64 (raw, rawlen, (char *)outbuf, outbufmax, outbuflen); if (_mongoc_sasl_is_failure (status, error)) { return FALSE; } return TRUE; }
static bool _mongoc_sasl_start (mongoc_sasl_t *sasl, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen, bson_error_t *error) { const char *service_name = "mongodb"; const char *service_host = ""; const char *mechanism = NULL; const char *raw = NULL; unsigned raw_len = 0; int status; BSON_ASSERT (sasl); BSON_ASSERT (outbuf); BSON_ASSERT (outbufmax); BSON_ASSERT (outbuflen); if (sasl->service_name) { service_name = sasl->service_name; } if (sasl->service_host) { service_host = sasl->service_host; } status = sasl_client_new (service_name, service_host, NULL, NULL, sasl->callbacks, 0, &sasl->conn); if (_mongoc_sasl_is_failure (status, error)) { return false; } status = sasl_client_start (sasl->conn, sasl->mechanism, &sasl->interact, &raw, &raw_len, &mechanism); if (_mongoc_sasl_is_failure (status, error)) { return false; } if ((0 != strcasecmp (mechanism, "GSSAPI")) && (0 != strcasecmp (mechanism, "PLAIN"))) { bson_set_error (error, MONGOC_ERROR_SASL, SASL_NOMECH, "SASL Failure: invalid mechanism \"%s\"", mechanism); return false; } status = sasl_encode64 (raw, raw_len, (char *)outbuf, outbufmax, outbuflen); if (_mongoc_sasl_is_failure (status, error)) { return false; } return true; }