[haiku-commits] haiku: hrev49808 - src/kits/network/libnetapi headers/os/net

  • From: pulkomandy@xxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 11 Nov 2015 01:19:00 +0100 (CET)

hrev49808 adds 1 changeset to branch 'master'
old head: 959355842feef458222e6b1648b29ccf9671de51
new head: c6149613643d55ee2d86c866343b3acee19627c3
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=c6149613643d+%5E959355842fee

----------------------------------------------------------------------------

c6149613643d: Implement CONNECT pass-through for HTTPS proxy

* When using a proxy, HTTPS connexion must still go directly to the
target website. The proxy can then act as a TCP stream relay and just
transmit the raw SSL stream between the client and website.
* For this, we ask the proxy sending an HTTP request with the CONNECT
method. If the proxy supports this, we can then send anything as the
payload and it will be forwarded.
* Untested, as the network here in Dusseldorf doesn't let me use a
proxy.

ticket : #10973

[ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision: hrev49808
Commit: c6149613643d55ee2d86c866343b3acee19627c3
URL: http://cgit.haiku-os.org/haiku/commit/?id=c6149613643d
Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date: Wed Nov 11 00:06:01 2015 UTC

Ticket: https://dev.haiku-os.org/ticket/10973

----------------------------------------------------------------------------

7 files changed, 232 insertions(+), 58 deletions(-)
headers/os/net/HttpRequest.h | 9 +-
headers/os/net/ProxySecureSocket.h | 32 ++++++++
headers/os/net/SecureSocket.h | 7 +-
src/kits/network/libnetapi/HttpRequest.cpp | 86 ++++++++++++++------
src/kits/network/libnetapi/Jamfile | 1 +
src/kits/network/libnetapi/ProxySecureSocket.cpp | 76 +++++++++++++++++
src/kits/network/libnetapi/SecureSocket.cpp | 79 ++++++++++--------

----------------------------------------------------------------------------

diff --git a/headers/os/net/HttpRequest.h b/headers/os/net/HttpRequest.h
index 6bac063..bc9d0b0 100644
--- a/headers/os/net/HttpRequest.h
+++ b/headers/os/net/HttpRequest.h
@@ -16,6 +16,12 @@
#include <NetworkRequest.h>


+namespace BPrivate {
+ class CheckedSecureSocket;
+ class CheckedProxySecureSocket;
+};
+
+
class BHttpRequest : public BNetworkRequest {
public:

BHttpRequest(const BUrl& url,
@@ -76,7 +82,8 @@ private:
BString& _ResultStatusText();

// SSL failure management
- friend class CheckedSecureSocket;
+ friend class BPrivate::CheckedSecureSocket;
+ friend class
BPrivate::CheckedProxySecureSocket;
bool
_CertificateVerificationFailed(

BCertificate& certificate,
const
char* message);
diff --git a/headers/os/net/ProxySecureSocket.h
b/headers/os/net/ProxySecureSocket.h
new file mode 100644
index 0000000..42b445e
--- /dev/null
+++ b/headers/os/net/ProxySecureSocket.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _PROXY_SECURE_SOCKET_H
+#define _PROXY_SECURE_SOCKET_H
+
+
+#include <SecureSocket.h>
+
+
+class BProxySecureSocket : public BSecureSocket {
+public:
+
BProxySecureSocket(const BNetworkAddress& proxy);
+
BProxySecureSocket(const BNetworkAddress& proxy,
+ const
BNetworkAddress& peer,
+
bigtime_t timeout = B_INFINITE_TIMEOUT);
+
BProxySecureSocket(const BProxySecureSocket& other);
+ virtual ~BProxySecureSocket();
+
+ // BSocket implementation
+
+ virtual status_t Connect(const BNetworkAddress&
peer,
+
bigtime_t timeout = B_INFINITE_TIMEOUT);
+
+private:
+ const BNetworkAddress fProxyAddress;
+};
+
+
+#endif // _PROXY_SECURE_SOCKET_H
+
diff --git a/headers/os/net/SecureSocket.h b/headers/os/net/SecureSocket.h
index 09d3c30..8e13d20 100644
--- a/headers/os/net/SecureSocket.h
+++ b/headers/os/net/SecureSocket.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011, Haiku, Inc. All Rights Reserved.
+ * Copyright 2011-2015, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _SECURE_SOCKET_H
@@ -23,6 +23,8 @@ public:
virtual bool
CertificateVerificationFailed(BCertificate&

certificate, const char* message);

+ status_t InitCheck();
+
// BSocket implementation

virtual status_t Connect(const BNetworkAddress&
peer,
@@ -37,6 +39,9 @@ public:
virtual ssize_t Read(void* buffer, size_t size);
virtual ssize_t Write(const void* buffer,
size_t size);

+protected:
+ status_t _Setup();
+
private:
friend class BCertificate;
class Private;
diff --git a/src/kits/network/libnetapi/HttpRequest.cpp
b/src/kits/network/libnetapi/HttpRequest.cpp
index 3c36250..f1e090b 100644
--- a/src/kits/network/libnetapi/HttpRequest.cpp
+++ b/src/kits/network/libnetapi/HttpRequest.cpp
@@ -23,6 +23,7 @@
#include <Debug.h>
#include <DynamicBuffer.h>
#include <File.h>
+#include <ProxySecureSocket.h>
#include <Socket.h>
#include <SecureSocket.h>
#include <StackOrHeapArray.h>
@@ -32,33 +33,66 @@
static const int32 kHttpBufferSize = 4096;


-class CheckedSecureSocket: public BSecureSocket
-{
-public:
- CheckedSecureSocket(BHttpRequest*
request);
+namespace BPrivate {

- bool CertificateVerificationFailed(BCertificate&
certificate,
- const char* message);
+ class CheckedSecureSocket: public BSecureSocket
+ {
+ public:
+ CheckedSecureSocket(BHttpRequest* request);

-private:
- BHttpRequest* fRequest;
-};
+ bool
CertificateVerificationFailed(BCertificate& certificate,
+ const char* message);

+ private:
+ BHttpRequest* fRequest;
+ };

-CheckedSecureSocket::CheckedSecureSocket(BHttpRequest* request)
- :
- BSecureSocket(),
- fRequest(request)
-{
-}

+ CheckedSecureSocket::CheckedSecureSocket(BHttpRequest* request)
+ :
+ BSecureSocket(),
+ fRequest(request)
+ {
+ }
+
+
+ bool
+ CheckedSecureSocket::CertificateVerificationFailed(BCertificate&
certificate,
+ const char* message)
+ {
+ return fRequest->_CertificateVerificationFailed(certificate,
message);
+ }

-bool
-CheckedSecureSocket::CertificateVerificationFailed(BCertificate& certificate,
- const char* message)
-{
- return fRequest->_CertificateVerificationFailed(certificate, message);
-}
+
+ class CheckedProxySecureSocket: public BProxySecureSocket
+ {
+ public:
+ CheckedProxySecureSocket(const BNetworkAddress& proxy,
BHttpRequest* request);
+
+ bool
CertificateVerificationFailed(BCertificate& certificate,
+ const char* message);
+
+ private:
+ BHttpRequest* fRequest;
+ };
+
+
+ CheckedProxySecureSocket::CheckedProxySecureSocket(const
BNetworkAddress& proxy,
+ BHttpRequest* request)
+ :
+ BProxySecureSocket(proxy),
+ fRequest(request)
+ {
+ }
+
+
+ bool
+ CheckedProxySecureSocket::CertificateVerificationFailed(BCertificate&
certificate,
+ const char* message)
+ {
+ return fRequest->_CertificateVerificationFailed(certificate,
message);
+ }
+};


BHttpRequest::BHttpRequest(const BUrl& url, bool ssl, const char* protocolName,
@@ -488,9 +522,13 @@ BHttpRequest::_MakeRequest()
{
delete fSocket;

- if (fSSL)
- fSocket = new(std::nothrow) CheckedSecureSocket(this);
- else
+ if (fSSL) {
+ if (fContext->UseProxy()) {
+ BNetworkAddress proxy(fContext->GetProxyHost(),
fContext->GetProxyPort());
+ fSocket = new(std::nothrow)
BPrivate::CheckedProxySecureSocket(proxy, this);
+ } else
+ fSocket = new(std::nothrow)
BPrivate::CheckedSecureSocket(this);
+ } else
fSocket = new(std::nothrow) BSocket();

if (fSocket == NULL)
diff --git a/src/kits/network/libnetapi/Jamfile
b/src/kits/network/libnetapi/Jamfile
index a0d606c..3220ec6 100644
--- a/src/kits/network/libnetapi/Jamfile
+++ b/src/kits/network/libnetapi/Jamfile
@@ -66,6 +66,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
DatagramSocket.cpp
Socket.cpp
SecureSocket.cpp
+ ProxySecureSocket.cpp

# TODO: another add-on for file:// (a much simpler one)
FileRequest.cpp
diff --git a/src/kits/network/libnetapi/ProxySecureSocket.cpp
b/src/kits/network/libnetapi/ProxySecureSocket.cpp
new file mode 100644
index 0000000..1ad8a23
--- /dev/null
+++ b/src/kits/network/libnetapi/ProxySecureSocket.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Haiku, Inc.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <ProxySecureSocket.h>
+
+#include <stdio.h>
+
+
+BProxySecureSocket::BProxySecureSocket(const BNetworkAddress& proxy)
+ :
+ BSecureSocket(),
+ fProxyAddress(proxy)
+{
+}
+
+
+BProxySecureSocket::BProxySecureSocket(const BNetworkAddress& proxy, const
BNetworkAddress& peer,
+ bigtime_t timeout)
+ :
+ BSecureSocket(),
+ fProxyAddress(proxy)
+{
+ Connect(peer, timeout);
+}
+
+
+BProxySecureSocket::BProxySecureSocket(const BProxySecureSocket& other)
+ :
+ BSecureSocket(other),
+ fProxyAddress(other.fProxyAddress)
+{
+}
+
+
+BProxySecureSocket::~BProxySecureSocket()
+{
+}
+
+
+status_t
+BProxySecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
+{
+ status_t status = InitCheck();
+ if (status != B_OK)
+ return status;
+
+ BSocket::Connect(fProxyAddress, timeout);
+ if (status != B_OK)
+ return status;
+
+ BString connectRequest;
+ connectRequest.SetToFormat("CONNECT %s:%d HTTP/1.0\r\n\r\n",
+ peer.HostName().String(), peer.Port());
+ BSocket::Write(connectRequest.String(), connectRequest.Length());
+
+ char buffer[256];
+ ssize_t length = BSocket::Read(buffer, sizeof(buffer) - 1);
+ if (length <= 0)
+ return length;
+
+ buffer[length] = '\0';
+ int httpStatus = 0;
+ int matches = scanf(buffer, "HTTP/1.0 %d %*[^\r\n]\r\n\r\n",
httpStatus);
+ if (matches != 2)
+ return B_BAD_DATA;
+
+ if (httpStatus < 200 || httpStatus > 299)
+ return B_BAD_VALUE;
+
+ return _Setup();
+}
+
+
diff --git a/src/kits/network/libnetapi/SecureSocket.cpp
b/src/kits/network/libnetapi/SecureSocket.cpp
index 1e3beaa..c763e63 100644
--- a/src/kits/network/libnetapi/SecureSocket.cpp
+++ b/src/kits/network/libnetapi/SecureSocket.cpp
@@ -256,42 +256,15 @@ BSecureSocket::~BSecureSocket()
status_t
BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
{
- if (fPrivate == NULL)
- return B_NO_MEMORY;
-
- status_t state = fPrivate->InitCheck();
- if (state != B_OK)
- return state;
-
- status_t status = BSocket::Connect(peer, timeout);
+ status_t status = InitCheck();
if (status != B_OK)
return status;

- // Do this only after BSocket::Connect has checked wether we're already
- // connected. We don't want to kill an existing SSL session, as that
would
- // likely crash the protocol loop for it.
- if (fPrivate->fSSL != NULL) {
- SSL_free(fPrivate->fSSL);
- }
-
- fPrivate->fSSL = SSL_new(BSecureSocket::Private::Context());
- if (fPrivate->fSSL == NULL) {
- BSocket::Disconnect();
- return B_NO_MEMORY;
- }
-
- BIO_set_fd(fPrivate->fBIO, fSocket, BIO_NOCLOSE);
- SSL_set_bio(fPrivate->fSSL, fPrivate->fBIO, fPrivate->fBIO);
- SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this);
-
- int returnValue = SSL_connect(fPrivate->fSSL);
- if (returnValue <= 0) {
- TRACE("SSLConnection can't connect\n");
- BSocket::Disconnect();
- return fPrivate->ErrorCode(returnValue);
- }
+ status = BSocket::Connect(peer, timeout);
+ if (status != B_OK)
+ return status;

- return B_OK;
+ return _Setup();
}


@@ -322,6 +295,17 @@ BSecureSocket::WaitForReadable(bigtime_t timeout) const
}


+status_t
+BSecureSocket::InitCheck()
+{
+ if (fPrivate == NULL)
+ return B_NO_MEMORY;
+
+ status_t state = fPrivate->InitCheck();
+ return state;
+}
+
+
bool
BSecureSocket::CertificateVerificationFailed(BCertificate&, const char*)
{
@@ -363,6 +347,37 @@ BSecureSocket::Write(const void* buffer, size_t size)
}


+status_t
+BSecureSocket::_Setup()
+{
+ // Do this only after BSocket::Connect has checked wether we're already
+ // connected. We don't want to kill an existing SSL session, as that
would
+ // likely crash the protocol loop for it.
+ if (fPrivate->fSSL != NULL) {
+ SSL_free(fPrivate->fSSL);
+ }
+
+ fPrivate->fSSL = SSL_new(BSecureSocket::Private::Context());
+ if (fPrivate->fSSL == NULL) {
+ BSocket::Disconnect();
+ return B_NO_MEMORY;
+ }
+
+ BIO_set_fd(fPrivate->fBIO, fSocket, BIO_NOCLOSE);
+ SSL_set_bio(fPrivate->fSSL, fPrivate->fBIO, fPrivate->fBIO);
+ SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this);
+
+ int returnValue = SSL_connect(fPrivate->fSSL);
+ if (returnValue <= 0) {
+ TRACE("SSLConnection can't connect\n");
+ BSocket::Disconnect();
+ return fPrivate->ErrorCode(returnValue);
+ }
+
+ return B_OK;
+}
+
+
#else // OPENSSL_ENABLED




Other related posts:

  • » [haiku-commits] haiku: hrev49808 - src/kits/network/libnetapi headers/os/net - pulkomandy