OpenVPN 3 Core Library
Loading...
Searching...
No Matches
cliproto.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#ifndef OPENVPN_CLIENT_CLIPROTO_H
13#define OPENVPN_CLIENT_CLIPROTO_H
14
15// This is a middle-layer object in the OpenVPN client protocol stack.
16// It is above the general OpenVPN protocol implementation in
17// class ProtoContext but below the top
18// level object in a client connect (ClientConnect). See ClientConnect for
19// a fuller description of the full client stack.
20//
21// This layer deals with setting up an OpenVPN client connection:
22//
23// 1. handles creation of transport-layer handler via TransportClientFactory
24// 2. handles creation of tun-layer handler via TunClientFactory
25// 3. handles sending PUSH_REQUEST to server and processing reply of server-pushed options
26// 4. manages the underlying OpenVPN protocol object (class ProtoContext)
27// 5. handles timers on behalf of the underlying OpenVPN protocol object
28// 6. acts as an exception dispatcher for errors occuring in any of the underlying layers
29
30#include <string>
31#include <vector>
32#include <memory>
33#include <algorithm> // for std::min
34#include <cstdint> // for std::uint...
35using namespace std::chrono_literals;
36
37#include <openvpn/io/io.hpp>
38
39#include <openvpn/common/rc.hpp>
44#include <openvpn/ip/ptb.hpp>
60
61#include <openvpn/ssl/proto.hpp>
63
64#ifdef OPENVPN_DEBUG_CLIPROTO
65#define OPENVPN_LOG_CLIPROTO(x) OPENVPN_LOG(x)
66#else
67#define OPENVPN_LOG_CLIPROTO(x)
68#endif
69
71
73
75{
76 virtual ~NotifyCallback() = default;
77
78 virtual void client_proto_terminate() = 0;
80 {
81 }
82 virtual void client_proto_auth_pending_timeout(int timeout)
83 {
84 }
86 {
87 }
88};
89
93 public RC<thread_unsafe_refcount>
94{
95 static inline const std::string certcheckProto = "cck1";
96
97 public:
99
100 OPENVPN_EXCEPTION(client_exception);
101 OPENVPN_EXCEPTION(client_halt_restart);
102 OPENVPN_EXCEPTION(tun_exception);
103 OPENVPN_EXCEPTION(transport_exception);
104 OPENVPN_EXCEPTION(max_pushed_options_exceeded);
105 OPENVPN_SIMPLE_EXCEPTION(session_invalidated);
106 OPENVPN_SIMPLE_EXCEPTION(authentication_failed);
107 OPENVPN_SIMPLE_EXCEPTION(inactive_timer_expired);
109
110 OPENVPN_EXCEPTION(proxy_exception);
111
112 struct Config : public RC<thread_unsafe_refcount>
113 {
115
117 : pushed_options_limit("server-pushed options data too large",
118 ProfileParseLimits::MAX_PUSH_SIZE,
119 ProfileParseLimits::OPT_OVERHEAD,
120 ProfileParseLimits::TERM_OVERHEAD,
121 0,
122 ProfileParseLimits::MAX_DIRECTIVE_SIZE)
123 {
124 }
125
136 unsigned int tcp_queue_limit = 0;
137 bool echo = false;
138 bool info = false;
139 bool autologin_sessions = false;
140 };
141
142 Session(openvpn_io::io_context &io_context_arg,
143 const Config &config,
144 NotifyCallback *notify_callback_arg)
145 : proto_context(this, config.proto_context_config, config.cli_stats),
146 io_context(io_context_arg),
150 notify_callback(notify_callback_arg),
151 housekeeping_timer(io_context_arg),
152 push_request_timer(io_context_arg),
153 received_options(config.push_base),
162 inactive_timer(io_context_arg),
163 info_hold_timer(io_context_arg)
164 {
165#ifdef OPENVPN_PACKET_LOG
166 packet_log.open(OPENVPN_PACKET_LOG, std::ios::binary);
167 if (!packet_log)
168 OPENVPN_THROW(open_file_error, "cannot open packet log for output: " << OPENVPN_PACKET_LOG);
169#endif
172 // proto_context.enable_strict_openvpn_2x();
173
174 info_hold.reset(new std::vector<ClientEvent::Base::Ptr>());
175 }
176
178 {
180 }
181
182 void start()
183 {
184 if (!halt)
185 {
187
188 // coarse wakeup range
189 housekeeping_schedule.init(Time::Duration::binary_ms(512), Time::Duration::binary_ms(1024));
190
191 // initialize transport-layer packet handler
196 else
198 }
199 }
200
207
209 {
210 transport_factory = std::move(factory);
211 }
212
218
220 {
221 if (tun)
223 }
224
231 void validate_and_post_cc_msg(const std::string &msg)
232 {
234 {
235 ClientEvent::Base::Ptr ev = new ClientEvent::UnsupportedFeature{"Invalid chars in control message", "Control channel message with invalid characters not allowed to be send with post_cc_msg", false};
236 cli_events->add_event(std::move(ev));
237 return;
238 }
240 }
241
248 void post_cc_msg(const std::string &msg)
249 {
252 proto_context.flush(true);
254 }
255
256 void post_app_control_message(const std::string &proto, const std::string &message)
257 {
259 {
260 ClientEvent::Base::Ptr ev = new ClientEvent::UnsupportedFeature{"missing acc protocol support", "server has not announced support of this custom app control protocol", false};
261 cli_events->add_event(std::move(ev));
262 return;
263 }
264
265 for (auto fragment : proto_context.conf().app_control_config.format_message(proto, message))
266 post_cc_msg(std::move(fragment));
267 }
268
269 void stop(const bool call_terminate_callback)
270 {
271 if (!halt)
272 {
273 halt = true;
274 housekeeping_timer.cancel();
275 push_request_timer.cancel();
276
277 out_tun_callback_.reset();
278 in_tun_callback_.reset();
279 inactive_timer.cancel();
280
281 info_hold_timer.cancel();
282 if (notify_callback && call_terminate_callback)
284 if (tun)
285 tun->stop(); // call after client_proto_terminate() so it can call back to tun_set_disconnect
286 if (transport)
287 transport->stop();
288 }
289 }
290
291 void stop_on_signal(const openvpn_io::error_code &error, int signal_number)
292 {
293 stop(true);
294 }
295
297 {
298 return bool(connected_);
299 }
300
301 // If fatal() returns something other than Error::UNDEF, it
302 // is intended to flag the higher levels (cliconnect.hpp)
303 // that special handling is required. This handling might include
304 // considering the error to be fatal and stopping future connect
305 // retries, or emitting a special event. See cliconnect.hpp
306 // for actual implementation.
308 {
309 return fatal_;
310 }
311 const std::string &fatal_reason() const
312 {
313 return fatal_reason_;
314 }
315
316 // Getters for values which could potentially be modified by
317 // a server's AUTH_FAILED,TEMP response flags
319 {
320 return temp_fail_advance_;
321 }
322 std::chrono::milliseconds reconnect_delay() const
323 {
324 return temp_fail_backoff_;
325 }
326
333 void start_acc_certcheck(SSLLib::SSLAPI::Config::Ptr config)
334 {
335 certcheck_hs.reset(std::move(config));
336 do_acc_certcheck(std::string(""));
337 }
338
339 virtual ~Session()
340 {
341 stop(false);
342 }
343
344 private:
346 {
347 return true;
348 }
349
350 // transport obj calls here with incoming packets
351 void transport_recv(BufferAllocated &buf) override
352 {
353 try
354 {
355 OPENVPN_LOG_CLIPROTO("Transport RECV " << server_endpoint_render() << ' ' << proto_context.dump_packet(buf));
356
357 // update current time
359
360 // update last packet received
362
363 // log connecting event (only on first packet received)
365 {
367 cli_events->add_event(std::move(ev));
369 }
370
371 // get packet type
373
374 // process packet
375 if (pt.is_data())
376 {
377 // data packet
379 if (!buf.empty())
380 {
381#ifdef OPENVPN_PACKET_LOG
382 log_packet(buf, false);
383#endif
384 // make packet appear as incoming on tun interface
385 if (tun)
386 {
387 OPENVPN_LOG_CLIPROTO("TUN send, size=" << buf.size());
388 tun->tun_send(buf);
389 }
390 }
391
392 // do a lightweight flush
393 proto_context.flush(false);
394 }
395 else if (pt.is_control())
396 {
397 // control packet
398 proto_context.control_net_recv(pt, std::move(buf));
399
400 // do a full flush
401 proto_context.flush(true);
402 }
403 else
405
406 // schedule housekeeping wakeup
408 }
409 catch (const ExceptionCode &e)
410 {
411 if (e.code_defined())
412 {
413 if (e.fatal())
414 transport_error((Error::Type)e.code(), e.what());
415 else
417 }
418 else
419 process_exception(e, "transport_recv_excode");
420 }
421 catch (const std::exception &e)
422 {
423 process_exception(e, "transport_recv");
424 }
425 }
426
427 void transport_needs_send() override
428 {
429 }
430
431 // tun i/o driver calls here with incoming packets
432 void tun_recv(BufferAllocated &buf) override
433 {
434 try
435 {
436 OPENVPN_LOG_CLIPROTO("TUN recv, size=" << buf.size());
437
438 // update current time
440
441 // log packet
442#ifdef OPENVPN_PACKET_LOG
443 log_packet(buf, true);
444#endif
445
446 // if transport layer has an output queue, check if it's full
448 {
450 {
451 buf.reset_size(); // queue full, drop packet
453 }
454 }
455
456 // encrypt packet
457 if (!buf.empty())
458 {
460
461 bool df = true;
462
463 if (IPCommon::version(buf[0]) == IPCommon::IPv4 && buf.size() >= sizeof(struct IPv4Header))
464 {
465 df = IPv4Header::is_df_set(buf.c_data());
466 }
467
468 // when calculating mss, we take IPv4 and TCP headers into account
469 // here we need to add it back since we check the whole IP packet size, not just TCP payload
470 constexpr size_t MinTcpHeader = 20;
471 constexpr size_t MinIpHeader = 20;
472 const size_t mss_no_tcp_ip_encap = c.mss_fix + (MinTcpHeader + MinIpHeader);
473
474 if (df && c.mss_fix > 0 && buf.size() > mss_no_tcp_ip_encap)
475 {
476 Ptb::generate_icmp_ptb(buf, clamp_to_typerange<unsigned short>(mss_no_tcp_ip_encap));
477 tun->tun_send(buf);
478 }
479 else
480 {
482 if (!buf.empty())
483 {
484 // send packet via transport to destination
485 OPENVPN_LOG_CLIPROTO("Transport SEND " << server_endpoint_render() << ' ' << proto_context.dump_packet(buf));
486 if (transport->transport_send(buf))
488 else if (halt)
489 return;
490 }
491 }
492 }
493
494 // do a lightweight flush
495 proto_context.flush(false);
496
497 // schedule housekeeping wakeup
499 }
500 catch (const std::exception &e)
501 {
502 process_exception(e, "tun_recv");
503 }
504 }
505
506 // Return true if keepalive parameter(s) are enabled.
507 bool is_keepalive_enabled() const override
508 {
510 }
511
512 // Disable keepalive for rest of session, but fetch
513 // the keepalive parameters (in seconds).
514 void disable_keepalive(unsigned int &keepalive_ping,
515 unsigned int &keepalive_timeout) override
516 {
517 proto_context.disable_keepalive(keepalive_ping, keepalive_timeout);
518 }
519
520 void transport_pre_resolve() override
521 {
523 cli_events->add_event(std::move(ev));
524 }
525
527 {
528 std::string server_host, server_port, server_proto, server_ip;
529 transport->server_endpoint_info(server_host, server_port, server_proto, server_ip);
530 std::ostringstream out;
531 out << '[' << server_host << "]:" << server_port << " (" << server_ip << ") via " << server_proto;
532 return out.str();
533 }
534
535 void transport_wait_proxy() override
536 {
538 cli_events->add_event(std::move(ev));
539 }
540
541 void transport_wait() override
542 {
544 cli_events->add_event(std::move(ev));
545 }
546
547 void transport_connecting() override
548 {
549 try
550 {
552 OPENVPN_LOG("Connecting to " << server_endpoint_render());
555 proto_context.flush(true);
557 }
558 catch (const std::exception &e)
559 {
560 process_exception(e, "transport_connecting");
561 }
562 }
563
564 void transport_error(const Error::Type fatal_err, const std::string &err_text) override
565 {
566 if (fatal_err != Error::UNDEF)
567 {
568 fatal_ = fatal_err;
569 fatal_reason_ = err_text;
570 }
571 if (notify_callback)
572 {
573 OPENVPN_LOG("Transport Error: " << err_text);
574 stop(true);
575 }
576 else
577 throw transport_exception(err_text);
578 }
579
580 void proxy_error(const Error::Type fatal_err, const std::string &err_text) override
581 {
582 if (fatal_err != Error::UNDEF)
583 {
584 fatal_ = fatal_err;
585 fatal_reason_ = err_text;
586 }
587 if (notify_callback)
588 {
589 OPENVPN_LOG("Proxy Error: " << err_text);
590 stop(true);
591 }
592 else
593 throw proxy_exception(err_text);
594 }
595
597 {
598 std::string username;
599
600 // auth-token-user
601 {
602 const Option *o = opt.get_ptr("auth-token-user");
603 if (o)
604 username = base64->decode(o->get(1, 340)); // 255 chars after base64 decode
605 }
606
607 // auth-token
608 {
609 // if auth-token is present, use it as the password for future renegotiations
610 const Option *o = opt.get_ptr("auth-token");
611 if (o)
612 {
613 const std::string &sess_id = o->get(1, 256);
614 if (creds)
615 {
616 if (!username.empty())
617 OPENVPN_LOG("Session user: " << username);
618#ifdef OPENVPN_SHOW_SESSION_TOKEN
619 OPENVPN_LOG("Session token: " << sess_id);
620#else
621 OPENVPN_LOG("Session token: [redacted]");
622#endif
624 creds->set_session_id(username, sess_id);
625 }
626 }
627 }
628 }
629
651 std::string parse_auth_failed_temp(const std::string &msg)
652 {
653 if (msg.empty())
654 return msg;
655
656 // Reset to default values
657 temp_fail_backoff_ = 0ms;
659
660 std::string::size_type reason_idx = 0;
661 auto endofflags = msg.find(']');
662 if (msg.at(0) == '[' && endofflags != std::string::npos)
663 {
664 reason_idx = ++endofflags;
665 auto flags = string::split(std::string{msg, 1, endofflags - 2}, ',');
666 for (const auto &flag : flags)
667 {
668 std::string key;
669 std::string value;
670 std::istringstream f(flag);
671
672 f >> key >> value;
673 if (f.fail())
674 {
675 OPENVPN_LOG("invalid AUTH_FAILED,TEMP flag: " << flag);
676 continue;
677 }
678
679 if (key == "backoff")
680 {
681 int timeout = 0;
682 if (!parse_number(value, timeout))
683 {
684 OPENVPN_LOG("invalid AUTH_FAILED,TEMP flag: " << flag);
685 }
686 temp_fail_backoff_ = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::seconds{timeout});
687 }
688 else if (key == "advance")
689 {
690 if (value == "no")
691 {
693 }
694 else if (value == "addr")
695 {
697 }
698 else if (value == "remote")
699 {
701 }
702 else
703 {
704 OPENVPN_LOG("unknown AUTH_FAILED,TEMP flag: " << flag);
705 }
706 }
707 else
708 {
709 OPENVPN_LOG("unknown AUTH_FAILED,TEMP flag: " << flag);
710 }
711 }
712 }
713
714 if (reason_idx >= msg.size() || msg[reason_idx] != ':')
715 return "";
716
717 // skip leading colon
718 return msg.substr(reason_idx + 1);
719 }
720
721 // proto base class calls here for control channel network sends
722 void control_net_send(const Buffer &net_buf) override
723 {
724 OPENVPN_LOG_CLIPROTO("Transport SEND " << server_endpoint_render() << ' ' << proto_context.dump_packet(net_buf));
725 if (transport->transport_send_const(net_buf))
727 }
728
729 void recv_auth_failed(const std::string &msg)
730 {
731 std::string reason;
732 std::string log_reason;
733
734 // get reason (if it exists) for authentication failure
735 if (msg.length() >= 13)
736 reason = string::trim_left_copy(std::string(msg, 12));
737
738 if (reason.starts_with("TEMP"))
739 {
740 log_reason = "AUTH_FAILED_TEMP:" + parse_auth_failed_temp(std::string(reason, 4));
741 }
742 else
743 {
744 bool password_defined = false;
745 bool session_id_defined = false;
746 if (creds)
747 {
748 password_defined = creds->password_defined();
749 session_id_defined = creds->session_id_defined();
750
751 // authentication failure, purge auth-token
753 }
754
755 // do we have a session-id?
756 if (session_id_defined)
757 {
758 bool reconnect = false;
759
760 // if there was an OOB auth (server pushed AUTH_PENDING) throw a fatal error since we need a user input
762 {
763 // reconnect if we have a password OR password is not needed
764 if (!creds->password_needed() || password_defined)
765 {
766 reconnect = true;
767 }
768 }
769
770 OPENVPN_LOG("need_user_interaction: " << creds->need_user_interaction() << ", pw_needed: " << creds->password_needed() << ", pw_defined: " << password_defined << ", reconnect: " << reconnect);
771
772 if (reconnect)
773 {
774 log_reason = "SESSION_AUTH_FAILED";
775 }
776 else
777 {
778 // we don't have a password and we need a user input, throw a fatal error and let the client to re-authenticate
780 fatal_reason_ = reason;
781 log_reason = "SESSION_EXPIRED";
782 }
783 }
784 else
785 {
786 // no session-id, throw fatal error
788 fatal_reason_ = reason;
789 log_reason = "AUTH_FAILED";
790 }
791 }
792
793 if (notify_callback)
794 {
795 OPENVPN_LOG(log_reason);
796 stop(true);
797 }
798 else
799 throw authentication_failed();
800 }
801
802 void recv_auth_pending(const std::string &msg)
803 {
804 // AUTH_PENDING indicates an out-of-band authentication step must
805 // be performed before the server will send the PUSH_REPLY message.
806 if (!auth_pending)
807 {
808 auth_pending = true;
809 std::string key_words;
810
811 unsigned int timeout = 0;
812
813 if (msg.starts_with("AUTH_PENDING,"))
814 {
815 key_words = msg.substr(strlen("AUTH_PENDING,"));
816 auto opts = OptionList::parse_from_csv_static(key_words, nullptr);
817 const std::string timeout_str = opts.get_optional("timeout", 1, 20);
818 if (!timeout_str.empty())
819 {
820 try
821 {
822 timeout = clamp_to_typerange<unsigned int>(std::stoul(timeout_str));
823 // Cap the timeout to end well before renegotiation starts
824 timeout = std::min(timeout, static_cast<decltype(timeout)>(proto_context.conf().renegotiate.to_seconds() / 2));
825 }
826 catch (const std::logic_error &)
827 {
828 OPENVPN_LOG("could not parse AUTH_PENDING timeout: " << timeout_str);
829 }
830 }
831 }
832
833 if (notify_callback && timeout > 0)
834 {
836 }
837
838 ClientEvent::Base::Ptr ev = new ClientEvent::AuthPending(timeout, std::move(key_words));
839 cli_events->add_event(std::move(ev));
840 }
841 }
842
844 {
846 {
848 fatal_reason_ = "";
849 }
850 else
851 {
853 fatal_reason_ = "not in relay mode";
854 }
855 if (notify_callback)
856 {
858 stop(true);
859 }
860 else
861 throw relay_event();
862 }
863
864 void recv_info(const std::string &msg, bool info_pre)
865 {
866 // Buffer INFO messages received near Connected event to fire
867 // one second after Connected event, to reduce the chance of
868 // race conditions in the client app, if the INFO event
869 // triggers the client app to perform an operation that
870 // requires the VPN tunnel to be ready.
871 std::string info_msg;
872
873 if (info_pre)
874 info_msg = msg.substr(std::string_view{"INFO_PRE,"}.length());
875 else
876 info_msg = msg.substr(std::string_view{"INFO,"}.length());
877
878 if (info_msg.starts_with("ACC:"))
879 {
880 // We want this to be parsed exactly like the custom-control option.
881 // That means we replace ACC: with custom-control for the parser.
882 auto acc_options = OptionList::parse_from_csv_static("custom-control " + info_msg.substr(std::strlen("ACC:")), &pushed_options_limit);
884 // check if we need to notify about ACC protocols
886 }
887 else
888 {
889 if ((info_msg.starts_with("WEB_AUTH:") || info_msg.starts_with("CR_TEXT:")) && creds)
890 {
892 }
893
894 ClientEvent::Info::Ptr ev = new ClientEvent::Info(std::move(info_msg));
895
896 // INFO_PRE is like INFO but it is never buffered
897 if (info_hold && !info_pre)
898 info_hold->push_back(std::move(ev));
899 else
900 cli_events->add_event(std::move(ev));
901 }
902 }
903
909 void recv_push_update(const std::string &msg)
910 {
912
913 // parse the received options
914 auto opt_str = msg.substr(strlen("PUSH_UPDATE,"));
916
918
920 {
921 // show options
922 OPENVPN_LOG("PUSH UPDATE:\n"
924
925 // Merge local and pushed options
927
928 if (tun)
929 {
931 }
932 }
933 }
934
935 // proto base class calls here for app-level control-channel messages received
936 void control_recv(BufferPtr &&app_bp) override
937 {
938 const std::string msg = ProtoContext::read_control_string<std::string>(*app_bp);
940 {
941 OPENVPN_LOG("Control channel message with invalid characters received, ignoring message");
942 return;
943 }
944
945 // OPENVPN_LOG("SERVER: " << sanitize_control_message(msg));
946
947 if (msg.starts_with("PUSH_REPLY,"))
948 {
950 }
951 else if (msg.starts_with("AUTH_FAILED"))
952 {
954 }
955 else if (ClientHalt::match(msg))
956 {
958 }
959 else if (info && msg.starts_with("INFO,"))
960 {
961 recv_info(msg, false);
962 }
963 else if (info && msg.starts_with("INFO_PRE,"))
964 {
965 recv_info(msg, true);
966 }
967 else if (msg == "AUTH_PENDING" || msg.starts_with("AUTH_PENDING,"))
968 {
970 }
971 else if (msg == "RELAY")
972 {
973 recv_relay();
974 }
975 else if (msg.starts_with("ACC,"))
976 {
978 }
979 else if (msg.starts_with("PUSH_UPDATE,"))
980 {
982 }
983 }
984
994 void recv_custom_control_message(const std::string &msg)
995 {
996 const bool fullmessage = proto_context.conf().app_control_recv.receive_message(msg);
997 if (!fullmessage)
998 return;
999
1000 auto [proto, app_proto_msg] = proto_context.conf().app_control_recv.get_message();
1001
1002 if (proto == certcheckProto) // handle this built-in ACC internal protocol intrinsically
1003 {
1004 do_acc_certcheck(app_proto_msg);
1005 }
1007 {
1008 ClientEvent::Base::Ptr ev = new ClientEvent::AppCustomControlMessage(std::move(proto), std::move(app_proto_msg));
1009 cli_events->add_event(std::move(ev));
1010 }
1011 else
1012 {
1013 OPENVPN_LOG("App custom control message with unsupported protocol [" + proto + "] received");
1014 }
1015 }
1021 void do_acc_certcheck(const std::string &msg_str)
1022 {
1023 AccHandshaker::MsgT reply = std::nullopt;
1024 AccHandshaker::MsgT msg = std::nullopt;
1025
1026 if (msg_str.empty() == false)
1027 msg = msg_str;
1028
1029 try
1030 {
1031 do
1032 {
1033 reply = certcheck_hs.process_msg(msg);
1034
1035 if (reply)
1036 {
1038 }
1039 msg = std::nullopt;
1040 } while (reply);
1041 }
1042 catch (std::exception &ex)
1043 {
1044 OPENVPN_LOG("App custom control cert check exception: " << ex.what());
1045 }
1046 }
1047
1049 {
1051 {
1052 // Signal support for supported protocols
1054 cli_events->add_event(std::move(ev));
1055 }
1056 }
1057
1058 void recv_push_reply(const std::string &msg)
1059 {
1061 {
1062 // parse the received options
1063 auto pushed_options_list = OptionList::parse_from_csv_static(msg.substr(11), &pushed_options_limit);
1064 try
1065 {
1066 received_options.add(pushed_options_list, pushed_options_filter.get());
1067 }
1068 catch (const Option::RejectedException &e)
1069 {
1070 recv_halt_restart("RESTART,rejected pushed option: " + e.err());
1071 }
1073 {
1074 // show options
1075 OPENVPN_LOG("OPTIONS:\n"
1077
1078 // relay servers are not allowed to establish a tunnel with us
1080 {
1081 tun_error(Error::RELAY_ERROR, "tunnel not permitted to relay server");
1082 return;
1083 }
1084
1085 // Merge local and pushed options
1087
1088 // process "echo" directives
1089 if (echo)
1091
1092 // process auth-token
1094
1095 // process pushed transport options
1097
1098 // modify proto config (cipher, auth, key-derivation and compression methods)
1100
1101 // process pushed auth-nocache
1103 {
1105 }
1106
1107 // initialize tun/routing
1110
1111 // we should be connected at this point
1112 if (!connected_)
1113 throw tun_exception("not connected");
1114
1115 // Propagate tun-mtu back, it might have been overwritten by a pushed tun-mtu option
1117
1118 // initialize data channel after pushed options have been processed
1120
1121 // we got pushed options and initializated crypto - now we can push mss to dco
1123
1124 // Allow ProtoContext to suggest an alignment adjustment
1125 // hint for transport layer.
1127
1128 // process "inactive" directive
1130
1131 // tell parent that we are connected
1132 if (notify_callback)
1134
1135 // start info-hold timer
1137
1138 // send the Connected event
1139 cli_events->add_event(connected_);
1141
1142 // send an event for custom app control if present
1144
1145 // check for proto options
1147 }
1148 else
1149 OPENVPN_LOG("Options continuation...");
1150 }
1151 else if (received_options.complete())
1152 {
1153 // We got a PUSH REPLY in the middle of a session. Ignore it apart from
1154 // updating the auth-token if included in the push reply
1155 auto opts = OptionList::parse_from_csv_static(msg.substr(11), nullptr);
1156 extract_auth_token(opts);
1157 }
1158 }
1159
1160 void tun_pre_tun_config() override
1161 {
1163 cli_events->add_event(std::move(ev));
1164 }
1165
1166 void tun_pre_route_config() override
1167 {
1169 cli_events->add_event(std::move(ev));
1170 }
1171
1173 {
1174 cli_events->add_event(std::move(ev));
1175 }
1176
1177 void tun_connected() override
1178 {
1179 OPENVPN_LOG("Connected via " + tun->tun_name());
1180
1182 if (creds)
1183 ev->user = creds->get_username();
1184 transport->server_endpoint_info(ev->server_host, ev->server_port, ev->server_proto, ev->server_ip);
1185 ev->vpn_ip4 = tun->vpn_ip4();
1186 ev->vpn_ip6 = tun->vpn_ip6();
1187 ev->vpn_gw4 = tun->vpn_gw4();
1188 ev->vpn_gw6 = tun->vpn_gw6();
1189 if (tun->vpn_mtu())
1190 {
1191 ev->vpn_mtu = std::to_string(tun->vpn_mtu());
1192 }
1193 else
1194 {
1195 ev->vpn_mtu = "(default)";
1196 }
1197 ev->vpn_interface_index = tun->vpn_interface_index();
1198
1199 try
1200 {
1201 const std::string client_ip = received_options.get_optional("client-ip", 1, 256);
1202 if (!client_ip.empty())
1203 ev->client_ip = IP::Addr::validate(client_ip, "client-ip");
1204 }
1205 catch (const std::exception &e)
1206 {
1207 OPENVPN_LOG("exception parsing client-ip: " << e.what());
1208 }
1209 ev->tun_name = tun->tun_name();
1210 connected_ = std::move(ev);
1211
1212 // On the initial connection the Connected event is emitted by
1213 // recv_push_reply(), once the data channel and the remaining
1214 // post-connect setup have been initialized, so we must not emit it
1215 // here. When the tun is re-established after a PUSH_UPDATE, however,
1216 // apply_push_update() runs tun_start() (and therefore this callback)
1217 // asynchronously, after recv_push_update() has already returned -- so
1218 // nobody else would emit the refreshed Connected event. Do it here to
1219 // signal that the tun is operational again, otherwise the controller
1220 // is left waiting in the IP-assignment state forever.
1222 cli_events->add_event(connected_);
1223 }
1224
1225 void tun_error(const Error::Type fatal_err, const std::string &err_text) override
1226 {
1227 if (fatal_err == Error::TUN_HALT)
1229 if (fatal_err != Error::UNDEF)
1230 {
1231 fatal_ = fatal_err;
1232 fatal_reason_ = err_text;
1233 }
1234 if (notify_callback)
1235 {
1236 OPENVPN_LOG("TUN Error: " << err_text);
1237 stop(true);
1238 }
1239 else
1240 throw tun_exception(err_text);
1241 }
1242
1243 // proto base class calls here to get auth credentials
1244 void client_auth(Buffer &buf) override
1245 {
1246 // we never send creds to a relay server
1248 {
1249 OPENVPN_LOG("Creds: " << creds->auth_info());
1251 {
1252 throw ErrorCode(Error::NEED_CREDS, true, "missing password");
1253 }
1255#ifdef OPENVPN_DISABLE_AUTH_TOKEN // debugging only
1257 {
1258 OPENVPN_LOG("NOTE: not sending auth-token");
1260 }
1261 else
1262#endif
1263 {
1265 }
1266
1267 // save username for auth-token, which might be pushed later
1269
1271 {
1273 }
1274 }
1275 else
1276 {
1277 OPENVPN_LOG("Creds: None");
1278 write_empty_string(buf); // username
1279 write_empty_string(buf); // password
1280 }
1281 }
1282
1283 void send_push_request_callback(const Time::Duration &dur,
1284 const openvpn_io::error_code &e)
1285 {
1286 try
1287 {
1288 if (!e && !halt && !received_options.partial())
1289 {
1291 if (!sent_push_request)
1292 {
1294 cli_events->add_event(std::move(ev));
1295 sent_push_request = true;
1296 }
1297 OPENVPN_LOG("Sending PUSH_REQUEST to server...");
1298 proto_context.write_control_string(std::string("PUSH_REQUEST"));
1299 proto_context.flush(true);
1301
1302 {
1303 if (auth_pending)
1304 {
1305 // With auth_pending, we can dial back the PUSH_REQUEST
1306 // frequency, but we still need back-and-forth network
1307 // activity to avoid an inactivity timeout, since the crypto
1308 // layer (and hence keepalive ping) is not initialized until
1309 // we receive the PUSH_REPLY from the server.
1310 schedule_push_request_callback(Time::Duration::seconds(8));
1311 }
1312 else
1313 {
1314 // step function with ceiling: 1 sec, 2 secs, 3 secs, 3, 3, ...
1315 const Time::Duration newdur = std::min(dur + Time::Duration::seconds(1),
1316 Time::Duration::seconds(3));
1318 }
1319 }
1320 }
1321 }
1322 catch (const std::exception &e)
1323 {
1324 process_exception(e, "send_push_request_callback");
1325 }
1326 }
1327
1328 void schedule_push_request_callback(const Time::Duration &dur)
1329 {
1331 {
1333 push_request_timer.async_wait([self = Ptr(this), dur](const openvpn_io::error_code &error)
1334 {
1336 self->send_push_request_callback(dur, error); });
1337 }
1338 }
1339
1340 // react to any tls warning triggered during the tls-handshake
1341 virtual void check_tls_warnings()
1342 {
1343 const uint32_t tls_warnings = proto_context.get_tls_warnings();
1344
1345 if (tls_warnings & SSLAPI::TLS_WARN_SIG_MD5)
1346 {
1347 ClientEvent::Base::Ptr ev = new ClientEvent::Warn("TLS: received certificate signed with MD5. Please inform your admin to upgrade to a stronger algorithm. Support for MD5 will be dropped in the near future");
1348 cli_events->add_event(std::move(ev));
1349 }
1350
1351 if (tls_warnings & SSLAPI::TLS_WARN_SIG_SHA1)
1352 {
1353 ClientEvent::Base::Ptr ev = new ClientEvent::Warn("TLS: received certificate signed with SHA1. Please inform your admin to upgrade to a stronger algorithm. Support for SHA1 signatures will be dropped in the future");
1354 cli_events->add_event(std::move(ev));
1355 }
1356 }
1357
1359 {
1361 {
1362 ClientEvent::Base::Ptr ev = new ClientEvent::Warn("Proto: Using a 64-bit block cipher that is vulnerable to the SWEET32 attack. Please inform your admin to upgrade to a stronger algorithm. Support for 64-bit block cipher will be dropped in the future.");
1363 cli_events->add_event(std::move(ev));
1364 }
1365
1367
1368 // abort connection if compression is pushed and its support is unannounced
1369 if (comp_type != CompressContext::COMP_STUBv2
1370 && comp_type != CompressContext::NONE
1372 {
1373 throw ErrorCode(Error::COMPRESS_ERROR, true, "server pushed compression "
1374 "settings that are not allowed and will result "
1375 "in a non-working connection. ");
1376 }
1377
1378 // Issue an event if compression is enabled
1379 if (comp_type != CompressContext::NONE
1380 && !CompressContext::is_any_stub(comp_type))
1381 {
1382 std::ostringstream msg;
1384 ? "Asymmetric compression enabled. Server may send compressed data."
1385 : "Compression enabled.");
1386 msg << " This may be a potential security issue.";
1388 cli_events->add_event(std::move(ev));
1389 }
1390 }
1391
1392 // base class calls here when session transitions to ACTIVE state
1393 void active(bool primary) override
1394 {
1395 if (primary)
1396 {
1397 OPENVPN_LOG("Session is ACTIVE");
1399 schedule_push_request_callback(Time::Duration::seconds(0));
1400 }
1401 else if (notify_callback)
1403 }
1404
1405 bool supports_epoch_data() override
1406 {
1408 }
1409
1410 void housekeeping_callback(const openvpn_io::error_code &e)
1411 {
1412 try
1413 {
1414 if (!e && !halt)
1415 {
1416 // update current time
1418
1422 {
1423 if (notify_callback)
1424 {
1425 OPENVPN_LOG("Session invalidated: " << Error::name(proto_context.invalidation_reason()));
1426 stop(true);
1427 }
1428 else
1429 throw session_invalidated();
1430 }
1432 }
1433 }
1434 catch (const std::exception &e)
1435 {
1436 process_exception(e, "housekeeping_callback");
1437 }
1438 }
1439
1441 {
1442 if (halt)
1443 return;
1444
1446 if (!housekeeping_schedule.similar(next))
1447 {
1448 if (!next.is_infinite())
1449 {
1450 next.max(proto_context.now());
1453 housekeeping_timer.async_wait([self = Ptr(this)](const openvpn_io::error_code &error)
1454 {
1456 self->housekeeping_callback(error); });
1457 }
1458 else
1459 {
1460 housekeeping_timer.cancel();
1462 }
1463 }
1464 }
1469 void set_cc_handshake_config(SSLLib::SSLAPI::Config::Ptr cfg)
1470 {
1471 certcheck_hs.reset(cfg);
1472 }
1473
1475 {
1476 try
1477 {
1478 const Option *o = load_duration_parm(inactive_duration, "inactive", opt, 1, false, false);
1479 if (o)
1480 {
1481 if (o->size() >= 3)
1482 inactivity_minimum_bytes = parse_number_throw<unsigned int>(o->get(2, 16), "inactive bytes");
1483
1486 [self = Ptr(this)](const count_t value)
1487 { self->reset_inactive_timer(value); });
1488
1491 [self = Ptr(this)](const count_t value)
1492 { self->reset_inactive_timer(value); });
1493
1495 }
1496 }
1497 catch (const std::exception &e)
1498 {
1499 OPENVPN_LOG("exception parsing inactive: " << e.what());
1500 }
1501 }
1502
1504 {
1506 inactive_timer.async_wait([self = Ptr(this)](const openvpn_io::error_code &error)
1507 {
1509 self->inactive_callback(error); });
1510 }
1511
1512 void reset_inactive_timer(const count_t bytes_count)
1513 {
1514 // Ensure that it's called within the io_context in case it needs to be invoked from a separate thread.
1515 openvpn_io::post(io_context, [self = Ptr(this), bytes_count]()
1516 {
1518
1519 self->inactivity_bytes += bytes_count;
1520 if (self->inactivity_bytes >= self->inactivity_minimum_bytes)
1521 {
1522 // OPENVPN_LOG("reset_inactive_timer: " << self->inactivity_bytes);
1523 self->inactivity_bytes = 0;
1524 self->schedule_inactive_timer();
1525 } });
1526 }
1527
1528 void inactive_callback(const openvpn_io::error_code &e) // fixme for DCO
1529 {
1530 try
1531 {
1532 if (!e && !halt)
1533 {
1534 // In non-DCO case, inactivity timeout is reset on data channel activity,
1535 // so this function is only called on timeout.
1536 //
1537 // With DCO, OpenVPN doesn't see data channel packets, so we have to
1538 // change the logic and check kernel counters here, either stopping or
1539 // rearming the timer if there is sufficient traffic.
1540 if (cli_stats->dco_update())
1541 {
1543 auto delta = sample - inactive_last_sample;
1544 if (delta >= inactivity_minimum_bytes)
1545 {
1546 inactive_last_sample = sample;
1548 return;
1549 }
1550 }
1551
1554 if (notify_callback)
1555 {
1556 OPENVPN_LOG("inactive timer expired");
1557 stop(true);
1558 }
1559 else
1560 throw inactive_timer_expired();
1561 }
1562 }
1563 catch (const std::exception &e)
1564 {
1565 process_exception(e, "inactive_callback");
1566 }
1567 }
1568
1569 void process_echo(const OptionList &opt)
1570 {
1571 const OptionList::IndexMap::const_iterator echo_opt = opt.map().find("echo");
1572 if (echo_opt != opt.map().end())
1573 {
1574 for (OptionList::IndexList::const_iterator i = echo_opt->second.begin(); i != echo_opt->second.end(); ++i)
1575 {
1576 const Option &o = opt[*i];
1577 o.touch();
1578 const std::string &value = o.get(1, 512);
1580 cli_events->add_event(std::move(ev));
1581 }
1582 }
1583 }
1584
1585 void process_exception(const std::exception &e, const char *method_name)
1586 {
1587 if (notify_callback)
1588 {
1589 OPENVPN_LOG("Client exception in " << method_name << ": " << e.what());
1590 stop(true);
1591 }
1592 else
1593 throw client_exception(e.what());
1594 }
1595
1596 void recv_halt_restart(const std::string &msg)
1597 {
1598 const ClientHalt ch(msg, true);
1599 if (!ch.psid() && creds)
1601 if (ch.restart())
1603 else
1605 fatal_reason_ = ch.reason();
1606 if (notify_callback)
1607 {
1608 OPENVPN_LOG("Client halt/restart: " << ch.render());
1609 stop(true);
1610 }
1611 else
1612 throw client_halt_restart(ch.render());
1613 }
1614
1616 {
1618 info_hold_timer.expires_after(Time::Duration::seconds(1));
1619 info_hold_timer.async_wait([self = Ptr(this)](const openvpn_io::error_code &error)
1620 {
1622 self->info_hold_callback(error); });
1623 }
1624
1625 void info_hold_callback(const openvpn_io::error_code &e)
1626 {
1627 try
1628 {
1629 if (!e && !halt)
1630 {
1632 if (info_hold)
1633 {
1634 for (auto &ev : *info_hold)
1635 cli_events->add_event(std::move(ev));
1636 info_hold.reset();
1637 }
1638 }
1639 }
1640 catch (const std::exception &exc)
1641 {
1642 process_exception(exc, "info_hold_callback");
1643 }
1644 }
1645
1646#ifdef OPENVPN_PACKET_LOG
1647 void log_packet(const Buffer &buf, const bool out)
1648 {
1649 if (buf.size())
1650 {
1651 std::uint16_t len = buf.size() & 0x7FFF;
1652 if (out)
1653 len |= 0x8000;
1654 packet_log.write((const char *)&len, sizeof(len));
1655 packet_log.write((const char *)buf.c_data(), buf.size());
1656 }
1657 }
1658#endif
1659
1661
1662 openvpn_io::io_context &io_context;
1663
1666
1669
1670 unsigned int tcp_queue_limit;
1672
1674
1678 bool halt = false;
1679
1681
1683
1685
1687 bool sent_push_request = false;
1688 bool auth_pending = false;
1689
1692
1694
1695 // True once the Connected event has been emitted for this session (by
1696 // recv_push_reply()). It tells tun_connected() that any later tun
1697 // re-establishment -- e.g. triggered by a PUSH_UPDATE -- must re-emit the
1698 // Connected event itself, because recv_push_update() drives the tun setup
1699 // asynchronously and does not emit it.
1701
1702 bool echo;
1703 bool info;
1704
1706 std::string fatal_reason_;
1707
1711
1713 Time::Duration inactive_duration;
1714
1717 std::uint64_t inactivity_bytes = 0;
1718 std::shared_ptr<SessionStats::inc_callback_t> out_tun_callback_;
1719 std::shared_ptr<SessionStats::inc_callback_t> in_tun_callback_;
1720
1721 std::unique_ptr<std::vector<ClientEvent::Base::Ptr>> info_hold;
1723
1724 // AUTH_FAILED,TEMP flag values
1725 std::chrono::milliseconds temp_fail_backoff_{0};
1727
1728 // Client side certcheck
1730
1731#ifdef OPENVPN_PACKET_LOG
1732 std::ofstream packet_log;
1733#endif
1734};
1735} // namespace openvpn::ClientProto
1736
1737#endif
#define OPENVPN_ASYNC_HANDLER
Definition bigmutex.hpp:36
bool receive_message(const std::string &msg)
std::pair< std::string, std::string > get_message()
std::size_t expires_at(const Time &t)
Definition asiotimer.hpp:64
std::size_t expires_after(const Time::Duration &d)
Definition asiotimer.hpp:69
size_t decode(void *data, size_t len, const std::string &str) const
Definition base64.hpp:186
bool password_defined() const
Definition clicreds.hpp:130
std::string get_password() const
Definition clicreds.hpp:102
bool password_needed() const
Definition clicreds.hpp:182
std::string auth_info() const
Definition clicreds.hpp:187
void set_need_user_interaction()
Definition clicreds.hpp:172
bool need_user_interaction() const
Definition clicreds.hpp:177
void set_session_id(const std::string &user, const std::string &sess_id)
Definition clicreds.hpp:74
std::string get_username() const
Definition clicreds.hpp:93
bool session_id_defined() const
Definition clicreds.hpp:145
void save_username_for_session_id()
Definition clicreds.hpp:164
bool restart() const
Definition clihalt.hpp:71
std::string render() const
Definition clihalt.hpp:88
static bool match(const std::string &msg)
Definition clihalt.hpp:63
const std::string & reason() const
Definition clihalt.hpp:83
bool psid() const
Definition clihalt.hpp:77
OPENVPN_EXCEPTION(transport_exception)
void recv_info(const std::string &msg, bool info_pre)
Definition cliproto.hpp:864
void stop_on_signal(const openvpn_io::error_code &error, int signal_number)
Definition cliproto.hpp:291
std::string parse_auth_failed_temp(const std::string &msg)
Definition cliproto.hpp:651
void info_hold_callback(const openvpn_io::error_code &e)
std::unique_ptr< std::vector< ClientEvent::Base::Ptr > > info_hold
bool transport_is_openvpn_protocol() override
Definition cliproto.hpp:345
void control_recv(BufferPtr &&app_bp) override
Definition cliproto.hpp:936
bool supports_epoch_data() override
void transport_recv(BufferAllocated &buf) override
Definition cliproto.hpp:351
void reset_inactive_timer(const count_t bytes_count)
void active(bool primary) override
Called when KeyContext transitions to ACTIVE state.
void recv_halt_restart(const std::string &msg)
static const std::string certcheckProto
Definition cliproto.hpp:95
openvpn_io::io_context & io_context
void housekeeping_callback(const openvpn_io::error_code &e)
void transport_wait() override
Definition cliproto.hpp:541
void start_acc_certcheck(SSLLib::SSLAPI::Config::Ptr config)
Start up the cert check handshake using the given certs and key.
Definition cliproto.hpp:333
TransportClient::Ptr transport
void schedule_push_request_callback(const Time::Duration &dur)
void recv_push_update(const std::string &msg)
Handles incoming PUSH_UPDATE message.
Definition cliproto.hpp:909
void control_net_send(const Buffer &net_buf) override
Definition cliproto.hpp:722
const std::string & fatal_reason() const
Definition cliproto.hpp:311
void tun_error(const Error::Type fatal_err, const std::string &err_text) override
TransportClientFactory::Ptr transport_factory_relay()
Definition cliproto.hpp:201
NotifyCallback * notify_callback
virtual void check_tls_warnings()
OptionList::Limits pushed_options_limit
void post_cc_msg(const std::string &msg)
Definition cliproto.hpp:248
Session(openvpn_io::io_context &io_context_arg, const Config &config, NotifyCallback *notify_callback_arg)
Definition cliproto.hpp:142
PushOptionsMerger::Ptr pushed_options_merger
RemoteList::Advance advance_type() const
Definition cliproto.hpp:318
void inactive_callback(const openvpn_io::error_code &e)
void transport_wait_proxy() override
Definition cliproto.hpp:535
void disable_keepalive(unsigned int &keepalive_ping, unsigned int &keepalive_timeout) override
Definition cliproto.hpp:514
void transport_factory_override(TransportClientFactory::Ptr factory)
Definition cliproto.hpp:208
void send_push_request_callback(const Time::Duration &dur, const openvpn_io::error_code &e)
OPENVPN_EXCEPTION(client_exception)
void tun_recv(BufferAllocated &buf) override
Definition cliproto.hpp:432
OptionList::FilterBase::Ptr pushed_options_filter
void tun_pre_tun_config() override
void tun_event(ClientEvent::Base::Ptr ev) override
OPENVPN_SIMPLE_EXCEPTION(session_invalidated)
ClientEvent::Connected::Ptr connected_
ProtoContextCompressionOptions::Ptr proto_context_options
unsigned int inactivity_minimum_bytes
void transport_pre_resolve() override
Definition cliproto.hpp:520
OPENVPN_EXCEPTION(max_pushed_options_exceeded)
void proxy_error(const Error::Type fatal_err, const std::string &err_text) override
Definition cliproto.hpp:580
OPENVPN_EXCEPTION(proxy_exception)
void recv_auth_failed(const std::string &msg)
Definition cliproto.hpp:729
SessionStats::Ptr cli_stats
void recv_custom_control_message(const std::string &msg)
receive, validate, and dispatch ACC messages
Definition cliproto.hpp:994
void stop(const bool call_terminate_callback)
Definition cliproto.hpp:269
void tun_pre_route_config() override
void recv_auth_pending(const std::string &msg)
Definition cliproto.hpp:802
OptionListContinuation received_options
void do_acc_certcheck(const std::string &msg_str)
Handles the ACC certcheck TLS handshake data exchange.
void transport_error(const Error::Type fatal_err, const std::string &err_text) override
Definition cliproto.hpp:564
void client_auth(Buffer &buf) override
void transport_needs_send() override
Definition cliproto.hpp:427
std::chrono::milliseconds reconnect_delay() const
Definition cliproto.hpp:322
void recv_push_reply(const std::string &msg)
void validate_and_post_cc_msg(const std::string &msg)
Definition cliproto.hpp:231
void process_inactive(const OptionList &opt)
void extract_auth_token(const OptionList &opt)
Definition cliproto.hpp:596
void transport_connecting() override
Definition cliproto.hpp:547
OPENVPN_EXCEPTION(tun_exception)
ClientEvent::Queue::Ptr cli_events
OPENVPN_SIMPLE_EXCEPTION(relay_event)
TunClientFactory::Ptr tun_factory
void process_exception(const std::exception &e, const char *method_name)
void process_echo(const OptionList &opt)
bool reached_connected_state() const
Definition cliproto.hpp:296
RemoteList::Advance temp_fail_advance_
std::string server_endpoint_render()
Definition cliproto.hpp:526
OPENVPN_EXCEPTION(client_halt_restart)
OPENVPN_SIMPLE_EXCEPTION(inactive_timer_expired)
void post_app_control_message(const std::string &proto, const std::string &message)
Definition cliproto.hpp:256
bool is_keepalive_enabled() const override
Definition cliproto.hpp:507
void set_cc_handshake_config(SSLLib::SSLAPI::Config::Ptr cfg)
Set the cc handshake config object.
std::shared_ptr< SessionStats::inc_callback_t > in_tun_callback_
Error::Type fatal() const
Definition cliproto.hpp:307
std::chrono::milliseconds temp_fail_backoff_
OPENVPN_SIMPLE_EXCEPTION(authentication_failed)
std::shared_ptr< SessionStats::inc_callback_t > out_tun_callback_
TransportClientFactory::Ptr transport_factory
bool similar(const Time &t) const
void init(const Time::Duration &pre, const Time::Duration &post)
void reset(const Time &t)
static bool is_any_stub(const Type t)
Definition compress.hpp:507
const T * c_data() const
Returns a const pointer to the start of the buffer.
Definition buffer.hpp:1193
size_t size() const
Returns the size of the buffer in T objects.
Definition buffer.hpp:1241
bool empty() const
Returns true if the buffer is empty.
Definition buffer.hpp:1235
void reset_size()
Resets the size of the buffer to zero.
Definition buffer.hpp:1169
bool fatal() const
Definition excode.hpp:51
Error::Type code() const
Definition excode.hpp:47
bool code_defined() const
Definition excode.hpp:56
static std::string validate(const std::string &ipstr, const TITLE &title, const Version required_version)
Definition ip.hpp:131
void reset_completion()
Resets completion flag. Intended to use by PUSH_UPDATE.
void finalize(const PushOptionsMerger::Ptr merger)
void add(const OptionList &other, OptionList::FilterBase *filt, bool push_update=false)
std::string get_optional(const std::string &name, size_t index, const size_t max_len) const
Definition options.hpp:1330
const IndexMap & map() const
Definition options.hpp:1546
static OptionList parse_from_csv_static(const std::string &str, Limits *lim)
Definition options.hpp:837
const Option * get_ptr(const std::string &name) const
Definition options.hpp:1179
void touch(bool lightly=false) const
Definition options.hpp:383
const std::string & get(const size_t index, const size_t max_len) const
Definition options.hpp:189
size_t size() const
Definition options.hpp:325
static void write_empty_string(Buffer &buf)
Definition proto.hpp:190
void build_connect_time_peer_info_string(TransportClient::Ptr transport)
Definition proto.hpp:1126
AppControlMessageReceiver app_control_recv
Definition proto.hpp:466
void set_xmit_creds(const bool xmit_creds_arg)
Definition proto.hpp:1045
AppControlMessageConfig app_control_config
Definition proto.hpp:465
void parse_custom_app_control(const OptionList &opt)
Definition proto.hpp:761
bool control_net_recv(const PacketType &type, BufferPtr &&net_bp)
Definition proto.hpp:4688
uint32_t get_tls_warnings() const
Definition proto.hpp:4332
void send_explicit_exit_notify()
Definition proto.hpp:4754
const Time & now() const
Definition proto.hpp:4895
CryptoDCSettings & dc_settings()
Definition proto.hpp:4877
void flush(const bool control_channel)
Definition proto.hpp:4615
bool uses_bs64_cipher() const
Definition proto.hpp:4341
PacketType packet_type(const Buffer &buf)
Definition proto.hpp:4565
void data_encrypt(BufferAllocated &in_out)
Definition proto.hpp:4709
bool is_keepalive_enabled() const
Definition proto.hpp:4842
void process_push(const OptionList &opt, const ProtoContextCompressionOptions &pco)
Definition proto.hpp:4826
static void write_auth_string(const S &str, Buffer &buf)
Definition proto.hpp:1570
void set_protocol(const Protocol &p)
Definition proto.hpp:4540
size_t align_adjust_hint() const
Definition proto.hpp:4836
SessionStats & stat() const
Definition proto.hpp:4953
std::string dump_packet(const Buffer &buf)
Definition proto.hpp:1455
static void write_empty_string(Buffer &buf)
Definition proto.hpp:1604
static void write_control_string(const S &str, Buffer &buf)
Definition proto.hpp:1597
bool data_decrypt(const PacketType &type, BufferAllocated &in_out)
Definition proto.hpp:4719
void disable_keepalive(unsigned int &keepalive_ping, unsigned int &keepalive_timeout)
Definition proto.hpp:4850
Error::Type invalidation_reason() const
Definition proto.hpp:4806
Time next_housekeeping() const
Definition proto.hpp:4653
bool invalidated() const
Definition proto.hpp:4800
void reset(const ProtoSessionID cookie_psid=ProtoSessionID())
Resets ProtoContext *this to it's initial state.
Definition proto.hpp:4436
void start(const ProtoSessionID cookie_psid=ProtoSessionID())
Initialize the state machine and start protocol negotiation.
Definition proto.hpp:4578
const ProtoConfig & conf() const
Definition proto.hpp:4939
static void generate_icmp_ptb(BufferAllocated &buf, std::uint16_t nexthop_mtu)
Definition ptb.hpp:30
The smart pointer class.
Definition rc.hpp:119
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
Definition rc.hpp:290
void swap(RCPtr &rhs) noexcept
swaps the contents of two RCPtr<T>
Definition rc.hpp:311
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
Definition rc.hpp:321
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:908
virtual void error(const size_t type, const std::string *text=nullptr)
std::shared_ptr< inc_callback_t > set_inc_callback(Stats stat, inc_callback_t callback)
Sets a callback to be triggered upon increment of stats.
void update_last_packet_received(const Time &now)
count_t get_stat(const size_t type) const
void max(const TimeType &t)
Definition time.hpp:343
bool is_infinite() const
Definition time.hpp:266
#define OPENVPN_LOG_CLIPROTO(x)
Definition cliproto.hpp:67
#define OPENVPN_THROW(exc, stuff)
#define OPENVPN_LOG(args)
const char * name(const size_t type)
Definition error.hpp:117
unsigned int version(const std::uint8_t version_len_prio)
Definition ipcommon.hpp:35
bool is_valid_utf8(const STRING &str, const size_t max_len_flags=0)
Definition unicode.hpp:75
OutT clamp_to_typerange(InT inVal)
Clamps the input value to the legal range for the output type.
auto join(const T &strings, const typename T::value_type &delim, const bool tail=false)
Definition string.hpp:481
std::vector< T > split(const T &str, const typename T::value_type sep, const int maxsplit=-1)
Definition string.hpp:452
std::string trim_left_copy(const std::string &str)
Definition string.hpp:509
const Option * load_duration_parm(Time::Duration &dur, const std::string &name, const OptionList &opt, const unsigned int min_value, const bool x2, const bool allow_ms)
Definition durhelper.hpp:41
std::string render_options_sanitized(const OptionList &opt, const unsigned int render_flags)
Definition sanitize.hpp:25
const Base64 * base64
Definition base64.hpp:299
bool parse_number(const char *str, T &retval, const bool nondigit_term=false)
Definition number.hpp:35
long long count_t
Definition count.hpp:16
defines a class that handles SSL/TLS handshaking
std::optional< std::string > MsgT
MsgT process_msg(const MsgT &msg)
Incrementally process the CLIENT HELLO / SERVER HELLO exchange.
void reset(SSLLib::SSLAPI::Config::Ptr cfg)
Re-init the handshaker.
bool supports_protocol(const std::string &protocol)
std::vector< std::string > supported_protocols
List of supported protocols.
std::vector< std::string > format_message(const std::string &protocol, const std::string &message)
Format a protocol string and a message into a properly packed series of message fragments.
virtual void client_proto_auth_pending_timeout(int timeout)
Definition cliproto.hpp:82
TunClientFactory::Ptr tun_factory
Definition cliproto.hpp:130
ClientEvent::Queue::Ptr cli_events
Definition cliproto.hpp:132
TransportClientFactory::Ptr transport_factory
Definition cliproto.hpp:129
OptionList::FilterBase::Ptr pushed_options_filter
Definition cliproto.hpp:135
OptionList::Limits pushed_options_limit
Definition cliproto.hpp:134
ProtoContextCompressionOptions::Ptr proto_context_options
Definition cliproto.hpp:127
ProtoContext::ProtoConfig::Ptr proto_context_config
Definition cliproto.hpp:126
static bool is_df_set(const unsigned char *data)
Definition ip4.hpp:36
virtual TransportClient::Ptr new_transport_client_obj(openvpn_io::io_context &io_context, TransportClientParent *parent)=0
virtual void process_push(const OptionList &)
virtual void reset_align_adjust(const size_t align_adjust)=0
virtual void transport_start()=0
virtual bool transport_send_const(const Buffer &buf)=0
virtual size_t transport_send_queue_size()=0
virtual bool transport_has_send_queue()=0
virtual bool transport_send(BufferAllocated &buf)=0
virtual void server_endpoint_info(std::string &host, std::string &port, std::string &proto, std::string &ip_addr) const =0
virtual void stop()=0
virtual Protocol transport_protocol() const =0
virtual TunClient::Ptr new_tun_client_obj(openvpn_io::io_context &io_context, TunClientParent &parent, TransportClient *transcli)=0
virtual bool supports_epoch_data()=0
virtual std::string vpn_gw6() const
Definition tunbase.hpp:50
virtual std::string vpn_ip4() const =0
virtual std::string tun_name() const =0
virtual void stop()=0
virtual int vpn_mtu() const =0
virtual void adjust_mss(int mss)
Definition tunbase.hpp:57
virtual void apply_push_update(const OptionList &opt, TransportClient &cli)
Notifies tun client about received PUSH_UPDATE control channel message.
Definition tunbase.hpp:70
virtual std::uint32_t vpn_interface_index() const
Definition tunbase.hpp:72
virtual void set_disconnect()=0
virtual void tun_start(const OptionList &, TransportClient &, CryptoDCSettings &)=0
virtual std::string vpn_gw4() const
Definition tunbase.hpp:46
virtual bool tun_send(BufferAllocated &buf)=0
virtual std::string vpn_ip6() const =0
auto f(const Thing1 t)
static const char config[]
static std::stringstream out
Definition test_path.cpp:10
const char message[]
#define msg(flags,...)