Ejemplo n.º 1
1
// Starts listening for client connections.
// When a new application connects, launches listeners in a goroutine.
// Returns an error when error occurs.
func StartListen(port int, useTls bool, crtPath string, keyPath string, sname string) error {
	// Create a listening address
	addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf(":%d", port))
	if err != nil {
		return err
	}

	// start a new server and listen on the address
	var l net.Listener
	l, err = net.ListenTCP("tcp", addr)
	if err != nil {
		return err
	}

	// wrap with TLS if required
	if useTls {
		cert, err := tls.LoadX509KeyPair(crtPath, keyPath)
		if err != nil {
			return err
		}
		conf := tls.Config{}

		certs := make([]tls.Certificate, 1)
		certs[0] = cert
		conf.Certificates = certs

		cp := x509.NewCertPool()
		caCert, err := ioutil.ReadFile(crtPath)
		if err != nil {
			return err
		}
		if !cp.AppendCertsFromPEM(caCert) {
			return errors.New("Could not append PEM cert")
		}
		conf.RootCAs = cp

		conf.ServerName = sname

		conf.ClientAuth = tls.RequireAndVerifyClientCert

		conf.ClientCAs = cp

		l = tls.NewListener(l, &conf)
	}

	// at the end of this function close the server connection
	defer l.Close()

	logging.Debug("Starting listen loop")
	for {
		a, err := acceptApp(l)
		if err != nil {
			return err
		} else {
			logging.Debug("Got connection")
			go ListenForCommands(a)
		}
	}
	return nil
}
Ejemplo n.º 2
0
// Generates a tls.Config object for a server from the given files.
func (info TLSInfo) ServerConfig() (*tls.Config, error) {
	// Both the key and cert must be present.
	if info.KeyFile == "" || info.CertFile == "" {
		return nil, fmt.Errorf("KeyFile and CertFile must both be present[key: %v, cert: %v]", info.KeyFile, info.CertFile)
	}

	var cfg tls.Config

	tlsCert, err := tls.LoadX509KeyPair(info.CertFile, info.KeyFile)
	if err != nil {
		return nil, err
	}

	cfg.Certificates = []tls.Certificate{tlsCert}

	if info.CAFile != "" {
		cfg.ClientAuth = tls.RequireAndVerifyClientCert
		cp, err := newCertPool(info.CAFile)
		if err != nil {
			return nil, err
		}

		cfg.RootCAs = cp
		cfg.ClientCAs = cp
	} else {
		cfg.ClientAuth = tls.NoClientCert
	}

	return &cfg, nil
}
Ejemplo n.º 3
0
// setupClientAuth sets up TLS client authentication only if
// any of the TLS configs specified at least one cert file.
func setupClientAuth(tlsConfigs []TLSConfig, config *tls.Config) error {
	whatClientAuth := tls.NoClientCert
	for _, cfg := range tlsConfigs {
		if whatClientAuth < cfg.ClientAuth { // Use the most restrictive.
			whatClientAuth = cfg.ClientAuth
		}
	}

	if whatClientAuth != tls.NoClientCert {
		pool := x509.NewCertPool()
		for _, cfg := range tlsConfigs {
			if len(cfg.ClientCerts) == 0 {
				continue
			}
			for _, caFile := range cfg.ClientCerts {
				caCrt, err := ioutil.ReadFile(caFile) // Anyone that gets a cert from this CA can connect
				if err != nil {
					return err
				}
				if !pool.AppendCertsFromPEM(caCrt) {
					return fmt.Errorf("error loading client certificate '%s': no certificates were successfully parsed", caFile)
				}
			}
		}
		config.ClientCAs = pool
		config.ClientAuth = whatClientAuth
	}

	return nil
}
Ejemplo n.º 4
0
// GetServerTLSConfig returns a TLS config for using with ListenAndServeTLS
// This sets up the Root and Client CAs for verification
func GetServerTLSConfig(caCert, serverCert, serverKey []byte, allowInsecure bool) (*tls.Config, error) {
	// TLS config
	var tlsConfig tls.Config
	tlsConfig.InsecureSkipVerify = allowInsecure
	certPool := x509.NewCertPool()

	// load system certs
	if err := loadSystemCertificates(certPool); err != nil {
		return nil, err
	}

	// append custom CA
	certPool.AppendCertsFromPEM(caCert)

	tlsConfig.RootCAs = certPool
	tlsConfig.ClientCAs = certPool

	log.Debugf("tls root CAs: %d", len(tlsConfig.RootCAs.Subjects()))

	// require client auth
	tlsConfig.ClientAuth = tls.VerifyClientCertIfGiven

	// server cert
	keypair, err := tls.X509KeyPair(serverCert, serverKey)
	if err != nil {
		return &tlsConfig, err

	}
	tlsConfig.Certificates = []tls.Certificate{keypair}

	return &tlsConfig, nil
}
Ejemplo n.º 5
0
// setupClientAuth sets up TLS client authentication only if
// any of the TLS configs specified at least one cert file.
func setupClientAuth(tlsConfigs []TLSConfig, config *tls.Config) error {
	var clientAuth bool
	for _, cfg := range tlsConfigs {
		if len(cfg.ClientCerts) > 0 {
			clientAuth = true
			break
		}
	}

	if clientAuth {
		pool := x509.NewCertPool()
		for _, cfg := range tlsConfigs {
			for _, caFile := range cfg.ClientCerts {
				caCrt, err := ioutil.ReadFile(caFile) // Anyone that gets a cert from Matt Holt can connect
				if err != nil {
					return err
				}
				if !pool.AppendCertsFromPEM(caCrt) {
					return fmt.Errorf("error loading client certificate '%s': no certificates were successfully parsed", caFile)
				}
			}
		}
		config.ClientCAs = pool
		config.ClientAuth = tls.RequireAndVerifyClientCert
	}

	return nil
}
Ejemplo n.º 6
0
// SecureListen obtains a listener that accepts
// secure connections
func SecureServe(addr string, certFile, keyFile, caFile string) {
	config := tls.Config{}

	// load the server cert / key
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		log.Fatalf("%s", err)
	}
	config.Certificates = []tls.Certificate{cert}

	// load the ca if necessary
	// FIXME(alainjobart) this doesn't quite work yet, have
	// to investigate
	if caFile != "" {
		config.ClientCAs = x509.NewCertPool()

		pemCerts, err := ioutil.ReadFile(caFile)
		if err != nil {
			log.Fatalf("%s", err)
		}
		if !config.ClientCAs.AppendCertsFromPEM(pemCerts) {
			log.Fatalf("%s", err)
		}

		config.ClientAuth = tls.RequireAndVerifyClientCert
	}
	l, err := tls.Listen("tcp", addr, &config)
	if err != nil {
		log.Fatalf("%s", err)
	}
	throttled := NewThrottledListener(l, *secureThrottle, *secureMaxBuffer)
	cl := proc.Published(throttled, "SecureConnections", "SecureAccepts")
	go http.Serve(cl, nil)
}
Ejemplo n.º 7
0
// NewTLSConfig returns an initialized TLS configuration suitable for client
// authentication. If caFile is non-empty, it will be loaded.
func NewTLSConfig(caFile string, mutualTLS bool) (*tls.Config, error) {
	var c tls.Config

	// TLS 1.0 at a minimum (for mysql)
	c.MinVersion = tls.VersionTLS10
	c.PreferServerCipherSuites = true

	if mutualTLS {
		log.Info("MutualTLS requested, client certificates will be verified")
		c.ClientAuth = tls.VerifyClientCertIfGiven
	}
	if caFile != "" {
		data, err := ioutil.ReadFile(caFile)
		if err != nil {
			return &c, err
		}
		c.ClientCAs = x509.NewCertPool()
		if !c.ClientCAs.AppendCertsFromPEM(data) {
			return &c, errors.New("No certificates parsed")
		}
		log.Info("Read in CA file:", caFile)
	}
	c.BuildNameToCertificate()
	return &c, nil
}
Ejemplo n.º 8
0
// HandleStartTLS is the companion to StartTLS, and will do the connection upgrade.  It assumes
// that the TLS command byte has already been read.  Like StartTLS it returns the peer name, or
// an error
func (p *Protocol) HandleStartTLS(identity *security.Identity, caCertificate *security.Certificate) (string, error) {
	var (
		err     error
		tlsConn *tls.Conn
	)

	// Build the config
	config := new(tls.Config)
	config.ClientAuth = tls.RequireAndVerifyClientCert

	// Setup the tls connection
	if err := p.tlsSetup(config, identity, caCertificate); err != nil {
		return "", err
	}

	// Upgrade the connection to TLS
	// TODO: Add a deadline here?
	tlsConn = tls.Server(p.conn, config)
	if err = tlsConn.Handshake(); err != nil {
		return "", err
	}

	// Capture the connection state
	cs := tlsConn.ConnectionState()

	// And replace the original connection
	p.conn = net.Conn(tlsConn)
	p.setupBuffers()

	// Send an Ack
	p.Ack()

	return cs.PeerCertificates[0].Subject.CommonName, nil
}
Ejemplo n.º 9
0
// NewTestServer wraps a Service as an httptest.Server.
func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error) {
	var tlsConfig *tls.Config
	if cert != nil {
		cert, err := tls.X509KeyPair(cert, key)
		if err != nil {
			return nil, err
		}
		tlsConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
	}

	if caCert != nil {
		rootCAs := x509.NewCertPool()
		rootCAs.AppendCertsFromPEM(caCert)
		if tlsConfig == nil {
			tlsConfig = &tls.Config{}
		}
		tlsConfig.ClientCAs = rootCAs
		tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
	}

	serveHTTP := func(w http.ResponseWriter, r *http.Request) {
		var review v1beta1.TokenReview
		if err := json.NewDecoder(r.Body).Decode(&review); err != nil {
			http.Error(w, fmt.Sprintf("failed to decode body: %v", err), http.StatusBadRequest)
			return
		}
		s.Review(&review)
		type userInfo struct {
			Username string   `json:"username"`
			UID      string   `json:"uid"`
			Groups   []string `json:"groups"`
		}
		type status struct {
			Authenticated bool     `json:"authenticated"`
			User          userInfo `json:"user"`
		}
		resp := struct {
			APIVersion string `json:"apiVersion"`
			Status     status `json:"status"`
		}{
			APIVersion: v1beta1.SchemeGroupVersion.String(),
			Status: status{
				review.Status.Authenticated,
				userInfo{
					Username: review.Status.User.Username,
					UID:      review.Status.User.UID,
					Groups:   review.Status.User.Groups,
				},
			},
		}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(resp)
	}

	server := httptest.NewUnstartedServer(http.HandlerFunc(serveHTTP))
	server.TLS = tlsConfig
	server.StartTLS()
	return server, nil
}
Ejemplo n.º 10
0
// ServerSecurePort obtains a listener that accepts secure connections.
// If the provided port is zero, the listening is disabled.
func ServeSecurePort(securePort int, certFile, keyFile, caCertFile string) {
	if securePort == 0 {
		log.Info("Not listening on secure port")
		return
	}

	config := tls.Config{}

	// load the server cert / key
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		log.Fatalf("SecureServe.LoadX509KeyPair(%v, %v) failed: %v", certFile, keyFile, err)
	}
	config.Certificates = []tls.Certificate{cert}

	// load the ca if necessary
	// FIXME(alainjobart) this doesn't quite work yet, have
	// to investigate
	if caCertFile != "" {
		config.ClientCAs = x509.NewCertPool()

		pemCerts, err := ioutil.ReadFile(caCertFile)
		if err != nil {
			log.Fatalf("SecureServe: cannot read ca file %v: %v", caCertFile, err)
		}
		if !config.ClientCAs.AppendCertsFromPEM(pemCerts) {
			log.Fatalf("SecureServe: AppendCertsFromPEM failed: %v", err)
		}

		config.ClientAuth = tls.RequireAndVerifyClientCert
	}
	l, err := tls.Listen("tcp", fmt.Sprintf(":%d", securePort), &config)
	if err != nil {
		log.Fatalf("Error listening on secure port %v: %v", securePort, err)
	}
	log.Infof("Listening on secure port %v", securePort)
	throttled := NewThrottledListener(l, *secureThrottle, *secureMaxBuffer)
	cl := proc.Published(throttled, "SecureConnections", "SecureAccepts")

	// rpc.HandleHTTP registers the default GOB handler at /_goRPC_
	// and the debug RPC service at /debug/rpc (it displays a list
	// of registered services and their methods).
	if ServiceMap["gob-vts"] {
		log.Infof("Registering GOB handler and /debug/rpc URL for vts port")
		secureRpcServer.HandleHTTP(rpcwrap.GetRpcPath("gob", false), rpcplus.DefaultDebugPath)
	}
	if ServiceMap["gob-auth-vts"] {
		log.Infof("Registering GOB handler and /debug/rpcs URL for SASL vts port")
		authenticatedSecureRpcServer.HandleHTTP(rpcwrap.GetRpcPath("gob", true), rpcplus.DefaultDebugPath+"s")
	}

	handler := http.NewServeMux()
	bsonrpc.ServeCustomRPC(handler, secureRpcServer, false)
	bsonrpc.ServeCustomRPC(handler, authenticatedSecureRpcServer, true)
	httpServer := http.Server{
		Handler: handler,
	}
	go httpServer.Serve(cl)
}
Ejemplo n.º 11
0
// ListenAnonymous returns a new Tao-based net.Listener that does not require
// its peer to attest to its identity.
func ListenAnonymous(network, laddr string, config *tls.Config, g Guard, v *Verifier, del *Attestation) (net.Listener, error) {
	config.ClientAuth = tls.NoClientCert
	inner, err := tls.Listen(network, laddr, config)
	if err != nil {
		return nil, err
	}

	return &anonymousListener{listener{inner, g, v, del}}, nil
}
Ejemplo n.º 12
0
func Init(messageQueue chan *bl.Message, conf map[string]interface{}) bl.Input {
	var tlsConfig tls.Config
	tag := bl.GString("tag", conf)
	bind := bl.GString("bind", conf)
	timeout := int64(bl.GInt("timeout", conf))
	if timeout <= 0 {
		log.Fatalf("[ERROR] [%s] You must specify right timeout (%d)", module, timeout)
	}
	SSLCertificate := bl.GString("ssl_cert", conf)
	SSLKey := bl.GString("ssl_key", conf)
	SSLCA := bl.GString("ssl_ca", conf)
	if len(SSLCertificate) > 0 && len(SSLKey) > 0 {
		tlsConfig.MinVersion = tls.VersionTLS12
		log.Printf("[INFO] [%s] Loading server ssl certificate and key from \"%s\" and \"%s\"", tag,
			SSLCertificate, SSLKey)
		cert, err := tls.LoadX509KeyPair(SSLCertificate, SSLKey)
		if err != nil {
			log.Fatalf("[ERROR] [%s] Failed loading server ssl certificate: %s", tag, err)
		}
		tlsConfig.Certificates = []tls.Certificate{cert}
		if len(SSLCA) > 0 {
			log.Printf("[INFO] [%s] Loading CA certificate from file: %s\n", tag, SSLCA)
			tlsConfig.ClientCAs = x509.NewCertPool()
			tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
			pemdata, err := ioutil.ReadFile(SSLCA)
			if err != nil {
				log.Fatalf("[ERROR] [%s] Failure reading CA certificate: %s\n", tag, err)
			}

			block, _ := pem.Decode(pemdata)
			if block == nil {
				log.Fatalf("[ERROR] [%s] Failed to decode PEM data of CA certificate from \"%s\"\n", tag, SSLCA)
			}
			if block.Type != "CERTIFICATE" {
				log.Fatalf("[ERROR] [%s] This is not a certificate file: %s\n", tag, SSLCA)
			}

			cacert, err := x509.ParseCertificate(block.Bytes)
			if err != nil {
				log.Fatalf("[ERROR] [%s] Failed to parse CA certificate: %s\n", tag, SSLCA)
			}
			tlsConfig.ClientCAs.AddCert(cacert)
		}

		v := &In_logear_forwarder{tag: tag,
			messageQueue: messageQueue,
			tlsConfig:    tlsConfig,
			bind:         bind,
			timeout:      time.Second * time.Duration(timeout)}
		return v
	} else {
		log.Fatalf("[ERROR] [%s] You must specify ssl_cert and ssl_key", module)
	}
	return nil
}
Ejemplo n.º 13
0
// NewTestServer wraps a Service as an httptest.Server.
func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error) {
	var tlsConfig *tls.Config
	if cert != nil {
		cert, err := tls.X509KeyPair(cert, key)
		if err != nil {
			return nil, err
		}
		tlsConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
	}

	if caCert != nil {
		rootCAs := x509.NewCertPool()
		rootCAs.AppendCertsFromPEM(caCert)
		if tlsConfig == nil {
			tlsConfig = &tls.Config{}
		}
		tlsConfig.ClientCAs = rootCAs
		tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
	}

	serveHTTP := func(w http.ResponseWriter, r *http.Request) {
		var review v1alpha1.ImageReview
		if err := json.NewDecoder(r.Body).Decode(&review); err != nil {
			http.Error(w, fmt.Sprintf("failed to decode body: %v", err), http.StatusBadRequest)
			return
		}
		if s.HTTPStatusCode() < 200 || s.HTTPStatusCode() >= 300 {
			http.Error(w, "HTTP Error", s.HTTPStatusCode())
			return
		}
		s.Review(&review)
		type status struct {
			Allowed bool   `json:"allowed"`
			Reason  string `json:"reason"`
		}
		resp := struct {
			APIVersion string `json:"apiVersion"`
			Kind       string `json:"kind"`
			Status     status `json:"status"`
		}{
			APIVersion: v1alpha1.SchemeGroupVersion.String(),
			Kind:       "ImageReview",
			Status:     status{review.Status.Allowed, review.Status.Reason},
		}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(resp)
	}

	server := httptest.NewUnstartedServer(http.HandlerFunc(serveHTTP))
	server.TLS = tlsConfig
	server.StartTLS()
	return server, nil
}
Ejemplo n.º 14
0
func (c Config) TLSConfig() *tls.Config {
	certs := []tls.Certificate{c.TLSCertificate()}

	tlsConfig := tls.Config{
		Certificates: certs,
	}

	if c.TLSClientAuthEnabled() {
		tlsConfig.ClientCAs = c.ClientCAsPool()
		tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
	}

	return &tlsConfig
}
Ejemplo n.º 15
0
func tlsConfig() *tls.Config {
	cfg := new(tls.Config)

	cfg.ClientCAs = x509.NewCertPool()
	cfg.ClientCAs.AppendCertsFromPEM([]byte(caCert))

	cert, err := tls.X509KeyPair([]byte(serverCert), []byte(serverKey))
	if err != nil {
		panic(err)
	}

	cfg.Certificates = append(cfg.Certificates, cert)
	cfg.ClientAuth = tls.RequireAndVerifyClientCert

	return cfg
}
Ejemplo n.º 16
0
// StartHttpsServer binds and starts an https server.
func StartHttpsServer(addr string, certFile, keyFile, caFile string) {
	config := tls.Config{}

	// load the server cert / key
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		relog.Fatal("StartHttpsServer.LoadX509KeyPair failed: %v", err)
	}
	config.Certificates = []tls.Certificate{cert}

	// load the ca if necessary
	// FIXME(alainjobart) this doesn't quite work yet, have
	// to investigate
	if caFile != "" {
		config.ClientCAs = x509.NewCertPool()

		ca, err := os.Open(caFile)
		if err != nil {
			relog.Fatal("StartHttpsServer failed to open caFile %v: %v", caFile, err)
		}
		defer ca.Close()

		fi, err := ca.Stat()
		if err != nil {
			relog.Fatal("StartHttpsServer failed to stat caFile %v: %v", caFile, err)
		}

		pemCerts := make([]byte, fi.Size())
		if _, err = ca.Read(pemCerts); err != nil {
			relog.Fatal("StartHttpsServer failed to read caFile %v: %v", caFile, err)
		}

		if !config.ClientCAs.AppendCertsFromPEM(pemCerts) {
			relog.Fatal("StartHttpsServer failed to parse caFile %v", caFile)
		}

		config.ClientAuth = tls.RequireAndVerifyClientCert
	}

	httpsListener, err := tls.Listen("tcp", addr, &config)
	if err != nil {
		relog.Fatal("StartHttpsServer failed: %v", err)
	}
	go asyncListener(httpsListener)
}
Ejemplo n.º 17
0
func setupTls(caFile, certFile, keyFile string) {
	if caFile == "" || certFile == "" || keyFile == "" {
		return
	}
	// Load certificates and key.
	caData, err := ioutil.ReadFile(caFile)
	if os.IsNotExist(err) {
		return
	}
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to load CA file\t%s\n",
			err)
		os.Exit(1)
	}
	caCertPool := x509.NewCertPool()
	if !caCertPool.AppendCertsFromPEM(caData) {
		fmt.Fprintln(os.Stderr, "Unable to parse CA file")
		os.Exit(1)
	}
	// Setup server.
	serverConfig := new(tls.Config)
	serverConfig.ClientAuth = tls.RequireAndVerifyClientCert
	serverConfig.MinVersion = tls.VersionTLS12
	serverConfig.ClientCAs = caCertPool
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if os.IsNotExist(err) {
		return
	}
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to load keypair\t%s\n",
			err)
		os.Exit(1)
	}
	serverConfig.Certificates = append(serverConfig.Certificates, cert)
	srpc.RegisterServerTlsConfig(serverConfig, true)
	// Setup client.
	clientConfig := new(tls.Config)
	clientConfig.InsecureSkipVerify = true
	clientConfig.MinVersion = tls.VersionTLS12
	clientConfig.Certificates = append(clientConfig.Certificates, cert)
	srpc.RegisterClientTlsConfig(clientConfig)
}
Ejemplo n.º 18
0
// GenTLSConfig loads TLS related configuration parameters.
func GenTLSConfig(tc *TLSConfigOpts) (*tls.Config, error) {

	// Now load in cert and private key
	cert, err := tls.LoadX509KeyPair(tc.CertFile, tc.KeyFile)
	if err != nil {
		return nil, fmt.Errorf("error parsing X509 certificate/key pair: %v", err)
	}
	cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		return nil, fmt.Errorf("error parsing certificate: %v", err)
	}

	// Create TLSConfig
	// We will determine the cipher suites that we prefer.
	config := tls.Config{
		Certificates:             []tls.Certificate{cert},
		PreferServerCipherSuites: true,
		MinVersion:               tls.VersionTLS12,
		CipherSuites:             tc.Ciphers,
	}

	// Require client certificates as needed
	if tc.Verify {
		config.ClientAuth = tls.RequireAndVerifyClientCert
	}
	// Add in CAs if applicable.
	if tc.CaFile != "" {
		rootPEM, err := ioutil.ReadFile(tc.CaFile)
		if err != nil || rootPEM == nil {
			return nil, err
		}
		pool := x509.NewCertPool()
		ok := pool.AppendCertsFromPEM([]byte(rootPEM))
		if !ok {
			return nil, fmt.Errorf("failed to parse root ca certificate")
		}
		config.ClientCAs = pool
	}

	return &config, nil
}
Ejemplo n.º 19
0
// serverSecurePort obtains a listener that accepts secure connections.
// All of this is based on *SecurePort being non-zero.
func serveSecurePort() {
	if *SecurePort == 0 {
		log.Info("Not listening on secure port")
		return
	}

	config := tls.Config{}

	// load the server cert / key
	cert, err := tls.LoadX509KeyPair(*certFile, *keyFile)
	if err != nil {
		log.Fatalf("SecureServe.LoadX509KeyPair(%v, %v) failed: %v", *certFile, *keyFile, err)
	}
	config.Certificates = []tls.Certificate{cert}

	// load the ca if necessary
	// FIXME(alainjobart) this doesn't quite work yet, have
	// to investigate
	if *caCertFile != "" {
		config.ClientCAs = x509.NewCertPool()

		pemCerts, err := ioutil.ReadFile(*caCertFile)
		if err != nil {
			log.Fatalf("SecureServe: cannot read ca file %v: %v", *caCertFile, err)
		}
		if !config.ClientCAs.AppendCertsFromPEM(pemCerts) {
			log.Fatalf("SecureServe: AppendCertsFromPEM failed: %v", err)
		}

		config.ClientAuth = tls.RequireAndVerifyClientCert
	}
	l, err := tls.Listen("tcp", fmt.Sprintf(":%d", *SecurePort), &config)
	if err != nil {
		log.Fatalf("Error listening on secure port %v: %v", *SecurePort, err)
	}
	log.Infof("Listening on secure port %v", *SecurePort)
	throttled := NewThrottledListener(l, *secureThrottle, *secureMaxBuffer)
	cl := proc.Published(throttled, "SecureConnections", "SecureAccepts")
	go http.Serve(cl, nil)
}
Ejemplo n.º 20
0
// setupTLSConfig returns a tls.Config for a credential set
func setupTLSConfig(cert []byte, key []byte, ca []byte) (*tls.Config, error) {
	// TLS config
	var tlsConfig tls.Config

	//Use only modern ciphers
	tlsConfig.CipherSuites = []uint16{
		tls.TLS_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
	}

	// Use only TLS v1.2
	tlsConfig.MinVersion = tls.VersionTLS12

	// Don't allow session resumption
	tlsConfig.SessionTicketsDisabled = true

	certPool := x509.NewCertPool()
	certPool.AppendCertsFromPEM(ca)
	tlsConfig.RootCAs = certPool
	tlsConfig.ClientCAs = certPool

	tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert

	keypair, err := tls.X509KeyPair(cert, key)
	if err != nil {
		return &tlsConfig, err
	}
	tlsConfig.Certificates = []tls.Certificate{keypair}

	return &tlsConfig, nil
}
Ejemplo n.º 21
0
func GetConfig(ca_f []byte, ee_f []byte, key_f []byte) (*tls.Config, error) {
	ca, err := x509.ParseCertificate(ca_f)
	if err != nil {
		return nil, err
	}
	pkey, err := x509.ParsePKCS1PrivateKey(key_f)
	if err != nil {
		return nil, err
	}
	ca_pool := x509.NewCertPool()
	ca_pool.AddCert(ca)
	ee_cert := tls.Certificate{
		Certificate: [][]byte{ee_f},
		PrivateKey:  pkey,
	}
	config := new(tls.Config)
	config.ClientAuth = tls.RequireAndVerifyClientCert
	config.Certificates = []tls.Certificate{ee_cert}
	config.ClientCAs = ca_pool
	config.RootCAs = ca_pool
	config.Rand = rand.Reader
	config.BuildNameToCertificate()
	return config, nil
}
Ejemplo n.º 22
0
// MakeTLSConfig reduces configs into a single tls.Config.
// If TLS is to be disabled, a nil tls.Config will be returned.
func MakeTLSConfig(configs []*Config) (*tls.Config, error) {
	if configs == nil || len(configs) == 0 {
		return nil, nil
	}

	config := new(tls.Config)
	ciphersAdded := make(map[uint16]struct{})
	configMap := make(configGroup)

	for i, cfg := range configs {
		if cfg == nil {
			// avoid nil pointer dereference below
			configs[i] = new(Config)
			continue
		}

		// Key this config by its hostname; this
		// overwrites configs with the same hostname
		configMap[cfg.Hostname] = cfg

		// Can't serve TLS and not-TLS on same port
		if i > 0 && cfg.Enabled != configs[i-1].Enabled {
			thisConfProto, lastConfProto := "not TLS", "not TLS"
			if cfg.Enabled {
				thisConfProto = "TLS"
			}
			if configs[i-1].Enabled {
				lastConfProto = "TLS"
			}
			return nil, fmt.Errorf("cannot multiplex %s (%s) and %s (%s) on same listener",
				configs[i-1].Hostname, lastConfProto, cfg.Hostname, thisConfProto)
		}

		// Union cipher suites
		for _, ciph := range cfg.Ciphers {
			if _, ok := ciphersAdded[ciph]; !ok {
				ciphersAdded[ciph] = struct{}{}
				config.CipherSuites = append(config.CipherSuites, ciph)
			}
		}

		// Can't resolve conflicting PreferServerCipherSuites settings
		if i > 0 && cfg.PreferServerCipherSuites != configs[i-1].PreferServerCipherSuites {
			return nil, fmt.Errorf("cannot both use PreferServerCipherSuites and not use it")
		}
		config.PreferServerCipherSuites = cfg.PreferServerCipherSuites

		// Go with the widest range of protocol versions
		if config.MinVersion == 0 || cfg.ProtocolMinVersion < config.MinVersion {
			config.MinVersion = cfg.ProtocolMinVersion
		}
		if cfg.ProtocolMaxVersion > config.MaxVersion {
			config.MaxVersion = cfg.ProtocolMaxVersion
		}

		// Go with the strictest ClientAuth type
		if cfg.ClientAuth > config.ClientAuth {
			config.ClientAuth = cfg.ClientAuth
		}
	}

	// Is TLS disabled? If so, we're done here.
	// By now, we know that all configs agree
	// whether it is or not, so we can just look
	// at the first one.
	if len(configs) == 0 || !configs[0].Enabled {
		return nil, nil
	}

	// Default cipher suites
	if len(config.CipherSuites) == 0 {
		config.CipherSuites = defaultCiphers
	}

	// For security, ensure TLS_FALLBACK_SCSV is always included
	if config.CipherSuites[0] != tls.TLS_FALLBACK_SCSV {
		config.CipherSuites = append([]uint16{tls.TLS_FALLBACK_SCSV}, config.CipherSuites...)
	}

	// Set up client authentication if enabled
	if config.ClientAuth != tls.NoClientCert {
		pool := x509.NewCertPool()
		clientCertsAdded := make(map[string]struct{})
		for _, cfg := range configs {
			for _, caFile := range cfg.ClientCerts {
				// don't add cert to pool more than once
				if _, ok := clientCertsAdded[caFile]; ok {
					continue
				}
				clientCertsAdded[caFile] = struct{}{}

				// Any client with a certificate from this CA will be allowed to connect
				caCrt, err := ioutil.ReadFile(caFile)
				if err != nil {
					return nil, err
				}

				if !pool.AppendCertsFromPEM(caCrt) {
					return nil, fmt.Errorf("error loading client certificate '%s': no certificates were successfully parsed", caFile)
				}
			}
		}
		config.ClientCAs = pool
	}

	// Associate the GetCertificate callback, or almost nothing we just did will work
	config.GetCertificate = configMap.GetCertificate

	return config, nil
}
Ejemplo n.º 23
0
// NewServer starts an HTTPS server the handles the redoctober JSON
// API. Each of the URIs in the functions map above is setup with a
// separate HandleFunc. Each HandleFunc is an instance of queueRequest
// above.
//
// Returns a valid http.Server handling redoctober JSON requests (and
// its associated listener) or an error
func NewServer(process chan<- userRequest, staticPath, addr, certPath, keyPath, caPath string) (*http.Server, *net.Listener, error) {
	cert, err := tls.LoadX509KeyPair(certPath, keyPath)
	if err != nil {
		return nil, nil, fmt.Errorf("Error loading certificate (%s, %s): %s", certPath, keyPath, err)
	}

	config := tls.Config{
		Certificates: []tls.Certificate{cert},
		Rand:         rand.Reader,
		PreferServerCipherSuites: true,
		SessionTicketsDisabled:   true,
		MinVersion:               tls.VersionTLS10,
	}

	// If a caPath has been specified then a local CA is being used
	// and not the system configuration.

	if caPath != "" {
		pemCert, err := ioutil.ReadFile(caPath)
		if err != nil {
			return nil, nil, fmt.Errorf("Error reading %s: %s\n", caPath, err)
		}

		derCert, _ := pem.Decode(pemCert)
		if derCert == nil {
			return nil, nil, fmt.Errorf("No PEM data was found in the CA certificate file\n")
		}

		cert, err := x509.ParseCertificate(derCert.Bytes)
		if err != nil {
			return nil, nil, fmt.Errorf("Error parsing CA certificate: %s\n", err)
		}

		rootPool := x509.NewCertPool()
		rootPool.AddCert(cert)

		config.ClientAuth = tls.RequireAndVerifyClientCert
		config.ClientCAs = rootPool
	}

	conn, err := net.Listen("tcp", addr)
	if err != nil {
		return nil, nil, fmt.Errorf("Error starting TCP listener on %s: %s\n", addr, err)
	}

	lstnr := tls.NewListener(conn, &config)

	mux := http.NewServeMux()

	// queue up post URIs
	for current := range functions {
		// copy this so reference does not get overwritten
		requestType := current
		mux.HandleFunc(requestType, func(w http.ResponseWriter, r *http.Request) {
			log.Printf("http.server: endpoint=%s remote=%s", requestType, r.RemoteAddr)
			queueRequest(process, requestType, w, r)
		})
	}

	// queue up web frontend
	idxHandler := &indexHandler{staticPath}
	mux.HandleFunc("/index", idxHandler.handle)
	mux.HandleFunc("/", idxHandler.handle)

	srv := http.Server{
		Addr:    addr,
		Handler: mux,
	}

	return &srv, &lstnr, nil
}
Ejemplo n.º 24
0
Archivo: opts.go Proyecto: pkoro/gnatsd
// Helper function to parse TLS configs.
func parseTLS(tlsm map[string]interface{}) (*tls.Config, error) {
	tc := tlsConfig{}
	for mk, mv := range tlsm {
		switch strings.ToLower(mk) {
		case "cert_file":
			certFile, ok := mv.(string)
			if !ok {
				return nil, fmt.Errorf("error parsing tls config, expected 'cert_file' to be filename")
			}
			tc.certFile = certFile
		case "key_file":
			keyFile, ok := mv.(string)
			if !ok {
				return nil, fmt.Errorf("error parsing tls config, expected 'key_file' to be filename")
			}
			tc.keyFile = keyFile
		case "ca_file":
			caFile, ok := mv.(string)
			if !ok {
				return nil, fmt.Errorf("error parsing tls config, expected 'ca_file' to be filename")
			}
			tc.caFile = caFile
		case "verify":
			verify, ok := mv.(bool)
			if !ok {
				return nil, fmt.Errorf("error parsing tls config, expected 'verify' to be a boolean")
			}
			tc.verify = verify

		default:
			return nil, fmt.Errorf("error parsing tls config, unknown field [%q]", mk)
		}
	}
	// Now load in cert and private key
	cert, err := tls.LoadX509KeyPair(tc.certFile, tc.keyFile)
	if err != nil {
		return nil, fmt.Errorf("error parsing X509 certificate/key pair: %v", err)
	}
	cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		return nil, fmt.Errorf("error parsing certificate: %v", err)
	}
	// Create TLSConfig
	// We will determine the cipher suites that we prefer.
	config := tls.Config{
		Certificates:             []tls.Certificate{cert},
		PreferServerCipherSuites: true,
		MinVersion:               tls.VersionTLS12,
		CipherSuites: []uint16{
			// The SHA384 versions are only in Go1.5
			//			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			//			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		},
	}
	// Require client certificates as needed
	if tc.verify == true {
		config.ClientAuth = tls.RequireAnyClientCert
	}
	// Add in CAs if applicable.
	if tc.caFile != "" {
		rootPEM, err := ioutil.ReadFile(tc.caFile)
		if err != nil || rootPEM == nil {
			return nil, err
		}
		pool := x509.NewCertPool()
		ok := pool.AppendCertsFromPEM([]byte(rootPEM))
		if !ok {
			return nil, fmt.Errorf("failed to parse root ca certificate")
		}
		config.RootCAs = pool
	}

	return &config, nil
}
Ejemplo n.º 25
0
func realMain() int {
	flag.Parse()

	config := DefaultConfig()
	if *flConfig != "" {
		in, err := ioutil.ReadFile(*flConfig)
		if err != nil {
			log.Println(err)
			return 1
		}

		if err := toml.Unmarshal(in, config); err != nil {
			log.Println(err)
			return 1
		}
	}

	l, err := net.Listen("tcp", ":8700")
	if err != nil {
		log.Println(err)
		return 1
	}

	if config.SSL.Enabled {
		cert, err := tls.LoadX509KeyPair(config.SSL.Certificate, config.SSL.PrivateKey)
		if err != nil {
			log.Println(err)
			return 1
		}

		tlsConfig := tls.Config{
			Certificates: []tls.Certificate{cert},
			ClientCAs:    x509.NewCertPool(),
			ClientAuth:   tls.NoClientCert,
		}
		if config.SSL.ClientCA != "" {
			data, err := ioutil.ReadFile(config.SSL.ClientCA)
			if err != nil {
				log.Println(err)
				return 1
			}
			tlsConfig.ClientCAs.AppendCertsFromPEM(data)
			tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
		}
		l = tls.NewListener(l, &tlsConfig)
	}

	server := ansible.NewServer()
	if config.Ldap.Enabled {
		if err := server.ConfigureLDAP(&config.Ldap); err != nil {
			log.Println(err)
			return 1
		}
	}

	if err := server.Serve(l); err != nil {
		log.Println(err)
		return 1
	}
	return 0
}
Ejemplo n.º 26
0
// NewTestServer wraps a Service as an httptest.Server.
func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error) {
	const webhookPath = "/testserver"
	var tlsConfig *tls.Config
	if cert != nil {
		cert, err := tls.X509KeyPair(cert, key)
		if err != nil {
			return nil, err
		}
		tlsConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
	}

	if caCert != nil {
		rootCAs := x509.NewCertPool()
		rootCAs.AppendCertsFromPEM(caCert)
		if tlsConfig == nil {
			tlsConfig = &tls.Config{}
		}
		tlsConfig.ClientCAs = rootCAs
		tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
	}

	serveHTTP := func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "POST" {
			http.Error(w, fmt.Sprintf("unexpected method: %v", r.Method), http.StatusMethodNotAllowed)
			return
		}
		if r.URL.Path != webhookPath {
			http.Error(w, fmt.Sprintf("unexpected path: %v", r.URL.Path), http.StatusNotFound)
			return
		}

		var review v1beta1.TokenReview
		bodyData, _ := ioutil.ReadAll(r.Body)
		if err := json.Unmarshal(bodyData, &review); err != nil {
			http.Error(w, fmt.Sprintf("failed to decode body: %v", err), http.StatusBadRequest)
			return
		}
		// ensure we received the serialized tokenreview as expected
		if review.APIVersion != "authentication.k8s.io/v1beta1" {
			http.Error(w, fmt.Sprintf("wrong api version: %s", string(bodyData)), http.StatusBadRequest)
			return
		}
		// once we have a successful request, always call the review to record that we were called
		s.Review(&review)
		if s.HTTPStatusCode() < 200 || s.HTTPStatusCode() >= 300 {
			http.Error(w, "HTTP Error", s.HTTPStatusCode())
			return
		}
		type userInfo struct {
			Username string              `json:"username"`
			UID      string              `json:"uid"`
			Groups   []string            `json:"groups"`
			Extra    map[string][]string `json:"extra"`
		}
		type status struct {
			Authenticated bool     `json:"authenticated"`
			User          userInfo `json:"user"`
		}

		var extra map[string][]string
		if review.Status.User.Extra != nil {
			extra = map[string][]string{}
			for k, v := range review.Status.User.Extra {
				extra[k] = v
			}
		}

		resp := struct {
			Kind       string `json:"kind"`
			APIVersion string `json:"apiVersion"`
			Status     status `json:"status"`
		}{
			Kind:       "TokenReview",
			APIVersion: v1beta1.SchemeGroupVersion.String(),
			Status: status{
				review.Status.Authenticated,
				userInfo{
					Username: review.Status.User.Username,
					UID:      review.Status.User.UID,
					Groups:   review.Status.User.Groups,
					Extra:    extra,
				},
			},
		}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(resp)
	}

	server := httptest.NewUnstartedServer(http.HandlerFunc(serveHTTP))
	server.TLS = tlsConfig
	server.StartTLS()

	// Adjust the path to point to our custom path
	serverURL, _ := url.Parse(server.URL)
	serverURL.Path = webhookPath
	server.URL = serverURL.String()

	return server, nil
}
Ejemplo n.º 27
0
func ServiceRequests() {
	var sockConfig tls.Config

	// resolve the bind address
	bindAddressStr := GetStringOpt("bind address")
	var bindAddr *net.IPAddr
	if bindAddressStr != "" {
		var err error
		bindAddr, err = net.ResolveIPAddr("ip", bindAddressStr)
		if err != nil {
			o.Warn("Ignoring bind address.  Couldn't resolve \"%s\": %s", bindAddressStr, err)
		} else {
			bindAddr = nil
		}
	}
	// load the x509 certificate and key, then attach it to the tls config.
	x509CertFilename := GetStringOpt("x509 certificate")
	x509PrivateKeyFilename := GetStringOpt("x509 private key")
	serverCert, err := tls.LoadX509KeyPair(x509CertFilename, x509PrivateKeyFilename)
	o.MightFail(err, "Couldn't load certificates")
	sockConfig.Certificates = append(sockConfig.Certificates, serverCert)

	// load the CA certs
	CACertPool = x509.NewCertPool()
	caCertNames := GetCACertList()
	if caCertNames != nil {
		for _, filename := range caCertNames {
			fh, err := os.Open(filename)
			if err != nil {
				o.Warn("Whilst parsing CA certs, couldn't open %s: %s", filename, err)
				continue
			}
			defer fh.Close()
			fi, err := fh.Stat()
			o.MightFail(err, "Couldn't stat CA certificate file: %s", filename)
			data := make([]byte, fi.Size())
			fh.Read(data)
			CACertPool.AppendCertsFromPEM(data)
		}
	}
	sockConfig.ClientCAs = CACertPool

	// determine the server hostname.
	servername := GetStringOpt("server name")
	if servername != "" {
		o.Info("Using %s as the server name", servername)
		sockConfig.ServerName = servername
	} else {
		if bindAddr != nil {
			o.Warn("Probing for FQDN for bind address as none was provided")
			hostnames, err := net.LookupAddr(bindAddr.String())
			o.MightFail(err, "Failed to get full hostname for bind address")
			sockConfig.ServerName = hostnames[0]
		} else {
			o.Warn("Probing for FQDN as no server name was provided")
			sockConfig.ServerName = o.ProbeHostname()
		}
	}

	// ask the client to authenticate
	sockConfig.ClientAuth = tls.RequireAndVerifyClientCert
	if *DontVerifyPeer {
		sockConfig.ClientAuth = tls.RequestClientCert
	}

	/* convert the bindAddress to a string suitable for the Listen call */
	var laddr string
	if bindAddr == nil {
		laddr = fmt.Sprintf(":%d", o.DefaultMasterPort)
	} else {
		laddr = fmt.Sprintf("%s:%d", bindAddr.String(), o.DefaultMasterPort)
	}
	o.Info("Binding to %s...", laddr)
	listener, err := tls.Listen("tcp", laddr, &sockConfig)
	o.MightFail(err, "Couldn't bind TLS listener")

	for {
		o.Info("Waiting for connection...")
		c, err := listener.Accept()
		o.MightFail(err, "Couldn't accept TLS connection")
		o.Info("Connection received from %s", c.RemoteAddr().String())
		HandleConnection(c)
	}
}
Ejemplo n.º 28
0
// Blocks listening for connections of that given protocol type,
// and calls the specified handler when one is received,
// passing the node ID of the connecting node, or 0 for the Client Protocol.
func Listen(protocol int, handler func(id uint16, b *BaseConn)) {

	ip := config.NodeIP(config.Id())
	ipStr := ip.String()
	port := getProtocolPort(protocol)
	portStr := strconv.FormatInt(int64(port), 10)

	tlsConfig := new(tls.Config)
	tlsConfig.Certificates = []tls.Certificate{*config.Certificate()}
	if protocol != CLIENT_PROTOCOL {
		tlsConfig.ClientAuth = tls.RequireAnyClientCert
	}

	listener, err := tls.Listen("tcp", ipStr+":"+portStr, tlsConfig)
	if err != nil {
		log.Fatal(err)
	}

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Fatal(err)
		}
		tlsConn := conn.(*tls.Conn)

		err = tlsConn.Handshake()
		if err != nil {
			tlsConn.Close()
			continue
		}

		if protocol != CLIENT_PROTOCOL {
			// Check this connecting node has authenticated.
			state := tlsConn.ConnectionState()
			if len(state.PeerCertificates) == 0 {
				tlsConn.Close()
				continue
			}
			cert := state.PeerCertificates[0]

			// Identify which node they authenticated as.
			matched := false
			for _, node := range config.Nodes() {
				var verifyOpts x509.VerifyOptions
				verifyOpts.Intermediates = new(x509.CertPool)
				verifyOpts.Roots = config.NodeCertPool(node)
				chains, err := cert.Verify(verifyOpts)
				if err != nil {
					continue
				}

				// Matched the node. Start the handler.
				if len(chains) > 0 {
					matched = true
					go handler(node, newBaseConn(tlsConn))
					break
				}
			}

			// No matching node found. Close the connection.
			if !matched {
				tlsConn.Close()
			}
		} else {
			// We don't authenticate clients.
			// Just run the handler.
			handler(0, newBaseConn(tlsConn))
		}
	}
}