]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
move init client ALPN to home server
authorAlan T. DeKok <aland@freeradius.org>
Tue, 11 Apr 2023 18:24:12 +0000 (14:24 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 12 Apr 2023 00:03:21 +0000 (20:03 -0400)
so that we don't have potential threading issues with SSL_CTX

src/main/listen.c
src/main/realms.c

index a5e04d3618c82b968fb6bd1d0de24abccc51dbfd..416d72e7bc83663189d7e59d5409c0d9ac4fece1 100644 (file)
@@ -737,7 +737,6 @@ static int radiusv11_server_alpn_cb(SSL *ssl,
        request = (REQUEST *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_REQUEST);
        fr_assert(request != NULL);
 
-
        fr_assert(inlen > 0);
 
        /*
@@ -862,6 +861,43 @@ static int radiusv11_server_advertised_cb(UNUSED SSL *ssl,
 
        return SSL_TLSEXT_ERR_OK;
 }
+
+/*
+ *     Tell the TLS code that we have a list of ALPN protocols to send over, and set the
+ *     callbacks to decide what we negotiated.
+ *
+ *     However, the OpenSSL API allows setting the callback only for the SSL_CTX, and not for
+ *     this particular SSL session.  So we have to associate this listener with the SSL*, and then
+ *     the radiusv11_client_alpn_cb() will retrieve the listener from SSL*, and then do the actual work.
+ */
+int fr_radiusv11_client_init(fr_tls_server_conf_t *tls);
+
+int fr_radiusv11_client_init(fr_tls_server_conf_t *tls)
+{
+       switch (tls->radiusv11) {
+       case FR_RADIUSV11_ALLOW:
+               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;
+               }
+               SSL_CTX_set_next_proto_select_cb(tls->ctx, radiusv11_client_alpn_cb, NULL);
+               DEBUG("(TLS) ALPN proxy has radiusv11 = allow");
+               break;
+
+       case FR_RADIUSV11_REQUIRE:
+               if (SSL_CTX_set_alpn_protos(tls->ctx, radiusv11_require_protos, sizeof(radiusv11_require_protos)) != 0) goto fail_protos;
+               SSL_CTX_set_next_proto_select_cb(tls->ctx, radiusv11_client_alpn_cb, NULL);
+               DEBUG("(TLS) ALPN proxy has radiusv11 = require");
+               break;
+
+       default:
+               DEBUG("(TLS) ALPN proxy has radiusv11 = forbid");
+               break;
+       }
+
+       return 0;
+}
 #endif
 
 
@@ -3347,40 +3383,7 @@ rad_listen_t *proxy_new_listener(TALLOC_CTX *ctx, home_server_t *home, uint16_t
                }
 
 #ifdef WITH_RADIUSV11
-               /*
-                *      Tell the TLS code that we have a list of ALPN protocols to send over, and set the
-                *      callbacks to decide what we negotiated.
-                *
-                *      @todo - this code should arguably be in src/main/realms.c, as mangling SSL_CTX isn't thread-safe.
-                *
-                *      However, the OpenSSL API allows setting the callback only for the SSL_CTX, and not for
-                *      this particular SSL session.  So we have to associate this listener with the SSL*, and then
-                *      the radiusv11_client_alpn_cb() will retrieve the listener from SSL*, and then do the actual work.
-                */
                this->radiusv11 = home->tls->radiusv11;
-
-               switch (home->tls->radiusv11) {
-               case FR_RADIUSV11_ALLOW:
-                       if (SSL_CTX_set_alpn_protos(home->tls->ctx, radiusv11_allow_protos, sizeof(radiusv11_allow_protos)) != 0) {
-                       fail_protos:
-                               ERROR("Failed setting RADIUSv11 negotiation flags");
-                               listen_free(&this);
-                               return 0;
-                       }
-                       SSL_CTX_set_next_proto_select_cb(home->tls->ctx, radiusv11_client_alpn_cb, NULL);
-                       DEBUG("(TLS) ALPN proxy has radiusv11 = allow");
-                       break;
-
-               case FR_RADIUSV11_REQUIRE:
-                       if (SSL_CTX_set_alpn_protos(home->tls->ctx, radiusv11_require_protos, sizeof(radiusv11_require_protos)) != 0) goto fail_protos;
-                       SSL_CTX_set_next_proto_select_cb(home->tls->ctx, radiusv11_client_alpn_cb, NULL);
-                       DEBUG("(TLS) ALPN proxy has radiusv11 = require");
-                       break;
-
-               default:
-                       DEBUG("(TLS) ALPN proxy has radiusv11 = forbid");
-                       break;
-               }
 #endif
 
                this->nonblock |= home->nonblock;
index 3553b99ffc1e68fc34dd8bf76b78ab2d0689dd0f..c05f6eb78713034576b24b7eafd01d399ec4d505 100644 (file)
@@ -93,6 +93,9 @@ static const FR_NAME_NUMBER home_proto[] = {
        { NULL, 0 }
 };
 
+#ifdef WITH_RADIUSV11
+extern int fr_radiusv11_client_init(fr_tls_server_conf_t *tls);
+#endif
 
 static realm_config_t *realm_config = NULL;
 
@@ -1139,6 +1142,11 @@ home_server_t *home_server_afrom_cs(TALLOC_CTX *ctx, realm_config_t *rc, CONF_SE
                                }
 
                                home->tls->radiusv11 = rcode;
+
+                               if (fr_radiusv11_client_init(home->tls) < 0) {
+                                       cf_log_err_cs(cs, "Failed setting OpenSSL callbacks for radiusv11");
+                                       goto error;
+                               }
                        }
 #endif