svn_error_t * svn_config_read_auth_data(apr_hash_t **hash, const char *cred_kind, const char *realmstring, const char *config_dir, apr_pool_t *pool) { svn_node_kind_t kind; const char *auth_path; *hash = NULL; SVN_ERR(svn_auth__file_path(&auth_path, cred_kind, realmstring, config_dir, pool)); if (! auth_path) return SVN_NO_ERROR; SVN_ERR(svn_io_check_path(auth_path, &kind, pool)); if (kind == svn_node_file) { svn_stream_t *stream; svn_string_t *stored_realm; SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool, pool), _("Unable to open auth file for reading")); *hash = apr_hash_make(pool); SVN_ERR_W(svn_hash_read2(*hash, stream, SVN_HASH_TERMINATOR, pool), apr_psprintf(pool, _("Error parsing '%s'"), svn_dirent_local_style(auth_path, pool))); stored_realm = svn_hash_gets(*hash, SVN_CONFIG_REALMSTRING_KEY); if (!stored_realm || strcmp(stored_realm->data, realmstring) != 0) *hash = NULL; /* Hash collision, or somebody tampering with storage */ SVN_ERR(svn_stream_close(stream)); } return SVN_NO_ERROR; }
svn_error_t * svn_config_read_auth_data(apr_hash_t **hash, const char *cred_kind, const char *realmstring, const char *config_dir, apr_pool_t *pool) { svn_node_kind_t kind; const char *auth_path; *hash = NULL; SVN_ERR(svn_auth__file_path(&auth_path, cred_kind, realmstring, config_dir, pool)); if (! auth_path) return SVN_NO_ERROR; SVN_ERR(svn_io_check_path(auth_path, &kind, pool)); if (kind == svn_node_file) { svn_stream_t *stream; SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool, pool), _("Unable to open auth file for reading")); *hash = apr_hash_make(pool); SVN_ERR_W(svn_hash_read2(*hash, stream, SVN_HASH_TERMINATOR, pool), apr_psprintf(pool, _("Error parsing '%s'"), svn_dirent_local_style(auth_path, pool))); SVN_ERR(svn_stream_close(stream)); } return SVN_NO_ERROR; }
/* Parse the file at DIGEST_PATH, populating the lock LOCK_P in that file (if it exists, and if *LOCK_P is non-NULL) and the hash of CHILDREN_P (if any exist, and if *CHILDREN_P is non-NULL). Use POOL for all allocations. */ static svn_error_t * read_digest_file(apr_hash_t **children_p, svn_lock_t **lock_p, const char *fs_path, const char *digest_path, apr_pool_t *pool) { svn_error_t *err = SVN_NO_ERROR; svn_lock_t *lock; apr_hash_t *hash; svn_stream_t *stream; const char *val; if (lock_p) *lock_p = NULL; if (children_p) *children_p = apr_hash_make(pool); err = svn_stream_open_readonly(&stream, digest_path, pool, pool); if (err && APR_STATUS_IS_ENOENT(err->apr_err)) { svn_error_clear(err); return SVN_NO_ERROR; } SVN_ERR(err); /* If our caller doesn't care about anything but the presence of the file... whatever. */ if (! (lock_p || children_p)) return svn_stream_close(stream); hash = apr_hash_make(pool); if ((err = svn_hash_read2(hash, stream, SVN_HASH_TERMINATOR, pool))) { svn_error_clear(svn_stream_close(stream)); return svn_error_createf(err->apr_err, err, _("Can't parse lock/entries hashfile '%s'"), svn_dirent_local_style(digest_path, pool)); } SVN_ERR(svn_stream_close(stream)); /* If our caller cares, see if we have a lock path in our hash. If so, we'll assume we have a lock here. */ val = hash_fetch(hash, PATH_KEY, pool); if (val && lock_p) { const char *path = val; /* Create our lock and load it up. */ lock = svn_lock_create(pool); lock->path = path; if (! ((lock->token = hash_fetch(hash, TOKEN_KEY, pool)))) return svn_error_trace(err_corrupt_lockfile(fs_path, path)); if (! ((lock->owner = hash_fetch(hash, OWNER_KEY, pool)))) return svn_error_trace(err_corrupt_lockfile(fs_path, path)); if (! ((val = hash_fetch(hash, IS_DAV_COMMENT_KEY, pool)))) return svn_error_trace(err_corrupt_lockfile(fs_path, path)); lock->is_dav_comment = (val[0] == '1'); if (! ((val = hash_fetch(hash, CREATION_DATE_KEY, pool)))) return svn_error_trace(err_corrupt_lockfile(fs_path, path)); SVN_ERR(svn_time_from_cstring(&(lock->creation_date), val, pool)); if ((val = hash_fetch(hash, EXPIRATION_DATE_KEY, pool))) SVN_ERR(svn_time_from_cstring(&(lock->expiration_date), val, pool)); lock->comment = hash_fetch(hash, COMMENT_KEY, pool); *lock_p = lock; } /* If our caller cares, see if we have any children for this path. */ val = hash_fetch(hash, CHILDREN_KEY, pool); if (val && children_p) { apr_array_header_t *kiddos = svn_cstring_split(val, "\n", FALSE, pool); int i; for (i = 0; i < kiddos->nelts; i++) { apr_hash_set(*children_p, APR_ARRAY_IDX(kiddos, i, const char *), APR_HASH_KEY_STRING, (void *)1); } }
svn_error_t * svn_config_walk_auth_data(const char *config_dir, svn_config_auth_walk_func_t walk_func, void *walk_baton, apr_pool_t *scratch_pool) { int i; apr_pool_t *iterpool; svn_boolean_t finished = FALSE; const char *cred_kinds[] = { SVN_AUTH_CRED_SIMPLE, SVN_AUTH_CRED_USERNAME, SVN_AUTH_CRED_SSL_CLIENT_CERT, SVN_AUTH_CRED_SSL_CLIENT_CERT_PW, SVN_AUTH_CRED_SSL_SERVER_TRUST, NULL }; iterpool = svn_pool_create(scratch_pool); for (i = 0; cred_kinds[i]; i++) { const char *item_path; const char *dir_path; apr_hash_t *nodes; svn_error_t *err; apr_pool_t *itempool; apr_hash_index_t *hi; svn_pool_clear(iterpool); if (finished) break; SVN_ERR(svn_auth__file_path(&item_path, cred_kinds[i], "!", config_dir, iterpool)); dir_path = svn_dirent_dirname(item_path, iterpool); err = svn_io_get_dirents3(&nodes, dir_path, TRUE, iterpool, iterpool); if (err) { if (!APR_STATUS_IS_ENOENT(err->apr_err) && !SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)) return svn_error_trace(err); svn_error_clear(err); continue; } itempool = svn_pool_create(iterpool); for (hi = apr_hash_first(iterpool, nodes); hi; hi = apr_hash_next(hi)) { svn_io_dirent2_t *dirent = apr_hash_this_val(hi); svn_stream_t *stream; apr_hash_t *creds_hash; const svn_string_t *realm; svn_boolean_t delete_file = FALSE; if (finished) break; if (dirent->kind != svn_node_file) continue; svn_pool_clear(itempool); item_path = svn_dirent_join(dir_path, apr_hash_this_key(hi), itempool); err = svn_stream_open_readonly(&stream, item_path, itempool, itempool); if (err) { /* Ignore this file. There are no credentials in it anyway */ svn_error_clear(err); continue; } creds_hash = apr_hash_make(itempool); err = svn_hash_read2(creds_hash, stream, SVN_HASH_TERMINATOR, itempool); err = svn_error_compose_create(err, svn_stream_close(stream)); if (err) { /* Ignore this file. There are no credentials in it anyway */ svn_error_clear(err); continue; } realm = svn_hash_gets(creds_hash, SVN_CONFIG_REALMSTRING_KEY); if (! realm) continue; /* Not an auth file */ err = walk_func(&delete_file, walk_baton, cred_kinds[i], realm->data, creds_hash, itempool); if (err && err->apr_err == SVN_ERR_CEASE_INVOCATION) { svn_error_clear(err); err = SVN_NO_ERROR; finished = TRUE; } SVN_ERR(err); if (delete_file) { /* Delete the file on disk */ SVN_ERR(svn_io_remove_file2(item_path, TRUE, itempool)); } } } svn_pool_destroy(iterpool); return SVN_NO_ERROR; }