OpenVPN 3 Core Library
Loading...
Searching...
No Matches
clievent.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// This file describes the basic set of OpenVPN client events, including the
13// normal events leading up to a connection as well as error events.
14
15#ifndef OPENVPN_CLIENT_CLIEVENT_H
16#define OPENVPN_CLIENT_CLIEVENT_H
17
18#include <sstream>
19#include <deque>
20#include <utility>
21
24#include <openvpn/common/rc.hpp>
26
27#ifdef HAVE_JSON
29#endif
30
98
99enum
100{
101 NONFATAL_ERROR_START = TRANSPORT_ERROR, // start of nonfatal errors that automatically reconnect
102 FATAL_ERROR_START = AUTH_FAILED, // start of fatal errors
103};
104
105inline const char *event_name(const Type type)
106{
107 static const char *names[] = {
108 "DISCONNECTED",
109 "CONNECTED",
110 "RECONNECTING",
111 "AUTH_PENDING",
112 "RESOLVE",
113 "WAIT",
114 "WAIT_PROXY",
115 "CONNECTING",
116 "GET_CONFIG",
117 "ASSIGN_IP",
118 "ADD_ROUTES",
119 "ECHO",
120 "INFO",
121 "CUSTOM_CONTROL",
122#ifdef HAVE_JSON
123 "INFO_JSON",
124#endif
125 "WARN",
126 "PAUSE",
127 "RESUME",
128 "RELAY",
129 "COMPRESSION_ENABLED",
130 "UNSUPPORTED_FEATURE",
131
132 // nonfatal errors
133 "TRANSPORT_ERROR",
134 "TUN_ERROR",
135 "CLIENT_RESTART",
136
137 // fatal errors
138 "AUTH_FAILED",
139 "CERT_VERIFY_FAIL",
140 "TLS_VERSION_MIN",
141 "TLS_ALERT_PROTOCOL_VERSION",
142 "TLS_ALERT_UNKNOWN_CA",
143 "TLS_ALERT_MISC",
144 "TLS_ALERT_HANDSHAKE_FAILURE",
145 "TLS_ALERT_CERTIFICATE_EXPIRED",
146 "TLS_ALERT_CERTIFICATE_REVOKED",
147 "TLS_ALERT_BAD_CERTIFICATE",
148 "TLS_ALERT_UNSUPPORTED_CERTIFICATE",
149 "TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED",
150 "CLIENT_HALT",
151 "CLIENT_SETUP",
152 "TUN_HALT",
153 "CONNECTION_TIMEOUT",
154 "INACTIVE_TIMEOUT",
155 "DYNAMIC_CHALLENGE",
156 "PROXY_NEED_CREDS",
157 "PROXY_ERROR",
158 "TUN_SETUP_FAILED",
159 "TUN_IFACE_CREATE",
160 "TUN_IFACE_DISABLED",
161 "EPKI_ERROR",
162 "EPKI_INVALID_ALIAS",
163 "RELAY_ERROR",
164 "COMPRESS_ERROR",
165 "NTLM_MISSING_CRYPTO",
166 "SESSION_EXPIRED",
167 "NEED_CREDS"};
168
169 static_assert(N_TYPES == array_size(names), "event names array inconsistency");
170 if (type < N_TYPES)
171 return names[type];
172 return "UNKNOWN_EVENT_TYPE";
173}
174
175struct Connected;
176
177// The base class for all events.
178class Base : public RC<thread_safe_refcount>
179{
180 public:
182 virtual ~Base() = default;
184 : id_(id)
185 {
186 }
187
188 Type id() const
189 {
190 return id_;
191 }
192
193 const char *name() const
194 {
195 return event_name(id_);
196 }
197
198 bool is_error() const
199 {
200 return int(id_) >= NONFATAL_ERROR_START;
201 }
202
203 bool is_fatal() const
204 {
205 return int(id_) >= FATAL_ERROR_START;
206 }
207
208 virtual std::string render() const
209 {
210 return "";
211 }
212
214 {
215 if (id_ == CONNECTED)
216 return (const Connected *)this;
217 return nullptr;
218 }
219
220 private:
222};
223
224// Specific client events. Some events have no additional data attached to them,
225// while other events (such as Connected) have many additional data fields.
226
227struct Resolve : public Base
228{
230 : Base(RESOLVE)
231 {
232 }
233};
234
235struct Wait : public Base
236{
238 : Base(WAIT)
239 {
240 }
241};
242
243struct WaitProxy : public Base
244{
247 {
248 }
249};
250
251struct Connecting : public Base
252{
255 {
256 }
257};
258
259struct Reconnecting : public Base
260{
263 {
264 }
265};
266
267struct GetConfig : public Base
268{
271 {
272 }
273};
274
275struct AssignIP : public Base
276{
278 : Base(ASSIGN_IP)
279 {
280 }
281};
282
283struct AddRoutes : public Base
284{
287 {
288 }
289};
290
291struct Resume : public Base
292{
294 : Base(RESUME)
295 {
296 }
297};
298
299struct Relay : public Base
300{
302 : Base(RELAY)
303 {
304 }
305};
306
307struct Disconnected : public Base
308{
311 {
312 }
313};
314
315struct ConnectionTimeout : public Base
316{
321};
322
323struct InactiveTimeout : public Base
324{
329};
330
331struct TLSMinVersion : public Base
332{
335 {
336 }
337};
338
339struct TLSVersionMinFail : public Base
340{
345};
346
354
362
370
378
386
394
402
410
411
412
413#ifdef HAVE_JSON
414
415struct InfoJSON : public Base
416{
418
419 InfoJSON(std::string msg_type_arg,
420 Json::Value jdata_arg)
421 : Base(INFO_JSON),
422 msg_type(std::move(msg_type_arg)),
423 jdata(std::move(jdata_arg))
424 {
425 }
426
427 virtual std::string render() const
428 {
431 buf_append_string(buf, ":");
433 return buf_to_string(buf);
434 }
435
436 std::string msg_type;
437 Json::Value jdata;
438};
439
440#endif
441
443{
445
446 UnsupportedFeature(const std::string &name_arg, const std::string &reason_arg, bool critical_arg)
448 name(name_arg),
449 reason(reason_arg),
450 critical(critical_arg)
451 {
452 }
453
454 std::string name;
455 std::string reason;
457
458 std::string render() const override
459 {
460 std::ostringstream out;
461 out << "name: " << name << ", reason: " << reason << ", critical: " << critical;
462 return out.str();
463 }
464};
465
466struct Connected : public Base
467{
469
471 : Base(CONNECTED)
472 {
473 }
474
475 std::string user;
476 std::string server_host;
477 std::string server_port;
478 std::string server_proto;
479 std::string server_ip;
480 std::string vpn_ip4;
481 std::string vpn_ip6;
482 std::string vpn_gw4;
483 std::string vpn_gw6;
484 std::string vpn_mtu;
485 std::string client_ip;
486 std::string tun_name;
487 std::uint32_t vpn_interface_index = static_cast<uint32_t>(-1);
488
489 std::string render() const override
490 {
491 std::ostringstream out;
492 // eg. "godot@foo.bar.gov:443 (1.2.3.4) via TCPv4 on tun0/5.5.1.1"
493 if (!user.empty())
494 out << user << '@';
495 if (server_host.find_first_of(':') == std::string::npos)
496 out << server_host;
497 else
498 out << '[' << server_host << ']';
499 out << ':' << server_port
500 << " (" << server_ip << ") via " << client_ip << '/' << server_proto
501 << " on " << tun_name << '/' << vpn_ip4 << '/' << vpn_ip6
502 << " gw=[" << vpn_gw4 << '/' << vpn_gw6 << ']'
503 << " mtu=" << vpn_mtu;
504 if (vpn_interface_index != static_cast<uint32_t>(-1))
505 out << " vpn_interface_index=" << vpn_interface_index;
506 return out.str();
507 }
508};
509
510struct NeedCreds : public Base
511{
514 {
515 }
516};
517
518struct ReasonBase : public Base
519{
520 ReasonBase(const Type id, const std::string &reason_arg)
521 : Base(id),
522 reason(reason_arg)
523 {
524 }
525
526 ReasonBase(const Type id, std::string &&reason_arg)
527 : Base(id),
528 reason(std::move(reason_arg))
529 {
530 }
531
532 std::string render() const override
533 {
534 return reason;
535 }
536
537 std::string reason;
538};
539
540/* thrown if no other of the TLSAlert* events are matching */
542{
543 TLSAlertMisc(std::string reason)
544 : ReasonBase(TLS_ALERT_MISC, std::move(reason))
545 {
546 }
547};
548
549struct AuthFailed : public ReasonBase
550{
551 AuthFailed(std::string reason)
552 : ReasonBase(AUTH_FAILED, std::move(reason))
553 {
554 }
555};
556
558{
560 : ReasonBase(SESSION_EXPIRED, std::move(reason))
561 {
562 }
563};
564
566{
568 : ReasonBase(CERT_VERIFY_FAIL, std::move(reason))
569 {
570 }
571};
572
573struct ClientHalt : public ReasonBase
574{
575 ClientHalt(std::string reason)
576 : ReasonBase(CLIENT_HALT, std::move(reason))
577 {
578 }
579};
580
582{
584 : ReasonBase(CLIENT_RESTART, std::move(reason))
585 {
586 }
587};
588
589struct TunHalt : public ReasonBase
590{
591 TunHalt(std::string reason)
592 : ReasonBase(TUN_HALT, std::move(reason))
593 {
594 }
595};
596
597struct RelayError : public ReasonBase
598{
599 RelayError(std::string reason)
600 : ReasonBase(RELAY_ERROR, std::move(reason))
601 {
602 }
603};
604
606{
608 : ReasonBase(COMPRESS_ERROR, std::move(reason))
609 {
610 }
611};
612
614{
616 : ReasonBase(DYNAMIC_CHALLENGE, std::move(reason))
617 {
618 }
619};
620
621struct Pause : public ReasonBase
622{
623 Pause(std::string reason)
624 : ReasonBase(PAUSE, std::move(reason))
625 {
626 }
627};
628
629struct ProxyError : public ReasonBase
630{
631 ProxyError(std::string reason)
632 : ReasonBase(PROXY_ERROR, std::move(reason))
633 {
634 }
635};
636
638{
641 {
642 }
643};
644
645
647{
649 : ReasonBase(PROXY_NEED_CREDS, std::move(reason))
650 {
651 }
652};
653
655{
657 : ReasonBase(TRANSPORT_ERROR, std::move(reason))
658 {
659 }
660};
661
663{
665 : ReasonBase(TUN_SETUP_FAILED, std::move(reason))
666 {
667 }
668};
669
671{
673 : ReasonBase(TUN_IFACE_CREATE, std::move(reason))
674 {
675 }
676};
677
679{
682 {
683 }
684};
685
686struct TunError : public ReasonBase
687{
688 TunError(std::string reason)
689 : ReasonBase(TUN_ERROR, std::move(reason))
690 {
691 }
692};
693
694struct EpkiError : public ReasonBase
695{
696 EpkiError(std::string reason)
697 : ReasonBase(EPKI_ERROR, std::move(reason))
698 {
699 }
700};
701
703{
706 {
707 }
708};
709
710struct Echo : public ReasonBase
711{
712 Echo(std::string value)
713 : ReasonBase(ECHO_OPT, std::move(value))
714 {
715 }
716};
717
718struct Info : public ReasonBase
719{
720 Info(std::string value)
721 : ReasonBase(INFO, std::move(value))
722 {
723 }
724};
725
730{
731 AppCustomControlMessage(std::string protocol, std::string message)
732 : Base(CUSTOM_CONTROL), protocol(std::move(protocol)), custommessage(std::move(message))
733 {
734 }
735 std::string protocol;
736 std::string custommessage;
737};
738
739struct AuthPending : public ReasonBase
740{
742 AuthPending(int timeout, std::string value)
743 : ReasonBase(AUTH_PENDING, std::move(value)), timeout(timeout)
744 {
745 }
746};
747
748struct Warn : public ReasonBase
749{
750 Warn(std::string value)
751 : ReasonBase(WARN, std::move(value))
752 {
753 }
754};
755
757{
758 public:
759 ClientSetup(const std::string &status, const std::string &message)
761 {
762 }
763
764 private:
765 static std::string make(const std::string &status, const std::string &message)
766 {
767 std::string ret;
768 ret += status;
769 if (!status.empty() && !message.empty())
770 ret += ": ";
771 ret += message;
772 return ret;
773 }
774};
775
777{
779 : ReasonBase(COMPRESSION_ENABLED, std::move(msg))
780 {
781 }
782};
783
784class Queue : public RC<thread_unsafe_refcount>
785{
786 public:
788
789 virtual void add_event(Base::Ptr event) = 0;
790};
791} // namespace openvpn::ClientEvent
792
793#endif // OPENVPN_CLIENT_CLIEVENT_H
const Connected * connected_cast() const
Definition clievent.hpp:213
virtual ~Base()=default
virtual std::string render() const
Definition clievent.hpp:208
const char * name() const
Definition clievent.hpp:193
static std::string make(const std::string &status, const std::string &message)
Definition clievent.hpp:765
ClientSetup(const std::string &status, const std::string &message)
Definition clievent.hpp:759
virtual void add_event(Base::Ptr event)=0
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:908
constexpr BufferFlags GROW(1U<< 2)
if enabled, buffer will grow (otherwise buffer_full exception will be thrown)
const char * event_name(const Type type)
Definition clievent.hpp:105
@ TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED
Definition clievent.hpp:76
void format_compact(const Json::Value &root, Buffer &buf)
constexpr std::size_t array_size(T(&)[N])
Definition arraysize.hpp:19
void buf_append_string(Buffer &buf, const std::string &str)
Definition bufstr.hpp:82
std::string buf_to_string(const Buffer &buf)
Definition bufstr.hpp:22
AppCustomControlMessage(std::string protocol, std::string message)
Definition clievent.hpp:731
AuthFailed(std::string reason)
Definition clievent.hpp:551
AuthPending(int timeout, std::string value)
Definition clievent.hpp:742
ClientHalt(std::string reason)
Definition clievent.hpp:575
ClientRestart(std::string reason)
Definition clievent.hpp:583
CompressError(std::string reason)
Definition clievent.hpp:607
std::string render() const override
Definition clievent.hpp:489
Echo(std::string value)
Definition clievent.hpp:712
EpkiError(std::string reason)
Definition clievent.hpp:696
InfoJSON(std::string msg_type_arg, Json::Value jdata_arg)
Definition clievent.hpp:419
virtual std::string render() const
Definition clievent.hpp:427
Info(std::string value)
Definition clievent.hpp:720
Pause(std::string reason)
Definition clievent.hpp:623
ProxyError(std::string reason)
Definition clievent.hpp:631
std::string render() const override
Definition clievent.hpp:532
ReasonBase(const Type id, const std::string &reason_arg)
Definition clievent.hpp:520
ReasonBase(const Type id, std::string &&reason_arg)
Definition clievent.hpp:526
RelayError(std::string reason)
Definition clievent.hpp:599
TLSAlertMisc(std::string reason)
Definition clievent.hpp:543
TunError(std::string reason)
Definition clievent.hpp:688
TunHalt(std::string reason)
Definition clievent.hpp:591
std::string render() const override
Definition clievent.hpp:458
UnsupportedFeature(const std::string &name_arg, const std::string &reason_arg, bool critical_arg)
Definition clievent.hpp:446
Warn(std::string value)
Definition clievent.hpp:750
std::string ret
static std::stringstream out
Definition test_path.cpp:10
const char message[]
#define msg(flags,...)