feat(ssh_command): now it works@@ -35,10 +35,9 @@ const onSSHAuth: ReqHandler<AppRouteParams, AppRoute.SSH_AUTH> = async (
if (
authMode === GitServer.AuthMode.NEVER ||
- (authMode === GitServer.AuthMode.PUSH_ONLY &&
- command !== "git-receive-pack") // push
+ (authMode === GitServer.AuthMode.PUSH_ONLY && command !== "git-upload-pack") // pull
) {
- console.log("Successful auth:", {
+ console.log("Successfull auth:", {
authMode,
command,
gitRepositoryDir,
@@ -34,11 +34,12 @@ SIDEBAND_PREFIX = "0008" + "\x02"
SIDEBAND_ERR_PREFIX = "0008" + "\x03"
# ---------- Helpers ----------
-def write_to_file(msg : String)
+def write_to_file(msg : String, divider : Bool = false)
txt = msg.gsub(SIDEBAND_PREFIX, "").gsub(SIDEBAND_ERR_PREFIX, "")
File.open(LOG_FILE, mode: "a", encoding: "utf-8") do |file|
file.flock_exclusive # prevent concurrent writes
- file.print "#{txt.ends_with?("\n") ? txt : txt + "\n"}"
+ file.print "\n#{"=" * 80}\n\n" if divider
+ file.print "[#{Time.utc.to_unix}] #{txt.ends_with?("\n") ? txt : txt + "\n"}"
file.flush
file.flock_unlock
end
@@ -177,15 +178,13 @@ if user.nil? || key_blob.nil?
die_with_message "usage: ssh-key-wrapper <user> <key_blob> [fingerprint]", 2
end
+SSH_ORIGINAL_COMMAND = ENV["SSH_ORIGINAL_COMMAND"]?.try(&.to_s) || ""
-write_to_file("new connection: #{user} -> #{key_blob} (#{fingerprint})\n")
-
-if ENV["SSH_ORIGINAL_COMMAND"]?.nil?
+if SSH_ORIGINAL_COMMAND.chomp == ""
die_with_message "Script has not been invoked by ssh. Missing environment variable SSH_ORIGINAL_COMMAND.", 2
end
-SSH_ORIGINAL_COMMAND = ENV["SSH_ORIGINAL_COMMAND"]?.try(&.to_s) || ""
-
+write_to_file("new client: #{user} -> #{key_blob} (#{fingerprint || "none"})\n", true)
write_to_file("command: #{SSH_ORIGINAL_COMMAND}\n")
org_repo = extract_org_repo(SSH_ORIGINAL_COMMAND)
@@ -220,42 +219,30 @@ begin
})
if resp.status != HTTP::Status::OK
- die_with_message("Key validation failed (auth service returned #{resp.status_code})")
- # end
- # if j.is_a?(Hash) && j["success"]?.try(&.as_bool) == true
- # authorized
+ die_with_message("Key validation: disallowed (#{resp.status_code} - #{resp.status_message})")
else
- j = JSON.parse(resp.body) rescue nil
- write_to_file("[ok] Got authorization (/_ssh/auth)\n")
- write_to_file("auth response: #{resp.body.to_json.to_s}\n")
- # pp j
# authorized
- # todo: handle authMode
- if j && j.is_a?(Hash)
- repoDir = j.as_h["gitRepositoryDir"].to_s
- end
- # todo: check command hasn't been tampered
+ write_to_file("Key validation: allowed (200 - OK)\n")
+ write_to_file("> #{resp.body.to_s}\n")
+ json = JSON.parse(resp.body)
+ repoDir = json.as_h["gitRepositoryDir"].to_s
end
-rescue ex
- die_with_message("Key validation error: #{ex.message}")
-end
-
-if repoDir.chomp == ""
- die_with_message("Something went wrong. Missing repository directory on the server.")
+rescue ex : Exception
+ die_with_message("Key validation: error: #{ex.message}")
end
write_to_file("repo_dir: #{repoDir}\n")
# ---------- Step 3: dispatch by SSH_ORIGINAL_COMMAND ----------
-if SSH_ORIGINAL_COMMAND.starts_with?("git-receive-pack")
+if SSH_ORIGINAL_COMMAND.starts_with?("git-receive-pack") # push
mode = :receive
-elsif SSH_ORIGINAL_COMMAND.starts_with?("git-upload-pack") || SSH_ORIGINAL_COMMAND.starts_with?("git-upload-archive")
+elsif SSH_ORIGINAL_COMMAND.starts_with?("git-upload-pack") || SSH_ORIGINAL_COMMAND.starts_with?("git-upload-archive") # clone/fetch/pull
mode = :upload
else
die_with_message("Unsupported command: only git-receive-pack, git-upload-pack, git-upload-archive are allowed")
end
-# sideband_println("Auth OK; allowing command (#{SSH_ORIGINAL_COMMAND.split(' ')[0]})")
+write_to_file("mode: #{mode.to_s}\n")
# For upload (fetch/pull), just exec the original command (auth already done).
if mode == :upload