# # add_file "tests/t_netsync_permissions.at" # # patch "ChangeLog" # from [ff8c5b74caec143b53b946742bcf9738c2c840c2] # to [cf58b0986a7cd99842cdadd0de78cbd64c580fff] # # patch "netsync.cc" # from [e1f885ae4739699f950e7d311e5d4bd8815ade54] # to [ab4461775be62d5f9e9a724632a8048a0d509803] # # patch "tests/t_netsync_permissions.at" # from [] # to [1150ab91c13b8c2e3640be346a1a4ba0306e0c72] # # patch "testsuite.at" # from [15e56f34d9bce816e570f1c0ed566d1b9b248eea] # to [df684acec26c92960c33b4d6a4235b1eb77513d7] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,10 @@ +2005-05-15 Derek Scherger + + * netsync.cc (process_anonymous_cmd, process_auth_cmd): log + details of permissions allowed/denied + * tests/t_netsync_permissions.at: new test + * testsuite.at: call it + 2005-05-14 Timothy Brownawell * contrib/monoprof.sh: Clean up variable definitions some. --- netsync.cc +++ netsync.cc @@ -1562,6 +1562,8 @@ // in our this->role field. // + // client must be a sink and server must be a source (anonymous read-only) + if (role != sink_role) { W(F("rejected attempt at anonymous connection for write\n")); @@ -1569,14 +1571,22 @@ return false; } - if (! ((this->role == source_role || this->role == source_and_sink_role) - && app.lua.hook_get_netsync_anonymous_read_permitted(collection))) + if (this->role != source_role && this->role != source_and_sink_role) { - W(F("anonymous read permission denied for '%s'\n") % collection); + W(F("rejected attempt at anonymous connection while running as sink\n")); this->saved_nonce = id(""); return false; } + if (!app.lua.hook_get_netsync_anonymous_read_permitted(collection)) + { + W(F("denied anonymous read permission for '%s'\n") % collection); + this->saved_nonce = id(""); + return false; + } + + P(F("allowed anonymous read permission for '%s'\n") % collection); + // get our private key and sign back L(F("anonymous read permitted, signing back nonce\n")); base64 sig; @@ -1666,28 +1676,48 @@ base64 their_key; app.db.get_pubkey(their_key_hash, their_id, their_key); + // client as sink, server as source (reading) + if (role == sink_role || role == source_and_sink_role) { - if (! ((this->role == source_role || this->role == source_and_sink_role) - && app.lua.hook_get_netsync_read_permitted(collection, - their_id()))) + if (this->role != source_role && this->role != source_and_sink_role) { - W(F("read permission denied for '%s'\n") % collection); + W(F("denied '%s' read permission for '%s' while running as sink\n") + % their_id % collection); this->saved_nonce = id(""); return false; } + + if (!app.lua.hook_get_netsync_read_permitted(collection, their_id())) + { + W(F("denied '%s' read permission for '%s'\n") % their_id % collection); + this->saved_nonce = id(""); + return false; + } + + P(F("allowed '%s' read permission for '%s'\n") % their_id % collection); } - + + // client as source, server as sink (writing) + if (role == source_role || role == source_and_sink_role) { - if (! ((this->role == sink_role || this->role == source_and_sink_role) - && app.lua.hook_get_netsync_write_permitted(collection, - their_id()))) + if (this->role != sink_role && this->role != source_and_sink_role) { - W(F("write permission denied for '%s'\n") % collection); + W(F("denied '%s' write permission for '%s' while running as source\n") + % their_id % collection); this->saved_nonce = id(""); return false; } + + if (!app.lua.hook_get_netsync_write_permitted(collection, their_id())) + { + W(F("denied '%s' write permission for '%s'\n") % their_id % collection); + this->saved_nonce = id(""); + return false; + } + + P(F("allowed '%s' write permission for '%s'\n") % their_id % collection); } // save their identity --- tests/t_netsync_permissions.at +++ tests/t_netsync_permissions.at @@ -0,0 +1,190 @@ +# -*- Autoconf -*- + +AT_SETUP([netsync permissions]) + +MONOTONE_SETUP + +# generate a new key + address@hidden +AT_CHECK((echo $OTHER; echo $OTHER) | MONOTONE genkey $OTHER, [], [ignore], [ignore]) + +NETSYNC_SETUP + +# test with open security settings + +AT_DATA(open.lua, [ +function get_netsync_read_permitted(collection, identity) + return true +end + +function get_netsync_write_permitted(collection, identity) + return true +end + +function get_netsync_anonymous_read_permitted(collection) + return true +end +]) + +AT_CHECK(cp test.db clean.db) + +ADD_FILE(testfile, [testfile +]) +AT_CHECK(MONOTONE --branch=testbranch commit --message testfile, [], [ignore], [ignore]) +BASE=`BASE_REVISION` + +NETSYNC_SERVE_START(testbranch --rcfile open.lua) + +# anonymous pull + +AT_CHECK(cp clean.db test2.db) +NETSYNC_CLIENT_RUN(pull --key="", testbranch) +AT_CHECK(MONOTONE2 cat revision $BASE, [0], [stdout], [stderr]) + +# pull with default key + +AT_CHECK(cp clean.db test2.db) +NETSYNC_CLIENT_RUN(pull, testbranch) +AT_CHECK(MONOTONE2 cat revision $BASE, [0], [stdout], [stderr]) + +# pull with other key + +AT_CHECK(cp clean.db test2.db) +NETSYNC_CLIENT_RUN(pull --key=$OTHER, testbranch) +AT_CHECK(MONOTONE2 cat revision $BASE, [0], [stdout], [stderr]) + +# pull with unknown key fails + +AT_CHECK(cp clean.db test2.db) address@hidden +AT_CHECK((echo $UNKNOWN; echo $UNKNOWN) | MONOTONE2 genkey $UNKNOWN, [], [ignore], [ignore]) +NETSYNC_CLIENT_RUN(pull --key=$UNKNOWN, testbranch) +AT_CHECK(MONOTONE2 cat revision $BASE, [1], [stdout], [stderr]) + +# push with default key + +AT_CHECK(cp test.db test2.db) +REVERT_TO($BASE) +ADD_FILE(default, [default +]) +AT_CHECK(MONOTONE2 commit --message default, [], [ignore], [ignore]) +DEFAULT_REV=`BASE_REVISION` +NETSYNC_CLIENT_RUN(push, testbranch) + +# push with other key + +REVERT_TO($BASE) +ADD_FILE(other, [other +]) +AT_CHECK(MONOTONE2 commit --message other, [], [ignore], [ignore]) +OTHER_REV=`BASE_REVISION` +NETSYNC_CLIENT_RUN(push --key=$OTHER , testbranch) + +# push with unknown key fails + +REVERT_TO($BASE) +ADD_FILE(unknown, [unknown +]) +AT_CHECK(MONOTONE2 commit --message unknown, [], [ignore], [ignore]) +UNKNOWN_REV=`BASE_REVISION` +AT_CHECK((echo $UNKNOWN; echo $UNKNOWN) | MONOTONE2 genkey $UNKNOWN, [], [ignore], [ignore]) +NETSYNC_CLIENT_RUN(push --key=$UNKNOWN, testbranch) + +NETSYNC_SERVE_STOP + +AT_CHECK(MONOTONE cat revision $DEFAULT_REV, [0], [stdout], [stderr]) +AT_CHECK(MONOTONE cat revision $OTHER_REV, [0], [stdout], [stderr]) +AT_CHECK(MONOTONE cat revision $UNKNOWN_REV, [1], [stdout], [stderr]) + + +# test with closed security settings + +AT_DATA(closed.lua, [ +function get_netsync_read_permitted(collection, identity) + if (identity == "address@hidden") then return true end + return false +end + +function get_netsync_write_permitted(collection, identity) + if (identity == "address@hidden") then return true end + return false +end + +function get_netsync_anonymous_read_permitted(collection) + return false +end +]) + +AT_CHECK(cp clean.db test.db) +AT_DATA(MT/revision []) + +ADD_FILE(testfile, [testfile +]) +AT_CHECK(MONOTONE --branch=testbranch commit --message testfile, [], [ignore], [ignore]) +BASE=`BASE_REVISION` + +NETSYNC_SERVE_START(testbranch --rcfile closed.lua) + +# anonymous pull fails + +AT_CHECK(cp clean.db test2.db) +NETSYNC_CLIENT_RUN(pull --key="", testbranch) +AT_CHECK(MONOTONE2 cat revision $BASE, [1], [stdout], [stderr]) + +# pull with default key + +AT_CHECK(cp clean.db test2.db) +NETSYNC_CLIENT_RUN(pull, testbranch) +AT_CHECK(MONOTONE2 cat revision $BASE, [0], [stdout], [stderr]) + +# pull with other key fails + +AT_CHECK(cp clean.db test2.db) +NETSYNC_CLIENT_RUN(pull --key=$OTHER, testbranch) +AT_CHECK(MONOTONE2 cat revision $BASE, [1], [stdout], [stderr]) + +# pull with unknown key fails + +AT_CHECK(cp clean.db test2.db) address@hidden +AT_CHECK((echo $UNKNOWN; echo $UNKNOWN) | MONOTONE2 genkey $UNKNOWN, [], [ignore], [ignore]) +NETSYNC_CLIENT_RUN(pull --key=$UNKNOWN, testbranch) +AT_CHECK(MONOTONE2 cat revision $BASE, [1], [stdout], [stderr]) + +# push with default key + +AT_CHECK(cp test.db test2.db) +REVERT_TO($BASE) +ADD_FILE(default, [default +]) +AT_CHECK(MONOTONE2 commit --message default, [], [ignore], [ignore]) +DEFAULT_REV=`BASE_REVISION` +NETSYNC_CLIENT_RUN(push, testbranch) + +# push with other key + +REVERT_TO($BASE) +ADD_FILE(other, [other +]) +AT_CHECK(MONOTONE2 commit --message other, [], [ignore], [ignore]) +OTHER_REV=`BASE_REVISION` +NETSYNC_CLIENT_RUN(push --key=$OTHER, testbranch) + +# push with unknown key fails + +REVERT_TO($BASE) +ADD_FILE(unknown, [unknown +]) +AT_CHECK(MONOTONE2 commit --message unknown, [], [ignore], [ignore]) +UNKNOWN_REV=`BASE_REVISION` +AT_CHECK((echo $UNKNOWN; echo $UNKNOWN) | MONOTONE2 genkey $UNKNOWN, [], [ignore], [ignore]) +NETSYNC_CLIENT_RUN(push --key=$UNKNOWN, testbranch) + +NETSYNC_SERVE_STOP + +AT_CHECK(MONOTONE cat revision $DEFAULT_REV, [0], [stdout], [stderr]) +AT_CHECK(MONOTONE cat revision $OTHER_REV, [1], [stdout], [stderr]) +AT_CHECK(MONOTONE cat revision $UNKNOWN_REV, [1], [stdout], [stderr]) + +AT_CLEANUP --- testsuite.at +++ testsuite.at @@ -643,3 +643,4 @@ m4_include(tests/t_commit_message_file.at) m4_include(tests/t_automate_attributes.at) m4_include(tests/t_unidiff3.at) +m4_include(tests/t_netsync_permissions.at)