From 18cd12eb0dbe5f75bfcdb798e54d70d1b5776d2d Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Sat, 13 Sep 2014 18:20:45 -0700 Subject: [PATCH] authrequired.cgi: use an 'ERR ' packet for older Git versions If a smart push is attempted and it appears that the client is an older version of Git, send the error message as an 'ERR ' packet instead of a text/plain response so the client can display it. In this case "older" is defined as Git < 1.8.3 or a different client entirely such as JGit or libgit2. --- cgi/authrequired.cgi | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/cgi/authrequired.cgi b/cgi/authrequired.cgi index dca7db9..f179205 100755 --- a/cgi/authrequired.cgi +++ b/cgi/authrequired.cgi @@ -17,7 +17,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# Version 1.0 +# Version 1.1 # We pretend like we don't exist. Unless this was an attempt to access a # push URL over HTTPS in which case we return a suitable error message in plain @@ -32,6 +32,13 @@ # provide a user name and password is completely pointless since we now are # providing copious amounts of help text. +# If the client appears to be an older version of Git that will probably not +# display a text/plain error response to the user then the error message is +# sent as an 'ERR ' packet in smart protocol format instead. Git versions +# older than 1.8.3 as well as JGit and libgit require the 'ERR ' packet format. +# This 'ERR ' packet format support requires that REQUEST_URI be set to the +# original URI that was fetched or it will never trigger. + set -e headers() { @@ -40,6 +47,7 @@ headers() { printf '%s\r\n' "Pragma: no-cache" printf '%s\r\n' "Cache-Control: no-cache, max-age=0, must-revalidate" printf '%s\r\n' "Content-Type: $2" + [ -z "$3" ] || printf "%s\r\n" "$3" printf '\r\n' } @@ -67,11 +75,28 @@ EOF # Set isgit if we've detected a Git client or a Git-only URL isgit= +isoldgit= case "$HTTP_USER_AGENT" in *[Gg]it/*) isgit=1 + case "$HTTP_USER_AGENT" in + *[Jj][Gg]it/*) + isoldgit=1 + ;; + *) + suffix="${HTTP_USER_AGENT##*[Gg]it/}" + gitvers="${suffix%%[!0-9.]*}" + gitvers="${gitvers%.}" + case "$gitvers" in + [1-9][0-9]*|[2-9]|[2-9].*|1.[1-9][0-9]*|1.9*| \ + 1.8.[1-9][0-9]*|1.8.[3-9]|1.8.[3-9].*) :;; + *) + isoldgit=1 + esac + esac esac needsauth=1 +service= if [ -n "$REQUEST_URI" ]; then # Try to detect whether or not it was something that needs auth needsauth= @@ -81,6 +106,7 @@ if [ -n "$REQUEST_URI" ]; then case "$BASE" in */info/refs) case "&$QS&" in *"&service=git-receive-pack&"*) + service=git-receive-pack case "$BASE" in /r/*) needsauth=1 @@ -92,6 +118,7 @@ if [ -n "$REQUEST_URI" ]; then esac ;; */git-receive-pack) + service=git-receive-pack case "$BASE" in /r/*) needsauth=1 @@ -112,8 +139,7 @@ fi . @basedir@/shlib.sh if [ -n "$isgit" ]; then - headers 403 "text/plain" - cat <