func certUploadPageHandler(w http.ResponseWriter, r *http.Request, bctx *BasePageContext) { r.ParseMultipartForm(32 << 20) file, handler, err := r.FormFile("uploadfile") if err != nil { logging.LogForRequest(logCerts, r).Warn("certUploadPageHandler - get form file error", "err", err) bctx.AddFlashMessage("Upload file error: "+err.Error(), "error") bctx.Save() http.Redirect(w, r, "/certs/", http.StatusFound) return } defer file.Close() f, err := os.OpenFile(path.Join(bctx.Globals.Config.CertsDir, handler.Filename), os.O_WRONLY|os.O_CREATE, 0666) if err != nil { logging.LogForRequest(logCerts, r).Warn("certUploadPageHandler - open file error", "certname", handler.Filename, "user", bctx.UserLogin(), "err", err) bctx.AddFlashMessage("Upload file error: "+err.Error(), "error") http.Redirect(w, r, "/certs/", http.StatusFound) bctx.Save() return } defer f.Close() if _, err := io.Copy(f, file); err == nil { logging.LogForRequest(logCerts, r).Info("certUploadPageHandler upload success", "certname", handler.Filename, "user", bctx.UserLogin()) bctx.AddFlashMessage("Upload file success", "success") } else { logging.LogForRequest(logCerts, r).Warn("certUploadPageHandler upload error", "certname", handler.Filename, "user", bctx.UserLogin(), "err", err) bctx.AddFlashMessage("Upload file error: "+err.Error(), "error") } bctx.Save() http.Redirect(w, r, "/certs/", http.StatusFound) }
func endpointPageHandler(w http.ResponseWriter, r *http.Request, bctx *BasePageContext) { vars := mux.Vars(r) ctx := &struct { *BasePageContext Form endpointForm AllUsers []*config.User Certs []string }{ BasePageContext: bctx, AllUsers: bctx.Globals.GetUsers(), Certs: bctx.Globals.FindCerts(), } if r.Method == "POST" && r.FormValue("_method") != "" { r.Method = r.FormValue("_method") } epname, ok := vars["name"] if !ok || epname == "" { logging.LogForRequest(logEP, r).Error("admin.endpointPageHandler missing name", "vars", vars) http.Error(w, "Missing name", http.StatusBadRequest) return } newEp := epname == "<new>" if !newEp { if ep := bctx.Globals.GetEndpoint(epname); ep != nil { ctx.Form.EndpointConf = ep.Clone() } else { logging.LogForRequest(logEP, r).Error("admin.endpointPageHandler ep not found", "endpoint", epname) http.Error(w, "Endpoint not found", http.StatusNotFound) return } } else { ctx.Form.EndpointConf = &config.EndpointConf{} } switch r.Method { case "POST": r.ParseForm() if err := decoder.Decode(&ctx.Form, r.Form); err != nil { logging.LogForRequest(logEP, r).Error("admin.endpointPageHandler decode form error", "err", err, "form", r.Form) break } if errors := ctx.Form.Validate(bctx.Globals, newEp); len(errors) > 0 { ctx.Form.Errors = errors break } bctx.Globals.SaveEndpoint(ctx.Form.EndpointConf) ctx.AddFlashMessage("Endpoint saved", "success") ctx.Save() http.Redirect(w, r, "/endpoints/", http.StatusFound) return } ctx.Save() RenderTemplateStd(w, ctx, "endpoints/endpoint.tmpl") }
func chpassPageHandler(w http.ResponseWriter, r *http.Request, bctx *BasePageContext) { ctx := &struct { *BasePageContext Form chpassForm }{ BasePageContext: bctx, } suser, ok := bctx.Session.GetLoggedUser() if !ok || suser == nil { logging.LogForRequest(logUsers, r).Error("admin.chpassPageHandler user not logged") http.Error(w, "Not logged user", http.StatusBadRequest) return } switch r.Method { case "POST": r.ParseForm() if err := decoder.Decode(&ctx.Form, r.Form); err != nil { logging.LogForRequest(logUsers, r).Error("admin.chpassPageHandler decode form error", "err", err, "form", r.Form) break } user := bctx.Globals.GetUser(suser.Login) if user == nil { logging.LogForRequest(logUsers, r).Error("admin.chpassPageHandler user not found", "login", suser.Login) http.Error(w, "Bad user", http.StatusBadRequest) return } ctx.Form.Errors = make(map[string]string) if !user.CheckPassword(ctx.Form.CurrentPass) { ctx.Form.Errors["CurrentPass"] = "******" break } if ctx.Form.NewPasswordC != ctx.Form.NewPassword { ctx.Form.Errors["NewPassword"] = "******" break } if user.Login == "admin" { user.Active = true } user.UpdatePassword(ctx.Form.NewPassword) bctx.Globals.SaveUser(user) ctx.AddFlashMessage("Password updated", "success") ctx.Save() http.Redirect(w, r, "/", http.StatusFound) return } ctx.Save() RenderTemplateStd(w, ctx, "users/chpass.tmpl") }
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) }) }
func setdebugPageHandler(w http.ResponseWriter, r *http.Request, bctx *BasePageContext) { r.ParseForm() level := "" if levels, ok := r.Form["l"]; ok && len(levels) > 0 { level = levels[0] } res := false switch level { case "0": res = logging.SetDebugLevel(0) break case "1": res = logging.SetDebugLevel(1) break case "2": res = logging.SetDebugLevel(2) break default: logging.LogForRequest(logCerts, r).Warn("setdebugPageHandler missing level", "form", r.Form) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } if res { bctx.AddFlashMessage("Logging level changed", "success") bctx.Save() } http.Redirect(w, r, "/settings/", http.StatusFound) }
func certDeletePageHandler(w http.ResponseWriter, r *http.Request, bctx *BasePageContext) { r.ParseForm() certname := "" if certnames, ok := r.Form["c"]; ok && len(certnames) > 0 { certname = certnames[0] } if certname == "" { logging.LogForRequest(logCerts, r).Warn("certDeletePageHandler missing certname", "form", r.Form) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } if epname, used := bctx.Globals.CertUsed(certname); used { logging.LogForRequest(logCerts, r).Info("certDeletePageHandler - cert used", "certname", certname, "endpoint", epname) bctx.AddFlashMessage("File is used in "+epname+" - can't be deleted", "error") bctx.Save() http.Redirect(w, r, "/certs/", http.StatusFound) return } certname, _ = filepath.Abs(certname) certname = filepath.Clean(certname) certsdir, _ := filepath.Abs(bctx.Globals.Config.CertsDir) certsdir = filepath.Clean(certsdir) if certname == "" || !strings.HasPrefix(certname, certsdir) || certname == certsdir { logging.LogForRequest(logCerts, r).Warn("certDeletePageHandler invalid cert", "certname", certname, "form", r.Form, "certsdir", certsdir) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } if err := os.Remove(certname); err == nil { logging.LogForRequest(logCerts, r).Info("certDeletePageHandler cert deleted", "certname", certname, "user", bctx.UserLogin()) bctx.AddFlashMessage("File deleted", "success") } else { logging.LogForRequest(logCerts, r).Warn("certDeletePageHandler cert deleted error", "certname", certname, "err", err, "user", bctx.UserLogin()) bctx.AddFlashMessage("File delete error: "+err.Error(), "error") } bctx.Save() http.Redirect(w, r, "/certs/", http.StatusFound) }
func endpointActionPageHandler(w http.ResponseWriter, r *http.Request, bctx *BasePageContext) { vars := mux.Vars(r) epname, ok := vars["name"] if !ok || epname == "" { logging.LogForRequest(logEP, r).Error("admin.endpointActionPageHandler missing name", "vars", vars) http.Error(w, "Missing name", http.StatusBadRequest) return } action, ok := vars["action"] if !ok || action == "" { logging.LogForRequest(logEP, r).Error("admin.endpointActionPageHandler missing action", "vars", vars) http.Error(w, "Missing action", http.StatusBadRequest) return } switch action { case "start": err := proxy.StartEndpoint(epname, bctx.Globals) if len(err) == 0 { bctx.AddFlashMessage("Endpoint started", "success") } else { bctx.AddFlashMessage("Endpoint failed to start: "+strings.Join(err, ", "), "error") } break case "stop": proxy.StopEndpoint(epname) bctx.AddFlashMessage("Endpoint stopped", "success") break case "delete": proxy.StopEndpoint(epname) bctx.Globals.DeleteEndpoint(epname) bctx.AddFlashMessage("Endpoint deleted", "success") break default: logging.LogForRequest(logEP, r).Warn("admin.endpointActionPageHandler invalid action", "action", action) } bctx.Save() http.Redirect(w, r, "/endpoints/", http.StatusFound) return }
// LogHandler log all requests. func LogHandler(h http.Handler, prefix string, logkv ...interface{}) http.HandlerFunc { orgLogkv := logkv return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() logkv = append(orgLogkv, "start") logkv = append(logkv, start.Unix()) logger := l.LogForRequest(l.Log, r).New(logkv...) logger.Debug(prefix + "begin request") writer := &loggingResponseWriter{ResponseWriter: w, status: 200} defer func() { end := time.Now() stack := debug.Stack() if err := recover(); err == nil { //l.Debugf("%d %s %s %s %s", writer.status, r.Method, r.URL.String(), r.RemoteAddr, end.Sub(start)) logger.Debug(prefix+"request finished", "status", writer.status, "end", end.Unix(), "time", end.Sub(start).String()) } else { logger.Debug(prefix+"request error", "status", writer.status, "err", err, "end", end.Unix(), "time", end.Sub(start).String(), "st", string(stack)) } }() h.ServeHTTP(writer, r) }) }
func userPageHandler(w http.ResponseWriter, r *http.Request, bctx *BasePageContext) { vars := mux.Vars(r) ctx := &struct { *BasePageContext Form userForm AllRoles []string }{ BasePageContext: bctx, AllRoles: []string{"ADMIN", "USER"}, } if r.Method == "POST" && r.FormValue("_method") != "" { r.Method = r.FormValue("_method") } login, ok := vars["login"] if !ok || login == "" { logging.LogForRequest(logUsers, r).Error("admin.userPageHandler missing login", "vars", vars) http.Error(w, "Missing login", http.StatusBadRequest) return } newUser := login == "<new>" if !newUser { if user := bctx.Globals.GetUser(login); user != nil { ctx.Form.User = user.Clone() } else { logging.LogForRequest(logUsers, r).Error("admin.userPageHandler user not found", "login", login) http.Error(w, "User not found", http.StatusNotFound) return } } else { ctx.Form.User = &config.User{} } switch r.Method { case "POST": r.ParseForm() var currLogin = ctx.Form.User.Login ctx.Form.User.Active = false // post not send unchecked checkboxes if err := decoder.Decode(&ctx.Form, r.Form); err != nil { logging.LogForRequest(logUsers, r).Error("admin.userPageHandler decode form error ", "err", err, "form", r.Form) break } if !newUser && ctx.Form.User.Login != login { logging.LogForRequest(logUsers, r).Error("admin.userPageHandler login != form.login ", "login", login, "login-form", ctx.Form.User.Login) http.Error(w, "Wrong/changed login", http.StatusBadRequest) return } if !newUser && ctx.Form.User.Login != currLogin { logging.LogForRequest(logUsers, r).Warn("login changed - reverting") ctx.Form.User.Login = currLogin } if errors := ctx.Form.Validate(bctx.Globals, newUser); len(errors) > 0 { ctx.Form.Errors = errors break } if ctx.Form.NewPassword != "" { ctx.Form.User.UpdatePassword(ctx.Form.NewPassword) } bctx.Globals.SaveUser(ctx.Form.User) ctx.AddFlashMessage("User saved", "success") ctx.Save() http.Redirect(w, r, "/users/", http.StatusFound) return } ctx.Save() RenderTemplateStd(w, ctx, "users/user.tmpl") }