From 942b821d861aba1da43ef6c999141853e9f8b3a8 Mon Sep 17 00:00:00 2001 From: paulr Date: Wed, 9 Nov 2011 03:42:13 +1100 Subject: [PATCH 1/1] moved the old git poc code off and away from the main directory added a permission level "4" which is "can manage repo as an owner" - which only extends to site admins and repo owners. Replaces the gwvp_canManageRepo() function --- archive/gwvpgitbackend_poccode.php | 217 ++++++++++++++++++++++++++++++++++++ gwvplib/gwvpauth.php | 4 +- gwvplib/gwvpdebug.php | 17 +++ gwvplib/gwvpgitbackend.php | 217 ------------------------------------ gwvplib/gwvpgitcontrol.php | 28 +++++- gwvplib/gwvplib.php | 3 +- gwvplib/gwvprepoadmin.php | 2 +- gwvplib/gwvpweb.php | 4 - 8 files changed, 264 insertions(+), 228 deletions(-) create mode 100644 archive/gwvpgitbackend_poccode.php delete mode 100644 gwvplib/gwvpgitbackend.php diff --git a/archive/gwvpgitbackend_poccode.php b/archive/gwvpgitbackend_poccode.php new file mode 100644 index 0000000..9ad85ae --- /dev/null +++ b/archive/gwvpgitbackend_poccode.php @@ -0,0 +1,217 @@ + $var) { + if($key != "q") { + //error_log("adding, $var from $key"); + if($qs == "") $qs.="$key=$var"; + else $qs.="&$key=$var"; + } + } + + //sleep(2); + + + + // this is where the fun, it ends. + $myoutput = ""; + unset($myoutput); + + // this be nasty! + + // setup env + if(isset($procenv)) unset($procenv); + $procenv["GATEWAY_INTERFACE"] = "CGI/1.1"; + $procenv["PATH_TRANSLATED"] = "/var/cache/git/test.git$euri"; + $procenv["REQUEST_METHOD"] = "$rmeth"; + $procenv["GIT_HTTP_EXPORT_ALL"] = "1"; + $procenv["QUERY_STRING"] = "$qs"; + $procenv["HTTP_USER_AGENT"] = "git/1.7.1"; + $procenv["REMOTE_USER"] = "user"; + $procenv["REMOTE_ADDR"] = "1.2.3.4"; + $procenv["AUTH_TYPE"] = "Basic"; + + if(isset($_SERVER["CONTENT_TYPE"])) { + $procenv["CONTENT_TYPE"] = $_SERVER["CONTENT_TYPE"]; + } else { + //$procenv["CONTENT_TYPE"] = ""; + } + if(isset($_SERVER["CONTENT_LENGTH"])) { + $procenv["CONTENT_LENGTH"] = $_SERVER["CONTENT_LENGTH"]; + } + + + + $pwd = "/var/cache/git"; + + //error_log("openproc"); + $proc = proc_open("/usr/lib/git-core/git-http-backend", array(array("pipe","rb"),array("pipe","wb"),array("file","/tmp/err", "a")), $pipes, $pwd, $procenv); + //$proc = proc_open("/home/paulr/src/eclipse-workspace/gwvp/datacatch/../datacatcher.sh", array(array("pipe","r"),array("pipe","w"),array("file","/tmp/err", "a")), $pipes, $pwd, $procenv); + //error_log("openproc2, $proc"); + + //error_log("openproc3"); + + //if($rmeth == "POST") { + //} + + + //error_log("openproc4"); + + $untilblank = false; + while(!$untilblank&&!feof($pipes[1])) { + $lines_t = fgets($pipes[1]); + $lines = trim($lines_t); + error_log("got line: $lines"); + if($lines_t == "\r\n") { + $untilblank = true; + error_log("now blank"); + } else header($lines); + if($lines === false) { + error_log("got an unexpexted exit..."); + exit(0); + } + + } + + //error_log("openproc5"); + // if would seam that post and output must be synchronised together somehow... i think + /* + $fh = fopen('php://input', 'rb'); + if ($fh) { + while (!feof($fh)) { + $s = fread($fh, 1024); + if($s === false) { + error_log("unexpected eror on input read"); + } + fwrite($pipes[0], $s); + } + fclose($fh); + } + + // now the body + $fl = fopen("/tmp/pushpipe", "ab"); + while(!feof($pipes[1])) { + $d = fread($pipes[1], 1024); + error_log("got read, $d"); + if($d === false) { + errog_log("got unexpected false on reads"); + } else { + echo $d; + fwrite($fl, $d); + } + }*/ + + // oh god, something goes wrong with all this data and i dont know what it is + // but i think its cause proc_open doesnt deal with binary data properly + $firstline = true; + $continue = true; + //$fl = fopen("/tmp/pushpipe", "w"); + + if(!stream_set_blocking($fh,0)) { + error_log("cant set input non-blocking"); + } + // problem no 1 - dont do this + //if(!stream_set_blocking($pipes[0],0)) { + //error_log("cant set pipe 0 non-blocking"); + //} + if(!stream_set_blocking($pipes[1],0)) { + error_log("cant set pipe1 non-blocking"); + } + + // i was going to use stream_select, but i feel this works better like this + while($continue) { + // do client + if(!feof($fh)) { + $from_client_data = fread($fh,8192); + if($from_client_data !== false) fwrite($pipes[0], $from_client_data); + fflush($pipes[0]); + //fwrite($fl, $from_client_data); + $client_len = strlen($from_client_data); + } else { + error_log("client end"); + $client_len = 0; + } + + // do cgi + // sometimes, we get a \r\n from the cgi, i do not know why she swallowed the fly, + // but i do know that the fgets for the headers above should have comsued that + if(!feof($pipes[1])) { + $from_cgi_data_t = fread($pipes[1],8192); + $from_cgi_data = $from_cgi_data_t; + + // i dont know if this will solve it... it coudl cause some serious issues elsewhere + // TODO: this is a hack, i need to know why the fgets above doesn consume the \r\n even tho it reads it + // i.e. why the pointer doesnt increment over it, cause the freads above then get them again. + if($firstline) { + if(strlen($from_cgi_data_t)>0) { + $from_cgi_data = preg_replace("/^\r\n/", "", $from_cgi_data_t); + $firstline = false; + } + } + + if($from_cgi_data !== false) { + echo $from_cgi_data; + flush(); + } + $cgi_len = strlen($from_cgi_data); + } else { + error_log("cgi end"); + $cgi_len = 0; + } + + if(feof($pipes[1])) $continue = false; + else { + if($client_len == 0 && $cgi_len == 0) { + usleep(200000); + error_log("sleep tick"); + } else { + error_log("sizes: $client_len, $cgi_len"); + if($cgi_len > 0) { + error_log("from cgi: \"$from_cgi_data\""); + } + } + } + + } + + + //fclose($fl); + fclose($fh); + fclose($pipes[1]); + fclose($pipes[0]); + + //error_log("openproc6"); + + } +} + +?> \ No newline at end of file diff --git a/gwvplib/gwvpauth.php b/gwvplib/gwvpauth.php index e06fdde..2602256 100644 --- a/gwvplib/gwvpauth.php +++ b/gwvplib/gwvpauth.php @@ -39,8 +39,8 @@ function gwvp_AskForBasicAuth() { error_log("AUTH: asking for basic auth"); if(!isset($_SERVER["PHP_AUTH_USER"])) { - header('WWW-Authenticate: Basic realm="My Realm"'); - header('HTTP/1.0 401 Unauthorized'); + header('WWW-Authenticate: Basic realm="GIT Repo"'); + header('HTTP/1.1 401 Unauthorized'); } else return; } diff --git a/gwvplib/gwvpdebug.php b/gwvplib/gwvpdebug.php index dcc7c7a..4a5c303 100644 --- a/gwvplib/gwvpdebug.php +++ b/gwvplib/gwvpdebug.php @@ -8,6 +8,21 @@ function gwvp_DebugEnabled() { global $BASE_URL, $LOGIN_TYPE; + $isgitagent = false; + + // tested the user agent bit with jgit from eclipse and normal git... seems to work + if(isset($_SERVER["HTTP_USER_AGENT"])) { + $agent = $_SERVER["HTTP_USER_AGENT"]; + error_log("in git backend with user agent $agent"); + if(stristr($agent, "git")!==false) { + $isgitagent = true; + } + } + + // we dont wan to send this to a git agent + if($isgitagent) return; + + echo "
";
 	if(isset($_SERVER["PHP_AUTH_USER"])) error_log("authuser: ".$_SERVER["PHP_AUTH_USER"]."\n");
 	echo "USERTYPE: $LOGIN_TYPE\n";
@@ -148,6 +163,8 @@ function gwvp_DebugCall()
 function gwvp_DebugBody()
 {
 	global $BASE_URL;
+	
+	
 	?>
 	Generate error message
Generate info message
diff --git a/gwvplib/gwvpgitbackend.php b/gwvplib/gwvpgitbackend.php deleted file mode 100644 index 9ad85ae..0000000 --- a/gwvplib/gwvpgitbackend.php +++ /dev/null @@ -1,217 +0,0 @@ - $var) { - if($key != "q") { - //error_log("adding, $var from $key"); - if($qs == "") $qs.="$key=$var"; - else $qs.="&$key=$var"; - } - } - - //sleep(2); - - - - // this is where the fun, it ends. - $myoutput = ""; - unset($myoutput); - - // this be nasty! - - // setup env - if(isset($procenv)) unset($procenv); - $procenv["GATEWAY_INTERFACE"] = "CGI/1.1"; - $procenv["PATH_TRANSLATED"] = "/var/cache/git/test.git$euri"; - $procenv["REQUEST_METHOD"] = "$rmeth"; - $procenv["GIT_HTTP_EXPORT_ALL"] = "1"; - $procenv["QUERY_STRING"] = "$qs"; - $procenv["HTTP_USER_AGENT"] = "git/1.7.1"; - $procenv["REMOTE_USER"] = "user"; - $procenv["REMOTE_ADDR"] = "1.2.3.4"; - $procenv["AUTH_TYPE"] = "Basic"; - - if(isset($_SERVER["CONTENT_TYPE"])) { - $procenv["CONTENT_TYPE"] = $_SERVER["CONTENT_TYPE"]; - } else { - //$procenv["CONTENT_TYPE"] = ""; - } - if(isset($_SERVER["CONTENT_LENGTH"])) { - $procenv["CONTENT_LENGTH"] = $_SERVER["CONTENT_LENGTH"]; - } - - - - $pwd = "/var/cache/git"; - - //error_log("openproc"); - $proc = proc_open("/usr/lib/git-core/git-http-backend", array(array("pipe","rb"),array("pipe","wb"),array("file","/tmp/err", "a")), $pipes, $pwd, $procenv); - //$proc = proc_open("/home/paulr/src/eclipse-workspace/gwvp/datacatch/../datacatcher.sh", array(array("pipe","r"),array("pipe","w"),array("file","/tmp/err", "a")), $pipes, $pwd, $procenv); - //error_log("openproc2, $proc"); - - //error_log("openproc3"); - - //if($rmeth == "POST") { - //} - - - //error_log("openproc4"); - - $untilblank = false; - while(!$untilblank&&!feof($pipes[1])) { - $lines_t = fgets($pipes[1]); - $lines = trim($lines_t); - error_log("got line: $lines"); - if($lines_t == "\r\n") { - $untilblank = true; - error_log("now blank"); - } else header($lines); - if($lines === false) { - error_log("got an unexpexted exit..."); - exit(0); - } - - } - - //error_log("openproc5"); - // if would seam that post and output must be synchronised together somehow... i think - /* - $fh = fopen('php://input', 'rb'); - if ($fh) { - while (!feof($fh)) { - $s = fread($fh, 1024); - if($s === false) { - error_log("unexpected eror on input read"); - } - fwrite($pipes[0], $s); - } - fclose($fh); - } - - // now the body - $fl = fopen("/tmp/pushpipe", "ab"); - while(!feof($pipes[1])) { - $d = fread($pipes[1], 1024); - error_log("got read, $d"); - if($d === false) { - errog_log("got unexpected false on reads"); - } else { - echo $d; - fwrite($fl, $d); - } - }*/ - - // oh god, something goes wrong with all this data and i dont know what it is - // but i think its cause proc_open doesnt deal with binary data properly - $firstline = true; - $continue = true; - //$fl = fopen("/tmp/pushpipe", "w"); - - if(!stream_set_blocking($fh,0)) { - error_log("cant set input non-blocking"); - } - // problem no 1 - dont do this - //if(!stream_set_blocking($pipes[0],0)) { - //error_log("cant set pipe 0 non-blocking"); - //} - if(!stream_set_blocking($pipes[1],0)) { - error_log("cant set pipe1 non-blocking"); - } - - // i was going to use stream_select, but i feel this works better like this - while($continue) { - // do client - if(!feof($fh)) { - $from_client_data = fread($fh,8192); - if($from_client_data !== false) fwrite($pipes[0], $from_client_data); - fflush($pipes[0]); - //fwrite($fl, $from_client_data); - $client_len = strlen($from_client_data); - } else { - error_log("client end"); - $client_len = 0; - } - - // do cgi - // sometimes, we get a \r\n from the cgi, i do not know why she swallowed the fly, - // but i do know that the fgets for the headers above should have comsued that - if(!feof($pipes[1])) { - $from_cgi_data_t = fread($pipes[1],8192); - $from_cgi_data = $from_cgi_data_t; - - // i dont know if this will solve it... it coudl cause some serious issues elsewhere - // TODO: this is a hack, i need to know why the fgets above doesn consume the \r\n even tho it reads it - // i.e. why the pointer doesnt increment over it, cause the freads above then get them again. - if($firstline) { - if(strlen($from_cgi_data_t)>0) { - $from_cgi_data = preg_replace("/^\r\n/", "", $from_cgi_data_t); - $firstline = false; - } - } - - if($from_cgi_data !== false) { - echo $from_cgi_data; - flush(); - } - $cgi_len = strlen($from_cgi_data); - } else { - error_log("cgi end"); - $cgi_len = 0; - } - - if(feof($pipes[1])) $continue = false; - else { - if($client_len == 0 && $cgi_len == 0) { - usleep(200000); - error_log("sleep tick"); - } else { - error_log("sizes: $client_len, $cgi_len"); - if($cgi_len > 0) { - error_log("from cgi: \"$from_cgi_data\""); - } - } - } - - } - - - //fclose($fl); - fclose($fh); - fclose($pipes[1]); - fclose($pipes[0]); - - //error_log("openproc6"); - - } -} - -?> \ No newline at end of file diff --git a/gwvplib/gwvpgitcontrol.php b/gwvplib/gwvpgitcontrol.php index 842d040..7c34d9b 100644 --- a/gwvplib/gwvpgitcontrol.php +++ b/gwvplib/gwvpgitcontrol.php @@ -6,6 +6,9 @@ $CALL_ME_FUNCTIONS["gitcontrol"] = "gwvp_gitControlCallMe"; //$MENU_ITEMS["20repos"]["link"] = "$BASE_URL/admin/repos"; $HOME_PAGE_PROVIDERS["gitlog"] = "gwvp_GitLogProvider"; +// TODO: we could actually change backend interface such that is +// will respond to any url's that contain "repo.git" rather then +// having to be $BASE_URL/git/repo.git function gwvp_gitControlCallMe() { if(isset($_REQUEST["q"])) { @@ -42,6 +45,20 @@ function gwvp_gitBackendInterface() // TODO: we need to stop passing the repo name around as "repo.git", it needs to be just "repo" + + /* bizare git problem that ignores 403's or continues on with a push despite them + error_log("FLAP for ".$_SERVER["REQUEST_URI"]); + if(isset($_REQUEST)) { + $dump = print_r($_REQUEST, true); + error_log("FLAP, $dump"); + } + if(isset($_SERVER["PHP_AUTH_USER"])) { + error_log("FLAP: donut hole"); + }*/ + + + + $repo = ""; $repoid = false; $newloc = "/"; @@ -71,12 +88,18 @@ function gwvp_gitBackendInterface() $write = false; if(isset($_REQUEST["service"])) { if($_REQUEST["service"] == "git-receive-pack") { + error_log("got write as receivepack in post"); $write = true; } } if($_SERVER["REQUEST_METHOD"] == "POST") { $write = true; } + // THIS MAY CAUSE ISSUES LATER ON but we do it cause the git client ignores our 403 when it uses git-receive-pack after an auth + // no, this isnt a solution cause auth'd read attempts will come up as writes... + //if(isset($_SERVER["PHP_AUTH_USER"])) { + //$write = true; + //} // if its a write, we push for authentication if($write) { @@ -465,6 +488,7 @@ function gwvp_createGitRepo($name, $ownerid, $desc, $bundle=null, $defaultperms= // 1 - visible // 2 - read // 3 - write +// 4 - owner/administrator function gwvp_resolvRepoPerms($userid, $repoid) { $ownerid = gwvp_getRepoOwner($repoid); @@ -472,9 +496,9 @@ function gwvp_resolvRepoPerms($userid, $repoid) error_log("USerid is $userid, ownerid $ownerid"); - if($isadmin) return 3; + if($isadmin) return 4; - if($userid == $ownerid) return 3; + if($userid == $ownerid) return 4; // now we load the perms table and pray $repoperms = gwvp_getRepoPermissions($repoid); diff --git a/gwvplib/gwvplib.php b/gwvplib/gwvplib.php index 0158b45..9850e97 100644 --- a/gwvplib/gwvplib.php +++ b/gwvplib/gwvplib.php @@ -2,7 +2,6 @@ require_once("gwvpweb.php"); -require_once("gwvpgitbackend.php"); require_once("gwvpuseradmin.php"); require_once("gwvprepoadmin.php"); require_once("gwvpauth.php"); @@ -17,7 +16,7 @@ require_once("gwvpemail.php"); require_once("gwvppluginloader.php"); // only enable this if you need it: -//require_once("gwvpdebug.php"); +require_once("gwvpdebug.php"); ?> \ No newline at end of file diff --git a/gwvplib/gwvprepoadmin.php b/gwvplib/gwvprepoadmin.php index cc78ba4..cb533bf 100644 --- a/gwvplib/gwvprepoadmin.php +++ b/gwvplib/gwvprepoadmin.php @@ -265,7 +265,7 @@ function gwvp_RepoAdminPageBody() $manordetslink = "details"; $manordets = "Details"; if(isset($_SESSION["id"])) { - if(gwvp_canManageRepo($_SESSION["id"], $rid)) { + if(gwvp_resolvRepoPerms($_SESSION["id"], $rid)>3) { $manordetslink = "manage"; $manordets = "Manage"; } diff --git a/gwvplib/gwvpweb.php b/gwvplib/gwvpweb.php index b9e7e1b..f01e537 100644 --- a/gwvplib/gwvpweb.php +++ b/gwvplib/gwvpweb.php @@ -154,7 +154,6 @@ function gwvp_MenuBuilder() ksort($MENU_ITEMS); - echo "\n\n\n"; echo ""; foreach($MENU_ITEMS as $key => $val) { $link = $val["link"]; @@ -187,7 +186,6 @@ function gwvp_MenuBuilder() } } echo "
Menu
"; - echo "\n\n\n"; } @@ -195,14 +193,12 @@ function gwvp_LoginBuilder() { global $WEB_ROOT_FS, $BASE_URL; - echo "\n\n\n"; $login = gwvp_IsLoggedIn(); if($login === false) { gwvp_SingleLineLoginForm(); } else { echo "Hello, ".gwvp_GetFullName($login)." logout"; } - echo "\n\n\n"; } // builds the body structure -- 1.7.0.4