config file and env config introduced

This commit is contained in:
tgic 2014-12-23 19:37:52 +08:00 committed by Boshi Lian
parent 9e0d8f1af4
commit ed367f9a6f
4 changed files with 161 additions and 40 deletions

125
sshpiperd/config.go Normal file
View file

@ -0,0 +1,125 @@
// Copyright 2014, 2015 tgic<farmer1992@gmail.com>. All rights reserved.
// this file is governed by MIT-license
//
// https://github.com/tg123/sshpiper
package main
import (
"flag"
"os"
"strings"
"text/template"
"github.com/docker/docker/pkg/mflag"
"github.com/rakyll/globalconf"
)
var (
config = struct {
ListenAddr string
Port uint
WorkingDir string
PiperKeyFile string
ShowHelp bool
Challenger string
ShowVersion bool
}{}
out = os.Stdout
configTemplate *template.Template
versionTemplate *template.Template
)
func initTemplate() {
configTemplate = template.Must(template.New("config").Parse(`
Listening : {{.ListenAddr}}:{{.Port}}
Server Key File : {{.PiperKeyFile}}
Working Dir : {{.WorkingDir}}
Additional Challenger : {{.Challenger}}
`[1:]))
versionTemplate = template.Must(template.New("ver").Parse(`
SSHPiper ver: {{.}} by tgic<farmer1992@gmail.com>
https://github.com/tg123/sshpiper
`[1:]))
}
func init() {
initTemplate()
configfile := mflag.String([]string{"-config"}, "/etc/sshpiperd.conf", "Config file path. Note: any option will be overwrite if it is set by commandline")
mflag.StringVar(&config.ListenAddr, []string{"l", "-listen_addr"}, "0.0.0.0", "Listening Address")
mflag.UintVar(&config.Port, []string{"p", "-port"}, 2222, "Listening Port")
mflag.StringVar(&config.WorkingDir, []string{"w", "-working_dir"}, "/var/sshpiper", "Working Dir")
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.BoolVar(&config.ShowHelp, []string{"h", "-help"}, false, "Print help and exit")
mflag.BoolVar(&config.ShowVersion, []string{"-version"}, false, "Print version and exit")
mflag.Parse()
if _, err := os.Stat(*configfile); os.IsNotExist(err) {
if !mflag.IsSet("-config") {
*configfile = ""
} else {
logger.Fatalf("config file %v not found", *configfile)
}
}
gconf, err := globalconf.NewWithOptions(&globalconf.Options{
Filename: *configfile,
EnvPrefix: "SSHPIPERD_",
})
if err != nil { // this error will happen only if file error
logger.Fatalln("load config file error %v: %v", *configfile, err)
}
// build a dummy flag set for globalconf to parse
fs := flag.NewFlagSet("", flag.ContinueOnError)
ignoreSet := make(map[string]bool)
mflag.Visit(func(f *mflag.Flag) {
for _, n := range f.Names {
ignoreSet[n] = true
}
})
// should be ignored
ignoreSet["-help"] = true
ignoreSet["-version"] = true
mflag.VisitAll(func(f *mflag.Flag) {
for _, n := range f.Names {
if len(n) < 2 {
continue
}
if !ignoreSet[n] {
n = strings.TrimPrefix(n, "-")
fs.Var(f.Value, n, f.Usage)
}
}
})
gconf.ParseSet("", fs)
}
func showHelp() {
mflag.Usage()
}
func showVersion() {
// TODO to build flag
versionTemplate.Execute(out, "v0.1")
}
func showConfig() {
configTemplate.Execute(out, config)
}

View file

@ -6,43 +6,38 @@
package main
import (
"flag"
"fmt"
"github.com/tg123/sshpiper/ssh"
"github.com/tg123/sshpiper/sshpiperd/challenger"
"io/ioutil"
"log"
"net"
"os"
"github.com/tg123/sshpiper/ssh"
"github.com/tg123/sshpiper/sshpiperd/challenger"
)
var (
ListenAddr string
Port uint
WorkingDir string
PiperKeyFile string
ShowHelp bool
Challenger string
logger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
)
func init() {
flag.StringVar(&ListenAddr, "l", "0.0.0.0", "Listening Address")
flag.UintVar(&Port, "p", 2222, "Listening Port")
flag.StringVar(&WorkingDir, "w", "/var/sshpiper", "Working Dir")
flag.StringVar(&PiperKeyFile, "i", "/etc/ssh/ssh_host_rsa_key", "Key file for SSH Piper")
flag.StringVar(&Challenger, "c", "", "Additional challenger name, e.g. pam, emtpy for no additional challenge")
flag.BoolVar(&ShowHelp, "h", false, "Print help and exit")
flag.Parse()
func showHelpOrVersion() {
if config.ShowHelp {
showHelp()
os.Exit(0)
}
if config.ShowVersion {
showVersion()
os.Exit(0)
}
}
func main() {
if ShowHelp {
flag.PrintDefaults()
return
}
showHelpOrVersion()
showVersion()
showConfig()
// TODO make this pluggable
piper := &ssh.SSHPiperConfig{
@ -50,17 +45,17 @@ func main() {
MapPublicKey: mapPublicKeyFromUserfile,
}
if Challenger != "" {
ac, err := challenger.GetChallenger(Challenger)
if config.Challenger != "" {
ac, err := challenger.GetChallenger(config.Challenger)
if err != nil {
logger.Fatalln(err)
logger.Fatalln("failed to load challenger", err)
}
logger.Printf("using additional challenger %s", Challenger)
logger.Printf("using additional challenger %s", config.Challenger)
piper.AdditionalChallenge = ac
}
privateBytes, err := ioutil.ReadFile(PiperKeyFile)
privateBytes, err := ioutil.ReadFile(config.PiperKeyFile)
if err != nil {
logger.Fatalln(err)
}
@ -72,13 +67,13 @@ func main() {
piper.AddHostKey(private)
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", ListenAddr, Port))
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.ListenAddr, config.Port))
if err != nil {
logger.Fatalln("failed to listen for connection")
logger.Fatalln("failed to listen for connection: %v", err)
}
defer listener.Close()
logger.Printf("listening at %s:%d, server key file %s, working dir %s", ListenAddr, Port, PiperKeyFile, WorkingDir)
logger.Printf("SSHPiperd started")
for {
c, err := listener.Accept()

View file

@ -24,7 +24,7 @@ var (
)
func userSpecFile(user, file string) string {
return fmt.Sprintf("%s/%s/%s", WorkingDir, user, file)
return fmt.Sprintf("%s/%s/%s", config.WorkingDir, user, file)
}
func (file userFile) read(user string) ([]byte, error) {

View file

@ -7,14 +7,15 @@ package main
import (
"bytes"
"github.com/tg123/sshpiper/ssh"
"github.com/tg123/sshpiper/ssh/testdata"
"io"
"io/ioutil"
"log"
"net"
"os"
"testing"
"github.com/tg123/sshpiper/ssh"
"github.com/tg123/sshpiper/ssh/testdata"
)
func init() {
@ -24,30 +25,30 @@ func init() {
}
func buildWorkingDir(users []string, t *testing.T) {
WorkingDir = ""
config.WorkingDir = ""
dir, err := ioutil.TempDir(os.TempDir(), "sshpiperd_workingdir")
if err != nil {
t.Fatalf("setup temp dir:%v", err)
}
WorkingDir = dir
config.WorkingDir = dir
for _, u := range users {
os.Mkdir(WorkingDir+"/"+u, os.ModePerm)
os.Mkdir(config.WorkingDir+"/"+u, os.ModePerm)
}
t.Logf("switch workingdir to %v", WorkingDir)
t.Logf("switch workingdir to %v", config.WorkingDir)
}
func cleanupWorkdir(t *testing.T) {
if WorkingDir == "" {
if config.WorkingDir == "" {
return
}
t.Logf("cleaning workingdir %v", WorkingDir)
t.Logf("cleaning workingdir %v", config.WorkingDir)
os.RemoveAll(WorkingDir)
os.RemoveAll(config.WorkingDir)
}
func TestReadUserFile(t *testing.T) {