func newDockerClient() *client.DockerCli { // Set terminal emulation based on platform as required. stdin, stdout, stderr := term.StdStreams() setDefaultConfFlag(flTrustKey, defaultTrustKeyFile) if len(flHosts) > 1 { log.Fatal("Please specify only one -H") } protoAddrParts := strings.SplitN(flHosts[0], "://", 2) var ( cli *client.DockerCli tlsConfig tls.Config ) tlsConfig.InsecureSkipVerify = true // Regardless of whether the user sets it to true or false, if they // specify --tlsverify at all then we need to turn on tls if flag.IsSet("-tlsverify") { *flTls = true } // If we should verify the server, we need to load a trusted ca if *flTlsVerify { certPool := x509.NewCertPool() file, err := ioutil.ReadFile(*flCa) if err != nil { log.Fatalf("Couldn't read ca cert %s: %s", *flCa, err) } certPool.AppendCertsFromPEM(file) tlsConfig.RootCAs = certPool tlsConfig.InsecureSkipVerify = false } // If tls is enabled, try to load and send client certificates if *flTls || *flTlsVerify { _, errCert := os.Stat(*flCert) _, errKey := os.Stat(*flKey) if errCert == nil && errKey == nil { *flTls = true cert, err := tls.LoadX509KeyPair(*flCert, *flKey) if err != nil { log.Fatalf("Couldn't load X509 key pair: %q. Make sure the key is encrypted", err) } tlsConfig.Certificates = []tls.Certificate{cert} } // Avoid fallback to SSL protocols < TLS1.0 tlsConfig.MinVersion = tls.VersionTLS10 } cli = client.NewDockerCli(stdin, stdout, stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], &tlsConfig) return cli }
func main() { if reexec.Init() { return } // Set terminal emulation based on platform as required. stdin, stdout, stderr := term.StdStreams() initLogging(stderr) flag.Parse() // FIXME: validate daemon flags here if *flVersion { showVersion() return } if *flConfigDir != "" { cliconfig.SetConfigDir(*flConfigDir) } if *flLogLevel != "" { lvl, err := logrus.ParseLevel(*flLogLevel) if err != nil { fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", *flLogLevel) os.Exit(1) } setLogLevel(lvl) } else { setLogLevel(logrus.InfoLevel) } if *flDebug { os.Setenv("DEBUG", "1") setLogLevel(logrus.DebugLevel) } if len(flHosts) == 0 { defaultHost := os.Getenv("DOCKER_HOST") if defaultHost == "" || *flDaemon { if runtime.GOOS != "windows" { // If we do not have a host, default to unix socket defaultHost = fmt.Sprintf("unix://%s", opts.DefaultUnixSocket) } else { // If we do not have a host, default to TCP socket on Windows defaultHost = fmt.Sprintf("tcp://%s:%d", opts.DefaultHTTPHost, opts.DefaultHTTPPort) } } defaultHost, err := opts.ValidateHost(defaultHost) if err != nil { if *flDaemon { logrus.Fatal(err) } else { fmt.Fprint(os.Stderr, err) } os.Exit(1) } flHosts = append(flHosts, defaultHost) } setDefaultConfFlag(flTrustKey, defaultTrustKeyFile) // Regardless of whether the user sets it to true or false, if they // specify --tlsverify at all then we need to turn on tls // *flTlsVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need to check that here as well if flag.IsSet("-tlsverify") || *flTlsVerify { *flTls = true } if *flDaemon { if *flHelp { flag.Usage() return } mainDaemon() return } // From here on, we assume we're a client, not a server. if len(flHosts) > 1 { fmt.Fprintf(os.Stderr, "Please specify only one -H") os.Exit(0) } protoAddrParts := strings.SplitN(flHosts[0], "://", 2) var tlsConfig *tls.Config if *flTls { tlsOptions.InsecureSkipVerify = !*flTlsVerify if !flag.IsSet("-tlscert") { if _, err := os.Stat(tlsOptions.CertFile); os.IsNotExist(err) { tlsOptions.CertFile = "" } } if !flag.IsSet("-tlskey") { if _, err := os.Stat(tlsOptions.KeyFile); os.IsNotExist(err) { tlsOptions.KeyFile = "" } } var err error tlsConfig, err = tlsconfig.Client(tlsOptions) if err != nil { fmt.Fprintln(stderr, err) os.Exit(1) } } cli := client.NewDockerCli(stdin, stdout, stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], tlsConfig) if err := cli.Cmd(flag.Args()...); err != nil { if sterr, ok := err.(client.StatusError); ok { if sterr.Status != "" { fmt.Fprintln(cli.Err(), sterr.Status) os.Exit(1) } os.Exit(sterr.StatusCode) } fmt.Fprintln(cli.Err(), err) os.Exit(1) } }
func main() { if reexec.Init() { return } flag.Parse() // FIXME: validate daemon flags here if *flVersion { showVersion() return } if *flLogLevel != "" { lvl, err := log.ParseLevel(*flLogLevel) if err != nil { log.Fatalf("Unable to parse logging level: %s", *flLogLevel) } initLogging(lvl) } else { initLogging(log.InfoLevel) } // -D, --debug, -l/--log-level=debug processing // When/if -D is removed this block can be deleted if *flDebug { os.Setenv("DEBUG", "1") initLogging(log.DebugLevel) } if len(flHosts) == 0 { defaultHost := os.Getenv("DOCKER_HOST") if defaultHost == "" || *flDaemon { // If we do not have a host, default to unix socket defaultHost = fmt.Sprintf("unix://%s", api.DEFAULTUNIXSOCKET) } defaultHost, err := api.ValidateHost(defaultHost) if err != nil { log.Fatal(err) } flHosts = append(flHosts, defaultHost) } setDefaultConfFlag(flTrustKey, defaultTrustKeyFile) if *flDaemon { mainDaemon() return } if len(flHosts) > 1 { log.Fatal("Please specify only one -H") } protoAddrParts := strings.SplitN(flHosts[0], "://", 2) var ( cli *client.DockerCli tlsConfig tls.Config ) tlsConfig.InsecureSkipVerify = true // Regardless of whether the user sets it to true or false, if they // specify --tlsverify at all then we need to turn on tls if flag.IsSet("-tlsverify") { *flTls = true } // If we should verify the server, we need to load a trusted ca if *flTlsVerify { certPool := x509.NewCertPool() file, err := ioutil.ReadFile(*flCa) if err != nil { log.Fatalf("Couldn't read ca cert %s: %s", *flCa, err) } certPool.AppendCertsFromPEM(file) tlsConfig.RootCAs = certPool tlsConfig.InsecureSkipVerify = false } // If tls is enabled, try to load and send client certificates if *flTls || *flTlsVerify { _, errCert := os.Stat(*flCert) _, errKey := os.Stat(*flKey) if errCert == nil && errKey == nil { *flTls = true cert, err := tls.LoadX509KeyPair(*flCert, *flKey) if err != nil { log.Fatalf("Couldn't load X509 key pair: %s. Key encrypted?", err) } tlsConfig.Certificates = []tls.Certificate{cert} } // Avoid fallback to SSL protocols < TLS1.0 tlsConfig.MinVersion = tls.VersionTLS10 } if *flTls || *flTlsVerify { cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], &tlsConfig) } else { cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], nil) } if err := cli.Cmd(flag.Args()...); err != nil { if sterr, ok := err.(*utils.StatusError); ok { if sterr.Status != "" { log.Println(sterr.Status) } os.Exit(sterr.StatusCode) } log.Fatal(err) } }
func main() { if reexec.Init() { return } // Set terminal emulation based on platform as required. stdin, stdout, stderr := term.StdStreams() initLogging(stderr) flag.Parse() // FIXME: validate daemon flags here if *flVersion { showVersion() return } if *flLogLevel != "" { lvl, err := logrus.ParseLevel(*flLogLevel) if err != nil { fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", *flLogLevel) os.Exit(1) } setLogLevel(lvl) } else { setLogLevel(logrus.InfoLevel) } if *flDebug { os.Setenv("DEBUG", "1") setLogLevel(logrus.DebugLevel) } if len(flHosts) == 0 { defaultHost := os.Getenv("DOCKER_HOST") if defaultHost == "" || *flDaemon { if runtime.GOOS != "windows" { // If we do not have a host, default to unix socket defaultHost = fmt.Sprintf("unix://%s", opts.DefaultUnixSocket) } else { // If we do not have a host, default to TCP socket on Windows defaultHost = fmt.Sprintf("tcp://%s:%d", opts.DefaultHTTPHost, opts.DefaultHTTPPort) } } defaultHost, err := opts.ValidateHost(defaultHost) if err != nil { if *flDaemon { logrus.Fatal(err) } else { fmt.Fprint(os.Stderr, err) } os.Exit(1) } flHosts = append(flHosts, defaultHost) } setDefaultConfFlag(flTrustKey, defaultTrustKeyFile) if *flDaemon { if *flHelp { flag.Usage() return } mainDaemon() return } if len(flHosts) > 1 { fmt.Fprintf(os.Stderr, "Please specify only one -H") os.Exit(0) } protoAddrParts := strings.SplitN(flHosts[0], "://", 2) var ( cli *client.DockerCli tlsConfig tls.Config ) tlsConfig.InsecureSkipVerify = true // Regardless of whether the user sets it to true or false, if they // specify --tlsverify at all then we need to turn on tls if flag.IsSet("-tlsverify") { *flTls = true } // If we should verify the server, we need to load a trusted ca if *flTlsVerify { certPool := x509.NewCertPool() file, err := ioutil.ReadFile(*flCa) if err != nil { fmt.Fprintf(os.Stderr, "Couldn't read ca cert %s: %s\n", *flCa, err) os.Exit(1) } certPool.AppendCertsFromPEM(file) tlsConfig.RootCAs = certPool tlsConfig.InsecureSkipVerify = false } // If tls is enabled, try to load and send client certificates if *flTls || *flTlsVerify { _, errCert := os.Stat(*flCert) _, errKey := os.Stat(*flKey) if errCert == nil && errKey == nil { *flTls = true cert, err := tls.LoadX509KeyPair(*flCert, *flKey) if err != nil { fmt.Fprintf(os.Stderr, "Couldn't load X509 key pair: %q. Make sure the key is encrypted\n", err) os.Exit(1) } tlsConfig.Certificates = []tls.Certificate{cert} } // Avoid fallback to SSL protocols < TLS1.0 tlsConfig.MinVersion = tls.VersionTLS10 } if *flTls || *flTlsVerify { cli = client.NewDockerCli(stdin, stdout, stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], &tlsConfig) } else { cli = client.NewDockerCli(stdin, stdout, stderr, *flTrustKey, protoAddrParts[0], protoAddrParts[1], nil) } if err := cli.Cmd(flag.Args()...); err != nil { if sterr, ok := err.(client.StatusError); ok { if sterr.Status != "" { fmt.Fprintln(cli.Err(), sterr.Status) os.Exit(1) } os.Exit(sterr.StatusCode) } fmt.Fprintln(cli.Err(), err) os.Exit(1) } }
func initConfig() { 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.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") 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) }