ProtocolError DTLSMessageChannel::command(Command command, void* arg) { DEBUG("session command: %d", command); switch (command) { case CLOSE: reset_session(); break; case DISCARD_SESSION: reset_session(); return IO_ERROR; //force re-establish case MOVE_SESSION: move_session = true; break; case LOAD_SESSION: sessionPersist.restore(callbacks.restore); break; case SAVE_SESSION: sessionPersist.save(callbacks.save); break; } return NO_ERROR; }
ProtocolError DTLSMessageChannel::send(Message& message) { if (ssl_context.state != MBEDTLS_SSL_HANDSHAKE_OVER) return INVALID_STATE; if (message.send_direct()) { // send unencrypted int bytes = this->send(message.buf(), message.length()); return bytes < 0 ? IO_ERROR : NO_ERROR; } #ifdef DEBUG_BUILD LOG(TRACE, "message length %d", message.length()); for (size_t i=0; i<message.length(); i++) { char buf[3]; char c = message.buf()[i]; sprintf(buf, "%02x", c); LOG_PRINT(TRACE, buf); } LOG_PRINT(TRACE, "\n"); #endif int ret = mbedtls_ssl_write(&ssl_context, message.buf(), message.length()); if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { reset_session(); return IO_ERROR; } sessionPersist.update(&ssl_context, callbacks.save, coap_state ? *coap_state : 0); return NO_ERROR; }
static int tee_open(struct inode *inode, struct file *filp) { struct tee_session *ts; filp->private_data = kmalloc(sizeof(struct tee_session), GFP_KERNEL); if (filp->private_data == NULL) { pr_err(TEED_PFX "[%s] allocation failed", __func__); return -ENOMEM; } ts = (struct tee_session *)(filp->private_data); reset_session(ts); return 0; }
static void handle_close_cancel_session(server *srv, connection *con, void *plugindata) { plugin_data *p = (plugin_data *)plugindata; if (copy_bits_session_id_or_set_error(srv, con)) return; if (set_error_if_request_has_content(srv, con)) return; char uuid_str[UUID_STR_LEN]; uuid_unparse(p->session_id, uuid_str); DEBUGLOG("ss", "Ending session", uuid_str); reset_session(p); bits_remove_session(srv, con); }
ProtocolError DTLSMessageChannel::receive(Message& message) { if (ssl_context.state != MBEDTLS_SSL_HANDSHAKE_OVER) return INVALID_STATE; create(message); uint8_t* buf = message.buf(); size_t len = message.capacity(); conf.read_timeout = 0; int ret = mbedtls_ssl_read(&ssl_context, buf, len); if (ret<0) { switch (ret) { case MBEDTLS_ERR_SSL_WANT_READ: break; case MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE: ret = 0; break; case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: command(CLOSE); break; default: reset_session(); return IO_ERROR; } } message.set_length(ret); if (ret>0) { cancel_move_session(); #if defined(DEBUG_BUILD) && 0 if (LOG_ENABLED(TRACE)) { LOG(TRACE, "message length %d", message.length()); for (size_t i=0; i<message.length(); i++) { char buf[3]; char c = message.buf()[i]; sprintf(buf, "%02x", c); LOG_PRINT(TRACE, buf); } LOG_PRINT(TRACE, "\n"); } #endif } return NO_ERROR; }
int teec_open_session(struct tee_context *context, struct tee_session *session, const struct tee_uuid *destination, unsigned int connection_method, void *connection_data, struct tee_operation *operation, unsigned int *error_origin) { int res = TEED_SUCCESS; if (session == NULL || destination == NULL) { pr_err(TEED_PFX "[%s] session or destination == NULL\n", __func__); if (error_origin != NULL) *error_origin = TEED_ORIGIN_DRIVER; res = TEED_ERROR_BAD_PARAMETERS; goto exit; } reset_session(session); /* * Open a session towards an application already loaded inside * the TEE. */ session->uuid = kmalloc(sizeof(struct tee_uuid), GFP_KERNEL); if (session->uuid == NULL) { pr_err(TEED_PFX "[%s] error, out of memory (uuid)\n", __func__); if (error_origin != NULL) *error_origin = TEED_ORIGIN_DRIVER; res = TEED_ERROR_OUT_OF_MEMORY; goto exit; } memcpy(session->uuid, destination, sizeof(struct tee_uuid)); session->ta = NULL; session->id = 0; exit: return res; }
static void handle_create_session(server *srv, connection *con, void *plugindata) { plugin_data *data = (plugin_data *)plugindata; if (!uuid_is_null(data->session_id)) { DEBUGLOG("s", "Session changed"); reset_session(data); } uuid_generate(data->session_id); bits_create_session(srv, con, data->session_id); if (data->conf.sparse) { DEBUGLOG("s", "Backend target is sparse"); data->state.backend_sparse = 1; } else { data->state.zero_unalloc = 1; } }
ProtocolError DTLSMessageChannel::establish(uint32_t& flags, uint32_t app_state_crc) { int ret = 0; INFO("establish"); ProtocolError error = setup_context(); if (error) { INFO("setup_contex error %x", error); return error; } bool renegotiate = false; SessionPersist::RestoreStatus restoreStatus = sessionPersist.restore(&ssl_context, renegotiate, keys_checksum, coap_state, callbacks.restore); DEBUG("restoreStatus = %d", restoreStatus); if (restoreStatus==SessionPersist::COMPLETE) { DEBUG("out_ctr %d,%d,%d,%d,%d,%d,%d,%d, next_coap_id=%d", sessionPersist.out_ctr[0], sessionPersist.out_ctr[1],sessionPersist.out_ctr[2],sessionPersist.out_ctr[3], sessionPersist.out_ctr[4],sessionPersist.out_ctr[5],sessionPersist.out_ctr[6], sessionPersist.out_ctr[7], sessionPersist.next_coap_id); sessionPersist.make_persistent(); uint32_t actual = sessionPersist.application_state_checksum(this->callbacks.calculate_crc); DEBUG("application state checksum: %x, expected: %x", actual, app_state_crc); if (actual==app_state_crc) { DEBUG("skipping sending hello message"); flags |= Protocol::SKIP_SESSION_RESUME_HELLO; } DEBUG("restored session from persisted session data. next_msg_id=%d", *coap_state); return SESSION_RESUMED; } else if (restoreStatus==SessionPersist::RENEGOTIATE) { // session partially restored, fully restored via handshake } else // no session or clear { reset_session(); ProtocolError error = setup_context(); if (error) return error; } uint8_t random[64]; do { while (ssl_context.state != MBEDTLS_SSL_HANDSHAKE_OVER) { ret = mbedtls_ssl_handshake_step(&ssl_context); if (ret != 0) break; // we've already received the ServerHello, thus // we have the random values for client and server if (ssl_context.state == MBEDTLS_SSL_SERVER_KEY_EXCHANGE) { memcpy(random, ssl_context.handshake->randbytes, 64); } } } while(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE); if (ret) { DEBUG("handshake failed -%x", -ret); reset_session(); } else { sessionPersist.prepare_save(random, keys_checksum, &ssl_context, 0); } return ret==0 ? NO_ERROR : IO_ERROR; }
/* Handle the connection of a client. */ static void connection_handler(t_session *session) { int result; #ifdef ENABLE_SSL t_ssl_accept_data sad; #endif #ifdef ENABLE_DEBUG session->current_task = "thread started"; #endif #ifdef ENABLE_SSL if (session->binding->use_ssl) { sad.context = &(session->ssl_context); sad.client_fd = &(session->client_socket); sad.private_key = session->binding->private_key; sad.certificate = session->binding->certificate; sad.ca_certificate = session->binding->ca_certificate; sad.ca_crl = session->binding->ca_crl; sad.timeout = session->kept_alive == 0 ? session->binding->time_for_1st_request : session->binding->time_for_request; sad.min_ssl_version = session->config->min_ssl_version; sad.dh_size = session->config->dh_size; #ifdef ENABLE_DEBUG sad.thread_id = session->thread_id; session->current_task = "ssl accept"; #endif switch (ssl_accept(&sad)) { case SSL_HANDSHAKE_NO_MATCH: log_system(session, "No cypher overlap during SSL handshake."); break; case SSL_HANDSHAKE_TIMEOUT: handle_timeout(session); break; case SSL_HANDSHAKE_OKE: session->socket_open = true; break; } } else #endif session->socket_open = true; if (session->socket_open) { #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_connection(session); } #endif do { result = serve_client(session); handle_request_result(session, result); #ifdef ENABLE_TOMAHAWK if (session->parsing_oke) { show_request_to_admins(session->method, session->request_uri, session->http_version, &(session->ip_address), session->http_headers, session->return_code, session->bytes_sent); } #endif #ifdef ENABLE_DEBUG session->current_task = "request done"; #endif if (session->socket_open) { /* Flush the output-buffer */ if (send_buffer(session, NULL, 0) == -1) { session->keep_alive = false; } } #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_host(session); } #endif reset_session(session); #ifdef ENABLE_DEBUG session->current_task = "session reset"; #endif if ((session->kept_alive > 0) && (session->config->ban_on_flooding > 0)) { if (client_is_flooding(session)) { if (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny) { ban_ip(&(session->ip_address), session->config->ban_on_flooding, session->config->kick_on_ban); log_system(session, "Client banned because of flooding"); session->keep_alive = false; #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif } } } } while (session->keep_alive && session->socket_open); #ifdef ENABLE_DEBUG session->current_task = "session done"; #endif destroy_session(session); close_socket(session); } else { close(session->client_socket); } if (session->config->reconnect_delay > 0) { mark_client_for_removal(session, session->config->reconnect_delay); } else { remove_client(session, true); } #ifdef ENABLE_DEBUG /* Show memory usage by thread */ memdbg_print_log(false); #endif /* Client session ends here */ #ifndef ENABLE_THREAD_POOL pthread_exit(NULL); #endif }
/* * Called when a process writes to a dev file. */ static int tee_write(struct file *filp, const char __user *buffer, size_t length, loff_t *offset) { struct tee_session ku_buffer; struct tee_session *ts; int ret = 0; if (length != sizeof(struct tee_session)) { pr_err(TEED_PFX "[%s] error, incorrect input length\n", __func__); return -EINVAL; } if (copy_from_user(&ku_buffer, buffer, length)) { pr_err(TEED_PFX "[%s] error, tee_session " "copy_from_user failed\n", __func__); return -EINVAL; } ts = (struct tee_session *)(filp->private_data); if (ts == NULL) { pr_err(TEED_PFX "[%s] error, private_data not " "initialized\n", __func__); return -EINVAL; } mutex_lock(&sync); switch (ts->state) { case TEED_STATE_OPEN_DEV: ret = open_tee_device(ts, &ku_buffer); break; case TEED_STATE_OPEN_SESSION: switch (ku_buffer.driver_cmd) { case TEED_INVOKE: ret = invoke_command(ts, &ku_buffer, (struct tee_session *)buffer); break; case TEED_CLOSE_SESSION: /* no caching implemented yet... */ if (call_sec_world(ts, TEED_CLOSE_SESSION)) { set_emsg(ts, TEED_ERROR_COMMUNICATION, __LINE__); ret = -EINVAL; } kfree(ts->ta); ts->ta = NULL; reset_session(ts); break; default: set_emsg(ts, TEED_ERROR_BAD_PARAMETERS, __LINE__); ret = -EINVAL; } break; default: pr_err(TEED_PFX "[%s] unknown state\n", __func__); set_emsg(ts, TEED_ERROR_BAD_STATE, __LINE__); ret = -EINVAL; } /* * We expect that ret has value zero when reaching the end here. * If it has any other value some error must have occured. */ if (!ret) ret = length; else { pr_err(TEED_PFX "[%s], forcing error to -EINVAL\n", __func__); ret = -EINVAL; } mutex_unlock(&sync); return ret; }
/* Handle the connection of a client. */ static void connection_handler(t_session *session) { int result; #ifdef ENABLE_SSL t_ssl_accept_data sad; #endif #ifdef ENABLE_MONITOR int connections; #ifdef ENABLE_DEBUG session->current_task = "thread started"; #endif connections = ++open_connections; if (session->config->monitor_enabled) { if (connections > session->config->monitor_stats.simultaneous_connections) { session->config->monitor_stats.simultaneous_connections = connections; } } #endif #ifdef ENABLE_SSL if (session->binding->use_ssl) { sad.context = &(session->ssl_context); sad.client_fd = &(session->client_socket); sad.private_key = session->binding->private_key; sad.certificate = session->binding->certificate; sad.ca_certificate = session->binding->ca_certificate; sad.ca_crl = session->binding->ca_crl; sad.timeout = session->kept_alive == 0 ? session->binding->time_for_1st_request : session->binding->time_for_request; sad.min_ssl_version = session->config->min_ssl_version; sad.dh_size = session->config->dh_size; #ifdef ENABLE_DEBUG session->current_task = "ssl accept"; #endif switch (ssl_accept(&sad)) { case -2: handle_timeout(session); break; case 0: session->socket_open = true; break; } } else #endif session->socket_open = true; if (session->socket_open) { do { result = serve_client(session); handle_request_result(session, result); #ifdef ENABLE_DEBUG session->current_task = "request done"; #endif if (session->socket_open) { send_buffer(session, NULL, 0); /* Flush the output-buffer */ } #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_counter_request(session); if (session->host->monitor_requests && (result > 0)) { monitor_request(session); } } #endif reset_session(session); #ifdef ENABLE_DEBUG session->current_task = "session reset"; #endif if ((session->kept_alive > 0) && (session->config->ban_on_flooding > 0)) { if (client_is_flooding(session)) { if (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny) { ban_ip(&(session->ip_address), session->config->ban_on_flooding, session->config->kick_on_ban); log_system(session, "Client banned because of flooding"); session->keep_alive = false; #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_counter_ban(session); } #endif } } } } while (session->keep_alive && session->socket_open); #ifdef ENABLE_DEBUG session->current_task = "session done"; #endif destroy_session(session); close_socket(session); } else { close(session->client_socket); } #ifdef ENABLE_MONITOR open_connections--; #endif if (session->config->reconnect_delay > 0) { mark_client_for_removal(session, session->config->reconnect_delay); } else { remove_client(session, true); } /* Client session ends here */ #ifndef ENABLE_THREAD_POOL pthread_exit(NULL); #endif }