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