Example #1
0
/**
 * This creates a new certificates pool that can be used to validate user
 * certificate and synchronizes concurrent access to that pool.
 * This is expected since ServerHTTP run on their own goroutine
 * @param path is the path to retrieve CA certificates
 * @param c is the channel to write to
 * @see #PopulateCertPool(string)
 */
func CaCertPoolManager(path string, c chan *x509.CertPool) {

	var logger = NewPrefixed("security#CaCertPoolManager")

	caCertPool := new(x509.CertPool)
	caCertPool, err := populateCertPool(path)
	if err != nil {
		logger.Fatal(err.Error())
	}

	for {
		select {
		case c <- caCertPool:
			logger.Finest("Written caCertPool: %v", len(caCertPool.Subjects()))
		}
	}
}
Example #2
0
File: main.go Project: sbinet/fedid
/**
 * This is the standard main function
 */
func main() {

	SetLoggerLevel(conf.LoggerLevel)
	var logger = NewPrefixed("main#main")

	confFilePath := ""
	baseName := filepath.Base(os.Args[0])
	jsonConfFileName := baseName + ".json"
	dirName, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		logger.Fatal("%v", err)
	}

	if len(os.Args) > 1 {
		confFilePath = os.Args[1]
	}
	jsonConfFile, err := os.Open(confFilePath)
	if err != nil {
		logger.Debug("Can't find json conf file : %v", confFilePath)
		confFilePath, err = filepath.Abs(dirName + "/../conf/" + jsonConfFileName)
	}
	jsonConfFile, err = os.Open(confFilePath)
	if err != nil {
		logger.Debug("Can't find json conf file : %v", confFilePath)
		confFilePath = "/etc/" + jsonConfFileName
	}
	jsonConfFile, err = os.Open(confFilePath)
	if err != nil {
		logger.Fatal("Can't find json conf file : %v", confFilePath)
	}

	decoder := json.NewDecoder(jsonConfFile)
	err = decoder.Decode(&conf)
	if err != nil {
		fmt.Println("error:", err)
	}

	logger.Info("%v", conf)

	if conf.CACertPath == "" {
		logger.Warn("CA certificate path is not set: X509 credentials refused")
	}
	if conf.CertPath == "" {
		logger.Fatal("server certificate path is not set")
	}
	if conf.KeyPath == "" {
		logger.Fatal("server key path is not set")
	}

	oauthConfigurationChannels = make(map[string]chan *oauth2.Config)
	hostName := GetLocalHostName()

	for _, s := range conf.OAuthServers {

		if len(s.Name) < 1 ||
			len(s.Clientid) < 1 ||
			len(s.Clientsecret) < 1 ||
			len(s.RedirectUrl) < 1 ||
			len(s.AuthUrl) < 1 ||
			len(s.TokenUrl) < 1 {

			logger.Warn("Ignoring %v : incorrect configuration", s.Name)
			continue
		}
		//
		// start OAuth config manager
		//
		logger.Info("s.Name = %v", s.Name)
		oauthConfigurationChannels[s.Name] = make(chan *oauth2.Config)
		go OAuthConfigurationManager(
			s.Clientid,
			s.Clientsecret,
			s.RedirectUrl,
			s.AuthUrl,
			s.TokenUrl,
			oauthConfigurationChannels[s.Name])
	}

	//
	// start CA cert pool manager
	//
	var caCertPool *x509.CertPool
	caChannel = nil
	caCertPool = nil

	if conf.CACertPath != "" {
		caChannel = make(chan *x509.CertPool)
		go CaCertPoolManager(conf.CACertPath, caChannel)

		//
		// get CA cert pool
		//
		caCertPool := <-caChannel
		logger.Debug("CA pool length = %v", len(caCertPool.Subjects()))
	}

	//
	// Retrieve certificate
	//
	cert, err := TLSCerficateFromPEMs(conf.CertPath, conf.KeyPath)
	if err != nil {
		logger.Fatal(err.Error())
	}

	logger.Debug("serverCert.Subject = %v", cert.Leaf.Subject)
	logger.Debug("serverCert.Issuer  = %v", cert.Leaf.Issuer)

	//
	// Verify cert against known CA
	//
	if caCertPool != nil {
		vOpts := x509.VerifyOptions{Roots: caCertPool}
		_, err = cert.Leaf.Verify(vOpts)
		if err != nil {
			logger.Warn("failed to parse server certificate: " + err.Error())
		}
	}

	tlsConfig := TLSConfig(cert, caCertPool)

	os.Create(backendfile)
	defer os.Remove(backendfile)
	backend, err = httpauth.NewGobFileAuthBackend(backendfile)
	if err != nil {
		logger.Fatal("can't create backend %v", err)
	}

	// create some default roles
	roles = make(map[string]httpauth.Role)
	roles["user"] = 30
	roles["admin"] = 80
	httpAuthorizer, err = httpauth.NewAuthorizer(backend, []byte("cookie-encryption-key"), "user", roles)

	// set up routers and route handlers
	r := mux.NewRouter()
	//	r.HandleFunc("/", handlePage).Methods("GET") // authorized page
	r.HandleFunc("/logout", handleLogout)
	r.HandleFunc(ROOTURL, X509Authenticator)
	r.HandleFunc(OAUTHURL, OAuthenticationPage)
	for _, s := range conf.OAuthServers {
		r.HandleFunc(OAUTHURL+s.Name, OAuthAuthenticator)
	}
	r.HandleFunc(APPSURL, handlePage)
	r.HandleFunc(JWTURL, JWTAuthenticator)

	server := http.Server{Addr: hostName + ":" + conf.PortNumber, TLSConfig: tlsConfig, Handler: r}

	// start https
	logger.Info("Listening HTTPS : " + hostName + ":" + conf.PortNumber)

	server.ListenAndServeTLS(conf.CertPath, conf.KeyPath)
}