request = sock->request;
+ if (sock->state == LISTEN_TLS_SETUP) {
+ RDEBUG3("Setting connection state to RUNNING");
+ sock->state = LISTEN_TLS_RUNNING;
+
+ if (sock->ssn->clean_out.used < 20) {
+ goto get_application_data;
+ }
+
+ goto read_application_data;
+ }
+
RDEBUG3("Reading from socket %d", request->packet->sockfd);
PTHREAD_MUTEX_LOCK(&sock->mutex);
if (SSL_pending(sock->ssn->ssl)) {
RDEBUG3("Reading pending buffered data");
sock->ssn->dirty_in.used = 0;
- goto get_application_data;
+ goto check_for_setup;
}
rcode = read(request->packet->sockfd,
}
/*
- * FIXME: Run the request through a virtual
- * server in order to see if we like the
- * certificate presented by the client.
+ * Else we MUST be finished the SSL setup.
*/
}
+ /*
+ * Run the request through a virtual server in
+ * order to see if we like the certificate
+ * presented by the client.
+ */
+check_for_setup:
+ if (sock->state == LISTEN_TLS_INIT) {
+ rad_assert(SSL_is_init_finished(sock->ssn->ssl));
+ sock->ssn->is_init_finished = true;
+ if (!listener->check_client_connections) {
+ sock->state = LISTEN_TLS_RUNNING;
+ goto get_application_data;
+ }
+
+ RDEBUG("Checking initial connection");
+ request->packet->vps = fr_pair_list_copy(request->packet, sock->certs);
+ rdebug_pair_list(L_DBG_LVL_1, request, request->packet->vps, "&request:");
+
+ /*
+ * Fake out a Status-Server packet, which
+ * does NOT have a Message-Authenticator,
+ * or any other contents.
+ */
+ request->packet->code = PW_CODE_STATUS_SERVER;
+ request->packet->data = talloc_zero_array(packet, uint8_t, 20);
+ request->packet->data[0] = PW_CODE_STATUS_SERVER;
+ request->packet->data[3] = 20;
+ sock->state = LISTEN_TLS_CHECKING;
+ PTHREAD_MUTEX_UNLOCK(&sock->mutex);
+ return 1;
+ }
+
/*
* Try to get application data.
*/
return 0;
}
+ /*
+ * Hold application data if we're not yet in the RUNNING
+ * state.
+ */
+ if (sock->state != LISTEN_TLS_RUNNING) {
+ RDEBUG3("Holding application data until setup is complete");
+ return 0;
+ }
+
+read_application_data:
/*
* We now have a bunch of application data.
*/
rad_assert(client != NULL);
packet = talloc_steal(NULL, sock->packet);
+ sock->request->packet = NULL;
sock->packet = NULL;
/*
#endif
case PW_CODE_STATUS_SERVER:
- if (!main_config.status_server) {
+ if (!main_config.status_server
+#ifdef WITH_TLS
+ && !listener->check_client_connections
+#endif
+ ) {
FR_STATS_INC(auth, total_unknown_types);
WARN("Ignoring Status-Server request due to security configuration");
rad_free(&packet);
if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;
+ /*
+ * See if the policies allowed this connection.
+ */
+ if (sock->state == LISTEN_TLS_CHECKING) {
+ if (request->reply->code != PW_CODE_ACCESS_ACCEPT) {
+ REDEBUG("Rejecting client TLS connection");
+ listener->status = RAD_LISTEN_STATUS_REMOVE_NOW;
+ listener->tls = NULL; /* parent owns this! */
+
+ /*
+ * Tell the event handler that an FD has disappeared.
+ */
+ radius_update_listener(listener);
+ return 0;
+ }
+
+ rad_assert(sock->request->packet != request->packet);
+
+ RDEBUG("Accepting client TLS connection");
+ sock->state = LISTEN_TLS_SETUP;
+ (void) dual_tls_recv(listener);
+ return 0;
+ }
+
/*
* Accounting reject's are silently dropped.
*