Do not use `date -d` as it's not portable
[girocco.git] / bin / git-http-backend-verify
bloba7d43e327ca74a38c17e0e9d0ea45544dad5be01
1 #!/bin/sh
3 # Abort any push early if the pushing user doesn't have any push permissions
4 # at all. This avoids unnecessary traffic and unpacked object pollution.
6 # Set GIT_HTTP_BACKEND_BIN to change the default http-backend binary from
7 # the default of Config.pm $git_http_backend_bin (which itself has a default
8 # of "/usr/lib/git-core/git-http-backend")
10 # Note that GIT_PROJECT_ROOT must be set to use this script.
12 set -e
14 . @basedir@/shlib.sh
16 [ -z "$GIT_HTTP_BACKEND_BIN" ] || cfg_git_http_backend_bin="$GIT_HTTP_BACKEND_BIN"
17 [ -n "$cfg_git_http_backend_bin" ] ||
18 cfg_git_http_backend_bin=/usr/lib/git-core/git-http-backend
20 # This script is called for both fetch and push.
21 # Only the following conditions trigger a push permissions check:
23 # 1. REQUEST_METHOD=GET
24 # and PATH_INFO ends with "/info/refs"
25 # and QUERY_STRING has "service=git-receive-pack"
27 # 2. REQUEST_METHOD=POST
28 # and PATH_INFO ends with "/git-receive-pack"
30 # Note that there is no check for PATH_INFO being under a certain root as
31 # it's presumed that GIT_PROJECT_ROOT has been set and so all PATH_INFO
32 # values are effectively forced under the desired root.
33 # The project name is, however, extracted and the project directory must exist
34 # under $cfg_reporoot.
36 errorhdrs()
38 # A single CR (0x0d) is between the quotes
39 cr=" "
40 echo "Status: $1 $2$cr"
41 echo "Expires: Fri, 01 Jan 1980 00:00:00 GMT$cr"
42 echo "Pragma: no-cache$cr"
43 echo "Cache-Control: no-cache, max-age=0, must-revalidate$cr"
44 echo "Content-Type: text/plain$cr"
45 echo "$cr"
48 msglines()
50 while [ $# -gt 0 ]; do
51 echo "$1"
52 shift
53 done
56 internalerr()
58 errorhdrs 500 "Internal Server Error"
59 if [ $# -eq 0 ]; then
60 msglines "Internal Server Error"
61 else
62 msglines "$@"
64 exit 0
67 forbidden()
69 errorhdrs 403 Forbidden
70 if [ $# -eq 0 ]; then
71 msglines "Forbidden"
72 else
73 msglines "$@"
75 exit 0
78 needsauth()
80 errorhdrs 401 "Authorization Required"
81 if [ $# -eq 0 ]; then
82 msglines "Authorization Required"
83 else
84 msglines "$@"
86 exit 0
89 [ -n "$GIT_PROJECT_ROOT" ] || { internalerr 'GIT_PROJECT_ROOT must be set'; exit 1; }
91 proj=
92 needscheck=
93 pathcheck="${PATH_INFO#/}"
94 if [ "$REQUEST_METHOD" = "GET" -o "$REQUEST_METHOD" = "HEAD" ]; then
95 case "$pathcheck" in *"/info/refs")
96 case "&$QUERY_STRING&" in *"&service=git-receive-pack&"*)
97 needscheck=1
98 proj="${pathcheck%/info/refs}"
99 esac
100 esac
101 elif [ "$REQUEST_METHOD" = "POST" ]; then
102 case "$pathcheck" in *"/git-receive-pack")
103 needscheck=1
104 proj="${pathcheck%/git-receive-pack}"
105 esac
108 [ -n "$needscheck" ] ||
109 { exec "$cfg_git_http_backend_bin" "$@"; forbidden "exec failed: $cfg_git_http_backend_bin"; exit 1; }
111 # add a missing trailing .git
112 case "$proj" in
113 *.git) :;;
115 proj="$proj.git"
116 esac
118 dir="$cfg_reporoot/$proj"
119 if ! [ -d "$dir" ] || ! [ -f "$dir/HEAD" ] || ! [ -d "$dir/objects" ]; then
120 forbidden
121 exit 1
124 projbare="${proj%.git}"
126 if ! [ -f "$dir/.nofetch" ]; then
127 forbidden "The $proj project is a mirror and may not be pushed to, sorry"
128 exit 1
131 authuser="${REMOTE_USER#/UID=}"
132 authuuid="${authuser}"
133 authuser="${authuser%/dnQualifier=*}"
134 authuuid="${authuuid#$authuser}"
135 authuuid="${authuuid#/dnQualifier=}"
136 if [ -z "$authuser" ]; then
137 needsauth "Only authenticated users may push, sorry"
138 exit 1
141 if perl -I@basedir@ -MGirocco::Project -MGirocco::User <<EOT; then :; else
142 my \$p = Girocco::Project->load('$projbare');
143 exit 1 unless \$p && \$p->can_user_push('$authuser');
144 exit 0 if \$Girocco::Config::mob eq 'mob' && '$authuser' eq 'mob';
145 my \$u = Girocco::User->load('$authuser');
146 exit 2 unless \$u && \$u->{uuid} eq '$authuuid';
147 exit 0
149 if [ $? -eq 2 ]; then
150 forbidden "The user '$authuser' certificate being used is no longer valid." \
151 "You may download a new user certificate at $cfg_webadmurl/edituser.cgi"
152 else
153 forbidden "The user '$authuser' does not have push permissions for project '$proj'." \
154 "You may adjust push permissions at $cfg_webadmurl/editproj.cgi?name=$proj"
156 exit 1
159 exec "$cfg_git_http_backend_bin" "$@"
160 forbidden "exec failed: $cfg_git_http_backend_bin"
161 exit 1