v0.2 add mapping username and smarter upstream_file

This commit is contained in:
tgic 2014-12-29 19:50:15 +08:00 committed by Boshi Lian
parent 1cd4e41a3e
commit 7b0704d475
5 changed files with 119 additions and 20 deletions

View file

@ -39,12 +39,6 @@ var (
versionTemplate *template.Template
)
func init() {
initConfig()
initTemplate()
initLogger()
}
func initTemplate() {
configTemplate = template.Must(template.New("config").Parse(`
Listening : {{.ListenAddr}}:{{.Port}}

View file

@ -37,6 +37,9 @@ func main() {
showHelpOrVersion()
showVersion()
initConfig()
initTemplate()
initLogger()
showConfig()
// TODO make this pluggable

View file

@ -6,13 +6,15 @@
package main
import (
"bufio"
"bytes"
"fmt"
"github.com/tg123/sshpiper/ssh"
"io/ioutil"
"net"
"os"
"strings"
"github.com/tg123/sshpiper/ssh"
)
type userFile string
@ -56,29 +58,72 @@ func (file userFile) checkPerm(user string) error {
return nil
}
func findUpstreamFromUserfile(conn ssh.ConnMetadata) (net.Conn, error) {
func parseUpstreamFile(data string) (string, string) {
var user string
var line string
r := bufio.NewReader(strings.NewReader(data))
for {
var err error
line, err = r.ReadString('\n')
if err != nil {
break
}
line = strings.TrimSpace(line)
if line != "" && line[0] != '#' {
break
}
}
t := strings.SplitN(line, "@", 2)
if len(t) > 1 {
user = t[0]
line = t[1]
}
// test if ok
if _, _, err := net.SplitHostPort(line); err != nil && line != "" {
// test valid after concat :22
if _, _, err := net.SplitHostPort(line + ":22"); err == nil {
line += ":22"
}
}
return line, user
}
func findUpstreamFromUserfile(conn ssh.ConnMetadata) (net.Conn, string, error) {
user := conn.User()
err := UserUpstreamFile.checkPerm(user)
if err != nil {
return nil, err
return nil, "", err
}
addr, err := UserUpstreamFile.read(user)
data, err := UserUpstreamFile.read(user)
if err != nil {
return nil, err
return nil, "", err
}
saddr := strings.TrimSpace(string(addr))
addr, mappedUser := parseUpstreamFile(string(data))
logger.Printf("mapping user [%s] to [%s]", user, saddr)
if addr == "" {
return nil, "", fmt.Errorf("empty addr")
}
c, err := net.Dial("tcp", saddr)
logger.Printf("mapping user [%v] to [%v@%v]", user, mappedUser, addr)
c, err := net.Dial("tcp", addr)
if err != nil {
return nil, err
return nil, "", err
}
return c, nil
return c, mappedUser, nil
}
func mapPublicKeyFromUserfile(conn ssh.ConnMetadata, key ssh.PublicKey) (ssh.Signer, error) {

View file

@ -124,6 +124,63 @@ func (s stubConnMetadata) ServerVersion() []byte { return nil }
func (s stubConnMetadata) RemoteAddr() net.Addr { return nil }
func (s stubConnMetadata) LocalAddr() net.Addr { return nil }
func TestParseUpstreamFile(t *testing.T) {
var addr, user string
addr, user = parseUpstreamFile(`
a:123
`)
if addr != "a:123" || user != "" {
t.Fatalf("parse failed common with port")
}
addr, user = parseUpstreamFile(`
a:123
b:456
`)
if addr != "a:123" || user != "" {
t.Fatalf("parse multi line")
}
addr, user = parseUpstreamFile(`
host
`)
if addr != "host:22" || user != "" {
t.Fatalf("parse no port")
}
addr, user = parseUpstreamFile(`
user@github.com
`)
if addr != "github.com:22" || user != "user" {
t.Fatalf("parse no port with user")
}
addr, user = parseUpstreamFile(``)
if addr != "" || user != "" {
t.Fatalf("empty file")
}
addr, user = parseUpstreamFile(`
# comment
user@github.com
test@linode.com
`)
if addr != "github.com:22" || user != "user" {
t.Fatalf("multi line with comment")
}
}
func TestFindUpstreamFromUserfile(t *testing.T) {
user := "testuser"
buildWorkingDir([]string{user}, t)
@ -154,7 +211,7 @@ func TestFindUpstreamFromUserfile(t *testing.T) {
}
t.Logf("testing file too open")
_, err = findUpstreamFromUserfile(stubConnMetadata{user})
_, _, err = findUpstreamFromUserfile(stubConnMetadata{user})
if err == nil {
t.Fatalf("should return err when file too open")
}
@ -165,7 +222,7 @@ func TestFindUpstreamFromUserfile(t *testing.T) {
}
t.Logf("testing conn dial to %v", addr)
conn, err := findUpstreamFromUserfile(stubConnMetadata{user})
conn, _, err := findUpstreamFromUserfile(stubConnMetadata{user})
if err != nil {
t.Fatalf("findUpstreamFromUserfile failed %v", err)
}
@ -186,7 +243,7 @@ func TestFindUpstreamFromUserfile(t *testing.T) {
}
t.Logf("testing user not found")
_, err = findUpstreamFromUserfile(stubConnMetadata{"nosuchuser"})
_, _, err = findUpstreamFromUserfile(stubConnMetadata{"nosuchuser"})
if err == nil {
t.Fatalf("should return err when finding nosuchuser")
}

2
ver
View file

@ -1 +1 @@
v0.1
v0.2.dev