X-Git-Url: http://git.sourceforge.jp/view?p=ffftp%2Fffftp.git;a=blobdiff_plain;f=connect.c;h=3e17909f239f171b0911d7d42e4ce65bae9314b6;hp=904fd0d07c296bd78f3472dc5860c7a9d20c4087;hb=2bffe82de6811b380d280099f638dd7b4cbb3404;hpb=132c39f5500bf34b4f6edad301ceb134c4a7d282 diff --git a/connect.c b/connect.c index 904fd0d..3e17909 100644 --- a/connect.c +++ b/connect.c @@ -35,7 +35,9 @@ #include #include #include -#include +// IPv6対応 +//#include +#include #include #include @@ -52,21 +54,32 @@ /*===== プロトタイプ =====*/ -static BOOL CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); -static int SendInitCommand(char *Cmd); +// 64ビット対応 +//static BOOL CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); +// 同時接続対応 +//static int SendInitCommand(char *Cmd); +static int SendInitCommand(SOCKET Socket, char *Cmd, int *CancelCheckWork); static void AskUseFireWall(char *Host, int *Fire, int *Pasv, int *List); static void SaveCurrentSetToHistory(void); static int ReConnectSkt(SOCKET *Skt); // 暗号化通信対応 +// 同時接続対応 //static SOCKET DoConnect(char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security); -static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security); -static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security); +static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork); +static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork); static int CheckOneTimePassword(char *Pass, char *Reply, int Type); static BOOL CALLBACK BlkHookFnc(void); static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port); +// IPv6対応 +static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port); static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork); -static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet); -static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet); +// 同時接続対応 +//static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet); +static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelCheckWork); +// 同時接続対応 +//static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet); +static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet, int *CancelCheckWork); static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork); /*===== 外部参照 =====*/ @@ -100,12 +113,21 @@ static HOSTDATA CurHost; /* 接続中の接続先、SOCKSサーバのアドレス情報を保存しておく */ /* この情報はlistenソケットを取得する際に用いる */ -static struct sockaddr_in SocksSockAddr; /* SOCKSサーバのアドレス情報 */ -static struct sockaddr_in CurSockAddr; /* 接続先ホストのアドレス情報 */ +// IPv6対応 +//static struct sockaddr_in SocksSockAddr; /* SOCKSサーバのアドレス情報 */ +//static struct sockaddr_in CurSockAddr; /* 接続先ホストのアドレス情報 */ +static struct sockaddr_in SocksSockAddrIPv4; /* SOCKSサーバのアドレス情報 */ +static struct sockaddr_in CurSockAddrIPv4; /* 接続先ホストのアドレス情報 */ +static struct sockaddr_in6 SocksSockAddrIPv6; /* SOCKSサーバのアドレス情報 */ +static struct sockaddr_in6 CurSockAddrIPv6; /* 接続先ホストのアドレス情報 */ +static const struct in6_addr IN6ADDR_NONE = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; static int UseIPadrs; static char DomainName[HOST_ADRS_LEN+1]; +#if defined(HAVE_TANDEM) +static int Oss = NO; /* OSS ファイルシステムへアクセスしている場合は YES */ +#endif @@ -143,6 +165,10 @@ void ConnectProc(int Type, int Num) InitPWDcommand(); CopyHostFromList(AskCurrentHost(), &CurHost); + // UTF-8対応 + CurHost.CurNameKanjiCode = CurHost.NameKanjiCode; + // IPv6対応 + CurHost.CurNetType = CurHost.NetType; if(ConnectRas(CurHost.Dialup, CurHost.DialupAlways, CurHost.DialupNotify, CurHost.DialEntry) == FFFTP_SUCCESS) { @@ -163,17 +189,58 @@ void ConnectProc(int Type, int Num) DisableUserOpe(); // 暗号化通信対応 + // 同時接続対応 // CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, Save, CurHost.Security); - CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, Save, CurHost.Security); + CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, Save, CurHost.Security, &CancelFlg); TrnCtrlSocket = CmdCtrlSocket; if(CmdCtrlSocket != INVALID_SOCKET) { + // 暗号化通信対応 + switch(CurHost.CryptMode) + { + case CRYPT_NONE: + if(CurHost.UseFTPIS != NO || CurHost.UseSFTP != NO) + { + if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES) + SetHostExcryption(AskCurrentHost(), CurHost.UseNoEncryption, CurHost.UseFTPES, NO, NO); + } + break; + case CRYPT_FTPES: + if(CurHost.UseNoEncryption != NO || CurHost.UseFTPIS != NO || CurHost.UseSFTP != NO) + { + if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES) + SetHostExcryption(AskCurrentHost(), NO, CurHost.UseFTPES, NO, NO); + } + break; + case CRYPT_FTPIS: + if(CurHost.UseNoEncryption != NO || CurHost.UseFTPES != NO || CurHost.UseSFTP != NO) + { + if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES) + SetHostExcryption(AskCurrentHost(), NO, NO, CurHost.UseFTPIS, NO); + } + break; + case CRYPT_SFTP: + if(CurHost.UseNoEncryption != NO || CurHost.UseFTPES != NO || CurHost.UseFTPIS != NO) + { + if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES) + SetHostExcryption(AskCurrentHost(), NO, NO, NO, CurHost.UseSFTP); + } + break; + } + + // UTF-8対応 + if(CurHost.CurNameKanjiCode == KANJI_AUTO) + { + if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE) + CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999); + } + strcpy(TitleHostName, CurHost.HostName); DispWindowTitle(); SoundPlay(SND_CONNECT); - SendInitCommand(CurHost.InitCmd); + SendInitCommand(CmdCtrlSocket, CurHost.InitCmd, &CancelFlg); if(strlen(CurHost.LocalInitDir) > 0) { @@ -225,6 +292,10 @@ void QuickConnectProc(void) InitPWDcommand(); CopyDefaultHost(&CurHost); + // UTF-8対応 + CurHost.CurNameKanjiCode = CurHost.NameKanjiCode; + // IPv6対応 + CurHost.CurNetType = CurHost.NetType; if(SplitUNCpath(Tmp, CurHost.HostAdrs, CurHost.RemoteInitDir, File, CurHost.UserName, CurHost.PassWord, &CurHost.Port) == FFFTP_SUCCESS) { if(strlen(CurHost.UserName) == 0) @@ -244,12 +315,20 @@ void QuickConnectProc(void) DisableUserOpe(); // 暗号化通信対応 + // 同時接続対応 // CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security); - CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security); + CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg); TrnCtrlSocket = CmdCtrlSocket; if(CmdCtrlSocket != INVALID_SOCKET) { + // UTF-8対応 + if(CurHost.CurNameKanjiCode == KANJI_AUTO) + { + if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE) + CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999); + } + strcpy(TitleHostName, CurHost.HostAdrs); DispWindowTitle(); SoundPlay(SND_CONNECT); @@ -286,7 +365,9 @@ void QuickConnectProc(void) * BOOL TRUE/FALSE *----------------------------------------------------------------------------*/ -static BOOL CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) +// 64ビット対応 +//static BOOL CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) { static char *Buf; int i; @@ -405,6 +486,10 @@ void DirectConnectProc(char *unc, int Kanji, int Kana, int Fkanji, int TrMode) CurHost.KanaCnv = Kana; CurHost.NameKanjiCode = Fkanji; CurHost.KanaCnv = YES; /* とりあえず */ + // UTF-8対応 + CurHost.CurNameKanjiCode = CurHost.NameKanjiCode; + // IPv6対応 + CurHost.CurNetType = CurHost.NetType; SetHostKanaCnvImm(CurHost.KanaCnv); SetHostKanjiCodeImm(CurHost.KanjiCode); @@ -418,12 +503,20 @@ void DirectConnectProc(char *unc, int Kanji, int Kana, int Fkanji, int TrMode) DisableUserOpe(); // 暗号化通信対応 + // 同時接続対応 // CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security); - CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security); + CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg); TrnCtrlSocket = CmdCtrlSocket; if(CmdCtrlSocket != INVALID_SOCKET) { + // UTF-8対応 + if(CurHost.CurNameKanjiCode == KANJI_AUTO) + { + if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE) + CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999); + } + strcpy(TitleHostName, CurHost.HostAdrs); DispWindowTitle(); SoundPlay(SND_CONNECT); @@ -479,6 +572,10 @@ void HistoryConnectProc(int MenuCmd) InitPWDcommand(); CopyHistoryToHost(&Hist, &CurHost); + // UTF-8対応 + CurHost.CurNameKanjiCode = CurHost.NameKanjiCode; + // IPv6対応 + CurHost.CurNetType = CurHost.NetType; if(ConnectRas(CurHost.Dialup, CurHost.DialupAlways, CurHost.DialupNotify, CurHost.DialEntry) == FFFTP_SUCCESS) { @@ -496,17 +593,25 @@ void HistoryConnectProc(int MenuCmd) DisableUserOpe(); // 暗号化通信対応 + // 同時接続対応 // CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security); - CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security); + CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg); TrnCtrlSocket = CmdCtrlSocket; if(CmdCtrlSocket != INVALID_SOCKET) { + // UTF-8対応 + if(CurHost.CurNameKanjiCode == KANJI_AUTO) + { + if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE) + CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999); + } + strcpy(TitleHostName, CurHost.HostAdrs); DispWindowTitle(); SoundPlay(SND_CONNECT); - SendInitCommand(CurHost.InitCmd); + SendInitCommand(CmdCtrlSocket, CurHost.InitCmd, &CancelFlg); DoLocalCWD(CurHost.LocalInitDir); GetLocalDirForWnd(); @@ -545,7 +650,9 @@ void HistoryConnectProc(int MenuCmd) * cmd1\r\ncmd2\r\n\0 *----------------------------------------------------------------------------*/ -static int SendInitCommand(char *Cmd) +// 同時接続対応 +//static int SendInitCommand(char *Cmd) +static int SendInitCommand(SOCKET Socket, char *Cmd, int *CancelCheckWork) { char Tmp[INITCMD_LEN+1]; char *Pos; @@ -556,7 +663,8 @@ static int SendInitCommand(char *Cmd) if((Pos = strchr(Tmp, '\r')) != NULL) *Pos = NUL; if(strlen(Tmp) > 0) - DoQUOTE(Tmp); +// DoQUOTE(Tmp); + DoQUOTE(Socket, Tmp, CancelCheckWork); if((Cmd = strchr(Cmd, '\n')) != NULL) Cmd++; @@ -645,10 +753,12 @@ int AskHostPort(void) int AskHostNameKanji(void) { - if(AskCurrentHost() != HOSTNUM_NOENTRY) - CopyHostFromListInConnect(AskCurrentHost(), &CurHost); - - return(CurHost.NameKanjiCode); + // UTF-8対応 +// if(AskCurrentHost() != HOSTNUM_NOENTRY) +// CopyHostFromListInConnect(AskCurrentHost(), &CurHost); +// +// return(CurHost.NameKanjiCode); + return(CurHost.CurNameKanjiCode); } @@ -793,6 +903,14 @@ int AskHostType(void) if(AskCurrentHost() != HOSTNUM_NOENTRY) CopyHostFromListInConnect(AskCurrentHost(), &CurHost); +#if defined(HAVE_TANDEM) + /* OSS ファイルシステムは UNIX ファイルシステムと同じでいいので AUTO を返す + ただし、Guardian ファイルシステムに戻ったときにおかしくならないように + CurHost.HostType 変数は更新しない */ + if(CurHost.HostType == HTYPE_TANDEM && Oss == YES) + return(HTYPE_AUTO); +#endif + return(CurHost.HostType); } @@ -929,9 +1047,7 @@ int ReConnectCmdSkt(void) int Sts; - // 同時接続対応 -// if(CmdCtrlSocket != TrnCtrlSocket) - if(CmdCtrlSocket != TrnCtrlSocket && TrnCtrlSocket != INVALID_SOCKET) + if(CmdCtrlSocket != TrnCtrlSocket) do_closesocket(TrnCtrlSocket); TrnCtrlSocket = INVALID_SOCKET; @@ -958,7 +1074,7 @@ int ReConnectCmdSkt(void) // return(ReConnectSkt(&TrnCtrlSocket)); //} // 同時接続対応 -int ReConnectTrnSkt(SOCKET *Skt) +int ReConnectTrnSkt(SOCKET *Skt, int *CancelCheckWork) { // char Path[FMAX_PATH+1]; int Sts; @@ -984,9 +1100,18 @@ int ReConnectTrnSkt(SOCKET *Skt) HostData.UseFTPIS = NO; if(HostData.CryptMode != CRYPT_SFTP) HostData.UseSFTP = NO; + // UTF-8対応 + HostData.CurNameKanjiCode = HostData.NameKanjiCode; + // IPv6対応 + HostData.CurNetType = HostData.NetType; + // 同時接続対応 + HostData.NoDisplayUI = YES; + // 暗号化通信対応 + // 同時接続対応 // if((*Skt = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET) - if((*Skt = DoConnect(&HostData, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET) + if((*Skt = DoConnect(&HostData, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, CancelCheckWork)) != INVALID_SOCKET) { + SendInitCommand(*Skt, CurHost.InitCmd, CancelCheckWork); // AskRemoteCurDir(Path, FMAX_PATH); // DoCWD(Path, YES, YES, YES); Sts = FFFTP_SUCCESS; @@ -1024,9 +1149,11 @@ static int ReConnectSkt(SOCKET *Skt) do_closesocket(*Skt); /* 再接続 */ // 暗号化通信対応 + // 同時接続対応 // if((*Skt = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET) - if((*Skt = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET) + if((*Skt = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg)) != INVALID_SOCKET) { + SendInitCommand(*Skt, CurHost.InitCmd, &CancelFlg); AskRemoteCurDir(Path, FMAX_PATH); DoCWD(Path, YES, YES, YES); Sts = FFFTP_SUCCESS; @@ -1086,10 +1213,13 @@ void SktShareProh(void) //SetTaskMsg("############### SktShareProh"); // 同時接続対応 - // 転送スレッドがソケットを各自で用意 - // TrnCtrlSocketはメインスレッド以外から使用されない // CmdCtrlSocket = INVALID_SOCKET; // ReConnectSkt(&CmdCtrlSocket); + if(CurHost.ReuseCmdSkt == YES) + { + CmdCtrlSocket = INVALID_SOCKET; + ReConnectSkt(&CmdCtrlSocket); + } } return; } @@ -1110,8 +1240,10 @@ int AskShareProh(void) int Sts; Sts = YES; + // 同時接続対応 // if(CmdCtrlSocket == TrnCtrlSocket) -// Sts = NO; + if(CmdCtrlSocket == TrnCtrlSocket || TrnCtrlSocket == INVALID_SOCKET) + Sts = NO; return(Sts); } @@ -1202,6 +1334,62 @@ int AskConnecting(void) } +#if defined(HAVE_TANDEM) +/*----- 接続している本当のホストのホストタイプを返す -------------------------- +* +* Parameter +* なし +* +* Return Value +* char *ファイル名/オプション +*----------------------------------------------------------------------------*/ + +int AskRealHostType(void) +{ + if(AskCurrentHost() != HOSTNUM_NOENTRY) + CopyHostFromListInConnect(AskCurrentHost(), &CurHost); + + return(CurHost.HostType); +} + +/*----- OSS ファイルシステムにアクセスしているかどうかのフラグを変更する ------ +* +* Parameter +* int ステータス (YES/NO) +* +* Return Value +* int ステータス (YES/NO) +*----------------------------------------------------------------------------*/ + +int SetOSS(int wkOss) +{ + if(Oss != wkOss) { + if (wkOss == YES) { + strcpy(CurHost.InitCmd, "OSS"); + } else { + strcpy(CurHost.InitCmd, "GUARDIAN"); + } + } + Oss = wkOss; + return(Oss); +} + +/*----- OSS ファイルシステムにアクセスしているかどうかを返す ------------------ +* +* Parameter +* なし +* +* Return Value +* int ステータス (YES/NO) +*----------------------------------------------------------------------------*/ + +int AskOSS(void) +{ + return(Oss); +} +#endif /* HAVE_TANDEM */ + + /*----- ホストへ接続する ------------------------------------------------------ * * Parameter @@ -1235,7 +1423,7 @@ int AskConnecting(void) *----------------------------------------------------------------------------*/ // 暗号化通信対応 -static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security) +static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork) { int Sts; int Flg; @@ -1282,7 +1470,9 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char if(strlen(Tmp) != 0) { - if((ContSock = connectsock(Tmp, Port, "", &CancelFlg)) != INVALID_SOCKET) + // 同時接続対応 +// if((ContSock = connectsock(Tmp, Port, "", &CancelFlg)) != INVALID_SOCKET) + if((ContSock = connectsock(Tmp, Port, "", CancelCheckWork)) != INVALID_SOCKET) { // バッファを無効 #ifdef DISABLE_CONTROL_NETWORK_BUFFERS @@ -1295,9 +1485,9 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char // ; if(CryptMode == CRYPT_FTPIS) { - if(AttachSSL(ContSock, INVALID_SOCKET)) + if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork)) { - while((Sts = ReadReplyMessage(ContSock, Buf, 1024, &CancelFlg, TmpBuf) / 100) == FTP_PRELIM) + while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM) ; } else @@ -1305,7 +1495,7 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char } else { - while((Sts = ReadReplyMessage(ContSock, Buf, 1024, &CancelFlg, TmpBuf) / 100) == FTP_PRELIM) + while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM) ; } @@ -1335,15 +1525,21 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char (Fwall == FWALL_FU_FP_USER) || (Fwall == FWALL_FU_FP)) { - if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", FwallUser) / 100) == FTP_CONTINUE) + // 同時接続対応 +// if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", FwallUser) / 100) == FTP_CONTINUE) + if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", FwallUser) / 100) == FTP_CONTINUE) { CheckOneTimePassword(FwallPass, Reply, FwallSecurity); - Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100; + // 同時接続対応 +// Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100; + Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100; } } else if(Fwall == FWALL_SIDEWINDER) { - Sts = command(ContSock, Reply, &CancelFlg, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100; + // 同時接続対応 +// Sts = command(ContSock, Reply, &CancelFlg, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100; + Sts = command(ContSock, Reply, CancelCheckWork, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100; } if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE)) { @@ -1362,9 +1558,13 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char Flg++; if(HostPort == PORT_NOR) - Sts = command(ContSock, NULL, &CancelFlg, "%s %s", SiteTbl[Flg], Host) / 100; + // 同時接続対応 +// Sts = command(ContSock, NULL, &CancelFlg, "%s %s", SiteTbl[Flg], Host) / 100; + Sts = command(ContSock, NULL, CancelCheckWork, "%s %s", SiteTbl[Flg], Host) / 100; else - Sts = command(ContSock, NULL, &CancelFlg, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100; + // 同時接続対応 +// Sts = command(ContSock, NULL, &CancelFlg, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100; + Sts = command(ContSock, NULL, CancelCheckWork, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100; } if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE)) @@ -1376,8 +1576,11 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char else { Anony = NO; + // 同時接続対応 +// if((strlen(User) != 0) || +// (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)) if((strlen(User) != 0) || - (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)) + ((HostData->NoDisplayUI == NO) && (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))) { if(Anony == YES) { @@ -1398,13 +1601,13 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char // FTPES対応 if(CryptMode == CRYPT_FTPES) { - if(IsOpenSSLLoaded() && (Sts = command(ContSock, Reply, &CancelFlg, "AUTH TLS")) == 234) + if(IsOpenSSLLoaded() && (Sts = command(ContSock, Reply, CancelCheckWork, "AUTH TLS")) == 234) { - if(AttachSSL(ContSock, INVALID_SOCKET)) + if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork)) { - if((Sts = command(ContSock, Reply, &CancelFlg, "PBSZ 0")) == 200) + if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200) { - if((Sts = command(ContSock, Reply, &CancelFlg, "PROT P")) == 200) + if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200) { } else @@ -1420,6 +1623,18 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char Sts = FTP_ERROR; } + // FTPIS対応 + // "PBSZ 0"と"PROT P"は黙示的に設定されているはずだが念のため + if(CryptMode == CRYPT_FTPIS) + { + if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200) + { + if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200) + { + } + } + } + ReInPass = NO; do { @@ -1427,10 +1642,15 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char if(Sts == FTP_ERROR) break; Continue = NO; - if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", Buf) / 100) == FTP_CONTINUE) + // 同時接続対応 +// if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", Buf) / 100) == FTP_CONTINUE) + if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", Buf) / 100) == FTP_CONTINUE) { + // 同時接続対応 +// if((strlen(Pass) != 0) || +// (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)) if((strlen(Pass) != 0) || - (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)) + ((HostData->NoDisplayUI == NO) && (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))) { CheckOneTimePassword(Pass, Reply, Security); @@ -1438,11 +1658,15 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char if(strcmp(Reply, " ") == 0) strcpy(Reply, ""); - Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100; + // 同時接続対応 +// Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100; + Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100; if(Sts == FTP_ERROR) { strcpy(Pass, ""); - if(InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES) + // 同時接続対応 +// if(InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES) + if(HostData->NoDisplayUI == NO && InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES) Continue = YES; else DoPrintf("No password specified."); @@ -1450,10 +1674,15 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char } else if(Sts == FTP_CONTINUE) { + // 同時接続対応 +// if((strlen(Acct) != 0) || +// (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)) if((strlen(Acct) != 0) || - (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)) + ((HostData->NoDisplayUI == NO) && (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))) { - Sts = command(ContSock, NULL, &CancelFlg, "ACCT %s", Acct) / 100; + // 同時接続対応 +// Sts = command(ContSock, NULL, &CancelFlg, "ACCT %s", Acct) / 100; + Sts = command(ContSock, NULL, CancelCheckWork, "ACCT %s", Acct) / 100; } else DoPrintf("No account specified"); @@ -1465,6 +1694,9 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char DoPrintf("No password specified."); } } + // FTPES対応 + if(Continue == YES) + Sts = FTP_COMPLETE; } while(Continue == YES); } @@ -1482,7 +1714,9 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char } else if((SavePass == YES) && (ReInPass == YES)) { - if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES) + // 同時接続対応 +// if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES) + if(HostData->NoDisplayUI == NO && DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES) SetHostPassword(AskCurrentHost(), Pass); } } @@ -1516,7 +1750,7 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char // ホストの機能を確認 if(ContSock != INVALID_SOCKET) { - if((Sts = command(ContSock, Reply, &CancelFlg, "FEAT")) == 211) + if((Sts = command(ContSock, Reply, CancelCheckWork, "FEAT")) == 211) { // 改行文字はReadReplyMessageで消去されるため区切り文字に空白を使用 // UTF-8対応 @@ -1530,48 +1764,104 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char HostData->Feature |= FEATURE_EPRT | FEATURE_EPSV; } // UTF-8対応 - if(HostData->NameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8)) + if(HostData->CurNameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8)) { - if((Sts = command(ContSock, Reply, &CancelFlg, "OPTS UTF8 ON")) == 200) - { - } + if((Sts = command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON")) == 200) + HostData->CurNameKanjiCode = KANJI_UTF8N; } } } else if(CryptMode == CRYPT_SFTP) { + // TODO: + // テストコード + // ログイン成功を確認 +#define strrcmp(_Str1, _Str2) (strcmp(strstr(_Str1, _Str2) ? strstr(_Str1, _Str2) : "", _Str2)) + size_t r; + ContSock = SFTP_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + SFTP_SetTimeoutCallback(ContSock, SSLTimeoutCallback); + while(1) + { + r = SFTP_recv(ContSock, Reply, 1024, 0); + if(r == SOCKET_ERROR) + break; + if(r <= 0) + continue; + Reply[r] = '\0'; + SetTaskMsg("%s", Reply); + if(strrcmp(Reply, "psftp> ") == 0) + break; + } + r = SFTP_send(ContSock, "open \"", strlen("open \""), 0); + r = SFTP_send(ContSock, Host, strlen(Host), 0); + r = SFTP_send(ContSock, "\"\r\n", strlen("\"\r\n"), 0); + while(1) + { + r = SFTP_recv(ContSock, Reply, 1024, 0); + if(r == SOCKET_ERROR) + break; + if(r <= 0) + continue; + Reply[r] = '\0'; + SetTaskMsg("%s", Reply); + if(strrcmp(Reply, "Store key in cache? (y/n) ") == 0) + { + r = SFTP_send(ContSock, "n\r\n", strlen("n\r\n"), 0); + } + if(strrcmp(Reply, "Update cached key? (y/n, Return cancels connection) ") == 0) + { + r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0); + } + if(strrcmp(Reply, "login as: ") == 0) + { + r = SFTP_send(ContSock, User, strlen(User), 0); + r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0); + } + if(strrcmp(Reply, "password: ") == 0) + { + r = SFTP_send(ContSock, Pass, strlen(Pass), 0); + r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0); + } + if(strrcmp(Reply, "psftp> ") == 0) + break; + Sleep(1); + } + SFTP_closesocket(ContSock); + ContSock = INVALID_SOCKET; } return(ContSock); } -static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security) +// 同時接続対応 +//static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security) +static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork) { SOCKET ContSock; ContSock = INVALID_SOCKET; - CancelFlg = NO; - if(CancelFlg == NO && ContSock == INVALID_SOCKET && HostData->UseSFTP == YES) + *CancelCheckWork = NO; + if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseSFTP == YES) { SetTaskMsg(MSGJPN317); - if((ContSock = DoConnectCrypt(CRYPT_SFTP, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security)) != INVALID_SOCKET) + if((ContSock = DoConnectCrypt(CRYPT_SFTP, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET) HostData->CryptMode = CRYPT_SFTP; } - if(CancelFlg == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES) + if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES) { SetTaskMsg(MSGJPN316); - if((ContSock = DoConnectCrypt(CRYPT_FTPIS, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security)) != INVALID_SOCKET) + if((ContSock = DoConnectCrypt(CRYPT_FTPIS, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET) HostData->CryptMode = CRYPT_FTPIS; } - if(CancelFlg == NO && ContSock == INVALID_SOCKET && HostData->UseFTPES == YES) + if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPES == YES) { SetTaskMsg(MSGJPN315); - if((ContSock = DoConnectCrypt(CRYPT_FTPES, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security)) != INVALID_SOCKET) + if((ContSock = DoConnectCrypt(CRYPT_FTPES, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET) HostData->CryptMode = CRYPT_FTPES; } - if(CancelFlg == NO && ContSock == INVALID_SOCKET && HostData->UseNoEncryption == YES) + if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseNoEncryption == YES) { SetTaskMsg(MSGJPN314); - if((ContSock = DoConnectCrypt(CRYPT_NONE, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security)) != INVALID_SOCKET) + if((ContSock = DoConnectCrypt(CRYPT_NONE, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET) HostData->CryptMode = CRYPT_NONE; } return ContSock; @@ -1703,8 +1993,36 @@ static int CheckOneTimePassword(char *Pass, char *Reply, int Type) * SOCKET ソケット *----------------------------------------------------------------------------*/ +// IPv6対応 SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork) { + SOCKET Result; + Result = INVALID_SOCKET; + switch(CurHost.CurNetType) + { + case NTYPE_AUTO: + if((Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET) + CurHost.CurNetType = NTYPE_IPV4; + else if((Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET) + CurHost.CurNetType = NTYPE_IPV6; + break; + case NTYPE_IPV4: + Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork); + CurHost.CurNetType = NTYPE_IPV4; + break; + case NTYPE_IPV6: + Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork); + CurHost.CurNetType = NTYPE_IPV6; + break; + } + return Result; +} + + +// IPv6対応 +//SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork) +SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork) +{ struct sockaddr_in saSockAddr; char HostEntry[MAXGETHOSTSTRUCT]; struct hostent *pHostEntry; @@ -1728,10 +2046,15 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork) UseIPadrs = YES; strcpy(DomainName, host); - memset(&CurSockAddr, 0, sizeof(CurSockAddr)); - CurSockAddr.sin_port = htons((u_short)port); - CurSockAddr.sin_family = AF_INET; - if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) + // IPv6対応 +// memset(&CurSockAddr, 0, sizeof(CurSockAddr)); +// CurSockAddr.sin_port = htons((u_short)port); +// CurSockAddr.sin_family = AF_INET; +// if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) + memset(&CurSockAddrIPv4, 0, sizeof(CurSockAddrIPv4)); + CurSockAddrIPv4.sin_port = htons((u_short)port); + CurSockAddrIPv4.sin_family = AF_INET; + if((CurSockAddrIPv4.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) { // ホスト名が指定された // ホスト名からアドレスを求める @@ -1745,20 +2068,27 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork) { // アドレスを取得 SetTaskMsg(MSGJPN016, DomainName); - pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork); + // IPv6対応 +// pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork); + pHostEntry = do_gethostbynameIPv4(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork); } if(pHostEntry != NULL) { - memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length); - SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port)); + // IPv6対応 +// memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length); +// SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port)); + memcpy((char *)&CurSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length); + SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port)); } else { if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) { UseIPadrs = NO; - SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port)); + // IPv6対応 +// SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port)); + SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv4.sin_port)); } else { @@ -1768,7 +2098,9 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork) } } else - SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port)); + // IPv6対応 +// SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port)); + SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddrIPv4.sin_addr), ntohs(CurSockAddrIPv4.sin_port)); if((Fwall == FWALL_SOCKS4) || (Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) { @@ -1778,37 +2110,56 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork) { Socks4Cmd.Ver = SOCKS4_VER; Socks4Cmd.Cmd = SOCKS4_CMD_CONNECT; - Socks4Cmd.Port = CurSockAddr.sin_port; - Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr; + // IPv6対応 +// Socks4Cmd.Port = CurSockAddr.sin_port; +// Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr; + Socks4Cmd.Port = CurSockAddrIPv4.sin_port; + Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr; strcpy(Socks4Cmd.UserID, FwallUser); Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1; } else { - Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port); + // IPv6対応 +// Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port); + Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port); } - memset(&SocksSockAddr, 0, sizeof(SocksSockAddr)); - if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE) + // IPv6対応 +// memset(&SocksSockAddr, 0, sizeof(SocksSockAddr)); +// if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE) + memset(&SocksSockAddrIPv4, 0, sizeof(SocksSockAddrIPv4)); + if((SocksSockAddrIPv4.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE) { - if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL) - memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length); + // IPv6対応 +// if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL) +// memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length); + if((pHostEntry = do_gethostbynameIPv4(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL) + memcpy((char *)&SocksSockAddrIPv4.sin_addr, pHostEntry->h_addr, pHostEntry->h_length); else { SetTaskMsg(MSGJPN021, FwallHost); return INVALID_SOCKET; } } - SocksSockAddr.sin_port = htons((u_short)FwallPort); - SocksSockAddr.sin_family = AF_INET; - SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port)); + // IPv6対応 +// SocksSockAddr.sin_port = htons((u_short)FwallPort); +// SocksSockAddr.sin_family = AF_INET; +// SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port)); + SocksSockAddrIPv4.sin_port = htons((u_short)FwallPort); + SocksSockAddrIPv4.sin_family = AF_INET; + SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddrIPv4.sin_addr), ntohs(SocksSockAddrIPv4.sin_port)); // connectで接続する先はSOCKSサーバ - memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr)); + // IPv6対応 +// memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr)); + memcpy(&saSockAddr, &SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4)); } else { // connectで接続するのは接続先のホスト - memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr)); + // IPv6対応 +// memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr)); + memcpy(&saSockAddr, &CurSockAddrIPv4, sizeof(CurSockAddrIPv4)); } ///////////// @@ -1822,8 +2173,12 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork) if(Fwall == FWALL_SOCKS4) { Socks4Reply.Result = -1; + // 同時接続対応 +// if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || +// (Socks4GetCmdReply(sSocket, &Socks4Reply) != FFFTP_SUCCESS) || +// (Socks4Reply.Result != SOCKS4_RES_OK)) if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || - (Socks4GetCmdReply(sSocket, &Socks4Reply) != FFFTP_SUCCESS) || + (Socks4GetCmdReply(sSocket, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || (Socks4Reply.Result != SOCKS4_RES_OK)) { SetTaskMsg(MSGJPN023, Socks4Reply.Result); @@ -1840,8 +2195,161 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork) } Socks5Reply.Result = -1; + // 同時接続対応 +// if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || +// (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || +// (Socks5Reply.Result != SOCKS5_RES_OK)) + if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || + (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || + (Socks5Reply.Result != SOCKS5_RES_OK)) + { + SetTaskMsg(MSGJPN024, Socks5Reply.Result); + DoClose(sSocket); + sSocket = INVALID_SOCKET; + } + + } + + if(sSocket != INVALID_SOCKET) + SetTaskMsg(MSGJPN025); + } + else + { +//#pragma aaa + SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/); + DoClose(sSocket); + sSocket = INVALID_SOCKET; + } + } + else + SetTaskMsg(MSGJPN027); + + return(sSocket); +} + + +SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork) +{ + struct sockaddr_in6 saSockAddr; + char HostEntry[MAXGETHOSTSTRUCT]; + struct hostent *pHostEntry; + SOCKET sSocket; + int Len; + int Fwall; + SOCKS5REQUEST Socks5Cmd; + SOCKS5REPLY Socks5Reply; + + ////////////////////////////// + // ホスト名解決と接続の準備 + ////////////////////////////// + + Fwall = FWALL_NONE; + if(AskHostFireWall() == YES) + Fwall = FwallType; + + sSocket = INVALID_SOCKET; + + UseIPadrs = YES; + strcpy(DomainName, host); + memset(&CurSockAddrIPv6, 0, sizeof(CurSockAddrIPv6)); + CurSockAddrIPv6.sin6_port = htons((u_short)port); + CurSockAddrIPv6.sin6_family = AF_INET6; + CurSockAddrIPv6.sin6_addr = inet6_addr(host); + if(memcmp(&CurSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0) + { + // ホスト名が指定された + // ホスト名からアドレスを求める + if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) && + (FwallResolv == YES)) + { + // ホスト名解決はSOCKSサーバに任せる + pHostEntry = NULL; + } + else + { + // アドレスを取得 + SetTaskMsg(MSGJPN016, DomainName); + pHostEntry = do_gethostbynameIPv6(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork); + } + + if(pHostEntry != NULL) + { + memcpy((char *)&CurSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length); + SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port)); + } + else + { + if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) + { + UseIPadrs = NO; + SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddrIPv6.sin6_port)); + } + else + { + SetTaskMsg(MSGJPN019, host); + return(INVALID_SOCKET); + } + } + } + else + SetTaskMsg(MSGJPN020, PreMsg, inet6_ntoa(CurSockAddrIPv6.sin6_addr), ntohs(CurSockAddrIPv6.sin6_port)); + + if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) + { + // SOCKSを使う + // SOCKSに接続する準備 + { + Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port); + } + + memset(&SocksSockAddrIPv6, 0, sizeof(SocksSockAddrIPv6)); + SocksSockAddrIPv6.sin6_addr = inet6_addr(FwallHost); + if(memcmp(&SocksSockAddrIPv6.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0) + { + if((pHostEntry = do_gethostbynameIPv6(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL) + memcpy((char *)&SocksSockAddrIPv6.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length); + else + { + SetTaskMsg(MSGJPN021, FwallHost); + return INVALID_SOCKET; + } + } + SocksSockAddrIPv6.sin6_port = htons((u_short)FwallPort); + SocksSockAddrIPv6.sin6_family = AF_INET6; + SetTaskMsg(MSGJPN022, inet6_ntoa(SocksSockAddrIPv6.sin6_addr), ntohs(SocksSockAddrIPv6.sin6_port)); + // connectで接続する先はSOCKSサーバ + memcpy(&saSockAddr, &SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6)); + } + else + { + // connectで接続するのは接続先のホスト + memcpy(&saSockAddr, &CurSockAddrIPv6, sizeof(CurSockAddrIPv6)); + } + + ///////////// + // 接続実行 + ///////////// + + inet6_ntoa(saSockAddr.sin6_addr); + if((sSocket = do_socket(AF_INET6, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET) + { + if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR) + { + if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) + { + if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL) + { + DoClose(sSocket); + sSocket = INVALID_SOCKET; + } + + Socks5Reply.Result = -1; + // 同時接続対応 +// if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || +// (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || +// (Socks5Reply.Result != SOCKS5_RES_OK)) if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || - (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || + (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || (Socks5Reply.Result != SOCKS5_RES_OK)) { SetTaskMsg(MSGJPN024, Socks5Reply.Result); @@ -1878,8 +2386,28 @@ SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork) * SOCKET リッスンソケット *----------------------------------------------------------------------------*/ +// IPv6対応 SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork) { + SOCKET Result; + Result = INVALID_SOCKET; + switch(CurHost.CurNetType) + { + case NTYPE_IPV4: + Result = GetFTPListenSocketIPv4(ctrl_skt, CancelCheckWork); + break; + case NTYPE_IPV6: + Result = GetFTPListenSocketIPv6(ctrl_skt, CancelCheckWork); + break; + } + return Result; +} + + +// IPv6対応 +//SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork) +SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork) +{ SOCKET listen_skt; int iLength; char *a,*p; @@ -1903,18 +2431,27 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork) { /*===== SOCKS4を使う =====*/ DoPrintf("Use SOCKS4 BIND"); - if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR) + // IPv6対応 +// if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR) + if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR) { Socks4Cmd.Ver = SOCKS4_VER; Socks4Cmd.Cmd = SOCKS4_CMD_BIND; - Socks4Cmd.Port = CurSockAddr.sin_port; - Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr; + // IPv6対応 +// Socks4Cmd.Port = CurSockAddr.sin_port; +// Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr; + Socks4Cmd.Port = CurSockAddrIPv4.sin_port; + Socks4Cmd.AdrsInt = CurSockAddrIPv4.sin_addr.s_addr; strcpy(Socks4Cmd.UserID, FwallUser); Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1; Socks4Reply.Result = -1; + // 同時接続対応 +// if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || +// (Socks4GetCmdReply(listen_skt, &Socks4Reply) != FFFTP_SUCCESS) || +// (Socks4Reply.Result != SOCKS4_RES_OK)) if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || - (Socks4GetCmdReply(listen_skt, &Socks4Reply) != FFFTP_SUCCESS) || + (Socks4GetCmdReply(listen_skt, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || (Socks4Reply.Result != SOCKS4_RES_OK)) { SetTaskMsg(MSGJPN028, Socks4Reply.Result); @@ -1923,7 +2460,9 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork) } if(Socks4Reply.AdrsInt == 0) - Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr; + // IPv6対応 +// Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr; + Socks4Reply.AdrsInt = SocksSockAddrIPv4.sin_addr.s_addr; a = (char *)&Socks4Reply.AdrsInt; p = (char *)&Socks4Reply.Port; @@ -1933,7 +2472,9 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork) { /*===== SOCKS5を使う =====*/ DoPrintf("Use SOCKS5 BIND"); - if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR) + // IPv6対応 +// if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR) + if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv4, sizeof(SocksSockAddrIPv4), CancelCheckWork) != SOCKET_ERROR) { if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL) { @@ -1942,11 +2483,17 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork) return(listen_skt); } - Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port); + // IPv6対応 +// Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port); + Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddrIPv4.sin_addr.s_addr, DomainName, CurSockAddrIPv4.sin_port); Socks5Reply.Result = -1; + // 同時接続対応 +// if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || +// (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || +// (Socks5Reply.Result != SOCKS5_RES_OK)) if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || - (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || + (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || (Socks5Reply.Result != SOCKS5_RES_OK)) { SetTaskMsg(MSGJPN029, Socks5Reply.Result); @@ -1954,11 +2501,15 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork) listen_skt = INVALID_SOCKET; } - if(Socks5Reply.AdrsInt == 0) - Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr; + // IPv6対応 +// if(Socks5Reply.AdrsInt == 0) +// Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr; - a = (char *)&Socks5Reply.AdrsInt; - p = (char *)&Socks5Reply.Port; + // IPv6対応 +// a = (char *)&Socks5Reply.AdrsInt; +// p = (char *)&Socks5Reply.Port; + a = (char *)&Socks5Reply._dummy[0]; + p = (char *)&Socks5Reply._dummy[4]; } } else @@ -2014,7 +2565,11 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork) if(listen_skt != INVALID_SOCKET) { #define UC(b) (((int)b)&0xff) - if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d", + // 同時接続対応 +// if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d", +// UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), +// UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE) + if((command(ctrl_skt,NULL, CancelCheckWork, "PORT %d,%d,%d,%d,%d,%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE) { @@ -2030,6 +2585,140 @@ SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork) } +SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork) +{ + SOCKET listen_skt; + int iLength; + char *a,*p; + struct sockaddr_in6 saCtrlAddr; + struct sockaddr_in6 saTmpAddr; + SOCKS5REQUEST Socks5Cmd; + SOCKS5REPLY Socks5Reply; + + int Len; + int Fwall; + + char Adrs[40]; + + Fwall = FWALL_NONE; + if(AskHostFireWall() == YES) + Fwall = FwallType; + + if((listen_skt = do_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET) + { + if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) + { + /*===== SOCKS5を使う =====*/ + DoPrintf("Use SOCKS5 BIND"); + if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddrIPv6, sizeof(SocksSockAddrIPv6), CancelCheckWork) != SOCKET_ERROR) + { + if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL) + { + DoClose(listen_skt); + listen_skt = INVALID_SOCKET; + return(listen_skt); + } + + Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, (char*)&CurSockAddrIPv6.sin6_addr, DomainName, CurSockAddrIPv6.sin6_port); + + Socks5Reply.Result = -1; + // 同時接続対応 +// if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || +// (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || +// (Socks5Reply.Result != SOCKS5_RES_OK)) + if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) || + (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || + (Socks5Reply.Result != SOCKS5_RES_OK)) + { + SetTaskMsg(MSGJPN029, Socks5Reply.Result); + DoClose(listen_skt); + listen_skt = INVALID_SOCKET; + } + + // IPv6対応 +// if(Socks5Reply.AdrsInt == 0) +// Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr; + + // IPv6対応 +// a = (char *)&Socks5Reply.AdrsInt; +// p = (char *)&Socks5Reply.Port; + a = (char *)&Socks5Reply._dummy[0]; + p = (char *)&Socks5Reply._dummy[16]; + } + } + else + { + /*===== SOCKSを使わない =====*/ + DoPrintf("Use normal BIND"); + saCtrlAddr.sin6_port = htons(0); + saCtrlAddr.sin6_family = AF_INET6; + memset(&saCtrlAddr.sin6_addr, 0, 16); + + if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr_in6)) != SOCKET_ERROR) + { + iLength = sizeof(saCtrlAddr); + if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR) + { + if(do_listen(listen_skt, 1) == 0) + { + iLength = sizeof(saTmpAddr); + if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR) + ReportWSError("getsockname", WSAGetLastError()); + + a = (char *)&saTmpAddr.sin6_addr; + p = (char *)&saCtrlAddr.sin6_port; + } + else + { + ReportWSError("listen", WSAGetLastError()); + do_closesocket(listen_skt); + listen_skt = INVALID_SOCKET; + } + } + else + { + ReportWSError("getsockname", WSAGetLastError()); + do_closesocket(listen_skt); + listen_skt = INVALID_SOCKET; + } + } + else + { + ReportWSError("bind", WSAGetLastError()); + do_closesocket(listen_skt); + listen_skt = INVALID_SOCKET; + } + + if(listen_skt == INVALID_SOCKET) + SetTaskMsg(MSGJPN030); + } + } + else + ReportWSError("socket create", WSAGetLastError()); + + if(listen_skt != INVALID_SOCKET) + { +#define UC(b) (((int)b)&0xff) + // 同時接続対応 +// if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d", +// UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), +// UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE) + if((command(ctrl_skt,NULL, CancelCheckWork, "EPRT |2|%s|%d|", + AddressToStringIPv6(Adrs, a), + (UC(p[0]) << 8) | UC(p[1])) / 100) != FTP_COMPLETE) + { + SetTaskMsg(MSGJPN031); + do_closesocket(listen_skt); + listen_skt = INVALID_SOCKET; + } +// else +// DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port)); + } + + return(listen_skt); +} + + /*----- ホストへ接続処理中かどうかを返す--------------------------------------- * * Parameter @@ -2123,6 +2812,44 @@ static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulo } +// IPv6対応 +static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port) +{ + uchar *Pos; + int Len; + int TotalLen; + + Pos = (uchar *)Packet; + Pos += SOCKS5REQUEST_SIZE; + TotalLen = SOCKS5REQUEST_SIZE + 2; /* +2はポートの分 */ + + Packet->Ver = SOCKS5_VER; + Packet->Cmd = Cmd; + Packet->Rsv = 0; + if(ValidIP == YES) + { + /* IPアドレスを指定 */ + Packet->Type = SOCKS5_ADRS_IPV6; + memcpy(Pos, IP, 16); + Pos += 16; + TotalLen += 16; + } + else + { + /* ホスト名を指定 */ + Packet->Type = SOCKS5_ADRS_NAME; + Len = strlen(Host); + *Pos++ = Len; + strcpy(Pos, Host); + Pos += Len; + TotalLen += Len + 1; + } + *((ushort *)Pos) = Port; + + return(TotalLen); +} + + /*----- SOCKSのコマンドを送る ------------------------------------------------- * * Parameter @@ -2157,7 +2884,9 @@ static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWor * int ステータス (FFFTP_SUCCESS/FFFTP_FAIL) *----------------------------------------------------------------------------*/ -static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet) +// 同時接続対応 +//static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet) +static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelCheckWork) { uchar *Pos; int Len; @@ -2166,15 +2895,19 @@ static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet) Pos = (uchar *)Packet; Pos += SOCKS5REPLY_SIZE; - if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, &CancelFlg)) == FFFTP_SUCCESS) + // 同時接続対応 +// if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, &CancelFlg)) == FFFTP_SUCCESS) + if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, CancelCheckWork)) == FFFTP_SUCCESS) { if(Packet->Type == SOCKS5_ADRS_IPV4) Len = 4 + 2; else if(Packet->Type == SOCKS5_ADRS_IPV6) - Len = 6 + 2; + Len = 16 + 2; else { - if((Ret = ReadNchar(Socket, (char *)Pos, 1, &CancelFlg)) == FFFTP_SUCCESS) + // 同時接続対応 +// if((Ret = ReadNchar(Socket, (char *)Pos, 1, &CancelFlg)) == FFFTP_SUCCESS) + if((Ret = ReadNchar(Socket, (char *)Pos, 1, CancelCheckWork)) == FFFTP_SUCCESS) { Len = *Pos + 2; Pos++; @@ -2182,7 +2915,9 @@ static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet) } if(Ret == FFFTP_SUCCESS) - Ret = ReadNchar(Socket, (char *)Pos, Len, &CancelFlg); + // 同時接続対応 +// Ret = ReadNchar(Socket, (char *)Pos, Len, &CancelFlg); + Ret = ReadNchar(Socket, (char *)Pos, Len, CancelCheckWork); } if(Ret != FFFTP_SUCCESS) @@ -2202,11 +2937,15 @@ static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet) * int ステータス (FFFTP_SUCCESS/FFFTP_FAIL) *----------------------------------------------------------------------------*/ -static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet) +// 同時接続対応 +//static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet) +static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet, int *CancelCheckWork) { int Ret; - Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, &CancelFlg); + // 同時接続対応 +// Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, &CancelFlg); + Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, CancelCheckWork); if(Ret != FFFTP_SUCCESS) DoPrintf(MSGJPN035); @@ -2242,8 +2981,12 @@ static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork) else Socks5Method.Methods[0] = SOCKS5_AUTH_USER; + // 同時接続対応 +// if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) || +// (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, &CancelFlg) != FFFTP_SUCCESS) || +// (Socks5MethodReply.Method == (uchar)0xFF)) if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) || - (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, &CancelFlg) != FFFTP_SUCCESS) || + (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, CancelCheckWork) != FFFTP_SUCCESS) || (Socks5MethodReply.Method == (uchar)0xFF)) { SetTaskMsg(MSGJPN036); @@ -2260,8 +3003,12 @@ static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork) Buf[2 + Len] = Len2; strcpy(Buf+3+Len, FwallPass); + // 同時接続対応 +// if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) || +// (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, &CancelFlg) != FFFTP_SUCCESS) || +// (Socks5Status.Status != 0)) if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) || - (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, &CancelFlg) != FFFTP_SUCCESS) || + (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, CancelCheckWork) != FFFTP_SUCCESS) || (Socks5Status.Status != 0)) { SetTaskMsg(MSGJPN037); @@ -2285,7 +3032,9 @@ static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork) * int ステータス (FFFTP_SUCCESS/FFFTP_FAIL) *----------------------------------------------------------------------------*/ -int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data) +// 同時接続対応 +//int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data) +int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data, int *CancelCheckWork) { int Ret; char Buf[300]; @@ -2293,14 +3042,18 @@ int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data) Ret = FFFTP_FAIL; if((AskHostFireWall() == YES) && (FwallType == FWALL_SOCKS4)) { - Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf); + // 同時接続対応 +// Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf); + Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf, CancelCheckWork); *Data = Socket; Ret = FFFTP_SUCCESS; } else if((AskHostFireWall() == YES) && ((FwallType == FWALL_SOCKS5_NOAUTH) || (FwallType == FWALL_SOCKS5_USER))) { - Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf); + // 同時接続対応 +// Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf); + Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf, CancelCheckWork); *Data = Socket; Ret = FFFTP_SUCCESS; } @@ -2346,6 +3099,11 @@ int AskMaxThreadCount(void) return(CurHost.MaxThreadCount); } +int AskReuseCmdSkt(void) +{ + return(CurHost.ReuseCmdSkt); +} + // FEAT対応 int AskHostFeature(void) { @@ -2359,8 +3117,25 @@ int AskUseMLSD(void) } // IPv6対応 -int AskUseIPv6(void) +int AskCurNetType(void) +{ + return(CurHost.CurNetType); +} + +// 自動切断対策 +int AskNoopInterval(void) +{ + return(CurHost.NoopInterval); +} + +// 再転送対応 +int AskTransferErrorMode(void) +{ + return(CurHost.TransferErrorMode); +} + +int AskTransferErrorNotify(void) { - return(CurHost.UseIPv6); + return(CurHost.TransferErrorNotify); }