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