diff --git a/uppsrc/Web/SSL/SSL.upp b/uppsrc/Web/SSL/SSL.upp index d5ba5b1da..8b732a3d3 100644 --- a/uppsrc/Web/SSL/SSL.upp +++ b/uppsrc/Web/SSL/SSL.upp @@ -31,6 +31,7 @@ link(WIN32 MT MSC71) /nodefaultlib:libc; file WebSSL.h, util.cpp, + httpscli.cpp, src.tpp, srcimp.tpp, srcdoc.tpp, diff --git a/uppsrc/Web/SSL/WebSSL.h b/uppsrc/Web/SSL/WebSSL.h index db80a18db..cdb57a517 100644 --- a/uppsrc/Web/SSL/WebSSL.h +++ b/uppsrc/Web/SSL/WebSSL.h @@ -6,6 +6,7 @@ #include #include +#include #include NAMESPACE_UPP @@ -19,7 +20,7 @@ String SSLToString(X509_NAME *name); String ASN1ToString(ASN1_STRING *time); Date ASN1ToDate(ASN1_STRING *time); -void SSLInit(); +//void SSLInit(); class SSLBuffer { @@ -124,7 +125,7 @@ private: class SSLContext { public: - SSLContext(SSL_CTX *c = NULL) : ssl_ctx(c) { SSLInit(); } + SSLContext(SSL_CTX *c = NULL) : ssl_ctx(c) { /*SSLInit();*/ } ~SSLContext() { Clear(); } bool IsEmpty() const { return !ssl_ctx; } @@ -159,6 +160,20 @@ inline String SSLInfoCertNotAfter() { return "SSL_CERT_NOT_AFTER"; } // inline String SSLInfoCertVersion() { return "SSL_CERT_VERSION"; } // int inline String SSLInfoCertSerialNumber() { return "SSL_CERT_SERIAL_NUMBER"; } // String +class HttpsClient : public HttpClient { +public: + HttpsClient(); + + void Secure(bool s) { secure = s; } + + virtual bool CreateClientSocket(); + +public: + One ssl_context; + + bool secure; +}; + END_UPP_NAMESPACE #endif//flagNOSSL diff --git a/uppsrc/Web/SSL/httpscli.cpp b/uppsrc/Web/SSL/httpscli.cpp new file mode 100644 index 000000000..9596ad558 --- /dev/null +++ b/uppsrc/Web/SSL/httpscli.cpp @@ -0,0 +1,33 @@ +#ifndef flagNOSSL + +#include "WebSSL.h" + +NAMESPACE_UPP + +HttpsClient::HttpsClient() +{ + secure = true; +} + +bool HttpsClient::CreateClientSocket() +{ + if(!secure) + return HttpClient::CreateClientSocket(); + if(!ssl_context) { + ssl_context = new SSLContext; + if(!ssl_context->Create(SSLv3_client_method())) { + error = t_("Error creating SSL context."); + return false; + } + } + if(!SSLClientSocket(socket, *ssl_context, socket_host, socket_port, true, NULL, 0, false)) { + error = Socket::GetErrorText(); + return false; + } + socket.Linger(0); + return true; +} + +END_UPP_NAMESPACE + +#endif diff --git a/uppsrc/Web/SSL/util.cpp b/uppsrc/Web/SSL/util.cpp index f10bb0d38..ff02993f6 100644 --- a/uppsrc/Web/SSL/util.cpp +++ b/uppsrc/Web/SSL/util.cpp @@ -5,7 +5,7 @@ NAMESPACE_UPP -#define LOG_UPP_SSL_MALLOC 0 +#define LOG_UPP_SSL_MALLOC 1 #if LOG_UPP_SSL_MALLOC static int UPP_SSL_alloc = 0; @@ -25,7 +25,7 @@ void *SSLAlloc(size_t size) *aptr++ = alloc; #if LOG_UPP_SSL_MALLOC UPP_SSL_alloc += alloc; - RLOG("UPP_SSL_MALLOC(" << (int)size << ", alloc " << alloc << ") -> " << aptr << ", total = " << UPP_SSL_alloc); + RLOG("UPP_SSL_MALLOC(" << (int)size << ", alloc " << alloc << ") -> " << FormatIntHex(aptr) << ", total = " << UPP_SSL_alloc); #endif return aptr; } @@ -67,13 +67,31 @@ void *SSLRealloc(void *ptr, size_t size) memcpy(newaptr, ptr, min(*aptr - sizeof(int), size)); #if LOG_UPP_SSL_MALLOC UPP_SSL_alloc += newalloc - *aptr; - RLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int)size << ", alloc " << newalloc << ") -> " << newaptr - << ", total = " << UPP_SSL_alloc); + RLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int)size << ", alloc " << newalloc << ") -> " + << FormatIntHex(newaptr) << ", total = " << UPP_SSL_alloc); #endif MemoryFree(aptr); return newaptr; } +INITBLOCK { + Socket::Init(); + CRYPTO_set_mem_functions(SSLAlloc, SSLRealloc, SSLFree); + SSL_load_error_strings(); + SSL_library_init(); +} + +EXITBLOCK { + CONF_modules_unload(1); +// destroy_ui_method(); + EVP_cleanup(); +// ENGINE_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_state(0); + ERR_free_strings(); +} + +/* void SSLInit() { static bool inited = false; @@ -86,6 +104,7 @@ void SSLInit() SSL_library_init(); } } +*/ String SSLGetLastError() { @@ -415,7 +434,7 @@ int SSLSocketData::Write(const void *buf, int amount) bool SSLSocketData::OpenClient(const char *host, int port, bool nodelay, dword *my_addr, int timeout, bool blocking) { - if(!Data::OpenClient(host, port, nodelay, my_addr, timeout, blocking)) + if(!Data::OpenClient(host, port, nodelay, my_addr, timeout, /*blocking*/true)) return false; if(!(ssl = SSL_new(ssl_context))) { @@ -479,8 +498,7 @@ bool SSLSocketData::Close(int timeout_msec) if(ssl) SSL_shutdown(ssl); bool res = Data::Close(timeout_msec); - if(ssl) - { + if(ssl) { SSL_free(ssl); ssl = NULL; } diff --git a/uppsrc/Web/httpcli.cpp b/uppsrc/Web/httpcli.cpp index c2c5ce8cc..db5de89aa 100644 --- a/uppsrc/Web/httpcli.cpp +++ b/uppsrc/Web/httpcli.cpp @@ -246,21 +246,16 @@ String HttpClient::Execute(Gate2 progress) Close(); error = Null; bool use_proxy = !IsNull(proxy_host); - String sock_host = (use_proxy ? proxy_host : host); - int sock_port = (use_proxy ? proxy_port : port); + socket_host = (use_proxy ? proxy_host : host); + socket_port = (use_proxy ? proxy_port : port); - LLOG("socket host = " << sock_host << ":" << sock_port); - if(!socket.IsOpen()) { - if(!ClientSocket(socket, sock_host, sock_port, true, NULL, 0, false)) { - error = Socket::GetErrorText(); - return String::GetVoid(); - } - socket.Linger(0); - } + LLOG("socket host = " << socket_host << ":" << socket_port); + if(!socket.IsOpen() && !CreateClientSocket()) + return String::GetVoid(); while(!socket.PeekWrite(1000)) { int time = msecs(); if(time >= end_time) { - error = NFormat(t_("%s:%d: connecting to host timed out"), sock_host, sock_port); + error = NFormat(t_("%s:%d: connecting to host timed out"), socket_host, socket_port); return String::GetVoid(); } if(progress(time - start_time, end_time - start_time)) { @@ -534,6 +529,16 @@ EXIT: return body; } +bool HttpClient::CreateClientSocket() +{ + if(!ClientSocket(socket, socket_host, socket_port, true, NULL, 0, false)) { + error = Socket::GetErrorText(); + return false; + } + socket.Linger(0); + return true; +} + String HttpClientGet(String url, String proxy, String username, String password, String *server_headers, String *error, Gate2 progress, int timeout, int num_redirect, int retries) diff --git a/uppsrc/Web/httpcli.h b/uppsrc/Web/httpcli.h index 760ba7b46..c13013990 100644 --- a/uppsrc/Web/httpcli.h +++ b/uppsrc/Web/httpcli.h @@ -67,7 +67,10 @@ public: void Close() { socket.Close(); } static void Trace(bool b = true); + + virtual bool CreateClientSocket(); + public: Socket socket; bool keepalive; @@ -107,6 +110,9 @@ public: String redirect_url; String authenticate; + + String socket_host; + int socket_port; enum { DEFAULT_PORT = 80,