preliminary git-proxy
This commit is contained in:
parent
e6631a053c
commit
0426760211
|
@ -0,0 +1,3 @@
|
||||||
|
module git.coolaj86.com/coolaj86/git-scripts/git-proxy
|
||||||
|
|
||||||
|
go 1.12
|
|
@ -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
|
||||||
|
}
|
|
@ -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.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue