summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Ipsum <richard.ipsum@codethink.co.uk>2014-01-13 17:08:29 +0000
committerRichard Ipsum <richard.ipsum@codethink.co.uk>2014-01-23 17:18:41 +0000
commit4ad632980d66816dec19c8c571a525297bbf182f (patch)
treecb987d88e9053c64382ec3cf53c92a32587049a7
parent0cfb688153bcc877820866d89cd2f60bfc739e6f (diff)
downloadgitano-4ad632980d66816dec19c8c571a525297bbf182f.tar.gz
is_authorized and check get requests are authd
-rwxr-xr-xcgi/gitano-smart-http.cgi199
1 files changed, 188 insertions, 11 deletions
diff --git a/cgi/gitano-smart-http.cgi b/cgi/gitano-smart-http.cgi
index 74ddd5e..18a6058 100755
--- a/cgi/gitano-smart-http.cgi
+++ b/cgi/gitano-smart-http.cgi
@@ -5,27 +5,204 @@ sio = require "luxio.simple"
stream = sio.stderr
+function is_authorized(cmdline)
+ --print("cmdline: " .. cmdline)
+ --print("package.path: " .. package.path .. '\n')
+
+ local gitano = require "gitano"
+ local gall = require "gall"
+ local luxio = require "luxio"
+ local sio = require "luxio.simple"
+ local sp = require "luxio.subprocess"
+
+ gitano.config.lib_bin_path("/usr/lib/gitano/bin")
+ gitano.config.share_path("/usr/share/gitano")
+
+ local repo_root = "/home/git/repos"
+ local username = "richardipsum" -- TODO: sort out
+ local keytag = "default"
+
+ local authorized = false
+
+ gitano.config.repo_path(repo_root)
+
+ --gitano.log.set_source("ssh")
+
+ local transactionid = gitano.log.syslog.open()
+
+ local parsed_cmdline, warnings = gitano.util.parse_cmdline(cmdline)
+
+ local start_log_level = gitano.log.get_level()
+ -- Clamp level at info until we have checked if the caller
+ -- is an admin or not
+ gitano.log.cap_level(gitano.log.level.INFO)
+
+ if (#warnings > 0) then
+ gitano.log.error("Warnings encountered parsing commandline.");
+ gitano.log.warn("\t" .. cmdline)
+ gitano.log.warn("")
+ gitano.log.warn("Parsed as:")
+ for i = 1, #parsed_cmdline do
+ gitano.log.warn((" =[%2d]> %s"):format(i, parsed_cmdline[i]))
+ end
+ gitano.log.warn("\nWarnings were:")
+ for i = 1, #warnings do
+ gitano.log.warn(" * " .. warnings[i])
+ end
+ gitano.log.warn("")
+ gitano.log.critical("Game over, sorry\n")
+ end
+
+ -- Now load the administration data
+
+ local admin_repo = gall.repository.new((repo_root or "") .. "/gitano-admin.git")
+
+ if not admin_repo then
+ gitano.log.critical("Unable to locate administration repository. Cannot continue");
+ end
+
+ local admin_head = admin_repo:get(admin_repo.HEAD)
+
+ if not admin_head then
+ gitano.log.critical("Unable to find the HEAD of the administration repository. Cannot continue");
+ end
+
+ local config, msg = gitano.config.parse(admin_head)
+
+ if not config then
+ gitano.log.critical("Unable to parse administration repository.")
+ gitano.log.critical(" * " .. (msg or "No error?"))
+ gitano.log.critical("Cannot continue")
+ end
+
+ -- Now, are we an admin?
+ if config.groups["gitano-admin"].filtered_members[username] then
+ -- Yep, so blithely reset logging level
+ gitano.log.set_level(start_log_level)
+ end
+
+ if not config.global.silent then
+ -- Not silent, bump to chatty level automatically
+ gitano.log.bump_level(gitano.log.level.CHAT)
+ end
+
+ local repo
+
+ -- Find the command
+
+
+ -- ip = string.match(luxio.getenv "SSH_CLIENT", "^[^ ]+") or ""
+
+ gitano.log.syslog.info("Client connected from", ip, "as", username,
+ "(" .. keytag .. ")", "Executing command:",
+ cmdline)
+
+ local cmd = gitano.command.get(parsed_cmdline[1])
+
+ if not cmd then
+ gitano.log.critical("Unknown command: " .. parsed_cmdline[1])
+ end
+
+ if cmd.takes_repo and #parsed_cmdline > 1 then
+ -- Acquire the repository object for the target repo
+ local msg
+ repo, msg = gitano.repository.find(config, parsed_cmdline[2])
+ if not repo then
+ gitano.log.critical("Unable to locate repository.")
+ gitano.log.critical(" * " .. (tostring(msg)))
+ gitano.log.critical("Cannot continue")
+ end
+
+ if repo.is_nascent then
+ gitano.log.info("Repository " .. repo.name .. " is nascent")
+ end
+ end
+
+ -- Validate the commandline, massaging it as necessary.
+
+ if not cmd.validate(config, repo, parsed_cmdline) then
+ gitano.log.critical("Validation of command line failed")
+ end
+
+ -- Construct our context ready for prep
+ local context = {
+ source = "ssh",
+ user = username,
+ keytag = keytag,
+ }
+
+ local action, reason = cmd.prep(config, repo, parsed_cmdline, context)
+
+ if not action then
+ gitano.log.critical(reason)
+ gitano.log.critical("Ruleset did not complete cleanly")
+ end
+
+ if action == "allow" then
+ gitano.log.info(reason or "Ruleset permitted action")
+ authorized = true
+ else
+ gitano.log.critical(reason)
+ gitano.log.critical("Ruleset denied action. Sorry.")
+ end
+
+ return authorized
+end
+
envbackup = {}
local names = {'PATH_INFO', 'REMOTE_USER', 'REMOTE_ADDR', 'CONTENT_TYPE',
'QUERY_STRING', 'REQUEST_METHOD'}
for _, name in pairs(names) do
- stream:write(name .. '\n') -- debug
- envbackup[name] = luxio.getenv(name)
+ s = luxio.getenv(name) or ""
+ stream:write("in: " .. name .. " " .. s .. "\n") -- debug
+ --envbackup[name] = luxio.getenv(name)
+ --stream:write(" " .. envbackup[name] .. '\n')
end
-local authorized = false
+request_method = os.getenv("REQUEST_METHOD")
-if authorized then
- os.execute("/usr/lib/git-core/git-http-backend")
-else
- print("Status: 403 Forbidden\r\n\r\n")
+function parse_get_request()
+ query_string = os.getenv("QUERY_STRING")
+
+ if query_string then
+ command = string.gsub(query_string, "^service=", "")
+ end
+
+ local cmdline = command .. " '" ..
+ string.match(os.getenv("PATH_INFO"), '/(.+)/info/refs') .. "'"
+
+ return cmdline
end
-for _, name in pairs(names) do
- if envbackup[name] then
- stream:write(name .. ": " .. envbackup[name] .. '\n') -- debug
- luxio.setenv(name, envbackup[name])
+--if command == "git-upload-pack" or command == "git-receive-pack" then
+
+if request_method == "GET" then
+ local cmdline = parse_get_request()
+
+ stream:write('cmdline: ' .. cmdline .. '\n') -- debug
+
+ local authorized = is_authorized(cmdline)
+
+ stream:write("authorized: " .. tostring(authorized) .. '\n') -- debug
+
+ if authorized == true then
+ -- set the push env var or whatever if push access is required
+ os.execute("/usr/lib/git-core/git-http-backend")
+ else
+ print("Status: 403 Forbidden\r\n\r\n")
end
+elseif request_method == "POST" then
+ os.execute("/usr/lib/git-core/git-http-backend")
+else
+ -- some sort of error happens
+ stream:write("no request method?")
end
+
+--for _, name in pairs(names) do
+-- if envbackup[name] then
+-- stream:write("out: " .. name .. ": " .. envbackup[name] .. '\n') -- debug
+-- luxio.setenv(name, envbackup[name])
+-- end
+--end