void incoming_push_message (struct context *c, const struct buffer *buffer) { struct gc_arena gc = gc_new (); unsigned int option_types_found = 0; int status; msg (D_PUSH, "PUSH: Received control message: '%s'", sanitize_control_message(BSTR(buffer), &gc)); status = process_incoming_push_msg (c, buffer, c->options.pull, pull_permission_mask (c), &option_types_found); if (status == PUSH_MSG_ERROR) msg (D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", sanitize_control_message(BSTR(buffer), &gc)); else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION) { c->options.push_option_types_found |= option_types_found; if (status == PUSH_MSG_REPLY) do_up (c, true, c->options.push_option_types_found ); /* delay bringing tun/tap up until --push parms received from remote */ event_timeout_clear (&c->c2.push_request_interval); } gc_free (&gc); }
void incoming_push_message(struct context *c, const struct buffer *buffer) { struct gc_arena gc = gc_new(); unsigned int option_types_found = 0; int status; msg(D_PUSH, "PUSH: Received control message: '%s'", sanitize_control_message(BSTR(buffer), &gc)); status = process_incoming_push_msg(c, buffer, c->options.pull, pull_permission_mask(c), &option_types_found); if (status == PUSH_MSG_ERROR) { msg(D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", sanitize_control_message(BSTR(buffer), &gc)); } else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION) { c->options.push_option_types_found |= option_types_found; /* delay bringing tun/tap up until --push parms received from remote */ if (status == PUSH_MSG_REPLY) { if (!do_up(c, true, c->options.push_option_types_found)) { msg(D_PUSH_ERRORS, "Failed to open tun/tap interface"); goto error; } } event_timeout_clear(&c->c2.push_request_interval); } else if (status == PUSH_MSG_REQUEST) { if (c->options.mode == MODE_SERVER) { struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE]; /* Do not regenerate keys if client send a second push request */ if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized && !tls_session_update_crypto_params(session, &c->options, &c->c2.frame)) { msg(D_TLS_ERRORS, "TLS Error: initializing data channel failed"); goto error; } } } goto cleanup; error: register_signal(c, SIGUSR1, "process-push-msg-failed"); cleanup: gc_free(&gc); }
/* * Send a string to remote over the TLS control channel. * Used for push/pull messages, passing username/password, * etc. */ bool send_control_channel_string (struct context *c, const char *str, int msglevel) { #if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) if (c->c2.tls_multi) { struct gc_arena gc = gc_new (); bool stat; /* buffered cleartext write onto TLS control channel */ stat = tls_send_payload (c->c2.tls_multi, (uint8_t*) str, strlen (str) + 1); /* * Reschedule tls_multi_process. * NOTE: in multi-client mode, usually the below two statements are * insufficient to reschedule the client instance object unless * multi_schedule_context_wakeup(m, mi) is also called. */ interval_action (&c->c2.tmp_int); context_immediate_reschedule (c); /* ZERO-TIMEOUT */ msg (msglevel, "SENT CONTROL [%s]: '%s' (status=%d)", tls_common_name (c->c2.tls_multi, false), sanitize_control_message (str, &gc), (int) stat); gc_free (&gc); return stat; } #endif return true; }