preliminary git-proxy

This commit is contained in:
AJ ONeal 2019-06-01 20:59:40 -06:00
parent e6631a053c
commit 0426760211
4 changed files with 150 additions and 0 deletions

3
git-proxy/go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.coolaj86.com/coolaj86/git-scripts/git-proxy
go 1.12

59
git-proxy/parseargs.go Normal file
View File

@ -0,0 +1,59 @@
package main
import (
"fmt"
"strings"
"unicode"
)
const NullStr = rune(0)
// ParseArgs will parse a string that contains quoted strings the same as bash does
// (same as most other *nix shells do). This is secure in the sense that it doesn't do any
// executing or interpeting. However, it also doesn't do any escaping, so you shouldn't pass
// these strings to shells without escaping them.
func ParseArgs(str string) ([]string, error) {
var m []string
var s string
str = strings.TrimSpace(str) + " "
lastQuote := NullStr
isSpace := false
for i, c := range str {
switch {
// If we're ending a quote, break out and skip this character
case c == lastQuote:
lastQuote = NullStr
// If we're in a quote, count this character
case lastQuote != NullStr:
s += string(c)
// If we encounter a quote, enter it and skip this character
case unicode.In(c, unicode.Quotation_Mark):
isSpace = false
lastQuote = c
// If it's a space, store the string
case unicode.IsSpace(c):
if 0 == i || isSpace {
continue
}
isSpace = true
m = append(m, s)
s = ""
default:
isSpace = false
s += string(c)
}
}
if lastQuote != NullStr {
return nil, fmt.Errorf("Quotes did not terminate")
}
return m, nil
}

View File

@ -0,0 +1,45 @@
package main
import (
"fmt"
"log"
"strings"
"testing"
)
func TestStrings(t *testing.T) {
tests := [][]string{
[]string{
` a 'b' '' '"d" e' " f " ""''""''''"""" g"h"'i'jkl'mno'pqr $("dangerous dangerous danger-ous-ous-ous")`,
"a", "b", "", `"d" e`, " f ", "", "ghijklmnopqr", "$(dangerous dangerous danger-ous-ous-ous)",
},
[]string{
` arg1 arg2 ' hello world'"'" '' " ' another hello world ' " `,
"arg1", "arg2", " hello world'", "", " ' another hello world ' ",
},
[]string{
`arg1 arg2 ' hello world'"'" " "" ' another hello world ' "`,
"arg1", "arg2", " hello world'", " ' another hello world ' ",
},
[]string{
` arg1 arg2 ' hello world'"'" "" " ' another hello world ' "`,
"arg1", "arg2", " hello world'", "", " ' another hello world ' ",
},
[]string{
`arg1 arg2 ' hello world'"'" "" " ' another hello world ' `,
},
}
for i := range tests {
strs := tests[i]
in := strs[0]
expected := strs[1:]
actual, _ := ParseArgs(in)
if strings.Join(actual, "#") != strings.Join(expected, "#") {
fmt.Printf("Expected: %#v\n", expected)
fmt.Printf("Actual: %#v\n", actual)
log.Fatal("Test failed.")
}
}
}

43
git-proxy/proxy.go Normal file
View File

@ -0,0 +1,43 @@
package main
import (
"errors"
"fmt"
"log"
"os"
"os/exec"
)
var ErrGitOnlyShell = errors.New("You've successfully authenticated, but this is a git-only shell")
var gitcmds = map[string]bool{
"git-receive-pack": true,
"git-upload-pack": true,
"git-upload-archive": true,
}
func main() {
cmds, err := ParseArgs(os.Getenv("SSH_ORIGINAL_COMMAND"))
if nil != err {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
if len(cmds) < 2 {
fmt.Fprintf(os.Stderr, "%s\n", ErrGitOnlyShell)
os.Exit(1)
}
bin := cmds[0]
_, ok := gitcmds[bin]
if !ok {
fmt.Fprintf(os.Stderr, "%s\n", ErrGitOnlyShell)
os.Exit(1)
}
args := cmds[1:]
cmd := exec.Command(bin, args...)
cmd.Env = append(os.Environ(), "GIT_PROXY=true")
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}