# # # patch "contrib/dump-test-logs.sh" # from [e8c725862bb8e18a11c8b93155fea908251d3c17] # to [ccc00999e139b734e54f498e7e32900465811ab4] # # patch "debian/changelog" # from [b724d70f4bb1d65f85ada08fdc1573aa2ccf29c0] # to [f4383665041ab3263c55b3b96b1c60c652ac8c77] # # patch "debian/control" # from [73ee7b2329440674ddd9cf8100c08676e91a3ed2] # to [57951fba1a69612e4f835e808295c7454b2bf384] # # patch "debian/rules" # from [dc5413bd12361de35bcd3def7e5549af8f5a8af0] # to [ffb0ab1ceb6447e4663d2a9c185ef0cfb94af99c] # # patch "key_store.cc" # from [55878f97b03349c66d95398799780f43ae63165b] # to [510eb02eab491fd9e79c49fcfcf5e6efa145872f] # # patch "lua-testsuite.lua" # from [0e0e38f25d6d9e4d063352806d82f85d0f97380f] # to [e453320c6ed5646151093b7001b0e838f0fc6395] # # patch "ssh_agent.cc" # from [dcc8cefe23e376c74df2eb10011f874802a609d6] # to [a2a0e96fd30804230e181747f36dcae3be34fd26] # # patch "ssh_agent.hh" # from [c0c03bdb37905e1e6bbf8350a00fc68b0d83611b] # to [c9b7efaf4b0f2c137336046b0ebe3ccff7ad5076] # # patch "testlib.lua" # from [44d6be1881e02da1a2bb908a99f995f1d0af4830] # to [0e8c0415f85924dfb385a6e6a0de8b0f787a611d] # # patch "tests/automate_inventory/__driver__.lua" # from [e12ed1600e4dc846891575fd758971461ff8512f] # to [eb93af3ddfc4ca69f6b8b3e37deba089cf6e02dc] # # patch "tests/automate_inventory_ignore_dirs/expected.stderr" # from [41fc6d7fb22c6a3040b0ba0c7708be080a4a8716] # to [78e70180356ed73018d76e1d40a422868cef4d11] # # patch "tests/automate_inventory_restricted/__driver__.lua" # from [ab30596e5444d0134d518cf7e14f40e99a475ae8] # to [b8805c0a9d10fc8bf5913d791f87f2fe208d1616] # # patch "tests/db_data_format_checking/__driver__.lua" # from [e3f5be2451252d0c52a609f638c402ac8a9cf302] # to [c675dbc20a827bb32bd02719a3223e0a0e4001ad] # # patch "tests/non_workspace_keydir/__driver__.lua" # from [d32720e0e63d4429dc590c0849a1eb8794848b06] # to [42fd41dbdf35be5288d60cb2e3ac589770cb83e9] # # patch "tests/pid_file_and_log_handles_open_failures/__driver__.lua" # from [1da5c1056509a1fa78b7492e9e9100228b8661f6] # to [9d10776466ab4ab193466e45a156a63f60491553] # # patch "tests/ssh_agent/__driver__.lua" # from [95cd8c83271295eacfdafa032182f9ee07ae1913] # to [ab2aa35c08886878f31dcccd54f76e55e04a8bc5] # # patch "tests/syntax_errors_in_.mtn-ignore/stdout-ref" # from [98b118d4a2e3bd4f52dcbe7c790a70f1b52aa901] # to [35ddfeda5089ea016cb0713fea9201fd00b5520b] # # patch "tests/two_parent_workspace_list/__driver__.lua" # from [65c50373573076490512bf8852e35bb671f34ff7] # to [5d6df31659e888cf21e541121d487d3e5249e2df] # ============================================================ --- contrib/dump-test-logs.sh e8c725862bb8e18a11c8b93155fea908251d3c17 +++ contrib/dump-test-logs.sh ccc00999e139b734e54f498e7e32900465811ab4 @@ -7,31 +7,18 @@ # the overall 'make' output. Run, with no arguments, from the top # level of a monotone build tree. -set -e -cd tester_dir +# Conveniently enough, testlib.lua does most of the work for us. dumped=0 -for log in */*/tester.log +for log in tester_dir/*.log do - label=${log%/tester.log} - status=${log%/tester.log}/STATUS - - if [ -f "$status" ]; then - shorttag=$(cat "$status") - case "$shorttag" in - ok | skipped* | expected\ failure* | partial\ skip ) - continue ;; - esac - else - shorttag="no status file" - fi - - if [ $dumped -eq 0 ]; then - echo "### Detailed test logs:" + if grep "^\*\**$" < $log > /dev/null 2>&1; then dumped=1 + echo + echo "### $log ###" + echo + sed -ne '/^Running tests/,/^$/!p' < $log fi - echo "### $label $shorttag" - cat "$log" done # Exit unsuccessfully if we dumped anything, so that a driver Makefile ============================================================ --- debian/changelog b724d70f4bb1d65f85ada08fdc1573aa2ccf29c0 +++ debian/changelog f4383665041ab3263c55b3b96b1c60c652ac8c77 @@ -1,3 +1,18 @@ +monotone (0.40-5) unstable; urgency=low + + * Backport from upstream development tree: + - fix for broken ssh_agent support + - testsuite hardening against unusable network, and DISABLE_NETWORK_TESTS + environment variable support + - improved contrib/dump-test-logs.sh + * debian/rules: Set DISABLE_NETWORK_TESTS when running the testsuite; + this may cure the mips buildd problems for real. Also, implement + support for DEB_BUILD_OPTS=parallel rather than probing available CPUs. + * monotone binary package Suggests: monotone-doc and monotone-server + (Closes: #476155) + + -- Zack Weinberg Sun, 08 Jun 2008 18:55:02 -0400 + monotone (0.40-4) unstable; urgency=low * Corrected .diff.gz including regeneration of Makefile.in. ============================================================ --- debian/control 73ee7b2329440674ddd9cf8100c08676e91a3ed2 +++ debian/control 57951fba1a69612e4f835e808295c7454b2bf384 @@ -14,6 +14,7 @@ Depends: ${shlibs:Depends} Package: monotone Architecture: any Depends: ${shlibs:Depends} +Suggests: monotone-doc, monotone-server Description: A distributed version (revision) control system Monotone is a free, distributed version control system. It provides fully disconnected operation, manages complete tree versions, keeps ============================================================ --- debian/rules dc5413bd12361de35bcd3def7e5549af8f5a8af0 +++ debian/rules ffb0ab1ceb6447e4663d2a9c185ef0cfb94af99c @@ -23,7 +23,9 @@ endif endif # This enables parallelism. -CPUS ?= $(shell getconf _NPROCESSORS_ONLN) +ifneq (,$(findstring parallel=,$(DEB_BUILD_OPTIONS))) +PAR := -j$(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) +endif # DEB_BUILD_OPTIONS=noopt handling (Policy 10.1) and arch-specific # compiler options. Allow total override of CFLAGS from the @@ -78,17 +80,23 @@ endif --infodir='$${prefix}/share/info' CFLAGS="$(CFLAGS)" \ CXXFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs" +# We don't want to generate the info documentation in build-arch, so +# we have to bypass the 'all' target. (Revisit after automake-ectomy.) + +# The testsuite is still not entirely reliable in parallel mode, and +# thanks to buildd configuration decisions that no one will explain to +# me in sufficient detail to detect reliably, we have to disable all +# netsync tests. (We could get away with only doing that on mips, but +# who knows whether another architecture will decide to do the same +# thing.) The real fix for both these issues will be network tests +# over local domain sockets, coming Real Soon Now from upstream. build-arch: build-arch-stamp build-arch-stamp: config.status - -# We don't want to generate the info documentation in build-arch, so -# we have to bypass the 'all' target. (Revisit after automake-ectomy.) -# The testsuite is still not entirely reliable in parallel mode. - make -j$(CPUS) -C po all - make -j$(CPUS) mtn + make $(PAR) -C po all + make $(PAR) mtn ifeq "$(findstring nocheck, $(DEB_BUILD_OPTIONS))" "" - make -j$(CPUS) unit_tester tester check_net - make check-local || sh contrib/dump-test-logs.sh + make $(PAR) unit_tester tester check_net + DISABLE_NETWORK_TESTS=1 make check-local || sh contrib/dump-test-logs.sh endif touch $@ @@ -96,7 +104,7 @@ build-indep-stamp: config.status build-indep-stamp: config.status # Just the formatted documentation. - make -j$(CPUS) info html monotone.pdf + make $(PAR) info html monotone.pdf touch $@ clean: ============================================================ --- key_store.cc 55878f97b03349c66d95398799780f43ae63165b +++ key_store.cc 510eb02eab491fd9e79c49fcfcf5e6efa145872f @@ -438,6 +438,14 @@ key_store::cache_decrypted_key(const rsa key_store::cache_decrypted_key(const rsa_keypair_id & id) { signing_key = id; + keypair key; + get_key_pair(id, key); + if (s->get_agent().has_key(key)) + { + L(FL("ssh-agent has key '%s' loaded, skipping internal cache") % id); + return; + } + if (s->lua.hook_persist_phrase_ok()) s->decrypt_private_key(id); } ============================================================ --- lua-testsuite.lua 0e0e38f25d6d9e4d063352806d82f85d0f97380f +++ lua-testsuite.lua e453320c6ed5646151093b7001b0e838f0fc6395 @@ -346,7 +346,13 @@ function prepare_to_run_tests (P) -- requires a helper program. local checknet = getpathof("check_net") - if checknet ~= nil then + if os.getenv("DISABLE_NETWORK_TESTS") ~= nil then + P("warning: DISABLE_NETWORK_TESTS set, skipping network server tests\n") + no_network_tests = true + elseif checknet == nil then + P("warning: check_net helper is missing, skipping network server tests\n") + no_network_tests = true + else writefile_q("in", nil) prepare_redirect("in", "out", "err") local status = execute(checknet) @@ -362,9 +368,6 @@ function prepare_to_run_tests (P) P("warning: network unavailable, skipping network server tests\n") no_network_tests = true end - else - P("warning: check_net helper is missing, skipping network server tests\n") - no_network_tests = true end -- Record the full version of monotone under test in the logfile. ============================================================ --- ssh_agent.cc dcc8cefe23e376c74df2eb10011f874802a609d6 +++ ssh_agent.cc a2a0e96fd30804230e181747f36dcae3be34fd26 @@ -20,6 +20,7 @@ #include "botan/bigint.h" #include #include "platform.hh" +#include "key_store.hh" #ifdef WIN32 #include "win32/ssh_agent_platform.hh" @@ -27,14 +28,18 @@ #include "unix/ssh_agent_platform.hh" #endif +using std::string; +using std::vector; + +using boost::shared_ptr; +using boost::shared_dynamic_cast; + using Botan::RSA_PublicKey; using Botan::RSA_PrivateKey; using Botan::BigInt; using Botan::SecureVector; +using Botan::X509_PublicKey; using Netxx::Stream; -using boost::shared_ptr; -using std::string; -using std::vector; struct ssh_agent_state : ssh_agent_platform { @@ -375,6 +380,35 @@ ssh_agent::get_keys() return s->keys; } +bool +ssh_agent::has_key(const keypair & key) +{ + //grab the monotone public key as an RSA_PublicKey + SecureVector pub_block; + pub_block.set(reinterpret_cast((key.pub)().data()), + (key.pub)().size()); + L(FL("has_key: building %d-byte pub key") % pub_block.size()); + shared_ptr x509_key = + shared_ptr(Botan::X509::load_key(pub_block)); + shared_ptr pub_key = shared_dynamic_cast(x509_key); + + if (!pub_key) + throw informative_failure("has_key: Failed to get monotone RSA public key"); + + vector ssh_keys = get_keys(); + for (vector::const_iterator + si = ssh_keys.begin(); si != ssh_keys.end(); ++si) + { + if ((*pub_key).get_e() == (*si).get_e() + && (*pub_key).get_n() == (*si).get_n()) + { + L(FL("has_key: key found")); + return true; + } + } + return false; +} + void ssh_agent::sign_data(RSA_PublicKey const & key, string const & data, ============================================================ --- ssh_agent.hh c0c03bdb37905e1e6bbf8350a00fc68b0d83611b +++ ssh_agent.hh c9b7efaf4b0f2c137336046b0ebe3ccff7ad5076 @@ -13,6 +13,8 @@ #include "vector.hh" #include +struct keypair; + namespace Botan { class RSA_PublicKey; @@ -26,6 +28,7 @@ struct ssh_agent ssh_agent(); ~ssh_agent(); std::vector const get_keys(); + bool has_key(const keypair & key); void sign_data(Botan::RSA_PublicKey const & key, std::string const & data, std::string & out); ============================================================ --- testlib.lua 44d6be1881e02da1a2bb908a99f995f1d0af4830 +++ testlib.lua 0e8c0415f85924dfb385a6e6a0de8b0f787a611d @@ -1061,6 +1061,16 @@ function run_one_test(tname) test.bglist = {} test.log = io.open("tester.log", "w") + -- Sanitize $HOME. This is done here so that each test gets its + -- very own empty directory (in case some test writes stuff inside). + unlogged_mkdir("emptyhomedir") + test.home = test.root .. "/emptyhomedir" + if ostype == "Windows" then + set_env("APPDATA", test.home) + else + set_env("HOME", test.home) + end + L("Test ", test.name, "\n") local driverfile = testdir .. "/" .. test.name .. "/__driver__.lua" ============================================================ --- tests/automate_inventory/__driver__.lua e12ed1600e4dc846891575fd758971461ff8512f +++ tests/automate_inventory/__driver__.lua eb93af3ddfc4ca69f6b8b3e37deba089cf6e02dc @@ -62,6 +62,11 @@ index = check_inventory (parsed, index, status = "dropped"}) index = check_inventory (parsed, index, +{ path = "emptyhomedir", + fs_type = "directory", + status = "unknown"}) + +index = check_inventory (parsed, index, { path = "ignored~", fs_type = "file", status = "ignored"}) ============================================================ --- tests/automate_inventory_ignore_dirs/expected.stderr 41fc6d7fb22c6a3040b0ba0c7708be080a4a8716 +++ tests/automate_inventory_ignore_dirs/expected.stderr 78e70180356ed73018d76e1d40a422868cef4d11 @@ -1,3 +1,4 @@ +ignore_file: 'emptyhomedir': ignore_file: 'keys': ignore_file: 'source': ignore_file: 'source/ignored_dir': ============================================================ --- tests/automate_inventory_restricted/__driver__.lua ab30596e5444d0134d518cf7e14f40e99a475ae8 +++ tests/automate_inventory_restricted/__driver__.lua b8805c0a9d10fc8bf5913d791f87f2fe208d1616 @@ -68,6 +68,11 @@ index = check_inventory (parsed, index, status = {"known"}}) index = check_inventory (parsed, index, +{ path = "emptyhomedir", + fs_type = "directory", + status = "unknown"}) + +index = check_inventory (parsed, index, { path = "file_0", old_type = "file", new_type = "file", @@ -106,6 +111,11 @@ index = check_inventory (parsed, index, status = {"known"}}) index = check_inventory (parsed, index, +{ path = "emptyhomedir", + fs_type = "directory", + status = "unknown"}) + +index = check_inventory (parsed, index, { path = "file_0", old_type = "file", new_type = "file", @@ -278,6 +288,11 @@ index = check_inventory (parsed, index, status = {"known"}}) index = check_inventory (parsed, index, +{ path = "emptyhomedir", + fs_type = "directory", + status = "unknown"}) + +index = check_inventory (parsed, index, { path = "file_0", old_type = "file", new_path = "dir_a/file_0", @@ -322,6 +337,11 @@ index = check_inventory (parsed, index, status = {"known"}}) index = check_inventory (parsed, index, +{ path = "emptyhomedir", + fs_type = "directory", + status = "unknown"}) + +index = check_inventory (parsed, index, { path = "file_0", old_type = "file", new_path = "dir_a/file_0", ============================================================ --- tests/db_data_format_checking/__driver__.lua e3f5be2451252d0c52a609f638c402ac8a9cf302 +++ tests/db_data_format_checking/__driver__.lua c675dbc20a827bb32bd02719a3223e0a0e4001ad @@ -13,7 +13,7 @@ check(mtn("-d", "cs-modern.db", "ls", "k check(mtn("-d", "cs-modern.db", "db", "migrate"), 0, false, false) check(mtn("-d", "cs-modern.db", "ls", "keys"), 1, false, false) -check(mtn("-d", "cs-modern.db", "serve", "--bind=127.0.0.1:63219"), 1, false, false) +check(mtn("-d", "cs-modern.db", "ls", "branches"), 1, false, false) check(get("rosterify.db.dumped", "stdin")) @@ -21,7 +21,7 @@ check(mtn("-d", "ro-modern.db", "ls", "k check(mtn("-d", "ro-modern.db", "db", "migrate"), 0, false, false) check(mtn("-d", "ro-modern.db", "ls", "keys"), 1, false, false) -check(mtn("-d", "ro-modern.db", "serve", "--bind=127.0.0.1:63219"), 1, false, false) +check(mtn("-d", "ro-modern.db", "ls", "branches"), 1, false, false) -- arguably "db regenerate_caches" should go here too -- it's treated -- similarly. But the test "schema_migration" tests for its behavior in this ============================================================ --- tests/non_workspace_keydir/__driver__.lua d32720e0e63d4429dc590c0849a1eb8794848b06 +++ tests/non_workspace_keydir/__driver__.lua 42fd41dbdf35be5288d60cb2e3ac589770cb83e9 @@ -1,5 +1,3 @@ -mtn_setup() - -- adapted from lua-testsuite.lua mtn; no --confdir, --keydir, or --key function pure_mtn(...) if monotone_path == nil then @@ -8,52 +6,40 @@ function pure_mtn(...) err("'mtn' environment variable not set") end end - return {monotone_path, "--ssh-sign=no", "--norc", "--root=" .. test.root, "--db", "test.db", - "--rcfile", test.root .. "/test_hooks.lua", unpack(arg)} + return {monotone_path, "--ssh-sign=no", "--norc", + "--root=" .. test.root, "--db", "test.db", + "--rcfile", test.root .. "/test_hooks.lua", unpack(arg)} end --- this should find a private key in the specified keydir +mtn_setup() --- On Unix, the return code from the background process is the signal --- value; srv:finish sends signal -15 to stop the process. Not so on --- Windows. +addfile("file", "contents") +commit() +rev = base_revision() --- However, this means we need to check stderr from the background --- command to check for success or failure. +-- make test.root not a workspace anymore +check(rename("_MTN", "not_MTN")) -if ostype == "Windows" then -expected_ret = 1 -else -expected_ret = -15 -end +-- this should fail to find any private key to sign the cert with +check(pure_mtn("cert", rev, "fail1", "value"), + 1, nil, true) +check(qgrep("you have no private key", "stderr")) --- srv = bg(pure_mtn("serve", "--confdir="..test.root, "--keydir="..test.root.."/keys"), expected_ret, false, true) --- sleep(2) --- srv:finish() --- check(qgrep("beginning service", "stderr")) --- this should find a private key in the keys directory under the specified confdir +-- this should find a private key in the keys directory under the +-- specified confdir +check(pure_mtn("--confdir="..test.root, + "cert", rev, "test1", "value"), + 0, nil, nil) --- srv = bg(pure_mtn("serve", "--confdir="..test.root), expected_ret, false, true) --- sleep(2) --- srv:finish() --- check(qgrep("beginning service", "stderr")) +-- this should fail to find a private key, since there is no +-- keys subdirectory of this directory +check(pure_mtn("--confdir="..test.home, + "cert", rev, "fail2", "value"), + 1, nil, true) +check(qgrep("you have no private key", "stderr")) +-- this should find a private key in the specified keydir +check(pure_mtn("--confdir="..test.home, "--keydir="..test.root.."/keys", + "cert", rev, "test2", "value"), + 0, nil, nil) --- this should fail to decrypt the private key found in ~/.monotone/keys - --- however before get_default_keydir was added to the key_dir option in --- options_list.hh it would hit an invariant on an empty key_dir for any --- CMD_NO_WORKSPACE that attempted to call get_user_key(...) - --- The expected return value is the same on Unix and Windows - -mkdir(test.root.."/empty") --- FIXME: this should probably be set globally in lua-testsuite.lua for --- all tests. -set_env("HOME", test.root.."/empty") -srv = bg(pure_mtn("serve"), 1, false, true) -sleep(2) -srv:finish() -check(qgrep("misuse: you have no private key", "stderr")) - --- end of file ============================================================ --- tests/pid_file_and_log_handles_open_failures/__driver__.lua 1da5c1056509a1fa78b7492e9e9100228b8661f6 +++ tests/pid_file_and_log_handles_open_failures/__driver__.lua 9d10776466ab4ab193466e45a156a63f60491553 @@ -22,9 +22,13 @@ else check({"chmod", "100", "noaccess"}) check(mtn("--log=noaccess/my.log", "status"), 1, false, false) - srv = bg(mtn("serve", "--bind=127.0.0.2:55597", "--pid-file=noaccess/my.pid"), 1, false, false) - + -- we use --stdio here to avoid the possibility of the pidfile being + -- created and then the test tripping over network restrictions. + srv = bg(mtn("serve", "--stdio", "--pid-file=noaccess/my.pid"), + 1, nil, true, nil) + check(srv:wait(5)) + check(qgrep("failed to create pid file", "stderr")) end remove("noaccess") ============================================================ --- tests/ssh_agent/__driver__.lua 95cd8c83271295eacfdafa032182f9ee07ae1913 +++ tests/ssh_agent/__driver__.lua ab2aa35c08886878f31dcccd54f76e55e04a8bc5 @@ -290,3 +290,12 @@ end if not ok then err("identity was not added to ssh-agent") end + +-- * (ok) commit with passworded key (provide password explicitly, although will be not necessary as SSH-agent is used) +addfile("some_file21", "test") +check(mtn("ci", "--key", "address@hidden", "--message", "commit msg"), 0, false, false, "pass\n") + +-- * (ok) commit with passworded key (provide no password at all, because SSH-agent is used) +addfile("some_file22", "test") +check(mtn("ci", "--key", "address@hidden", "--message", "commit msg"), 0, false, false) + ============================================================ --- tests/syntax_errors_in_.mtn-ignore/stdout-ref 98b118d4a2e3bd4f52dcbe7c790a70f1b52aa901 +++ tests/syntax_errors_in_.mtn-ignore/stdout-ref 35ddfeda5089ea016cb0713fea9201fd00b5520b @@ -1,5 +1,6 @@ dontignoreme .mtn-ignore dontignoreme +emptyhomedir keys min_hooks.lua test_hooks.lua ============================================================ --- tests/two_parent_workspace_list/__driver__.lua 65c50373573076490512bf8852e35bb671f34ff7 +++ tests/two_parent_workspace_list/__driver__.lua 5d6df31659e888cf21e541121d487d3e5249e2df @@ -31,7 +31,7 @@ check(mtn("ls", "ignored"), 0, "keys\nte -- subdirectory for the workspace (and therefore to keep it cleaner) -- or to ignore them all properly, this will have to change. check(mtn("ls", "ignored"), 0, "keys\ntest.db\ntest_hooks.lua\nts-stderr\nts-stdin\nts-stdout\n", nil) -check(mtn("ls", "unknown"), 0, "_MTN.old\nmin_hooks.lua\npaths-new\npaths-old\nstderr\ntester.log\n", nil) +check(mtn("ls", "unknown"), 0, "_MTN.old\nemptyhomedir\nmin_hooks.lua\npaths-new\npaths-old\nstderr\ntester.log\n", nil) -- we do this after the other tests so it doesn't interfere with them. remove("file4")