static int send_sasl_step(mc_pSESSREQ sreq, packet_info *packet) { protocol_binary_request_no_extras req; protocol_binary_request_header *hdr = &req.message.header; cbsasl_error_t saslerr; const char *step_data; unsigned int ndata; mc_pSESSINFO ctx = sreq->inner; saslerr = cbsasl_client_step( ctx->sasl, packet->payload, PACKET_NBODY(packet), NULL, &step_data, &ndata); if (saslerr != SASL_CONTINUE) { set_error_ex(sreq, LCB_EINTERNAL, "Unable to perform SASL STEP"); return -1; } memset(&req, 0, sizeof(req)); hdr->request.magic = PROTOCOL_BINARY_REQ; hdr->request.opcode = PROTOCOL_BINARY_CMD_SASL_STEP; hdr->request.keylen = htons((uint16_t)ctx->nmech); hdr->request.bodylen = htonl((uint32_t)ndata + ctx->nmech); hdr->request.datatype = PROTOCOL_BINARY_RAW_BYTES; lcbio_ctx_put(sreq->ctx, req.bytes, sizeof(req.bytes)); lcbio_ctx_put(sreq->ctx, ctx->mech, ctx->nmech); lcbio_ctx_put(sreq->ctx, step_data, ndata); lcbio_ctx_rwant(sreq->ctx, 24); return 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; }