sasl_conn_t *php_mongo_saslstart(mongo_con_manager *manager, mongo_connection *con, mongo_server_options *options, mongo_server_def *server_def, sasl_conn_t *conn, char **out_payload, int *out_payload_len, int32_t *conversation_id, char **error_message) { const char *raw_payload; char encoded_payload[4096]; unsigned int raw_payload_len, encoded_payload_len; int result; char *mechanism_list = "GSSAPI"; const char *mechanism_selected; sasl_interact_t *client_interact=NULL; result = sasl_client_start(conn, mechanism_list, &client_interact, &raw_payload, &raw_payload_len, &mechanism_selected); if (is_sasl_failure(conn, result, error_message)) { return NULL; } if (result != SASL_CONTINUE) { *error_message = strdup("Could not negotiate SASL mechanism"); return NULL; } mechanism_selected = "GSSAPI"; result = sasl_encode64(raw_payload, raw_payload_len, encoded_payload, sizeof(encoded_payload), &encoded_payload_len); if (is_sasl_failure(conn, result, error_message)) { return NULL; } if (!mongo_connection_authenticate_saslstart(manager, con, options, server_def, (char *)mechanism_selected, encoded_payload, encoded_payload_len + 1, out_payload, out_payload_len, conversation_id, error_message)) { return NULL; } return conn; }
int php_mongo_saslcontinue(mongo_con_manager *manager, mongo_connection *con, mongo_server_options *options, mongo_server_def *server_def, sasl_conn_t *conn, char *step_payload, int step_payload_len, int32_t conversation_id, char **error_message) { sasl_interact_t *client_interact=NULL; /* * Snippet from sasl.h: * 4. client calls sasl_client_step() * 4b. If SASL error, goto 7 or 3 * 4c. If SASL_OK, continue or goto 6 if last server response was success */ do { char base_payload[4096], payload[4096]; unsigned int base_payload_len, payload_len; const char *out; unsigned int outlen; unsigned char done = 0; int result; step_payload_len--; /* Remove the \0 from the string */ result = sasl_decode64(step_payload, step_payload_len, base_payload, sizeof(base_payload), &base_payload_len); if (is_sasl_failure(conn, result, error_message)) { return 0; } result = sasl_client_step(conn, (const char *)base_payload, base_payload_len, &client_interact, &out, &outlen); if (is_sasl_failure(conn, result, error_message)) { return 0; } result = sasl_encode64(out, outlen, payload, sizeof(base_payload), &payload_len); if (is_sasl_failure(conn, result, error_message)) { return 0; } if (!mongo_connection_authenticate_saslcontinue(manager, con, options, server_def, conversation_id, payload, payload_len + 1, &step_payload, &step_payload_len, &done, error_message)) { return 0; } if (done) { break; } } while (1); return 1; }
int php_mongo_saslcontinue(mongo_con_manager *manager, mongo_connection *con, mongo_server_options *options, mongo_server_def *server_def, sasl_conn_t *conn, char *step_payload, int step_payload_len, int32_t conversation_id, char **error_message) { int result; sasl_interact_t *client_interact=NULL; do { char base_payload[4096], payload[4096]; unsigned int base_payload_len, payload_len; unsigned char done; const char *out; unsigned int outlen; result = sasl_decode64(step_payload, step_payload_len, base_payload, sizeof(base_payload), &base_payload_len); if (is_sasl_failure(conn, result, error_message)) { return result; } result = sasl_client_step(conn, (const char *)base_payload, base_payload_len, &client_interact, &out, &outlen); if (is_sasl_failure(conn, result, error_message)) { return result; } /* TODO : Deal with interaction */ if (result == SASL_OK) { /* We are all done */ break; } result = sasl_encode64(out, outlen, payload, sizeof(base_payload), &payload_len); if (is_sasl_failure(conn, result, error_message)) { return result; } if (!mongo_connection_authenticate_saslcontinue(manager, con, options, server_def, conversation_id, payload, payload_len + 1, &step_payload, &step_payload_len, &done, (char **)&error_message)) { *error_message = strdup("saslStart failed miserably"); return result; } } while (result == SASL_INTERACT || result == SASL_CONTINUE); return result; }