]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
select SSL_CTX based on realm, if hash table exists
authorAlan T. DeKok <aland@freeradius.org>
Sun, 25 Jul 2021 13:49:21 +0000 (09:49 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 25 Jul 2021 13:49:21 +0000 (09:49 -0400)
src/main/tls.c

index 8926fe75ed942183515db8bf512ec64468495459..c5fcea9ab0ecf208a7da4b87193414275a1aa67f 100644 (file)
@@ -158,6 +158,11 @@ static unsigned int        record_plus(record_t *buf, void const *ptr,
 static unsigned int    record_minus(record_t *buf, void *ptr,
                                     unsigned int size);
 
+typedef struct {
+       char const      *name;
+       SSL_CTX         *ctx;
+} fr_realm_ctx_t;
+
 DIAG_OFF(format-nonliteral)
 /** Print errors in the TLS thread local error stack
  *
@@ -724,6 +729,34 @@ tls_session_t *tls_new_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *conf, REQU
 
                RDEBUG2("(TLS) Loading session certificate file \"%s\"", vp->vp_strvalue);
 
+               if (conf->realms) {
+                       fr_realm_ctx_t my_r, *r;
+
+                       /*
+                        *      Use a pre-existing SSL CTX, if
+                        *      available.  Note that due to OpenSSL
+                        *      issues, this really changes only the
+                        *      certificate files, and leaves all
+                        *      other fields alone.  e.g. you can't
+                        *      select a different TLS version.
+                        *
+                        *      This is fine for our purposes in v3.
+                        *      Due to how we build them, the various
+                        *      additional SSL_CTXs are identical to
+                        *      the main one, except for certs.
+                        */
+                       my_r.name = vp->vp_strvalue;
+                       r = fr_hash_table_finddata(conf->realms, &my_r);
+                       if (r) {
+                               (void) SSL_set_SSL_CTX(state->ssl, r->ctx);
+                               goto after_chain;
+                       }
+
+                       /*
+                        *      Else fall through to trying to dynamically load the certs.
+                        */
+               }
+
                if (conf->file_type) {
                        if (SSL_use_certificate_chain_file(state->ssl, vp->vp_strvalue) != 1) {
                                tls_error_log(request, "Failed loading TLS session certificate \"%s\"",
@@ -761,6 +794,7 @@ tls_session_t *tls_new_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *conf, REQU
                        goto error;
                }
        }
+after_chain:
 #endif
 
        /*
@@ -4364,11 +4398,6 @@ static int store_cmp(void const *a, void const *b)
        return (one < two) - (one > two);
 }
 
-typedef struct {
-       char const      *name;
-       SSL_CTX         *ctx;
-} fr_realm_ctx_t;
-
 static uint32_t realm_hash(void const *data)
 {
        fr_realm_ctx_t const *r = data;