Loweynet
Revision | 193bc37b9f55b9a1dd24a72e06203cb1503eab15 (tree) |
---|---|
Zeit | 2011-10-14 23:02:53 |
Autor | s_kawamoto <s_kawamoto@user...> |
Commiter | s_kawamoto |
Add dialog to confirm certificate for SSL (experimental).
Prepare member variables for IPv6.
@@ -875,6 +875,9 @@ LIST_UNIX_70 | ||
875 | 875 | #define FEATURE_UTF8 0x00000001 |
876 | 876 | // MLSD対応 |
877 | 877 | #define FEATURE_MLSD 0x00000002 |
878 | +// IPv6対応 | |
879 | +#define FEATURE_EPRT 0x00000004 | |
880 | +#define FEATURE_EPSV 0x00000008 | |
878 | 881 | |
879 | 882 | |
880 | 883 | /*================================================= |
@@ -931,6 +934,8 @@ typedef struct { | ||
931 | 934 | int Feature; /* 利用可能な機能のフラグ (FEATURE_xxx) */ |
932 | 935 | // MLSD対応 |
933 | 936 | int UseMLSD; /* "MLSD"コマンドを使用する */ |
937 | + // IPv6対応 | |
938 | + int UseIPv6; /* IPv6接続を許可しEPRT/EPSVコマンドを使用する */ | |
934 | 939 | } HOSTDATA; |
935 | 940 | |
936 | 941 |
@@ -985,6 +990,8 @@ typedef struct historydata { | ||
985 | 990 | int MaxThreadCount; /* 同時接続数 */ |
986 | 991 | // MLSD対応 |
987 | 992 | int UseMLSD; /* "MLSD"コマンドを使用する */ |
993 | + // IPv6対応 | |
994 | + int UseIPv6; /* IPv6接続を許可しEPRT/EPSVコマンドを使用する */ | |
988 | 995 | struct historydata *Next; |
989 | 996 | } HISTORYDATA; |
990 | 997 |
@@ -1219,6 +1226,7 @@ void ResetAutoExitFlg(void); | ||
1219 | 1226 | int AskAutoExit(void); |
1220 | 1227 | // 暗号化通信対応 |
1221 | 1228 | BOOL __stdcall SSLTimeoutCallback(); |
1229 | +BOOL __stdcall SSLConfirmCallback(BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName); | |
1222 | 1230 | |
1223 | 1231 | /*===== filelist.c =====*/ |
1224 | 1232 |
@@ -1402,6 +1410,8 @@ int AskMaxThreadCount(void); | ||
1402 | 1410 | int AskHostFeature(void); |
1403 | 1411 | // MLSD対応 |
1404 | 1412 | int AskUseMLSD(void); |
1413 | +// IPv6対応 | |
1414 | +int AskUseIPv6(void); | |
1405 | 1415 | |
1406 | 1416 | /*===== cache.c =====*/ |
1407 | 1417 |
@@ -1542,6 +1542,9 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char | ||
1542 | 1542 | // MLST対応 |
1543 | 1543 | if(strstr(Reply, " MLST ") || strstr(Reply, " MLSD ")) |
1544 | 1544 | HostData->Feature |= FEATURE_MLSD; |
1545 | + // IPv6対応 | |
1546 | + if(strstr(Reply, " EPRT ") || strstr(Reply, " EPSV ")) | |
1547 | + HostData->Feature |= FEATURE_EPRT | FEATURE_EPSV; | |
1545 | 1548 | } |
1546 | 1549 | // UTF-8対応 |
1547 | 1550 | if(HostData->NameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8)) |
@@ -2366,3 +2369,9 @@ int AskUseMLSD(void) | ||
2366 | 2369 | return(CurHost.UseMLSD); |
2367 | 2370 | } |
2368 | 2371 | |
2372 | +// IPv6対応 | |
2373 | +int AskUseIPv6(void) | |
2374 | +{ | |
2375 | + return(CurHost.UseIPv6); | |
2376 | +} | |
2377 | + |
@@ -231,6 +231,8 @@ static void CopyHostToHistory(HOSTDATA *Host, HISTORYDATA *New) | ||
231 | 231 | New->MaxThreadCount = Host->MaxThreadCount; |
232 | 232 | // MLSD対応 |
233 | 233 | New->UseMLSD = Host->UseMLSD; |
234 | + // IPv6対応 | |
235 | + New->UseIPv6 = Host->UseIPv6; | |
234 | 236 | return; |
235 | 237 | } |
236 | 238 |
@@ -288,6 +290,8 @@ void CopyHistoryToHost(HISTORYDATA *Hist, HOSTDATA *Host) | ||
288 | 290 | Host->MaxThreadCount = Hist->MaxThreadCount; |
289 | 291 | // MLSD対応 |
290 | 292 | Host->UseMLSD = Hist->UseMLSD; |
293 | + // IPv6対応 | |
294 | + Host->UseIPv6 = Hist->UseIPv6; | |
291 | 295 | return; |
292 | 296 | } |
293 | 297 |
@@ -1037,6 +1037,8 @@ int CopyHostFromListInConnect(int Num, HOSTDATA *Set) | ||
1037 | 1037 | Set->MaxThreadCount = Pos->Set.MaxThreadCount; |
1038 | 1038 | // MLSD対応 |
1039 | 1039 | Set->UseMLSD = Pos->Set.UseMLSD; |
1040 | + // IPv6対応 | |
1041 | + Set->UseIPv6 = Pos->Set.UseIPv6; | |
1040 | 1042 | Sts = FFFTP_SUCCESS; |
1041 | 1043 | } |
1042 | 1044 | return(Sts); |
@@ -1321,6 +1323,8 @@ void CopyDefaultHost(HOSTDATA *Set) | ||
1321 | 1323 | // MLSD対応 |
1322 | 1324 | Set->Feature = 0; |
1323 | 1325 | Set->UseMLSD = YES; |
1326 | + // IPv6対応 | |
1327 | + Set->UseIPv6 = YES; | |
1324 | 1328 | return; |
1325 | 1329 | } |
1326 | 1330 |
@@ -458,6 +458,7 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow) | ||
458 | 458 | |
459 | 459 | // 暗号化通信対応 |
460 | 460 | SetSSLTimeoutCallback(TimeOut * 1000, SSLTimeoutCallback); |
461 | + SetSSLConfirmCallback(SSLConfirmCallback); | |
461 | 462 | |
462 | 463 | LoadJre(); |
463 | 464 | if(NoRasControl == NO) |
@@ -2824,3 +2825,19 @@ BOOL __stdcall SSLTimeoutCallback() | ||
2824 | 2825 | return FALSE; |
2825 | 2826 | } |
2826 | 2827 | |
2828 | +BOOL __stdcall SSLConfirmCallback(BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName) | |
2829 | +{ | |
2830 | + BOOL bResult; | |
2831 | + char* pm0; | |
2832 | + bResult = FALSE; | |
2833 | + pm0 = NULL; | |
2834 | + if(pm0 = AllocateStringM(strlen(Certificate) + 1024)) | |
2835 | + { | |
2836 | + sprintf(pm0, MSGJPN326, IsHostNameMatched(AskHostAdrs(), CommonName) ? MSGJPN327 : MSGJPN328, bVerified ? MSGJPN327 : MSGJPN328, Certificate); | |
2837 | + if(MessageBox(GetMainHwnd(), pm0, "FFFTP", MB_YESNO) == IDYES) | |
2838 | + bResult = TRUE; | |
2839 | + } | |
2840 | + FreeDuplicatedString(pm0); | |
2841 | + return bResult; | |
2842 | +} | |
2843 | + |
@@ -323,3 +323,6 @@ | ||
323 | 323 | #define MSGJPN323 "Failed to unload untrustworthy DLLs." |
324 | 324 | #define MSGJPN324 "Failed to hook required functions to protect the process." |
325 | 325 | #define MSGJPN325 "New master passwords are not identical." |
326 | +#define MSGJPN326 "Choose 'Yes' if you trust this certificate and continue.\r\nCN is identical: %s\r\nVerified successfully: %s\r\n\r\n%s" | |
327 | +#define MSGJPN327 "Yes" | |
328 | +#define MSGJPN328 "No" |
@@ -323,3 +323,6 @@ | ||
323 | 323 | #define MSGJPN323 "Failed to unload untrustworthy DLLs." |
324 | 324 | #define MSGJPN324 "Failed to hook required functions to protect the process." |
325 | 325 | #define MSGJPN325 "New master passwords are not identical." |
326 | +#define MSGJPN326 "Choose 'Yes' if you trust this certificate and continue.\r\nCN is identical: %s\r\nVerified successfully: %s\r\n\r\n%s" | |
327 | +#define MSGJPN327 "Yes" | |
328 | +#define MSGJPN328 "No" |
@@ -323,3 +323,6 @@ | ||
323 | 323 | #define MSGJPN323 "\xE4\xBF\xA1\xE9\xA0\xBC\xE3\x81\xA7\xE3\x81\x8D\xE3\x81\xAA\xE3\x81\x84\x44LL\xE3\x82\x92\xE3\x82\xA2\xE3\x83\xB3\xE3\x83\xAD\xE3\x83\xBC\xE3\x83\x89\xE3\x81\xA7\xE3\x81\x8D\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93\xE3\x81\xA7\xE3\x81\x97\xE3\x81\x9F." |
324 | 324 | #define MSGJPN324 "\xE3\x83\x97\xE3\x83\xAD\xE3\x82\xBB\xE3\x82\xB9\xE3\x81\xAE\xE4\xBF\x9D\xE8\xAD\xB7\xE3\x81\xAB\xE5\xBF\x85\xE8\xA6\x81\xE3\x81\xAA\xE9\x96\xA2\xE6\x95\xB0\xE3\x82\x92\xE3\x83\x95\xE3\x83\x83\xE3\x82\xAF\xE3\x81\xA7\xE3\x81\x8D\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93\xE3\x81\xA7\xE3\x81\x97\xE3\x81\x9F." |
325 | 325 | #define MSGJPN325 "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x9E\xE3\x82\xB9\xE3\x82\xBF\xE3\x83\xBC\xE3\x83\x91\xE3\x82\xB9\xE3\x83\xAF\xE3\x83\xBC\xE3\x83\x89\xE3\x81\x8C\xE4\xB8\x80\xE8\x87\xB4\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93." |
326 | +#define MSGJPN326 "\xE3\x81\x93\xE3\x81\xAE\xE8\xA8\xBC\xE6\x98\x8E\xE6\x9B\xB8\xE3\x82\x92\xE4\xBF\xA1\xE9\xA0\xBC\xE3\x81\x97,\xE9\x80\x9A\xE4\xBF\xA1\xE3\x82\x92\xE7\xB6\x9A\xE8\xA1\x8C\xE3\x81\x99\xE3\x82\x8B\xE3\x81\xAB\xE3\x81\xAF\xE3\x80\x8C\xE3\x81\xAF\xE3\x81\x84\xE3\x80\x8D\xE3\x82\x92\xE9\x81\xB8\xE6\x8A\x9E\xE3\x81\x97\xE3\x81\xA6\xE3\x81\x8F\xE3\x81\xA0\xE3\x81\x95\xE3\x81\x84.\r\nCN\xE3\x81\xAE\xE4\xB8\x80\xE8\x87\xB4: %s\r\n\xE6\xA4\x9C\xE8\xA8\xBC\xE3\x81\xAB\xE6\x88\x90\xE5\x8A\x9F: %s\r\n\r\n%s" | |
327 | +#define MSGJPN327 "\xE3\x81\xAF\xE3\x81\x84" | |
328 | +#define MSGJPN328 "\xE3\x81\x84\xE3\x81\x84\xE3\x81\x88" |
@@ -323,3 +323,6 @@ | ||
323 | 323 | #define MSGJPN323 "MÅ«È¢DLLðA[hūܹñŵ½." |
324 | 324 | #define MSGJPN324 "vZXÌÛìÉKvÈÖðtbNūܹñŵ½." |
325 | 325 | #define MSGJPN325 "Vµ¢}X^[pX[hªêvµÜ¹ñ." |
326 | +#define MSGJPN326 "±ÌؾðMµ,ÊMð±s·éÉÍuÍ¢vðIðµÄ¾³¢.\r\nCNÌêv: %s\r\nØɬ÷: %s\r\n\r\n%s" | |
327 | +#define MSGJPN327 "Í¢" | |
328 | +#define MSGJPN328 "¢¢¦" |
@@ -470,6 +470,8 @@ void SaveRegistory(void) | ||
470 | 470 | SaveIntNum(hKey5, "ThreadCount", Hist.MaxThreadCount, DefaultHist.MaxThreadCount); |
471 | 471 | // MLSD対応 |
472 | 472 | SaveIntNum(hKey5, "MLSD", Hist.UseMLSD, DefaultHist.UseMLSD); |
473 | + // IPv6対応 | |
474 | + SaveIntNum(hKey5, "IPv6", Hist.UseIPv6, DefaultHist.UseIPv6); | |
473 | 475 | |
474 | 476 | CloseSubKey(hKey5); |
475 | 477 | n++; |
@@ -546,6 +548,8 @@ void SaveRegistory(void) | ||
546 | 548 | SaveIntNum(hKey5, "ThreadCount", Host.MaxThreadCount, DefaultHost.MaxThreadCount); |
547 | 549 | // MLSD対応 |
548 | 550 | SaveIntNum(hKey5, "MLSD", Host.UseMLSD, DefaultHost.UseMLSD); |
551 | + // IPv6対応 | |
552 | + SaveIntNum(hKey5, "IPv6", Host.UseIPv6, DefaultHost.UseIPv6); | |
549 | 553 | } |
550 | 554 | CloseSubKey(hKey5); |
551 | 555 | } |
@@ -804,6 +808,8 @@ int LoadRegistory(void) | ||
804 | 808 | ReadIntValueFromReg(hKey5, "ThreadCount", &Hist.MaxThreadCount); |
805 | 809 | // MLSD対応 |
806 | 810 | ReadIntValueFromReg(hKey5, "MLSD", &Hist.UseMLSD); |
811 | + // IPv6対応 | |
812 | + ReadIntValueFromReg(hKey5, "IPv6", &Hist.UseIPv6); | |
807 | 813 | |
808 | 814 | CloseSubKey(hKey5); |
809 | 815 | AddHistoryToHistory(&Hist); |
@@ -882,6 +888,8 @@ int LoadRegistory(void) | ||
882 | 888 | ReadIntValueFromReg(hKey5, "ThreadCount", &Host.MaxThreadCount); |
883 | 889 | // MLSD対応 |
884 | 890 | ReadIntValueFromReg(hKey5, "MLSD", &Host.UseMLSD); |
891 | + // IPv6対応 | |
892 | + ReadIntValueFromReg(hKey5, "IPv6", &Host.UseIPv6); | |
885 | 893 | |
886 | 894 | CloseSubKey(hKey5); |
887 | 895 |
@@ -28,31 +28,55 @@ typedef int (__cdecl* _SSL_write)(SSL*, const void*, int); | ||
28 | 28 | typedef int (__cdecl* _SSL_peek)(SSL*, void*, int); |
29 | 29 | typedef int (__cdecl* _SSL_read)(SSL*, void*, int); |
30 | 30 | typedef int (__cdecl* _SSL_get_error)(SSL*, int); |
31 | +typedef X509* (__cdecl* _SSL_get_peer_certificate)(const SSL*); | |
32 | +typedef long (__cdecl* _SSL_get_verify_result)(const SSL*); | |
33 | +typedef BIO_METHOD* (__cdecl* _BIO_s_mem)(); | |
34 | +typedef BIO* (__cdecl* _BIO_new)(BIO_METHOD*); | |
35 | +typedef int (__cdecl* _BIO_free)(BIO*); | |
36 | +typedef long (__cdecl* _BIO_ctrl)(BIO*, int, long, void*); | |
37 | +typedef void (__cdecl* _X509_free)(X509*); | |
38 | +typedef int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long); | |
39 | +typedef X509_NAME* (__cdecl* _X509_get_subject_name)(X509*); | |
40 | +typedef X509_NAME* (__cdecl* _X509_get_issuer_name)(X509*); | |
41 | +typedef int (__cdecl* _X509_NAME_print_ex)(BIO*, X509_NAME*, int, unsigned long); | |
31 | 42 | |
32 | -_SSL_load_error_strings pSSL_load_error_strings; | |
33 | -_SSL_library_init pSSL_library_init; | |
34 | -_SSLv23_method pSSLv23_method; | |
35 | -_SSL_CTX_new pSSL_CTX_new; | |
36 | -_SSL_CTX_free pSSL_CTX_free; | |
37 | -_SSL_new pSSL_new; | |
38 | -_SSL_free pSSL_free; | |
39 | -_SSL_shutdown pSSL_shutdown; | |
40 | -_SSL_get_fd pSSL_get_fd; | |
41 | -_SSL_set_fd pSSL_set_fd; | |
42 | -_SSL_accept pSSL_accept; | |
43 | -_SSL_connect pSSL_connect; | |
44 | -_SSL_write pSSL_write; | |
45 | -_SSL_peek pSSL_peek; | |
46 | -_SSL_read pSSL_read; | |
47 | -_SSL_get_error pSSL_get_error; | |
43 | +_SSL_load_error_strings p_SSL_load_error_strings; | |
44 | +_SSL_library_init p_SSL_library_init; | |
45 | +_SSLv23_method p_SSLv23_method; | |
46 | +_SSL_CTX_new p_SSL_CTX_new; | |
47 | +_SSL_CTX_free p_SSL_CTX_free; | |
48 | +_SSL_new p_SSL_new; | |
49 | +_SSL_free p_SSL_free; | |
50 | +_SSL_shutdown p_SSL_shutdown; | |
51 | +_SSL_get_fd p_SSL_get_fd; | |
52 | +_SSL_set_fd p_SSL_set_fd; | |
53 | +_SSL_accept p_SSL_accept; | |
54 | +_SSL_connect p_SSL_connect; | |
55 | +_SSL_write p_SSL_write; | |
56 | +_SSL_peek p_SSL_peek; | |
57 | +_SSL_read p_SSL_read; | |
58 | +_SSL_get_error p_SSL_get_error; | |
59 | +_SSL_get_peer_certificate p_SSL_get_peer_certificate; | |
60 | +_SSL_get_verify_result p_SSL_get_verify_result; | |
61 | +_BIO_s_mem p_BIO_s_mem; | |
62 | +_BIO_new p_BIO_new; | |
63 | +_BIO_free p_BIO_free; | |
64 | +_BIO_ctrl p_BIO_ctrl; | |
65 | +_X509_free p_X509_free; | |
66 | +_X509_print_ex p_X509_print_ex; | |
67 | +_X509_get_subject_name p_X509_get_subject_name; | |
68 | +_X509_get_issuer_name p_X509_get_issuer_name; | |
69 | +_X509_NAME_print_ex p_X509_NAME_print_ex; | |
48 | 70 | |
49 | 71 | #define MAX_SSL_SOCKET 64 |
50 | 72 | |
51 | 73 | BOOL g_bOpenSSLLoaded; |
52 | 74 | HMODULE g_hOpenSSL; |
75 | +HMODULE g_hOpenSSLCommon; | |
53 | 76 | CRITICAL_SECTION g_OpenSSLLock; |
54 | 77 | DWORD g_OpenSSLTimeout; |
55 | 78 | LPSSLTIMEOUTCALLBACK g_pOpenSSLTimeoutCallback; |
79 | +LPSSLCONFIRMCALLBACK g_pOpenSSLConfirmCallback; | |
56 | 80 | SSL_CTX* g_pOpenSSLCTX; |
57 | 81 | SSL* g_pOpenSSLHandle[MAX_SSL_SOCKET]; |
58 | 82 |
@@ -62,6 +86,11 @@ BOOL __stdcall DefaultSSLTimeoutCallback() | ||
62 | 86 | return FALSE; |
63 | 87 | } |
64 | 88 | |
89 | +BOOL __stdcall DefaultSSLConfirmCallback(BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName) | |
90 | +{ | |
91 | + return bVerified; | |
92 | +} | |
93 | + | |
65 | 94 | BOOL LoadOpenSSL() |
66 | 95 | { |
67 | 96 | if(g_bOpenSSLLoaded) |
@@ -78,32 +107,55 @@ BOOL LoadOpenSSL() | ||
78 | 107 | if(!g_hOpenSSL) |
79 | 108 | g_hOpenSSL = LoadLibrary("libssl32.dll"); |
80 | 109 | if(!g_hOpenSSL |
81 | - || !(pSSL_load_error_strings = (_SSL_load_error_strings)GetProcAddress(g_hOpenSSL, "SSL_load_error_strings")) | |
82 | - || !(pSSL_library_init = (_SSL_library_init)GetProcAddress(g_hOpenSSL, "SSL_library_init")) | |
83 | - || !(pSSLv23_method = (_SSLv23_method)GetProcAddress(g_hOpenSSL, "SSLv23_method")) | |
84 | - || !(pSSL_CTX_new = (_SSL_CTX_new)GetProcAddress(g_hOpenSSL, "SSL_CTX_new")) | |
85 | - || !(pSSL_CTX_free = (_SSL_CTX_free)GetProcAddress(g_hOpenSSL, "SSL_CTX_free")) | |
86 | - || !(pSSL_new = (_SSL_new)GetProcAddress(g_hOpenSSL, "SSL_new")) | |
87 | - || !(pSSL_free = (_SSL_free)GetProcAddress(g_hOpenSSL, "SSL_free")) | |
88 | - || !(pSSL_shutdown = (_SSL_shutdown)GetProcAddress(g_hOpenSSL, "SSL_shutdown")) | |
89 | - || !(pSSL_get_fd = (_SSL_get_fd)GetProcAddress(g_hOpenSSL, "SSL_get_fd")) | |
90 | - || !(pSSL_set_fd = (_SSL_set_fd)GetProcAddress(g_hOpenSSL, "SSL_set_fd")) | |
91 | - || !(pSSL_accept = (_SSL_accept)GetProcAddress(g_hOpenSSL, "SSL_accept")) | |
92 | - || !(pSSL_connect = (_SSL_connect)GetProcAddress(g_hOpenSSL, "SSL_connect")) | |
93 | - || !(pSSL_write = (_SSL_write)GetProcAddress(g_hOpenSSL, "SSL_write")) | |
94 | - || !(pSSL_peek = (_SSL_peek)GetProcAddress(g_hOpenSSL, "SSL_peek")) | |
95 | - || !(pSSL_read = (_SSL_read)GetProcAddress(g_hOpenSSL, "SSL_read")) | |
96 | - || !(pSSL_get_error = (_SSL_get_error)GetProcAddress(g_hOpenSSL, "SSL_get_error"))) | |
110 | + || !(p_SSL_load_error_strings = (_SSL_load_error_strings)GetProcAddress(g_hOpenSSL, "SSL_load_error_strings")) | |
111 | + || !(p_SSL_library_init = (_SSL_library_init)GetProcAddress(g_hOpenSSL, "SSL_library_init")) | |
112 | + || !(p_SSLv23_method = (_SSLv23_method)GetProcAddress(g_hOpenSSL, "SSLv23_method")) | |
113 | + || !(p_SSL_CTX_new = (_SSL_CTX_new)GetProcAddress(g_hOpenSSL, "SSL_CTX_new")) | |
114 | + || !(p_SSL_CTX_free = (_SSL_CTX_free)GetProcAddress(g_hOpenSSL, "SSL_CTX_free")) | |
115 | + || !(p_SSL_new = (_SSL_new)GetProcAddress(g_hOpenSSL, "SSL_new")) | |
116 | + || !(p_SSL_free = (_SSL_free)GetProcAddress(g_hOpenSSL, "SSL_free")) | |
117 | + || !(p_SSL_shutdown = (_SSL_shutdown)GetProcAddress(g_hOpenSSL, "SSL_shutdown")) | |
118 | + || !(p_SSL_get_fd = (_SSL_get_fd)GetProcAddress(g_hOpenSSL, "SSL_get_fd")) | |
119 | + || !(p_SSL_set_fd = (_SSL_set_fd)GetProcAddress(g_hOpenSSL, "SSL_set_fd")) | |
120 | + || !(p_SSL_accept = (_SSL_accept)GetProcAddress(g_hOpenSSL, "SSL_accept")) | |
121 | + || !(p_SSL_connect = (_SSL_connect)GetProcAddress(g_hOpenSSL, "SSL_connect")) | |
122 | + || !(p_SSL_write = (_SSL_write)GetProcAddress(g_hOpenSSL, "SSL_write")) | |
123 | + || !(p_SSL_peek = (_SSL_peek)GetProcAddress(g_hOpenSSL, "SSL_peek")) | |
124 | + || !(p_SSL_read = (_SSL_read)GetProcAddress(g_hOpenSSL, "SSL_read")) | |
125 | + || !(p_SSL_get_error = (_SSL_get_error)GetProcAddress(g_hOpenSSL, "SSL_get_error")) | |
126 | + || !(p_SSL_get_peer_certificate = (_SSL_get_peer_certificate)GetProcAddress(g_hOpenSSL, "SSL_get_peer_certificate")) | |
127 | + || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result"))) | |
128 | + { | |
129 | + if(g_hOpenSSL) | |
130 | + FreeLibrary(g_hOpenSSL); | |
131 | + g_hOpenSSL = NULL; | |
132 | + return FALSE; | |
133 | + } | |
134 | + g_hOpenSSLCommon = LoadLibrary("libeay32.dll"); | |
135 | + if(!g_hOpenSSLCommon | |
136 | + || !(p_BIO_s_mem = (_BIO_s_mem)GetProcAddress(g_hOpenSSLCommon, "BIO_s_mem")) | |
137 | + || !(p_BIO_new = (_BIO_new)GetProcAddress(g_hOpenSSLCommon, "BIO_new")) | |
138 | + || !(p_BIO_free = (_BIO_free)GetProcAddress(g_hOpenSSLCommon, "BIO_free")) | |
139 | + || !(p_BIO_ctrl = (_BIO_ctrl)GetProcAddress(g_hOpenSSLCommon, "BIO_ctrl")) | |
140 | + || !(p_X509_free = (_X509_free)GetProcAddress(g_hOpenSSLCommon, "X509_free")) | |
141 | + || !(p_X509_print_ex = (_X509_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_print_ex")) | |
142 | + || !(p_X509_get_subject_name = (_X509_get_subject_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_subject_name")) | |
143 | + || !(p_X509_get_issuer_name = (_X509_get_issuer_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_issuer_name")) | |
144 | + || !(p_X509_NAME_print_ex = (_X509_NAME_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_NAME_print_ex"))) | |
97 | 145 | { |
98 | 146 | if(g_hOpenSSL) |
99 | 147 | FreeLibrary(g_hOpenSSL); |
100 | 148 | g_hOpenSSL = NULL; |
149 | + if(g_hOpenSSLCommon) | |
150 | + FreeLibrary(g_hOpenSSLCommon); | |
151 | + g_hOpenSSLCommon = NULL; | |
101 | 152 | return FALSE; |
102 | 153 | } |
103 | 154 | InitializeCriticalSection(&g_OpenSSLLock); |
104 | - pSSL_load_error_strings(); | |
105 | - pSSL_library_init(); | |
155 | + p_SSL_load_error_strings(); | |
156 | + p_SSL_library_init(); | |
106 | 157 | SetSSLTimeoutCallback(60000, DefaultSSLTimeoutCallback); |
158 | + SetSSLConfirmCallback(DefaultSSLConfirmCallback); | |
107 | 159 | g_bOpenSSLLoaded = TRUE; |
108 | 160 | return TRUE; |
109 | 161 | } |
@@ -118,16 +170,18 @@ void FreeOpenSSL() | ||
118 | 170 | { |
119 | 171 | if(g_pOpenSSLHandle[i]) |
120 | 172 | { |
121 | - pSSL_shutdown(g_pOpenSSLHandle[i]); | |
122 | - pSSL_free(g_pOpenSSLHandle[i]); | |
173 | + p_SSL_shutdown(g_pOpenSSLHandle[i]); | |
174 | + p_SSL_free(g_pOpenSSLHandle[i]); | |
123 | 175 | g_pOpenSSLHandle[i] = NULL; |
124 | 176 | } |
125 | 177 | } |
126 | 178 | if(g_pOpenSSLCTX) |
127 | - pSSL_CTX_free(g_pOpenSSLCTX); | |
179 | + p_SSL_CTX_free(g_pOpenSSLCTX); | |
128 | 180 | g_pOpenSSLCTX = NULL; |
129 | 181 | FreeLibrary(g_hOpenSSL); |
130 | 182 | g_hOpenSSL = NULL; |
183 | + FreeLibrary(g_hOpenSSLCommon); | |
184 | + g_hOpenSSLCommon = NULL; | |
131 | 185 | LeaveCriticalSection(&g_OpenSSLLock); |
132 | 186 | DeleteCriticalSection(&g_OpenSSLLock); |
133 | 187 | g_bOpenSSLLoaded = FALSE; |
@@ -156,13 +210,82 @@ SSL** FindSSLPointerFromSocket(SOCKET s) | ||
156 | 210 | { |
157 | 211 | if(g_pOpenSSLHandle[i]) |
158 | 212 | { |
159 | - if(pSSL_get_fd(g_pOpenSSLHandle[i]) == s) | |
213 | + if(p_SSL_get_fd(g_pOpenSSLHandle[i]) == s) | |
160 | 214 | return &g_pOpenSSLHandle[i]; |
161 | 215 | } |
162 | 216 | } |
163 | 217 | return NULL; |
164 | 218 | } |
165 | 219 | |
220 | +BOOL ConfirmSSLCertificate(SSL* pSSL) | |
221 | +{ | |
222 | + BOOL bResult; | |
223 | + BOOL bVerified; | |
224 | + char* pData; | |
225 | + char* pSubject; | |
226 | + X509* pX509; | |
227 | + BIO* pBIO; | |
228 | + long Length; | |
229 | + char* pBuffer; | |
230 | + char* pCN; | |
231 | + char* p; | |
232 | + bResult = FALSE; | |
233 | + bVerified = FALSE; | |
234 | + pData = NULL; | |
235 | + pSubject = NULL; | |
236 | + if(pX509 = p_SSL_get_peer_certificate(pSSL)) | |
237 | + { | |
238 | + if(pBIO = p_BIO_new(p_BIO_s_mem())) | |
239 | + { | |
240 | + p_X509_print_ex(pBIO, pX509, 0, XN_FLAG_RFC2253); | |
241 | + if((Length = p_BIO_ctrl(pBIO, BIO_CTRL_INFO, 0, &pBuffer)) > 0) | |
242 | + { | |
243 | + if(pData = (char*)malloc(Length + sizeof(char))) | |
244 | + { | |
245 | + memcpy(pData, pBuffer, Length); | |
246 | + *(char*)((size_t)pData + Length) = '\0'; | |
247 | + } | |
248 | + } | |
249 | + p_BIO_free(pBIO); | |
250 | + } | |
251 | + if(pBIO = p_BIO_new(p_BIO_s_mem())) | |
252 | + { | |
253 | + p_X509_NAME_print_ex(pBIO, p_X509_get_subject_name(pX509), 0, XN_FLAG_RFC2253); | |
254 | + if((Length = p_BIO_ctrl(pBIO, BIO_CTRL_INFO, 0, &pBuffer)) > 0) | |
255 | + { | |
256 | + if(pSubject = (char*)malloc(Length + sizeof(char))) | |
257 | + { | |
258 | + memcpy(pSubject, pBuffer, Length); | |
259 | + *(char*)((size_t)pSubject + Length) = '\0'; | |
260 | + } | |
261 | + } | |
262 | + p_BIO_free(pBIO); | |
263 | + } | |
264 | + p_X509_free(pX509); | |
265 | + } | |
266 | + if(p_SSL_get_verify_result(pSSL) == X509_V_OK) | |
267 | + bVerified = TRUE; | |
268 | + pCN = pSubject; | |
269 | + while(pCN) | |
270 | + { | |
271 | + if(strncmp(pCN, "CN=", strlen("CN=")) == 0) | |
272 | + { | |
273 | + pCN += strlen("CN="); | |
274 | + if(p = strchr(pCN, ',')) | |
275 | + *p = '\0'; | |
276 | + break; | |
277 | + } | |
278 | + if(pCN = strchr(pCN, ',')) | |
279 | + pCN++; | |
280 | + } | |
281 | + bResult = g_pOpenSSLConfirmCallback(bVerified, pData, pCN); | |
282 | + if(pData) | |
283 | + free(pData); | |
284 | + if(pSubject) | |
285 | + free(pSubject); | |
286 | + return bResult; | |
287 | +} | |
288 | + | |
166 | 289 | void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback) |
167 | 290 | { |
168 | 291 | if(!g_bOpenSSLLoaded) |
@@ -173,6 +296,40 @@ void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback) | ||
173 | 296 | LeaveCriticalSection(&g_OpenSSLLock); |
174 | 297 | } |
175 | 298 | |
299 | +void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback) | |
300 | +{ | |
301 | + if(!g_bOpenSSLLoaded) | |
302 | + return; | |
303 | + EnterCriticalSection(&g_OpenSSLLock); | |
304 | + g_pOpenSSLConfirmCallback = pCallback; | |
305 | + LeaveCriticalSection(&g_OpenSSLLock); | |
306 | +} | |
307 | + | |
308 | +BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName) | |
309 | +{ | |
310 | + BOOL bResult; | |
311 | + char* pAsterisk; | |
312 | + bResult = FALSE; | |
313 | + if(HostName && CommonName) | |
314 | + { | |
315 | + if(pAsterisk = strchr(CommonName, '*')) | |
316 | + { | |
317 | + if(_strnicmp(HostName, CommonName, ((size_t)pAsterisk - (size_t)CommonName) / sizeof(char)) == 0) | |
318 | + { | |
319 | + while(*pAsterisk == '*') | |
320 | + { | |
321 | + pAsterisk++; | |
322 | + } | |
323 | + if(_stricmp(HostName + strlen(HostName) - strlen(pAsterisk), pAsterisk) == 0) | |
324 | + bResult = TRUE; | |
325 | + } | |
326 | + } | |
327 | + else if(_stricmp(HostName, CommonName) == 0) | |
328 | + bResult = TRUE; | |
329 | + } | |
330 | + return bResult; | |
331 | +} | |
332 | + | |
176 | 333 | BOOL AttachSSL(SOCKET s) |
177 | 334 | { |
178 | 335 | BOOL r; |
@@ -184,18 +341,18 @@ BOOL AttachSSL(SOCKET s) | ||
184 | 341 | Time = timeGetTime(); |
185 | 342 | EnterCriticalSection(&g_OpenSSLLock); |
186 | 343 | if(!g_pOpenSSLCTX) |
187 | - g_pOpenSSLCTX = pSSL_CTX_new(pSSLv23_method()); | |
344 | + g_pOpenSSLCTX = p_SSL_CTX_new(p_SSLv23_method()); | |
188 | 345 | if(g_pOpenSSLCTX) |
189 | 346 | { |
190 | 347 | if(ppSSL = GetUnusedSSLPointer()) |
191 | 348 | { |
192 | - if(*ppSSL = pSSL_new(g_pOpenSSLCTX)) | |
349 | + if(*ppSSL = p_SSL_new(g_pOpenSSLCTX)) | |
193 | 350 | { |
194 | - if(pSSL_set_fd(*ppSSL, s) != 0) | |
351 | + if(p_SSL_set_fd(*ppSSL, s) != 0) | |
195 | 352 | { |
196 | 353 | r = TRUE; |
197 | 354 | // SSLのネゴシエーションには時間がかかる場合がある |
198 | - while(pSSL_connect(*ppSSL) != 1) | |
355 | + while(p_SSL_connect(*ppSSL) != 1) | |
199 | 356 | { |
200 | 357 | LeaveCriticalSection(&g_OpenSSLLock); |
201 | 358 | if(g_pOpenSSLTimeoutCallback() || (g_OpenSSLTimeout > 0 && timeGetTime() - Time >= g_OpenSSLTimeout)) |
@@ -214,6 +371,14 @@ BOOL AttachSSL(SOCKET s) | ||
214 | 371 | DetachSSL(s); |
215 | 372 | EnterCriticalSection(&g_OpenSSLLock); |
216 | 373 | } |
374 | + if(ConfirmSSLCertificate(*ppSSL)) | |
375 | + { | |
376 | + } | |
377 | + else | |
378 | + { | |
379 | + DetachSSL(s); | |
380 | + r = FALSE; | |
381 | + } | |
217 | 382 | } |
218 | 383 | } |
219 | 384 | } |
@@ -231,8 +396,8 @@ BOOL DetachSSL(SOCKET s) | ||
231 | 396 | EnterCriticalSection(&g_OpenSSLLock); |
232 | 397 | if(ppSSL = FindSSLPointerFromSocket(s)) |
233 | 398 | { |
234 | - pSSL_shutdown(*ppSSL); | |
235 | - pSSL_free(*ppSSL); | |
399 | + p_SSL_shutdown(*ppSSL); | |
400 | + p_SSL_free(*ppSSL); | |
236 | 401 | *ppSSL = NULL; |
237 | 402 | r = TRUE; |
238 | 403 | } |
@@ -305,7 +470,7 @@ int sendS(SOCKET s, const char * buf, int len, int flags) | ||
305 | 470 | LeaveCriticalSection(&g_OpenSSLLock); |
306 | 471 | if(!ppSSL) |
307 | 472 | return send(s, buf, len, flags); |
308 | - return pSSL_write(*ppSSL, buf, len); | |
473 | + return p_SSL_write(*ppSSL, buf, len); | |
309 | 474 | } |
310 | 475 | |
311 | 476 | int recvS(SOCKET s, char * buf, int len, int flags) |
@@ -319,7 +484,7 @@ int recvS(SOCKET s, char * buf, int len, int flags) | ||
319 | 484 | if(!ppSSL) |
320 | 485 | return recv(s, buf, len, flags); |
321 | 486 | if(flags & MSG_PEEK) |
322 | - return pSSL_peek(*ppSSL, buf, len); | |
323 | - return pSSL_read(*ppSSL, buf, len); | |
487 | + return p_SSL_peek(*ppSSL, buf, len); | |
488 | + return p_SSL_read(*ppSSL, buf, len); | |
324 | 489 | } |
325 | 490 |
@@ -8,11 +8,14 @@ | ||
8 | 8 | #define USE_OPENSSL |
9 | 9 | |
10 | 10 | typedef BOOL (__stdcall* LPSSLTIMEOUTCALLBACK)(); |
11 | +typedef BOOL (__stdcall* LPSSLCONFIRMCALLBACK)(BOOL, LPCSTR, LPCSTR); | |
11 | 12 | |
12 | 13 | BOOL LoadOpenSSL(); |
13 | 14 | void FreeOpenSSL(); |
14 | 15 | BOOL IsOpenSSLLoaded(); |
15 | 16 | void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback); |
17 | +void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback); | |
18 | +BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName); | |
16 | 19 | BOOL AttachSSL(SOCKET s); |
17 | 20 | BOOL DetachSSL(SOCKET s); |
18 | 21 | BOOL IsSSLAttached(SOCKET s); |