protected override string ConnectJob(SockTcp client, SockTcp server, List <byte[]> clientBuf) { //最初のグリーティングメッセージ取得 var buf = server.LineRecv(Timeout, this); if (buf == null) { return(null);//タイムアウト } //EHLO送信 server.LineSend(clientBuf[0]); clientBuf.RemoveAt(0); //「250 OK」が返るまで読み飛ばす while (IsLife()) { buf = server.LineRecv(Timeout, this); if (buf == null) { return(null);//タイムアウト } var str = Inet.TrimCrlf(Encoding.ASCII.GetString(buf)); if (str.ToUpper().IndexOf("250 ") == 0) { return(str); } } return(null); }
public void EchoサーバにlineSendで1行送信してlineRecvで1行受信する() { //setUp const string addr = "127.0.0.1"; const int port = 9993; var sv = new EchoServer(addr, port); sv.Start(); var sut = new SockTcp(new Kernel(), new Ip(addr), port, 100, null); sut.LineSend(Encoding.UTF8.GetBytes("本日は晴天なり")); Thread.Sleep(10); var expected = "本日は晴天なり\r\n"; //exercise var bytes = sut.LineRecv(1, this); var actual = Encoding.UTF8.GetString(bytes); //verify Assert.That(actual, Is.EqualTo(expected)); //tearDown sut.Close(); sv.Stop(); }
//TODO RecvCmdのパラメータ形式を変更するが、これは、後ほど、Web,Ftp,SmtpのServerで使用されているため影響がでる予定 //コマンド取得 //コネクション切断などエラーが発生した時はnullが返される protected Cmd recvCmd(SockTcp sockTcp) { if (sockTcp.SockState != sock.SockState.Connect) { //切断されている return(null); } var recvbuf = sockTcp.LineRecv(Timeout, this); //切断された場合 if (recvbuf == null) { return(null); } //受信待機中の場合 if (recvbuf.Length == 0) { //Ver5.8.5 Java fix //return new Cmd("", "", ""); return(new Cmd("waiting", "", "")); //待機中の場合、そのことが分かるように"waiting"を返す } //CRLFの排除 recvbuf = Inet.TrimCrlf(recvbuf); //String str = new String(recvbuf, Charset.forName("Shift-JIS")); var str = Encoding.GetEncoding("Shift-JIS").GetString(recvbuf); if (str == "") { return(new Cmd("", "", "")); } //受信行をコマンドとパラメータに分解する(コマンドとパラメータは1つ以上のスペースで区切られている) String cmdStr = null; String paramStr = null; for (int i = 0; i < str.Length; i++) { if (str[i] == ' ') { if (cmdStr == null) { cmdStr = str.Substring(0, i); } } if (cmdStr == null || str[i] == ' ') { continue; } paramStr = str.Substring(i); break; } if (cmdStr == null) { //パラメータ区切りが見つからなかった場合 cmdStr = str; //全部コマンド } return(new Cmd(str, cmdStr, paramStr)); }
//TODO RecvCmd�̃p�����[�^�`����ύX���邪�A����́A��قǁAWeb,Ftp,Smtp��Server�Ŏg�p����Ă��邽�߉e�����ł�\�� //�R�}���h�擾 //�R�l�N�V�����ؒf�ȂǃG���[��������������null���Ԃ���� protected Cmd recvCmd(SockTcp sockTcp) { if (sockTcp.SockState != sock.SockState.Connect) { //�ؒf����Ă��� return(null); } var recvbuf = sockTcp.LineRecv(Timeout, this); //�ؒf���ꂽ�ꍇ if (recvbuf == null) { return(null); } //��M�ҋ@���̏ꍇ if (recvbuf.Length == 0) { //Ver5.8.5 Java fix //return new Cmd("", "", ""); return(new Cmd("waiting", "", "")); //�ҋ@���̏ꍇ�A���̂��Ƃ�������悤��"waiting"��Ԃ� } //CRLF�̔r�� recvbuf = Inet.TrimCrlf(recvbuf); //String str = new String(recvbuf, Charset.forName("Shift-JIS")); var str = Encoding.GetEncoding("Shift-JIS").GetString(recvbuf); if (str == "") { return(new Cmd("", "", "")); } //��M�s��R�}���h�ƃp�����[�^�ɕ������i�R�}���h�ƃp�����[�^�͂P�ȏ�̃X�y�[�X�ŋ���Ă���j String cmdStr = null; String paramStr = null; for (int i = 0; i < str.Length; i++) { if (str[i] == ' ') { if (cmdStr == null) { cmdStr = str.Substring(0, i); } } if (cmdStr == null || str[i] == ' ') { continue; } paramStr = str.Substring(i); break; } if (cmdStr == null) { //�p�����[�^��肪������Ȃ������ꍇ cmdStr = str; //�S���R�}���h } return(new Cmd(str, cmdStr, paramStr)); }
protected override string BeforeJob(SockTcp client, List <byte[]> clientBuf) { Protocol = MailProxyProtocolKind.Smtp; //挨拶文をサーバに変わって送出する client.AsciiSend("220 SMTP-Proxy"); while (clientBuf.Count < 5) { var buf = client.LineRecv(Timeout, this); if (buf == null) { return(null);//タイムアウト } //Ver5.8.6 //var str = Inet.TrimCrlf(Encoding.ASCII.GetString(buf)); buf = Inet.TrimCrlf(buf); var str = Encoding.ASCII.GetString(buf); //Ver5,3,4 RESTコマンドは蓄積がプロトコル上できないのでサーバへは送らない if (str.ToUpper().IndexOf("RSET") != 0) { clientBuf.Add(buf); } if (str.ToUpper().IndexOf("QUIT") != -1) { return(null); } if (clientBuf.Count > 1) { if (str.ToUpper().IndexOf("MAIL FROM:") != -1) { var mailAddress = str.Substring(str.IndexOf(":") + 1); mailAddress = mailAddress.Trim(); mailAddress = mailAddress.Trim(new[] { '<', '>' }); return(mailAddress);//メールアドレス } } client.AsciiSend("250 OK"); } return(null); }
bool RecvStatus() { var buf = _sockTcp.LineRecv(_sec, _iLife); if (buf == null) { SetLastError("Timeout in PopClient RecvStatus()"); ConfirmConnect();//接続確認 return(false); } var str = Encoding.ASCII.GetString(buf); if (str.ToUpper().IndexOf("+OK") == 0) { return(true); } SetLastError("Not Found +OK in PopClient RecvStatus()"); ConfirmConnect();//接続確認 return(false); }
protected override string BeforeJob(SockTcp client, List <byte[]> clientBuf) { Protocol = MailProxyProtocol.Pop3; //挨拶文をサーバに変わって送出する client.AsciiSend("+OK "); //USER コマンドを受け付けるまでループ(最大5回)する for (var i = 0; i < 5; i++) { var buf = client.LineRecv(Timeout, this); if (buf != null) { var str = Inet.TrimCrlf(Encoding.ASCII.GetString(buf)); if (str.ToUpper().IndexOf("USER") == 0) { clientBuf.Add(buf); var tmp = str.Split(' '); if (tmp.Length >= 2) { return(tmp[1]);//ユーザ名 } } else if (str.ToUpper().IndexOf("QUIT") == 0) { return(null); } else { client.AsciiSend("-ERR "); } } else { Thread.Sleep(300); } } return(null); }
static public List <String> RecvLines(SockTcp cl, int sec, ILife iLife) { var lines = new List <string>(); while (true) { var buf = cl.LineRecv(sec, iLife); if (buf == null) { break; } if (buf.Length == 0) { break; } var s = Encoding.ASCII.GetString(TrimCrlf(buf)); //if (s == "") // break; lines.Add(s); } return(lines); }
public bool Recv(SockTcp sockTcp, int timeout, ILife iLife) { //�w�b�_�擾�i�f�[�^�͏����������j _ar.Clear(); var key = ""; while (iLife.IsLife()) { var line = sockTcp.LineRecv(timeout, iLife); if (line == null) { return(false); } line = Inet.TrimCrlf(line); if (line.Length == 0) { return(true);//�w�b�_�̏I�� } //�P�s���̃f�[�^����Key��Val��擾���� byte[] val = GetKeyVal(line, ref key); if (key != "") { Append(key, val); } else { //Ver5.4.4 HTTP/1.0 200 OK��Q�s�Ԃ��T�[�o�������̂ɑΏ� var s = Encoding.ASCII.GetString(line); if (s.IndexOf("HTTP/") != 0) { return(false);//�w�b�_�ُ� } } } return(false); }
bool RecvStatus(int no) { while (_iLife.IsLife()) { var buf = _sockTcp.LineRecv(_sec, _iLife); if (buf == null) { SetLastError("Timeout in SmtpClient RecvStatus()"); break; } _recvStr = Encoding.ASCII.GetString(buf); if (_recvStr.Length < 3) { SetLastError("str.Length<3 in SmtpClient RecvStatus()"); break; } if (_recvStr.Length > 3 && _recvStr[4] == '-') { continue; } int result; if (!Int32.TryParse(_recvStr.Substring(0, 3), out result)) { SetLastError("Faild TryPatse() in SmtpClient RecvStatus()"); break; } if (result == no) { return(true); } SetLastError(_recvStr); break; } ConfirmConnect();//接続確認 return(false); }
//string esmtpUser��null�łȂ��ꍇ�ASMTP�F��g�p���� public SmtpClientResult Send(SockTcp sockTcp, string serverName, Mail mail, MailAddress from, MailAddress to, string authUser, string authPass, ILife iLife) { var state = State.Ehlo; const int timeout = 3; var result = SmtpClientResult.Faild; //AUTH_STATE authState = AUTH_STATE.LOGIN; var smtpAuthClient = new SmtpAuthClient(authUser, authPass); LastLog.Clear();//���M���s���̋L�^�̓N���A���� while (iLife.IsLife()) { //******************************************************************** // �T�[�o����̃��X�|���X�R�[�h(response)��M //******************************************************************** int response; //var recvBuf = sockTcp.LineRecv(timeout,OperateCrlf.No,ref life); //Ver5.7.3 �^�C���A�E�g���������āA�Ԏ��̒x���T�[�o�ŃG���[�ƂȂ��Ă��܂� var recvBuf = sockTcp.LineRecv(timeout + 30, iLife); if (recvBuf == null) { //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); //LastLog.Add(recvStr); break; } if (recvBuf.Length == 0) { Thread.Sleep(10); continue; } recvBuf = Inet.TrimCrlf(recvBuf);//\r\n�̔r�� var recvStr = Encoding.ASCII.GetString(recvBuf); if (state == State.Ehlo) { smtpAuthClient.Ehlo(recvStr);//AUTH�̑Ή���擾 } if (recvStr[3] == '-') { //string paramStr = recvStr.Substring(4); continue; } if (recvStr.IndexOf(' ') == 3) { response = Convert.ToInt32(recvStr.Substring(0, 3)); } else { //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); LastLog.Add(recvStr); break; } //******************************************************************** // ��M�������X�|���X�R�[�h(response)�ɂ����(mode)�̕ύX //******************************************************************** if (response == 220) { state = State.Ehlo; } else if (response == 221) { if (state == State.Quit) { break; } } else if (response == 250) { if (state == State.Ehlo || state == State.Helo) { state = State.Mail; } else if (state == State.Mail) { state = State.Rcpt; } else if (state == State.Rcpt) { state = State.Data; } else if (state == State.Send) { result = SmtpClientResult.Success;//���M���� state = State.Quit; } } else if (response == 354) { if (state == State.Data) { state = State.Send; } } else if (response / 100 == 5) { // �]����SMTP�F��K�v�Ƃ��Ȃ��ꍇ�AEHLO�Ɏ��s������HELO�ōĐڑ�����݂� //if (Mode == 1 && TryEhlo && SmtpAuthClient == NULL) { if (state == State.Ehlo) { state = State.Helo; //HELO��500�������ꍇ�̓G���[�����ɉ�� } else //���M���s //���M���s���̍Ō�̑���M�L�^ { LastLog.Add(sockTcp.LastLineSend); LastLog.Add(recvStr); result = SmtpClientResult.ErrorCode;//�G���[�R�[�h��M state = State.Quit; } } //SMTP�F�� var ret = smtpAuthClient.Set(recvStr); if (ret != null) { sockTcp.AsciiSend(ret); continue; } //******************************************************************** // ���(mode)���Ƃ̏��� //******************************************************************** if (state == State.Ehlo) { sockTcp.AsciiSend(string.Format("EHLO {0}", serverName)); } else if (state == State.Helo) { sockTcp.AsciiSend(string.Format("HELO {0}", serverName)); } else if (state == State.Mail) { //Ver5.0.0-a24 //sockTcp.AsciiSend(string.Format("MAIL From:{0}",from),OPERATE_CRLF.YES); sockTcp.AsciiSend(string.Format("MAIL From: <{0}>", from)); } else if (state == State.Rcpt) { //Ver5.0.0-a24 //sockTcp.AsciiSend(string.Format("RCPT To:{0}",to),OPERATE_CRLF.YES); sockTcp.AsciiSend(string.Format("RCPT To: <{0}>", to)); } else if (state == State.Data) { sockTcp.AsciiSend("DATA"); } else if (state == State.Send) { if (mail == null) { //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); LastLog.Add(recvStr); break; //�G���[���� } const int count = -1; //count ���M����{���̍s���i-1�̏ꍇ�͑S���j if (!mail.Send(sockTcp, count)) { //_logger.Set(LogKind.Error, null, 9000058, ex.Message); //mail.GetLastError()�𖢏��� break;//�G���[���� } sockTcp.AsciiSend("."); } else if (state == State.Quit) { sockTcp.AsciiSend("QUIT"); } } return(result); }
//接続単位の処理 override protected void OnSubThread(SockObj sockObj) { var client = (SockTcp)sockObj; SockTcp server = null; string _targetServer; int _targetPort; var clientBuf = new List <byte[]>(); _targetServer = (string)Conf.Get("targetServer"); _targetPort = (int)Conf.Get("targetPort"); if (_targetServer == "") { Logger.Set(LogKind.Error, client, 1, ""); goto end; } if (_targetPort == 0) { Logger.Set(LogKind.Error, client, 2, ""); goto end; } //*************************************************************** //前処理(接続先・ユーザの取得と特別なユーザの置換) //*************************************************************** { var keyWord = BeforeJob(client, clientBuf);//前処理 if (keyWord == null) { goto end; } //特別なユーザにヒットしているかどうかの確認 var oneSpecialUser = _specialUser.Search(keyWord); if (oneSpecialUser != null) //ヒットした場合 //置換 { _targetServer = oneSpecialUser.Server; //サーバ _targetPort = oneSpecialUser.Port; //ポート番号 for (int i = 0; i < clientBuf.Count; i++) { //string str = Inet.TrimCRLF(Encoding.ASCII.GetString(clientBuf[i])); var str = Encoding.ASCII.GetString(clientBuf[i]); if ((Protocol == MailProxyProtocol.Smtp && str.ToUpper().IndexOf("MAIL FROM:") == 0) || (Protocol == MailProxyProtocol.Pop3 && str.ToUpper().IndexOf("USER") == 0)) { str = Util.SwapStr(oneSpecialUser.Before, oneSpecialUser.After, str); clientBuf[i] = Encoding.ASCII.GetBytes(str); break; } } Logger.Set(LogKind.Normal, client, 3, string.Format("{0}->{1} {2}:{3}", oneSpecialUser.Before, oneSpecialUser.After, _targetServer, _targetPort)); } } //*************************************************************** // サーバとの接続 //*************************************************************** { var port = _targetPort; //var ipList = new List<Ip>{new Ip(_targetServer)}; //if (ipList[0].ToString() == "0.0.0.0") { // ipList = Kernel.DnsCache.Get(_targetServer); // if (ipList.Count == 0) { // Logger.Set(LogKind.Normal, client, 4, string.Format("{0}:{1}", _targetServer, _targetPort)); // goto end; // } //} var ipList = Kernel.GetIpList(_targetServer); if (ipList.Count == 0) { Logger.Set(LogKind.Normal, client, 4, string.Format("{0}:{1}", _targetServer, _targetPort)); goto end; } foreach (var ip in ipList) { server = Inet.Connect(Kernel, ip, port, Timeout, null); if (server != null) { break; } } if (server == null) { Logger.Set(LogKind.Normal, client, 5, string.Format("{0}:{1}", _targetServer, _targetPort)); goto end; } } Logger.Set(LogKind.Normal, client, 4, string.Format("connect {0}:{1}", _targetServer, _targetPort)); //*************************************************************** //後処理(接続先・ユーザの取得と特別なユーザの置換) //*************************************************************** foreach (var buf in clientBuf) { //byte[] serverBuf = server.LineRecv(timeout, OperateCrlf.No, ref life); server.LineRecv(Timeout, this); //クライアントからの受信分を送信する //Ver5.8.4 //server.LineSend(buf); server.Send(buf); } //*************************************************************** // パイプ //*************************************************************** var tunnel = new Tunnel(Logger, (int)Conf.Get("idleTime"), Timeout); tunnel.Pipe(server, client, this); end: if (client != null) { client.Close(); } if (server != null) { server.Close(); } }
//�f�[�^�擾�i����f�[�^�́A�����������j public bool Recv(Logger logger, SockTcp tcpObj, int timeout, ILife iLife) { var buf = tcpObj.LineRecv(timeout, iLife); if (buf == null) { return(false); } buf = Inet.TrimCrlf(buf); _urlEncoding = MLang.GetEncoding(buf);//URL�G���R�[�h�̌`����ۑ����� //Ver5.9.8 if (_urlEncoding == null) { var sb = new StringBuilder(); for (int i = 0; i < buf.Length; i++) { sb.Append(String.Format("0x{0:X},", buf[i])); } logger.Set(LogKind.Error, tcpObj, 9999, String.Format("_urlEncoding==null buf.Length={0} buf={1}", buf.Length, sb.ToString())); //���̂܂ܗ�O�֓˓������� } var str = _urlEncoding.GetString(buf); // ���\�b�h�EURI�E�o�[�W�����ɕ��� //"GET http://hostname:port@user:pass/path/filename.ext?param HTTP/1.1" RequestStr = str; //(�ŕ�������)�@"GET <=> http://hostname:port@user:pass/path/filename.ext?param HTTP/1.1" var index = str.IndexOf(' '); if (index < 0) //Ver5.0.0-a8 { return(false); } //(�O��) "GET" var methodStr = str.Substring(0, index); foreach (HttpMethod m in Enum.GetValues(typeof(HttpMethod))) { if (methodStr.ToUpper() == m.ToString().ToUpper()) { HttpMethod = m; break; } } if (HttpMethod == HttpMethod.Unknown) { logger.Set(LogKind.Secure, tcpObj, 1, string.Format("{0}", RequestStr));//�T�|�[�g�O�̃��\�b�h�ł��i������p���ł��܂���j return(false); } if (HttpMethod == HttpMethod.Connect) { Protocol = ProxyProtocol.Ssl; Port = 443;//�f�t�H���g�̃|�[�g�ԍ���443�ɂȂ� } //(�㔼) "http://*****:*****@user:pass/path/filename.ext?param HTTP/1.1" str = str.Substring(index + 1); //(�ŕ�������)�@"http://*****:*****@user:pass/path/filename.ext?param <=> HTTP/1.1" index = str.IndexOf(' '); if (index < 0) //Ver5.0.0-a8 { return(false); } //(�㔼) "HTTP/1.1" HttpVer = str.Substring(index + 1); if (HttpVer != "HTTP/0.9" && HttpVer != "HTTP/1.0" && HttpVer != "HTTP/1.1") { logger.Set(LogKind.Secure, tcpObj, 2, RequestStr);//�T�|�[�g�O�̃o�[�W�����ł��i������p���ł��܂���j return(false); } //(�O��) "http://*****:*****@user:pass/path/filename.ext?param" str = str.Substring(0, index); if (Protocol == ProxyProtocol.Unknown) //�v���g�R���擾 //("://"�ŕ�������)�@"http <=> hostname:port@user:pass/path/filename.ext?param <=> HTTP/1.1" { index = str.IndexOf("://"); if (index < 0) //Ver5.0.0-a8 { return(false); } //(�O��) "http" var protocolStr = str.Substring(0, index); if (protocolStr.ToLower() == "ftp") { Protocol = ProxyProtocol.Ftp; //�v���g�R����FTP�ɏC�� Port = 21; //FTP�ڑ��̃f�t�H���g�̃|�[�g�ԍ���21�ɂȂ� } else if (protocolStr.ToLower() != "http") { //Ver5.6.7 //Msg.Show(MsgKind.Error,"�v�G���[�@Request.Recv()"); //�G���[�\����|�b�v�A�b�v���烍�O�ɕύX logger.Set(LogKind.Error, tcpObj, 29, string.Format("protocolStr={0}", protocolStr)); return(false); } else { Protocol = ProxyProtocol.Http; } //(�㔼) "hostname:port@user:pass/path/filename.ext?param" str = str.Substring(index + 3); } //(�ŏ���"/"�ŕ�������)�@"hostname:port@user:pass <=> /path/filename.ext?param" index = str.IndexOf('/'); HostName = str; if (0 <= index) { //(�O��) ""hostname:port@user:pass" HostName = str.Substring(0, index); //(�㔼) "/path/filename.ext?param" str = str.Substring(index); } else { // GET http://hostname HTTP/1.0 �̂悤�ɁA���[�g�f�B���N�g�����w�肳��Ă��Ȃ��ꍇ�̑Ώ� str = "/"; } //�z�X�g�������Ƀ��[�U���F�p�X���[�h�������Ă���ꍇ�̏��� index = HostName.IndexOf("@"); if (0 <= index) { var userpass = HostName.Substring(0, index); //���[�U���F�p�X���[�h��j������ HostName = HostName.Substring(index + 1); var i = userpass.IndexOf(':'); if (i == -1) { User = userpass; } else { User = userpass.Substring(0, i); Pass = userpass.Substring(i + 1); } } //Ver5.1.2 IPv6�A�h���X�\�L�̃z�X�g���ɑΉ� var tmp = HostName.Split(new[] { '[', ']' }); if (tmp.Length == 3) //IPv6�A�h���X�\�L�ł���Ɣ��f���� { HostName = string.Format("[{0}]", tmp[1]); index = tmp[2].IndexOf(":"); if (0 <= index) { var s = tmp[2].Substring(index + 1); Port = Convert.ToInt32(s); } } else { //�z�X�g�������Ƀ|�[�g�ԍ��������Ă���ꍇ�̏��� index = HostName.IndexOf(":"); if (0 <= index) { var s = HostName.Substring(index + 1); Port = Convert.ToInt32(s); HostName = HostName.Substring(0, index); } } Uri = str; //CGI���� if (-1 != Uri.LastIndexOf('?')) { Cgi = true; } //�g���q�擾 if (!Cgi) { index = Uri.LastIndexOf('/'); if (index != -1) { str = Uri.Substring(index + 1); } index = str.LastIndexOf('.'); if (index != -1) { Ext = str.Substring(index + 1); } } return(true); }