From: s_kawamoto Date: Sun, 11 Sep 2011 14:59:43 +0000 (+0900) Subject: Fix bugs of UTF-8 to UTF-16 API bridge. X-Git-Url: http://git.sourceforge.jp/view?p=ffftp%2Fffftp.git;a=commitdiff_plain;h=756eb24e756aa444a4f4bc2bfd2640d525ccdcb1 Fix bugs of UTF-8 to UTF-16 API bridge. Add UIs for encryption. Add support for FTP over Explicit SSL/TLS (OpenSSL is required). Fix bugs of synchronization between threads. Fix bugs of behavior caused by uninitialized variables. Fix bugs of algorithm to wait for SOCKET signals. --- diff --git a/FFFTP.exe b/FFFTP.exe index b17506b..30c7891 100644 Binary files a/FFFTP.exe and b/FFFTP.exe differ diff --git a/FFFTP.vc90.vcproj b/FFFTP.vc90.vcproj index ab1b0aa..4457a7a 100644 --- a/FFFTP.vc90.vcproj +++ b/FFFTP.vc90.vcproj @@ -335,6 +335,10 @@ > + + @@ -375,6 +379,10 @@ RelativePath=".\Resource\resource.h" > + + + + @@ -332,6 +336,10 @@ > + + @@ -365,9 +373,17 @@ > + + + + + + @@ -375,6 +379,10 @@ RelativePath=".\Resource_eng\resource.h" > + + + + @@ -332,6 +336,10 @@ > + + @@ -365,9 +373,17 @@ > + + + + Size; Pkt.Time = Pos->Time; Pkt.KanjiCode = AskHostKanjiCode(); + // UTF-8‘Ήž Pkt.KanjiCodeDesired = AskLocalKanjiCode(); Pkt.KanaCnv = AskHostKanaCnv(); @@ -302,6 +303,7 @@ void DirectDownLoadProc(char *Fname) /* ƒTƒCƒY‚Æ“ú•t‚Í“]‘—‘¤ƒXƒŒƒbƒh‚Ŏ擾‚µAƒZƒbƒg‚·‚é */ Pkt.KanjiCode = AskHostKanjiCode(); + // UTF-8‘Ήž Pkt.KanjiCodeDesired = AskLocalKanjiCode(); Pkt.KanaCnv = AskHostKanaCnv(); @@ -553,6 +555,7 @@ void MirrorDownloadProc(int Notify) Pkt.Time = RemotePos->Time; // Pkt.Attr = 0; Pkt.KanjiCode = AskHostKanjiCode(); + // UTF-8‘Ήž Pkt.KanjiCodeDesired = AskLocalKanjiCode(); Pkt.KanaCnv = AskHostKanaCnv(); Pkt.Mode = EXIST_OVW; @@ -947,6 +950,7 @@ void UpLoadListProc(int ChName, int All) Pkt.Time = Pos->Time; Pkt.Attr = AskUpLoadFileAttr(Pkt.RemoteFile); Pkt.KanjiCode = AskHostKanjiCode(); + // UTF-8‘Ήž Pkt.KanjiCodeDesired = AskLocalKanjiCode(); Pkt.KanaCnv = AskHostKanaCnv(); Pkt.Mode = CheckRemoteFile(&Pkt, RemoteList); @@ -1098,6 +1102,7 @@ void UpLoadDragProc(WPARAM wParam) Pkt.Time = Pos->Time; Pkt.Attr = AskUpLoadFileAttr(Pkt.RemoteFile); Pkt.KanjiCode = AskHostKanjiCode(); + // UTF-8‘Ήž Pkt.KanjiCodeDesired = AskLocalKanjiCode(); Pkt.KanaCnv = AskHostKanaCnv(); Pkt.Mode = CheckRemoteFile(&Pkt, RemoteList); @@ -1365,6 +1370,7 @@ void MirrorUploadProc(int Notify) Pkt.Time = LocalPos->Time; Pkt.Attr = AskUpLoadFileAttr(Pkt.RemoteFile); Pkt.KanjiCode = AskHostKanjiCode(); + // UTF-8‘Ήž Pkt.KanjiCodeDesired = AskLocalKanjiCode(); Pkt.KanaCnv = AskHostKanaCnv(); Pkt.Mode = EXIST_OVW; diff --git a/getput.c b/getput.c index cf28616..8aa9db2 100644 --- a/getput.c +++ b/getput.c @@ -57,7 +57,7 @@ #define SOCKBUF_SIZE (256 * 1024) /* End */ -#ifdef DISABLE_NETWORK_BUFFERS +#ifdef DISABLE_TRANSFER_NETWORK_BUFFERS #undef BUFSIZE #define BUFSIZE (64 * 1024) // RWIN’lˆÈ‰º‚ŏ[•ª‚È‘å‚«‚³‚ª–]‚Ü‚µ‚¢‚ÆŽv‚í‚ê‚éB #undef SET_BUFFER_SIZE @@ -1017,7 +1017,17 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) if(data_socket != INVALID_SOCKET) { - iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + // FTPS‘Ήž +// iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) + { + if(AttachSSL(data_socket)) + iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + else + iRetCode = FTP_ERROR; + } + else + iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); // data_socket = DoClose(data_socket); } } @@ -1070,6 +1080,8 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) { if((data_socket = connectsock(Adrs, Port, MSGJPN091, CancelCheckWork)) != INVALID_SOCKET) { + // •Ï”‚ª–¢‰Šú‰»‚̃oƒOC³ + Flg = 1; if(setsockopt(data_socket, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR) ReportWSError("setsockopt", WSAGetLastError()); @@ -1079,7 +1091,17 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "%s", Buf); if(iRetCode/100 == FTP_PRELIM) { - iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + // FTPS‘Ήž +// iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) + { + if(AttachSSL(data_socket)) + iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + else + iRetCode = FTP_ERROR; + } + else + iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); // data_socket = DoClose(data_socket); } else @@ -1155,8 +1177,8 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc /* End */ #endif -#ifdef DISABLE_NETWORK_BUFFERS - // ”O‚Ì‚½‚ߎóMƒoƒbƒtƒ@‚𖳌ø‚É‚·‚éB + // ”O‚Ì‚½‚ߎóMƒoƒbƒtƒ@‚𖳌ø‚É‚·‚é +#ifdef DISABLE_TRANSFER_NETWORK_BUFFERS int buf_size = 0; setsockopt(dSkt, SOL_SOCKET, SO_RCVBUF, (char *)&buf_size, sizeof(buf_size)); #endif @@ -2002,7 +2024,17 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) if(data_socket != INVALID_SOCKET) { - iRetCode = UpLoadFile(Pkt, data_socket); + // FTPS‘Ήž +// iRetCode = UpLoadFile(Pkt, data_socket); + if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) + { + if(AttachSSL(data_socket)) + iRetCode = UpLoadFile(Pkt, data_socket); + else + iRetCode = FTP_ERROR; + } + else + iRetCode = UpLoadFile(Pkt, data_socket); data_socket = DoClose(data_socket); } } @@ -2052,6 +2084,8 @@ static int UpLoadPassive(TRANSPACKET *Pkt) { if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled)) != INVALID_SOCKET) { + // •Ï”‚ª–¢‰Šú‰»‚̃oƒOC³ + Flg = 1; if(setsockopt(data_socket, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR) ReportWSError("setsockopt", WSAGetLastError()); @@ -2064,7 +2098,17 @@ static int UpLoadPassive(TRANSPACKET *Pkt) iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf); if(iRetCode/100 == FTP_PRELIM) { - iRetCode = UpLoadFile(Pkt, data_socket); + // FTPS‘Ήž +// iRetCode = UpLoadFile(Pkt, data_socket); + if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) + { + if(AttachSSL(data_socket)) + iRetCode = UpLoadFile(Pkt, data_socket); + else + iRetCode = FTP_ERROR; + } + else + iRetCode = UpLoadFile(Pkt, data_socket); data_socket = DoClose(data_socket); } @@ -2140,8 +2184,8 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) /* End */ #endif -#ifdef DISABLE_NETWORK_BUFFERS - // ”O‚Ì‚½‚ß‘—Mƒoƒbƒtƒ@‚𖳌ø‚É‚·‚éB + // ”O‚Ì‚½‚ß‘—Mƒoƒbƒtƒ@‚𖳌ø‚É‚·‚é +#ifdef DISABLE_TRANSFER_NETWORK_BUFFERS int buf_size = 0; setsockopt(dSkt, SOL_SOCKET, SO_SNDBUF, (char *)&buf_size, sizeof(buf_size)); #endif @@ -3021,7 +3065,7 @@ static int IsSpecialDevice(char *Fname) int Sts; Sts = NO; - // ƒoƒOC³ + // ”äŠr‚ª•sŠ®‘S‚ȃoƒOC³ // if((_stricmp(Fname, "CON") == 0) || // (_stricmp(Fname, "PRN") == 0) || // (_stricmp(Fname, "AUX") == 0) || diff --git a/history.c b/history.c index fe2ab64..91c3c74 100644 --- a/history.c +++ b/history.c @@ -223,6 +223,10 @@ static void CopyHostToHistory(HOSTDATA *Host, HISTORYDATA *New) New->DialupAlways = Host->DialupAlways; New->DialupNotify = Host->DialupNotify; strcpy(New->DialEntry, Host->DialEntry); + // ˆÃ†‰»’ʐM‘Ήž + New->UseFTPES = Host->UseFTPES; + New->UseFTPIS = Host->UseFTPIS; + New->UseSFTP = Host->UseSFTP; return; } @@ -272,6 +276,10 @@ void CopyHistoryToHost(HISTORYDATA *Hist, HOSTDATA *Host) Host->DialupAlways = Hist->DialupAlways; Host->DialupNotify = Hist->DialupNotify; strcpy(Host->DialEntry, Hist->DialEntry); + // ˆÃ†‰»’ʐM‘Ήž + Host->UseFTPES = Hist->UseFTPES; + Host->UseFTPIS = Hist->UseFTPIS; + Host->UseSFTP = Hist->UseSFTP; return; } diff --git a/hostman.c b/hostman.c index abecc33..4589389 100644 --- a/hostman.c +++ b/hostman.c @@ -63,6 +63,8 @@ static BOOL CALLBACK AdvSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPA static BOOL CALLBACK CodeSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); static BOOL CALLBACK DialupSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); static BOOL CALLBACK Adv2SettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); +// ˆÃ†‰»’ʐM‘Ήž +static BOOL CALLBACK CryptSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); /*===== ŠO•”ŽQÆ =====*/ @@ -1015,6 +1017,10 @@ int CopyHostFromListInConnect(int Num, HOSTDATA *Set) Set->UseNLST_R = Pos->Set.UseNLST_R; Set->LastDir = Pos->Set.LastDir; Set->TimeZone = Pos->Set.TimeZone; + // ˆÃ†‰»’ʐM‘Ήž + Set->UseFTPES = Pos->Set.UseFTPES; + Set->UseFTPIS = Pos->Set.UseFTPIS; + Set->UseSFTP = Pos->Set.UseSFTP; Sts = SUCCESS; } return(Sts); @@ -1288,6 +1294,11 @@ void CopyDefaultHost(HOSTDATA *Set) Set->DialupAlways = NO; Set->DialupNotify = YES; strcpy(Set->DialEntry, ""); + // ˆÃ†‰»’ʐM‘Ήž + Set->CryptMode = CRYPT_NONE; + Set->UseFTPES = YES; + Set->UseFTPIS = YES; + Set->UseSFTP = YES; return; } @@ -1499,7 +1510,9 @@ void ImportFromWSFTP(void) static int DispHostSetDlg(HWND hDlg) { - PROPSHEETPAGE psp[5]; +// SFTPAFTPESAFTPIS‘Ήž +// PROPSHEETPAGE psp[5]; + PROPSHEETPAGE psp[6]; PROPSHEETHEADER psh; psp[0].dwSize = sizeof(PROPSHEETPAGE); @@ -1552,6 +1565,17 @@ static int DispHostSetDlg(HWND hDlg) psp[4].lParam = 0; psp[4].pfnCallback = NULL; +// SFTPAFTPESAFTPIS‘Ήž + psp[5].dwSize = sizeof(PROPSHEETPAGE); + psp[5].dwFlags = PSP_USETITLE | PSP_HASHELP; + psp[5].hInstance = GetFtpInst(); + psp[5].pszTemplate = MAKEINTRESOURCE(hset_crypt_dlg); + psp[5].pszIcon = NULL; + psp[5].pfnDlgProc = CryptSettingProc; + psp[5].pszTitle = MSGJPN313; + psp[5].lParam = 0; + psp[5].pfnCallback = NULL; + psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_HASHELP | PSH_NOAPPLYNOW | PSH_PROPSHEETPAGE; psh.hwndParent = hDlg; @@ -1851,11 +1875,11 @@ static BOOL CALLBACK CodeSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LP // UTF-8‘Ήž case HSET_NO_CNV : - case HSET_SJIS_CNV : case HSET_UTF8N_CNV : EnableWindow(GetDlgItem(hDlg, HSET_HANCNV), FALSE); break; + case HSET_SJIS_CNV : case HSET_FN_JIS_CNV : case HSET_FN_EUC_CNV : EnableWindow(GetDlgItem(hDlg, HSET_FN_HANCNV), TRUE); @@ -2071,3 +2095,65 @@ static BOOL CALLBACK Adv2SettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LP } +// ˆÃ†‰»’ʐM‘Ήž +static BOOL CALLBACK CryptSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) +{ + NMHDR *pnmhdr; + int Num; + + switch (iMessage) + { + case WM_INITDIALOG : + if(IsOpenSSLLoaded()) + { + SendDlgItemMessage(hDlg, HSET_FTPES, BM_SETCHECK, TmpHost.UseFTPES, 0); + SendDlgItemMessage(hDlg, HSET_FTPIS, BM_SETCHECK, TmpHost.UseFTPIS, 0); + SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, TmpHost.UseSFTP, 0); + } + else + { + SendDlgItemMessage(hDlg, HSET_FTPES, BM_SETCHECK, BST_UNCHECKED, 0); + EnableWindow(GetDlgItem(hDlg, HSET_FTPES), FALSE); + SendDlgItemMessage(hDlg, HSET_FTPIS, BM_SETCHECK, BST_UNCHECKED, 0); + EnableWindow(GetDlgItem(hDlg, HSET_FTPIS), FALSE); + SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, BST_UNCHECKED, 0); + EnableWindow(GetDlgItem(hDlg, HSET_SFTP), FALSE); + } + // TODO: FTPIS‘Ήž + SendDlgItemMessage(hDlg, HSET_FTPIS, BM_SETCHECK, BST_UNCHECKED, 0); + EnableWindow(GetDlgItem(hDlg, HSET_FTPIS), FALSE); + // TODO: SFTP‘Ήž + SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, BST_UNCHECKED, 0); + EnableWindow(GetDlgItem(hDlg, HSET_SFTP), FALSE); + return(TRUE); + + case WM_NOTIFY: + pnmhdr = (NMHDR FAR *)lParam; + switch(pnmhdr->code) + { + case PSN_APPLY : + if(IsOpenSSLLoaded()) + { + TmpHost.UseFTPES = SendDlgItemMessage(hDlg, HSET_FTPES, BM_GETCHECK, 0, 0); + // TODO: FTPIS‘Ήž +// TmpHost.UseFTPIS = SendDlgItemMessage(hDlg, HSET_FTPIS, BM_GETCHECK, 0, 0); + // TODO: SFTP‘Ήž +// TmpHost.UseSFTP = SendDlgItemMessage(hDlg, HSET_SFTP, BM_GETCHECK, 0, 0); + } + Apply = YES; + break; + + case PSN_RESET : + break; + + case PSN_HELP : + // TODO: ƒwƒ‹ƒvƒgƒsƒbƒN +// hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000032); + break; + } + break; + } + return(FALSE); +} + + diff --git a/main.c b/main.c index 8aebef3..8432896 100644 --- a/main.c +++ b/main.c @@ -236,6 +236,10 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi InitCommonControls(); +#ifdef USE_OPENSSL + LoadOpenSSL(); +#endif + Ret = FALSE; hWndFtp = NULL; hInstFtp = hInstance; @@ -265,6 +269,9 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi Ret = Msg.wParam; } UnregisterClass(FtpClassStr, hInstFtp); +#ifdef USE_OPENSSL + FreeOpenSSL(); +#endif OleUninitialize(); return(Ret); } @@ -375,6 +382,9 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow) { LoadRegistory(); + // ˆÃ†‰»’ʐM‘Ήž + SetSSLTimeoutCallback(TimeOut * 1000, SSLTimeoutCallback); + LoadJre(); if(NoRasControl == NO) LoadRasLib(); @@ -458,6 +468,14 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow) } } + // ˆÃ†‰»’ʐM‘Ήž +#ifdef USE_OPENSSL + if(IsOpenSSLLoaded()) + SetTaskMsg(MSGJPN318); + else + SetTaskMsg(MSGJPN319); +#endif + if(sts == FAIL) DeleteAllObject(); @@ -969,6 +987,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA DispTransferType(); CheckHistoryNum(0); SetAllHistoryToMenu(); + // ˆÃ†‰»’ʐM‘Ήž + SetSSLTimeoutCallback(TimeOut * 1000, SSLTimeoutCallback); break; case MENU_FILTER : @@ -2577,6 +2597,7 @@ int BackgrndMessageProc(void) int Ret; Ret = NO; + SendMessage(GetMainHwnd(), WM_NULL, 0, 0); while(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) { if(!HtmlHelp(NULL, NULL, HH_PRETRANSLATEMESSAGE, (DWORD)&Msg)) @@ -2669,3 +2690,19 @@ int EnterMasterPasswordAndSet( int Res, HWND hWnd ) } return 0; } + +// ˆÃ†‰»’ʐM‘Ήž +BOOL __stdcall SSLTimeoutCallback() +{ + Sleep(1); + if(BackgrndMessageProc() == YES) + return TRUE; + // ”O‚Ì‚½‚߃c[ƒ‹ƒo[‚ÌMENU_ABORT‚àŠm”F +// if(MainTransPkt.Abort != ABORT_NONE) +// { +// MainTransPkt.Abort = ABORT_NONE; +// return TRUE; +// } + return FALSE; +} + diff --git a/mbswrapper.c b/mbswrapper.c index 8cb6257..fc4841a 100644 --- a/mbswrapper.c +++ b/mbswrapper.c @@ -414,6 +414,20 @@ START_ROUTINE pw0 = DuplicateMtoW((LPCSTR)lParam, -1); r = SendMessageW(hWnd, CB_ADDSTRING, wParam, (LPARAM)pw0); break; + case CB_GETLBTEXT: + Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1; + pw0 = AllocateStringW(Size); + SendMessageW(hWnd, CB_GETLBTEXT, wParam, (LPARAM)pw0); + // ƒoƒbƒtƒ@’·•s–¾‚Ì‚½‚߃I[ƒo[ƒ‰ƒ“‚̉”\«‚ ‚è + WtoM((LPSTR)lParam, Size * 4, pw0, -1); + r = TerminateStringM((LPSTR)lParam, Size * 4); + break; + case CB_GETLBTEXTLEN: + Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1; + pw0 = AllocateStringW(Size); + SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0); + r = WtoM(NULL, 0, pw0, -1) - 1; + break; case CB_INSERTSTRING: pw0 = DuplicateMtoW((LPCSTR)lParam, -1); r = SendMessageW(hWnd, CB_INSERTSTRING, wParam, (LPARAM)pw0); @@ -441,12 +455,18 @@ START_ROUTINE break; case LB_GETTEXT: Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1; - pw0 = AllocateStringW(Size * 4); + pw0 = AllocateStringW(Size); SendMessageW(hWnd, LB_GETTEXT, wParam, (LPARAM)pw0); // ƒoƒbƒtƒ@’·•s–¾‚Ì‚½‚߃I[ƒo[ƒ‰ƒ“‚̉”\«‚ ‚è WtoM((LPSTR)lParam, Size * 4, pw0, -1); r = TerminateStringM((LPSTR)lParam, Size * 4); break; + case LB_GETTEXTLEN: + Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1; + pw0 = AllocateStringW(Size); + SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0); + r = WtoM(NULL, 0, pw0, -1) - 1; + break; default: r = SendMessageW(hWnd, Msg, wParam, lParam); break; @@ -1343,8 +1363,3 @@ END_ROUTINE return r; } - - - - - diff --git a/mesg-eng.h b/mesg-eng.h index 554aa2b..f3fa824 100644 --- a/mesg-eng.h +++ b/mesg-eng.h @@ -310,3 +310,10 @@ #define MSGJPN310 "EUC Kanji Code (Local)" #define MSGJPN311 "JIS Kanji Code (Local)" #define MSGJPN312 "UTF-8N Kanji Code (Local)" +#define MSGJPN313 "Encryption" +#define MSGJPN314 "Communication is not encrypted.\r\nPassword and other data may be intercepted by a third party." +#define MSGJPN315 "Using FTP over Explicit SSL/TLS (FTPES)." +#define MSGJPN316 "Using FTP over Inplicit SSL/TLS (FTPIS)." +#define MSGJPN317 "Using SSH FTP (SFTP)." +#define MSGJPN318 "OpenSSL is loaded." +#define MSGJPN319 "OpenSSL is not installed.\r\nCommunication will not be encrypted." diff --git a/mesg-eng.old.h b/mesg-eng.old.h index ce44780..7ca33c0 100644 --- a/mesg-eng.old.h +++ b/mesg-eng.old.h @@ -310,3 +310,10 @@ #define MSGJPN310 "EUC Kanji Code (Local)" #define MSGJPN311 "JIS Kanji Code (Local)" #define MSGJPN312 "UTF-8N Kanji Code (Local)" +#define MSGJPN313 "Encryption" +#define MSGJPN314 "Communication is not encrypted.\r\nPassword and other data may be intercepted by a third party." +#define MSGJPN315 "Using FTP over Explicit SSL/TLS (FTPES)." +#define MSGJPN316 "Using FTP over Inplicit SSL/TLS (FTPIS)." +#define MSGJPN317 "Using SSH FTP (SFTP)." +#define MSGJPN318 "OpenSSL is loaded." +#define MSGJPN319 "OpenSSL is not installed.\r\nCommunication will not be encrypted." diff --git a/mesg-jpn.h b/mesg-jpn.h index 395d8dd..df2baa4 100644 --- a/mesg-jpn.h +++ b/mesg-jpn.h @@ -310,3 +310,10 @@ #define MSGJPN310 "\xE3\x83\xAD\xE3\x83\xBC\xE3\x82\xAB\xE3\x83\xAB\xE3\x81\xAE\xE6\xBC\xA2\xE5\xAD\x97\xE3\x82\xB3\xE3\x83\xBC\xE3\x83\x89\xE3\x81\xAF\x45UC" #define MSGJPN311 "\xE3\x83\xAD\xE3\x83\xBC\xE3\x82\xAB\xE3\x83\xAB\xE3\x81\xAE\xE6\xBC\xA2\xE5\xAD\x97\xE3\x82\xB3\xE3\x83\xBC\xE3\x83\x89\xE3\x81\xAFJIS" #define MSGJPN312 "\xE3\x83\xAD\xE3\x83\xBC\xE3\x82\xAB\xE3\x83\xAB\xE3\x81\xAE\xE6\xBC\xA2\xE5\xAD\x97\xE3\x82\xB3\xE3\x83\xBC\xE3\x83\x89\xE3\x81\xAFUTF-8N" +#define MSGJPN313 "\xE6\x9A\x97\xE5\x8F\xB7\xE5\x8C\x96" +#define MSGJPN314 "\xE9\x80\x9A\xE4\xBF\xA1\xE3\x81\xAF\xE6\x9A\x97\xE5\x8F\xB7\xE5\x8C\x96\xE3\x81\x95\xE3\x82\x8C\xE3\x81\xA6\xE3\x81\x84\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93.\r\n\xE7\xAC\xAC\xE4\xB8\x89\xE8\x80\x85\xE3\x81\xAB\xE3\x83\x91\xE3\x82\xB9\xE3\x83\xAF\xE3\x83\xBC\xE3\x83\x89\xE3\x81\x8A\xE3\x82\x88\xE3\x81\xB3\xE5\x86\x85\xE5\xAE\xB9\xE3\x82\x92\xE5\x82\x8D\xE5\x8F\x97\xE3\x81\x95\xE3\x82\x8C\xE3\x82\x8B\xE5\x8F\xAF\xE8\x83\xBD\xE6\x80\xA7\xE3\x81\x8C\xE3\x81\x82\xE3\x82\x8A\xE3\x81\xBE\xE3\x81\x99." +#define MSGJPN315 "FTP over Explicit SSL/TLS (FTPES)\xE3\x82\x92\xE4\xBD\xBF\xE7\x94\xA8\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x99." +#define MSGJPN316 "FTP over Inplicit SSL/TLS (FTPIS)\xE3\x82\x92\xE4\xBD\xBF\xE7\x94\xA8\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x99." +#define MSGJPN317 "SSH FTP (SFTP)\xE3\x82\x92\xE4\xBD\xBF\xE7\x94\xA8\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x99." +#define MSGJPN318 "OpenSSL\xE3\x81\x8C\xE8\xAA\xAD\xE3\x81\xBF\xE8\xBE\xBC\xE3\x81\xBE\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F." +#define MSGJPN319 "OpenSSL\xE3\x81\x8C\xE3\x82\xA4\xE3\x83\xB3\xE3\x82\xB9\xE3\x83\x88\xE3\x83\xBC\xE3\x83\xAB\xE3\x81\x95\xE3\x82\x8C\xE3\x81\xA6\xE3\x81\x84\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93.\r\n\xE9\x80\x9A\xE4\xBF\xA1\xE3\x81\xAE\xE6\x9A\x97\xE5\x8F\xB7\xE5\x8C\x96\xE3\x81\xAF\xE8\xA1\x8C\xE3\x82\x8F\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93." diff --git a/mesg-jpn.old.h b/mesg-jpn.old.h index 1677022..159c38e 100644 --- a/mesg-jpn.old.h +++ b/mesg-jpn.old.h @@ -310,3 +310,10 @@ #define MSGJPN310 "ƒ[ƒJƒ‹‚ÌŠ¿ŽšƒR[ƒh‚ÍEUC" #define MSGJPN311 "ƒ[ƒJƒ‹‚ÌŠ¿ŽšƒR[ƒh‚ÍJIS" #define MSGJPN312 "ƒ[ƒJƒ‹‚ÌŠ¿ŽšƒR[ƒh‚ÍUTF-8N" +#define MSGJPN313 "ˆÃ†‰»" +#define MSGJPN314 "’ʐM‚͈͆‰»‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ.\r\n‘æŽOŽÒ‚ɃpƒXƒ[ƒh‚¨‚æ‚Ñ“à—e‚ð–TŽó‚³‚ê‚é‰Â”\«‚ª‚ ‚è‚Ü‚·." +#define MSGJPN315 "FTP over Explicit SSL/TLS (FTPES)‚ðŽg—p‚µ‚Ü‚·." +#define MSGJPN316 "FTP over Inplicit SSL/TLS (FTPIS)‚ðŽg—p‚µ‚Ü‚·." +#define MSGJPN317 "SSH FTP (SFTP)‚ðŽg—p‚µ‚Ü‚·." +#define MSGJPN318 "OpenSSL‚ª“ǂݍž‚Ü‚ê‚Ü‚µ‚½." +#define MSGJPN319 "OpenSSL‚ªƒCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ.\r\n’ʐM‚̈͆‰»‚͍s‚í‚ê‚Ü‚¹‚ñ." diff --git a/registory.c b/registory.c index d36c574..70fc3ce 100644 --- a/registory.c +++ b/registory.c @@ -462,6 +462,10 @@ void SaveRegistory(void) SaveIntNum(hKey5, "UseIt", Hist.DialupAlways, DefaultHist.DialupAlways); SaveIntNum(hKey5, "Notify", Hist.DialupNotify, DefaultHist.DialupNotify); SaveStr(hKey5, "DialTo", Hist.DialEntry, DefaultHist.DialEntry); + // ˆÃ†‰»’ʐM‘Ήž + SaveIntNum(hKey5, "FTPES", Hist.UseFTPES, DefaultHist.UseFTPES); + SaveIntNum(hKey5, "FTPIS", Hist.UseFTPIS, DefaultHist.UseFTPIS); + SaveIntNum(hKey5, "SFTP", Hist.UseSFTP, DefaultHist.UseSFTP); CloseSubKey(hKey5); n++; @@ -530,6 +534,10 @@ void SaveRegistory(void) SaveIntNum(hKey5, "UseIt", Host.DialupAlways, DefaultHost.DialupAlways); SaveIntNum(hKey5, "Notify", Host.DialupNotify, DefaultHost.DialupNotify); SaveStr(hKey5, "DialTo", Host.DialEntry, DefaultHost.DialEntry); + // ˆÃ†‰»’ʐM‘Ήž + SaveIntNum(hKey5, "FTPES", Host.UseFTPES, DefaultHost.UseFTPES); + SaveIntNum(hKey5, "FTPIS", Host.UseFTPIS, DefaultHost.UseFTPIS); + SaveIntNum(hKey5, "SFTP", Host.UseSFTP, DefaultHost.UseSFTP); } CloseSubKey(hKey5); } @@ -780,6 +788,10 @@ int LoadRegistory(void) ReadIntValueFromReg(hKey5, "UseIt", &Hist.DialupAlways); ReadIntValueFromReg(hKey5, "Notify", &Hist.DialupNotify); ReadStringFromReg(hKey5, "DialTo", Hist.DialEntry, RAS_NAME_LEN+1); + // ˆÃ†‰»’ʐM‘Ήž + ReadIntValueFromReg(hKey5, "FTPES", &Hist.UseFTPES); + ReadIntValueFromReg(hKey5, "FTPIS", &Hist.UseFTPIS); + ReadIntValueFromReg(hKey5, "SFTP", &Hist.UseSFTP); CloseSubKey(hKey5); AddHistoryToHistory(&Hist); @@ -845,6 +857,10 @@ int LoadRegistory(void) ReadIntValueFromReg(hKey5, "UseIt", &Host.DialupAlways); ReadIntValueFromReg(hKey5, "Notify", &Host.DialupNotify); ReadStringFromReg(hKey5, "DialTo", Host.DialEntry, RAS_NAME_LEN+1); + // ˆÃ†‰»’ʐM‘Ήž + ReadIntValueFromReg(hKey5, "FTPES", &Host.UseFTPES); + ReadIntValueFromReg(hKey5, "FTPIS", &Host.UseFTPIS); + ReadIntValueFromReg(hKey5, "SFTP", &Host.UseSFTP); CloseSubKey(hKey5); diff --git a/remote.c b/remote.c index 46cf59a..2244517 100644 --- a/remote.c +++ b/remote.c @@ -1025,7 +1025,15 @@ static int ReadOneLine(SOCKET cSkt, char *Buf, int Max, int *CancelCheckWork) memset(Buf, 0, Max); if((SizeOnce == -2) || (AskTransferNow() == YES)) - DisconnectSet(); + // “]‘—’†‚É‘S‚Ä’†Ž~‚ðs‚¤‚Æ•s³‚ȃf[ƒ^‚ª“¾‚ç‚ê‚éê‡‚̃oƒOC³ + // ƒGƒ‰[‚ÌŽí—Þ‚É‚æ‚Á‚Ä‚Í–³ŒÀƒ‹[ƒv‚ƃXƒ^ƒbƒNƒI[ƒo[ƒtƒ[‚̉”\«‚ ‚è +// DisconnectSet(); + { + if(SizeOnce == -1) + ReConnectCmdSkt(); + else + DisconnectSet(); + } } else { diff --git a/socket.c b/socket.c index 7ec5b1c..b823c40 100644 --- a/socket.c +++ b/socket.c @@ -73,8 +73,11 @@ typedef struct { } ASYNCSIGNALDATABASE; -#define MAX_SIGNAL_ENTRY 10 -#define MAX_SIGNAL_ENTRY_DBASE 5 +// ƒXƒŒƒbƒhÕ“˂̃oƒOC³ +//#define MAX_SIGNAL_ENTRY 10 +//#define MAX_SIGNAL_ENTRY_DBASE 5 +#define MAX_SIGNAL_ENTRY 100 +#define MAX_SIGNAL_ENTRY_DBASE 50 @@ -104,6 +107,8 @@ static ASYNCSIGNAL Signal[MAX_SIGNAL_ENTRY]; static ASYNCSIGNALDATABASE SignalDbase[MAX_SIGNAL_ENTRY_DBASE]; //static HANDLE hAsyncTblAccMutex; +// ƒXƒŒƒbƒhÕ“˂̃oƒOC³ +static HANDLE hAsyncTblAccMutex; @@ -148,10 +153,18 @@ int MakeSocketWin(HWND hWnd, HINSTANCE hInst) { // hAsyncTblAccMutex = CreateMutex(NULL, FALSE, NULL); - for(i = 0; i < MAX_SIGNAL_ENTRY; i++) - Signal[i].Socket = INVALID_SOCKET; - for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++) - SignalDbase[i].Async = 0; + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ +// for(i = 0; i < MAX_SIGNAL_ENTRY; i++) +// Signal[i].Socket = INVALID_SOCKET; +// for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++) +// SignalDbase[i].Async = 0; + if(hAsyncTblAccMutex = CreateMutex(NULL, FALSE, NULL)) + { + for(i = 0; i < MAX_SIGNAL_ENTRY; i++) + Signal[i].Socket = INVALID_SOCKET; + for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++) + SignalDbase[i].Async = 0; + } Sts = SUCCESS; } return(Sts); @@ -170,6 +183,9 @@ int MakeSocketWin(HWND hWnd, HINSTANCE hInst) void DeleteSocketWin(void) { // CloseHandle(hAsyncTblAccMutex); + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + CloseHandle(hAsyncTblAccMutex); + hAsyncTblAccMutex = NULL; if(hWndSocket != NULL) DestroyWindow(hWndSocket); @@ -196,6 +212,8 @@ static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LP switch(message) { case WM_ASYNC_SOCKET : + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) { if(Signal[Pos].Socket == (SOCKET)wParam) @@ -247,9 +265,13 @@ static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LP break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); break; case WM_ASYNC_DBASE : + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++) { if(SignalDbase[Pos].Async == (HANDLE)wParam) @@ -268,6 +290,8 @@ static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LP break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); break; default : @@ -293,6 +317,8 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask) int Sts; int Pos; + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; *Error = 0; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) @@ -344,6 +370,8 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask) break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY) { @@ -375,6 +403,8 @@ static int AskAsyncDoneDbase(HANDLE Async, int *Error) int Sts; int Pos; + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; *Error = 0; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++) @@ -392,6 +422,8 @@ static int AskAsyncDoneDbase(HANDLE Async, int *Error) break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY_DBASE) { @@ -417,6 +449,8 @@ static int RegistAsyncTable(SOCKET s) int Sts; int Pos; + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) { @@ -426,9 +460,13 @@ static int RegistAsyncTable(SOCKET s) break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY) { + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) { if(Signal[Pos].Socket == INVALID_SOCKET) @@ -447,6 +485,8 @@ static int RegistAsyncTable(SOCKET s) break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY) { @@ -473,6 +513,8 @@ static int RegistAsyncTableDbase(HANDLE Async) int Sts; int Pos; + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++) { @@ -482,9 +524,13 @@ static int RegistAsyncTableDbase(HANDLE Async) break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY_DBASE) { + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) { if(SignalDbase[Pos].Async == 0) @@ -499,6 +545,8 @@ static int RegistAsyncTableDbase(HANDLE Async) break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY_DBASE) { @@ -525,6 +573,8 @@ static int UnRegistAsyncTable(SOCKET s) int Sts; int Pos; + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) { @@ -538,6 +588,8 @@ static int UnRegistAsyncTable(SOCKET s) break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); return(Sts); } @@ -556,6 +608,8 @@ static int UnRegistAsyncTableDbase(HANDLE Async) int Sts; int Pos; + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++) { @@ -569,6 +623,8 @@ static int UnRegistAsyncTableDbase(HANDLE Async) break; } } + // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + ReleaseMutex(hAsyncTblAccMutex); return(Sts); } @@ -652,7 +708,12 @@ int do_closesocket(SOCKET s) #endif CancelCheckWork = NO; - Ret = closesocket(s); + // FTPS‘Ήž +// Ret = closesocket(s); + if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) + Ret = closesocketS(s); + else + Ret = closesocket(s); if(Ret == SOCKET_ERROR) { Error = 0; @@ -703,7 +764,12 @@ int do_connect(SOCKET s, const struct sockaddr *name, int namelen, int *CancelCh Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE); if(Ret != SOCKET_ERROR) { - Ret = connect(s, name, namelen); + // FTPS‘Ήž +// Ret = connect(s, name, namelen); + if(AskCryptMode() == CRYPT_FTPIS) + Ret = connectS(s, name, namelen); + else + Ret = connect(s, name, namelen); if(Ret == SOCKET_ERROR) { do @@ -797,7 +863,12 @@ SOCKET do_accept(SOCKET s, struct sockaddr *addr, int *addrlen) { do { - Ret2 = accept(s, addr, addrlen); + // FTPS‘Ήž +// Ret2 = accept(s, addr, addrlen); + if(AskCryptMode() == CRYPT_FTPIS) + Ret2 = acceptS(s, addr, addrlen); + else + Ret2 = accept(s, addr, addrlen); if(Ret2 != INVALID_SOCKET) { #if DBG_MSG @@ -866,7 +937,10 @@ int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *Cance if(TimeOut != 0) time(&StartTime); - while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES)) + // FTPS‘Ήž + // OpenSSL‚Å‚ÍŽóMŠm”F‚ÍFD_READ‚ª•¡”‰ñŽóM‚³‚ê‚é‰Â”\«‚ª‚ ‚é +// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES)) + while(AskCryptMode() == CRYPT_NONE && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES)) { if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES) { @@ -897,13 +971,38 @@ int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *Cance DoPrintf("## recv()"); #endif - Ret = recv(s, buf, len, flags); + // FTPS‘Ήž +// Ret = recv(s, buf, len, flags); + if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) + Ret = recvS(s, buf, len, flags); + else + Ret = recv(s, buf, len, flags); if(Ret != SOCKET_ERROR) break; Error = WSAGetLastError(); Sleep(1); if(BackgrndMessageProc() == YES) break; + // FTPS‘Ήž + // ŽóMŠm”F‚ðƒoƒCƒpƒX‚µ‚½‚½‚ß‚±‚±‚Ń^ƒCƒ€ƒAƒEƒg‚ÌŠm”F + if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) + { + if(BackgrndMessageProc() == YES) + *CancelCheckWork = YES; + } + else if(TimeOut != 0) + { + time(&ElapseTime); + ElapseTime -= StartTime; + if(ElapseTime >= TimeOut) + { + DoPrintf("do_recv timed out"); + *TimeOutErr = YES; + *CancelCheckWork = YES; + } + } + if(*CancelCheckWork == YES) + break; } while(Error == WSAEWOULDBLOCK); } @@ -948,7 +1047,10 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int if(BackgrndMessageProc() == YES) *CancelCheckWork = YES; - while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES)) + // FTPS‘Ήž + // ‘—Mƒoƒbƒtƒ@‚Ì‹ó‚«Šm”F‚ɂ͉e‹¿‚µ‚È‚¢‚ª”O‚Ì‚½‚ß +// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES)) + while(AskCryptMode() == CRYPT_NONE && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES)) { if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES) { @@ -980,7 +1082,12 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int DoPrintf("## send()"); #endif - Ret = send(s, buf, len, flags); + // FTPS‘Ήž +// Ret = send(s, buf, len, flags); + if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) + Ret = sendS(s, buf, len, flags); + else + Ret = send(s, buf, len, flags); if(Ret != SOCKET_ERROR) { #if DBG_MSG @@ -992,6 +1099,26 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int Sleep(1); if(BackgrndMessageProc() == YES) break; + // FTPS‘Ήž + // ‘—Mƒoƒbƒtƒ@Šm”F‚ðƒoƒCƒpƒX‚µ‚½‚½‚ß‚±‚±‚Ń^ƒCƒ€ƒAƒEƒg‚ÌŠm”F + if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) + { + if(BackgrndMessageProc() == YES) + *CancelCheckWork = YES; + } + else if(TimeOut != 0) + { + time(&ElapseTime); + ElapseTime -= StartTime; + if(ElapseTime >= TimeOut) + { + DoPrintf("do_recv timed out"); + *TimeOutErr = YES; + *CancelCheckWork = YES; + } + } + if(*CancelCheckWork == YES) + break; } while(Error == WSAEWOULDBLOCK); } diff --git a/socketwrapper.c b/socketwrapper.c new file mode 100644 index 0000000..744f7c2 --- /dev/null +++ b/socketwrapper.c @@ -0,0 +1,299 @@ +// socketwrapper.cpp +// Copyright (C) 2011 Suguru Kawamoto +// ƒ\ƒPƒbƒgƒ‰ƒbƒp[ +// socketŠÖ˜AŠÖ”‚ðOpenSSL—p‚É’uŠ· +// ƒRƒ“ƒpƒCƒ‹‚É‚ÍOpenSSL‚̃wƒbƒ_[ƒtƒ@ƒCƒ‹‚ª•K—v +// ŽÀs‚É‚ÍOpenSSL‚ÌDLL‚ª•K—v + +#include +#include +#include + +#include "socketwrapper.h" + +typedef void (__stdcall* _SSL_load_error_strings)(); +typedef int (__stdcall* _SSL_library_init)(); +typedef SSL_METHOD* (__stdcall* _SSLv23_method)(); +typedef SSL_CTX* (__stdcall* _SSL_CTX_new)(SSL_METHOD*); +typedef void (__stdcall* _SSL_CTX_free)(SSL_CTX*); +typedef SSL* (__stdcall* _SSL_new)(SSL_CTX*); +typedef void (__stdcall* _SSL_free)(SSL*); +typedef int (__stdcall* _SSL_shutdown)(SSL*); +typedef int (__stdcall* _SSL_get_fd)(SSL*); +typedef int (__stdcall* _SSL_set_fd)(SSL*, int); +typedef int (__stdcall* _SSL_accept)(SSL*); +typedef int (__stdcall* _SSL_connect)(SSL*); +typedef int (__stdcall* _SSL_write)(SSL*, const void*, int); +typedef int (__stdcall* _SSL_peek)(SSL*, void*, int); +typedef int (__stdcall* _SSL_read)(SSL*, void*, int); +typedef int (__stdcall* _SSL_get_error)(SSL*, int); + +_SSL_load_error_strings pSSL_load_error_strings; +_SSL_library_init pSSL_library_init; +_SSLv23_method pSSLv23_method; +_SSL_CTX_new pSSL_CTX_new; +_SSL_CTX_free pSSL_CTX_free; +_SSL_new pSSL_new; +_SSL_free pSSL_free; +_SSL_shutdown pSSL_shutdown; +_SSL_get_fd pSSL_get_fd; +_SSL_set_fd pSSL_set_fd; +_SSL_accept pSSL_accept; +_SSL_connect pSSL_connect; +_SSL_write pSSL_write; +_SSL_peek pSSL_peek; +_SSL_read pSSL_read; +_SSL_get_error pSSL_get_error; + +#define MAX_SSL_SOCKET 16 + +BOOL g_bOpenSSLLoaded; +HMODULE g_hOpenSSL; +CRITICAL_SECTION g_OpenSSLLock; +DWORD g_OpenSSLTimeout; +LPSSLTIMEOUTCALLBACK g_pOpenSSLTimeoutCallback; +SSL_CTX* g_pOpenSSLCTX; +SSL* g_pOpenSSLHandle[MAX_SSL_SOCKET]; + +BOOL __stdcall DefaultSSLTimeoutCallback() +{ + Sleep(100); + return FALSE; +} + +BOOL LoadOpenSSL() +{ + if(g_bOpenSSLLoaded) + return FALSE; + g_hOpenSSL = LoadLibrary("ssleay32.dll"); + if(!g_hOpenSSL) + g_hOpenSSL = LoadLibrary("libssl32.dll"); + if(!g_hOpenSSL + || !(pSSL_load_error_strings = (_SSL_load_error_strings)GetProcAddress(g_hOpenSSL, "SSL_load_error_strings")) + || !(pSSL_library_init = (_SSL_library_init)GetProcAddress(g_hOpenSSL, "SSL_library_init")) + || !(pSSLv23_method = (_SSLv23_method)GetProcAddress(g_hOpenSSL, "SSLv23_method")) + || !(pSSL_CTX_new = (_SSL_CTX_new)GetProcAddress(g_hOpenSSL, "SSL_CTX_new")) + || !(pSSL_CTX_free = (_SSL_CTX_free)GetProcAddress(g_hOpenSSL, "SSL_CTX_free")) + || !(pSSL_new = (_SSL_new)GetProcAddress(g_hOpenSSL, "SSL_new")) + || !(pSSL_free = (_SSL_free)GetProcAddress(g_hOpenSSL, "SSL_free")) + || !(pSSL_shutdown = (_SSL_shutdown)GetProcAddress(g_hOpenSSL, "SSL_shutdown")) + || !(pSSL_get_fd = (_SSL_get_fd)GetProcAddress(g_hOpenSSL, "SSL_get_fd")) + || !(pSSL_set_fd = (_SSL_set_fd)GetProcAddress(g_hOpenSSL, "SSL_set_fd")) + || !(pSSL_accept = (_SSL_accept)GetProcAddress(g_hOpenSSL, "SSL_accept")) + || !(pSSL_connect = (_SSL_connect)GetProcAddress(g_hOpenSSL, "SSL_connect")) + || !(pSSL_write = (_SSL_write)GetProcAddress(g_hOpenSSL, "SSL_write")) + || !(pSSL_peek = (_SSL_peek)GetProcAddress(g_hOpenSSL, "SSL_peek")) + || !(pSSL_read = (_SSL_read)GetProcAddress(g_hOpenSSL, "SSL_read")) + || !(pSSL_get_error = (_SSL_get_error)GetProcAddress(g_hOpenSSL, "SSL_get_error"))) + { + FreeLibrary(g_hOpenSSL); + g_hOpenSSL = NULL; + return FALSE; + } + InitializeCriticalSection(&g_OpenSSLLock); + pSSL_load_error_strings(); + pSSL_library_init(); + SetSSLTimeoutCallback(60000, DefaultSSLTimeoutCallback); + g_bOpenSSLLoaded = TRUE; + return TRUE; +} + +void FreeOpenSSL() +{ + int i; + if(!g_bOpenSSLLoaded) + return; + EnterCriticalSection(&g_OpenSSLLock); + for(i = 0; i < MAX_SSL_SOCKET; i++) + { + if(g_pOpenSSLHandle[i]) + { + pSSL_shutdown(g_pOpenSSLHandle[i]); + pSSL_free(g_pOpenSSLHandle[i]); + g_pOpenSSLHandle[i] = NULL; + } + } + if(g_pOpenSSLCTX) + pSSL_CTX_free(g_pOpenSSLCTX); + g_pOpenSSLCTX = NULL; + FreeLibrary(g_hOpenSSL); + g_hOpenSSL = NULL; + LeaveCriticalSection(&g_OpenSSLLock); + DeleteCriticalSection(&g_OpenSSLLock); + g_bOpenSSLLoaded = FALSE; +} + +BOOL IsOpenSSLLoaded() +{ + return g_bOpenSSLLoaded; +} + +SSL** GetUnusedSSLPointer() +{ + int i; + for(i = 0; i < MAX_SSL_SOCKET; i++) + { + if(!g_pOpenSSLHandle[i]) + return &g_pOpenSSLHandle[i]; + } + return NULL; +} + +SSL** FindSSLPointerFromSocket(SOCKET s) +{ + int i; + for(i = 0; i < MAX_SSL_SOCKET; i++) + { + if(g_pOpenSSLHandle[i]) + { + if(pSSL_get_fd(g_pOpenSSLHandle[i]) == s) + return &g_pOpenSSLHandle[i]; + } + } + return NULL; +} + +void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback) +{ + EnterCriticalSection(&g_OpenSSLLock); + g_OpenSSLTimeout = Timeout; + g_pOpenSSLTimeoutCallback = pCallback; + LeaveCriticalSection(&g_OpenSSLLock); +} + +BOOL AttachSSL(SOCKET s) +{ + BOOL r; + DWORD Time; + SSL** ppSSL; + r = FALSE; + Time = timeGetTime(); + EnterCriticalSection(&g_OpenSSLLock); + if(!g_pOpenSSLCTX) + g_pOpenSSLCTX = pSSL_CTX_new(pSSLv23_method()); + if(g_pOpenSSLCTX) + { + if(ppSSL = GetUnusedSSLPointer()) + { + if(*ppSSL = pSSL_new(g_pOpenSSLCTX)) + { + if(pSSL_set_fd(*ppSSL, s) != 0) + { + r = TRUE; + // SSL‚̃lƒSƒVƒG[ƒVƒ‡ƒ“‚É‚ÍŽžŠÔ‚ª‚©‚©‚éê‡‚ª‚ ‚é + while(pSSL_connect(*ppSSL) != 1) + { + LeaveCriticalSection(&g_OpenSSLLock); + if(g_pOpenSSLTimeoutCallback() || timeGetTime() - Time >= g_OpenSSLTimeout) + { + DetachSSL(s); + r = FALSE; + EnterCriticalSection(&g_OpenSSLLock); + break; + } + EnterCriticalSection(&g_OpenSSLLock); + } + } + else + DetachSSL(s); + } + } + } + LeaveCriticalSection(&g_OpenSSLLock); + return r; +} + +BOOL DetachSSL(SOCKET s) +{ + BOOL r; + SSL** ppSSL; + r = FALSE; + EnterCriticalSection(&g_OpenSSLLock); + if(ppSSL = FindSSLPointerFromSocket(s)) + { + pSSL_shutdown(*ppSSL); + pSSL_free(*ppSSL); + *ppSSL = NULL; + r = TRUE; + } + LeaveCriticalSection(&g_OpenSSLLock); + return r; +} + +BOOL IsSSLAttached(SOCKET s) +{ + SSL** ppSSL; + EnterCriticalSection(&g_OpenSSLLock); + ppSSL = FindSSLPointerFromSocket(s); + LeaveCriticalSection(&g_OpenSSLLock); + if(!ppSSL) + return TRUE; + return TRUE; +} + +SOCKET socketS(int af, int type, int protocol) +{ + return socket(af, type, protocol); +} + +int bindS(SOCKET s, const struct sockaddr *addr, int namelen) +{ + return bind(s, addr, namelen); +} + +int listenS(SOCKET s, int backlog) +{ + return listen(s, backlog); +} + +SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen) +{ + SOCKET r; + r = accept(s, addr, addrlen); + if(!AttachSSL(r)) + { + closesocket(r); + return INVALID_SOCKET; + } + return r; +} + +int connectS(SOCKET s, const struct sockaddr *name, int namelen) +{ + int r; + r = connect(s, name, namelen); + if(!AttachSSL(r)) + return SOCKET_ERROR; + return r; +} + +int closesocketS(SOCKET s) +{ + DetachSSL(s); + return closesocket(s); +} + +int sendS(SOCKET s, const char * buf, int len, int flags) +{ + SSL** ppSSL; + EnterCriticalSection(&g_OpenSSLLock); + ppSSL = FindSSLPointerFromSocket(s); + LeaveCriticalSection(&g_OpenSSLLock); + if(!ppSSL) + return send(s, buf, len, flags); + return pSSL_write(*ppSSL, buf, len); +} + +int recvS(SOCKET s, char * buf, int len, int flags) +{ + SSL** ppSSL; + EnterCriticalSection(&g_OpenSSLLock); + ppSSL = FindSSLPointerFromSocket(s); + LeaveCriticalSection(&g_OpenSSLLock); + if(!ppSSL) + return recv(s, buf, len, flags); + if(flags & MSG_PEEK) + return pSSL_peek(*ppSSL, buf, len); + return pSSL_read(*ppSSL, buf, len); +} + diff --git a/socketwrapper.h b/socketwrapper.h new file mode 100644 index 0000000..884f63d --- /dev/null +++ b/socketwrapper.h @@ -0,0 +1,29 @@ +// socketwrapper.h +// Copyright (C) 2011 Suguru Kawamoto +// ƒ\ƒPƒbƒgƒ‰ƒbƒp[ + +#ifndef __SOCKETWRAPPER_H__ +#define __SOCKETWRAPPER_H__ + +#define USE_OPENSSL + +typedef BOOL (__stdcall* LPSSLTIMEOUTCALLBACK)(); + +BOOL LoadOpenSSL(); +void FreeOpenSSL(); +BOOL IsOpenSSLLoaded(); +void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback); +BOOL AttachSSL(SOCKET s); +BOOL DetachSSL(SOCKET s); +BOOL IsSSLAttached(SOCKET s); +SOCKET socketS(int af, int type, int protocol); +int bindS(SOCKET s, const struct sockaddr *addr, int namelen); +int listenS(SOCKET s, int backlog); +SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen); +int connectS(SOCKET s, const struct sockaddr *name, int namelen); +int closesocketS(SOCKET s); +int sendS(SOCKET s, const char * buf, int len, int flags); +int recvS(SOCKET s, char * buf, int len, int flags); + +#endif +