]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Revert "remove "radius/1.0" as it's not needed"
authorAlan T. DeKok <aland@freeradius.org>
Mon, 14 Aug 2023 19:01:54 +0000 (15:01 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 14 Aug 2023 19:01:54 +0000 (15:01 -0400)
This reverts commit 063246067e5c9c5d58992c1a0f723fdb0094107d.

src/main/listen.c

index 8e77d5c18d05fe06d041314860f253d46277cad2..d1a5e61251bc4ce415ec0f698334c5f3d6a05d5e 100644 (file)
@@ -720,7 +720,12 @@ static int tls_sni_callback(SSL *ssl, UNUSED int *al, void *arg)
 #endif
 
 #ifdef WITH_RADIUSV11
-static const unsigned char radiusv11_alpn_protos[] = {
+static const unsigned char radiusv11_allow_protos[] = {
+       10, 'r', 'a', 'd', 'i', 'u', 's', '/', '1', '.', '1', /* prefer this */
+       10, 'r', 'a', 'd', 'i', 'u', 's', '/', '1', '.', '0',
+};
+
+static const unsigned char radiusv11_require_protos[] = {
        10, 'r', 'a', 'd', 'i', 'u', 's', '/', '1', '.', '1',
 };
 
@@ -759,14 +764,18 @@ static int radiusv11_server_alpn_cb(SSL *ssl,
                 *      never have been registered.
                 */
        case FR_RADIUSV11_FORBID:
-               *out = NULL;
-               *outlen = 0;
-               return SSL_TLSEXT_ERR_OK;
+               server =  radiusv11_allow_protos + 11;
+               server_len = 11;
+               break;
 
        case FR_RADIUSV11_ALLOW:
+               server = radiusv11_allow_protos;
+               server_len = sizeof(radiusv11_allow_protos);
+               break;
+
        case FR_RADIUSV11_REQUIRE:
-               server = radiusv11_alpn_protos;
-               server_len = sizeof(radiusv11_alpn_protos);
+               server = radiusv11_require_protos;
+               server_len = sizeof(radiusv11_require_protos);
                break;
        }
 
@@ -819,13 +828,17 @@ int fr_radiusv11_client_init(fr_tls_server_conf_t *tls)
 {
        switch (tls->radiusv11) {
        case FR_RADIUSV11_ALLOW:
-       case FR_RADIUSV11_REQUIRE:
-               if (SSL_CTX_set_alpn_protos(tls->ctx, radiusv11_alpn_protos, sizeof(radiusv11_alpn_protos)) != 0) {
+               if (SSL_CTX_set_alpn_protos(tls->ctx, radiusv11_allow_protos, sizeof(radiusv11_allow_protos)) != 0) {
+               fail_protos:
                        ERROR("Failed setting RADIUSv11 negotiation flags");
                        return -1;
                }
                break;
 
+       case FR_RADIUSV11_REQUIRE:
+               if (SSL_CTX_set_alpn_protos(tls->ctx, radiusv11_require_protos, sizeof(radiusv11_require_protos)) != 0) goto fail_protos;
+               break;
+
        default:
                break;
        }
@@ -841,41 +854,53 @@ int fr_radiusv11_client_get_alpn(rad_listen_t *listener)
 
        SSL_get0_alpn_selected(sock->ssn->ssl, &data, &len);
        if (!data) {
-               DEBUG("(TLS) ALPN home server did not send any application protocol");
+               DEBUG("(TLS) ALPN server did not send any application protocol");
                if (listener->radiusv11 == FR_RADIUSV11_REQUIRE) {
                        DEBUG("(TLS) We have 'radiusv11 = require', but the home server has not negotiated it - closing socket");
                        return -1;
                }
 
-               DEBUG("(TLS) ALPN assuming historical RADIUS");
-               return 0;
+               DEBUG("(TLS) ALPN assuming \"radius/1.0\"");
+               return 0;       /* allow radius/1.0 */
        }
 
-       DEBUG("(TLS) ALPN home server sent application protocol \"%.*s\"", (int) len, data);
+       DEBUG("(TLS) ALPN server sent application protocol \"%.*s\"", (int) len, data);
 
        if (len != 10) {
        radiusv11_unknown:
-               DEBUG("(TLS) ALPN home server sent unknown application protocol - closing connection");
+               DEBUG("(TLS) ALPN server sent unknown application protocol - closing connection to home server");
                return -1;
        }
 
        /*
-        *      Should always be "radius/1.1".  The server MUST echo back one of the strings
+        *      Should always be "radius/1.0" or "radius/1.1".  The server MUST echo back one of the strings
         *      we sent.  If it doesn't, it's a bad server.
         */
-       if (memcmp(data, "radius/1.1", 10) != 0) goto radiusv11_unknown;
+       if (memcmp(data, "radius/1.", 9) != 0) goto radiusv11_unknown;
+
+       if ((data[9] != '0') && (data[9] != '1')) goto radiusv11_unknown;
 
        /*
         *      Double-check what the server sent us.  It SHOULD be sane, but it never hurts to check.
         */
        switch (listener->radiusv11) {
        case FR_RADIUSV11_FORBID:
-               DEBUG("(TLS) ALPN home server sent \"radius/v1.1\" but we forbid it - closing connection to home server");
-               return -1;
+               if (data[9] != '0') {
+                       DEBUG("(TLS) ALPN server did not send \"radius/v1.0\" - closing connection to home server");
+                       return -1;
+               }
+               break;
 
        case FR_RADIUSV11_ALLOW:
+               sock->radiusv11 = (data[9] == '1');
+               break;
+
        case FR_RADIUSV11_REQUIRE:
-               DEBUG("(TLS) ALPN using \"radius/1.1\"");
+               if (data[9] != '1') {
+                       DEBUG("(TLS) ALPN server did not send \"radius/v1.1\" - closing connection to home server");
+                       return -1;
+               }
+
                sock->radiusv11 = true;
                break;
        }