diff --git a/server/core/auth.go b/server/core/auth.go index f8c5fecd..5e5e7e8c 100644 --- a/server/core/auth.go +++ b/server/core/auth.go @@ -251,7 +251,7 @@ type AuthState struct { // StatusMessage is the HTTP response payload that is sent to the remote server that asked for authentication. StatusMessage string - // Service is set by Nauthilus depending on the router endpoint. Look at httpQueryHandler for the structure of available + // Service is set by Nauthilus depending on the router endpoint. Look at requestHandler for the structure of available // endpoints. Service string @@ -580,9 +580,9 @@ func (a *AuthState) authOK(ctx *gin.Context) { switch a.Service { case global.ServNginx: setNginxHeaders(ctx, a) - case global.ServDovecot: - setDovecotHeaders(ctx, a) - case global.ServUserInfo, global.ServJSON: + case global.ServHeader: + setHeaderHeaders(ctx, a) + case global.ServJSON: sendAuthResponse(ctx, a) } @@ -597,13 +597,13 @@ func (a *AuthState) authOK(ctx *gin.Context) { // setCommonHeaders sets common headers for the given gin.Context and AuthState. // It sets the "Auth-Status" header to "OK" and the "X-Nauthilus-Session" header to the GUID of the AuthState. -// If the AuthState's Service is not global.ServBasicAuth, and the HaveAccountField flag is true, +// If the AuthState's Service is not global.ServBasic, and the HaveAccountField flag is true, // it retrieves the account from the AuthState and sets the "Auth-User" header func setCommonHeaders(ctx *gin.Context, a *AuthState) { ctx.Header("Auth-Status", "OK") ctx.Header("X-Nauthilus-Session", *a.GUID) - if a.Service != global.ServBasicAuth { + if a.Service != global.ServBasic { if account, found := a.getAccountOk(); found { ctx.Header("Auth-User", account) } @@ -650,7 +650,7 @@ func setNginxHeaders(ctx *gin.Context, a *AuthState) { } } -// setDovecotHeaders sets the specified headers in the given gin.Context based on the attributes in the AuthState object. +// setHeaderHeaders sets the specified headers in the given gin.Context based on the attributes in the AuthState object. // It iterates through the attributes and calls the handleAttributeValue function for each attribute. // // Parameters: @@ -665,12 +665,12 @@ func setNginxHeaders(ctx *gin.Context, a *AuthState) { // "Attribute2": []any{"Value2_1", "Value2_2"}, // }, // } -// setDovecotHeaders(ctx, a) +// setHeaderHeaders(ctx, a) // // Resulting headers in ctx: // - X-Nauthilus-Attribute1: "Value1" // - X-Nauthilus-Attribute2: "Value2_1,Value2_2" -func setDovecotHeaders(ctx *gin.Context, a *AuthState) { +func setHeaderHeaders(ctx *gin.Context, a *AuthState) { if a.Attributes != nil && len(a.Attributes) > 0 { for name, value := range a.Attributes { handleAttributeValue(ctx, name, value) @@ -805,7 +805,7 @@ func (a *AuthState) setFailureHeaders(ctx *gin.Context) { ctx.Header("Auth-Wait", fmt.Sprintf("%v", waitDelay)) } - case global.ServUserInfo, global.ServJSON: + case global.ServJSON: ctx.Header("Content-Type", "application/json; charset=UTF-8") if a.PasswordHistory != nil { @@ -859,7 +859,7 @@ func (a *AuthState) setSMPTHeaders(ctx *gin.Context) { // // func (a *AuthState) authTempFail(ctx *gin.Context, reason string) { // ... -// if a.Service == global.ServUserInfo { +// if a.Service == global.ServJSON { // a.sendAuthResponse(ctx, reason) // return // } @@ -875,7 +875,6 @@ func (a *AuthState) setUserInfoHeaders(ctx *gin.Context, reason string) { } ctx.Header("Content-Type", "application/json; charset=UTF-8") - ctx.Header("X-User-Found", fmt.Sprintf("%v", a.UserFound)) ctx.JSON(a.StatusCodeInternalError, &errType{Error: reason}) } @@ -892,12 +891,12 @@ func (a *AuthState) setUserInfoHeaders(ctx *gin.Context, reason string) { // // Usage example: // -// func (a *AuthState) generic(ctx *gin.Context) { +// func (a *AuthState) handleAuthentication(ctx *gin.Context) { // ... // a.authTempFail(ctx, global.TempFailDefault) // ... // } -// func (a *AuthState) saslAuthd(ctx *gin.Context) { +// func (a *AuthState) handleSASLAuthdAuthentication(ctx *gin.Context) { // ... // a.authTempFail(ctx, global.TempFailDefault) // ... @@ -915,8 +914,9 @@ func (a *AuthState) authTempFail(ctx *gin.Context, reason string) { a.StatusMessage = reason - if a.Service == global.ServUserInfo { + if a.Service == global.ServJSON { a.setUserInfoHeaders(ctx, reason) + return } @@ -1117,11 +1117,11 @@ func updateAuthentication(a *AuthState, passDBResult *PassDBResult, passDB *Pass // setStatusCodes sets different status codes for various services. func (a *AuthState) setStatusCodes(service string) error { switch service { - case global.ServNginx, global.ServDovecot: + case global.ServNginx: a.StatusCodeOK = http.StatusOK a.StatusCodeInternalError = http.StatusOK a.StatusCodeFail = http.StatusOK - case global.ServSaslauthd, global.ServBasicAuth, global.ServOryHydra, global.ServUserInfo, global.ServJSON, global.ServCallback: + case global.ServSaslauthd, global.ServBasic, global.ServOryHydra, global.ServHeader, global.ServJSON, global.ServCallback: a.StatusCodeOK = http.StatusOK a.StatusCodeInternalError = http.StatusInternalServerError a.StatusCodeFail = http.StatusForbidden @@ -2163,10 +2163,10 @@ func setupBodyBasedAuth(ctx *gin.Context, auth *AuthState) { } } -// setupHTTPBasiAuth sets up basic authentication for HTTP requests. +// setupHTTPBasicAuth sets up basic authentication for HTTP requests. // It takes in a gin.Context object and a pointer to an AuthState object. // It calls the withClientInfo, withLocalInfo, withUserAgent, and withXSSL methods of the AuthState object to set client, local, user-agent, and X-SSL information, respectively -func setupHTTPBasiAuth(ctx *gin.Context, auth *AuthState) { +func setupHTTPBasicAuth(ctx *gin.Context, auth *AuthState) { // NOTE: We must get username and password later! auth.withClientInfo(ctx) auth.withLocalInfo(ctx) @@ -2192,9 +2192,9 @@ func (a *AuthState) initMethodAndUserAgent() *AuthState { // setupAuth sets up the authentication based on the service parameter in the gin context. // It takes the gin context and an AuthState struct as input. // -// If the service parameter is "nginx", "dovecot", or "user", it calls the setupHeaderBasedAuth function. +// If the service parameter is "nginx" or "header", it calls the setupHeaderBasedAuth function. // If the service parameter is "saslauthd", it calls the setupBodyBasedAuth function. -// If the service parameter is "basicauth", it calls the setupHTTPBasiAuth function. +// If the service parameter is "basicauth", it calls the setupHTTPBasicAuth function. // // After setting up the authentication, it calls the withDefaults method on the AuthState struct. // @@ -2208,19 +2208,19 @@ func setupAuth(ctx *gin.Context, auth *AuthState) { auth.Protocol = &config.Protocol{} switch ctx.Param("service") { - case global.ServNginx, global.ServDovecot, global.ServUserInfo: + case global.ServNginx, global.ServHeader: setupHeaderBasedAuth(ctx, auth) case global.ServSaslauthd, global.ServJSON: setupBodyBasedAuth(ctx, auth) - case global.ServBasicAuth: - setupHTTPBasiAuth(ctx, auth) + case global.ServBasic: + setupHTTPBasicAuth(ctx, auth) case global.ServCallback: auth.withDefaults(ctx) return } - if ctx.Query("mode") != "list-accounts" && ctx.Param("service") != global.ServBasicAuth { + if ctx.Query("mode") != "list-accounts" && ctx.Param("service") != global.ServBasic { if !util.ValidateUsername(auth.Username) { auth.Username = "" @@ -2293,7 +2293,7 @@ func (a *AuthState) withDefaults(ctx *gin.Context) *AuthState { a.Service = ctx.Param("service") a.Context = ctx.MustGet(global.CtxDataExchangeKey).(*lualib.Context) - if a.Service == global.ServBasicAuth { + if a.Service == global.ServBasic { a.Protocol.Set(global.ProtoHTTP) } diff --git a/server/core/features.go b/server/core/features.go index 322452dc..883363a7 100644 --- a/server/core/features.go +++ b/server/core/features.go @@ -47,7 +47,7 @@ func isLocalOrEmptyIP(ip string) bool { return ip == global.Localhost4 || ip == global.Localhost6 || ip == "" } -// logAddMessage logs a message with the specified parameters using the global logger. It is intended to be a generic logging function. +// logAddMessage logs a message with the specified parameters using the global logger. It is intended to be a handleAuthentication logging function. // // Parameters: // - auth: Pointer to AuthState diff --git a/server/core/http.go b/server/core/http.go index d1694f89..f1bfff54 100644 --- a/server/core/http.go +++ b/server/core/http.go @@ -69,7 +69,7 @@ var ( LangBundle *i18n.Bundle ) -// RESTResult is a generic JSON result object for the Nauthilus REST API. +// RESTResult is a handleAuthentication JSON result object for the Nauthilus REST API. type RESTResult struct { // GUID represents a unique identifier for a session. It is a string field used in the RESTResult struct // and is also annotated with the json tag "session". @@ -165,12 +165,12 @@ func (w *customWriter) Write(data []byte) (numBytes int, err error) { } //nolint:gocognit // Main logic -func httpQueryHandler(ctx *gin.Context) { +func requestHandler(ctx *gin.Context) { if ctx.FullPath() == "/ping" { healthCheck(ctx) } else { switch ctx.Param("category") { - case global.CatMail, global.CatGeneric: + case global.CatAuth: auth := NewAuthState(ctx) if auth == nil { ctx.AbortWithStatus(http.StatusBadRequest) @@ -185,42 +185,21 @@ func httpQueryHandler(ctx *gin.Context) { } switch ctx.Param("service") { - case global.ServNginx, global.ServDovecot, global.ServUserInfo, global.ServJSON: - auth.generic(ctx) + case global.ServBasic, global.ServNginx, global.ServHeader, global.ServJSON: + auth.handleAuthentication(ctx) case global.ServSaslauthd: - auth.saslAuthd(ctx) + auth.handleSASLAuthdAuthentication(ctx) case global.ServCallback: - auth.callback(ctx) + auth.handleCallback(ctx) ctx.Status(auth.StatusCodeOK) default: ctx.AbortWithStatus(http.StatusNotFound) } - case global.CatHTTP: - auth := NewAuthState(ctx) - if auth == nil { - ctx.AbortWithStatus(http.StatusBadRequest) - - return - } - - if found, reject := auth.preproccessAuthRequest(ctx); reject { - return - } else if found { - auth.withClientInfo(ctx).withLocalInfo(ctx).withUserAgent(ctx).withXSSL(ctx) - } - - switch ctx.Param("service") { - case global.ServBasicAuth: - auth.generic(ctx) - default: - ctx.AbortWithStatus(http.StatusNotFound) - } - case global.CatBruteForce: switch ctx.Param("service") { case global.ServList: - listBruteforce(ctx) + hanldeBruteForceList(ctx) default: ctx.AbortWithStatus(http.StatusNotFound) } @@ -239,23 +218,23 @@ func httpQueryHandler(ctx *gin.Context) { // 2. It uses a switch statement to handle different category values. // 3. For the "cache" category, it retrieves the "service" parameter and uses a switch statement // to handle different service values. -// 4. For the "flush" service, it calls the flushCache function. +// 4. For the "flush" service, it calls the handleUserFlush function. // 5. For the "bruteforce" category, it retrieves the "service" parameter and uses a switch statement // to handle different service values. -// 6. For the "flush" service, it calls the flushBruteForceRule function. +// 6. For the "flush" service, it calls the handleBruteForceRuleFlush function. func httpCacheHandler(ctx *gin.Context) { //nolint:gocritic // Prepared for future commands switch ctx.Param("category") { case global.CatCache: switch ctx.Param("service") { case global.ServFlush: - flushCache(ctx) + handleUserFlush(ctx) } case global.CatBruteForce: switch ctx.Param("service") { case global.ServFlush: - flushBruteForceRule(ctx) + handleBruteForceRuleFlush(ctx) } } } @@ -359,7 +338,7 @@ func basicAuthMiddleware() gin.HandlerFunc { guid := ctx.GetString(global.CtxGUIDKey) // Note: Chicken-egg problem. - if ctx.Param("category") == global.CatHTTP && ctx.Param("service") == global.ServBasicAuth { + if ctx.Param("category") == global.CatAuth && ctx.Param("service") == global.ServBasic { level.Warn(log.Logger).Log( global.LogKeyGUID, guid, global.LogKeyMsg, "Disabling HTTP basic Auth", @@ -732,8 +711,8 @@ func setupNotifyEndpoint(router *gin.Engine, sessionStore sessions.Store) { // it adds a middleware to the group that implements basic authentication. // // It then adds three endpoints to the group: -// - A GET endpoint with the path "/:category/:service" that is handled by the luaContextMiddleware and httpQueryHandler functions. -// - A POST endpoint with the path "/:category/:service" that is also handled by the luaContextMiddleware and httpQueryHandler functions. +// - A GET endpoint with the path "/:category/:service" that is handled by the luaContextMiddleware and requestHandler functions. +// - A POST endpoint with the path "/:category/:service" that is also handled by the luaContextMiddleware and requestHandler functions. // - A DELETE endpoint with the path "/:category/:service" that is handled by the httpCacheHandler function. func setupBackChannelEndpoints(router *gin.Engine) { group := router.Group("/api/v1") @@ -742,8 +721,8 @@ func setupBackChannelEndpoints(router *gin.Engine) { group.Use(basicAuthMiddleware()) } - group.GET("/:category/:service", luaContextMiddleware(), httpQueryHandler) - group.POST("/:category/:service", luaContextMiddleware(), httpQueryHandler) + group.GET("/:category/:service", luaContextMiddleware(), requestHandler) + group.POST("/:category/:service", luaContextMiddleware(), requestHandler) group.DELETE("/:category/:service", httpCacheHandler) } @@ -990,7 +969,7 @@ func setupRouter(router *gin.Engine) { router.GET("/metrics", gin.WrapF(promhttp.Handler().ServeHTTP)) // Healthcheck - router.GET("/ping", httpQueryHandler) + router.GET("/ping", requestHandler) // Parse static folder for template files router.LoadHTMLGlob(viper.GetString("html_static_content_path") + "/*.html") diff --git a/server/core/rest.go b/server/core/rest.go index 688efce8..811f477a 100644 --- a/server/core/rest.go +++ b/server/core/rest.go @@ -111,11 +111,11 @@ type FilterCmd struct { IPAddress []string `json:"ip_addresses,omitempty"` } -// generic handles the generic authentication logic based on the selected service type. -func (a *AuthState) generic(ctx *gin.Context) { +// handleAuthentication handles the authentication logic based on the selected service type. +func (a *AuthState) handleAuthentication(ctx *gin.Context) { var mode string - if a.Service == global.ServBasicAuth { + if a.Service == global.ServBasic { var httpBasicAuthOk bool // Decode HTTP basic Auth @@ -195,8 +195,8 @@ func (a *AuthState) generic(ctx *gin.Context) { } } -// saslAuthd handles the authentication logic for the saslAuthd service. -func (a *AuthState) saslAuthd(ctx *gin.Context) { +// handleSASLAuthdAuthentication handles the authentication logic for the handleSASLAuthdAuthentication service. +func (a *AuthState) handleSASLAuthdAuthentication(ctx *gin.Context) { switch a.handlePassword(ctx) { case global.AuthResultOK: a.authOK(ctx) @@ -216,8 +216,8 @@ func (a *AuthState) saslAuthd(ctx *gin.Context) { } } -// callback handles the execution of a Lua callback request in a Gin context. -func (a *AuthState) callback(ctx *gin.Context) { +// handleCallback handles the execution of a Lua handleCallback request in a Gin context. +func (a *AuthState) handleCallback(ctx *gin.Context) { if hookScript := config.LoadableConfig.GetLuaCallbackScriptPath(); hookScript != "" { hook.RunLuaCallback(ctx, hookScript) } @@ -351,8 +351,8 @@ func listBlockedAccounts(ctx context.Context, filterCmd *FilterCmd, guid string) return blockedAccounts, err } -// listBruteforce lists all blocked IP addresses and accounts in response to a brute force attack event. -func listBruteforce(ctx *gin.Context) { +// hanldeBruteForceList lists all blocked IP addresses and accounts in response to a brute force attack event. +func hanldeBruteForceList(ctx *gin.Context) { var filterCmd *FilterCmd guid := ctx.GetString(global.CtxGUIDKey) @@ -388,7 +388,7 @@ func listBruteforce(ctx *gin.Context) { }) } -// flushCache is a handler function for a Gin HTTP server. It takes a gin.Context as a parameter +// handleUserFlush is a handler function for a Gin HTTP server. It takes a gin.Context as a parameter // and attempts to flush the cache according to the *FlushUserCmd in the request's JSON body. // // Parameters: @@ -415,7 +415,7 @@ func listBruteforce(ctx *gin.Context) { // 5. If there are no binding errors, the function processes the cache flush. // 6. Based on the useCache flag and the outcome of the cache flush operation, the function // updates the statusMsg and sends the cache status to the client. -func flushCache(ctx *gin.Context) { +func handleUserFlush(ctx *gin.Context) { guid := ctx.GetString(global.CtxGUIDKey) userCmd := &FlushUserCmd{} @@ -676,13 +676,13 @@ func sendCacheStatus(ctx *gin.Context, guid string, userCmd *FlushUserCmd, useCa } } -// flushBruteForceRule handles the flushing of a brute force rule by processing the provided IP command and updating the necessary data. +// handleBruteForceRuleFlush handles the flushing of a brute force rule by processing the provided IP command and updating the necessary data. // It logs information about the action, including the GUID, brute force category, and flush operation. // If the IP command fails to bind, an error is logged, and a bad request status is returned. // If there is an error processing the brute force rules, an error is logged, and an internal server error status is returned. // If the rule flush error flag is true, the status message is set to "not flushed". // The function then logs the status message and returns a JSON response containing the GUID, brute force category, flush operation, and the result of the command, including the IP address -func flushBruteForceRule(ctx *gin.Context) { +func handleBruteForceRuleFlush(ctx *gin.Context) { var ( ruleFlushError bool removedKeys []string diff --git a/server/global/const.go b/server/global/const.go index fddf7efa..15529d00 100644 --- a/server/global/const.go +++ b/server/global/const.go @@ -479,14 +479,8 @@ const ImageCopyright = "Logo (c) by Roessner-Network-Solutions" // Categories and services. const ( - // CatMail is a constant for the "mail" category. - CatMail = "mail" - - // CatHTTP is a constant for the "http" category. - CatHTTP = "http" - - // CatGeneric is a constant for the "generic" category. - CatGeneric = "generic" + // CatAuth is a constant for the "generic" category. + CatAuth = "auth" // CatCache is a constant for the "cache" category. CatCache = "cache" @@ -500,21 +494,18 @@ const ( // ServSaslauthd is a constant for the "saslauthd" service. ServSaslauthd = "saslauthd" - // ServDovecot is a constant for the "dovecot" service. - ServDovecot = "dovecot" + // ServHeader is a constant for the "header" service. + ServHeader = "header" // ServCallback is a generic callback to call Lua ServCallback = "callback" - // ServBasicAuth is a constant for the "basicauth" service. - ServBasicAuth = "basicauth" + // ServBasic is a constant for the "basicauth" service. + ServBasic = "basic" // ServOryHydra is a constant for the "ory_hydra" service. ServOryHydra = "ory_hydra" - // ServUserInfo is a constant for the "user" service. - ServUserInfo = "user" - // ServJSON is a constant for the "json" service. ServJSON = "json"