/** * Serve a git request. * * @param string Username. * @param string Command to be run. */ public function serve($username, $cmd) { if (false !== strpos($cmd, "\n")) { throw new Exception('Command may not contain newline.'); } $splitted = preg_split('/\\s/', $cmd, 2); if (count($splitted) != 2) { throw new Exception('Unknown command denied.'); } if ($splitted[0] == 'git') { $sub_splitted = preg_split('/\\s/', $splitted[1], 2); if (count($sub_splitted) != 2) { throw new Exception('Unknown command denied.'); } $verb = sprintf('%s %s', $splitted[0], $sub_splitted[0]); $args = $sub_splitted[1]; } else { $verb = $splitted[0]; $args = $splitted[1]; } if (!in_array($verb, $this->commands_write) and !in_array($verb, $this->commands_readonly)) { throw new Exception('Unknown command denied.'); } if (!preg_match($this->preg, $args, $matches)) { throw new Exception('Arguments to command look dangerous.'); } $path = $matches['path']; // Check read/write rights $new_path = $this->haveAccess($username, $path, 'writable'); if ($new_path == false) { $new_path = $this->haveAccess($username, $path, 'readonly'); if ($new_path == false) { throw new Exception('Repository read access denied.'); } if (in_array($verb, $this->commands_write)) { throw new Exception('Repository write access denied.'); } } list($topdir, $relpath) = $new_path; $repopath = sprintf('%s.git', $relpath); $fullpath = $topdir . DIRECTORY_SEPARATOR . $repopath; if (!file_exists($fullpath) and in_array($verb, $this->commands_write)) { // it doesn't exist on the filesystem, but the // configuration refers to it, we're serving a write // request, and the user is authorized to do that: create // the repository on the fly $p = explode(DIRECTORY_SEPARATOR, $fullpath); $mpath = implode(DIRECTORY_SEPARATOR, array_slice($p, 0, -1)); if (!file_exists($mpath)) { mkdir($mpath, 0750, true); } $this->initRepository($fullpath); $this->setGitExport($relpath, $fullpath); } $new_cmd = sprintf("%s '%s'", $verb, $fullpath); Pluf_Log::info(array('IDF_Plugin_Git_Serve::serve', $username, $cmd, $new_cmd)); return $new_cmd; }