int process_incoming_push_msg(struct context *c, const struct buffer *buffer, bool honor_received_options, unsigned int permission_mask, unsigned int *option_types_found) { int ret = PUSH_MSG_ERROR; struct buffer buf = *buffer; #if P2MP_SERVER if (buf_string_compare_advance(&buf, "PUSH_REQUEST")) { ret = process_incoming_push_request(c); } else #endif if (honor_received_options && buf_string_compare_advance(&buf, "PUSH_REPLY")) { const uint8_t ch = buf_read_u8(&buf); if (ch == ',') { struct buffer buf_orig = buf; if (!c->c2.pulled_options_digest_init_done) { c->c2.pulled_options_state = md_ctx_new(); md_ctx_init(c->c2.pulled_options_state, md_kt_get("SHA256")); c->c2.pulled_options_digest_init_done = true; } if (!c->c2.did_pre_pull_restore) { pre_pull_restore(&c->options, &c->c2.gc); c->c2.did_pre_pull_restore = true; } if (apply_push_options(&c->options, &buf, permission_mask, option_types_found, c->c2.es)) { push_update_digest(c->c2.pulled_options_state, &buf_orig, &c->options); switch (c->options.push_continuation) { case 0: case 1: md_ctx_final(c->c2.pulled_options_state, c->c2.pulled_options_digest.digest); md_ctx_cleanup(c->c2.pulled_options_state); md_ctx_free(c->c2.pulled_options_state); c->c2.pulled_options_state = NULL; c->c2.pulled_options_digest_init_done = false; ret = PUSH_MSG_REPLY; break; case 2: ret = PUSH_MSG_CONTINUATION; break; } } } else if (ch == '\0') { ret = PUSH_MSG_REPLY; } /* show_settings (&c->options); */ } return ret; }
int process_incoming_push_msg (struct context *c, const struct buffer *buffer, bool honor_received_options, unsigned int permission_mask, unsigned int *option_types_found) { int ret = PUSH_MSG_ERROR; struct buffer buf = *buffer; #if P2MP_SERVER if (buf_string_compare_advance (&buf, "PUSH_REQUEST")) { if (tls_authentication_status (c->c2.tls_multi, 0) == TLS_AUTHENTICATION_FAILED || c->c2.context_auth == CAS_FAILED) { const char *client_reason = tls_client_reason (c->c2.tls_multi); send_auth_failed (c, client_reason); ret = PUSH_MSG_AUTH_FAILURE; } else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED) { time_t now; openvpn_time(&now); if (c->c2.sent_push_reply_expiry > now) { ret = PUSH_MSG_ALREADY_REPLIED; } else { if (send_push_reply (c)) { ret = PUSH_MSG_REQUEST; c->c2.sent_push_reply_expiry = now + 30; } } } else { ret = PUSH_MSG_REQUEST_DEFERRED; } } else #endif if (honor_received_options && buf_string_compare_advance (&buf, "PUSH_REPLY")) { const uint8_t ch = buf_read_u8 (&buf); if (ch == ',') { struct buffer buf_orig = buf; if (!c->c2.pulled_options_md5_init_done) { md5_state_init (&c->c2.pulled_options_state); c->c2.pulled_options_md5_init_done = true; } if (!c->c2.did_pre_pull_restore) { pre_pull_restore (&c->options); c->c2.did_pre_pull_restore = true; } if (apply_push_options (&c->options, &buf, permission_mask, option_types_found, c->c2.es)) switch (c->options.push_continuation) { case 0: case 1: md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig)); md5_state_final (&c->c2.pulled_options_state, &c->c2.pulled_options_digest); c->c2.pulled_options_md5_init_done = false; ret = PUSH_MSG_REPLY; break; case 2: md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig)); ret = PUSH_MSG_CONTINUATION; break; } } else if (ch == '\0') { ret = PUSH_MSG_REPLY; } /* show_settings (&c->options); */ } return ret; }