diff --git a/README.md b/README.md index f01a1750..4f002dfa 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,8 @@ sshpiper reads `workingdir/github/sshpiper_upstream` and the connect to the upst #### User files +*These file MUST be in mode 400* + * sshpiper_upstream one line file `upstream_host:port` e.g. `github.com:22` @@ -169,8 +171,6 @@ sshpiper use a [modified version](ssh) of [golang.org/x/crypto/ssh](http://golan ## TODO List - * more friendly log - * check of key's perm * additional challenge (like google authenticator support) before send auth to upstream * deb package * live upgrade diff --git a/sshpiperd/example/showme.sh b/sshpiperd/example/showme.sh index 90873b9f..4ddf8153 100755 --- a/sshpiperd/example/showme.sh +++ b/sshpiperd/example/showme.sh @@ -8,8 +8,7 @@ fi echo "Using go path $GOPATH" -if [ ! -f $GOPATH/bin/sshpiperd ];then - go get github.com/tg123/sshpiper/sshpiperd +if [ ! -f $GOPATH/bin/sshpiperd ] || [ $GOPATH/bin/sshpiperd -ot $GOPATH/src/github.com/tg123/sshpiper ];then go install github.com/tg123/sshpiper/sshpiperd fi @@ -21,6 +20,7 @@ if [ ! -f $BASEDIR/sshpiperd_key ];then fi for u in `find $BASEDIR/workingdir/ -name sshpiper_upstream`; do + chmod 400 $u upstream=`cat $u` username=`dirname $u` diff --git a/sshpiperd/sshpiperd.go b/sshpiperd/sshpiperd.go index 16a8b926..6b40f727 100644 --- a/sshpiperd/sshpiperd.go +++ b/sshpiperd/sshpiperd.go @@ -39,20 +39,6 @@ func init() { flag.Parse() } -func parsePrivateKeyFile(filename string) (ssh.Signer, error) { - privateBytes, err := ioutil.ReadFile(filename) - if err != nil { - return nil, err - } - - private, err := ssh.ParsePrivateKey(privateBytes) - if err != nil { - return nil, err - } - - return private, nil -} - func userSpecFile(user, file string) string { return fmt.Sprintf("%s/%s/%s", WorkingDir, user, file) } @@ -65,7 +51,27 @@ func (file userFile) realPath(user string) string { return userSpecFile(user, string(file)) } -// TODO log +// return error if not 400, nil if 400 and no err occurs +func (file userFile) check400(user string) error { + filename := userSpecFile(user, string(file)) + f, err := os.Open(filename) + if err != nil { + return err + } + defer f.Close() + + fi, err := f.Stat() + if err != nil { + return err + } + + if fi.Mode().Perm() != 0400 { + return fmt.Errorf("%v's perm is too open, change it to 400", filename) + } + + return nil +} + func main() { if ShowHelp { @@ -76,15 +82,21 @@ func main() { piper := &ssh.SSHPiper{ FindUpstream: func(conn ssh.ConnMetadata) (net.Conn, *ssh.ClientConfig, error) { - // TODO security - addr, err := UserUpstreamFile.read(conn.User()) + user := conn.User() + + err := UserUpstreamFile.check400(user) + if err != nil { + return nil, nil, err + } + + addr, err := UserUpstreamFile.read(user) if err != nil { return nil, nil, err } saddr := strings.TrimSpace(string(addr)) - logger.Printf("mapping user [%s] to [%s]", conn.User(), saddr) + logger.Printf("mapping user [%s] to [%s]", user, saddr) c, err := net.Dial("tcp", saddr) if err != nil { @@ -105,6 +117,11 @@ func main() { } }() + err = UserAuthorizedKeysFile.check400(user) + if err != nil { + return nil, err + } + keydata := key.Marshal() var rest []byte @@ -123,6 +140,10 @@ func main() { } if bytes.Equal(authedPubkey.Marshal(), keydata) { + err = UserKeyFile.check400(user) + if err != nil { + return nil, err + } var privateBytes []byte privateBytes, err = UserKeyFile.read(user)