#
# 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)