1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
/*
* Copyright (c) 2002-2009 Moxie Marlinspike
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include "HttpConnectionManager.hpp"
#include <boost/bind/bind.hpp>
#include <boost/asio.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <string>
#include <map>
#include "../util/Destination.hpp"
#include "../util/Util.hpp"
#include "../FingerprintManager.hpp"
#include "../FirefoxUpdater.hpp"
#include "../UpdateManager.hpp"
// Public
using namespace boost::asio;
HttpConnectionManager::HttpConnectionManager(io_context& io_service, int port,
CertificateManager &certificateManager,
bool denyOCSP)
: acceptor_(io_service, ip::tcp::endpoint(ip::tcp::v4(), port)),
port_(port),
certificateManager(certificateManager),
denyOCSP(denyOCSP)
{
if (port != -1)
acceptIncomingConnection();
}
void HttpConnectionManager::acceptIncomingConnection() {
// In modern Asio, get the io_context from the acceptor's executor.
auto &io = static_cast<io_context&>(acceptor_.get_executor().context());
boost::shared_ptr<ip::tcp::socket> socket(new ip::tcp::socket(io));
acceptor_.async_accept(*socket, boost::bind(&HttpConnectionManager::handleClientConnection,
this, socket, boost::asio::placeholders::error));
}
void HttpConnectionManager::bridgeHttpRequest(boost::shared_ptr<ip::tcp::socket> socket,
ip::tcp::endpoint destination)
{
auto &io = static_cast<io_context&>(acceptor_.get_executor().context());
Bridge::ptr bridge = HttpBridge::create(socket, io,
FingerprintManager::getInstance());
bridge->getServerSocket().
async_connect(destination, boost::bind(&HttpConnectionManager::handleServerConnection,
this, bridge, boost::asio::placeholders::error));
}
void HttpConnectionManager::handleClientConnection(boost::shared_ptr<ip::tcp::socket> socket,
const boost::system::error_code& error)
{
if (error) {
socket->close();
Logger::logError("HTTP Accept Error...");
return;
}
try {
ip::tcp::endpoint destination;
Destination::getOriginalDestination(*socket, destination);
if (denyOCSP && certificateManager.isOCSPAddress(destination))
OCSPDenier::getInstance()->denyOCSPRequest(socket);
else
bridgeHttpRequest(socket, destination);
} catch (IndeterminateDestinationException &exception) {
std::cerr << "Error: Could not determine original destination..." << std::endl;
}
acceptIncomingConnection();
}
void HttpConnectionManager::handleServerConnection(Bridge::ptr bridge,
const boost::system::error_code& error)
{
if (!error) {
bridge->shuttle();
} else {
Logger::logError("HTTP Connect Error");
bridge->close();
}
}
|