void lcb_server_connect_handler(lcb_connection_t conn, lcb_error_t err) { lcb_server_t *server = (lcb_server_t *)conn->data; struct nameinfo_common nistrs; int sasl_in_progress; int should_do_sasl = 0; if (err != LCB_SUCCESS) { connection_error(server, err); return; } server->inside_handler = 1; sasl_in_progress = (server->sasl_conn != NULL); if (!get_nameinfo(conn, &nistrs)) { /** This normally shouldn't happen! */ connection_error(server, LCB_NETWORK_ERROR); } if (!sasl_in_progress) { int sasl_ok = cbsasl_client_new("couchbase", conn->host, nistrs.local, nistrs.remote, server->instance->sasl.callbacks, 0, &server->sasl_conn); lcb_assert(sasl_ok == SASL_OK); } if (server->index == -1) { should_do_sasl = 1; } else if (vbucket_config_get_user(server->instance->config.handle) != NULL) { should_do_sasl = 1; } if (should_do_sasl) { if (!sasl_in_progress) { start_sasl_auth_server(server); } } else { /* No SASL AUTH needed */ lcb_server_connected(server); } lcb_connection_cancel_timer(conn); lcb_sockrw_apply_want(conn); server->inside_handler = 0; }
static void sasl_auth_response_handler(lcb_server_t *server, struct lcb_command_data_st *command_data, protocol_binary_response_header *res) { lcb_uint16_t ret = ntohs(res->response.status); if (ret == PROTOCOL_BINARY_RESPONSE_SUCCESS) { if (server->sasl_conn) { cbsasl_dispose(&server->sasl_conn); } server->sasl_conn = NULL; lcb_server_connected(server); } else if (ret == PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE) { protocol_binary_request_no_extras req; lcb_connection_t conn = &server->connection; const char *out, *bytes = (const char *)res + sizeof(res->bytes); unsigned int nout, nbytes = ntohl(res->response.bodylen); if (cbsasl_client_step(server->sasl_conn, bytes, nbytes, NULL, &out, &nout) != SASL_CONTINUE) { lcb_error_handler(server->instance, LCB_AUTH_ERROR, "Unable to perform SASL STEP"); return; } memset(&req, 0, sizeof(req)); req.message.header.request.magic = PROTOCOL_BINARY_REQ; req.message.header.request.opcode = PROTOCOL_BINARY_CMD_SASL_STEP; req.message.header.request.keylen = ntohs((lcb_uint16_t)server->sasl_nmech); req.message.header.request.datatype = PROTOCOL_BINARY_RAW_BYTES; req.message.header.request.bodylen = ntohl((lcb_uint32_t)(server->sasl_nmech + nout)); lcb_server_buffer_start_packet(server, command_data->cookie, conn->output, &server->output_cookies, req.bytes, sizeof(req.bytes)); lcb_server_buffer_write_packet(server, conn->output, server->sasl_mech, server->sasl_nmech); lcb_server_buffer_write_packet(server, conn->output, out, nout); lcb_server_buffer_end_packet(server, conn->output); lcb_sockrw_set_want(conn, LCB_WRITE_EVENT, 0); } else { lcb_error_handler(server->instance, LCB_AUTH_ERROR, "SASL authentication failed"); } /* Make it known that this was a success. */ lcb_error_handler(server->instance, LCB_SUCCESS, NULL); (void)command_data; }
static void sasl_step_response_handler(lcb_server_t *server, struct lcb_command_data_st *command_data, protocol_binary_response_header *res) { lcb_uint16_t ret = ntohs(res->response.status); if (ret == PROTOCOL_BINARY_RESPONSE_SUCCESS) { if (server->sasl_conn) { cbsasl_dispose(&server->sasl_conn); } server->sasl_conn = NULL; lcb_server_connected(server); } else { lcb_error_handler(server->instance, LCB_AUTH_ERROR, "SASL authentication failed"); } (void)command_data; }