SSLConnectionManager.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright (c) 2002-2009 Moxie Marlinspike
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 3 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  17. * USA
  18. */
  19. #include "FirefoxAddonUpdater.hpp"
  20. #include "FirefoxUpdater.hpp"
  21. #include "RawBridge.hpp"
  22. #include "HTTPSBridge.hpp"
  23. #include "SSLConnectionManager.hpp"
  24. #include "UpdateManager.hpp"
  25. #include "certificate/Certificate.hpp"
  26. #include "util/Destination.hpp"
  27. #include "FingerprintManager.hpp"
  28. #include <boost/asio.hpp>
  29. #include <boost/thread.hpp>
  30. #include <boost/bind.hpp>
  31. #include <boost/shared_ptr.hpp>
  32. using namespace boost::asio;
  33. SSLConnectionManager::SSLConnectionManager(io_service &io_service,
  34. CertificateManager &certificateManager,
  35. int sslListenPort)
  36. : acceptor(io_service, ip::tcp::endpoint(ip::tcp::v4(), sslListenPort)),
  37. certificateManager(certificateManager)
  38. {
  39. acceptIncomingConnection();
  40. }
  41. void SSLConnectionManager::acceptIncomingConnection() {
  42. boost::shared_ptr<ip::tcp::socket> socket(new ip::tcp::socket(acceptor.get_io_service()));
  43. acceptor.async_accept(*socket, boost::bind(&SSLConnectionManager::handleClientConnection,
  44. this, socket, placeholders::error));
  45. }
  46. void SSLConnectionManager::handleClientConnection(boost::shared_ptr<ip::tcp::socket> socket,
  47. const boost::system::error_code &error)
  48. {
  49. ip::tcp::endpoint originalDestination;
  50. Destination::getOriginalDestination(*socket, originalDestination);
  51. ip::address source = socket->remote_endpoint().address();
  52. bool isValidWildcardTarget = FingerprintManager::getInstance()->isValidWildcardTarget(source);
  53. bool isValidSourceTarget = FingerprintManager::getInstance()->isValidTarget(source);
  54. bool isValidCertTarget = certificateManager.isValidTarget(originalDestination,
  55. isValidWildcardTarget);
  56. if (isValidSourceTarget && isValidCertTarget)
  57. boost::thread intercept(boost::bind(&SSLConnectionManager::interceptConnection,
  58. this, socket, originalDestination,
  59. isValidWildcardTarget));
  60. else
  61. shuttleConnection(socket, originalDestination);
  62. acceptIncomingConnection();
  63. }
  64. void SSLConnectionManager::shuttleConnection(boost::shared_ptr<ip::tcp::socket> clientSocket,
  65. ip::tcp::endpoint &destination)
  66. {
  67. Bridge::ptr bridge = RawBridge::create(clientSocket, destination, acceptor.get_io_service());
  68. bridge->shuttle();
  69. }
  70. void SSLConnectionManager::interceptUpdate(boost::shared_ptr<ip::tcp::socket> clientSocket,
  71. ip::tcp::endpoint &destination,
  72. bool wildcardOK)
  73. {
  74. try {
  75. Logger::logError("Intercepting Update...");
  76. FirefoxUpdater updater(clientSocket, destination);
  77. updater.handshakeWithClient(certificateManager, wildcardOK);
  78. updater.readMetaUpdateRequest();
  79. updater.sendMetaUpdateResponse();
  80. updater.close();
  81. } catch (SSLConnectionError &error) {
  82. std::stringstream errorStream;
  83. errorStream << "Got exception: " << error.what();
  84. std::string error = errorStream.str();
  85. Logger::logError(error);
  86. } catch (FirefoxUpdateException &error) {
  87. std::stringstream errorStream;
  88. errorStream << "Got exception: " << error.what();
  89. std::string error = errorStream.str();
  90. Logger::logError(error);
  91. }
  92. }
  93. void SSLConnectionManager::interceptAddon(boost::shared_ptr<ip::tcp::socket> clientSocket,
  94. ip::tcp::endpoint &destination,
  95. bool wildcardOK)
  96. {
  97. try {
  98. Logger::logError("Intercepting addon..");
  99. FirefoxAddonUpdater updater(clientSocket, destination);
  100. updater.handshakeWithClient(certificateManager, wildcardOK);
  101. updater.readMetaUpdateRequest();
  102. updater.sendMetaUpdateResponse();
  103. updater.close();
  104. } catch (SSLConnectionError &error) {
  105. std::stringstream errorStream;
  106. errorStream << "Got exception: " << error.what();
  107. std::string error = errorStream.str();
  108. Logger::logError(error);
  109. } catch (FirefoxUpdateException &error) {
  110. std::stringstream errorStream;
  111. errorStream << "Got exception: " << error.what();
  112. std::string error = errorStream.str();
  113. Logger::logError(error);
  114. }
  115. }
  116. void SSLConnectionManager::interceptSSL(boost::shared_ptr<ip::tcp::socket> clientSocket,
  117. ip::tcp::endpoint &destination,
  118. bool wildcardOK)
  119. {
  120. ip::tcp::socket serverSocket(acceptor.get_io_service());
  121. boost::system::error_code error;
  122. serverSocket.connect(destination, error);
  123. if (!error) {
  124. try {
  125. boost::shared_ptr<SSLBridge> bridge((destination.port() == HTTPS_PORT) ?
  126. new HTTPSBridge(clientSocket, &serverSocket) :
  127. new SSLBridge(clientSocket, &serverSocket));
  128. bridge->handshakeWithServer();
  129. bridge->handshakeWithClient(certificateManager, wildcardOK);
  130. bridge->shuttleData();
  131. bridge->close();
  132. } catch (SSLConnectionError &error) {
  133. std::stringstream errorStream;
  134. errorStream << "Got exception: " << error.what();
  135. std::string error = errorStream.str();
  136. Logger::logError(error);
  137. }
  138. }
  139. }
  140. void SSLConnectionManager::interceptConnection(boost::shared_ptr<ip::tcp::socket> clientSocket,
  141. ip::tcp::endpoint destination,
  142. bool wildcardOK)
  143. {
  144. if (UpdateManager::getInstance()->isUpdateTarget(destination))
  145. interceptUpdate(clientSocket, destination, wildcardOK);
  146. else if (UpdateManager::getInstance()->isAddonTarget(destination))
  147. interceptAddon(clientSocket, destination, wildcardOK);
  148. else
  149. interceptSSL(clientSocket, destination, wildcardOK);
  150. }