]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Glue TLS code into listen.c
authorDante <dante@dante.org.uk>
Thu, 12 May 2011 13:04:54 +0000 (15:04 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 12 May 2011 13:04:54 +0000 (15:04 +0200)
src/main/listen.c
src/main/tls.c
src/modules/rlm_eap/libeap/eap_tls.c
src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c

index 5766f55884e99b37cd529f42aac894e5b108a95c..593ba2884b0373ac08be8454784d7ed439092634 100644 (file)
@@ -636,6 +636,13 @@ static int dual_tcp_accept(rad_listen_t *listener)
        this->status = RAD_LISTEN_STATUS_INIT;
        this->recv = dual_tcp_recv;
 
+#ifdef WITH_TLS
+       if (this->tls) {
+               this->recv = dual_tls_recv;
+               this->send = dual_tls_send;
+       }
+#endif
+
        /*
         *      FIXME: set O_NONBLOCK on the accept'd fd.
         *      See djb's portability rants for details.
@@ -2396,6 +2403,19 @@ int proxy_new_listener(home_server *home, int src_port)
                 */
                this->fd = fr_tcp_client_socket(&home->src_ipaddr,
                                                &home->ipaddr, home->port);
+#ifdef WITH_TLS
+               if (home->tls) {
+                       DEBUG("Trying SSL to port %d\n", home->port);
+                       sock->ssn = tls_new_client_session(home->tls, this->fd);
+                       if (!sock->ssn) {
+                               listen_free(&this);
+                               return 0;
+                       }
+
+                       this->recv = proxy_tls_recv;
+                       this->send = proxy_tls_send;
+               }
+#endif
        } else
 #endif
                this->fd = fr_socket(&home->src_ipaddr, src_port);
index b1ef23e57a2f133ad11caf0ace0fd6226c48a86a..fbc5414f4606e773e6e4a86b8fda9f784555e0a3 100644 (file)
@@ -306,13 +306,19 @@ int tls_handshake_recv(REQUEST *request, tls_session_t *ssn)
 {
        int err;
 
-       BIO_write(ssn->into_ssl, ssn->dirty_in.data, ssn->dirty_in.used);
+       err = BIO_write(ssn->into_ssl, ssn->dirty_in.data, ssn->dirty_in.used);
+       if (err != (int) ssn->dirty_in.used) {
+               RDEBUG("Failed writing %d to SSL BIO: %d", ssn->dirty_in.used,
+                       err);
+               record_init(&ssn->dirty_in);
+               return 0;
+       }
+       record_init(&ssn->dirty_in);
 
        err = SSL_read(ssn->ssl, ssn->clean_out.data + ssn->clean_out.used,
                       sizeof(ssn->clean_out.data) - ssn->clean_out.used);
        if (err > 0) {
                ssn->clean_out.used += err;
-               record_init(&ssn->dirty_in);
                return 1;
        }
 
@@ -1191,7 +1197,7 @@ int cbtls_verify(int ok, X509_STORE_CTX *ctx)
         *      For this next bit, we create the attributes *only* if
         *      we're at the client or issuing certificate.
         */
-       if ((lookup <= 1) && sn && (sn->length < (sizeof(buf) / 2))) {
+       if ((lookup <= 1) && sn && ((size_t) sn->length < (sizeof(buf) / 2))) {
                char *p = buf;
                int i;
 
@@ -1441,7 +1447,7 @@ static X509_STORE *init_revocation_store(fr_tls_server_conf_t *conf)
  */
 static SSL_CTX *init_tls_ctx(fr_tls_server_conf_t *conf)
 {
-       SSL_METHOD *meth;
+       const SSL_METHOD *meth;
        SSL_CTX *ctx;
        X509_STORE *certstore;
        int verify_mode = SSL_VERIFY_NONE;
@@ -1484,7 +1490,7 @@ static SSL_CTX *init_tls_ctx(fr_tls_server_conf_t *conf)
                /*
                 * We don't want to put the private key password in eap.conf, so  check
                 * for our special string which indicates we should get the password
-                * programmatically.
+                * programmatically. 
                 */
                const char* special_string = "Apple:UseCertAdmin";
                if (strncmp(conf->private_key_password,
@@ -1536,20 +1542,25 @@ static SSL_CTX *init_tls_ctx(fr_tls_server_conf_t *conf)
         *      the cert chain needs to be given in PEM from
         *      openSSL.org
         */
+       if (!conf->certificate_file) goto load_ca;
+
        if (type == SSL_FILETYPE_PEM) {
                if (!(SSL_CTX_use_certificate_chain_file(ctx, conf->certificate_file))) {
-                       radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
-                       radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
+                       radlog(L_ERR, "Error reading certificate file %s:%s",
+                              conf->certificate_file,
+                              ERR_error_string(ERR_get_error(), NULL));
                        return NULL;
                }
 
        } else if (!(SSL_CTX_use_certificate_file(ctx, conf->certificate_file, type))) {
-               radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
-               radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
+               radlog(L_ERR, "Error reading certificate file %s:%s",
+                      conf->certificate_file,
+                      ERR_error_string(ERR_get_error(), NULL));
                return NULL;
        }
 
        /* Load the CAs we trust */
+load_ca:
        if (conf->ca_file || conf->ca_path) {
                if (!SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) {
                        radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
@@ -1558,18 +1569,22 @@ static SSL_CTX *init_tls_ctx(fr_tls_server_conf_t *conf)
                }
        }
        if (conf->ca_file && *conf->ca_file) SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file));
-       if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) {
-               radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
-               radlog(L_ERR, "rlm_eap_tls: Error reading private key file %s", conf->private_key_file);
-               return NULL;
-       }
 
-       /*
-        * Check if the loaded private key is the right one
-        */
-       if (!SSL_CTX_check_private_key(ctx)) {
-               radlog(L_ERR, "rlm_eap_tls: Private key does not match the certificate public key");
-               return NULL;
+       if (conf->private_key_file) {
+               if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) {
+                       radlog(L_ERR, "Failed reading private key file %s:%s",
+                              conf->private_key_file,
+                              ERR_error_string(ERR_get_error(), NULL));
+                       return NULL;
+               }
+               
+               /*
+                * Check if the loaded private key is the right one
+                */
+               if (!SSL_CTX_check_private_key(ctx)) {
+                       radlog(L_ERR, "Private key does not match the certificate public key");
+                       return NULL;
+               }
        }
 
        /*
@@ -1621,7 +1636,7 @@ static SSL_CTX *init_tls_ctx(fr_tls_server_conf_t *conf)
 
        /*
         *      Callbacks, etc. for session resumption.
-        */
+        */                                                   
        if (conf->session_cache_enable) {
                SSL_CTX_sess_set_new_cb(ctx, cbtls_new_session);
                SSL_CTX_sess_set_get_cb(ctx, cbtls_get_session);
index a54a929790e11caf8873410a68caa3b3847c2f66..2ff2e13204ddeb831ab8bf41ee8d6bc3435a5b75 100644 (file)
@@ -147,10 +147,7 @@ int eaptls_fail(EAP_HANDLER *handler, int peap_flag)
        reply.data = NULL;
        reply.dlen = 0;
 
-       /*
-        *      Force the session to NOT be cached.
-        */
-       SSL_CTX_remove_session(tls_session->ctx, tls_session->ssl->session);
+       tls_fail(tls_session);
 
        eaptls_compose(handler->eap_ds, &reply);
 
index 457cf8b4fae53133d8cc6eba3bb19bf45705e731..e5616d1a89e18113b896b763aa0ee2c38408a7b8 100644 (file)
@@ -192,43 +192,9 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
        SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_STORE, (void *)inst->ocsp_store);
 #endif
 
-       ssn->length_flag = inst->include_length;
-
-       /*
-        *      We use default fragment size, unless the Framed-MTU
-        *      tells us it's too big.  Note that we do NOT account
-        *      for the EAP-TLS headers if conf->fragment_size is
-        *      large, because that config item looks to be confusing.
-        *
-        *      i.e. it should REALLY be called MTU, and the code here
-        *      should figure out what that means for TLS fragment size.
-        *      asking the administrator to know the internal details
-        *      of EAP-TLS in order to calculate fragment sizes is
-        *      just too much.
-        */
-       ssn->offset = inst->fragment_size;
-       vp = pairfind(handler->request->packet->vps, PW_FRAMED_MTU, 0);
-       if (vp && ((vp->vp_integer - 14) < ssn->offset)) {
-               /*
-                *      Discount the Framed-MTU by:
-                *       4 : EAPOL header
-                *       4 : EAP header (code + id + length)
-                *       1 : EAP type == EAP-TLS
-                *       1 : EAP-TLS Flags
-                *       4 : EAP-TLS Message length
-                *          (even if conf->include_length == 0,
-                *           just to be lazy).
-                *      ---
-                *      14
-                */
-               ssn->offset = vp->vp_integer - 14;
-       }
-
        handler->opaque = ((void *)ssn);
        handler->free_opaque = session_free;
 
-       RDEBUG2("Initiate");
-
        /*
         *      Set up type-specific information.
         */
@@ -268,10 +234,6 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
                break;
        }
 
-       if (inst->session_cache_enable) {
-               ssn->allow_session_resumption = 1; /* otherwise it's zero */
-       }
-
        /*
         *      TLS session initialization is over.  Now handle TLS
         *      related handshaking or application data.
@@ -355,10 +317,7 @@ static int eaptls_authenticate(void *arg, EAP_HANDLER *handler)
                 *      the client can't re-use it.
                 */
        default:
-               if (inst->session_cache_enable) {
-                       SSL_CTX_remove_session(inst->ctx,
-                                              tls_session->ssl->session);
-               }
+               tls_fail(tls_session);
 
                return 0;
        }