[sysadmin-bin] run-git-or-special-cmd: check the git directory
- From: Owen Taylor <otaylor src gnome org>
- To: gnome-sysadmin gnome org,commits-list gnome org
- Subject: [sysadmin-bin] run-git-or-special-cmd: check the git directory
- Date: Fri, 6 Sep 2013 16:15:09 +0000 (UTC)
commit 55fcf6a0f19f8093b33fdc3b4da7b8c1c1d27c9b
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Fri Sep 6 10:47:31 2013 -0400
run-git-or-special-cmd: check the git directory
Check that the directory being accessed is in /git and has the
correct hooks.
https://bugzilla.gnome.org/show_bug.cgi?id=599066
run-git-or-special-cmd | 59 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 54 insertions(+), 5 deletions(-)
---
diff --git a/run-git-or-special-cmd b/run-git-or-special-cmd
index d2b683e..7b6caff 100755
--- a/run-git-or-special-cmd
+++ b/run-git-or-special-cmd
@@ -1,6 +1,8 @@
#!/usr/bin/python
+import grp
import os
+import pwd
import shlex
# vim: set ts=4 sw=4:
@@ -10,8 +12,52 @@ import shlex
# not world-readable
os.umask(0002)
+# We want to restrict the translations user; hopefully using
+# getpwuid() for this will be reasonably robust. If getpwuid()
+# fails this will throw an exception rather than getting a
+# false negative.
+username = pwd.getpwuid(os.getuid()).pw_name
+is_translations = username == 'translations'
+
+groups = os.getgroups()
+sysadmin_gid = grp.getgrnam('sysadmin').gr_gid
+is_sysadmin = sysadmin_gid in groups
+
+# os.path.normpath can't be used for security because it's
+# only textual and doesn't check symlinks.
+# /home/joe.smith/foo/../../../git isn't necessarily /git
+def normalize_path(path):
+ curpath = os.getcwd()
+ try:
+ os.chdir(path)
+ return os.getcwd()
+ except:
+ return None
+ finally:
+ os.chdir(curpath)
+
+def validate_git_dir(path):
+ path = normalize_path(path)
+ if path is None:
+ print >>sys.stderr, "git repository does not exist."
+ sys.exit(1)
+
+ if not path.startswith('/git/'):
+ print >>sys.stderr, "git repository is not in /git."
+ sys.exit(1)
+
+ if (not is_sysadmin and
+ (os.readlink(path + '/hooks/pre-receive') != '/home/admin/bin/git/gnome-pre-receive' or
+ os.readlink(path + '/hooks/post-receive') != '/home/admin/bin/git/gnome-post-receive')):
+ print >>sys.stderr, "git repository doesn't have required gnome.org hooks."
+ sys.exit(1)
+
+ return path
+
def rungitcommand(args):
- cmds = {
+ git_cmds =[ 'receive-pack', 'upload-pack', 'upload-archive' ]
+
+ special_cmds = {
'create-repository': '/home/admin/bin/git/create-repository',
'finish-import': '/home/admin/bin/git/finish-import',
# These allow 'git push --exec=force/import'
@@ -19,15 +65,18 @@ def rungitcommand(args):
'import': '/home/admin/bin/git/receive-pack-import',
}
- if args[0] in cmds:
- cmd = [cmds[args[0]]]
+ if args[0] in git_cmds:
+ validate_git_dir(args[1])
+ cmd = ['/usr/bin/git-shell', '-c', os.environ['SSH_ORIGINAL_COMMAND']]
+ elif args[0] in special_cmds and not is_translations:
+ cmd = [special_cmds[args[0]]]
cmd.extend(args[1:])
else:
- cmd = ['/usr/bin/git-shell', '-c', os.environ['SSH_ORIGINAL_COMMAND']]
+ print >>sys.stderr, 'Unknown command.'
+ sys.exit(1)
os.execv(cmd[0], cmd)
-
if __name__ == "__main__":
if 'SSH_ORIGINAL_COMMAND' in os.environ:
rungitcommand(shlex.split(os.environ['SSH_ORIGINAL_COMMAND']))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]