]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Use linelog for auth logging in TACACS
authorNick Porter <nick@portercomputing.co.uk>
Fri, 8 Mar 2024 13:53:05 +0000 (13:53 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Fri, 8 Mar 2024 17:54:14 +0000 (17:54 +0000)
doc/antora/modules/raddb/pages/sites-available/tacacs.adoc
raddb/mods-available/linelog
raddb/sites-available/tacacs
src/process/tacacs/base.c

index d4110efabdb023b0b806f538fc2c759548baf4a5..cd9d28a3c6f692824f5b1cba116d7a786c65a414 100644 (file)
@@ -33,54 +33,6 @@ packets.  At this time, there is no configuration
 needed for other packet types.
 
 
-log:: Logging configuration for TACACS+ authentication
-
-
-stripped_names:: Log the full
-`link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]` attribute, as it was
-found in the request.
-
-allowed values: {no, yes}
-
-
-
-auth:: Log authentication requests
-to the log file.
-
-allowed values: {no, yes}
-
-
-
-auth_goodpass:: Log "good"
-passwords with the authentication
-requests.
-
-allowed values: {no, yes}
-
-
-
-auth_badpass:: Log "bad"
-passwords with the authentication
-requests.
-
-allowed values: {no, yes}
-
-
-
-msg_goodpass::
-msg_badpass::
-
-Log additional text at the end of the "Login OK" messages.
-for these to work, the "auth" and "auth_goodpass" or "auth_badpass"
-configurations above have to be set to "yes".
-
-The strings below are dynamically expanded, which means that
-you can put anything you want in them.  However, note that
-this expansion can be slow, and can negatively impact server
-performance.
-
-
-
 session:: Controls how ongoing
 (multi-round) sessions are handled
 
@@ -331,14 +283,6 @@ server tacacs {
        namespace = tacacs
        tacacs {
                Authentication {
-                       log {
-                               stripped_names = no
-                               auth = no
-                               auth_goodpass = no
-                               auth_badpass = no
-#                              msg_goodpass = ""
-#                              msg_badpass = ""
-                       }
                        session {
 #                              max = 4096
                                max_rounds = 4
index 453427db1f088058b841246e805f77f4f1e8f3e3..e28a70d50e743dd064c2ba7bfb0f04a17109357c 100644 (file)
@@ -452,3 +452,30 @@ linelog log_auth_access_reject {
 
        format = "Login incorrect (%{Module-Failure-Message}): [%{User-Name}] (from %client(shortname) port %{NAS-Port} cli %{Calling-Station-Id})"
 }
+
+linelog log_auth_authentication_pass {
+       destination = ${log.destination}
+       file {
+               filename = ${log.file}
+       }
+       syslog {
+               facility = ${log.syslog_facility}
+               severity = notice
+       }
+
+       format = "Login OK: [%{User-Name}] (from client %client(shortname))"
+}
+
+
+linelog log_auth_authentication_fail {
+       destination = ${log.destination}
+       file {
+               filename = ${log.file}
+       }
+       syslog {
+               facility = ${log.syslog_facility}
+               severity = notice
+       }
+
+       format = "Login incorrect (%{Module-Failure-Message}): [%{User-Name}] (from %client(shortname))"
+}
index b1ea4cd8d96cbe54c4210dce32f81f0bfc3f5c00..a0da50e22d2ce0b87280b706aed5a50cdc434eb2 100644 (file)
@@ -42,62 +42,6 @@ server tacacs {
                #  needed for other packet types.
                #
                Authentication {
-                       #
-                       #  log:: Logging configuration for TACACS+ authentication
-                       #
-                       log {
-                               #
-                               #  stripped_names:: Log the full
-                               #  `User-Name` attribute, as it was
-                               #  found in the request.
-                               #
-                               #  allowed values: {no, yes}
-                               #
-                               stripped_names = no
-
-                               #
-                               #  auth:: Log authentication requests
-                               #  to the log file.
-                               #
-                               #  allowed values: {no, yes}
-                               #
-                               auth = no
-
-                               #
-                               #  auth_goodpass:: Log "good"
-                               #  passwords with the authentication
-                               #  requests.
-                               #
-                               #  allowed values: {no, yes}
-                               #
-                               auth_goodpass = no
-
-                               #
-                               #  auth_badpass:: Log "bad"
-                               #  passwords with the authentication
-                               #  requests.
-                               #
-                               #  allowed values: {no, yes}
-                               #
-                               auth_badpass = no
-
-                               #
-                               #  msg_goodpass::
-                               #  msg_badpass::
-                               #
-                               #  Log additional text at the end of the "Login OK" messages.
-                               #  for these to work, the "auth" and "auth_goodpass" or "auth_badpass"
-                               #  configurations above have to be set to "yes".
-                               #
-                               #  The strings below are dynamically expanded, which means that
-                               #  you can put anything you want in them.  However, note that
-                               #  this expansion can be slow, and can negatively impact server
-                               #  performance.
-                               #
-#                              msg_goodpass = ""
-#                              msg_badpass = ""
-                       }
-
                        #
                        #  session:: Controls how ongoing
                        #  (multi-round) sessions are handled
@@ -332,10 +276,24 @@ server tacacs {
        #
        send Authentication-Pass {
                &reply.Server-Message := "Hello %{User-Name}"
+
+               #
+               #  Call an instance of `linelog` to log the authentication success
+               #  - equivalent to the previous log `auth = yes` option in v3.
+               #  See `mods-enabled/linelog` for message formats and destinations.
+               #
+#              log_auth_authentication_pass
        }
 
        send Authentication-Fail {
                &reply.Server-Message := "Failed login!"
+
+               #
+               #  Call an instance of `linelog` to log the authentication failure
+               #  - equivalent to the previous log `auth = yes` option in v3.
+               #  See `mods-enabled/linelog` for message formats and destinations.
+               #
+#              log_auth_authentication_fail
        }
 
        #
index 4345951aca006bd7dfb53b0ee75ea3bf1a046878..12a4b61e8ff7af0271d1a3acaa0a215fb31acfc8 100644 (file)
@@ -158,13 +158,6 @@ typedef struct {
 } process_tacacs_sections_t;
 
 typedef struct {
-       bool            log_stripped_names;
-       bool            log_auth;               //!< Log authentication attempts.
-       bool            log_auth_badpass;       //!< Log failed authentications.
-       bool            log_auth_goodpass;      //!< Log successful authentications.
-       char const      *auth_badpass_msg;      //!< Additional text to append to failed auth messages.
-       char const      *auth_goodpass_msg;     //!< Additional text to append to successful auth messages.
-
        fr_time_delta_t session_timeout;        //!< Maximum time between the last response and next request.
        uint32_t        max_session;            //!< Maximum ongoing session allowed.
 
@@ -212,20 +205,7 @@ static const conf_parser_t session_config[] = {
        CONF_PARSER_TERMINATOR
 };
 
-static const conf_parser_t log_config[] = {
-       { FR_CONF_OFFSET("stripped_names", process_tacacs_auth_t, log_stripped_names), .dflt = "no" },
-       { FR_CONF_OFFSET("auth", process_tacacs_auth_t, log_auth), .dflt = "no" },
-       { FR_CONF_OFFSET("auth_badpass", process_tacacs_auth_t, log_auth_badpass), .dflt = "no" },
-       { FR_CONF_OFFSET("auth_goodpass", process_tacacs_auth_t,  log_auth_goodpass), .dflt = "no" },
-       { FR_CONF_OFFSET("msg_badpass", process_tacacs_auth_t, auth_badpass_msg) },
-       { FR_CONF_OFFSET("msg_goodpass", process_tacacs_auth_t, auth_goodpass_msg) },
-
-       CONF_PARSER_TERMINATOR
-};
-
 static const conf_parser_t auth_config[] = {
-       { FR_CONF_POINTER("log", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) log_config },
-
        { FR_CONF_POINTER("session", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) session_config },
 
        CONF_PARSER_TERMINATOR
@@ -241,116 +221,6 @@ static const conf_parser_t config[] = {
 
 #define RAUTH(fmt, ...)                log_request(L_AUTH, L_DBG_LVL_OFF, request, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
 
-/*
- *     Return a short string showing the terminal server, port
- *     and calling station ID.
- */
-static char *auth_name(char *buf, size_t buflen, request_t *request)
-{
-       char const      *tls = "";
-       fr_client_t     *client = client_from_request(request);
-
-       if (request->packet->socket.inet.dst_port == 0) tls = " via proxy to virtual server";
-
-       snprintf(buf, buflen, "from client %.128s%s",
-                client ? client->shortname : "", tls);
-
-       return buf;
-}
-
-
-/*
- *     Make sure user/pass are clean and then create an attribute
- *     which contains the log message.
- */
-static void CC_HINT(format (printf, 4, 5)) auth_message(process_tacacs_auth_t const *inst,
-                                                       request_t *request, bool goodpass, char const *fmt, ...)
-{
-       va_list          ap;
-
-       bool            logit;
-       char const      *extra_msg = NULL;
-
-       char            password_buff[256];
-       char const      *password_str = NULL;
-
-       char            buf[1024];
-       char            extra[1024];
-       char            *p;
-       char            *msg;
-       fr_pair_t       *username = NULL;
-       fr_pair_t       *password = NULL;
-
-       /*
-        *      No logs?  Then no logs.
-        */
-       if (!inst->log_auth) return;
-
-       /*
-        *      Get the correct username based on the configured value
-        */
-       if (!inst->log_stripped_names) {
-               username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_name);
-       } else {
-               username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_stripped_user_name);
-               if (!username) username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_name);
-       }
-
-       /*
-        *      Clean up the password
-        */
-       if (inst->log_auth_badpass || inst->log_auth_goodpass) {
-               password = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_password);
-               if (!password) {
-                       fr_pair_t *auth_type;
-
-                       auth_type = fr_pair_find_by_da(&request->control_pairs, NULL, attr_auth_type);
-                       if (auth_type) {
-                               snprintf(password_buff, sizeof(password_buff), "<via Auth-Type = %s>",
-                                        fr_dict_enum_name_by_value(auth_type->da, &auth_type->data));
-                               password_str = password_buff;
-                       } else {
-                               password_str = "<no User-Password attribute>";
-                       }
-               } else if (fr_pair_find_by_da(&request->request_pairs, NULL, attr_chap_password)) {
-                       password_str = "<CHAP-Password>";
-               }
-       }
-
-       if (goodpass) {
-               logit = inst->log_auth_goodpass;
-               extra_msg = inst->auth_goodpass_msg;
-       } else {
-               logit = inst->log_auth_badpass;
-               extra_msg = inst->auth_badpass_msg;
-       }
-
-       if (extra_msg) {
-               extra[0] = ' ';
-               p = extra + 1;
-               if (xlat_eval(p, sizeof(extra) - 1, request, extra_msg, NULL, NULL) < 0) return;
-       } else {
-               *extra = '\0';
-       }
-
-       /*
-        *      Expand the input message
-        */
-       va_start(ap, fmt);
-       msg = fr_vasprintf(request, fmt, ap);
-       va_end(ap);
-
-       RAUTH("%s: [%pV%s%pV] (%s)%s",
-             msg,
-             username ? &username->data : fr_box_strvalue("<no User-Name attribute>"),
-             logit ? "/" : "",
-             logit ? (password_str ? fr_box_strvalue(password_str) : &password->data) : fr_box_strvalue(""),
-             auth_name(buf, sizeof(buf), request),
-             extra);
-
-       talloc_free(msg);
-}
-
 /*
  *     Synthesize a State attribute from connection && session information.
  */
@@ -761,18 +631,10 @@ RESUME(auth_type)
 
 RESUME(auth_pass)
 {
-       fr_pair_t                       *vp;
        process_tacacs_t const          *inst = talloc_get_type_abort_const(mctx->inst->data, process_tacacs_t);
 
        PROCESS_TRACE;
 
-       vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_module_success_message);
-       if (vp) {
-               auth_message(&inst->auth, request, true, "Login OK (%pV)", &vp->data);
-       } else {
-               auth_message(&inst->auth, request, true, "Login OK");
-       }
-
        // @todo - worry about user identity existing?
 
        fr_state_discard(inst->auth.state_tree, request);
@@ -781,18 +643,10 @@ RESUME(auth_pass)
 
 RESUME(auth_fail)
 {
-       fr_pair_t                       *vp;
        process_tacacs_t const          *inst = talloc_get_type_abort_const(mctx->inst->data, process_tacacs_t);
 
        PROCESS_TRACE;
 
-       vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_module_failure_message);
-       if (vp) {
-               auth_message(&inst->auth, request, false, "Login incorrect (%pV)", &vp->data);
-       } else {
-               auth_message(&inst->auth, request, false, "Login incorrect");
-       }
-
        // @todo - insert server message saying "failed"
        // and also for FAIL