Execute script with git permissions

This commit is contained in:
Patrick Lühne 2020-05-26 05:44:08 +02:00
parent 0eb22fcfd9
commit 0eb9f4929d
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
3 changed files with 59 additions and 54 deletions

View File

@ -1,2 +1,2 @@
#/usr/bin/env bash #/usr/bin/env bash
/usr/lib/github-fast-env/github-fast-env.rb "$@" sudo /usr/lib/github-fast-env/github-fast-env.rb "$@"

View File

@ -176,11 +176,11 @@ while true
mode = arguments[1] mode = arguments[1]
if mode == "named-pipes" if mode == "named-pipes"
if arguments.length < 3 if arguments.length < 4
raise ClientError.new "malformed command" raise ClientError.new "malformed command"
end end
elsif mode == "pseudoterminal" elsif mode == "pseudoterminal"
if arguments.length < 4 if arguments.length < 5
raise ClientError.new "malformed command" raise ClientError.new "malformed command"
end end
@ -189,71 +189,75 @@ while true
raise ClientError.new "unknown mode (#{mode})" raise ClientError.new "unknown mode (#{mode})"
end end
script_path = Base64.decode64(arguments.last) working_directory = Base64.decode64(arguments[-2])
script_path = Base64.decode64(arguments[-1])
connection_id += 1 connection_id += 1
child_process = fork { child_process = fork {
process_id = Process.pid Dir.chdir(working_directory) do
control_socket.puts "pid #{process_id}" process_id = Process.pid
control_socket.puts "pid #{process_id}"
exit_code = "unknown" exit_code = "unknown"
if mode == "named-pipes" if mode == "named-pipes"
set_up_named_pipes(control_socket, connection_id) set_up_named_pipes(control_socket, connection_id)
else else
set_up_pseudoterminal(control_socket, pseudoterminal_path) set_up_pseudoterminal(control_socket, pseudoterminal_path)
end end
$original_stderr.puts " executing script #{script_path} (#{process_id})" Process.gid = Process.egid = "git"
Process.uid = Process.euid = "git"
$original_stderr.puts " executing script #{script_path} (#{process_id})"
begin
begin begin
load script_path, true begin
rescue SystemExit => error load script_path, true
$original_stderr.puts " exit code: #{error.status}" rescue SystemExit => error
exit_code = error.status $original_stderr.puts " exit code: #{error.status}"
exit_code = error.status
rescue StandardError => error
$stdin = $original_stdin
$stdout = $original_stdout
$stderr = $original_stderr
raise ClientScriptError.new error
end
rescue ClientScriptError => error
encoded_error_output = Base64.encode64(error.source.full_message).delete("\n")
$original_stderr.puts " error executing script, ignoring request"
begin
control_socket.puts "script_error #{encoded_error_output}"
rescue
end
rescue ClientError => error
$original_stderr.puts " error communicating with client, ignoring request (#{error})"
begin
control_socket.puts "error #{error}"
rescue
end
rescue StandardError => error rescue StandardError => error
$stdin = $original_stdin $original_stderr.puts " error, ignoring request (#{error})"
$stdout = $original_stdout begin
$stderr = $original_stderr control_socket.puts "error internal server error"
rescue
raise ClientScriptError.new error end
end end
rescue ClientScriptError => error
encoded_error_output = Base64.encode64(error.source.full_message).delete("\n")
$original_stderr.puts " error executing script, ignoring request"
begin begin
control_socket.puts "script_error #{encoded_error_output}" control_socket.puts "done #{exit_code}"
rescue rescue
end end
rescue ClientError => error control_socket.close
$original_stderr.puts " error communicating with client, ignoring request (#{error})"
begin if mode == "named-pipes"
control_socket.puts "error #{error}" clean_up_named_pipes(control_socket, connection_id)
rescue
end
rescue StandardError => error
$original_stderr.puts " error, ignoring request (#{error})"
begin
control_socket.puts "error internal server error"
rescue
end end
$original_stderr.puts " finished handling request (#{process_id})"
end end
begin
control_socket.puts "done #{exit_code}"
rescue
end
control_socket.close
if mode == "named-pipes"
clean_up_named_pipes(control_socket, connection_id)
end
$original_stderr.puts " finished handling request (#{process_id})"
Kernel.exit!
} }
Process.detach(child_process) Process.detach(child_process)

View File

@ -156,6 +156,7 @@ end
log "info", "connected to control socket" log "info", "connected to control socket"
working_directory = Base64.encode64(Dir.pwd).delete("\n")
encoded_script_path = Base64.encode64(script_path).delete("\n") encoded_script_path = Base64.encode64(script_path).delete("\n")
read_ios = [$control_socket] read_ios = [$control_socket]
@ -164,9 +165,9 @@ if $options[:interactive]
pseudoterminal_path = File.readlink("/proc/self/fd/0") pseudoterminal_path = File.readlink("/proc/self/fd/0")
encoded_pseudoterminal_path = Base64.encode64(pseudoterminal_path).delete("\n") encoded_pseudoterminal_path = Base64.encode64(pseudoterminal_path).delete("\n")
$control_socket.puts "new v1 pseudoterminal #{encoded_pseudoterminal_path} #{encoded_script_path}" $control_socket.puts "new v1 pseudoterminal #{encoded_pseudoterminal_path} #{working_directory} #{encoded_script_path}"
else else
$control_socket.puts "new v1 named-pipes #{encoded_script_path}" $control_socket.puts "new v1 named-pipes #{working_directory} #{encoded_script_path}"
end end
pipes = {"stdin" => nil, "stdout" => nil, "stderr" => nil} pipes = {"stdin" => nil, "stdout" => nil, "stderr" => nil}