]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
authentication type updates
authorAlan T. DeKok <aland@freeradius.org>
Thu, 9 Mar 2023 15:41:44 +0000 (10:41 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 9 Mar 2023 22:35:56 +0000 (17:35 -0500)
implement simple auth type

enforce password length restrictions

src/listen/bfd/proto_bfd.c
src/listen/bfd/proto_bfd_udp.c
src/listen/bfd/session.c

index dfd6d15b29b571f3b8dfddee57fbb3a26b12f8ed..4b8de32b8c87dab7ed0308919f141e56f8b0915a 100644 (file)
@@ -500,6 +500,8 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx)
                                break;
 
                        case BFD_AUTH_SIMPLE:
+                       case BFD_AUTH_KEYED_MD5:
+                       case BFD_AUTH_MET_KEYED_MD5:
                                if (!c->secret) {
                                        cf_log_err(cs, "A 'secret' must be specified when using 'auth_type = simple'");
                                        goto error;
@@ -511,15 +513,17 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx)
                                }
                                break;
 
-                               /*
-                                *      Secrets can be any length.
-                                */
-                       default:
+                       case BFD_AUTH_KEYED_SHA1:
+                       case BFD_AUTH_MET_KEYED_SHA1:
                                if (!c->secret) {
                                        cf_log_err(cs, "A 'secret' must be specified when using 'auth_type = ...'");
                                        goto error;
                                }
 
+                               if (strlen(c->secret) > 20) {
+                                       cf_log_err(cs, "Length of 'secret' must be no more than 16 octets for 'auth_type = simple'");
+                                       goto error;
+                               }
                                break;
 
                        }
index 8f905a34d05ba90d308f0934ae69b6e09279f8bc..e2109a1feb9b2bc30626c04e31c0853b688668a0 100644 (file)
@@ -157,13 +157,13 @@ static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time
                goto fail;
        }
 
-       if (packet->length < 24) {
-               DEBUG("BFD packet has wrong length (%d < 24)", packet->length);
+       if (packet->length < FR_BFD_HEADER_LENGTH) {
+               DEBUG("BFD packet header has wrong length (%d < 24)", packet->length);
                goto fail;
        }
 
        if (packet->length > sizeof(*packet)) {
-               DEBUG("BFD packet has wrong length (%d > %zd)", packet->length, sizeof(*packet));
+               DEBUG("BFD packet length is larger than received packet (%d > %zd)", packet->length, sizeof(*packet));
                goto fail;
        }
 
@@ -174,13 +174,13 @@ static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time
 
        if (packet->auth_present) {
                if (packet->length < (FR_BFD_HEADER_LENGTH + 2)) { /* auth-type and auth-len */
-                       DEBUG("BFD packet has wrong length (%d < 26)",
+                       DEBUG("BFD packet length is not enough for auth-type and auth-len (%d < 26)",
                              packet->length);
                        goto fail;
                }
 
                if (packet->length < 24 + packet->auth.basic.auth_len) {
-                       DEBUG("BFD packet is too short (%d < %d)",
+                       DEBUG("BFD packet length is not enough for authentication data (%d < %d)",
                              packet->length, FR_BFD_HEADER_LENGTH + packet->auth.basic.auth_len);
                        goto fail;
 
index 71facb44927c8900756f60c1d8ed5004e36e2008..b4a49cc44993cbfc0dfe14fb3ee07457e1873f1c 100644 (file)
@@ -65,9 +65,11 @@ static void bfd_trigger(proto_bfd_peer_t *session)
        snprintf(buffer, sizeof(buffer), "server.bfd.%s",
                 fr_bfd_packet_names[session->session_state]);
 
+       DEBUG("BFD %s trigger %s", session->client.shortname, buffer);
+
 //     bfd_request(session, request, &packet);
 
-       trigger_exec(unlang_interpret_get_thread_default(), NULL, buffer, false, NULL);
+//     trigger_exec(unlang_interpret_get_thread_default(), NULL, buffer, false, NULL);
 }
 
 /*
@@ -137,6 +139,8 @@ static void bfd_poll_response(proto_bfd_peer_t *session)
 
 int bfd_session_process(proto_bfd_peer_t *session, bfd_packet_t *bfd)
 {
+       bool state_change = false;
+
        if (bfd->auth_present &&
            (session->auth_type == BFD_AUTH_RESERVED)) {
                DEBUG("BFD %s packet asked to authenticate an unauthenticated session.", session->client.shortname);
@@ -226,6 +230,7 @@ int bfd_session_process(proto_bfd_peer_t *session, bfd_packet_t *bfd)
                      session->client.shortname, fr_bfd_packet_names[session->session_state]);
                session->session_state = BFD_STATE_DOWN;
                bfd_trigger(session);
+               state_change = true;
 
                bfd_set_desired_min_tx_interval(session, fr_time_delta_from_usec(1));
 
@@ -238,6 +243,7 @@ int bfd_session_process(proto_bfd_peer_t *session, bfd_packet_t *bfd)
                                      session->client.shortname);
                                session->session_state = BFD_STATE_INIT;
                                bfd_trigger(session);
+                               state_change = true;
 
                                bfd_set_desired_min_tx_interval(session, fr_time_delta_from_usec(1));
                                break;
@@ -247,6 +253,7 @@ int bfd_session_process(proto_bfd_peer_t *session, bfd_packet_t *bfd)
                                      session->client.shortname);
                                session->session_state = BFD_STATE_UP;
                                bfd_trigger(session);
+                               state_change = true;
                                break;
 
                        default: /* don't change anything */
@@ -262,6 +269,7 @@ int bfd_session_process(proto_bfd_peer_t *session, bfd_packet_t *bfd)
                                      session->client.shortname);
                                session->session_state = BFD_STATE_UP;
                                bfd_trigger(session);
+                               state_change = true;
                                break;
 
                        default: /* don't change anything */
@@ -277,6 +285,7 @@ int bfd_session_process(proto_bfd_peer_t *session, bfd_packet_t *bfd)
                                DEBUG("BFD %s State UP -> DOWN (neighbor down)", session->client.shortname);
                                session->session_state = BFD_STATE_DOWN;
                                bfd_trigger(session);
+                               state_change = true;
 
                                bfd_set_desired_min_tx_interval(session, fr_time_delta_from_usec(1));
                                break;
@@ -327,13 +336,14 @@ int bfd_session_process(proto_bfd_peer_t *session, bfd_packet_t *bfd)
        }
 #endif
 
-
        if ((!session->remote_demand_mode) ||
            (session->session_state != BFD_STATE_UP) ||
            (session->remote_session_state != BFD_STATE_UP)) {
                bfd_start_control(session);
        }
 
+       if (!state_change) return 0;
+
        // @todo - send the packet through a "recv foo" section?
 
        return 1;
@@ -351,6 +361,31 @@ int bfd_session_process(proto_bfd_peer_t *session, bfd_packet_t *bfd)
  *     mean we start polling.
  */
 
+/*
+ *     Verify and/or calculate passwords
+ */
+static void bfd_calc_simple(proto_bfd_peer_t *session, bfd_packet_t *bfd)
+{
+       bfd_auth_simple_t *simple = &bfd->auth.password;
+
+       fr_assert(session->secret_len <= sizeof(simple->password));
+
+       memcpy(simple->password, session->client.secret, session->secret_len);
+       simple->auth_len = session->secret_len;
+}
+
+static void bfd_auth_simple(proto_bfd_peer_t *session, bfd_packet_t *bfd)
+{
+       bfd_auth_simple_t *simple = &bfd->auth.password;
+
+       simple->auth_type = session->auth_type;
+       simple->auth_len = session->secret_len;
+       bfd->length += simple->auth_len;
+
+       simple->key_id = 0;
+
+       bfd_calc_simple(session, bfd);
+}
 
 /*
  *     Verify and/or calculate auth-type digests.
@@ -439,6 +474,17 @@ static int bfd_verify_sequence(proto_bfd_peer_t *session, uint32_t sequence_no,
        return 1;
 }
 
+static int bfd_verify_simple(proto_bfd_peer_t *session, bfd_packet_t *bfd)
+{
+       bfd_auth_simple_t *simple = &bfd->auth.password;
+
+       if (simple->auth_len != session->secret_len) return 0;
+
+       if (simple->key_id != 0) return 0;
+
+       return (fr_digest_cmp((uint8_t const *) session->client.secret, simple->password, session->secret_len) == 0);
+}
+
 static int bfd_verify_md5(proto_bfd_peer_t *session, bfd_packet_t *bfd)
 {
        int rcode;
@@ -524,6 +570,7 @@ static int bfd_authenticate(proto_bfd_peer_t *session, bfd_packet_t *bfd)
                return 0;
 
        case BFD_AUTH_SIMPLE:
+               bfd_verify_simple(session, bfd);
                break;
 
        case BFD_AUTH_KEYED_MD5:
@@ -547,6 +594,7 @@ static void bfd_sign(proto_bfd_peer_t *session, bfd_packet_t *bfd)
                        break;
 
                case BFD_AUTH_SIMPLE:
+                       bfd_auth_simple(session, bfd);
                        break;
 
                case BFD_AUTH_KEYED_MD5: