svn_error_t * svn_ra_svn__do_internal_auth(svn_ra_svn__session_baton_t *sess, const apr_array_header_t *mechlist, const char *realm, apr_pool_t *pool) { svn_ra_svn_conn_t *conn = sess->conn; const char *realmstring, *user, *password, *msg; svn_auth_iterstate_t *iterstate; void *creds; realmstring = apr_psprintf(pool, "%s %s", sess->realm_prefix, realm); if (sess->is_tunneled && svn_ra_svn__find_mech(mechlist, "EXTERNAL")) { /* Ask the server to use the tunnel connection environment (on * Unix, that means uid) to determine the authentication name. */ SVN_ERR(svn_ra_svn__auth_response(conn, pool, "EXTERNAL", "")); return read_success(conn, pool); } else if (svn_ra_svn__find_mech(mechlist, "ANONYMOUS")) { SVN_ERR(svn_ra_svn__auth_response(conn, pool, "ANONYMOUS", "")); return read_success(conn, pool); } else if (svn_ra_svn__find_mech(mechlist, "CRAM-MD5")) { SVN_ERR(svn_auth_first_credentials(&creds, &iterstate, SVN_AUTH_CRED_SIMPLE, realmstring, sess->callbacks->auth_baton, pool)); if (!creds) return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL, _("Can't get password")); while (creds) { user = ((svn_auth_cred_simple_t *) creds)->username; password = ((svn_auth_cred_simple_t *) creds)->password; SVN_ERR(svn_ra_svn__auth_response(conn, pool, "CRAM-MD5", NULL)); SVN_ERR(svn_ra_svn__cram_client(conn, pool, user, password, &msg)); if (!msg) break; SVN_ERR(svn_auth_next_credentials(&creds, iterstate, pool)); } if (!creds) return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL, _("Authentication error from server: %s"), msg); SVN_ERR(svn_auth_save_credentials(iterstate, pool)); return SVN_NO_ERROR; } else return svn_error_create(SVN_ERR_RA_SVN_NO_MECHANISMS, NULL, NULL); }
static svn_error_t * handle_basic_auth(svn_ra_serf__session_t *session, svn_ra_serf__connection_t *conn, serf_request_t *request, serf_bucket_t *response, char *auth_hdr, char *auth_attr, apr_pool_t *pool) { void *creds; char *last, *realm_name; svn_auth_cred_simple_t *simple_creds; const char *tmp; apr_size_t tmp_len; apr_port_t port; int i; if (!session->realm) { char *attr; attr = apr_strtok(auth_attr, "=", &last); if (strcmp(attr, "realm") == 0) { realm_name = apr_strtok(NULL, "=", &last); if (realm_name[0] == '\"') { apr_size_t realm_len; realm_len = strlen(realm_name); if (realm_name[realm_len - 1] == '\"') { realm_name[realm_len - 1] = '\0'; realm_name++; } } } else { return svn_error_create (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Missing 'realm' attribute in Authorization header.")); } if (!realm_name) { return svn_error_create (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Missing 'realm' attribute in Authorization header.")); } if (session->repos_url.port_str) { port = session->repos_url.port; } else { port = apr_uri_port_of_scheme(session->repos_url.scheme); } session->realm = apr_psprintf(session->pool, "<%s://%s:%d> %s", session->repos_url.scheme, session->repos_url.hostname, port, realm_name); } if (!session->auth_state) { SVN_ERR(svn_auth_first_credentials(&creds, &session->auth_state, SVN_AUTH_CRED_SIMPLE, session->realm, session->wc_callbacks->auth_baton, session->pool)); } else { SVN_ERR(svn_auth_next_credentials(&creds, session->auth_state, session->pool)); } session->auth_attempts++; if (!creds || session->auth_attempts > 4) { /* No more credentials. */ return svn_error_create(SVN_ERR_AUTHN_FAILED, NULL, "No more credentials or we tried too many times.\n" "Authentication failed"); } simple_creds = creds; tmp = apr_pstrcat(session->pool, simple_creds->username, ":", simple_creds->password, NULL); tmp_len = strlen(tmp); svn_ra_serf__encode_auth_header(session->auth_protocol->auth_name, &session->auth_value, tmp, tmp_len, pool); session->auth_header = "Authorization"; /* FIXME Come up with a cleaner way of changing the connection auth. */ for (i = 0; i < session->num_conns; i++) { session->conns[i]->auth_header = session->auth_header; session->conns[i]->auth_value = session->auth_value; } return SVN_NO_ERROR; }