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 else
195 return false;
196 }
197};
198
200{
201 public:
203
208
210
211 StrongRandomAPI::Ptr rng; // random data source
212
213 DigestFactory::Ptr digest_factory; // needed by proxy auth methods
214
216
218
219 static Ptr new_obj()
220 {
221 return new ClientConfig;
222 }
223
224 TransportClient::Ptr new_transport_client_obj(openvpn_io::io_context &io_context,
225 TransportClientParent *parent) override;
226
227 private:
230 socket_protect(nullptr),
231 skip_html(false)
232 {
233 }
234};
235
237{
239
241
242 friend class ClientConfig; // calls constructor
243 friend LinkImpl::Base; // calls tcp_read_handler
244
245 public:
246 void transport_start() override
247 {
248 if (!impl)
249 {
250 if (!config->http_proxy_options)
251 {
252 parent->proxy_error(Error::PROXY_ERROR, "http_proxy_options not defined");
253 return;
254 }
255
256 halt = false;
257
258 // Get target server host:port. We don't care about resolving it
259 // since proxy server will do that for us.
261
262 // Get proxy server host:port, and resolve it if not already cached
263 if (proxy_remote_list().endpoint_available(&proxy_host, &proxy_port, nullptr))
264 {
265 // already cached
267 }
268 else
269 {
270 // resolve it
272
275 }
276 }
277 }
278
279 bool transport_send_const(const Buffer &buf) override
280 {
281 return send_const(buf);
282 }
283
284 bool transport_send(BufferAllocated &buf) override
285 {
286 return send(buf);
287 }
288
290 {
291 if (impl)
292 return impl->send_queue_empty();
293 else
294 return false;
295 }
296
298 {
299 return true;
300 }
301
303 {
304 }
305
307 {
308 if (impl)
309 return impl->send_queue_size();
310 else
311 return 0;
312 }
313
314 void reset_align_adjust(const size_t align_adjust) override
315 {
316 if (impl)
317 impl->reset_align_adjust(align_adjust);
318 }
319
320 void server_endpoint_info(std::string &host, std::string &port, std::string &proto, std::string &ip_addr) const override
321 {
324 const IP::Addr addr = server_endpoint_addr();
325 proto = "TCP";
326 proto += addr.version_string();
327 proto += "-via-HTTP";
328 ip_addr = addr.to_string();
329 }
330
332 {
333 return IP::Addr::from_asio(server_endpoint.address());
334 }
335
337 {
338 if (server_endpoint.address().is_v4())
340 else if (server_endpoint.address().is_v6())
342 else
343 return Protocol();
344 }
345
346 void stop() override
347 {
348 stop_();
349 }
350 virtual ~Client()
351 {
352 stop_();
353 }
354
355 private:
356 struct ProxyResponseLimit : public BufferLimit<size_t>
357 {
359 : BufferLimit(1024, 65536)
360 {
361 }
362
363 void bytes_exceeded() override
364 {
365 OPENVPN_THROW_EXCEPTION("HTTP proxy response too large (> " << max_bytes << " bytes)");
366 }
367
368 void lines_exceeded() override
369 {
370 OPENVPN_THROW_EXCEPTION("HTTP proxy response too large (> " << max_lines << " lines)");
371 }
372 };
373
374 Client(openvpn_io::io_context &io_context_arg,
375 ClientConfig *config_arg,
376 TransportClientParent *parent_arg)
377 : AsyncResolvableTCP(io_context_arg),
378 socket(io_context_arg),
379 config(config_arg),
380 parent(parent_arg),
381 halt(false),
383 proxy_established(false),
384 http_reply_status(HTTP::ReplyParser::pending),
387 {
388 }
389
390 void transport_reparent(TransportClientParent *parent_arg) override
391 {
392 parent = parent_arg;
393 }
394
395 bool send_const(const Buffer &cbuf)
396 {
397 if (impl)
398 {
399 BufferAllocated buf(cbuf);
400 return impl->send(buf);
401 }
402 else
403 return false;
404 }
405
407 {
408 if (impl)
409 return impl->send(buf);
410 else
411 return false;
412 }
413
414 void tcp_error_handler(const char *error) // called by LinkImpl and internally
415 {
416 std::ostringstream os;
417 os << "Transport error on '" << server_host << "' via HTTP proxy " << proxy_host << ':' << proxy_port << " : " << error;
418 stop();
420 }
421
422 void proxy_error(const Error::Type fatal_err, const std::string &what)
423 {
424 std::ostringstream os;
425 os << "on " << proxy_host << ':' << proxy_port << ": " << what;
426 stop();
427 parent->proxy_error(fatal_err, os.str());
428 }
429
430 bool tcp_read_handler(BufferAllocated &buf) // called by LinkImpl
431 {
433 {
434 if (!html_skip)
436 else
437 drain_html(buf); // skip extraneous HTML after header
438 }
439 else
440 {
441 try
442 {
444 }
445 catch (const std::exception &e)
446 {
448 }
449 }
450 return true;
451 }
452
453 void tcp_write_queue_needs_send() // called by LinkImpl
454 {
457 }
458
459 void tcp_eof_handler() // called by LinkImpl
460 {
462 {
463 config->stats->error(Error::NETWORK_EOF_ERROR);
464 tcp_error_handler("NETWORK_EOF_ERROR");
465 }
466 else
467 {
468 try
469 {
471 }
472 catch (const std::exception &e)
473 {
475 }
476 }
477 }
478
480 {
481 // for anti-DoS, only allow a maximum number of chars in HTTP response
483
485 {
486 OPENVPN_LOG_NTNL("FROM PROXY: " << buf_to_string(buf));
487 for (size_t i = 0; i < buf.size(); ++i)
488 {
491 {
492 buf.advance(i + 1);
494 {
495 // OPENVPN_LOG("*** HTTP header parse complete, resid_size=" << buf.size());
496 // OPENVPN_LOG(http_reply.to_string());
497
498 // we are connected, switch socket to tunnel mode
500 {
501 if (config->skip_html)
502 {
504 html_skip.reset(new HTTP::HTMLSkip());
505 drain_html(buf);
506 }
507 else
508 proxy_connected(buf, true);
509 }
512 }
513 else
514 {
515 throw Exception("HTTP proxy header parse error");
516 }
517 break;
518 }
519 }
520 }
521
522 // handle draining of content controlled by Content-length header
524 {
525 const size_t drain = std::min(drain_content_length, buf.size());
526 buf.advance(drain);
527 drain_content_length -= drain;
529 {
532 }
533 }
534 }
535
536 void proxy_connected(BufferAllocated &buf, const bool notify_parent)
537 {
538 proxy_established = true;
540 {
541 // switch socket from HTTP proxy handshake mode to OpenVPN protocol mode
542 impl->set_raw_mode(false);
543 if (notify_parent)
545 try
546 {
547 impl->inject(buf);
548 }
549 catch (const std::exception &e)
550 {
551 proxy_error(Error::PROXY_ERROR, std::string("post-header inject error: ") + e.what());
552 return;
553 }
554 }
555 else
556 {
557 if (notify_parent)
560 }
561 }
562
563 // Called after header received but before possible extraneous HTML
564 // is drained. At this point, we are in a state where output data
565 // (if OpenVPN protocol) is packetized, but input data is still in
566 // raw mode as we search the input stream for the end of the
567 // extraneous HTML. When we reach the beginning of payload data,
568 // proxy_connected() should be called with notify_parent == false.
570 {
571 proxy_established = true;
573 impl->set_raw_mode_write(false);
575 }
576
578 {
579 while (!buf.empty())
580 {
581 switch (html_skip->add(buf.pop_front()))
582 {
585 {
586 OPENVPN_LOG("Proxy: Skipped " << html_skip->n_bytes() << " byte(s) of HTML");
587 html_skip->get_residual(buf);
588 html_skip.reset();
589 proxy_connected(buf, false);
590 return;
591 }
593 break;
594 }
595 }
596 }
597
599 {
600 for (HTTP::HeaderList::const_iterator i = http_reply.headers.begin(); i != http_reply.headers.end(); ++i)
601 {
602 const HTTP::Header &h = *i;
603 if (string::strcasecmp(h.name, "proxy-authenticate") == 0)
604 {
606 if (string::strcasecmp(type, pa->method) == 0)
607 return pa;
608 }
609 }
611 }
612
614 {
616 {
618 {
619 if (config->http_proxy_options->auth_method == None)
620 throw Exception("HTTP proxy authentication is disabled");
621 if (n_transactions > 1)
622 {
623 proxy_error(Error::PROXY_NEED_CREDS, "HTTP proxy credentials were not accepted");
624 return;
625 }
626 if (config->http_proxy_options->username.empty())
627 {
628 proxy_error(Error::PROXY_NEED_CREDS, "HTTP proxy requires credentials");
629 return;
630 }
631
633 const AuthMethod method(config->http_proxy_options->auth_method);
634
635 if (method == Any || method == Ntlm)
636 {
638 if (pa)
639 {
641 return;
642 }
643 }
644
645 if (method == Any || method == Digest)
646 {
647 pa = get_proxy_authenticate_header("digest");
648 if (pa)
649 {
650 digest_auth(*pa);
651 return;
652 }
653 }
654
655 if (method == Any || method == Basic)
656 {
657 pa = get_proxy_authenticate_header("basic");
658 if (pa)
659 {
660 if (!config->http_proxy_options->allow_cleartext_auth)
661 throw Exception("HTTP proxy basic authentication not allowed by user preference");
662
663 basic_auth(*pa);
664 return;
665 }
666 }
667
668 throw Exception("HTTP proxy-authenticate method not allowed / supported");
669 }
673 {
674 // this is a nonfatal error, so we pass Error::UNDEF to tell the upper layer to
675 // retry the connection
676 proxy_error(Error::UNDEF, "HTTP proxy server could not connect to OpenVPN server");
677 return;
678 }
680 OPENVPN_THROW_EXCEPTION("HTTP proxy returned Forbidden status code");
681 else
682 OPENVPN_THROW_EXCEPTION("HTTP proxy status code: " << http_reply.status_code);
683 }
685 throw Exception("HTTP proxy unexpected EOF: reply incomplete");
686 else
687 throw Exception("HTTP proxy general error");
688 }
689
691 {
692 OPENVPN_LOG("Proxy method: Basic" << std::endl
693 << pa.to_string());
694
695 std::ostringstream os;
697 os << "Proxy-Authorization: Basic "
698 << base64->encode(config->http_proxy_options->username + ':' + config->http_proxy_options->password)
699 << "\r\n";
700 http_request = os.str();
701 reset();
703 }
704
706 {
707 try
708 {
709 OPENVPN_LOG("Proxy method: Digest" << std::endl
710 << pa.to_string());
711
712 // constants
713 const std::string http_method = "CONNECT";
714 const std::string nonce_count = "00000001";
715 const std::string qop = "auth";
716
717 // get values from Proxy-Authenticate header
718 const std::string realm = pa.parms.get_value("realm");
719 const std::string nonce = pa.parms.get_value("nonce");
720 const std::string algorithm = pa.parms.get_value("algorithm");
721 const std::string opaque = pa.parms.get_value("opaque");
722
723 // generate a client nonce
724 unsigned char cnonce_raw[8];
725 config->rng->rand_bytes(cnonce_raw, sizeof(cnonce_raw));
726 const std::string cnonce = render_hex(cnonce_raw, sizeof(cnonce_raw));
727
728 // build URI
729 const std::string uri = server_host + ":" + server_port;
730
731 // calculate session key
732 const std::string session_key = HTTPProxy::Digest::calcHA1(
733 *config->digest_factory,
734 algorithm,
735 config->http_proxy_options->username,
736 realm,
737 config->http_proxy_options->password,
738 nonce,
739 cnonce);
740
741 // calculate response
742 const std::string response = HTTPProxy::Digest::calcResponse(
743 *config->digest_factory,
744 session_key,
745 nonce,
746 nonce_count,
747 cnonce,
748 qop,
749 http_method,
750 uri,
751 "");
752
753 // generate proxy request
754 std::ostringstream os;
756 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 << "\"";
757 if (!opaque.empty())
758 os << ", opaque=\"" + opaque + "\"";
759 os << "\r\n";
760
761 http_request = os.str();
762 reset();
764 }
765 catch (const std::exception &e)
766 {
767 proxy_error(Error::PROXY_ERROR, std::string("Digest Auth: ") + e.what());
768 }
769 }
770
772 {
773 for (HTTP::HeaderList::const_iterator i = http_reply.headers.begin(); i != http_reply.headers.end(); ++i)
774 {
775 const HTTP::Header &h = *i;
776 if (string::strcasecmp(h.name, "proxy-authenticate") == 0)
777 {
778 std::vector<std::string> v = Split::by_space<std::vector<std::string>, StandardLex, SpaceMatch, Split::NullLimit>(h.value);
779 if (v.size() >= 2 && string::strcasecmp("ntlm", v[0]) == 0)
780 return v[1];
781 }
782 }
783 return "";
784 }
785
787 {
788 OPENVPN_LOG("Proxy method: NTLM" << std::endl
789 << pa.to_string());
790
791 const std::string phase_1_reply = HTTPProxy::NTLM::phase_1();
792
793 std::ostringstream os;
795 os << "Proxy-Connection: Keep-Alive\r\n";
796 os << "Proxy-Authorization: NTLM " << phase_1_reply << "\r\n";
797
798 http_request = os.str();
799 reset();
802 }
803
805 {
806 // if content exists, drain it first, then progress to ntlm_auth_phase_2
807 const std::string content_length_str = http_reply.headers.get_value_trim("content-length");
808 const unsigned int content_length = parse_number_throw<unsigned int>(content_length_str, "content-length");
809 if (content_length)
810 drain_content_length = content_length;
811 else
813 }
814
816 {
818
820 throw Exception("NTLM phase-2 status is not ProxyAuthenticationRequired");
821
822 const std::string phase_2_response = get_ntlm_phase_2_response();
823 if (!phase_2_response.empty())
824 ntlm_auth_phase_3(phase_2_response);
825 else
826 throw Exception("NTLM phase-2 response missing");
827 }
828
829 void ntlm_auth_phase_3(const std::string &phase_2_response)
830 {
831 // do the NTLMv2 handshake
832 try
833 {
834 // OPENVPN_LOG("NTLM phase 3: " << phase_2_response);
835
836 const std::string phase_3_reply = HTTPProxy::NTLM::phase_3(
837 *config->digest_factory,
838 phase_2_response,
839 config->http_proxy_options->username,
840 config->http_proxy_options->password,
841 *config->rng);
842
843 std::ostringstream os;
845 os << "Proxy-Connection: Keep-Alive\r\n";
846 os << "Proxy-Authorization: NTLM " << phase_3_reply << "\r\n";
847
848 http_request = os.str();
851 }
852 catch (const std::exception &e)
853 {
854 std::string what{e.what()};
855 if (what.find("openssl_digest_error") != std::string::npos)
856 {
857 proxy_error(Error::NTLM_MISSING_CRYPTO, "Crypto primitives required for NTLM authentication are unavailable");
858 }
859 else
860 {
861 proxy_error(Error::PROXY_ERROR, std::string("NTLM Auth: ") + e.what());
862 }
863 }
864 }
865
866 void gen_headers(std::ostringstream &os)
867 {
868 bool host_header_sent = false;
869
870 // emit custom headers
871 {
872 const Options::CustomHeaderList &headers = config->http_proxy_options->headers;
873 for (Options::CustomHeaderList::const_iterator i = headers.begin(); i != headers.end(); ++i)
874 {
875 const Options::CustomHeader &h = **i;
876 if (!h.p2.empty())
877 {
878 os << h.p1 << ": " << h.p2 << "\r\n";
879 if (!string::strcasecmp(h.p1, "host"))
880 host_header_sent = true;
881 }
882 else
883 {
884 os << h.p1 << "\r\n";
885 const std::string h5 = h.p1.substr(0, 5);
886 if (!string::strcasecmp(h5, "host:"))
887 host_header_sent = true;
888 }
889 }
890 }
891
892 // emit user-agent header
893 {
894 const std::string &user_agent = config->http_proxy_options->user_agent;
895 if (!user_agent.empty())
896 os << "User-Agent: " << user_agent << "\r\n";
897 }
898
899 // emit host header
900 if (!host_header_sent)
901 os << "Host: " << server_host << "\r\n";
902 }
903
904 void stop_()
905 {
906 if (!halt)
907 {
908 halt = true;
909 if (impl)
910 impl->stop();
911
912 socket.close();
914 }
915 }
916
917 // do DNS resolve
918 void resolve_callback(const openvpn_io::error_code &error,
919 results_type results) override
920 {
921 // release resolver allocated resources
923
924 if (!halt)
925 {
926 if (!error)
927 {
928 // save resolved endpoint list in proxy remote_list
931 }
932 else
933 {
934 std::ostringstream os;
935 os << "DNS resolve error on '" << proxy_host << "' for TCP (HTTP proxy): " << error.message();
936 config->stats->error(Error::RESOLVE_ERROR);
937 stop();
939 }
940 }
941 }
942
943 void reset()
944 {
945 stop();
946 halt = false;
948 proxy_established = false;
950 }
951
961
962 // do TCP connect
964 {
966 OPENVPN_LOG("Contacting " << server_endpoint << " via HTTP Proxy");
968 socket.open(server_endpoint.protocol());
969
970 if (config->socket_protect)
971 {
972 if (!config->socket_protect->socket_protect(socket.native_handle(), server_endpoint_addr()))
973 {
974 config->stats->error(Error::SOCKET_PROTECT_ERROR);
975 stop();
976 parent->transport_error(Error::UNDEF, "socket_protect error (HTTP Proxy)");
977 return;
978 }
979 }
980
981 socket.set_option(openvpn_io::ip::tcp::no_delay(true));
982 socket.async_connect(server_endpoint, [self = Ptr(this)](const openvpn_io::error_code &error)
983 {
985 self->start_impl_(error); });
986 }
987
988 // start I/O on TCP socket
989 void start_impl_(const openvpn_io::error_code &error)
990 {
991 if (!halt)
992 {
993 if (!error)
994 {
996 impl.reset(new LinkImpl(this,
997 socket,
998 0, // send_queue_max_size is unlimited because we regulate size in cliproto.hpp
999 config->free_list_max_size,
1000 (*config->frame)[Frame::READ_LINK_TCP],
1001 config->stats));
1002 impl->set_raw_mode(true);
1003 impl->start();
1005
1006 // tell proxy to connect through to OpenVPN server
1008 }
1009 else
1010 {
1012
1013 std::ostringstream os;
1014 os << "TCP connect error on '" << proxy_host << ':' << proxy_port << "' (" << server_endpoint << ") for TCP-via-HTTP-proxy session: " << error.message();
1015 config->stats->error(Error::TCP_CONNECT_ERROR);
1016 stop();
1018 }
1019 }
1020 }
1021
1023 {
1024 BufferAllocated buf;
1026 send(buf);
1027 }
1028
1029 // create HTTP CONNECT message
1031 {
1032 std::ostringstream os;
1033 const std::string &http_version = config->http_proxy_options->http_version;
1034 os << "CONNECT " << server_host << ':' << server_port << " HTTP/";
1035 if (!http_version.empty())
1036 os << http_version;
1037 else
1038 os << "1.0";
1039 os << "\r\n";
1040 if (!http_request.empty())
1041 os << http_request;
1042 else
1043 gen_headers(os);
1044 os << "\r\n";
1045 const std::string str = os.str();
1046 http_request = "";
1047
1048 OPENVPN_LOG_NTNL("TO PROXY: " << str);
1049
1050 config->frame->prepare(Frame::WRITE_HTTP, buf);
1051 buf_write_string(buf, str);
1052 }
1053
1055 {
1056 return *config->remote_list;
1057 }
1059 {
1060 return *config->http_proxy_options->proxy_server;
1061 }
1062
1063 std::string proxy_host;
1064 std::string proxy_port;
1065
1066 std::string server_host;
1067 std::string server_port;
1068
1069 openvpn_io::ip::tcp::socket socket;
1073 LinkImpl::protocol::endpoint server_endpoint;
1074 bool halt;
1075
1076 unsigned int n_transactions;
1082 std::string http_request;
1083
1086
1087 std::unique_ptr<HTTP::HTMLSkip> html_skip;
1088};
1089
1091{
1092 return TransportClient::Ptr(new Client(io_context, this, parent));
1093}
1094} // namespace openvpn::HTTPProxyTransport
1095
1096#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:1242
void advance(const size_t delta)
Advances the buffer by the specified delta.
Definition buffer.hpp:1277
bool empty() const
Returns true if the buffer is empty.
Definition buffer.hpp:1236
T pop_front()
Removes and returns the first element from the buffer.
Definition buffer.hpp:1256
TransportClient::Ptr new_transport_client_obj(openvpn_io::io_context &io_context, TransportClientParent *parent) override
Definition httpcli.hpp:1090
void gen_headers(std::ostringstream &os)
Definition httpcli.hpp:866
void tcp_error_handler(const char *error)
Definition httpcli.hpp:414
void proxy_read_handler(BufferAllocated &buf)
Definition httpcli.hpp:479
HTTP::ReplyParser::status http_reply_status
Definition httpcli.hpp:1079
void proxy_error(const Error::Type fatal_err, const std::string &what)
Definition httpcli.hpp:422
openvpn_io::ip::tcp::socket socket
Definition httpcli.hpp:1069
IP::Addr server_endpoint_addr() const override
Definition httpcli.hpp:331
Client(openvpn_io::io_context &io_context_arg, ClientConfig *config_arg, TransportClientParent *parent_arg)
Definition httpcli.hpp:374
void ntlm_auth_phase_1(HTTPProxy::ProxyAuthenticate &pa)
Definition httpcli.hpp:786
LinkImpl::protocol::endpoint server_endpoint
Definition httpcli.hpp:1073
void proxy_connected(BufferAllocated &buf, const bool notify_parent)
Definition httpcli.hpp:536
std::unique_ptr< HTTP::HTMLSkip > html_skip
Definition httpcli.hpp:1087
bool transport_has_send_queue() override
Definition httpcli.hpp:297
RemoteList & proxy_remote_list() const
Definition httpcli.hpp:1058
void transport_stop_requeueing() override
Definition httpcli.hpp:302
void ntlm_auth_phase_3(const std::string &phase_2_response)
Definition httpcli.hpp:829
bool tcp_read_handler(BufferAllocated &buf)
Definition httpcli.hpp:430
bool transport_send(BufferAllocated &buf) override
Definition httpcli.hpp:284
TCPTransport::TCPLink< openvpn_io::ip::tcp, Client *, false > LinkImpl
Definition httpcli.hpp:240
void server_endpoint_info(std::string &host, std::string &port, std::string &proto, std::string &ip_addr) const override
Definition httpcli.hpp:320
RemoteList & remote_list() const
Definition httpcli.hpp:1054
ProxyResponseLimit proxy_response_limit
Definition httpcli.hpp:1077
Protocol transport_protocol() const override
Definition httpcli.hpp:336
bool send(BufferAllocated &buf)
Definition httpcli.hpp:406
void drain_html(BufferAllocated &buf)
Definition httpcli.hpp:577
void start_impl_(const openvpn_io::error_code &error)
Definition httpcli.hpp:989
TransportClientParent * parent
Definition httpcli.hpp:1071
void reset_align_adjust(const size_t align_adjust) override
Definition httpcli.hpp:314
void digest_auth(HTTPProxy::ProxyAuthenticate &pa)
Definition httpcli.hpp:705
HTTPProxy::ProxyAuthenticate::Ptr get_proxy_authenticate_header(const char *type)
Definition httpcli.hpp:598
bool transport_send_const(const Buffer &buf) override
Definition httpcli.hpp:279
void basic_auth(HTTPProxy::ProxyAuthenticate &pa)
Definition httpcli.hpp:690
bool transport_send_queue_empty() override
Definition httpcli.hpp:289
void transport_reparent(TransportClientParent *parent_arg) override
Definition httpcli.hpp:390
void create_http_connect_msg(BufferAllocated &buf)
Definition httpcli.hpp:1030
void resolve_callback(const openvpn_io::error_code &error, results_type results) override
Definition httpcli.hpp:918
size_t transport_send_queue_size() override
Definition httpcli.hpp:306
bool send_const(const Buffer &cbuf)
Definition httpcli.hpp:395
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:1276
const Option * get_ptr(const std::string &name) const
Definition options.hpp:1186
std::vector< unsigned int > IndexList
Definition options.hpp:520
bool exists(const std::string &name) const
Definition options.hpp:1325
std::string get_optional(const size_t index, const size_t max_len) const
Definition options.hpp:194
void touch(bool lightly=false) const
Definition options.hpp:385
const std::string & get(const size_t index, const size_t max_len) const
Definition options.hpp:187
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:912
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:29
std::string render_hex(const unsigned char *data, size_t size, const bool caps=false)
Definition hexstr.hpp:135
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:75
std::string get_value_trim(const std::string &key) const
Definition header.hpp:84
std::string name
Definition header.hpp:49
std::string value
Definition header.hpp:50
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