Merge tag 'release_3_0_10' into tr-integ
[freeradius.git] / src / main / tls.c
index 075c03b..d86391f 100644 (file)
@@ -169,7 +169,7 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity,
                        return 0;
                }
 
-               vp = pair_make_packet("TLS-PSK-Identity", identity, T_OP_SET);
+               vp = pair_make_request("TLS-PSK-Identity", identity, T_OP_SET);
                if (!vp) return 0;
 
                hex_len = radius_xlat(buffer, sizeof(buffer), request, conf->psk_query,
@@ -313,7 +313,6 @@ tls_session_t *tls_new_client_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *con
        return ssn;
 }
 
-
 /** Create a new TLS session
  *
  * Configures a new TLS session, configuring options, setting callbacks etc...
@@ -954,13 +953,13 @@ static CONF_PARSER cache_config[] = {
 
        { "max_entries", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_tls_server_conf_t, session_cache_size), "255" },
        { "persist_dir", FR_CONF_OFFSET(PW_TYPE_STRING, fr_tls_server_conf_t, session_cache_path), NULL },
-       { NULL, -1, 0, NULL, NULL }        /* end the list */
+       CONF_PARSER_TERMINATOR
 };
 
 static CONF_PARSER verify_config[] = {
        { "tmpdir", FR_CONF_OFFSET(PW_TYPE_STRING, fr_tls_server_conf_t, verify_tmp_dir), NULL },
        { "client", FR_CONF_OFFSET(PW_TYPE_STRING, fr_tls_server_conf_t, verify_client_cert_cmd), NULL },
-       { NULL, -1, 0, NULL, NULL }        /* end the list */
+       CONF_PARSER_TERMINATOR
 };
 
 #ifdef HAVE_OPENSSL_OCSP_H
@@ -971,7 +970,7 @@ static CONF_PARSER ocsp_config[] = {
        { "use_nonce", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, fr_tls_server_conf_t, ocsp_use_nonce), "yes" },
        { "timeout", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_tls_server_conf_t, ocsp_timeout), "yes" },
        { "softfail", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, fr_tls_server_conf_t, ocsp_softfail), "no" },
-       { NULL, -1, 0, NULL, NULL }        /* end the list */
+       CONF_PARSER_TERMINATOR
 };
 #endif
 
@@ -1033,8 +1032,7 @@ static CONF_PARSER tls_server_config[] = {
 #ifdef HAVE_OPENSSL_OCSP_H
        { "ocsp", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) ocsp_config },
 #endif
-
-       { NULL, -1, 0, NULL, NULL }        /* end the list */
+       CONF_PARSER_TERMINATOR
 };
 
 
@@ -1076,8 +1074,7 @@ static CONF_PARSER tls_client_config[] = {
 #ifdef SSL_OP_NO_TLSv1_2
        { "disable_tlsv1_2", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, fr_tls_server_conf_t, disable_tlsv1_2), NULL },
 #endif
-
-       { NULL, -1, 0, NULL, NULL }        /* end the list */
+       CONF_PARSER_TERMINATOR
 };
 
 
@@ -1338,7 +1335,7 @@ static SSL_SESSION *cbtls_get_session(SSL *ssl, unsigned char *data, int len, in
                }
 
                /* move the cached VPs into the session */
-               fr_pair_list_move_by_num(talloc_ctx, &vps, &pairlist->reply, 0, 0, TAG_ANY);
+               fr_pair_list_mcopy_by_num(talloc_ctx, &vps, &pairlist->reply, 0, 0, TAG_ANY);
 
                SSL_SESSION_set_ex_data(sess, fr_tls_ex_index_vps, vps);
                RWDEBUG("Successfully restored session %s", buffer);
@@ -1352,14 +1349,24 @@ err:
 }
 
 #ifdef HAVE_OPENSSL_OCSP_H
-/*
- * This function extracts the OCSP Responder URL
- * from an existing x509 certificate.
+
+/** Extract components of OCSP responser URL from a certificate
+ *
+ * @param[in] cert to extract URL from.
+ * @param[out] host_out Portion of the URL (must be freed with free()).
+ * @param[out] port_out Port portion of the URL (must be freed with free()).
+ * @param[out] path_out Path portion of the URL (must be freed with free()).
+ * @param[out] is_https Whether the responder should be contacted using https.
+ * @return
+ *     - 0 if no valid URL is contained in the certificate.
+ *     - 1 if a URL was found and parsed.
+ *     - -1 if at least one URL was found, but none could be parsed.
  */
-static int ocsp_parse_cert_url(X509 *cert, char **phost, char **pport,
-                              char **ppath, int *pssl)
+static int ocsp_parse_cert_url(X509 *cert, char **host_out, char **port_out,
+                              char **path_out, int *is_https)
 {
        int                     i;
+       bool                    found_uri = false;
 
        AUTHORITY_INFO_ACCESS   *aia;
        ACCESS_DESCRIPTION      *ad;
@@ -1368,15 +1375,14 @@ static int ocsp_parse_cert_url(X509 *cert, char **phost, char **pport,
 
        for (i = 0; i < sk_ACCESS_DESCRIPTION_num(aia); i++) {
                ad = sk_ACCESS_DESCRIPTION_value(aia, i);
-               if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
-                       if (ad->location->type == GEN_URI) {
-                         if(OCSP_parse_url((char *) ad->location->d.ia5->data,
-                                                 phost, pport, ppath, pssl))
-                                       return 1;
-                       }
-               }
+               if (OBJ_obj2nid(ad->method) != NID_ad_OCSP) continue;
+               if (ad->location->type != GEN_URI) continue;
+               found_uri = true;
+
+               if (OCSP_parse_url((char *) ad->location->d.ia5->data, host_out,
+                                  port_out, path_out, is_https)) return 1;
        }
-       return 0;
+       return found_uri ? -1 : 0;
 }
 
 /*
@@ -1428,17 +1434,36 @@ static int ocsp_check(REQUEST *request, X509_STORE *store, X509 *issuer_cert, X5
        if (conf->ocsp_override_url) {
                char *url;
 
+       use_ocsp_url:
                memcpy(&url, &conf->ocsp_url, sizeof(url));
                /* Reading the libssl src, they do a strdup on the URL, so it could of been const *sigh* */
                OCSP_parse_url(url, &host, &port, &path, &use_ssl);
+               if (!host || !port || !path) {
+                       RWDEBUG("ocsp: Host or port or path missing from configured URL \"%s\".  Not doing OCSP", url);
+                       ocsp_ok = 2;
+                       goto ocsp_skip;
+               }
        } else {
-               ocsp_parse_cert_url(client_cert, &host, &port, &path, &use_ssl);
-       }
+               int ret;
 
-       if (!host || !port || !path) {
-               RWDEBUG("ocsp: Host / port / path missing.  Not doing OCSP");
-               ocsp_ok = 2;
-               goto ocsp_skip;
+               ret = ocsp_parse_cert_url(client_cert, &host, &port, &path, &use_ssl);
+               switch (ret) {
+               case -1:
+                       RWDEBUG("ocsp: Invalid URL in certificate.  Not doing OCSP");
+                       break;
+
+               case 0:
+                       if (conf->ocsp_url) {
+                               RWDEBUG("ocsp: No OCSP URL in certificate, falling back to configured URL");
+                               goto use_ocsp_url;
+                       }
+                       RWDEBUG("ocsp: No OCSP URL in certificate.  Not doing OCSP");
+                       ocsp_ok = 2;
+                       goto ocsp_skip;
+
+               case 1:
+                       break;
+               }
        }
 
        RDEBUG2("ocsp: Using responder URL \"http://%s:%s%s\"", host, port, path);
@@ -2042,7 +2067,7 @@ int cbtls_verify(int ok, X509_STORE_CTX *ctx)
                        }
                        fclose(fp);
 
-                       if (!pair_make_packet("TLS-Client-Cert-Filename",
+                       if (!pair_make_request("TLS-Client-Cert-Filename",
                                             filename, T_OP_SET)) {
                                RDEBUG("Failed creating TLS-Client-Cert-Filename");
 
@@ -3015,7 +3040,7 @@ int tls_success(tls_session_t *ssn, REQUEST *request)
                /*
                 *      Mark the request as resumed.
                 */
-               pair_make_packet("EAP-Session-Resumed", "1", T_OP_SET);
+               pair_make_request("EAP-Session-Resumed", "1", T_OP_SET);
        }
 
        return 0;