Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 92 lines (74 sloc) 2.899 kb
3ec1a3c @DanBUK Adding git limit script
DanBUK authored
1 #!/usr/bin/python
2
3 # Copyright (c) 2007 Tommi Virtanen <tv@eagain.net>
4 #
5 # Permission is hereby granted, free of charge, to any person
6 # obtaining a copy of this software and associated documentation files
7 # (the "Software"), to deal in the Software without restriction,
8 # including without limitation the rights to use, copy, modify, merge,
9 # publish, distribute, sublicense, and/or sell copies of the Software,
10 # and to permit persons to whom the Software is furnished to do so,
11 # subject to the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 # SOFTWARE.
24
25 # Enforce git-shell to only serve repositories
26 # in the given directory. The client should refer
27 # to them without any directory prefix.
28 # Repository names are forced to match ALLOW.
29
30 import sys, os, optparse, re
31
32 def die(msg):
33 print >>sys.stderr, '%s: %s' % (sys.argv[0], msg)
34 sys.exit(1)
35
36 def getParser():
37 parser = optparse.OptionParser(
38 usage='%prog [OPTIONS] DIR',
39 description='Allow restricted git operations under DIR',
40 )
41 parser.add_option('--read-only',
42 help='disable write operations',
43 action='store_true',
44 default=False,
45 )
46 return parser
47
48 ALLOW_RE = re.compile("^(?P<command>git-(?:receive|upload)-pack) '[a-zA-Z0-9@._-]*(/[a-zA-Z0-9@._-]*)*'$")
49
50 COMMANDS_READONLY = [
51 'git-upload-pack',
52 ]
53
54 COMMANDS_WRITE = [
55 'git-receive-pack',
56 ]
57
58 def main(args):
59 os.umask(0022)
60
61 parser = getParser()
62 (options, args) = parser.parse_args()
63 try:
64 (path,) = args
65 except ValueError:
66 parser.error('Missing argument DIR.')
67 os.chdir(path)
68
69 cmd = os.environ.get('SSH_ORIGINAL_COMMAND', None)
70 if cmd is None:
71 die("Need SSH_ORIGINAL_COMMAND in environment.")
72
73 if '\n' in cmd:
74 die("Command may not contain newlines.")
75
76 match = ALLOW_RE.match(cmd)
77 if match is None:
78 die("Command to run looks dangerous")
79
80 allowed = list(COMMANDS_READONLY)
81 if not options.read_only:
82 allowed.extend(COMMANDS_WRITE)
83
84 if match.group('command') not in allowed:
85 die("Command not allowed")
86
87 os.execve('/usr/bin/git-shell', ['git-shell', '-c', cmd], {})
88 die("Cannot execute git-shell.")
89
90 if __name__ == '__main__':
91 main(args=sys.argv[1:])
Something went wrong with that request. Please try again.