Fix bugs of simultaneous connection.
Change to reuse SSL sessions.
This version may be nearly stable (not for 1.99 but for 1.98b).
int Mode; /* 転送モード (EXIST_xxx) */\r
HWND hWndTrans; /* 転送中ダイアログのウインドウハンドル */\r
int Abort; /* 転送中止フラグ (ABORT_xxx) */\r
- // 暗号化通信対応\r
- int CryptMode; /* 暗号化通信モード (CRYPT_xxx) */\r
// 同時接続対応\r
int ThreadCount;\r
struct transpacket *Next;\r
// ;\r
if(CryptMode == CRYPT_FTPIS)\r
{\r
- if(AttachSSL(ContSock))\r
+ if(AttachSSL(ContSock, INVALID_SOCKET))\r
{\r
while((Sts = ReadReplyMessage(ContSock, Buf, 1024, &CancelFlg, TmpBuf) / 100) == FTP_PRELIM)\r
;\r
{\r
if(IsOpenSSLLoaded() && (Sts = command(ContSock, Reply, &CancelFlg, "AUTH TLS")) == 234)\r
{\r
- if(AttachSSL(ContSock))\r
+ if(AttachSSL(ContSock, INVALID_SOCKET))\r
{\r
if((Sts = command(ContSock, Reply, &CancelFlg, "PBSZ 0")) == 200)\r
{\r
static int MirrorDelNotify(int Cur, int Notify, TRANSPACKET *Pkt);\r
static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
static void SetErrorMsg(char *fmt, ...);\r
+// 同時接続対応\r
+static char* GetErrMsg();\r
\r
/*===== ローカルなワーク =====*/\r
\r
static int MoveToForeground = NO; /* ウインドウを前面に移動するかどうか (YES/NO) */\r
\r
static char CurDir[FMAX_PATH+1] = { "" };\r
-static char ErrMsg[ERR_MSG_LEN+7];\r
+// 同時接続対応\r
+//static char ErrMsg[ERR_MSG_LEN+7];\r
+static char ErrMsg[MAX_DATA_CONNECTION+1][ERR_MSG_LEN+7];\r
+static DWORD ErrMsgThreadId[MAX_DATA_CONNECTION+1];\r
+static HANDLE hErrMsgMutex;\r
\r
// 同時接続対応\r
static int WaitForMainThread = NO;\r
\r
hListAccMutex = CreateMutex( NULL, FALSE, NULL );\r
hRunMutex = CreateMutex( NULL, TRUE, NULL );\r
+ // 同時接続対応\r
+ hErrMsgMutex = CreateMutex( NULL, FALSE, NULL );\r
\r
ClearAll = NO;\r
ForceAbort = NO;\r
\r
CloseHandle( hListAccMutex );\r
CloseHandle( hRunMutex );\r
+ // 同時接続対応\r
+ CloseHandle( hErrMsgMutex );\r
return;\r
}\r
\r
BackgrndMessageProc();\r
Sleep(1);\r
}\r
- memset(ErrMsg, NUL, ERR_MSG_LEN+7);\r
+// memset(ErrMsg, NUL, ERR_MSG_LEN+7);\r
+ memset(GetErrMsg(), NUL, ERR_MSG_LEN+7);\r
\r
// Canceled = NO;\r
Canceled[ThreadCount] = NO;\r
ReleaseMutex(hListAccMutex);\r
// FTPS対応\r
// iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
- if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
+ if(IsSSLAttached(Pkt->ctrl_skt))\r
{\r
- if(AttachSSL(data_socket))\r
+ if(AttachSSL(data_socket, Pkt->ctrl_skt))\r
iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
else\r
- iRetCode = FTP_ERROR;\r
+ iRetCode = 500;\r
}\r
else\r
iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
ReleaseMutex(hListAccMutex);\r
// FTPS対応\r
// iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
- if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
+ if(IsSSLAttached(Pkt->ctrl_skt))\r
{\r
- if(AttachSSL(data_socket))\r
+ if(AttachSSL(data_socket, Pkt->ctrl_skt))\r
iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
else\r
- iRetCode = FTP_ERROR;\r
+ iRetCode = 500;\r
}\r
else\r
iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
{\r
case WM_INITDIALOG :\r
SendDlgItemMessage(hDlg, UPDOWN_ERR_FNAME, WM_SETTEXT, 0, (LPARAM)lParam);\r
- SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)ErrMsg);\r
+ // 同時接続対応\r
+// SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)ErrMsg);\r
+ SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)GetErrMsg());\r
return(TRUE);\r
\r
case WM_COMMAND :\r
ReleaseMutex(hListAccMutex);\r
// FTPS対応\r
// iRetCode = UpLoadFile(Pkt, data_socket);\r
- if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
+ if(IsSSLAttached(Pkt->ctrl_skt))\r
{\r
- if(AttachSSL(data_socket))\r
+ if(AttachSSL(data_socket, Pkt->ctrl_skt))\r
iRetCode = UpLoadFile(Pkt, data_socket);\r
else\r
- iRetCode = FTP_ERROR;\r
+ iRetCode = 500;\r
}\r
else\r
iRetCode = UpLoadFile(Pkt, data_socket);\r
ReleaseMutex(hListAccMutex);\r
// FTPS対応\r
// iRetCode = UpLoadFile(Pkt, data_socket);\r
- if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
+ if(IsSSLAttached(Pkt->ctrl_skt))\r
{\r
- if(AttachSSL(data_socket))\r
+ if(AttachSSL(data_socket, Pkt->ctrl_skt))\r
iRetCode = UpLoadFile(Pkt, data_socket);\r
else\r
- iRetCode = FTP_ERROR;\r
+ iRetCode = 500;\r
}\r
else\r
iRetCode = UpLoadFile(Pkt, data_socket);\r
{\r
va_list Args;\r
\r
- if(strlen(ErrMsg) == 0)\r
+ // 同時接続対応\r
+// if(strlen(ErrMsg) == 0)\r
+ if(strlen(GetErrMsg()) == 0)\r
{\r
va_start(Args, fmt);\r
- wvsprintf(ErrMsg, fmt, Args);\r
+ // 同時接続対応\r
+// wvsprintf(ErrMsg, fmt, Args);\r
+ wvsprintf(GetErrMsg(), fmt, Args);\r
va_end(Args);\r
}\r
return;\r
}\r
\r
\r
+// 同時接続対応\r
+static char* GetErrMsg()\r
+{\r
+ char* r;\r
+ DWORD ThreadId;\r
+ int i;\r
+ r = NULL;\r
+ WaitForSingleObject(hErrMsgMutex, INFINITE);\r
+ ThreadId = GetCurrentThreadId();\r
+ i = 0;\r
+ while(i < MAX_DATA_CONNECTION + 1)\r
+ {\r
+ if(ErrMsgThreadId[i] == ThreadId)\r
+ {\r
+ r = ErrMsg[i];\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ if(!r)\r
+ {\r
+ i = 0;\r
+ while(i < MAX_DATA_CONNECTION + 1)\r
+ {\r
+ if(ErrMsgThreadId[i] == 0)\r
+ {\r
+ ErrMsgThreadId[i] = ThreadId;\r
+ r = ErrMsg[i];\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ }\r
+ ReleaseMutex(hErrMsgMutex);\r
+ return r;\r
+}\r
break;\r
\r
case WM_ASYNC_DBASE :\r
+ // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり\r
+ RegistAsyncTableDbase((HANDLE)wParam);\r
// スレッド衝突のバグ修正\r
WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
break;\r
}\r
}\r
- // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり\r
- if(Pos == MAX_SIGNAL_ENTRY_DBASE)\r
- {\r
- for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
- {\r
- if(SignalDbase[Pos].Async == 0)\r
- {\r
- SignalDbase[Pos].Async = (HANDLE)wParam;\r
- SignalDbase[Pos].Done = 0;\r
- SignalDbase[Pos].ErrorDb = 0;\r
- if(HIWORD(lParam) != 0)\r
- {\r
- SignalDbase[Pos].ErrorDb = 1;\r
-#if DBG_MSG\r
- DoPrintf("##### SignalDatabase: error");\r
-#endif\r
- }\r
- SignalDbase[Pos].Done = 1;\r
-#if DBG_MSG\r
- DoPrintf("##### SignalDatabase: Done");\r
-#endif\r
- break;\r
- }\r
- }\r
- }\r
// スレッド衝突のバグ修正\r
ReleaseMutex(hAsyncTblAccMutex);\r
break;\r
#endif\r
CancelCheckWork = NO;\r
\r
+ // スレッド衝突のバグ修正\r
+ WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
+ UnRegistAsyncTable(s);\r
// FTPS対応\r
// Ret = closesocket(s);\r
Ret = closesocketS(s);\r
Ret = 0;\r
}\r
\r
- WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
+ // スレッド衝突のバグ修正\r
+// WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
if(BackgrndMessageProc() == YES)\r
CancelCheckWork = YES;\r
- UnRegistAsyncTable(s);\r
+ // スレッド衝突のバグ修正\r
+// UnRegistAsyncTable(s);\r
\r
#if DBG_MSG\r
DoPrintf("# Exit close");\r
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
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
_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
_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
|| !(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
|| !(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
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
if(!g_bOpenSSLLoaded)\r
return FALSE;\r
r = FALSE;\r
{\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
+ r = TRUE;\r
while(p_SSL_connect(*ppSSL) != 1)\r
{\r
LeaveCriticalSection(&g_OpenSSLLock);\r
}\r
EnterCriticalSection(&g_OpenSSLLock);\r
}\r
+ if(ConfirmSSLCertificate(*ppSSL))\r
+ {\r
+ }\r
+ else\r
+ {\r
+ DetachSSL(s);\r
+ r = FALSE;\r
+ }\r
}\r
else\r
{\r
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
{\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
{\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
void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback);\r
void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback);\r
BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName);\r
-BOOL AttachSSL(SOCKET s);\r
+BOOL AttachSSL(SOCKET s, SOCKET parent);\r
BOOL DetachSSL(SOCKET s);\r
BOOL IsSSLAttached(SOCKET s);\r
SOCKET socketS(int af, int type, int protocol);\r