/* Read the "success" response to ANONYMOUS or EXTERNAL authentication. */ static svn_error_t *read_success(svn_ra_svn_conn_t *conn, apr_pool_t *pool) { const char *status, *arg; SVN_ERR(svn_ra_svn_read_tuple(conn, pool, "w(?c)", &status, &arg)); if (strcmp(status, "failure") == 0 && arg) return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL, _("Authentication error from server: %s"), arg); else if (strcmp(status, "success") != 0 || arg) return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL, _("Unexpected server response to authentication")); return SVN_NO_ERROR; }
static svn_error_t *try_auth(svn_ra_svn_conn_t *conn, sasl_conn_t *sasl_ctx, apr_pool_t *pool, server_baton_t *b, svn_boolean_t *success) { const char *out, *mech; const svn_string_t *arg = NULL, *in; unsigned int outlen; int result; svn_boolean_t use_base64; *success = FALSE; /* Read the client's chosen mech and the initial token. */ SVN_ERR(svn_ra_svn_read_tuple(conn, pool, "w(?s)", &mech, &in)); if (strcmp(mech, "EXTERNAL") == 0 && !in) in = svn_string_create(b->tunnel_user, pool); else if (in) in = svn_base64_decode_string(in, pool); /* For CRAM-MD5, we don't base64-encode stuff. */ use_base64 = (strcmp(mech, "CRAM-MD5") != 0); result = sasl_server_start(sasl_ctx, mech, in ? in->data : NULL, in ? in->len : 0, &out, &outlen); if (result != SASL_OK && result != SASL_CONTINUE) return fail_auth(conn, pool, sasl_ctx); while (result == SASL_CONTINUE) { svn_ra_svn_item_t *item; arg = svn_string_ncreate(out, outlen, pool); /* Encode what we send to the client. */ if (use_base64) arg = svn_base64_encode_string2(arg, TRUE, pool); SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(s)", "step", arg)); /* Read and decode the client response. */ SVN_ERR(svn_ra_svn_read_item(conn, pool, &item)); if (item->kind != SVN_RA_SVN_STRING) return SVN_NO_ERROR; in = item->u.string; if (use_base64) in = svn_base64_decode_string(in, pool); result = sasl_server_step(sasl_ctx, in->data, in->len, &out, &outlen); } if (result != SASL_OK) return fail_auth(conn, pool, sasl_ctx); /* Send our last response, if necessary. */ if (outlen) arg = svn_base64_encode_string2(svn_string_ncreate(out, outlen, pool), TRUE, pool); else arg = NULL; *success = TRUE; SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(?s)", "success", arg)); return SVN_NO_ERROR; }