1
2//
3// SetSourceIP.cpp
4//
5// This sample demonstrates setting the source IP address.
6//
7// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
8// and Contributors.
9//
10// SPDX-License-Identifier: BSL-1.0
11//
12
13
14#include <Poco/Net/SSLManager.h>
15#include <Poco/Net/RejectCertificateHandler.h>
16#include <Poco/Net/KeyConsoleHandler.h>
17#include <Poco/Net/ConsoleCertificateHandler.h>
18#include <Poco/Net/Context.h>
19#include <Poco/Net/HTTPSClientSession.h>
20#include <Poco/Net/HTTPRequest.h>
21#include <Poco/Net/HTTPResponse.h>
22#include <Poco/Net/SecureStreamSocket.h>
23#include <Poco/Net/SocketImpl.h>
24#include <Poco/Path.h>
25#include <Poco/URI.h>
26#include <Poco/Exception.h>
27#include <Poco/SharedPtr.h>
28
29
30#include <iostream>
31#include <sstream>
32#include <string>
33#include <map>
34
35Poco::Path programName;
36
37void usage(std::string errorMessage)
38{
39 std::cerr << "ERROR: " << errorMessage << std::endl;
40 std::cerr << std::endl;
41 std::cerr << " syntax: " << std::endl;
42
43 std::cerr << " " << programName.getBaseName() << " OPTIONS uri" << std::endl;
44 std::cerr << std::endl;
45 std::cerr << " OPTIONS:" << std::endl;
46 std::cerr << " --sourceip <source IP address>" << std::endl;
47 std::cerr << " --proxyuri <proxy uri>" << std::endl;
48
49 std::cerr << std::endl;
50 std::cerr << " supported uri schemes for target are http and https" << std::endl;
51 std::cerr << " supported uri scheme for proxy is http" << std::endl;
52 std::cerr << std::endl;
53 std::cerr << " examples: " << std::endl;
54 std::cerr << " " << programName.getBaseName() << " http://www.example.com/" << std::endl;
55 std::cerr << " " << programName.getBaseName() << " https://www.example.com/" << std::endl;
56 std::cerr << " " << programName.getBaseName() << " --sourceip 10.2.5.6 http://www.example.com/" << std::endl;
57 std::cerr << " " << programName.getBaseName() << " --sourceip 192.168.15.122 https://www.example.com/" << std::endl;
58 std::cerr << " " << programName.getBaseName() << " --proxyuri http://localhost:3128 https://www.example.com/" << std::endl;
59 std::cerr << " " << programName.getBaseName() << " --sourceip 192.168.15.122 --proxyuri http://localhost:3128 https://www.example.com/" << std::endl;
60 std::cerr << std::endl;
61 exit(1);
62}
63
64
65int main(int argc, char **argv)
66{
67 // save program name in case usage() gets called
68 programName = argv[0];
69
70 std::string uriString;
71 std::list<std::string> sourceIpList;
72 std::string proxyUriString;
73
74 for (int i = 1; i < argc; ++i)
75 {
76 std::string optionName = argv[i];
77
78 if (optionName == "--sourceip")
79 {
80 ++i;
81 if (i >= argc)
82 {
83 usage("Missing option arguments");
84 }
85
86 sourceIpList.push_back(argv[i]);
87 continue;
88 }
89
90 if (optionName == "--proxyuri")
91 {
92 ++i;
93 if (i >= argc)
94 {
95 usage("Missing option arguments");
96 }
97
98 proxyUriString = argv[i];
99 continue;
100 }
101
102 // last argument??
103 if ((i+1) == argc)
104 uriString = argv[i];
105 else
106 usage("Unknown option");
107 }
108
109 if (uriString.empty())
110 {
111 usage("URI not specified");
112 }
113
114 Poco::SharedPtr<Poco::Net::HTTPClientSession> session;
115
116 try
117 {
118 Poco::URI uri(uriString);
119
120 if (uri.getScheme() == "https")
121 {
122 Poco::Net::initializeSSL();
123
124 Poco::Net::Context::Params params;
125 params.verificationMode = Poco::Net::Context::VERIFY_NONE;
126 params.verificationDepth = 9;
127 params.loadDefaultCAs = true;
128 params.cipherList = "ALL";
129
130 Poco::Net::Context::Ptr context = new Poco::Net::Context(Poco::Net::Context::TLSV1_2_CLIENT_USE, params);
131
132 Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> ptrCert = new Poco::Net::ConsoleCertificateHandler(false); // ask the user via console
133
134 Poco::Net::SSLManager::instance().initializeClient(NULL, ptrCert, context);
135
136 session = new Poco::Net::HTTPSClientSession(uri.getHost(), uri.getPort());
137 }
138 else if (uri.getScheme() == "http")
139 {
140 session = new Poco::Net::HTTPClientSession(uri.getHost(), uri.getPort());
141 }
142 else
143 {
144 usage("wrong scheme '" + uri.getScheme() + "' for target uri, expected http or https");
145 }
146
147 while (!sourceIpList.empty())
148 {
149 std::string sourceIpString = sourceIpList.front();
150 sourceIpList.pop_front();
151
152 // Set the sourceIP address, but leave the source port to 0 so ANY port can be used
153 Poco::Net::SocketAddress sa = Poco::Net::SocketAddress(sourceIpString, 0);
154 session->setSourceAddress(sa);
155
156 std::cout << "Using source IP address" << std::endl;
157 std::cout << "source IP address : " << sa.toString() << std::endl;
158 std::cout << std::endl;
159 }
160
161 if (!proxyUriString.empty())
162 {
163 Poco::URI proxyUri(proxyUriString);
164
165 if (proxyUri.getScheme() == "http")
166 session->setProxy(proxyUri.getHost(), proxyUri.getPort());
167 else
168 usage("wrong scheme '" + proxyUri.getScheme() + "' for proxy uri, expected http");
169
170 std::cout << "Using proxy" << std::endl;
171 std::cout << "Proxy Host: " << proxyUri.getHost() << std::endl;
172 std::cout << "Proxy Port: " << proxyUri.getPort() << std::endl;
173 std::cout << std::endl;
174 }
175
176 std::string path(uri.getPathAndQuery());
177
178 std::cout << "Host: " << uri.getHost() << std::endl;
179 std::cout << "Port: " << uri.getPort() << std::endl;
180 std::cout << "Path: " << path << std::endl;
181
182 Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
183
184 session->sendRequest(request);
185
186 Poco::Net::HTTPResponse response;
187 std::istream &istream = session->receiveResponse(response);
188
189 std::cout << "Status: " << response.getStatus() << std::endl;
190
191 std::string responseString;
192
193 Poco::StreamCopier::copyToString(istream, responseString);
194
195 std::cout << "Response: " << responseString << std::endl;
196 }
197 catch (Poco::Exception &ex)
198 {
199 std::cout << "Exception: name (" << ex.name() << ") message [" << ex.message() << "]" << std::endl << std::flush;
200 }
201
202 return 0;
203}
204