Modified: subversion/branches/patch-exec/subversion/tests/libsvn_repos/repos-test.c URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/libsvn_repos/repos-test.c?rev=1694027&r1=1694026&r2=1694027&view=diff ============================================================================== --- subversion/branches/patch-exec/subversion/tests/libsvn_repos/repos-test.c (original) +++ subversion/branches/patch-exec/subversion/tests/libsvn_repos/repos-test.c Tue Aug 4 10:46:47 2015 @@ -3612,6 +3612,241 @@ deprecated_access_context_api(const svn_ return SVN_NO_ERROR; } +static svn_error_t * +mkdir_delete_copy(svn_repos_t *repos, + const char *src, + const char *dst, + apr_pool_t *pool) +{ + svn_fs_t *fs = svn_repos_fs(repos); + svn_revnum_t youngest_rev; + svn_fs_txn_t *txn; + svn_fs_root_t *txn_root, *rev_root; + + SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool)); + + SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); + SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); + SVN_ERR(svn_fs_make_dir(txn_root, "A/T", pool)); + SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); + + SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); + SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); + SVN_ERR(svn_fs_delete(txn_root, "A/T", pool)); + SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); + + SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); + SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); + SVN_ERR(svn_fs_revision_root(&rev_root, fs, youngest_rev - 1, pool)); + SVN_ERR(svn_fs_copy(rev_root, src, txn_root, dst, pool)); + SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); + + return SVN_NO_ERROR; +} + +struct authz_read_baton_t { + apr_hash_t *paths; + apr_pool_t *pool; + const char *deny; +}; + +static svn_error_t * +authz_read_func(svn_boolean_t *allowed, + svn_fs_root_t *root, + const char *path, + void *baton, + apr_pool_t *pool) +{ + struct authz_read_baton_t *b = baton; + + if (b->deny && !strcmp(b->deny, path)) + *allowed = FALSE; + else + *allowed = TRUE; + + svn_hash_sets(b->paths, apr_pstrdup(b->pool, path), (void*)1); + + return SVN_NO_ERROR; +} + +static svn_error_t * +verify_locations(apr_hash_t *actual, + apr_hash_t *expected, + apr_hash_t *checked, + apr_pool_t *pool) +{ + apr_hash_index_t *hi; + + for (hi = apr_hash_first(pool, expected); hi; hi = apr_hash_next(hi)) + { + const svn_revnum_t *rev = apr_hash_this_key(hi); + const char *path = apr_hash_get(actual, rev, sizeof(svn_revnum_t)); + + if (!path) + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, + "expected %s for %d found (null)", + (char*)apr_hash_this_val(hi), (int)*rev); + else if (strcmp(path, apr_hash_this_val(hi))) + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, + "expected %s for %d found %s", + (char*)apr_hash_this_val(hi), (int)*rev, path); + + } + + for (hi = apr_hash_first(pool, actual); hi; hi = apr_hash_next(hi)) + { + const svn_revnum_t *rev = apr_hash_this_key(hi); + const char *path = apr_hash_get(expected, rev, sizeof(svn_revnum_t)); + + if (!path) + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, + "found %s for %d expected (null)", + (char*)apr_hash_this_val(hi), (int)*rev); + else if (strcmp(path, apr_hash_this_val(hi))) + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, + "found %s for %d expected %s", + (char*)apr_hash_this_val(hi), (int)*rev, path); + + if (!svn_hash_gets(checked, path)) + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, + "did not check %s", path); + } + + return SVN_NO_ERROR; +} + +static void +set_expected(apr_hash_t *expected, + svn_revnum_t rev, + const char *path, + apr_pool_t *pool) +{ + svn_revnum_t *rp = apr_palloc(pool, sizeof(svn_revnum_t)); + *rp = rev; + apr_hash_set(expected, rp, sizeof(svn_revnum_t), path); +} + +static svn_error_t * +trace_node_locations_authz(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_repos_t *repos; + svn_fs_t *fs; + svn_revnum_t youngest_rev = 0; + svn_fs_txn_t *txn; + svn_fs_root_t *txn_root; + struct authz_read_baton_t arb; + apr_array_header_t *revs = apr_array_make(pool, 10, sizeof(svn_revnum_t)); + apr_hash_t *locations; + apr_hash_t *expected = apr_hash_make(pool); + int i; + + /* Create test repository. */ + SVN_ERR(svn_test__create_repos(&repos, "test-repo-trace-node-locations-authz", + opts, pool)); + fs = svn_repos_fs(repos); + + /* r1 create A */ + SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool)); + SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); + SVN_ERR(svn_fs_make_dir(txn_root, "A", pool)); + SVN_ERR(svn_fs_make_file(txn_root, "A/f", pool)); + SVN_ERR(svn_test__set_file_contents(txn_root, "A/f", "foobar", pool)); + SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool)); + + /* r4 copy A to B */ + SVN_ERR(mkdir_delete_copy(repos, "A", "B", pool)); + + /* r7 copy B to C */ + SVN_ERR(mkdir_delete_copy(repos, "B", "C", pool)); + + /* r10 copy C to D */ + SVN_ERR(mkdir_delete_copy(repos, "C", "D", pool)); + + SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool)); + SVN_ERR_ASSERT(youngest_rev == 10); + + arb.paths = apr_hash_make(pool); + arb.pool = pool; + arb.deny = NULL; + + apr_array_clear(revs); + for (i = 0; i <= youngest_rev; ++i) + APR_ARRAY_PUSH(revs, svn_revnum_t) = i; + set_expected(expected, 10, "/D/f", pool); + set_expected(expected, 8, "/C/f", pool); + set_expected(expected, 7, "/C/f", pool); + set_expected(expected, 5, "/B/f", pool); + set_expected(expected, 4, "/B/f", pool); + set_expected(expected, 2, "/A/f", pool); + set_expected(expected, 1, "/A/f", pool); + apr_hash_clear(arb.paths); + SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, + authz_read_func, &arb, pool)); + SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); + + apr_array_clear(revs); + for (i = 1; i <= youngest_rev; ++i) + APR_ARRAY_PUSH(revs, svn_revnum_t) = i; + apr_hash_clear(arb.paths); + SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, + authz_read_func, &arb, pool)); + SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); + + apr_array_clear(revs); + for (i = 2; i <= youngest_rev; ++i) + APR_ARRAY_PUSH(revs, svn_revnum_t) = i; + set_expected(expected, 1, NULL, pool); + apr_hash_clear(arb.paths); + SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, + authz_read_func, &arb, pool)); + SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); + + apr_array_clear(revs); + for (i = 3; i <= youngest_rev; ++i) + APR_ARRAY_PUSH(revs, svn_revnum_t) = i; + set_expected(expected, 2, NULL, pool); + apr_hash_clear(arb.paths); + SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, + authz_read_func, &arb, pool)); + SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); + + apr_array_clear(revs); + for (i = 6; i <= youngest_rev; ++i) + APR_ARRAY_PUSH(revs, svn_revnum_t) = i; + set_expected(expected, 5, NULL, pool); + set_expected(expected, 4, NULL, pool); + apr_hash_clear(arb.paths); + SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, + authz_read_func, &arb, pool)); + SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); + + arb.deny = "/B/f"; + apr_array_clear(revs); + for (i = 0; i <= youngest_rev; ++i) + APR_ARRAY_PUSH(revs, svn_revnum_t) = i; + apr_hash_clear(arb.paths); + SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, + authz_read_func, &arb, pool)); + SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); + + apr_array_clear(revs); + for (i = 6; i <= youngest_rev; ++i) + APR_ARRAY_PUSH(revs, svn_revnum_t) = i; + apr_hash_clear(arb.paths); + SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, + authz_read_func, &arb, pool)); + SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); + + APR_ARRAY_PUSH(revs, svn_revnum_t) = 0; + apr_hash_clear(arb.paths); + SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs, + authz_read_func, &arb, pool)); + SVN_ERR(verify_locations(locations, expected, arb.paths, pool)); + + return SVN_NO_ERROR; +} + /* The test table. */ static int max_threads = 4; @@ -3667,6 +3902,8 @@ static struct svn_test_descriptor_t test "test test_repos_fs_type"), SVN_TEST_OPTS_PASS(deprecated_access_context_api, "test deprecated access context api"), + SVN_TEST_OPTS_PASS(trace_node_locations_authz, + "authz for svn_repos_trace_node_locations"), SVN_TEST_NULL };
Modified: subversion/branches/patch-exec/tools/dist/rat-excludes URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/tools/dist/rat-excludes?rev=1694027&r1=1694026&r2=1694027&view=diff ============================================================================== --- subversion/branches/patch-exec/tools/dist/rat-excludes (original) +++ subversion/branches/patch-exec/tools/dist/rat-excludes Tue Aug 4 10:46:47 2015 @@ -32,7 +32,7 @@ subversion/bindings/ctypes-python/csvn/e subversion/tests/cmdline/svntest/err.py tools/buildbot/master/public_html/buildbot.css tools/dist/rat-excludes -tools/dist/_gnupg.py +tools/dist/security/_gnupg.py tools/dist/templates/*.ezt tools/dev/iz/defect.dem tools/dev/iz/ff2csv.command Modified: subversion/branches/patch-exec/tools/dist/release.py URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/tools/dist/release.py?rev=1694027&r1=1694026&r2=1694027&view=diff ============================================================================== --- subversion/branches/patch-exec/tools/dist/release.py (original) +++ subversion/branches/patch-exec/tools/dist/release.py Tue Aug 4 10:46:47 2015 @@ -803,7 +803,7 @@ def get_siginfo(args, quiet=False): try: import gnupg except ImportError: - import _gnupg as gnupg + import security._gnupg as gnupg gpg = gnupg.GPG() target = get_target(args) Modified: subversion/branches/patch-exec/win-tests.py URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/win-tests.py?rev=1694027&r1=1694026&r2=1694027&view=diff ============================================================================== --- subversion/branches/patch-exec/win-tests.py (original) +++ subversion/branches/patch-exec/win-tests.py Tue Aug 4 10:46:47 2015 @@ -490,6 +490,7 @@ class Httpd: self.httpd_config = os.path.join(self.root, 'httpd.conf') self.httpd_users = os.path.join(self.root, 'users') self.httpd_mime_types = os.path.join(self.root, 'mime.types') + self.httpd_groups = os.path.join(self.root, 'groups') self.abs_builddir = abs_builddir self.abs_objdir = abs_objdir self.service_name = 'svn-test-httpd-' + str(httpd_port) @@ -503,6 +504,7 @@ class Httpd: create_target_dir(self.root_dir) self._create_users_file() + self._create_groups_file() self._create_mime_types_file() self._create_dontdothat_file() @@ -543,6 +545,8 @@ class Httpd: if self.httpd_ver >= 2.2: fp.write(self._sys_module('auth_basic_module', 'mod_auth_basic.so')) fp.write(self._sys_module('authn_file_module', 'mod_authn_file.so')) + fp.write(self._sys_module('authz_groupfile_module', 'mod_authz_groupfile.so')) + fp.write(self._sys_module('authz_host_module', 'mod_authz_host.so')) else: fp.write(self._sys_module('auth_module', 'mod_auth.so')) fp.write(self._sys_module('alias_module', 'mod_alias.so')) @@ -565,6 +569,7 @@ class Httpd: # Define two locations for repositories fp.write(self._svn_repo('repositories')) fp.write(self._svn_repo('local_tmp')) + fp.write(self._svn_authz_repo()) # And two redirects for the redirect tests fp.write('RedirectMatch permanent ^/svn-test-work/repositories/' @@ -597,6 +602,17 @@ class Httpd: 'jconstant', 'rayjandom']) os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users, '__dumpster__', '__loadster__']) + os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users, + 'JRANDOM', 'rayjandom']) + os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users, + 'JCONSTANT', 'rayjandom']) + + def _create_groups_file(self): + "Create groups for mod_authz_svn tests" + fp = open(self.httpd_groups, 'w') + fp.write('random: jrandom\n') + fp.write('constant: jconstant\n') + fp.close() def _create_mime_types_file(self): "Create empty mime.types file" @@ -657,6 +673,153 @@ class Httpd: ' DontDoThatConfigFile ' + self._quote(self.dontdothat_file) + '\n' \ '</Location>\n' + def _svn_authz_repo(self): + local_tmp = os.path.join(self.abs_builddir, + CMDLINE_TEST_SCRIPT_NATIVE_PATH, + 'svn-test-work', 'local_tmp') + return \ + '<Location /authz-test-work/anon>' + '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' <IfModule mod_authz_core.c>' + '\n' \ + ' Require all granted' + '\n' \ + ' </IfModule>' + '\n' \ + ' <IfModule !mod_authz_core.c>' + '\n' \ + ' Allow from all' + '\n' \ + ' </IfModule>' + '\n' \ + ' SVNPathAuthz ' + self.path_authz_option + '\n' \ + '</Location>' + '\n' \ + '<Location /authz-test-work/mixed>' + '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' AuthType Basic' + '\n' \ + ' AuthName "Subversion Repository"' + '\n' \ + ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ + ' Require valid-user' + '\n' \ + ' Satisfy Any' + '\n' \ + ' SVNPathAuthz ' + self.path_authz_option + '\n' \ + '</Location>' + '\n' \ + '<Location /authz-test-work/mixed-noauthwhenanon>' + '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' AuthType Basic' + '\n' \ + ' AuthName "Subversion Repository"' + '\n' \ + ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ + ' Require valid-user' + '\n' \ + ' AuthzSVNNoAuthWhenAnonymousAllowed On' + '\n' \ + ' SVNPathAuthz On' + '\n' \ + '</Location>' + '\n' \ + '<Location /authz-test-work/authn>' + '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' AuthType Basic' + '\n' \ + ' AuthName "Subversion Repository"' + '\n' \ + ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ + ' Require valid-user' + '\n' \ + ' SVNPathAuthz ' + self.path_authz_option + '\n' \ + '</Location>' + '\n' \ + '<Location /authz-test-work/authn-anonoff>' + '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' AuthType Basic' + '\n' \ + ' AuthName "Subversion Repository"' + '\n' \ + ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ + ' Require valid-user' + '\n' \ + ' AuthzSVNAnonymous Off' + '\n' \ + ' SVNPathAuthz On' + '\n' \ + '</Location>' + '\n' \ + '<Location /authz-test-work/authn-lcuser>' + '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' AuthType Basic' + '\n' \ + ' AuthName "Subversion Repository"' + '\n' \ + ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ + ' Require valid-user' + '\n' \ + ' AuthzForceUsernameCase Lower' + '\n' \ + ' SVNPathAuthz ' + self.path_authz_option + '\n' \ + '</Location>' + '\n' \ + '<Location /authz-test-work/authn-lcuser>' + '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' AuthType Basic' + '\n' \ + ' AuthName "Subversion Repository"' + '\n' \ + ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ + ' Require valid-user' + '\n' \ + ' AuthzForceUsernameCase Lower' + '\n' \ + ' SVNPathAuthz ' + self.path_authz_option + '\n' \ + '</Location>' + '\n' \ + '<Location /authz-test-work/authn-group>' + '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' AuthType Basic' + '\n' \ + ' AuthName "Subversion Repository"' + '\n' \ + ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ + ' AuthGroupFile ' + self._quote(self.httpd_groups) + '\n' \ + ' Require group random' + '\n' \ + ' AuthzSVNAuthoritative Off' + '\n' \ + ' SVNPathAuthz On' + '\n' \ + '</Location>' + '\n' \ + '<IfModule mod_authz_core.c>' + '\n' \ + '<Location /authz-test-work/sallrany>' + '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' AuthType Basic' + '\n' \ + ' AuthName "Subversion Repository"' + '\n' \ + ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ + ' AuthzSendForbiddenOnFailure On' + '\n' \ + ' Satisfy All' + '\n' \ + ' <RequireAny>' + '\n' \ + ' Require valid-user' + '\n' \ + ' Require expr req(\'ALLOW\') == \'1\'' + '\n' \ + ' </RequireAny>' + '\n' \ + ' SVNPathAuthz ' + self.path_authz_option + '\n' \ + '</Location>' + '\n' \ + '<Location /authz-test-work/sallrall>'+ '\n' \ + ' DAV svn' + '\n' \ + ' SVNParentPath ' + local_tmp + '\n' \ + ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ + ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ + ' SVNListParentPath On' + '\n' \ + ' AuthType Basic' + '\n' \ + ' AuthName "Subversion Repository"' + '\n' \ + ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ + ' AuthzSendForbiddenOnFailure On' + '\n' \ + ' Satisfy All' + '\n' \ + ' <RequireAll>' + '\n' \ + ' Require valid-user' + '\n' \ + ' Require expr req(\'ALLOW\') == \'1\'' + '\n' \ + ' </RequireAll>' + '\n' \ + ' SVNPathAuthz ' + self.path_authz_option + '\n' \ + '</Location>' + '\n' \ + '</IfModule>' + '\n' \ + def start(self): if self.service: self._start_service() @@ -826,6 +989,10 @@ if not test_javahl and not test_swig: log_file = os.path.join(abs_builddir, log) fail_log_file = os.path.join(abs_builddir, faillog) + if run_httpd: + httpd_version = gen_obj._libraries['httpd'].version + else: + httpd_version = None th = run_tests.TestHarness(abs_srcdir, abs_builddir, log_file, fail_log_file, @@ -835,6 +1002,7 @@ if not test_javahl and not test_swig: fsfs_sharding, fsfs_packing, list_tests, svn_bin, mode_filter, milestone_filter, + httpd_version=httpd_version, set_log_level=log_level, ssl_cert=ssl_cert, exclusive_wc_locks=exclusive_wc_locks, memcached_server=memcached_server,
