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 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: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:765
ClientSetup(const std::string &status, const std::string &message)
Definition clievent.hpp:759
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: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:491
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:421
virtual std::string render() const
Definition clievent.hpp:429
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: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:750
std::string ret
static std::stringstream out
Definition test_path.cpp:10
const char message[]
#define msg(flags,...)