From d6c488fe6b60f2bc9156410902088c1a69fef0ce Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 14 Nov 2019 15:09:34 -0500 Subject: [PATCH] gitsrht-shell: add comments --- gitsrht-shell/main.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/gitsrht-shell/main.go b/gitsrht-shell/main.go index ff7e04c..e258b12 100644 --- a/gitsrht-shell/main.go +++ b/gitsrht-shell/main.go @@ -26,6 +26,15 @@ const ( ) func main() { + // gitsrht-shell runs after we've authenticated the SSH session as an + // authentic agent of a particular account, but before we've checked if + // they have permission to perform the git operation they're trying to do. + // Our job is to: + // + // 1. Find the repo they're trying to access, and handle redirects + // 2. Check if they're allowed to do the thing they're trying to + // 3. exec(2) into the git binary that does the rest of the work + var ( config ini.File err error @@ -44,6 +53,7 @@ func main() { cmd []string ) + // Initialization and set up, collect our runtime needs log.SetFlags(0) logf, err := os.OpenFile("/var/log/gitsrht-shell", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) @@ -98,6 +108,7 @@ func main() { cmdstr = "" } + // Grab the command the user is trying to execute cmd, err = shlex.Split(cmdstr) if err != nil { logger.Fatalf("Unable to parse command: %v", err) @@ -105,6 +116,7 @@ func main() { logger.Println("Running git.sr.ht shell") + // Make sure it's a git command that we're expecting validCommands := []string{ "git-receive-pack", "git-upload-pack", "git-upload-archive", } @@ -124,6 +136,7 @@ func main() { os.Chdir(repos) + // Validate the path that they're trying to access is in the repos directory path := cmd[len(cmd)-1] path, err = filepath.Abs(path) if err != nil { @@ -134,11 +147,18 @@ func main() { } cmd[len(cmd)-1] = path + // Check what kind of access they're interested in needsAccess := ACCESS_READ if cmd[0] == "git-receive-pack" { needsAccess = ACCESS_WRITE } + // Fetch the necessary info from SQL. This first query fetches: + // + // 1. Repository information, such as visibility (public|unlisted|private) + // 2. Information about the repository owner's account + // 3. Information about the pusher's account + // 4. Any access control policies for that repo that apply to the pusher pgcs, ok := config.Get("git.sr.ht", "connection-string") if !ok { logger.Fatalf("No connection string configured for git.sr.ht: %v", err) @@ -184,6 +204,9 @@ func main() { logger.Printf("Lookup failed: %v", err) logger.Println("Looking up redirect") + // If looking up the repo failed, it might have been renamed. Look for a + // corresponding redirect, and grab all of the same information that we + // need for the new repo while we're at it. row = db.QueryRow(` SELECT repo.id, @@ -210,6 +233,11 @@ func main() { logger.Printf("Lookup failed: %v", err) + // There wasn't a repo or a redirect by this name, so maybe the user + // is pushing to a repo that doesn't exist. If so, autocreate it. + // + // If an error occurs at this step, we just log it internally and + // tell the user we couldn't find the repo they're asking after. repoName = gopath.Base(path) repoOwnerName = gopath.Base(gopath.Dir(path)) if repoOwnerName != "" { @@ -291,6 +319,8 @@ func main() { } } + // We have everything we need, now we find out if the user is allowed to do + // what they're trying to do. hasAccess := ACCESS_NONE if pusherId == repoOwnerId { hasAccess = ACCESS_READ | ACCESS_WRITE | ACCESS_MANAGE @@ -336,6 +366,10 @@ func main() { os.Exit(128) } + // At this point, we know they're allowed to execute this operation. We + // gather some of the information we've collected so far into a "push + // context" so that steps later in the pipeline don't have to repeat our + // lookups, then exec(2) into git. type RepoContext struct { Id int `json:"id"` Name string `json:"name"` -- 2.38.4