feat(ssh_command): now it works
+ 18
- 32
app/controllers/ssh-auth.ts
@@ -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,

packages/gitfoss-ssh-command/src/ssh-command.cr
@@ -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