#
# patch "ChangeLog"
# from [a24ce791acb8bd531e77e9df290a5bdedd056645]
# to [62f84027102e0ef51d71f5d62d5c58ae6e2eafa8]
#
# patch "monotone.texi"
# from [e2d963f7d556623abd609e6511a5a45b026d765b]
# to [303b2ddca2046e2e602515b2b72927f6a4dee8bb]
#
# patch "std_hooks.lua"
# from [7035181f8e65b9fd1a41718fb9b225cf62ab8276]
# to [d9534c87d99f1e4ac6159f1e4c6bf63eee72dd81]
#
========================================================================
--- ChangeLog a24ce791acb8bd531e77e9df290a5bdedd056645
+++ ChangeLog 62f84027102e0ef51d71f5d62d5c58ae6e2eafa8
@@ -1,5 +1,11 @@
2005-10-23 Timothy Brownawell
+ * std_hooks.lua: new default get_netsync_*_permitted hooks, which
+ read permissions setting from $confdir/{read,write}-permissions
+ * monotone.texi: document the new default hooks
+
+2005-10-23 Timothy Brownawell
+
* contrib/usher.cc: new option "-p ", catch SIGTERM and SIGINT
and exit cleanly
========================================================================
--- monotone.texi e2d963f7d556623abd609e6511a5a45b026d765b
+++ monotone.texi 303b2ddca2046e2e602515b2b72927f6a4dee8bb
@@ -1623,23 +1623,20 @@
@end smallexample
Now Jim's monotone is able to identify Beth and Abe, and he is ready to
-give them permission to access his database. He does this by adding a
-small amount of extra information to his @file{monotonerc} file:
+give them permission to access his database. He does this by editing a
+pair of small files in his @file{~/.monotone} directory:
@smallexample
@group
-$ cat >>~/.monotone/monotonerc
-function get_netsync_read_permitted (branch, identity)
- if (identity == "abe@@juicebot.co.jp") then return true end
- if (identity == "beth@@juicebot.co.jp") then return true end
- return false
-end
+$ cat >>~/.monotone/read-permissions
+[*]
+abe@@juicebot.co.jp
+beth@@juicebot.co.jp
+^D
-function get_netsync_write_permitted (identity)
- if (identity == "abe@@juicebot.co.jp") then return true end
- if (identity == "beth@@juicebot.co.jp") then return true end
- return false
-end
+$ cat >>~/.monotone/write-permissions
+abe@@juicebot.co.jp
+beth@@juicebot.co.jp
^D
@end group
@end smallexample
@@ -5900,9 +5897,36 @@
Returns @code{true} if a peer authenticated as key @var{identity}
should be allowed to read from your database certs, revisions,
manifests, and files associated with @var{branch}; otherwise @code{false}.
-This hook has no default definition, therefore the default behavior is
-to deny all reads.
+The default definition of this hook reads a file @file{read-permissions} in
+the configuration directory. This file looks like
address@hidden
address@hidden
+[net.example.project.security*]
+[net.example.project.private*]
+! --all--
+joe@@example.net
+jim@@example.net
+[net.example.public*]
+[net.example.project*]
+--all--
address@hidden group
address@hidden smallexample
+This example allows everyone access to branches @code{net.example.project} and
address@hidden and their sub-branches, except for the branches in
address@hidden and @code{net.example.private}, which are only
+readable by Joe and Jim.
+The file is divided into sections of one or more lines in square brackets
+followed by one or more lines not in square brackets. A line in square brackets
+is a wildcard expression, which is matched against the @var{branch}. If one
+matches, then the other lines in that section are compared against
address@hidden A line @code{keyname} allows @code{keyname} read access, and a
+line @code{! keyname} denies access. The special value @code{--all--} allows
+read access to everyone (including anonymous), and @code{! --all--} means that
+only keys allowed by this section have access. Without @code{! --all--}, if a
+key is neither allowed nor denied permission in a section, the hook will keep
+looking for matching sections in the rest of the file.
+
If a client connects anonymously, this hook will be called with a
@var{identity} of @code{nil}.
@@ -5917,8 +5941,10 @@
Returns @code{true} if a peer authenticated as key @var{identity} should
be allowed to write into your database certs, revisions, manifests, and
-files; otherwise @code{false}. This hook has no default definition,
-therefore the default behavior is to deny all writes.
+files; otherwise @code{false}. The default definition of this hook reads a file
address@hidden in the configuration directory which contains a list
+of keys, one per line, which are allowed write access. The special value
address@hidden means to allow access to anyone whose public key we already have.
If a client connects anonymously, it will be unconditionally denied
write access; this hook will @emph{not} be called with a @var{identity}
========================================================================
--- std_hooks.lua 7035181f8e65b9fd1a41718fb9b225cf62ab8276
+++ std_hooks.lua d9534c87d99f1e4ac6159f1e4c6bf63eee72dd81
@@ -781,3 +781,67 @@
os.remove (new_file);
end
+function wildcard_match(glob, str)
+ local pat = string.gsub(glob, "([%^%$%(%)%%%.%*%+%-%?])", "%%%1")
+ pat = string.gsub(pat, "%%%*", ".*")
+ pat = string.gsub(pat, "%%%?", ".")
+ pat = string.gsub(pat, "%[!", "%[%^")
+ return string.find(str, pat)
+end
+
+function get_netsync_read_permitted(branch, ident)
+ local permfile = io.open(get_confdir() .. "/read-permissions", "r")
+ if (permfile == nil) then return false end
+ local fallthrough = true
+ local first = true
+ local line = permfile:read()
+ while line ~= nil and (first or fallthrough) do
+ -- find the appropriate section
+ local gotbr
+ while (line ~= nil and not gotbr) do
+ local foo, _, pat = string.find(line, "^%[(.*)%]$")
+ if foo then
+ gotbr = wildcard_match(pat, branch)
+ end
+ line = permfile:read()
+ end
+ -- several [glob] lines immediately following eachother
+ -- share a list of allowed keys
+ while (line ~= nil and string.find(line, "^%[.*%]$")) do
+ line = permfile:read()
+ end
+ -- no matching entries
+ if not gotbr then return false end
+ -- check that section only
+ while (line ~= nil and not string.find(line, "^%[.*%]$")) do
+ local _, _, ln = string.find(line, "%s*([^%s]*)%s*")
+ local _, _, notln = string.find(line, "%s*!%s+([^%s]*)%s*")
+ if ln == "--all--" then return true end
+ if notln == "--all--" then fallthrough = false end
+ if ident ~= nil then
+ if ln == ident then return true end
+ if notln == ident then return false end
+ end
+ line = permfile:read()
+ end
+ first = false
+ end
+ io.close(permfile)
+ return false
+end
+
+function get_netsync_write_permitted(ident)
+ local permfile = io.open(get_confdir() .. "/write-permissions", "r")
+ if (permfile == nil) then
+ return false
+ end
+ local line = permfile:read()
+ while (line ~= nil) do
+ local _, _, ln = string.find(line, "%s*([^%s]*)%s*")
+ if ln == "--all--" then return true end
+ if ln == ident then return true end
+ line = permfile:read()
+ end
+ io.close(permfile)
+ return false
+end