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 else
173 return "UNKNOWN_EVENT_TYPE";
174}
175
176struct Connected;
177
178// The base class for all events.
179class Base : public RC<thread_safe_refcount>
180{
181 public:
183 virtual ~Base() = default;
185 : id_(id)
186 {
187 }
188
189 Type id() const
190 {
191 return id_;
192 }
193
194 const char *name() const
195 {
196 return event_name(id_);
197 }
198
199 bool is_error() const
200 {
201 return int(id_) >= NONFATAL_ERROR_START;
202 }
203
204 bool is_fatal() const
205 {
206 return int(id_) >= FATAL_ERROR_START;
207 }
208
209 virtual std::string render() const
210 {
211 return "";
212 }
213
215 {
216 if (id_ == CONNECTED)
217 return (const Connected *)this;
218 else
219 return nullptr;
220 }
221
222 private:
224};
225
226// Specific client events. Some events have no additional data attached to them,
227// while other events (such as Connected) have many additional data fields.
228
229struct Resolve : public Base
230{
232 : Base(RESOLVE)
233 {
234 }
235};
236
237struct Wait : public Base
238{
240 : Base(WAIT)
241 {
242 }
243};
244
245struct WaitProxy : public Base
246{
249 {
250 }
251};
252
253struct Connecting : public Base
254{
257 {
258 }
259};
260
261struct Reconnecting : public Base
262{
265 {
266 }
267};
268
269struct GetConfig : public Base
270{
273 {
274 }
275};
276
277struct AssignIP : public Base
278{
280 : Base(ASSIGN_IP)
281 {
282 }
283};
284
285struct AddRoutes : public Base
286{
289 {
290 }
291};
292
293struct Resume : public Base
294{
296 : Base(RESUME)
297 {
298 }
299};
300
301struct Relay : public Base
302{
304 : Base(RELAY)
305 {
306 }
307};
308
309struct Disconnected : public Base
310{
313 {
314 }
315};
316
317struct ConnectionTimeout : public Base
318{
323};
324
325struct InactiveTimeout : public Base
326{
331};
332
333struct TLSMinVersion : public Base
334{
337 {
338 }
339};
340
341struct TLSVersionMinFail : public Base
342{
347};
348
356
364
372
380
388
396
404
412
413
414
415#ifdef HAVE_JSON
416
417struct InfoJSON : public Base
418{
420
421 InfoJSON(std::string msg_type_arg,
422 Json::Value jdata_arg)
423 : Base(INFO_JSON),
424 msg_type(std::move(msg_type_arg)),
425 jdata(std::move(jdata_arg))
426 {
427 }
428
429 virtual std::string render() const
430 {
433 buf_append_string(buf, ":");
435 return buf_to_string(buf);
436 }
437
438 std::string msg_type;
439 Json::Value jdata;
440};
441
442#endif
443
445{
447
448 UnsupportedFeature(const std::string &name_arg, const std::string &reason_arg, bool critical_arg)
450 name(name_arg),
451 reason(reason_arg),
452 critical(critical_arg)
453 {
454 }
455
456 std::string name;
457 std::string reason;
459
460 std::string render() const override
461 {
462 std::ostringstream out;
463 out << "name: " << name << ", reason: " << reason << ", critical: " << critical;
464 return out.str();
465 }
466};
467
468struct Connected : public Base
469{
471
473 : Base(CONNECTED)
474 {
475 }
476
477 std::string user;
478 std::string server_host;
479 std::string server_port;
480 std::string server_proto;
481 std::string server_ip;
482 std::string vpn_ip4;
483 std::string vpn_ip6;
484 std::string vpn_gw4;
485 std::string vpn_gw6;
486 std::string vpn_mtu;
487 std::string client_ip;
488 std::string tun_name;
489 std::uint32_t vpn_interface_index = static_cast<uint32_t>(-1);
490
491 std::string render() const override
492 {
493 std::ostringstream out;
494 // eg. "godot@foo.bar.gov:443 (1.2.3.4) via TCPv4 on tun0/5.5.1.1"
495 if (!user.empty())
496 out << user << '@';
497 if (server_host.find_first_of(':') == std::string::npos)
498 out << server_host;
499 else
500 out << '[' << server_host << ']';
501 out << ':' << server_port
502 << " (" << server_ip << ") via " << client_ip << '/' << server_proto
503 << " on " << tun_name << '/' << vpn_ip4 << '/' << vpn_ip6
504 << " gw=[" << vpn_gw4 << '/' << vpn_gw6 << ']'
505 << " mtu=" << vpn_mtu;
506 if (vpn_interface_index != static_cast<uint32_t>(-1))
507 out << " vpn_interface_index=" << vpn_interface_index;
508 return out.str();
509 }
510};
511
512struct NeedCreds : public Base
513{
516 {
517 }
518};
519
520struct ReasonBase : public Base
521{
522 ReasonBase(const Type id, const std::string &reason_arg)
523 : Base(id),
524 reason(reason_arg)
525 {
526 }
527
528 ReasonBase(const Type id, std::string &&reason_arg)
529 : Base(id),
530 reason(std::move(reason_arg))
531 {
532 }
533
534 std::string render() const override
535 {
536 return reason;
537 }
538
539 std::string reason;
540};
541
542/* thrown if no other of the TLSAlert* events are matching */
544{
545 TLSAlertMisc(std::string reason)
546 : ReasonBase(TLS_ALERT_MISC, std::move(reason))
547 {
548 }
549};
550
551struct AuthFailed : public ReasonBase
552{
553 AuthFailed(std::string reason)
554 : ReasonBase(AUTH_FAILED, std::move(reason))
555 {
556 }
557};
558
560{
562 : ReasonBase(SESSION_EXPIRED, std::move(reason))
563 {
564 }
565};
566
568{
570 : ReasonBase(CERT_VERIFY_FAIL, std::move(reason))
571 {
572 }
573};
574
575struct ClientHalt : public ReasonBase
576{
577 ClientHalt(std::string reason)
578 : ReasonBase(CLIENT_HALT, std::move(reason))
579 {
580 }
581};
582
584{
586 : ReasonBase(CLIENT_RESTART, std::move(reason))
587 {
588 }
589};
590
591struct TunHalt : public ReasonBase
592{
593 TunHalt(std::string reason)
594 : ReasonBase(TUN_HALT, std::move(reason))
595 {
596 }
597};
598
599struct RelayError : public ReasonBase
600{
601 RelayError(std::string reason)
602 : ReasonBase(RELAY_ERROR, std::move(reason))
603 {
604 }
605};
606
608{
610 : ReasonBase(COMPRESS_ERROR, std::move(reason))
611 {
612 }
613};
614
616{
618 : ReasonBase(DYNAMIC_CHALLENGE, std::move(reason))
619 {
620 }
621};
622
623struct Pause : public ReasonBase
624{
625 Pause(std::string reason)
626 : ReasonBase(PAUSE, std::move(reason))
627 {
628 }
629};
630
631struct ProxyError : public ReasonBase
632{
633 ProxyError(std::string reason)
634 : ReasonBase(PROXY_ERROR, std::move(reason))
635 {
636 }
637};
638
640{
643 {
644 }
645};
646
647
649{
651 : ReasonBase(PROXY_NEED_CREDS, std::move(reason))
652 {
653 }
654};
655
657{
659 : ReasonBase(TRANSPORT_ERROR, std::move(reason))
660 {
661 }
662};
663
665{
667 : ReasonBase(TUN_SETUP_FAILED, std::move(reason))
668 {
669 }
670};
671
673{
675 : ReasonBase(TUN_IFACE_CREATE, std::move(reason))
676 {
677 }
678};
679
681{
684 {
685 }
686};
687
688struct TunError : public ReasonBase
689{
690 TunError(std::string reason)
691 : ReasonBase(TUN_ERROR, std::move(reason))
692 {
693 }
694};
695
696struct EpkiError : public ReasonBase
697{
698 EpkiError(std::string reason)
699 : ReasonBase(EPKI_ERROR, std::move(reason))
700 {
701 }
702};
703
705{
708 {
709 }
710};
711
712struct Echo : public ReasonBase
713{
714 Echo(std::string value)
715 : ReasonBase(ECHO_OPT, std::move(value))
716 {
717 }
718};
719
720struct Info : public ReasonBase
721{
722 Info(std::string value)
723 : ReasonBase(INFO, std::move(value))
724 {
725 }
726};
727
732{
733 AppCustomControlMessage(std::string protocol, std::string message)
734 : Base(CUSTOM_CONTROL), protocol(std::move(protocol)), custommessage(std::move(message))
735 {
736 }
737 std::string protocol;
738 std::string custommessage;
739};
740
741struct AuthPending : public ReasonBase
742{
744 AuthPending(int timeout, std::string value)
745 : ReasonBase(AUTH_PENDING, std::move(value)), timeout(timeout)
746 {
747 }
748};
749
750struct Warn : public ReasonBase
751{
752 Warn(std::string value)
753 : ReasonBase(WARN, std::move(value))
754 {
755 }
756};
757
759{
760 public:
761 ClientSetup(const std::string &status, const std::string &message)
763 {
764 }
765
766 private:
767 static std::string make(const std::string &status, const std::string &message)
768 {
769 std::string ret;
770 ret += status;
771 if (!status.empty() && !message.empty())
772 ret += ": ";
773 ret += message;
774 return ret;
775 }
776};
777
779{
781 : ReasonBase(COMPRESSION_ENABLED, std::move(msg))
782 {
783 }
784};
785
786class Queue : public RC<thread_unsafe_refcount>
787{
788 public:
790
791 virtual void add_event(Base::Ptr event) = 0;
792};
793} // namespace openvpn::ClientEvent
794
795#endif // OPENVPN_CLIENT_CLIEVENT_H
const Connected * connected_cast() const
Definition clievent.hpp:214
virtual ~Base()=default
virtual std::string render() const
Definition clievent.hpp:209
const char * name() const
Definition clievent.hpp:194
static std::string make(const std::string &status, const std::string &message)
Definition clievent.hpp:767
ClientSetup(const std::string &status, const std::string &message)
Definition clievent.hpp:761
virtual void add_event(Base::Ptr event)=0
The smart pointer class.
Definition rc.hpp:119
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:912
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:733
AuthFailed(std::string reason)
Definition clievent.hpp:553
AuthPending(int timeout, std::string value)
Definition clievent.hpp:744
ClientHalt(std::string reason)
Definition clievent.hpp:577
ClientRestart(std::string reason)
Definition clievent.hpp:585
CompressError(std::string reason)
Definition clievent.hpp:609
std::string render() const override
Definition clievent.hpp:491
Echo(std::string value)
Definition clievent.hpp:714
EpkiError(std::string reason)
Definition clievent.hpp:698
InfoJSON(std::string msg_type_arg, Json::Value jdata_arg)
Definition clievent.hpp:421
virtual std::string render() const
Definition clievent.hpp:429
Info(std::string value)
Definition clievent.hpp:722
Pause(std::string reason)
Definition clievent.hpp:625
ProxyError(std::string reason)
Definition clievent.hpp:633
std::string render() const override
Definition clievent.hpp:534
ReasonBase(const Type id, const std::string &reason_arg)
Definition clievent.hpp:522
ReasonBase(const Type id, std::string &&reason_arg)
Definition clievent.hpp:528
RelayError(std::string reason)
Definition clievent.hpp:601
TLSAlertMisc(std::string reason)
Definition clievent.hpp:545
TunError(std::string reason)
Definition clievent.hpp:690
TunHalt(std::string reason)
Definition clievent.hpp:593
std::string render() const override
Definition clievent.hpp:460
RCPtr< UnsupportedFeature > Ptr
Definition clievent.hpp:446
UnsupportedFeature(const std::string &name_arg, const std::string &reason_arg, bool critical_arg)
Definition clievent.hpp:448
Warn(std::string value)
Definition clievent.hpp:752
std::string ret
static std::stringstream out
Definition test_path.cpp:10
const char message[]
#define msg(flags,...)