OpenVPN 3 Core Library
Loading...
Searching...
No Matches
httpcli.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// HTTP proxy transport object.
13
14#ifndef OPENVPN_TRANSPORT_CLIENT_HTTPCLI_H
15#define OPENVPN_TRANSPORT_CLIENT_HTTPCLI_H
16
17#include <vector>
18#include <string>
19#include <sstream>
20#include <algorithm> // for std::min
21#include <memory>
22
23#include <openvpn/io/io.hpp>
24
47
49
58
59class Options : public RC<thread_safe_refcount>
60{
61 public:
62 struct CustomHeader : public RC<thread_unsafe_refcount>
63 {
65
66 std::string p1;
67 std::string p2;
68 };
69
70 struct CustomHeaderList : public std::vector<CustomHeader::Ptr>
71 {
72 };
73
75
77 std::string username;
78 std::string password;
81
82 std::string http_version;
83 std::string user_agent;
84
86
87 void set_proxy_server(const std::string &host, const std::string &port)
88 {
89 proxy_server.reset(new RemoteList(host, port, Protocol(Protocol::TCP), "http proxy port"));
90 }
91
92 void proxy_server_set_enable_cache(const bool enable_cache)
93 {
94 proxy_server->set_enable_cache(enable_cache);
95 }
96
102
103 static Ptr parse(const OptionList &opt)
104 {
105 if (opt.exists("http-proxy"))
106 {
107 Ptr obj(new Options);
108 if (obj->parse_options(opt))
109 return obj;
110 }
111 return Ptr();
112 }
113
114 private:
115 bool parse_options(const OptionList &opt)
116 {
117 const Option *hp = opt.get_ptr("http-proxy");
118 if (hp)
119 {
120 // get server/port
121 set_proxy_server(hp->get(1, 256), hp->get(2, 16));
122
123 // get creds
124 UserPass::parse(opt, "http-proxy-user-pass", 0, username, password);
125
126 const std::string auth = hp->get_optional(3, 16);
127 if (!auth.empty())
128 {
129 if (auth == "auto")
130 {
133 }
134 else if (auth == "auto-nct")
135 {
136 allow_cleartext_auth = false;
138 }
139 else if (auth == "basic")
140 {
143 }
144 else if (auth == "digest")
145 {
146 allow_cleartext_auth = false;
148 }
149 else if (auth == "ntlm")
150 {
151 allow_cleartext_auth = false;
153 }
154 else if (auth == "none")
155 {
157 }
158 else
159 {
160 throw Exception("Unsupported HTTP proxy auth method: " + auth);
161 }
162 }
163
164 // get options
165 const OptionList::IndexList *hpo = opt.get_index_ptr("http-proxy-option");
166 if (hpo)
167 {
168 for (OptionList::IndexList::const_iterator i = hpo->begin(); i != hpo->end(); ++i)
169 {
170 const Option &o = opt[*i];
171 const std::string &type = o.get(1, 64);
172 if (type == "VERSION")
173 {
174 http_version = o.get(2, 16);
175 o.touch();
176 }
177 else if (type == "AGENT")
178 {
179 user_agent = o.get(2, 256);
180 o.touch();
181 }
182 else if (type == "EXT1" || type == "EXT2" || type == "CUSTOM-HEADER")
183 {
185 h->p1 = o.get(2, 512);
186 h->p2 = o.get_optional(3, 512);
187 headers.push_back(h);
188 o.touch();
189 }
190 }
191 }
192 return true;
193 }
194 return false;
195 }
196};
197
199{
200 public:
202
207
209
210 StrongRandomAPI::Ptr rng; // random data source
211
212 DigestFactory::Ptr digest_factory; // needed by proxy auth methods
213
215
217
218 static Ptr new_obj()
219 {
220 return new ClientConfig;
221 }
222
223 TransportClient::Ptr new_transport_client_obj(openvpn_io::io_context &io_context,
224 TransportClientParent *parent) override;
225
226 private:
229 socket_protect(nullptr),
230 skip_html(false)
231 {
232 }
233};
234
236{
238
240
241 friend class ClientConfig; // calls constructor
242 friend LinkImpl::Base; // calls tcp_read_handler
243
244 public:
245 void transport_start() override
246 {
247 if (!impl)
248 {
249 if (!config->http_proxy_options)
250 {
251 parent->proxy_error(Error::PROXY_ERROR, "http_proxy_options not defined");
252 return;
253 }
254
255 halt = false;
256
257 // Get target server host:port. We don't care about resolving it
258 // since proxy server will do that for us.
260
261 // Get proxy server host:port, and resolve it if not already cached
262 if (proxy_remote_list().endpoint_available(&proxy_host, &proxy_port, nullptr))
263 {
264 // already cached
266 }
267 else
268 {
269 // resolve it
271
274 }
275 }
276 }
277
278 bool transport_send_const(const Buffer &buf) override
279 {
280 return send_const(buf);
281 }
282
283 bool transport_send(BufferAllocated &buf) override
284 {
285 return send(buf);
286 }
287
289 {
290 if (impl)
291 return impl->send_queue_empty();
292 return false;
293 }
294
296 {
297 return true;
298 }
299
301 {
302 }
303
305 {
306 if (impl)
307 return impl->send_queue_size();
308 return 0;
309 }
310
311 void reset_align_adjust(const size_t align_adjust) override
312 {
313 if (impl)
314 impl->reset_align_adjust(align_adjust);
315 }
316
317 void server_endpoint_info(std::string &host, std::string &port, std::string &proto, std::string &ip_addr) const override
318 {
321 const IP::Addr addr = server_endpoint_addr();
322 proto = "TCP";
323 proto += addr.version_string();
324 proto += "-via-HTTP";
325 ip_addr = addr.to_string();
326 }
327
329 {
330 return IP::Addr::from_asio(server_endpoint.address());
331 }
332
334 {
335 if (server_endpoint.address().is_v4())
337 if (server_endpoint.address().is_v6())
339 return Protocol();
340 }
341
342 void stop() override
343 {
344 stop_();
345 }
346 virtual ~Client()
347 {
348 stop_();
349 }
350
351 private:
352 struct ProxyResponseLimit : public BufferLimit<size_t>
353 {
355 : BufferLimit(1024, 65536)
356 {
357 }
358
359 void bytes_exceeded() override
360 {
361 OPENVPN_THROW_EXCEPTION("HTTP proxy response too large (> " << max_bytes << " bytes)");
362 }
363
364 void lines_exceeded() override
365 {
366 OPENVPN_THROW_EXCEPTION("HTTP proxy response too large (> " << max_lines << " lines)");
367 }
368 };
369
370 Client(openvpn_io::io_context &io_context_arg,
371 ClientConfig *config_arg,
372 TransportClientParent *parent_arg)
373 : AsyncResolvableTCP(io_context_arg),
374 socket(io_context_arg),
375 config(config_arg),
376 parent(parent_arg),
377 halt(false),
379 proxy_established(false),
380 http_reply_status(HTTP::ReplyParser::pending),
383 {
384 }
385
386 void transport_reparent(TransportClientParent *parent_arg) override
387 {
388 parent = parent_arg;
389 }
390
391 bool send_const(const Buffer &cbuf)
392 {
393 if (impl)
394 {
395 BufferAllocated buf(cbuf);
396 return impl->send(buf);
397 }
398 return false;
399 }
400
402 {
403 if (impl)
404 return impl->send(buf);
405 return false;
406 }
407
408 void tcp_error_handler(const char *error) // called by LinkImpl and internally
409 {
410 std::ostringstream os;
411 os << "Transport error on '" << server_host << "' via HTTP proxy " << proxy_host << ':' << proxy_port << " : " << error;
412 stop();
414 }
415
416 void proxy_error(const Error::Type fatal_err, const std::string &what)
417 {
418 std::ostringstream os;
419 os << "on " << proxy_host << ':' << proxy_port << ": " << what;
420 stop();
421 parent->proxy_error(fatal_err, os.str());
422 }
423
424 bool tcp_read_handler(BufferAllocated &buf) // called by LinkImpl
425 {
427 {
428 if (!html_skip)
430 else
431 drain_html(buf); // skip extraneous HTML after header
432 }
433 else
434 {
435 try
436 {
438 }
439 catch (const std::exception &e)
440 {
442 }
443 }
444 return true;
445 }
446
447 void tcp_write_queue_needs_send() // called by LinkImpl
448 {
451 }
452
453 void tcp_eof_handler() // called by LinkImpl
454 {
456 {
457 config->stats->error(Error::NETWORK_EOF_ERROR);
458 tcp_error_handler("NETWORK_EOF_ERROR");
459 }
460 else
461 {
462 try
463 {
465 }
466 catch (const std::exception &e)
467 {
469 }
470 }
471 }
472
474 {
475 // for anti-DoS, only allow a maximum number of chars in HTTP response
477
479 {
480 OPENVPN_LOG_NTNL("FROM PROXY: " << buf_to_string(buf));
481 for (size_t i = 0; i < buf.size(); ++i)
482 {
485 {
486 buf.advance(i + 1);
488 {
489 // OPENVPN_LOG("*** HTTP header parse complete, resid_size=" << buf.size());
490 // OPENVPN_LOG(http_reply.to_string());
491
492 // we are connected, switch socket to tunnel mode
494 {
495 if (config->skip_html)
496 {
498 html_skip.reset(new HTTP::HTMLSkip());
499 drain_html(buf);
500 }
501 else
502 proxy_connected(buf, true);
503 }
506 }
507 else
508 {
509 throw Exception("HTTP proxy header parse error");
510 }
511 break;
512 }
513 }
514 }
515
516 // handle draining of content controlled by Content-length header
518 {
519 const size_t drain = std::min(drain_content_length, buf.size());
520 buf.advance(drain);
521 drain_content_length -= drain;
523 {
526 }
527 }
528 }
529
530 void proxy_connected(BufferAllocated &buf, const bool notify_parent)
531 {
532 proxy_established = true;
534 {
535 // switch socket from HTTP proxy handshake mode to OpenVPN protocol mode
536 impl->set_raw_mode(false);
537 if (notify_parent)
539 try
540 {
541 impl->inject(buf);
542 }
543 catch (const std::exception &e)
544 {
545 proxy_error(Error::PROXY_ERROR, std::string("post-header inject error: ") + e.what());
546 return;
547 }
548 }
549 else
550 {
551 if (notify_parent)
554 }
555 }
556
557 // Called after header received but before possible extraneous HTML
558 // is drained. At this point, we are in a state where output data
559 // (if OpenVPN protocol) is packetized, but input data is still in
560 // raw mode as we search the input stream for the end of the
561 // extraneous HTML. When we reach the beginning of payload data,
562 // proxy_connected() should be called with notify_parent == false.
564 {
565 proxy_established = true;
567 impl->set_raw_mode_write(false);
569 }
570
572 {
573 while (!buf.empty())
574 {
575 switch (html_skip->add(buf.pop_front()))
576 {
579 {
580 OPENVPN_LOG("Proxy: Skipped " << html_skip->n_bytes() << " byte(s) of HTML");
581 html_skip->get_residual(buf);
582 html_skip.reset();
583 proxy_connected(buf, false);
584 return;
585 }
587 break;
588 }
589 }
590 }
591
593 {
594 for (HTTP::HeaderList::const_iterator i = http_reply.headers.begin(); i != http_reply.headers.end(); ++i)
595 {
596 const HTTP::Header &h = *i;
597 if (string::strcasecmp(h.name, "proxy-authenticate") == 0)
598 {
600 if (string::strcasecmp(type, pa->method) == 0)
601 return pa;
602 }
603 }
605 }
606
608 {
610 {
612 {
613 if (config->http_proxy_options->auth_method == None)
614 throw Exception("HTTP proxy authentication is disabled");
615 if (n_transactions > 1)
616 {
617 proxy_error(Error::PROXY_NEED_CREDS, "HTTP proxy credentials were not accepted");
618 return;
619 }
620 if (config->http_proxy_options->username.empty())
621 {
622 proxy_error(Error::PROXY_NEED_CREDS, "HTTP proxy requires credentials");
623 return;
624 }
625
627 const AuthMethod method(config->http_proxy_options->auth_method);
628
629 if (method == Any || method == Ntlm)
630 {
632 if (pa)
633 {
635 return;
636 }
637 }
638
639 if (method == Any || method == Digest)
640 {
641 pa = get_proxy_authenticate_header("digest");
642 if (pa)
643 {
644 digest_auth(*pa);
645 return;
646 }
647 }
648
649 if (method == Any || method == Basic)
650 {
651 pa = get_proxy_authenticate_header("basic");
652 if (pa)
653 {
654 if (!config->http_proxy_options->allow_cleartext_auth)
655 throw Exception("HTTP proxy basic authentication not allowed by user preference");
656
657 basic_auth(*pa);
658 return;
659 }
660 }
661
662 throw Exception("HTTP proxy-authenticate method not allowed / supported");
663 }
667 {
668 // this is a nonfatal error, so we pass Error::UNDEF to tell the upper layer to
669 // retry the connection
670 proxy_error(Error::UNDEF, "HTTP proxy server could not connect to OpenVPN server");
671 return;
672 }
674 OPENVPN_THROW_EXCEPTION("HTTP proxy returned Forbidden status code");
675 else
676 OPENVPN_THROW_EXCEPTION("HTTP proxy status code: " << http_reply.status_code);
677 }
679 throw Exception("HTTP proxy unexpected EOF: reply incomplete");
680 else
681 throw Exception("HTTP proxy general error");
682 }
683
685 {
686 OPENVPN_LOG("Proxy method: Basic\n"
687 << pa.to_string());
688
689 std::ostringstream os;
691 os << "Proxy-Authorization: Basic "
692 << base64->encode(config->http_proxy_options->username + ':' + config->http_proxy_options->password)
693 << "\r\n";
694 http_request = os.str();
695 reset();
697 }
698
700 {
701 try
702 {
703 OPENVPN_LOG("Proxy method: Digest\n"
704 << pa.to_string());
705
706 // constants
707 const std::string http_method = "CONNECT";
708 const std::string nonce_count = "00000001";
709 const std::string qop = "auth";
710
711 // get values from Proxy-Authenticate header
712 const std::string realm = pa.parms.get_value("realm");
713 const std::string nonce = pa.parms.get_value("nonce");
714 const std::string algorithm = pa.parms.get_value("algorithm");
715 const std::string opaque = pa.parms.get_value("opaque");
716
717 // generate a client nonce
718 unsigned char cnonce_raw[8];
719 config->rng->rand_bytes(cnonce_raw, sizeof(cnonce_raw));
720 const std::string cnonce = render_hex(cnonce_raw, sizeof(cnonce_raw));
721
722 // build URI
723 const std::string uri = server_host + ":" + server_port;
724
725 // calculate session key
726 const std::string session_key = HTTPProxy::Digest::calcHA1(
727 *config->digest_factory,
728 algorithm,
729 config->http_proxy_options->username,
730 realm,
731 config->http_proxy_options->password,
732 nonce,
733 cnonce);
734
735 // calculate response
736 const std::string response = HTTPProxy::Digest::calcResponse(
737 *config->digest_factory,
738 session_key,
739 nonce,
740 nonce_count,
741 cnonce,
742 qop,
743 http_method,
744 uri,
745 "");
746
747 // generate proxy request
748 std::ostringstream os;
750 os << "Proxy-Authorization: Digest username=\"" << config->http_proxy_options->username << "\", realm=\"" << realm << "\", nonce=\"" << nonce << "\", uri=\"" << uri << "\", qop=" << qop << ", nc=" << nonce_count << ", cnonce=\"" << cnonce << "\", response=\"" << response << "\"";
751 if (!opaque.empty())
752 os << ", opaque=\"" + opaque + "\"";
753 os << "\r\n";
754
755 http_request = os.str();
756 reset();
758 }
759 catch (const std::exception &e)
760 {
761 proxy_error(Error::PROXY_ERROR, std::string("Digest Auth: ") + e.what());
762 }
763 }
764
766 {
767 for (HTTP::HeaderList::const_iterator i = http_reply.headers.begin(); i != http_reply.headers.end(); ++i)
768 {
769 const HTTP::Header &h = *i;
770 if (string::strcasecmp(h.name, "proxy-authenticate") == 0)
771 {
772 std::vector<std::string> v = Split::by_space<std::vector<std::string>, StandardLex, SpaceMatch, Split::NullLimit>(h.value);
773 if (v.size() >= 2 && string::strcasecmp("ntlm", v[0]) == 0)
774 return v[1];
775 }
776 }
777 return "";
778 }
779
781 {
782 OPENVPN_LOG("Proxy method: NTLM\n"
783 << pa.to_string());
784
785 const std::string phase_1_reply = HTTPProxy::NTLM::phase_1();
786
787 std::ostringstream os;
789 os << "Proxy-Connection: Keep-Alive\r\n";
790 os << "Proxy-Authorization: NTLM " << phase_1_reply << "\r\n";
791
792 http_request = os.str();
793 reset();
796 }
797
799 {
800 // if content exists, drain it first, then progress to ntlm_auth_phase_2
801 const std::string content_length_str = http_reply.headers.get_value_trim("content-length");
802 const unsigned int content_length = parse_number_throw<unsigned int>(content_length_str, "content-length");
803 if (content_length)
804 drain_content_length = content_length;
805 else
807 }
808
810 {
812
814 throw Exception("NTLM phase-2 status is not ProxyAuthenticationRequired");
815
816 const std::string phase_2_response = get_ntlm_phase_2_response();
817 if (!phase_2_response.empty())
818 ntlm_auth_phase_3(phase_2_response);
819 else
820 throw Exception("NTLM phase-2 response missing");
821 }
822
823 void ntlm_auth_phase_3(const std::string &phase_2_response)
824 {
825 // do the NTLMv2 handshake
826 try
827 {
828 // OPENVPN_LOG("NTLM phase 3: " << phase_2_response);
829
830 const std::string phase_3_reply = HTTPProxy::NTLM::phase_3(
831 *config->digest_factory,
832 phase_2_response,
833 config->http_proxy_options->username,
834 config->http_proxy_options->password,
835 *config->rng);
836
837 std::ostringstream os;
839 os << "Proxy-Connection: Keep-Alive\r\n";
840 os << "Proxy-Authorization: NTLM " << phase_3_reply << "\r\n";
841
842 http_request = os.str();
845 }
846 catch (const std::exception &e)
847 {
848 std::string what{e.what()};
849 if (what.find("openssl_digest_error") != std::string::npos)
850 {
851 proxy_error(Error::NTLM_MISSING_CRYPTO, "Crypto primitives required for NTLM authentication are unavailable");
852 }
853 else
854 {
855 proxy_error(Error::PROXY_ERROR, std::string("NTLM Auth: ") + e.what());
856 }
857 }
858 }
859
860 void gen_headers(std::ostringstream &os)
861 {
862 bool host_header_sent = false;
863
864 // emit custom headers
865 {
866 const Options::CustomHeaderList &headers = config->http_proxy_options->headers;
867 for (Options::CustomHeaderList::const_iterator i = headers.begin(); i != headers.end(); ++i)
868 {
869 const Options::CustomHeader &h = **i;
870 if (!h.p2.empty())
871 {
872 os << h.p1 << ": " << h.p2 << "\r\n";
873 if (!string::strcasecmp(h.p1, "host"))
874 host_header_sent = true;
875 }
876 else
877 {
878 os << h.p1 << "\r\n";
879 const std::string h5 = h.p1.substr(0, 5);
880 if (!string::strcasecmp(h5, "host:"))
881 host_header_sent = true;
882 }
883 }
884 }
885
886 // emit user-agent header
887 {
888 const std::string &user_agent = config->http_proxy_options->user_agent;
889 if (!user_agent.empty())
890 os << "User-Agent: " << user_agent << "\r\n";
891 }
892
893 // emit host header
894 if (!host_header_sent)
895 os << "Host: " << server_host << "\r\n";
896 }
897
898 void stop_()
899 {
900 if (!halt)
901 {
902 halt = true;
903 if (impl)
904 impl->stop();
905
906 socket.close();
908 }
909 }
910
911 // do DNS resolve
912 void resolve_callback(const openvpn_io::error_code &error,
913 results_type results) override
914 {
915 // release resolver allocated resources
917
918 if (!halt)
919 {
920 if (!error)
921 {
922 // save resolved endpoint list in proxy remote_list
925 }
926 else
927 {
928 std::ostringstream os;
929 os << "DNS resolve error on '" << proxy_host << "' for TCP (HTTP proxy): " << error.message();
930 config->stats->error(Error::RESOLVE_ERROR);
931 stop();
933 }
934 }
935 }
936
937 void reset()
938 {
939 stop();
940 halt = false;
942 proxy_established = false;
944 }
945
955
956 // do TCP connect
958 {
960 OPENVPN_LOG("Contacting " << server_endpoint << " via HTTP Proxy");
962 socket.open(server_endpoint.protocol());
963
964 if (config->socket_protect)
965 {
966 if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr()))
967 {
968 config->stats->error(Error::SOCKET_PROTECT_ERROR);
969 stop();
970 parent->transport_error(Error::UNDEF, "socket_protect error (HTTP Proxy)");
971 return;
972 }
973 }
974
975 socket.set_option(openvpn_io::ip::tcp::no_delay(true));
976 socket.async_connect(server_endpoint, [self = Ptr(this)](const openvpn_io::error_code &error)
977 {
979 self->start_impl_(error); });
980 }
981
982 // start I/O on TCP socket
983 void start_impl_(const openvpn_io::error_code &error)
984 {
985 if (!halt)
986 {
987 if (!error)
988 {
990 impl.reset(new LinkImpl(this,
991 socket,
992 0, // send_queue_max_size is unlimited because we regulate size in cliproto.hpp
993 config->free_list_max_size,
994 (*config->frame)[Frame::READ_LINK_TCP],
995 config->stats));
996 impl->set_raw_mode(true);
997 impl->start();
999
1000 // tell proxy to connect through to OpenVPN server
1002 }
1003 else
1004 {
1006
1007 std::ostringstream os;
1008 os << "TCP connect error on '" << proxy_host << ':' << proxy_port << "' (" << server_endpoint << ") for TCP-via-HTTP-proxy session: " << error.message();
1009 config->stats->error(Error::TCP_CONNECT_ERROR);
1010 stop();
1012 }
1013 }
1014 }
1015
1017 {
1018 BufferAllocated buf;
1020 send(buf);
1021 }
1022
1023 // create HTTP CONNECT message
1025 {
1026 std::ostringstream os;
1027 const std::string &http_version = config->http_proxy_options->http_version;
1028 os << "CONNECT " << server_host << ':' << server_port << " HTTP/";
1029 if (!http_version.empty())
1030 os << http_version;
1031 else
1032 os << "1.0";
1033 os << "\r\n";
1034 if (!http_request.empty())
1035 os << http_request;
1036 else
1037 gen_headers(os);
1038 os << "\r\n";
1039 const std::string str = os.str();
1040 http_request = "";
1041
1042 OPENVPN_LOG_NTNL("TO PROXY: " << str);
1043
1044 config->frame->prepare(Frame::WRITE_HTTP, buf);
1045 buf_write_string(buf, str);
1046 }
1047
1049 {
1050 return *config->remote_list;
1051 }
1053 {
1054 return *config->http_proxy_options->proxy_server;
1055 }
1056
1057 std::string proxy_host;
1058 std::string proxy_port;
1059
1060 std::string server_host;
1061 std::string server_port;
1062
1063 openvpn_io::ip::tcp::socket socket;
1067 LinkImpl::protocol::endpoint server_endpoint;
1068 bool halt;
1069
1070 unsigned int n_transactions;
1076 std::string http_request;
1077
1080
1081 std::unique_ptr<HTTP::HTMLSkip> html_skip;
1082};
1083
1085{
1086 return TransportClient::Ptr(new Client(io_context, this, parent));
1087}
1088} // namespace openvpn::HTTPProxyTransport
1089
1090#endif
#define OPENVPN_ASYNC_HANDLER
Definition bigmutex.hpp:36
typename RESOLVER_TYPE::results_type results_type
Definition asio.hpp:97
virtual void async_resolve_name(const std::string &host, const std::string &port)
Definition asio.hpp:125
std::string encode(const V &data) const
Definition base64.hpp:139
void add(const Buffer &buf)
Definition buflimit.hpp:50
size_t size() const
Returns the size of the buffer in T objects.
Definition buffer.hpp:1241
void advance(const size_t delta)
Advances the buffer by the specified delta.
Definition buffer.hpp:1276
bool empty() const
Returns true if the buffer is empty.
Definition buffer.hpp:1235
T pop_front()
Removes and returns the first element from the buffer.
Definition buffer.hpp:1255
TransportClient::Ptr new_transport_client_obj(openvpn_io::io_context &io_context, TransportClientParent *parent) override
Definition httpcli.hpp:1084
void gen_headers(std::ostringstream &os)
Definition httpcli.hpp:860
void tcp_error_handler(const char *error)
Definition httpcli.hpp:408
void proxy_read_handler(BufferAllocated &buf)
Definition httpcli.hpp:473
HTTP::ReplyParser::status http_reply_status
Definition httpcli.hpp:1073
void proxy_error(const Error::Type fatal_err, const std::string &what)
Definition httpcli.hpp:416
openvpn_io::ip::tcp::socket socket
Definition httpcli.hpp:1063
IP::Addr server_endpoint_addr() const override
Definition httpcli.hpp:328
Client(openvpn_io::io_context &io_context_arg, ClientConfig *config_arg, TransportClientParent *parent_arg)
Definition httpcli.hpp:370
void ntlm_auth_phase_1(HTTPProxy::ProxyAuthenticate &pa)
Definition httpcli.hpp:780
LinkImpl::protocol::endpoint server_endpoint
Definition httpcli.hpp:1067
void proxy_connected(BufferAllocated &buf, const bool notify_parent)
Definition httpcli.hpp:530
std::unique_ptr< HTTP::HTMLSkip > html_skip
Definition httpcli.hpp:1081
bool transport_has_send_queue() override
Definition httpcli.hpp:295
RemoteList & proxy_remote_list() const
Definition httpcli.hpp:1052
void transport_stop_requeueing() override
Definition httpcli.hpp:300
void ntlm_auth_phase_3(const std::string &phase_2_response)
Definition httpcli.hpp:823
bool tcp_read_handler(BufferAllocated &buf)
Definition httpcli.hpp:424
bool transport_send(BufferAllocated &buf) override
Definition httpcli.hpp:283
void server_endpoint_info(std::string &host, std::string &port, std::string &proto, std::string &ip_addr) const override
Definition httpcli.hpp:317
RemoteList & remote_list() const
Definition httpcli.hpp:1048
ProxyResponseLimit proxy_response_limit
Definition httpcli.hpp:1071
Protocol transport_protocol() const override
Definition httpcli.hpp:333
bool send(BufferAllocated &buf)
Definition httpcli.hpp:401
void drain_html(BufferAllocated &buf)
Definition httpcli.hpp:571
void start_impl_(const openvpn_io::error_code &error)
Definition httpcli.hpp:983
TransportClientParent * parent
Definition httpcli.hpp:1065
void reset_align_adjust(const size_t align_adjust) override
Definition httpcli.hpp:311
void digest_auth(HTTPProxy::ProxyAuthenticate &pa)
Definition httpcli.hpp:699
HTTPProxy::ProxyAuthenticate::Ptr get_proxy_authenticate_header(const char *type)
Definition httpcli.hpp:592
bool transport_send_const(const Buffer &buf) override
Definition httpcli.hpp:278
void basic_auth(HTTPProxy::ProxyAuthenticate &pa)
Definition httpcli.hpp:684
bool transport_send_queue_empty() override
Definition httpcli.hpp:288
void transport_reparent(TransportClientParent *parent_arg) override
Definition httpcli.hpp:386
void create_http_connect_msg(BufferAllocated &buf)
Definition httpcli.hpp:1024
void resolve_callback(const openvpn_io::error_code &error, results_type results) override
Definition httpcli.hpp:912
size_t transport_send_queue_size() override
Definition httpcli.hpp:304
TCPTransport::TCPLink< openvpn_io::ip::tcp, Client *, false > LinkImpl
Definition httpcli.hpp:239
bool send_const(const Buffer &cbuf)
Definition httpcli.hpp:391
bool parse_options(const OptionList &opt)
Definition httpcli.hpp:115
static Ptr parse(const OptionList &opt)
Definition httpcli.hpp:103
void proxy_server_set_enable_cache(const bool enable_cache)
Definition httpcli.hpp:92
void proxy_server_precache(RemoteList::Ptr &r)
Definition httpcli.hpp:97
void set_proxy_server(const std::string &host, const std::string &port)
Definition httpcli.hpp:87
static std::string calcResponse(DigestFactory &digest_factory, const std::string &hA1, const std::string &nonce, const std::string &nonce_count, const std::string &cnonce, const std::string &qop, const std::string &method, const std::string &digestUri, const std::string &hEntity)
static std::string calcHA1(DigestFactory &digest_factory, const std::string &alg, const std::string &username, const std::string &realm, const std::string &password, const std::string &nonce, const std::string &cnonce)
static std::string phase_1()
Definition ntlm.hpp:44
static std::string phase_3(DigestFactory &digest_factory, const std::string &phase_2_response, const std::string &dom_username, const std::string &password, StrongRandomAPI &rng)
Definition ntlm.hpp:49
RCPtr< ProxyAuthenticate > Ptr
Definition proxyauth.hpp:27
status consume(Reply &req, const unsigned char input)
Definition reply.hpp:109
static Addr from_asio(const openvpn_io::ip::address &addr)
Definition ip.hpp:576
std::string to_string() const
Definition ip.hpp:528
const char * version_string() const
Definition ip.hpp:877
const IndexList * get_index_ptr(const std::string &name) const
Definition options.hpp:1260
std::vector< unsigned int > IndexList
Definition options.hpp:513
const Option * get_ptr(const std::string &name) const
Definition options.hpp:1174
bool exists(const std::string &name) const
Definition options.hpp:1308
std::string get_optional(const size_t index, const size_t max_len) const
Definition options.hpp:191
void touch(bool lightly=false) const
Definition options.hpp:378
const std::string & get(const size_t index, const size_t max_len) const
Definition options.hpp:184
The smart pointer class.
Definition rc.hpp:119
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
Definition rc.hpp:290
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:908
void set_endpoint_range(EPRANGE &endpoint_range)
bool endpoint_available(std::string *server_host, std::string *server_port, Protocol *transport_protocol) const
void get_endpoint(EP &endpoint) const
void next(Advance type=Advance::Addr)
bool get_enable_cache() const
void set_enable_cache(const bool enable_cache_arg)
#define OPENVPN_THROW_EXCEPTION(stuff)
#define OPENVPN_LOG_NTNL(args)
#define OPENVPN_LOG(args)
@ NETWORK_EOF_ERROR
Definition error.hpp:25
@ NTLM_MISSING_CRYPTO
Definition error.hpp:93
@ TCP_CONNECT_ERROR
Definition error.hpp:50
@ SOCKET_PROTECT_ERROR
Definition error.hpp:36
bool parse(const OptionList &options, const std::string &opt_name, const unsigned int flags, std::vector< std::string > *user_pass)
interpret user-pass option
Definition userpass.hpp:74
int strcasecmp(const char *s1, const char *s2)
Definition string.hpp:33
std::string render_hex(const unsigned char *data, size_t size, const bool caps=false)
Definition hexstr.hpp:133
const Base64 * base64
Definition base64.hpp:299
std::string buf_to_string(const Buffer &buf)
Definition bufstr.hpp:22
void buf_write_string(Buffer &buf, const std::string &str)
Definition bufstr.hpp:34
std::string get_value(const std::string &key) const
Definition header.hpp:74
std::string get_value_trim(const std::string &key) const
Definition header.hpp:82
std::string name
Definition header.hpp:48
std::string value
Definition header.hpp:49
HeaderList headers
Definition reply.hpp:59
virtual void transport_connecting()=0
virtual void transport_pre_resolve()=0
virtual void transport_error(const Error::Type fatal_err, const std::string &err_text)=0
virtual void proxy_error(const Error::Type fatal_err, const std::string &err_text)=0
virtual bool transport_is_openvpn_protocol()=0
virtual void transport_wait()=0
virtual void transport_recv(BufferAllocated &buf)=0
virtual void transport_wait_proxy()=0
virtual void transport_needs_send()=0
RCPtr< TransportClient > Ptr
Definition transbase.hpp:37
proxy_host_port port
os<< "Session Name: "<< tbc-> session_name<< '\n';os<< "Layer: "<< tbc-> layer str()<< '\n'
proxy_host_port host
std::ostringstream os