bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
7476.2.1
by Jelmer Vernooij
Default to running Python 3. |
1 |
#!/usr/bin/env python3
|
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
2 |
###############################################################################
|
3 |
#
|
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
4 |
# brz_access:
|
5 |
# Simple access control for shared Breezy repository accessed over ssh.
|
|
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
6 |
#
|
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
7 |
# Copyright (C) 2007 Balint Aradi
|
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
8 |
#
|
3099.4.6
by John Arbash Meinel
Add GPL license to bzr_access script |
9 |
# This program is free software; you can redistribute it and/or modify
|
10 |
# it under the terms of the GNU General Public License as published by
|
|
11 |
# the Free Software Foundation; either version 2 of the License, or
|
|
12 |
# (at your option) any later version.
|
|
13 |
#
|
|
14 |
# This program is distributed in the hope that it will be useful,
|
|
15 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17 |
# GNU General Public License for more details.
|
|
18 |
#
|
|
19 |
# You should have received a copy of the GNU General Public License
|
|
20 |
# along with this program; if not, write to the Free Software
|
|
4183.7.1
by Sabin Iacob
update FSF mailing address |
21 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
3099.4.6
by John Arbash Meinel
Add GPL license to bzr_access script |
22 |
#
|
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
23 |
###############################################################################
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
24 |
"""
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
25 |
Invocation: brz_access <brz_executable> <repo_collection> <user>
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
26 |
|
27 |
The script extracts from the SSH_ORIGINAL_COMMAND environment variable the
|
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
28 |
repository, which Breezy tries to access through the brz+ssh protocol. The
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
29 |
repository is assumed to be relative to <repo_collection>. Based
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
30 |
on the configuration file <repo_collection>/brz_access.conf it determines
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
31 |
the access rights (denied, read-only, read-write) for the specified user.
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
32 |
If the user has read-only or read-write access a Breezy smart server is
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
33 |
started for it in read-only or in read-write mode, rsp., using the specified
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
34 |
brz executable.
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
35 |
|
36 |
Config file: INI format, pretty much similar to the authfile of subversion.
|
|
37 |
||
38 |
Groups can be defined in the [groups] section. The options in this block are
|
|
39 |
the names of the groups to be defined, the corresponding values the lists of
|
|
40 |
the users belonging to the given groups. (User names must be separated by
|
|
3112.1.4
by Balint Aradi
Changing example to show comma separated user names. |
41 |
commas.)
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
42 |
|
3475.1.1
by j at oil21
fix contrib/bzr_access |
43 |
Right now only one section is supported [/], defining the permissions for the
|
44 |
repository. The options in those sections are user names or group references
|
|
45 |
(group name with a leading '@'), the corresponding values are the
|
|
46 |
permissions: 'rw', 'r' and '' (without the quotes)
|
|
47 |
for read-write, read-only and no access, respectively.
|
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
48 |
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
49 |
Sample brz_access.conf::
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
50 |
|
51 |
[groups]
|
|
52 |
admins = alpha
|
|
3112.1.4
by Balint Aradi
Changing example to show comma separated user names. |
53 |
devels = beta, gamma, delta
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
54 |
|
3475.1.1
by j at oil21
fix contrib/bzr_access |
55 |
[/]
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
56 |
@admins = rw
|
57 |
@devels = r
|
|
58 |
||
3099.4.5
by John Arbash Meinel
A bit more documentation cleanup |
59 |
This allows you to set up a single SSH user, and customize the access based on
|
60 |
ssh key. Your ``.ssh/authorized_key`` file should look something like this::
|
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
61 |
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
62 |
command="/path/to/brz_access /path/to/brz /path/to/repository <username>",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-<type> <key>
|
3099.4.4
by John Arbash Meinel
Change initial comment into the docstring, and update snippets to be proper ReST |
63 |
"""
|
64 |
||
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
65 |
import ConfigParser |
3099.4.2
by John Arbash Meinel
Some simple spelling fixes, and switch to using subprocess since that is space-in-filename safe |
66 |
import os |
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
67 |
import re |
3099.4.2
by John Arbash Meinel
Some simple spelling fixes, and switch to using subprocess since that is space-in-filename safe |
68 |
import subprocess |
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
69 |
import sys |
70 |
||
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
71 |
CONFIG_FILE = "brz_access.conf" |
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
72 |
SCRIPT_NAME = os.path.basename(sys.argv[0]) |
73 |
||
74 |
# Permission constants
|
|
75 |
PERM_DENIED = 0 |
|
76 |
PERM_READ = 1 |
|
77 |
PERM_READWRITE = 2 |
|
78 |
PERM_DICT = { "r": PERM_READ, "rw": PERM_READWRITE } |
|
79 |
||
80 |
# Exit codes
|
|
81 |
EXIT_BAD_NR_ARG = 1 |
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
82 |
EXIT_brz_NOEXEC = 2 |
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
83 |
EXIT_REPO_NOREAD = 3 |
84 |
EXIT_BADENV = 4 |
|
85 |
EXIT_BADDIR = 5 |
|
86 |
EXIT_NOCONF = 6 |
|
87 |
EXIT_NOACCESS = 7 |
|
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
88 |
EXIT_BADUSERNAME = 8 |
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
89 |
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
90 |
# pattern for the brz command passed to ssh
|
91 |
PAT_SSH_COMMAND = re.compile(r"""^brz\s+ |
|
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
92 |
serve\s+
|
93 |
--inet\s+
|
|
94 |
--directory=(?P<dir>\S+)\s+
|
|
95 |
--allow-writes\s*$""", re.VERBOSE) |
|
96 |
||
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
97 |
# Command line for starting brz
|
98 |
brz_OPTIONS = ['serve', '--inet', '--directory'] |
|
99 |
brz_READWRITE_FLAGS = ['--allow-writes'] |
|
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
100 |
|
101 |
||
102 |
||
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
103 |
def error(msg, exit_code): |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
104 |
"""Prints error message to stdout and exits with given error code.""" |
105 |
||
106 |
print >>sys.stderr, "%s::error: %s" % (SCRIPT_NAME, msg) |
|
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
107 |
sys.exit(exit_code) |
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
108 |
|
109 |
||
110 |
||
111 |
class AccessManager(object): |
|
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
112 |
"""Manages the permissions, can be queried for a specific user and path.""" |
113 |
||
114 |
def __init__(self, fp): |
|
115 |
""":param fp: File like object, containing the configuration options. |
|
116 |
"""
|
|
6622.1.34
by Jelmer Vernooij
Rename brzlib => breezy. |
117 |
# TODO: jam 20071211 Consider switching to breezy.util.configobj
|
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
118 |
self.config = ConfigParser.ConfigParser() |
119 |
self.config.readfp(fp) |
|
120 |
self.groups = {} |
|
121 |
if self.config.has_section("groups"): |
|
122 |
for group, users in self.config.items("groups"): |
|
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
123 |
self.groups[group] = set([ s.strip() for s in users.split(",")]) |
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
124 |
|
125 |
||
3475.1.1
by j at oil21
fix contrib/bzr_access |
126 |
def permission(self, user): |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
127 |
"""Determines the permission for a given user and a given path |
128 |
:param user: user to look for.
|
|
129 |
:return: permission.
|
|
130 |
"""
|
|
3475.1.1
by j at oil21
fix contrib/bzr_access |
131 |
configSection = "/" |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
132 |
perm = PERM_DENIED |
3475.1.1
by j at oil21
fix contrib/bzr_access |
133 |
pathFound = self.config.has_section(configSection) |
134 |
if (pathFound): |
|
135 |
options = reversed(self.config.options(configSection)) |
|
136 |
for option in options: |
|
137 |
value = PERM_DICT.get(self.config.get(configSection, option), |
|
138 |
PERM_DENIED) |
|
139 |
if self._is_relevant(option, user): |
|
140 |
perm = value |
|
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
141 |
return perm |
3475.1.1
by j at oil21
fix contrib/bzr_access |
142 |
|
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
143 |
|
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
144 |
def _is_relevant(self, option, user): |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
145 |
"""Decides if a certain option is relevant for a given user. |
146 |
|
|
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
147 |
An option is relevant if it is identical with the user or with a
|
148 |
reference to a group including the user.
|
|
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
149 |
|
150 |
:param option: Option to check.
|
|
151 |
:param user: User
|
|
152 |
:return: True if option is relevant for the user, False otherwise.
|
|
153 |
"""
|
|
154 |
if option.startswith("@"): |
|
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
155 |
result = (user in self.groups.get(option[1:], set())) |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
156 |
else: |
157 |
result = (option == user) |
|
158 |
return result |
|
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
159 |
|
160 |
||
161 |
||
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
162 |
def get_directory(command): |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
163 |
"""Extracts the directory name from the command pass to ssh. |
164 |
:param command: command to parse.
|
|
165 |
:return: Directory name or empty string, if directory was not found or if it
|
|
166 |
does not start with '/'.
|
|
167 |
"""
|
|
168 |
match = PAT_SSH_COMMAND.match(command) |
|
169 |
if not match: |
|
170 |
return "" |
|
171 |
directory = match.group("dir") |
|
172 |
return os.path.normpath(directory) |
|
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
173 |
|
174 |
||
175 |
||
176 |
############################################################################
|
|
177 |
# Main program
|
|
178 |
############################################################################
|
|
179 |
def main(): |
|
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
180 |
# Read arguments
|
181 |
if len(sys.argv) != 4: |
|
182 |
error("Invalid number or arguments.", EXIT_BAD_NR_ARG) |
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
183 |
(brzExec, repoRoot, user) = sys.argv[1:4] |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
184 |
|
185 |
# Sanity checks
|
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
186 |
if not os.access(brzExec, os.X_OK): |
187 |
error("brz is not executable.", EXIT_brz_NOEXEC) |
|
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
188 |
if not os.access(repoRoot, os.R_OK): |
189 |
error("Path to repository not readable.", EXIT_REPO_NOREAD) |
|
190 |
||
191 |
# Extract the repository path from the command passed to ssh.
|
|
6619.3.8
by Jelmer Vernooij
Cope with has_key -> contains rename. |
192 |
if "SSH_ORIGINAL_COMMAND" not in os.environ: |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
193 |
error("Environment variable SSH_ORIGINAL_COMMAND missing.", EXIT_BADENV) |
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
194 |
directory = get_directory(os.environ["SSH_ORIGINAL_COMMAND"]) |
3112.1.5
by John Arbash Meinel
a small bit of cleanup. |
195 |
if len(directory) == 0: |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
196 |
error("Bad directory name.", EXIT_BADDIR) |
3112.1.3
by Balint Aradi
Tiny changes for more readable code and better compliance with bzr style. |
197 |
|
198 |
# Control user name
|
|
199 |
if not user.isalnum(): |
|
200 |
error("Invalid user name", EXIT_BADUSERNAME) |
|
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
201 |
|
202 |
# Read in config file.
|
|
203 |
try: |
|
204 |
fp = open(os.path.join(repoRoot, CONFIG_FILE), "r") |
|
205 |
try: |
|
206 |
accessMan = AccessManager(fp) |
|
207 |
finally: |
|
208 |
fp.close() |
|
209 |
except IOError: |
|
210 |
error("Can't read config file.", EXIT_NOCONF) |
|
211 |
||
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
212 |
# Determine permission and execute brz with appropriate options
|
3475.1.1
by j at oil21
fix contrib/bzr_access |
213 |
perm = accessMan.permission(user) |
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
214 |
command = [brzExec] + brz_OPTIONS + [repoRoot] |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
215 |
if perm == PERM_READ: |
216 |
# Nothing extra needed for readonly operations
|
|
217 |
pass
|
|
218 |
elif perm == PERM_READWRITE: |
|
219 |
# Add the write flags
|
|
6622.1.8
by Jelmer Vernooij
s/bzr_access/brz_access/ |
220 |
command.extend(brz_READWRITE_FLAGS) |
3099.4.3
by John Arbash Meinel
Change the indentation to 4 spaces according to Bazaar style guidelines. |
221 |
else: |
222 |
error("Access denied.", EXIT_NOACCESS) |
|
223 |
return subprocess.call(command) |
|
3099.4.1
by Bálint Aradi
Add a bzr_access script for allowing custom access control over bzr+ssh |
224 |
|
225 |
||
226 |
if __name__ == "__main__": |
|
227 |
main() |
|
228 |
||
229 |
||
230 |
### Local Variables:
|
|
231 |
### mode:python
|
|
232 |
### End:
|