OSDN Git Service

Fix bugs of corruption on resuming downloading files larger than 4GB.
[ffftp/ffftp.git] / socketwrapper.c
index 48ebfcf..612218e 100644 (file)
@@ -30,6 +30,8 @@ typedef int (__cdecl* _SSL_read)(SSL*, void*, int);
 typedef int (__cdecl* _SSL_get_error)(SSL*, int);\r
 typedef X509* (__cdecl* _SSL_get_peer_certificate)(const SSL*);\r
 typedef long (__cdecl* _SSL_get_verify_result)(const SSL*);\r
+typedef SSL_SESSION* (__cdecl* _SSL_get_session)(SSL*);\r
+typedef int (__cdecl* _SSL_set_session)(SSL*, SSL_SESSION*);\r
 typedef BIO_METHOD* (__cdecl* _BIO_s_mem)();\r
 typedef BIO* (__cdecl* _BIO_new)(BIO_METHOD*);\r
 typedef int (__cdecl* _BIO_free)(BIO*);\r
@@ -37,7 +39,6 @@ typedef long (__cdecl* _BIO_ctrl)(BIO*, int, long, void*);
 typedef void (__cdecl* _X509_free)(X509*);\r
 typedef int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long);\r
 typedef X509_NAME* (__cdecl* _X509_get_subject_name)(X509*);\r
-typedef X509_NAME* (__cdecl* _X509_get_issuer_name)(X509*);\r
 typedef int (__cdecl* _X509_NAME_print_ex)(BIO*, X509_NAME*, int, unsigned long);\r
 \r
 _SSL_load_error_strings p_SSL_load_error_strings;\r
@@ -58,6 +59,8 @@ _SSL_read p_SSL_read;
 _SSL_get_error p_SSL_get_error;\r
 _SSL_get_peer_certificate p_SSL_get_peer_certificate;\r
 _SSL_get_verify_result p_SSL_get_verify_result;\r
+_SSL_get_session p_SSL_get_session;\r
+_SSL_set_session p_SSL_set_session;\r
 _BIO_s_mem p_BIO_s_mem;\r
 _BIO_new p_BIO_new;\r
 _BIO_free p_BIO_free;\r
@@ -65,7 +68,6 @@ _BIO_ctrl p_BIO_ctrl;
 _X509_free p_X509_free;\r
 _X509_print_ex p_X509_print_ex;\r
 _X509_get_subject_name p_X509_get_subject_name;\r
-_X509_get_issuer_name p_X509_get_issuer_name;\r
 _X509_NAME_print_ex p_X509_NAME_print_ex;\r
 \r
 #define MAX_SSL_SOCKET 64\r
@@ -124,7 +126,9 @@ BOOL LoadOpenSSL()
                || !(p_SSL_read = (_SSL_read)GetProcAddress(g_hOpenSSL, "SSL_read"))\r
                || !(p_SSL_get_error = (_SSL_get_error)GetProcAddress(g_hOpenSSL, "SSL_get_error"))\r
                || !(p_SSL_get_peer_certificate = (_SSL_get_peer_certificate)GetProcAddress(g_hOpenSSL, "SSL_get_peer_certificate"))\r
-               || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result")))\r
+               || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result"))\r
+               || !(p_SSL_get_session = (_SSL_get_session)GetProcAddress(g_hOpenSSL, "SSL_get_session"))\r
+               || !(p_SSL_set_session = (_SSL_set_session)GetProcAddress(g_hOpenSSL, "SSL_set_session")))\r
        {\r
                if(g_hOpenSSL)\r
                        FreeLibrary(g_hOpenSSL);\r
@@ -140,7 +144,6 @@ BOOL LoadOpenSSL()
                || !(p_X509_free = (_X509_free)GetProcAddress(g_hOpenSSLCommon, "X509_free"))\r
                || !(p_X509_print_ex = (_X509_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_print_ex"))\r
                || !(p_X509_get_subject_name = (_X509_get_subject_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_subject_name"))\r
-               || !(p_X509_get_issuer_name = (_X509_get_issuer_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_issuer_name"))\r
                || !(p_X509_NAME_print_ex = (_X509_NAME_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_NAME_print_ex")))\r
        {\r
                if(g_hOpenSSL)\r
@@ -330,11 +333,15 @@ BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName)
        return bResult;\r
 }\r
 \r
-BOOL AttachSSL(SOCKET s)\r
+BOOL AttachSSL(SOCKET s, SOCKET parent)\r
 {\r
        BOOL r;\r
        DWORD Time;\r
        SSL** ppSSL;\r
+       SSL** ppSSLParent;\r
+       SSL_SESSION* pSession;\r
+       int Return;\r
+       int Error;\r
        if(!g_bOpenSSLLoaded)\r
                return FALSE;\r
        r = FALSE;\r
@@ -350,18 +357,53 @@ BOOL AttachSSL(SOCKET s)
                        {\r
                                if(p_SSL_set_fd(*ppSSL, s) != 0)\r
                                {\r
-                                       r = TRUE;\r
+                                       if(parent != INVALID_SOCKET)\r
+                                       {\r
+                                               if(ppSSLParent = FindSSLPointerFromSocket(parent))\r
+                                               {\r
+                                                       if(pSession = p_SSL_get_session(*ppSSLParent))\r
+                                                       {\r
+                                                               if(p_SSL_set_session(*ppSSL, pSession) == 1)\r
+                                                               {\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
                                        // SSLのネゴシエーションには時間がかかる場合がある\r
-                                       while(p_SSL_connect(*ppSSL) != 1)\r
+                                       r = TRUE;\r
+                                       while(r)\r
                                        {\r
-                                               LeaveCriticalSection(&g_OpenSSLLock);\r
-                                               if(g_pOpenSSLTimeoutCallback() || (g_OpenSSLTimeout > 0 && timeGetTime() - Time >= g_OpenSSLTimeout))\r
+                                               Return = p_SSL_connect(*ppSSL);\r
+                                               if(Return == 1)\r
+                                                       break;\r
+                                               Error = p_SSL_get_error(*ppSSL, Return);\r
+                                               if(Error == SSL_ERROR_WANT_READ || Error == SSL_ERROR_WANT_WRITE)\r
+                                               {\r
+                                                       LeaveCriticalSection(&g_OpenSSLLock);\r
+                                                       if(g_pOpenSSLTimeoutCallback() || (g_OpenSSLTimeout > 0 && timeGetTime() - Time >= g_OpenSSLTimeout))\r
+                                                               r = FALSE;\r
+                                                       EnterCriticalSection(&g_OpenSSLLock);\r
+                                               }\r
+                                               else\r
+                                                       r = FALSE;\r
+                                       }\r
+                                       if(r)\r
+                                       {\r
+                                               if(ConfirmSSLCertificate(*ppSSL))\r
                                                {\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       LeaveCriticalSection(&g_OpenSSLLock);\r
                                                        DetachSSL(s);\r
                                                        r = FALSE;\r
                                                        EnterCriticalSection(&g_OpenSSLLock);\r
-                                                       break;\r
                                                }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               LeaveCriticalSection(&g_OpenSSLLock);\r
+                                               DetachSSL(s);\r
                                                EnterCriticalSection(&g_OpenSSLLock);\r
                                        }\r
                                }\r
@@ -371,14 +413,6 @@ BOOL AttachSSL(SOCKET s)
                                        DetachSSL(s);\r
                                        EnterCriticalSection(&g_OpenSSLLock);\r
                                }\r
-                               if(ConfirmSSLCertificate(*ppSSL))\r
-                               {\r
-                               }\r
-                               else\r
-                               {\r
-                                       DetachSSL(s);\r
-                                       r = FALSE;\r
-                               }\r
                        }\r
                }\r
        }\r
@@ -414,7 +448,7 @@ BOOL IsSSLAttached(SOCKET s)
        ppSSL = FindSSLPointerFromSocket(s);\r
        LeaveCriticalSection(&g_OpenSSLLock);\r
        if(!ppSSL)\r
-               return TRUE;\r
+               return FALSE;\r
        return TRUE;\r
 }\r
 \r
@@ -437,7 +471,7 @@ SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen)
 {\r
        SOCKET r;\r
        r = accept(s, addr, addrlen);\r
-       if(!AttachSSL(r))\r
+       if(!AttachSSL(r, INVALID_SOCKET))\r
        {\r
                closesocket(r);\r
                return INVALID_SOCKET;\r
@@ -449,7 +483,7 @@ int connectS(SOCKET s, const struct sockaddr *name, int namelen)
 {\r
        int r;\r
        r = connect(s, name, namelen);\r
-       if(!AttachSSL(r))\r
+       if(!AttachSSL(r, INVALID_SOCKET))\r
                return SOCKET_ERROR;\r
        return r;\r
 }\r