Beispiel #1
0
func authenticationMW(h http.Handler, endpoint string, globals *config.Globals) http.Handler {
	conf := globals.GetEndpoint(endpoint)
	var networks []*net.IPNet
	if conf.AcceptAddr != "" {
		networks = prepareNetworks(conf.AcceptAddr)
	}

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if networks != nil {
			if !acceptAddress(networks, r.RemoteAddr) {
				log.Info("authenticationMW 403 Forbidden - addr", "endpoint", endpoint,
					"addr", r.RemoteAddr)
				http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
				counters.Add(endpoint+"|403", 1)
				return
			}
		}

		if len(conf.Users) == 0 {
			h.ServeHTTP(w, r)
			return
		}
		usr, pass, _ := r.BasicAuth()
		if usr == "" && r.URL != nil && r.URL.User != nil {
			usr = r.URL.User.Username()
			pass, _ = r.URL.User.Password()
		}

		if usr == "" {
			w.Header().Set("WWW-Authenticate", "Basic realm=\"REALM\"")
			logging.LogForRequest(log, r).Info("authenticationMW 401 Unauthorized", "endpoint", endpoint, "status", 401)
			http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
			counters.Add(endpoint+"|401", 1)
			return
		}

		user := globals.GetUser(usr)
		if user.Active && conf.AcceptUser(user.Login) && user.CheckPassword(pass) {
			r.Header.Set("X-Authenticated-User", usr)
			counters.Add(endpoint+"|pass", 1)
			h.ServeHTTP(w, r)
			return
		}
		//log.Info("authenticationMW ", endpoint, " 403 Forbidden")
		//http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
		counters.Add(endpoint+"|403", 1)

		w.Header().Set("WWW-Authenticate", "Basic realm=\"REALM\"")
		logging.LogForRequest(log, r).Info("authenticationMW 401 Unauthorized", "endpoint", endpoint, "status", 401,
			"user", user.Login, "user_active", user.Active)
		http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
	})
}
Beispiel #2
0
func StartEndpoint(name string, globals *config.Globals) (errstr []string) {
	log.Info("server.StartEndpoint starting ", "endpoint", name)

	mu.Lock()
	defer mu.Unlock()

	var st *state
	var ok bool
	if st, ok = states[name]; ok && st != nil {
		if st.running || st.runningSSL {
			log.Warn("server.StartEndpoint already started ", "enpoint", name)
			return []string{"already running"}
		}
	}
	if st == nil {
		st = &state{
			serverClose:    make(chan bool),
			serverSSLClose: make(chan bool),
		}
		states[name] = st
	}

	servStat.Set(name, varState("stopped"))
	servStat.Set(name+"|ssl", varState("stopped"))
	conf := globals.GetEndpoint(name)
	if conf == nil {
		return []string{"invalid endpoint"}
	}
	uri, err := url.Parse(conf.Destination)
	if err != nil {
		return []string{"invalid url"}
	}

	var handler http.Handler

	handler = httputil.NewSingleHostReverseProxy(uri)
	handler = authenticationMW(handler, name, globals)
	handler = counterMw(handler, name)
	handler = common.LogHandler(handler, "server:", "endpoint", name, "module", "server")
	handler = globals.StatsServer.Handler(handler)

	if conf.HTTPAddress != "" {
		log.Info("server.StartEndpoint starting http", "endpoint", name)
		s := &http.Server{
			Addr:         conf.HTTPAddress,
			Handler:      handler,
			ReadTimeout:  10 * time.Second,
			WriteTimeout: 10 * time.Second,
		}
		ls, e := net.Listen("tcp", conf.HTTPAddress)
		if e != nil {
			log.Error("server.StartEndpoint starting http listen error ", "endpoint", name, "err", e)
			errstr = append(errstr, "starting http error "+e.Error())
			errors.Set(name, varState(e.Error()))
		} else {
			go func() {
				st.running = true
				go s.Serve(ls)
				servStat.Set(name, varState("running"))
				errors.Set(name, varState(""))
				select {
				case <-st.serverClose:
					log.Info("server.StartEndpoint stop http ", "endpoint", name)
					ls.Close()
					st.running = false
					servStat.Set(name, varState("stopped"))
					return
				}
			}()
		}
	}

	if conf.HTTPSAddress != "" {
		log.Info("server.StartEndpoint starting https ", "endpoint", name)
		s := &http.Server{
			Addr:         conf.HTTPSAddress,
			Handler:      handler,
			ReadTimeout:  10 * time.Second,
			WriteTimeout: 10 * time.Second,
		}
		config := &tls.Config{}
		if config.NextProtos == nil {
			config.NextProtos = []string{"http/1.1"}
		}

		var err error
		config.Certificates = make([]tls.Certificate, 1)
		config.Certificates[0], err = tls.LoadX509KeyPair(conf.SslCert, conf.SslKey)
		if err != nil {
			log.Error("server.StartEndpoint starting https cert error", "err", err, "endpoint", name)
			errstr = append(errstr, "starting https - cert error "+err.Error())
			errors.Set(name+"|ssl", varState(err.Error()))
		} else {
			ln, err := net.Listen("tcp", conf.HTTPSAddress)
			if err != nil {
				log.Error("server.StartEndpoint starting https listen error ", "err", err, "endpoint", name)
				errstr = append(errstr, "starting https error "+err.Error())
				errors.Set(name+"|ssl", varState(err.Error()))
			} else {
				tlsListener := tls.NewListener(ln, config)
				go func() {
					st.runningSSL = true
					go s.Serve(tlsListener)
					servStat.Set(name+"|ssl", varState("running"))
					errors.Set(name+"|ssl", varState(""))
					select {
					case <-st.serverSSLClose:
						log.Info("server.StartEndpoint stop https", "endpoint", name)
						ln.Close()
						st.runningSSL = false
						servStat.Set(name, varState("stopped"))
						return
					}
				}()
			}
		}
	}

	return
}