From: Dante Date: Thu, 12 May 2011 13:04:54 +0000 (+0200) Subject: Glue TLS code into listen.c X-Git-Tag: release_3_0_0_beta0~841 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed2e9cd1e31722a2711f058551d48f95da97a5c2;p=thirdparty%2Ffreeradius-server.git Glue TLS code into listen.c --- diff --git a/src/main/listen.c b/src/main/listen.c index 5766f55884e..593ba2884b0 100644 --- a/src/main/listen.c +++ b/src/main/listen.c @@ -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); diff --git a/src/main/tls.c b/src/main/tls.c index b1ef23e57a2..fbc5414f460 100644 --- a/src/main/tls.c +++ b/src/main/tls.c @@ -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); diff --git a/src/modules/rlm_eap/libeap/eap_tls.c b/src/modules/rlm_eap/libeap/eap_tls.c index a54a929790e..2ff2e13204d 100644 --- a/src/modules/rlm_eap/libeap/eap_tls.c +++ b/src/modules/rlm_eap/libeap/eap_tls.c @@ -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); diff --git a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c index 457cf8b4fae..e5616d1a89e 100644 --- a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c +++ b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c @@ -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; }