usernames have to follow unix naming rule (security reason)

This commit is contained in:
tgic 2014-12-30 19:31:34 +08:00 • committed by Boshi Lian
parent e915d447b3
commit 4eadb2b71f
2 changed files with 38 additions and 10 deletions

View file

@ -23,14 +23,15 @@ var githash = "0000000000"
var (
config = struct {
ListenAddr string
Port uint
WorkingDir string
PiperKeyFile string
ShowHelp bool
Challenger string
Logfile string
ShowVersion bool
ListenAddr string
Port uint
WorkingDir string
PiperKeyFile string
ShowHelp bool
Challenger string
Logfile string
ShowVersion bool
AllowBadUsername bool
}{}
out = os.Stdout
@ -84,6 +85,7 @@ func initConfig() {
mflag.StringVar(&config.PiperKeyFile, []string{"i", "-server_key"}, "/etc/ssh/ssh_host_rsa_key", "Key file for SSH Piper")
mflag.StringVar(&config.Challenger, []string{"c", "-challenger"}, "", "Additional challenger name, e.g. pam, emtpy for no additional challenge")
mflag.StringVar(&config.Logfile, []string{"-log"}, "", "Logfile path. Leave emtpy or any error occurs will fall back to stdout")
mflag.BoolVar(&config.AllowBadUsername, []string{"-allow_bad_username"}, false, "disable username check while search the working dir")
mflag.BoolVar(&config.ShowHelp, []string{"h", "-help"}, false, "Print help and exit")
mflag.BoolVar(&config.ShowVersion, []string{"-version"}, false, "Print version and exit")

View file

@ -12,6 +12,7 @@ import (
"io/ioutil"
"net"
"os"
"regexp"
"strings"
"github.com/tg123/sshpiper/ssh"
@ -23,8 +24,16 @@ var (
UserAuthorizedKeysFile userFile = "authorized_keys"
UserKeyFile userFile = "id_rsa"
UserUpstreamFile userFile = "sshpiper_upstream"
usernameRule *regexp.Regexp
)
func init() {
// http://stackoverflow.com/questions/6949667/what-are-the-real-rules-for-linux-usernames-on-centos-6-and-rhel-6
// #NAME_REGEX="^[a-z][-a-z0-9_]*\$"
usernameRule, _ = regexp.Compile("^[a-z_][a-z0-9_]{0,30}$")
}
func userSpecFile(user, file string) string {
return fmt.Sprintf("%s/%s/%s", config.WorkingDir, user, file)
}
@ -58,6 +67,16 @@ func (file userFile) checkPerm(user string) error {
return nil
}
// return false if username is not a valid unix user name
// this is for security reason
func checkUsername(user string) bool {
if config.AllowBadUsername {
return true
}
return usernameRule.MatchString(user)
}
func parseUpstreamFile(data string) (string, string) {
var user string
@ -100,6 +119,10 @@ func parseUpstreamFile(data string) (string, string) {
func findUpstreamFromUserfile(conn ssh.ConnMetadata) (net.Conn, string, error) {
user := conn.User()
if !checkUsername(user) {
return nil, "", fmt.Errorf("downstream is not using a valid username")
}
err := UserUpstreamFile.checkPerm(user)
if err != nil {
return nil, "", err
@ -126,10 +149,13 @@ func findUpstreamFromUserfile(conn ssh.ConnMetadata) (net.Conn, string, error) {
return c, mappedUser, nil
}
func mapPublicKeyFromUserfile(conn ssh.ConnMetadata, key ssh.PublicKey) (ssh.Signer, error) {
func mapPublicKeyFromUserfile(conn ssh.ConnMetadata, key ssh.PublicKey) (signer ssh.Signer, err error) {
user := conn.User()
var err error
if !checkUsername(user) {
return nil, fmt.Errorf("downstream is not using a valid username")
}
defer func() { // print error when func exit
if err != nil {
logger.Printf("mapping private key error: %v, public key auth denied for [%v] from [%v]", err, user, conn.RemoteAddr())