public LogTemporary(LogKind logKind, SockObj sockObj, int messageNo, String detailInfomation) { LogKind = logKind; SockObj = sockObj; MessageNo = messageNo; DetailInfomation = detailInfomation; }
//�ڑ��P�ʂ̏��� protected override void OnSubThread(SockObj sockObj) { if (_protocolKind == ProtocolKind.Tcp) { TcpTunnel((SockTcp)sockObj); } else { UdpTunnel((SockUdp)sockObj); } }
//接続単位の処理 protected override void OnSubThread(SockObj sockObj) { var sockUdp = (SockUdp)sockObj; //作業フォルダの確認 if (_workDir == "") { Logger.Set(LogKind.Error,null,5,""); goto end; } if (!Directory.Exists(_workDir)) { Logger.Set(LogKind.Error,null,6,string.Format("workDir = {0}",_workDir)); goto end; } Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US"); Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); var offset = 0; var opCode = Opcode.Unknown; var fileName = ""; var tftpMode = TftpMode.Netascii; if (!GetOpCode(sockUdp,ref opCode,ref offset))//オペコードの取得 goto end; if (opCode != Opcode.Wrq && opCode != Opcode.Rrq) { //クライアントからのリクエストでWRQ及びRRQ以外はエラーとして受け付けない goto end; } if (!GetFileName(sockUdp,ref fileName,ref offset))//ファイル名の取得 goto end; if (!GetMode(sockUdp,ref tftpMode,ref offset))//モードの取得 goto end; var path = string.Format("{0}\\{1}",_workDir,fileName); //リクエスト元に対するソケットを新規に作成する var ip = sockUdp.RemoteIp; var port = sockUdp.RemoteAddress.Port; var childObj = new SockUdp(Kernel,ip,port,null,new byte[0]); if (opCode == Opcode.Wrq) {//アップロード処理 if (!UpLoad(childObj,path)) { //エラー } } else if (opCode == Opcode.Rrq) {//ダウンロード処理 if (!DownLoad(childObj, path)){ goto end; } } end: if (sockUdp != null) sockUdp.Close(); }
protected override void OnSubThread(SockObj sockObj) { for (var i = 3; i >= 0 && IsLife(); i--){ if (sockObj.SockState != Bjd.sock.SockState.Connect){ //TestUtil.prompt(String.format("接続中...sockAccept.getSockState!=Connect")); break; } //TestUtil.prompt(String.format("接続中...あと%d回待機", i)); Thread.Sleep(1000); } }
//接続単位の処理 protected override void OnSubThread(SockObj sockObj) { //UDPサーバの場合は、UdpObjで受ける var sockTcp = (SockTcp)sockObj; //オプションから「sampleText」を取得する //var sampleText = (string)OneOption.GetValue("sampleText"); //1行受信 var str = sockTcp.AsciiRecv(30,this);//this.lifeをそのまま渡す //1行送信 sockTcp.AsciiSend(str); //このメソッドを抜けると切断される }
//接続単位の処理 protected override void OnSubThread(SockObj sockObj) { var sockUdp = (SockUdp)sockObj; //受信データの解析 var reception = new Reception(sockUdp.RecvBuf); //スタートラインの形式に問題がある if (reception.StartLine.ReceptionKind == ReceptionKind.Unknown) { //Logger return; } //未対応のSIPバージョン if (reception.StartLine.SipVer.No != 2.0) { //Logger return; } //リクエストの処理 if (reception.StartLine.ReceptionKind == ReceptionKind.Request) { //Logger(詳細) リクエスト受信をプリント switch (reception.StartLine.SipMethod) { case SipMethod.Register: var jobRegister = new JobRegister(_user); break; case SipMethod.Invite: break; } if (reception.StartLine.SipMethod == SipMethod.Invite) { var oneCall = new OneCall(); //oneCall.Invite(lines); } } else{//ステータスの処理 //Logger(詳細) ステータス受信をプリント } //このメソッドを抜けると切断される }
//Ver5.3.2 public void Exception(Exception ex, SockObj sockObj, int messageNo) { Set(LogKind.Error, sockObj, messageNo, ex.Message); string[] tmp = ex.StackTrace.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (string s in tmp) { var lines = new List<string>(); var l = Util.SwapStr("\r\n", "", s); while (true) { if (l.Length < 80) { lines.Add(l); break; } lines.Add(l.Substring(0, 80)); l = l.Substring(80); } for (int i = 0; i < lines.Count; i++) { if (i == 0) { Set(LogKind.Error, sockObj, messageNo, lines[i]); } else { Set(LogKind.Error, sockObj, messageNo, " -" + lines[i]); } } } }
//接続単位の処理 protected override 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; //特別なユーザにヒットしているかどうかの確認 OneSpecialUser oneSpecialUser = _specialUser.Search(keyWord); if(oneSpecialUser != null) {//ヒットした場合 //置換 _targetServer = oneSpecialUser.Server;//サーバ _targetPort = oneSpecialUser.Port;//ポート番号 for(var i = 0;i < clientBuf.Count;i++) { //string str = Inet.TrimCRLF(Encoding.ASCII.GetString(clientBuf[i])); var str = Encoding.ASCII.GetString(clientBuf[i]); if((Protocol == MailProxyProtocolKind.Smtp && str.ToUpper().IndexOf("MAIL FROM:") == 0) || (Protocol == MailProxyProtocolKind.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; } if(null == ConnectJob(client,server,clientBuf))//接続後の処理 goto end; } Logger.Set(LogKind.Normal,client,4,string.Format("connect {0}:{1}",_targetServer,_targetPort)); //*************************************************************** //後処理(接続先・ユーザの取得と特別なユーザの置換) //*************************************************************** foreach(byte[] buf in clientBuf) { //Ver5.2.5 //byte[] serverBuf = server.LineRecv(timeout,OPERATE_CRLF.NO,ref life); //クライアントからの受信分を送信する server.LineSend(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(); }
public void Set(LogKind logKind,SockObj sockBase,int messageNo,string detailInfomation) { if (_logger != null){ _logger.Set(logKind, sockBase, messageNo, detailInfomation); } }
//�ڑ��P�ʂ̏��� protected override void OnSubThread(SockObj sockObj) { var sockUdp = (SockUdp)sockObj; if (sockUdp.RemoteAddress.Port != 68) {// �ڑ����|�[�g�ԍ���68�ȊO�́ADHCP�p�P�b�g�ł͂Ȃ��̂Ŕj������ return; } //�p�P�b�g�̓Ǎ�(��M�p�P�b�grp) var rp = new PacketDhcp(); if (!rp.Read(sockUdp.RecvBuf)) return; //�f�[�^��߂Ɏ��s�����ꍇ�́A�����Ȃ� if (rp.Opcode != 1) return;//OpCode���u�v���v�Ŗ����ꍇ�́A�������� //���M���u���[�h�L���X�g�ɐݒ肷�� var ep = new IPEndPoint(IPAddress.Broadcast, 68); sockUdp.RemoteAddress = ep; //******************************************************** // MAC���� //******************************************************** if ((bool)Conf.Get("useMacAcl")) {// MAC���䂪�L���ȏꍇ if (!_lease.SearchMac(rp.Mac)) { Logger.Set(LogKind.Secure,sockUdp,1,rp.Mac.ToString()); return; } } // �r������ (�f�[�^�x�[�X�����̂���) lock (_lockObj) { //�T�[�o�A�h���X Ip serverIp = rp.ServerIp; if (serverIp.AddrV4 == 0) { serverIp = new Ip(_serverAddress); } //���N�G�X�g�A�h���X Ip requestIp = rp.RequestIp; //this.Logger.Set(LogKind.Detail,sockUdp,3,string.Format("{0} {1} {2}",rp.Mac,requestIp.ToString(),rp.Type.ToString())); Log(sockUdp, 3, rp.Mac, requestIp, rp.Type); if (rp.Type == DhcpType.Discover) {// ���o requestIp = _lease.Discover(requestIp, rp.Id, rp.Mac); if(requestIp!=null){ // OFFER���M var sp = new PacketDhcp(rp.Id,requestIp,serverIp,rp.Mac,DhcpType.Offer,_leaseTime,_maskIp,_gwIp,_dnsIp0,_dnsIp1,_wpadUrl); Send(sockUdp,sp); } } else if (rp.Type == DhcpType.Request) {// �v�� requestIp = _lease.Request(requestIp, rp.Id, rp.Mac); if (requestIp != null) { if (serverIp.ToString() == _serverAddress) {// ���T�[�o���� // ACK���M var sp = new PacketDhcp(rp.Id,requestIp,serverIp,rp.Mac,DhcpType.Ack,_leaseTime,_maskIp,_gwIp,_dnsIp0,_dnsIp1,_wpadUrl); Send(sockUdp,sp); //this.Logger.Set(LogKind.Normal,sockUdp,5,string.Format("{0} {1} {2}",rp.Mac,requestIp.ToString(),rp.Type.ToString())); Log(sockUdp, 5, rp.Mac, requestIp, rp.Type); } else { _lease.Release(rp.Mac);//���������� } } else { // NACK���M var sp = new PacketDhcp(rp.Id,requestIp,serverIp,rp.Mac,DhcpType.Nak,_leaseTime,_maskIp,_gwIp,_dnsIp0,_dnsIp1,_wpadUrl); Send(sockUdp,sp); } } else if (rp.Type == DhcpType.Release) {// �J�� requestIp = _lease.Release(rp.Mac);//�J�� if(requestIp!=null) //this.Logger.Set(LogKind.Normal,sockUdp,6,string.Format("{0} {1} {2}",rp.Mac,requestIp.ToString(),rp.Type.ToString())); Log(sockUdp, 6, rp.Mac, requestIp, rp.Type); } else if (rp.Type == DhcpType.Infrm) {// ��� // ACK���M //Send(sockUdp,sp); } }// �r������ }
protected override void OnSubThread(SockObj sockObj) { //サーバ終了までキープする while (IsLife()){ Thread.Sleep(100); } }
protected override void OnSubThread(SockObj sockObj) { var sockUdp = (SockUdp) sockObj; //セッションごとの情報 //Session session = new Session((SockTcp) sockObj); PacketDns rp; //受信パケット try { //パケットの読込(受信パケットrp) var buf = sockUdp.RecvBuf; if (buf.Length < 12) { return; } rp = new PacketDns(sockUdp.RecvBuf); } catch (IOException) { //データ解釈に失敗した場合は、処理なし Logger.Set(LogKind.Secure, sockUdp, 4, ""); //不正パケットの可能性あり return; } //リクエストのドメイン名を取得する var domainName = InitRequestDomain(rp.GetRequestName(), rp.GetDnsType()); //リクエスト解釈完了 Logger.Set(LogKind.Normal, sockUdp, 8, string.Format("{0} {1} domain={2}", rp.GetDnsType(), rp.GetRequestName(), domainName)); //Query var aa = false; // ドメインオーソリティ(管理ドメインかそうでないか) const bool ra = true; //再帰可能 var targetCache = _rootCache; //デフォルトはルートキャッシュ if (rp.GetDnsType() == DnsType.Ptr) { if (rp.GetRequestName().ToUpper() == "1.0.0.127.IN-ADDR.ARPA." || rp.GetRequestName().ToUpper() == "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA." || rp.GetRequestName().ToUpper() == "LOCALHOST.") { //キャッシュはデフォルトであるルートキャッシュが使用される aa = true; Logger.Set(LogKind.Detail, sockUdp, 9, ""); //"request to a domain under auto (localhost)" } else { foreach (var cache in _cacheList) { if (cache.Find(rp.GetRequestName(), DnsType.Ptr)) { targetCache = cache; aa = true; Logger.Set(LogKind.Detail, sockUdp, 10, string.Format("Resource={0}", targetCache.GetDomainName())); //"request to a domain under management" break; } } } } else { //A if (rp.GetRequestName().ToUpper() == "LOCALHOST.") { //キャッシュはデフォルトであるルートキャッシュが使用される aa = true; Logger.Set(LogKind.Detail, sockUdp, 11, ""); //"request to a domain under auto (localhost)" } else { foreach (var cache in _cacheList) { if (cache.GetDomainName().ToUpper() == domainName.ToUpper()) { //大文字で比較される targetCache = cache; aa = true; Logger.Set(LogKind.Detail, sockUdp, 12, string.Format("Resource={0}", domainName)); //"request to a domain under management" break; } } } } //管理するドメインでなく、かつ 再帰要求が無い場合は、処理を終わる if (!(aa) && !(rp.GetRd())) { return; } //aa ドメインオーソリティ //rs 再帰可能 //rd 再起要求あり // (A)「ヘッダ」作成 const bool qr = true; //応答 //******************************************************** //パケットの生成(送信パケットsp) //******************************************************** //Ver6.1.0 again: var sp = new PacketDns(rp.GetId(), qr, aa, rp.GetRd(), ra); // (B)「質問セクション」の追加 AppendRr(sp, RrKind.QD, new RrQuery(rp.GetRequestName(), rp.GetDnsType())); //質問フィールドの追加 if (!aa) { //ドメインオーソリティ(権威サーバ)で無い場合 //ルートキャッシュにターゲットのデータが蓄積されるまで、再帰的に検索する try { SearchLoop(rp.GetRequestName(), rp.GetDnsType(), sockUdp.RemoteIp); } catch (IOException) { // ここはどうやって扱えばいいか??? //e.printStackTrace(); } } // (B)「回答セクション」作成 var ansList = targetCache.GetList(rp.GetRequestName(), rp.GetDnsType()); //Ver6.1.0 (リソースに無い場合は、再帰検索に入る) if (ansList.Count == 0 && aa && !targetCache.Authority) { targetCache = _rootCache; //ルートキャッシュに戻す aa = false; goto again; } //Ver5.9.4 Aレコードを検索してCNAMEしか帰らない場合の処理 // if (ansList.Count == 0 && rp.GetDnsType() == DnsType.A){ // foreach (RrCname o in targetCache.GetList(rp.GetRequestName(), DnsType.Cname)) { // ansList.Add(o); // var list = targetCache.GetList(o.CName, DnsType.A); // foreach (var l in list){ // ansList.Add(l); // } // } // } Logger.Set(LogKind.Detail, sockUdp, 13, string.Format("{0} ansList.Count={1}", rp.GetDnsType(), ansList.Count)); //"Create Response (AN)" if (0 < ansList.Count) { //検索でヒットした場合 foreach (var oneRr in ansList) { AppendRr(sp, RrKind.AN, DnsUtil.CreateRr(rp.GetRequestName(), rp.GetDnsType(), oneRr.Ttl, oneRr.Data)); if (rp.GetDnsType() == DnsType.Mx || rp.GetDnsType() == DnsType.Cname || rp.GetDnsType() == DnsType.Ns) { var targetName = ""; if (rp.GetDnsType() == DnsType.Mx) { targetName = ((RrMx) oneRr).MailExchangeHost; } else if (rp.GetDnsType() == DnsType.Ns) { targetName = ((RrNs) oneRr).NsName; } else if (rp.GetDnsType() == DnsType.Cname) { targetName = ((RrCname) oneRr).CName; } else { Util.RuntimeException("not implement [Server.onSubThread()]"); } //追加情報が必要な場合 (Aレコード)をパケットに追加する var rr = targetCache.GetList(targetName, DnsType.A); foreach (OneRr r in rr) { AppendRr(sp, RrKind.AR, new RrA(targetName, r.Ttl, r.Data)); } //追加情報が必要な場合 (AAAAレコード)をパケットに追加する rr = targetCache.GetList(targetName, DnsType.Aaaa); foreach (var r in rr) { AppendRr(sp, RrKind.AR, new RrAaaa(targetName, r.Ttl, r.Data)); } } } } else { //検索でヒットしない場合 if (rp.GetDnsType() == DnsType.A) { // CNAMEに定義されていないかどうかを確認する //Ver5.9.4 再帰的にCNAMEを検索する //var cnameList = targetCache.GetList(rp.GetRequestName(), DnsType.Cname); var cnameList = new List<OneRr>(); cnameList = GetAllCname(targetCache, rp.GetRequestName(), cnameList); foreach (var o in cnameList) { Logger.Set(LogKind.Detail, sockUdp, 16, o.ToString()); //"Append RR" AppendRr(sp, RrKind.AN, o); var cname = ((RrCname) o).CName; var aList = targetCache.GetList(cname, DnsType.A); foreach (var a in aList) { // Logger.Set(LogKind.Detail, sockUdp, 16, o.ToString()); //"Append RR" // AppendRr(sp, RrKind.AN, o); Logger.Set(LogKind.Detail, sockUdp, 16, a.ToString()); //"Append RR" AppendRr(sp, RrKind.AN, a); } } } } if (rp.GetDnsType() == DnsType.A || rp.GetDnsType() == DnsType.Aaaa || rp.GetDnsType() == DnsType.Soa || rp.GetDnsType() == DnsType.Cname) { // (C)「権威セクション」「追加情報セクション」作成 var nsList = targetCache.GetList(domainName, DnsType.Ns); Logger.Set(LogKind.Detail, sockUdp, 22, string.Format("{0} nsList.Count={1}", DnsType.Ns, nsList.Count)); // Create Response (AR) foreach (var o in nsList) { var ns = (RrNs) o; AppendRr(sp, RrKind.NS, new RrNs(ns.Name, ns.Ttl, ns.Data)); if (domainName.ToUpper() != "LOCALHOST.") { //localhost検索の場合は、追加情報はない //「追加情報」 var addList = targetCache.GetList(ns.NsName, DnsType.A); foreach (OneRr rr in addList) { AppendRr(sp, RrKind.AR, new RrA(ns.NsName, rr.Ttl, rr.Data)); } addList = targetCache.GetList(ns.NsName, DnsType.Aaaa); foreach (OneRr rr in addList) { AppendRr(sp, RrKind.AR, new RrAaaa(ns.NsName, rr.Ttl, rr.Data)); } } } } sockUdp.Send(sp.GetBytes()); //送信 //sockUdp.Close();UDPソケット(sockUdp)はクローンなのでクローズしても、処理されない※Close()を呼び出しても問題はない sockUdp.Close(); }
//接続単位の処理 protected override void OnSubThread(SockObj sockObj) { Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); var sockTcp = (SockTcp)sockObj; var remoteIp = sockTcp.RemoteIp; //opBase 及び loggerはバーチャルホストで変更されるので、 //このポインタを初期化に使用できない bool keepAlive = true;//レスポンスが終了したとき接続を切断しないで継続する //1回目の通信でバーチャルホストの検索を実施する var checkVirtual = true; var request = new Request(Logger,sockTcp);//リクエストライン処理クラス //受信ヘッダ var recvHeader = new Header(); //Ver5.1.x string urlStr = null;//http://example.com //接続が継続している間は、このループの中にいる(継続か否かをkeepAliveで保持する) //「continue」は、次のリクエストを待つ 「break」は、接続を切断する事を意味する WebStream inputStream = null; var outputStream = new WebStream(-1); while (keepAlive && IsLife()) { int responseCode; //*************************************************************** // ドキュメント生成クラスの初期化 //*************************************************************** var contentType = new ContentType(Conf); var document = new Document(Kernel, Logger, Conf, sockTcp, contentType); var authrization = new Authorization(Conf, Logger); var authName = ""; //*************************************************************** //データ取得 //*************************************************************** //リクエスト取得 //ここのタイムアウト値は、大きすぎるとブラウザの切断を取得できないでブロックしてしまう var requestStr = sockTcp.AsciiRecv(Timeout, this); if (requestStr == null) break; //\r\nの削除 requestStr = Inet.TrimCrlf(requestStr); //Ver5.8.8 リクエストの解釈に失敗した場合に、処理を中断する //request.Init(requestStr); if (!request.Init(requestStr)){ break; } //ヘッダ取得(内部データは初期化される) if (!recvHeader.Recv(sockTcp,(int)Conf.Get("timeOut"),this)) break; { //Ver5.1.x var hostStr = recvHeader.GetVal("host"); urlStr = hostStr==null ? null : string.Format("{0}://{1}",(ssl != null)?"https":"http",hostStr); } //入力取得(POST及びPUTの場合) var contentLengthStr = recvHeader.GetVal("Content-Length"); if(contentLengthStr != null) { try{ //max,lenはともにlong var max = Convert.ToInt64(contentLengthStr); if(max!=0){//送信データあり inputStream = new WebStream((256000<max)?-1:(int)max); var errorCount = 0; while(inputStream.Length<max && IsLife()){ var len = max - inputStream.Length; if (len > 51200000) { len = 51200000; } var b = sockTcp.Recv((int)len, (int)Conf.Get("timeOut"),this); if (!inputStream.Add(b)) { errorCount++;//エラー蓄積 Logger.Set(LogKind.Error, null, 41, string.Format("content-Length={0} Recv={1}", max, inputStream.Length)); } else { errorCount = 0;//初期化 } Logger.Set(LogKind.Detail, null,38, string.Format("Content-Length={0} {1}bytes Received.", max, inputStream.Length)); if (errorCount > 5){//5回連続して受信が無かった場合、サーバエラー responseCode = 500; goto SEND;//サーバエラー } Thread.Sleep(10); } Logger.Set(LogKind.Detail, null, 39, string.Format("Content-Length={0} {1}bytes", max, inputStream.Length)); } }catch(Exception ex){ Logger.Set(LogKind.Error, null, 40, ex.Message); } } // /によるパラメータ渡しに対応 //for (int i = 0;i < Option->CgiExt->Count;i++) { // wsprintf(TmpBuf,".%s/",Option->CgiExt->Strings[i]); // strupr(TmpBuf); // strcpy(Buf,Headers->Uri); // strupr(Buf); // if (NULL != (p = strstr(Buf,TmpBuf))) { // i = p - Buf; // i += strlen(TmpBuf) - 1; // p = &Headers->Uri[i]; // *p = '\0'; // p = &Headers->UriNoConversion[i]; // *p = '\0'; // wsprintf(TmpBuf,"/%s",p + 1); // Headers->PathInfo = new char[strlen(TmpBuf) + 1]; // strcpy(Headers->PathInfo,TmpBuf); // break; // } //} //*************************************************************** //バーチャルホストの検索を実施し、opBase、logger及び webDavDb を置き換える //*************************************************************** if (checkVirtual) {//初回のみ ReplaceVirtualHost(recvHeader.GetVal("host"),sockTcp.LocalAddress.Address,sockTcp.LocalAddress.Port); checkVirtual = false; } //*************************************************************** //接続を継続するかどうかの判断 keepAliveの初期化 //*************************************************************** if (ssl != null) { keepAlive = false;//SSL通信では、1回づつコネクションが必要 }else{ if (request.Ver == "HTTP/1.1") {//HTTP1.1はデフォルトで keepAlive=true keepAlive = true; } else { // HTTP/1.1以外の場合、継続接続は、Connection: Keep-Aliveの有無に従う keepAlive = recvHeader.GetVal("Connection") == "Keep-Alive"; } } //*************************************************************** // ドキュメント生成クラスの初期化 //*************************************************************** //var contentType = new ContentType(OneOption); //var document = new Document(kernel,Logger,OneOption,sockTcp,contentType); //*************************************************************** // ログ //*************************************************************** Logger.Set(LogKind.Normal, sockTcp, ssl != null ? 23 : 24, request.LogStr); //*************************************************************** // 認証 //*************************************************************** //var authrization = new Authorization(OneOption,Logger); //string authName = ""; if (!authrization.Check(request.Uri, recvHeader.GetVal("authorization"), ref authName)) { responseCode = 401; keepAlive = false;//切断 goto SEND; } //*************************************************************** // 不正なURIに対するエラー処理 //*************************************************************** //URIを点検して不正な場合はエラーコードを返す responseCode = CheckUri(sockTcp, request, recvHeader); if (responseCode != 200) { keepAlive = false;//切断 goto SEND; } //*************************************************************** //ターゲットオブジェクトの初期化 //*************************************************************** var target = new Target(Conf,Logger); if (target.DocumentRoot == null) { Logger.Set(LogKind.Error,sockTcp,14,string.Format("documentRoot={0}",Conf.Get("documentRoot")));//ドキュメントルートで指定されたフォルダが存在しません(処理を継続できません) break;//ドキュメントルートが無効な場合は、処理を継続できない } target.InitFromUri(request.Uri); //*************************************************************** // 送信ヘッダの追加 //*************************************************************** // 特別拡張 BlackJumboDog経由のリクエストの場合 送信ヘッダにRemoteHostを追加する if ((bool)Conf.Get("useExpansion")) { if (recvHeader.GetVal("Host") != null) { document.AddHeader("RemoteHost",sockTcp.RemoteAddress.Address.ToString()); } } //受信ヘッダに「PathInfo:」が設定されている場合、送信ヘッダに「PathTranslated」を追加する var pathInfo = recvHeader.GetVal("PathInfo"); if (pathInfo != null) { pathInfo = target.DocumentRoot + pathInfo; document.AddHeader("PathTranslated",Util.SwapChar('/','\\',pathInfo)); } //*************************************************************** //メソッドに応じた処理 OPTIONS 対応 Ver5.1.x //*************************************************************** if(WebDav.IsTarget(request.Method)){ var webDav = new WebDav(Logger, _webDavDb, target, document, urlStr, recvHeader.GetVal("Depth"), contentType,(bool)Conf.Get("useEtag")); var inputBuf = new byte[0]; if(inputStream!=null){ inputBuf = inputStream.GetBytes(); } switch(request.Method) { case HttpMethod.Options: responseCode = webDav.Option(); break; case HttpMethod.Delete: responseCode = webDav.Delete(); break; case HttpMethod.Put: responseCode = webDav.Put(inputBuf); break; case HttpMethod.Proppatch: responseCode = webDav.PropPatch(inputBuf); break; case HttpMethod.Propfind: responseCode = webDav.PropFind(); break; case HttpMethod.Mkcol: responseCode = webDav.MkCol(); break; case HttpMethod.Copy: case HttpMethod.Move: responseCode = 405; //Destnationで指定されたファイルは書き込み許可されているか? var dstTarget = new Target(Conf,Logger); string destinationStr = recvHeader.GetVal("Destination"); if(destinationStr != null) { if(destinationStr.IndexOf("://") == -1) { destinationStr = urlStr + destinationStr; } var uri = new Uri(destinationStr); dstTarget.InitFromUri(uri.LocalPath); if(dstTarget.WebDavKind == WebDavKind.Write) { var overwrite = false; var overwriteStr = recvHeader.GetVal("Overwrite"); if(overwriteStr != null) { if(overwriteStr == "F") { overwrite = true; } } responseCode = webDav.MoveCopy(dstTarget,overwrite,request.Method); document.AddHeader("Location",destinationStr); } } break; } //WebDAVに対するリクエストは、ここで処理完了 goto SEND; } //以下 label SENDまでの間は、GET/POSTに関する処理 //*************************************************************** //ターゲットの種類に応じた処理 //*************************************************************** if (target.TargetKind == TargetKind.Non) { //見つからない場合 responseCode = 404; goto SEND; } if (target.TargetKind == TargetKind.Move) { //ターゲットはディレクトリの場合 responseCode = 301; goto SEND; } if (target.TargetKind == TargetKind.Dir) { //ディレクトリ一覧表示の場合 //インデックスドキュメントを生成する if (!document.CreateFromIndex(request, target.FullPath)) break; goto SEND; } //*************************************************************** // 隠し属性のファイルへのアクセス制御 //*************************************************************** if (!(bool)Conf.Get("useHidden")) { if ((target.Attr & FileAttributes.Hidden) == FileAttributes.Hidden) { //エラーキュメントを生成する responseCode = 404; keepAlive = false;//切断 goto SEND; } } if (target.TargetKind == TargetKind.Cgi || target.TargetKind == TargetKind.Ssi) { keepAlive = false;//デフォルトで切断 //環境変数作成 var env = new Env(Kernel,Conf,request, recvHeader,sockTcp, target.FullPath); // 詳細ログ Logger.Set(LogKind.Detail,sockTcp,18,string.Format("{0} {1}",target.CgiCmd,Path.GetFileName(target.FullPath))); if (target.TargetKind == TargetKind.Cgi) { var cgi = new Cgi(); var cgiTimeout = (int)Conf.Get("cgiTimeout"); if (!cgi.Exec(target,request.Param,env,inputStream,out outputStream,cgiTimeout)) { // エラー出力 var errStr = Encoding.ASCII.GetString(outputStream.GetBytes()); Logger.Set(LogKind.Error,sockTcp,16,errStr); responseCode = 500; goto SEND; } //*************************************************** // NPH (Non-Parsed Header CGI)スクリプト nph-で始まる場合、サーバ処理(レスポンスコードやヘッダの追加)を経由しない //*************************************************** if (Path.GetFileName(target.FullPath).IndexOf("nph-") == 0) { sockTcp.SendUseEncode(outputStream.GetBytes());//CGI出力をそのまま送信する break; } // CGIで得られた出力から、本体とヘッダを分離する if(!document.CreateFromCgi(outputStream.GetBytes())) break; // cgi出力で、Location:が含まれる場合、レスポンスコードを302にする if (document.SearchLocation())//Location:ヘッダを含むかどうか responseCode = 302; goto SEND; } //SSI var ssi = new Ssi(Kernel, Logger,Conf, sockTcp, request, recvHeader); if (!ssi.Exec(target,env,outputStream)) { // エラー出力 Logger.Set(LogKind.Error,sockTcp,22,MLang.GetString(outputStream.GetBytes())); responseCode = 500; goto SEND; } document.CreateFromSsi(outputStream.GetBytes(),target.FullPath); goto SEND; } //以下は、通常ファイルの処理 TARGET_KIND.FILE //******************************************************************** //Modified処理 //******************************************************************** if (recvHeader.GetVal("If_Modified_Since") != null) { var dt = Util.Str2Time(recvHeader.GetVal("If-Modified-Since")); if (target.FileInfo.LastWriteTimeUtc.Ticks / 10000000 <= dt.Ticks / 10000000) { responseCode = 304; goto SEND; } } if (recvHeader.GetVal("If_Unmodified_Since") != null) { var dt = Util.Str2Time(recvHeader.GetVal("If_Unmodified_Since")); if (target.FileInfo.LastWriteTimeUtc.Ticks / 10000000 > dt.Ticks / 10000000) { responseCode = 412; goto SEND; } } document.AddHeader("Last-Modified",Util.UtcTime2Str(target.FileInfo.LastWriteTimeUtc)); //******************************************************************** //ETag処理 //******************************************************************** // (1) useEtagがtrueの場合は、送信時にETagを付加する // (2) If-None-Match 若しくはIf-Matchヘッダが指定されている場合は、排除対象かどうかの判断が必要になる if ((bool)Conf.Get("useEtag") || recvHeader.GetVal("If-Match") != null || recvHeader.GetVal("If-None-Match") != null) { //Ver5.1.5 //string etagStr = string.Format("\"{0:x}-{1:x}\"", target.FileInfo.Length, (target.FileInfo.LastWriteTimeUtc.Ticks / 10000000)); var etagStr = WebServerUtil.Etag(target.FileInfo); string str; if (null != (str = recvHeader.GetVal("If-Match"))) { if (str != "*" && str != etagStr) { responseCode = 412; goto SEND; } } if (null != (str = recvHeader.GetVal("If-None-Match"))) { if (str != "*" && str == etagStr) { responseCode = 304; goto SEND; } } if ((bool)Conf.Get("useEtag")) document.AddHeader("ETag",etagStr); } //******************************************************************** //Range処理 //******************************************************************** document.AddHeader("Accept-Range","bytes"); var rangeFrom = 0L;//デフォルトは最初から var rangeTo = target.FileInfo.Length;//デフォルトは最後まで(ファイルサイズ) if (recvHeader.GetVal("Range") != null) {//レンジ指定のあるリクエストの場合 var range = recvHeader.GetVal("Range"); //指定範囲を取得する(マルチ指定には未対応) if (range.IndexOf("bytes=") == 0) { range = range.Substring(6); var tmp = range.Split('-'); //Ver5.3.5 ApacheKiller対処 if (tmp.Length > 20) { Logger.Set(LogKind.Secure, sockTcp,9000054, string.Format("[ Apache Killer ]Range:{0}", range)); AutoDeny(false, remoteIp); responseCode = 503; keepAlive = false;//切断 goto SEND; } if(tmp.Length == 2) { //Ver5.3.6 のデバッグ用 //tmp[1] = "499"; if(tmp[0] != "") { if(tmp[1] != "") {// bytes=0-10 0~10の11バイト //Ver5.5.9 rangeFrom = Convert.ToInt64(tmp[0]); if (tmp[1] != "") { //Ver5.5.9 rangeTo = Convert.ToInt64(tmp[1]); if (target.FileInfo.Length <= rangeTo) { rangeTo = target.FileInfo.Length - 1; } else { document.SetRangeTo = true;//Ver5.4.0 } } } else {// bytes=3- 3~最後まで rangeTo = target.FileInfo.Length - 1; rangeFrom = Convert.ToInt64(tmp[0]); } } else { if(tmp[1] != "") {// bytes=-3 最後から3バイト var len = Convert.ToInt64(tmp[1]); rangeTo = target.FileInfo.Length - 1; rangeFrom = rangeTo-len+1; if(rangeFrom<0) rangeFrom=0; document.SetRangeTo = true;//Ver5.4.0 } } if(rangeFrom <= rangeTo) { //正常に範囲を取得できた場合、事後Rangeモードで動作する document.AddHeader("Content-Range",string.Format("bytes {0}-{1}/{2}",rangeFrom,rangeTo,target.FileInfo.Length)); responseCode = 206; } } } } //通常ファイルのドキュメント if (request.Method != HttpMethod.Head) { if (!document.CreateFromFile(target.FullPath,rangeFrom,rangeTo)) break; } SEND: //レスポンスコードが200以外の場合は、ドキュメント(及び送信ヘッダ)をエラー用に変更する if(responseCode != 200 && responseCode != 302 && responseCode != 206 && responseCode != 207 && responseCode != 204 && responseCode != 201) { //ResponceCodeの応じてエラードキュメントを生成する if (!document.CreateFromErrorCode(request,responseCode)) break; if (responseCode == 301) {//ターゲットがファイルではなくディレクトの間違いの場合 if(urlStr != null) { var str = string.Format("{0}{1}/",urlStr,request.Uri); document.AddHeader("Location",Encoding.UTF8.GetBytes(str)); } } if (responseCode == 304 || responseCode == 301) {//304 or 301 の場合は、ヘッダのみになる document.Clear(); } else { if (responseCode == 401) { document.AddHeader("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", authName)); } } } //Ver5.6.2 request.Send()廃止 var responseStr = request.CreateResponse(responseCode); sockTcp.AsciiSend(responseStr);//レスポンス送信 Logger.Set(LogKind.Detail, sockTcp, 4, responseStr);//ログ document.Send(keepAlive,this);//ドキュメント本体送信 } if(inputStream!=null) inputStream.Dispose(); if (outputStream != null) outputStream.Dispose(); //end://このソケット接続の終了 if (sockTcp != null) { sockTcp.Close(); } }
protected override void OnSubThread(SockObj sockObj) { _sockTcp = (SockTcp)sockObj; //************************************************************* // �p�X���[�h�F�� //************************************************************* var password = (string)Conf.Get("password"); if (password == ""){ Logger.Set(LogKind.Normal,_sockTcp,5,""); }else{//�p�X���[�h�F���K�v�ȏꍇ var challengeStr = Inet.ChallengeStr(10);//�`�������W������̐��� RemoteData.Send(_sockTcp, RemoteDataKind.DatAuth, challengeStr); //�p�X���[�h�̉����҂� var success = false;//Ver5.0.0-b14 while (IsLife() && _sockTcp.SockState == Bjd.sock.SockState.Connect) { var o = RemoteData.Recv(_sockTcp,this); if(o!=null){ if (o.Kind == RemoteDataKind.CmdAuth) { //�n�b�V��������̍쐬�iMD5�j var md5Str = Inet.Md5Str(password + challengeStr); if(md5Str != o.Str) { Logger.Set(LogKind.Secure,_sockTcp,4,""); //DOS�� 3�b�Ԃ͎��̐ڑ���t���Ȃ� //for (int i = 0; i < 30 && life; i++) { // Thread.Sleep(100); //} //tcpObj.Close();//���̐ڑ��͔j������� //return; } else { success = true;//Ver5.0.0-b14 } break; } }else{ Thread.Sleep(500); } } //Ver5.0.0-b14 if(!success) { //�F�؎��s�i�p�X���[�h�L�����Z���E�p�X���[�h�Ⴂ�E�����ؒf�j //DOS�� 3�b�Ԃ͎��̐ڑ���t���Ȃ� for(var i = 0;i < 30 && IsLife();i++) { Thread.Sleep(100); } _sockTcp.Close();//���̐ڑ��͔j������� return; } } //************************************************************* // �F�؊��� //************************************************************* Logger.Set(LogKind.Normal,_sockTcp,1,string.Format("address={0}",_sockTcp.RemoteAddress.Address)); //�o�[�W����/���O�C�������̑��M RemoteData.Send(_sockTcp, RemoteDataKind.DatVer, Kernel.Ver.VerData()); //kernel.LocalAddress��Remote���Ő������� RemoteData.Send(_sockTcp, RemoteDataKind.DatLocaladdress, LocalAddress.GetInstance().RemoteStr()); //�I�v�V�����̑��M var optionFileName = string.Format("{0}\\Option.ini",Kernel.ProgDir()); string optionStr; using (var sr = new StreamReader(optionFileName, Encoding.GetEncoding("Shift_JIS"))) { optionStr = sr.ReadToEnd(); sr.Close(); } RemoteData.Send(_sockTcp, RemoteDataKind.DatOption, optionStr); Kernel.RemoteConnect = new Bjd.remote.RemoteConnect(_sockTcp);//�����[�g�N���C�A���g�ڑ��J�n Kernel.View.SetColor();//�E�C���h�F�̏����� while (IsLife() && _sockTcp.SockState == Bjd.sock.SockState.Connect) { var o = RemoteData.Recv(_sockTcp,this); if (o==null) continue; //�R�}���h�́A���ׂăL���[�Ɋi�[���� _queue.Enqueue(o); if (_queue.Count == 0) { GC.Collect(); Thread.Sleep(500); } else { Cmd(_queue.Dequeue()); } } Kernel.RemoteConnect = null;//�����[�g�N���C�A���g�ڑ��I�� Logger.Set(LogKind.Normal, _sockTcp, 2, string.Format("address={0}", _sockTcp.RemoteAddress.Address)); Kernel.View.SetColor();//�E�C���h�F�̏����� _sockTcp.Close(); }
//接続単位の処理 protected override void OnSubThread(SockObj sockObj) { var sockTcp = (SockTcp)sockObj; //WebApi関連 if (!Kernel.WebApi.ServiceSmtp) { if (sockTcp != null) sockTcp.Close(); return; } //グリーティングメッセージの表示 sockTcp.AsciiSend("220 " + Kernel.ChangeTag((string)Conf.Get("bannerMessage"))); var checkParam = new CheckParam((bool)Conf.Get("useNullFrom"), (bool)Conf.Get("useNullDomain")); var session = new Session(); SmtpAuth smtpAuth = null; var useEsmtp = (bool)Conf.Get("useEsmtp"); if (useEsmtp) { if (_smtpAuthRange.IsHit(sockTcp.RemoteIp)) { var usePlain = (bool)Conf.Get("useAuthPlain"); var useLogin = (bool)Conf.Get("useAuthLogin"); var useCramMd5 = (bool)Conf.Get("useAuthCramMD5"); smtpAuth = new SmtpAuth(_smtpAuthUserList, usePlain, useLogin, useCramMd5); } } //受信サイズ制限 var sizeLimit = (int)Conf.Get("sizeLimit"); //Ver5.0.0-b8 Frmo:偽造の拒否 var useCheckFrom = (bool)Conf.Get("useCheckFrom"); while (IsLife()) { Thread.Sleep(0); var cmd = recvCmd(sockTcp); if (cmd == null){ break;//切断された } if (cmd.Str == "") { Thread.Sleep(100);//受信待機中 continue; } var smtpCmd = new SmtpCmd(cmd); //WebApi関連 var responseSmtp = Kernel.WebApi.ResponseSmtp(cmd.CmdStr); if (responseSmtp != -1){ sockTcp.AsciiSend(string.Format("{0} WebAPI response", responseSmtp)); continue; } if (smtpCmd.Kind == SmtpCmdKind.Unknown) {//無効コマンド //SMTP認証 if (smtpAuth != null) { if (!smtpAuth.IsFinish) { var ret = smtpAuth.Job(smtpCmd.Str); if (ret != null) { sockTcp.AsciiSend(ret); continue; } } } sockTcp.AsciiSend(string.Format("500 command not understood: {0}", smtpCmd.Str)); //無効コマンドが10回続くと不正アクセスとして切断する session.UnknownCmdCounter++; if (session.UnknownCmdCounter > 10) { Logger.Set(LogKind.Secure, sockTcp, 54, string.Format("unknownCmdCount={0}", session.UnknownCmdCounter)); break; } continue; } session.UnknownCmdCounter = 0; //不正でない場合クリアする //QUIT・NOOP・RSETはいつでも受け付ける if (smtpCmd.Kind == SmtpCmdKind.Quit) { sockTcp.AsciiSend("221 closing connection"); break; } if (smtpCmd.Kind == SmtpCmdKind.Noop) { sockTcp.AsciiSend("250 OK"); continue; } if (smtpCmd.Kind == SmtpCmdKind.Rset) { session.Rest(); sockTcp.AsciiSend("250 Reset state"); continue; } //下記のコマンド以外は、SMTP認証の前には使用できない if (smtpCmd.Kind != SmtpCmdKind.Noop && smtpCmd.Kind != SmtpCmdKind.Helo && smtpCmd.Kind != SmtpCmdKind.Ehlo && smtpCmd.Kind != SmtpCmdKind.Rset) { if (smtpAuth != null) { if (!smtpAuth.IsFinish) { sockTcp.AsciiSend("530 Authentication required."); continue; } } } if (smtpCmd.Kind == SmtpCmdKind.Helo || smtpCmd.Kind == SmtpCmdKind.Ehlo) { if (session.Hello != null) {//HELO/EHLOは1回しか受け取らない sockTcp.AsciiSend(string.Format("503 {0} Duplicate HELO/EHLO", Kernel.ServerName)); continue; } if (smtpCmd.ParamList.Count < 1) { sockTcp.AsciiSend(string.Format("501 {0} requires domain address", smtpCmd.Kind.ToString().ToUpper())); continue; } session.Helo(smtpCmd.ParamList[0]); Logger.Set(LogKind.Normal, sockTcp, 1, string.Format("{0} {1} from {2}[{3}]", smtpCmd.Kind.ToString().ToUpper(), session.Hello, sockObj.RemoteHostname, sockTcp.RemoteAddress)); if (smtpCmd.Kind == SmtpCmdKind.Ehlo) { sockTcp.AsciiSend(string.Format("250-{0} Helo {1}[{2}], Pleased to meet you.", Kernel.ServerName, sockObj.RemoteHostname, sockObj.RemoteAddress)); sockTcp.AsciiSend("250-8BITMIME"); sockTcp.AsciiSend(string.Format("250-SIZE={0}", sizeLimit)); if (smtpAuth != null) { string ret = smtpAuth.EhloStr();//SMTP認証に関するhelp文字列の取得 if (ret != null) { sockTcp.AsciiSend(ret); } } sockTcp.AsciiSend("250 HELP"); } else { sockTcp.AsciiSend(string.Format("250 {0} Helo {1}[{2}], Pleased to meet you.", Kernel.ServerName, sockObj.RemoteHostname, sockObj.RemoteAddress)); } continue; } if (smtpCmd.Kind == SmtpCmdKind.Mail) { if (!checkParam.Mail(smtpCmd.ParamList)){ sockTcp.AsciiSend(checkParam.Message); continue; } session.Mail(new MailAddress(smtpCmd.ParamList[1]));//MAILコマンドを取得完了(""もあり得る) sockTcp.AsciiSend(string.Format("250 {0}... Sender ok", smtpCmd.ParamList[1])); continue; } if (smtpCmd.Kind == SmtpCmdKind.Rcpt) { if (session.From == null) {//RCPTの前にMAILコマンドが必要 sockTcp.AsciiSend("503 Need MAIL before RCPT"); continue; } if (!checkParam.Rcpt(smtpCmd.ParamList)) { sockTcp.AsciiSend(checkParam.Message); continue; } var mailAddress = new MailAddress(smtpCmd.ParamList[1]); if (mailAddress.Domain == "") {//ドメイン指定の無い場合は、自ドメイン宛と判断する mailAddress = new MailAddress(mailAddress.User, DomainList[0]); } //自ドメイン宛かどうかの確認 if (mailAddress.IsLocal(DomainList)) { //Ver5.0.0-b4 エリアスで指定したユーザ名の確認 if (!Alias.IsUser(mailAddress.User)) { //有効なユーザかどうかの確認 if (!Kernel.MailBox.IsUser(mailAddress.User)) { //Ver_Ml //有効なメーリングリスト名かどうかの確認 //********************************************************************** //Ver_Ml //********************************************************************** //#if ML_SERVER if(!_mlList.IsUser(mailAddress)){ this.Logger.Set(LogKind.Secure,sockTcp,6,mailAddress.User); sockTcp.AsciiSend(string.Format("550 {0}... User unknown",mailAddress.User)); continue; } //#else // Logger.Set(LogKind.Secure, sockTcp, 6, mailAddress.User); // sockTcp.AsciiSend(string.Format("550 {0}... User unknown", mailAddress.User)); // continue; //#endif //********************************************************************** } } } else {//中継(リレー)が許可されているかどうかのチェック if (!_popBeforeSmtp.Auth(sockObj.RemoteIp)) { //Allow及びDenyリストで中継(リレー)が許可されているかどうかのチェック if (!_relay.IsAllow(sockObj.RemoteIp)) { sockTcp.AsciiSend(string.Format("553 {0}... Relay operation rejected", mailAddress)); continue; } } } //メールアドレスをRCPTリストへ追加する session.Rcpt(mailAddress); sockTcp.AsciiSend(string.Format("250 {0}... Recipient ok", mailAddress)); continue; } if (smtpCmd.Kind == SmtpCmdKind.Data) { if (session.From == null) { sockTcp.AsciiSend("503 Need MAIL command"); continue; } if (session.To.Count == 0) { sockTcp.AsciiSend("503 Need RCPT (recipient)"); continue; } sockTcp.AsciiSend("354 Enter mail,end with \".\" on a line by ltself"); var data = new Data(sizeLimit); if(!data.Recv(sockTcp,20,Logger,this)){ Thread.Sleep(1000); break; } //以降は、メール受信完了の場合 if (useCheckFrom) {//Frmo:偽造の拒否 var mailAddress = new MailAddress(data.Mail.GetHeader("From")); if (mailAddress.User == "") { Logger.Set(LogKind.Secure, sockTcp, 52, string.Format("From:{0}", mailAddress)); sockTcp.AsciiSend("530 There is not an email address in a local user"); continue; } //ローカルドメインでない場合は拒否する if (!mailAddress.IsLocal(DomainList)) { Logger.Set(LogKind.Secure, sockTcp, 28, string.Format("From:{0}", mailAddress)); sockTcp.AsciiSend("530 There is not an email address in a local domain"); continue; } //有効なユーザでない場合拒否する if (!Kernel.MailBox.IsUser(mailAddress.User)) { Logger.Set(LogKind.Secure, sockTcp, 29, string.Format("From:{0}", mailAddress)); sockTcp.AsciiSend("530 There is not an email address in a local user"); continue; } } //ヘッダの変換及び追加 _changeHeader.Exec(data.Mail, Logger); //テンポラリバッファの内容でMailオブジェクトを生成する var error = false; foreach (var to in Alias.Reflection(session.To, Logger)) { if (!MailSave2(session.From, to, data.Mail, sockTcp.RemoteHostname, sockTcp.RemoteIp)) {//MLとそれ以外を振り分けて保存する error = true; break; } } sockTcp.AsciiSend(error ? "554 MailBox Error" : "250 OK"); session.To.Clear(); } } if (sockTcp != null) sockTcp.Close(); }
protected override void OnSubThread(SockObj sockObj) { //�Z�b�V�������Ƃ̏�� var session = new Session((SockTcp) sockObj); //���̃R�l�N�V�����̊ԁA�P�ÂC���N�����g���Ȃ���g�p����� //�{���́A�ؒf�����|�[�g�ԍ��͍ė��p�\�Ȃ̂ŁA�C���N�������g�̕K�v�͖������A //�Z���Ԃōė��p���悤�Ƃ���ƃG���[����������ꍇ������̂ŁA���������ړI�ŃC���N�������g���Ďg�p���Ă��� //�O���[�e�B���O���b�Z�[�W�̑��M session.StringSend(string.Format("220 {0}", _bannerMessage)); //�R�l�N�V������p�����邩�ǂ����̃t���O var result = true; while (IsLife() && result){ //���̃��[�v�͍ŏ��ɃN���C�A���g����̃R�}���h��P�s��M���A�Ō�ɁA //sockCtrl.LineSend(resStr)�Ń��X�|���X������s�� //continue��w�肵���ꍇ�́A���X�|���X��Ԃ����Ɏ��̃R�}���h��M�ɓ���i��O�����p�j //break��w�肵���ꍇ�́A�R�l�N�V�����̏I����Ӗ�����iQUIT ABORT �y�уG���[�̏ꍇ�j Thread.Sleep(0); var cmd = recvCmd(session.SockCtrl); if (cmd == null){ //�ؒf����Ă��� break; } if (cmd.Str == ""){ session.StringSend("500 Invalid command: try being more creative."); //��M�ҋ@�� //Thread.Sleep(100); continue; } //�R�}���h������̉�� //var ftpCmd = (FtpCmd) Enum.Parse(typeof (FtpCmd), cmd.CmdStr); var ftpCmd = FtpCmd.Unknown; foreach (FtpCmd n in Enum.GetValues(typeof(FtpCmd))) { if (n.ToString().ToUpper() != cmd.CmdStr.ToUpper()) continue; ftpCmd = n; break; } //FtpCmd ftpCmd = FtpCmd.parse(cmd.CmdStr); var param = cmd.ParamStr; //SYST�R�}���h���L�����ǂ����̔��f if (ftpCmd == FtpCmd.Syst){ if (!(bool) Conf.Get("useSyst")){ ftpCmd = FtpCmd.Unknown; } } //�R�}���h�������ȏꍇ�̏��� if (ftpCmd == FtpCmd.Unknown){ //session.StringSend("502 Command not implemented."); session.StringSend("500 Command not understood."); } //QUIT�͂��ł�t���� if (ftpCmd == FtpCmd.Quit){ session.StringSend("221 Goodbye."); break; } if (ftpCmd == FtpCmd.Abor){ session.StringSend("250 ABOR command successful."); break; } // //����́A���O�C���������t���Ȃ��R�}���h����H // //RNFR�Ŏw�肳�ꂽ�p�X�̖����� // if (ftpCmd != FtpCmd.Rnfr) { // session.setRnfrName(""); // } // �R�}���h�g�ւ� if (ftpCmd == FtpCmd.Cdup){ param = ".."; ftpCmd = FtpCmd.Cwd; } //�s���A�N�Z�X�Ώ� �p�����[�^�ɋɒ[�ɒ���������𑗂荞�܂ꂽ�ꍇ if (param.Length > 128){ Logger.Set(LogKind.Secure, session.SockCtrl, 1, string.Format("{0} Length={1}", ftpCmd, param.Length)); break; } //�f�t�H���g�̃��X�|���X������ //���������ׂĒʉ߂��Ă��܂����ꍇ�A���̕����Ԃ���� //String resStr2 = string.Format("451 {0} error", ftpCmd); // ���O�C���O�̏��� if (session.CurrentDir == null){ //ftpCmd == FTP_CMD.PASS //������ //PASS�̑O��USER�R�}���h��K�v�Ƃ��� //sockCtrl.LineSend("503 Login with USER first."); if (ftpCmd == FtpCmd.User){ if (param == ""){ session.StringSend(string.Format("500 {0}: command requires a parameter.", ftpCmd.ToString().ToUpper())); continue; } result = JobUser(session, param); } else if (ftpCmd == FtpCmd.Pass){ result = JobPass(session, param); } else{ //USER�APASS�ȊO�̓G���[��Ԃ� session.StringSend("530 Please login with USER and PASS."); } // ���O�C����̏��� } else{ // �p�����[�^�̊m�F(�p�����[�^�������ꍇ�̓G���[��Ԃ�) if (param == ""){ if (ftpCmd == FtpCmd.Cwd || ftpCmd == FtpCmd.Type || ftpCmd == FtpCmd.Mkd || ftpCmd == FtpCmd.Rmd || ftpCmd == FtpCmd.Dele || ftpCmd == FtpCmd.Port || ftpCmd == FtpCmd.Rnfr || ftpCmd == FtpCmd.Rnto || ftpCmd == FtpCmd.Stor || ftpCmd == FtpCmd.Retr){ //session.StringSend("500 command not understood:"); session.StringSend(string.Format("500 {0}: command requires a parameter.", ftpCmd.ToString().ToUpper())); continue; } } // �f�[�^�R�l�N�V�����������ƃG���[�ƂȂ�R�}���h if (ftpCmd == FtpCmd.Nlst || ftpCmd == FtpCmd.List || ftpCmd == FtpCmd.Stor || ftpCmd == FtpCmd.Retr){ if (session.SockData == null || session.SockData.SockState !=Bjd.sock.SockState.Connect){ session.StringSend("226 data connection close."); continue; } } // ���[�U�̃A�N�Z�X���ɃG���[�ƂȂ�R�}���h if (session.OneUser != null){ if (session.OneUser.FtpAcl == FtpAcl.Down){ if (ftpCmd == FtpCmd.Stor || ftpCmd == FtpCmd.Dele || ftpCmd == FtpCmd.Rnfr || ftpCmd == FtpCmd.Rnto || ftpCmd == FtpCmd.Rmd || ftpCmd == FtpCmd.Mkd){ session.StringSend("550 Permission denied."); continue; } } else if (session.OneUser.FtpAcl == FtpAcl.Up){ if (ftpCmd == FtpCmd.Retr || ftpCmd == FtpCmd.Dele || ftpCmd == FtpCmd.Rnfr || ftpCmd == FtpCmd.Rnto || ftpCmd == FtpCmd.Rmd || ftpCmd == FtpCmd.Mkd){ session.StringSend("550 Permission denied."); continue; } } } // ���O�C����(�F�؊����j���́AUSER�APASS ��t���Ȃ� if (ftpCmd == FtpCmd.User || ftpCmd == FtpCmd.Pass){ session.StringSend("530 Already logged in."); continue; } if (ftpCmd == FtpCmd.Noop){ session.StringSend("200 NOOP command successful."); } else if (ftpCmd == FtpCmd.Pwd || ftpCmd == FtpCmd.Xpwd){ session.StringSend(string.Format("257 \"{0}\" is current directory.", session.CurrentDir.GetPwd())); } else if (ftpCmd == FtpCmd.Cwd){ result = JobCwd(session, param); } else if (ftpCmd == FtpCmd.Syst){ var os = Environment.OSVersion; session.StringSend(string.Format("215 {0}", os.VersionString)); } else if (ftpCmd == FtpCmd.Type){ result = JobType(session, param); } else if (ftpCmd == FtpCmd.Mkd || ftpCmd == FtpCmd.Rmd || ftpCmd == FtpCmd.Dele){ result = JobDir(session, param, ftpCmd); } else if (ftpCmd == FtpCmd.Nlst || ftpCmd == FtpCmd.List){ result = JobNlist(session, param, ftpCmd); } else if (ftpCmd == FtpCmd.Port || ftpCmd == FtpCmd.Eprt){ result = JobPort(session, param, ftpCmd); } else if (ftpCmd == FtpCmd.Pasv || ftpCmd == FtpCmd.Epsv){ result = JobPasv(session, ftpCmd); } else if (ftpCmd == FtpCmd.Rnfr){ result = jobRnfr(session, param, ftpCmd); } else if (ftpCmd == FtpCmd.Rnto){ result = JobRnto(session, param, ftpCmd); } else if (ftpCmd == FtpCmd.Stor){ result = JobStor(session, param, ftpCmd); } else if (ftpCmd == FtpCmd.Retr){ result = JobRetr(session, param); } } } //���O�C�����Ă���ꍇ�́A���O�A�E�g�̃��O��o�͂��� if (session.CurrentDir != null){ //logout Logger.Set(LogKind.Normal, session.SockCtrl, 13, string.Format("{0}", session.OneUser.UserName)); } session.SockCtrl.Close(); if (session.SockData != null){ session.SockData.Close(); } }
public new void Set(LogKind logKind, SockObj sockObj, int messageNo, String detailInfomation) { _ar.Add(new LogTemporary(logKind, sockObj, messageNo, detailInfomation)); }
//ログ出力 //Override可能(テストで使用) public void Set(LogKind logKind, SockObj sockBase, int messageNo, String detailInfomation) { //デバッグ等でkernelが初期化されていない場合、処理なし if (_logFile == null && _logView == null){ return; } //詳細ログが対象外の場合、処理なし if (logKind == LogKind.Detail){ if (!_useDetailsLog){ return; } } int threadId = GetCurrentThreadId(); //long threadId = Thread.currentThread().getId(); var message = _isJp ? "定義されていません" : "Message is not defined"; if (messageNo < 9000000){ if (_logger != null){ message = _logger.GetMsg(messageNo); //デリゲートを使用した継承によるメッセージ取得 } } else{ //(9000000以上)共通番号の場合の処理 switch (messageNo){ case 9000000: message = _isJp ? "サーバ開始" : "Server started it"; break; case 9000001: message = _isJp ? "サーバ停止" : "Server stopped"; break; case 9000002: message = "_subThread() started."; break; case 9000003: message = "_subThread() stopped."; break; case 9000004: message = _isJp ? "同時接続数を超えたのでリクエストをキャンセルします" : "Because the number of connection exceeded it at the same time, the request was canceled."; break; case 9000005: message = _isJp ? "受信文字列が長すぎます(不正なリクエストの可能性があるため切断しました)" : "Reception character string is too long (cut off so that there was possibility of an unjust request in it)"; break; case 9000006: message = _isJp ? "このポートは、既に他のプログラムが使用しているため使用できません" : "Cannot use this port so that other programs already use it"; break; case 9000007: message = _isJp ? "callBack関数が指定されていません[UDP]" : "It is not appointed in callback function [UDP]"; break; case 9000008: message = _isJp ? "プラグインをインストールしました" : "setup initialize plugin"; break; //case 9000009: // message = _isJp ? "Socket.Bind()でエラーが発生しました。[TCP]" : "An error occurred in Socket.Bind() [TCP]"; // break; //case 9000010: // message = _isJp // ? "Socket.Listen()でエラーが発生しました。[TCP]" // : "An error occurred in Socket..Listen() [TCP]"; // break; case 9000011: message = "tcpQueue().Dequeue()=null"; break; case 9000012: message = "tcpQueue().Dequeue() SocektObjState != SOCKET_OBJ_STATE.CONNECT break"; break; case 9000013: message = "tcpQueue().Dequeue()"; break; // case 9000014: // message = "SendBinaryFile(string fileName) socket.Send()"; // break; // case 9000015: // message = "SendBinaryFile(string fileName,long rangeFrom,long rangeTo) socket.Send()"; // break; case 9000016: message = _isJp ? "このアドレスからの接続は許可されていません(ACL)" : "Connection from this address is not admitted.(ACL)"; break; case 9000017: message = _isJp ? "このアドレスからの接続は許可されていません(ACL)" : "Connection from this address is not admitted.(ACL)"; break; case 9000018: message = _isJp ? "この利用者のアクセスは許可されていません(ACL)" : "Access of this user is not admitted (ACL)"; break; case 9000019: message = _isJp ? "アイドルタイムアウト" : "Timeout of an idle"; break; case 9000020: message = _isJp ? "送信に失敗しました" : "Transmission of a message failure"; break; case 9000021: message = _isJp ? "ThreadBase::loop()で例外が発生しました" : "An exception occurred in ThreadBase::Loop()"; break; case 9000022: message = _isJp ? "ウインドウ情報保存ファイルにIOエラーが発生しました" : "An IO error occurred in a window information save file"; break; case 9000023: message = _isJp ? "証明書の読み込みに失敗しました" : "Reading of a certificate made a blunder"; break; case 9000024: message = _isJp ? "SSLの初期化に失敗しているためサーバは起動できません" : "A server cannot start in order to fail in initialization of SSL"; break; //case 9000025: message = isJp ? "ファイル(秘密鍵)が見つかりません" : "Private key is not found"; break; case 9000026: message = _isJp ? "ファイル(証明書)が見つかりません" : "A certificate is not found"; break; //case 9000027: message = isJp ? "OpenSSLのライブラリ(ssleay32.dll,libeay32.dll)が見つかりません" : "OpenSSL library (ssleay32.dll,libeay32.dll) is not found"; break; case 9000028: message = _isJp ? "SSLの初期化に失敗しています" : "Initialization of SSL made a blunder"; break; case 9000029: message = _isJp ? "指定された作業ディレクトリが存在しません" : "A work directory is not found"; break; case 9000030: message = _isJp ? "起動するサーバが見つかりません" : "A starting server is not found"; break; case 9000031: message = _isJp ? "ログファイルの初期化に失敗しました" : "Failed in initialization of logfile"; break; case 9000032: message = _isJp ? "ログ保存場所" : "a save place of LogFile"; break; case 9000033: message = _isJp ? "ファイル保存時にエラーが発生しました" : "An error occurred in a File save"; break; case 9000034: message = _isJp ? "ACL指定に問題があります" : "ACL configuration failure"; break; case 9000035: message = _isJp ? "Socket()でエラーが発生しました。[TCP]" : "An error occurred in Socket() [TCP]"; break; //case 9000036: // message = _isJp ? "Socket()でエラーが発生しました。[UDP]" : "An error occurred in Socket() [UDP]"; // break; case 9000037: message = _isJp ? "_subThread()で例外が発生しました" : "An exception occurred in _subThread()"; break; case 9000038: message = _isJp ? "【例外】" : "[Exception]"; break; case 9000039: message = _isJp ? "【STDOUT】" : "[STDOUT]"; break; case 9000040: message = _isJp ? "拡張SMTP適用範囲の指定に問題があります" : "ESMTP range configuration failure"; break; case 9000041: message = _isJp ? "disp2()で例外が発生しました" : "An exception occurred in disp2()"; break; case 9000042: message = _isJp ? "初期化に失敗しているためサーバを開始できません" : "Can't start a server in order to fail in initialization"; break; case 9000043: message = _isJp ? "クライアント側が切断されました" : "The client side was cut off"; break; case 9000044: message = _isJp ? "サーバ側が切断されました" : "The server side was cut off"; break; case 9000045: message = _isJp ? "「オプション(O)-ログ表示(L)-基本設定-ログの保存場所」が指定されていません" : "\"log save place\" is not appointed"; break; case 9000046: message = _isJp ? "socket.send()でエラーが発生しました" : "socket.send()"; break; case 9000047: message = _isJp ? "ユーザ名が無効です" : "A user name is null and void"; break; case 9000048: message = _isJp ? "ThreadBase::Loop()で例外が発生しました" : "An exception occurred in ThreadBase::Loop()"; break; case 9000049: message = _isJp ? "【例外】" : "[Exception]"; break; case 9000050: message = _isJp ? "ファイルにアクセスできませんでした" : "Can't open a file"; break; case 9000051: message = _isJp ? "インスタンスの生成に失敗しました" : "Can't create instance"; break; case 9000052: message = _isJp ? "名前解決に失敗しました" : "Non-existent domain"; break; case 9000053: message = _isJp ? "【例外】SockObj.Resolve()" : "[Exception] SockObj.Resolve()"; break; case 9000054: message = _isJp ? "Apache Killerによる攻撃の可能性があります" : "There is possibility of attack by Apache Killer in it"; break; case 9000055: message = _isJp ? "【自動拒否】「ACL」の禁止する利用者(アドレス)に追加しました" : "Add it to a deny list automatically"; break; case 9000056: message = _isJp ? "不正アクセスを検出しましたが、ACL「拒否」リストは追加されませんでした" : "I detected possibility of Attack, but the ACL [Deny] list was not added"; break; case 9000057: message = _isJp ? "【例外】" : "[Exception]"; break; case 9000058: message = _isJp ? "メールの送信に失敗しました" : "Failed in the transmission of a message of an email"; break; case 9000059: message = _isJp ? "メールの保存に失敗しました" : "Failed in a save of an email"; break; case 9000060: message = _isJp ? "【例外】" : "[Exception]"; break; case 9000061: message = _isJp ? "【例外】" : "[Exception]"; break; //case 9000061: // message = isJp ? "ファイルの作成に失敗しました" : "Failed in making of a file"; // break; } } var remoteHostname = (sockBase == null) ? "-" : sockBase.RemoteHostname; var oneLog = new OneLog(DateTime.Now, logKind, _nameTag, threadId, remoteHostname, messageNo, message, detailInfomation); // 表示制限にヒットするかどうかの確認 var isDisplay = true; if (!oneLog.IsSecure()){ //セキュリティログは表示制限の対象外 if (_logLimit != null){ isDisplay = _logLimit.IsDisplay(oneLog.ToString()); } } if (_logView != null && isDisplay){ //isDisplayの結果に従う _logView.Append(oneLog); } //Ver5.8.8 //LogViewの中で実行していたリモートクライアントへの送信をこちらに移動する //サービス起動の際に、ListViewがnullで、処理されないから //リモートクライアントへのログ送信 if (_kernel != null && _kernel.RemoteConnect != null && _kernel.ListServer != null) { //クライアントから接続されている場合 var sv = _kernel.ListServer.Get("Remote"); if (sv != null) sv.Append(oneLog); } if (_logFile != null){ if (_useLimitString){ //表示制限が有効な場合 if (isDisplay){ //isDisplayの結果に従う _logFile.Append(oneLog); } } else{ //表示制限が無効な場合は、すべて保存される _logFile.Append(oneLog); } } }
//接続単位の処理 protected override void OnSubThread(SockObj sockObj) { //UDPサーバの場合は、UdpObjで受ける var sockTcp = (SockTcp)sockObj; // レスポンス用のJSON文字列 var json = JsonConvert.SerializeObject(new Error(500,"Not Implemented","")); //1行受信 var str = sockTcp.AsciiRecv(30,this); if (str == null){ return; } //GET /mail/cmd?p1=v1&p2=v2 HTTP/1.1 var tmp = str.Split(' '); if (tmp.Length == 3){ var method = Method.Unknown; foreach (Method m in Enum.GetValues(typeof(Method))){ if (m.ToString().ToLower() == tmp[0].ToLower()){ method = m; break; } } if (method != Method.Unknown) { // /mail/cmd?p1=v1&p2=v2 var p = tmp[1].Split('/'); if (p.Length == 3){ var server = p[1].ToLower(); //パラメータの値以外は、強制的に小文字に設定する var n = p[2].Split('?'); var cmd = n[0].ToLower();//パラメータの値以外は、強制的に小文字に設定する var param = new Dictionary<String, String>(); if (n.Length == 2){ foreach (var m in n[1].Split('&')){ var o = m.Split('='); if (o.Length == 2){ param.Add(o[0].ToLower(), o[1]); //パラメータの値以外は、強制的に小文字に設定する } else{ param.Add(m.ToLower(), ""); //パラメータの値以外は、強制的に小文字に設定する } } } if (server == "mail"){ // OneOption.GetValue("sampleText"); var mail = new SvMail(Kernel); json = mail.Exec(method,cmd, param); //Ver5.9.8 if (method == Method.Delete){ var error = JsonConvert.DeserializeObject<Error>(json); sockTcp.Send(Encoding.UTF8.GetBytes(string.Format("HTTP/1.1 {0} {1}\r\n\r\n", error.code, error.message))); return; } } } } } //1行送信 //Ver5.9.8 sockTcp.Send(Encoding.UTF8.GetBytes(string.Format("HTTP/1.1 200\r\n\r\n{0}",json))); //sockTcp.Send(Encoding.UTF8.GetBytes(json)); //このメソッドを抜けると切断される }
//�ڑ��P�ʂ̏��� protected override void OnSubThread(SockObj sockObj) { string hostName; var client = (SockTcp)sockObj; SockTcp server = null; //*************************************************************** //�O�����i�ڑ���E���[�U���E�p�X���[�h�̎擾) //*************************************************************** //{ // //�ڑ���i�z�X�g�j���擾 // client.AsciiSend("open>"); // var sb = new StringBuilder(); // while (IsLife()) { // var b = client.Recv(1,Timeout,this);//timeout=60sec // if (b == null) // break; // var c = Convert.ToChar(b[0]); // if (c == '\r'){ // continue; // } // if (c == '\n') // break; // //Ver6.0.6 TeraTerm�Ή� // if (c == 0 && sb.Length != 0) // { // break; // } // if ((c == '.') || ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) // { // client.Send(b);//�G�R�[ // sb.Append(c); // } // } // hostName = sb.ToString(); //} var buf = new List<byte>(); { //�ڑ���i�z�X�g�j���擾 client.Send(Encoding.ASCII.GetBytes("open>")); var iac = false; var ego = false; var sb = new StringBuilder(); while (IsLife()){ var b = client.Recv(1, Timeout, this); //timeout=60sec if (b == null) break; var d = Convert.ToChar(b[0]); if (d == 0) continue; if (d == '\xFF'){ iac = true; buf.Add(b[0]); continue; } if (iac){ if (d == '\xFA'){ ego = true; iac = false; buf.Add(b[0]); continue; } if (d == '\xF0'){ ego = false; iac = false; buf.Add(b[0]); continue; } if (d == '\xFB' || d == '\xFC' || d == '\xFD' || d == '\xFE'){ buf.Add(b[0]); continue; } iac = false; buf.Add(b[0]); continue; } if (ego){ buf.Add(b[0]); continue; } client.Send(b); //�G�R�[ if (d == '\r' || d == '\n') break; if (d == '\b'){ sb.Remove(sb.Length - 1, 1); } else{ sb.Append(d); } } hostName = sb.ToString(); } // ���݂̔j�� while (IsLife() && client.Length()>0) { var b = client.Recv(1, Timeout, this); //timeout=60sec } //*************************************************************** // �T�[�o�Ƃ̐ڑ� //*************************************************************** { const int port = 23; //var ipList = new List<Ip>{new Ip(hostName)}; //if (ipList[0].ToString() == "0.0.0.0") { // ipList = Kernel.DnsCache.Get(hostName); // if (ipList.Count == 0) { // Logger.Set(LogKind.Normal,null,2,string.Format("open>{0}",hostName)); // goto end; // } //} var ipList = Kernel.GetIpList(hostName); if (ipList.Count == 0) { Logger.Set(LogKind.Normal, null, 2, string.Format("open>{0}", hostName)); 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, null, 3, string.Format("open>{0}", hostName)); goto end; } //Ver6.0.6 if (server.SockState != Bjd.sock.SockState.Connect){ Logger.Set(LogKind.Normal, null, 3, string.Format("open>{0}", hostName)); goto end; } } Logger.Set(LogKind.Normal,server,1,string.Format("open>{0}",hostName)); server.Send(buf.ToArray(),buf.Count); //*************************************************************** // �p�C�v //*************************************************************** var tunnel = new Tunnel(Logger,(int)Conf.Get("idleTime"),Timeout); tunnel.Pipe(server,client,this); end: client.Close(); if (server != null) server.Close(); }
//�ڑ��P�ʂ̏��� protected override void OnSubThread(SockObj sockObj) { var timeout = (int)Conf.Get("timeOut"); var client = (SockTcp)sockObj; SockTcp server = null; var user = "";//���[�U�� string pass;//�p�X���[�h var hostName = "";//�z�X�g�� //*************************************************************** //�O�����i�ڑ���E���[�U���E�p�X���[�h�̎擾) //*************************************************************** { var str = string.Format("220 {0} {1}", Define.ApplicationName(), Define.Copyright()); client.AsciiSend(str); var cmdStr = ""; var paramStr = ""; //wait USER user@hostName if (!WaitLine(client, ref cmdStr, ref paramStr)) { goto end; } if (cmdStr.ToUpper() != "USER") goto end; //paramStr = "user@hostName" if (paramStr != null) { //string[] tmp = paramStr.Split('@'); //if(tmp.Length == 2) { // user = tmp[0];//���[�U���擾 // hostName = tmp[1];//�z�X�g���擾 //} var i = paramStr.LastIndexOf('@'); if (i != -1) { user = paramStr.Substring(0, i);//���[�U���擾 hostName = paramStr.Substring(i + 1);//�z�X�g���擾 } } if (hostName == "") { Logger.Set(LogKind.Error, sockObj, 8, ""); goto end; } client.AsciiSend("331 USER OK enter password"); //wait PASS password if (!WaitLine(client, ref cmdStr, ref paramStr)) { goto end; } if (cmdStr.ToUpper() != "PASS") goto end; //paramStr = "password" pass = paramStr;//�p�X���[�h�擾 } //*************************************************************** // �T�[�o�Ƃ̐ڑ� //*************************************************************** { const int port = 21; //var ipList = new List<Ip>{new Ip(hostName)}; //if (ipList[0].ToString() == "0.0.0.0") { // ipList = Kernel.DnsCache.Get(hostName); // if (ipList.Count == 0) { // goto end; // } //} var ipList = Kernel.GetIpList(hostName); if (ipList.Count == 0) { goto end; } Ssl ssl = null; foreach (var ip in ipList) { server = Inet.Connect(Kernel,ip, port,Timeout, ssl); if (server != null) break; } if (server == null) goto end; } //*************************************************************** //�㏈���i���[�U���E�p�X���[�h�̑��M) //*************************************************************** { var cmdStr = ""; var paramStr = ""; //wait 220 welcome while (cmdStr != "220") { if (!WaitLine(server, ref cmdStr, ref paramStr)) { goto end; } } server.AsciiSend(string.Format("USER {0}", user)); //wait 331 USER OK enter password while (cmdStr != "331") { if (!WaitLine(server, ref cmdStr, ref paramStr)) { goto end; } } server.AsciiSend(string.Format("PASS {0}", pass)); if (!WaitLine(server, ref cmdStr, ref paramStr)) { goto end; } client.AsciiSend(string.Format("{0} {1}", cmdStr, paramStr)); } //*************************************************************** // �p�C�v //*************************************************************** var ftpTunnel = new FtpTunnel(Kernel, Logger, (int)Conf.Get("idleTime"), _dataPort, timeout); //Ver5.0.5 //ftpTunnel.BytePipe(ref life, server,client); ftpTunnel.Pipe(server, client,this); _dataPort = ftpTunnel.Dispose(); if (_dataPort > DataPortMax) _dataPort = DataPortMin; end: client.Close(); if (server != null) server.Close(); }
protected abstract void OnSubThread(SockObj sockObj);
protected override void OnSubThread(SockObj sockObj) { while (IsLife()){ Thread.Sleep(0); //これが無いと、別スレッドでlifeをfalseにできない if (sockObj.SockState != Bjd.sock.SockState.Connect){ Console.WriteLine(@">>>>>sockAccept.getSockState()!=SockState.CONNECT"); break; } } }
//ACL�����̃`�F�b�N //sockObj �����Ώۂ̃\�P�b�g private AclKind AclCheck(SockObj sockObj) { var aclKind = AclKind.Allow; if (AclList != null){ var ip = new Ip(sockObj.RemoteAddress.Address.ToString()); aclKind = AclList.Check(ip); } if (aclKind == AclKind.Deny){ _denyAddress = sockObj.RemoteAddress.ToString(); } return aclKind; }
//�ڑ��P�ʂ̏��� protected override void OnSubThread(SockObj sockObj) { var sockTcp = (SockTcp) sockObj; var pop3LoginState = Pop3LoginState.User; var authType = (int) Conf.Get("authType"); // 0=USER/PASS 1=APOP 2=���� var useChps = (bool) Conf.Get("useChps"); //�p�X���[�h�ύX[CPHS]�̎g�p�E���g�p string user = null; //�O���[�e�B���O���b�Z�[�W�̕\�� var bannerMessage = Kernel.ChangeTag((string) Conf.Get("bannerMessage")); var authStr = ""; //APOP�p�̔F�ؕ����� if (authType == 0){ //USER/PASS sockTcp.AsciiSend("+OK " + bannerMessage); } else{ //APOP authStr = APop.CreateAuthStr(Kernel.ServerName); sockTcp.AsciiSend("+OK " + bannerMessage + " " + authStr); } //���[���{�b�N�X�Ƀ��O�C�����āA���̎��_�̃��[�����X�g��擾���� //���ۂ̃��[���̍폜�́AQUIT��M���ɁAmailList.Update()�ŏ������� MessageList messageList = null; while (IsLife()){ //���̃��[�v�͍ŏ��ɃN���C�A���g����̃R�}���h��P�s��M���A�Ō�ɁA //sockCtrl.LineSend(resStr)�Ń��X�|���X������s�� //continue��w�肵���ꍇ�́A���X�|���X��Ԃ����Ɏ��̃R�}���h��M�ɓ���i��O�����p�j //break��w�肵���ꍇ�́A�R�l�N�V�����̏I����Ӗ�����iQUIT ABORT �y�уG���[�̏ꍇ�j Thread.Sleep(0); var str = ""; var cmdStr = ""; var remoteIp = new Ip(sockTcp.RemoteAddress.Address.ToString()); var paramStr2 = ""; if (!RecvCmd(sockTcp, ref str, ref cmdStr, ref paramStr2)) break; //�ؒf���ꂽ if (str == "waiting"){ Thread.Sleep(100); //��M�ҋ@�� continue; } //�R�}���h������̉�� var cmd = Pop3Cmd.Unknown; foreach (Pop3Cmd n in Enum.GetValues(typeof (Pop3Cmd))){ if (n.ToString().ToUpper() == cmdStr.ToUpper()){ cmd = n; break; } } if (cmd == Pop3Cmd.Unknown){ //�����R�}���h goto UNKNOWN; } //�p�����[�^���� var paramList = new List<string>(); if (paramStr2 != null){ paramList.AddRange( paramStr2.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim(' '))); } //���ł�t���� if (cmd == Pop3Cmd.Quit){ if (messageList != null){ messageList.Update(); //�����ō폜���������s����� } goto END; } if (pop3LoginState == Pop3LoginState.User){ if (cmd == Pop3Cmd.User && (authType == 0 || authType == 2)){ if (paramList.Count < 1){ goto FEW; } user = paramList[0]; pop3LoginState = Pop3LoginState.Pass; sockTcp.AsciiSend(string.Format("+OK Password required for {0}.", user)); } else if (cmd == Pop3Cmd.Apop && (authType == 1 || authType == 2)){ //APOP if (paramList.Count < 2){ goto FEW; } user = paramList[0]; //�F��(APOP�Ή�) var success = APop.Auth(user, Kernel.MailBox.GetPass(user), authStr, paramList[1]); //var success = APopAuth(user, authStr, paramList[1]); AutoDeny(success, remoteIp); //�u���[�g�t�H�[�X�� if (success){ if ( !Login(sockTcp, ref pop3LoginState, ref messageList, user, new Ip(sockObj.RemoteAddress.Address.ToString()))) goto END; } else{ AuthError(sockTcp, user, paramList[1]); goto END; } } else{ goto UNKNOWN; } } else if (pop3LoginState == Pop3LoginState.Pass){ if (cmd != Pop3Cmd.Pass){ goto UNKNOWN; } if (paramList.Count < 1){ goto FEW; } string pass = paramList[0]; var success = Kernel.MailBox.Auth(user, pass); //�F�� AutoDeny(success, remoteIp); //�u���[�g�t�H�[�X�� if (success){ //�F�� if ( !Login(sockTcp, ref pop3LoginState, ref messageList, user, new Ip(sockObj.RemoteAddress.Address.ToString()))) goto END; } else{ AuthError(sockTcp, user, pass); goto END; } } else if (pop3LoginState == Pop3LoginState.Login){ if (cmd == Pop3Cmd.Dele || cmd == Pop3Cmd.Retr){ if (paramList.Count < 1) goto FEW; } if (cmd == Pop3Cmd.Top){ if (paramList.Count < 2) goto FEW; } int index = -1; //���[���A�� if (cmd != Pop3Cmd.Chps && 1 <= paramList.Count){ try{ index = Convert.ToInt32(paramList[0]); } catch (Exception){ sockTcp.AsciiSend("-ERR Invalid message number."); continue; } index--; if (index < 0 || messageList.Max <= index){ sockTcp.AsciiSend(string.Format("-ERR Message {0} does not exist.", index + 1)); continue; } } int count = -1; //TOP �s�� if (cmd != Pop3Cmd.Chps && 2 <= paramList.Count){ try{ count = Convert.ToInt32(paramList[1]); } catch (Exception){ sockTcp.AsciiSend("-ERR Invalid line number."); continue; } if (count < 0){ sockTcp.AsciiSend(string.Format("-ERR Linenumber range over: {0}", count)); continue; } } if (cmd == Pop3Cmd.Noop){ sockTcp.AsciiSend("+OK"); continue; } if (cmd == Pop3Cmd.Stat){ sockTcp.AsciiSend(string.Format("+OK {0} {1}", messageList.Count, messageList.Size)); continue; } if (cmd == Pop3Cmd.Rset){ messageList.Rset(); sockTcp.AsciiSend(string.Format("+OK {0} has {1} message ({2} octets).", user, messageList.Count, messageList.Size)); continue; } if (cmd == Pop3Cmd.Dele){ if (messageList[index].Del){ sockTcp.AsciiSend(string.Format("-ERR Message {0} has been markd for delete.", index + 1)); continue; } messageList[index].Del = true; //Ver5.0.3 //sockTcp.AsciiSend(string.Format("+OK {0} octets",messageList.Size),OPERATE_CRLF.YES); sockTcp.AsciiSend(string.Format("+OK {0} octets", messageList[index].Size)); continue; } if (cmd == Pop3Cmd.Uidl || cmd == Pop3Cmd.List){ if (paramList.Count < 1){ sockTcp.AsciiSend(string.Format("+OK {0} message ({1} octets)", messageList.Count, messageList.Size)); for (int i = 0; i < messageList.Max; i++){ if (!messageList[i].Del){ if (cmd == Pop3Cmd.Uidl) sockTcp.AsciiSend(string.Format("{0} {1}", i + 1, messageList[i].Uid)); else //LIST sockTcp.AsciiSend(string.Format("{0} {1}", i + 1, messageList[i].Size)); } } sockTcp.AsciiSend("."); continue; } if (cmd == Pop3Cmd.Uidl) sockTcp.AsciiSend(string.Format("+OK {0} {1}", index + 1, messageList[index].Uid)); else //LIST sockTcp.AsciiSend(string.Format("+OK {0} {1}", index + 1, messageList[index].Size)); } if (cmd == Pop3Cmd.Top || cmd == Pop3Cmd.Retr){ //OneMessage oneMessage = messageList[index]; sockTcp.AsciiSend(string.Format("+OK {0} octets", messageList[index].Size)); if (!messageList[index].Send(sockTcp, count)){ //���[���̑��M break; } MailInfo mailInfo = messageList[index].GetMailInfo(); Logger.Set(LogKind.Normal, sockTcp, 5, mailInfo.ToString()); sockTcp.AsciiSend("."); continue; } if (cmd == Pop3Cmd.Chps){ if (!useChps) goto UNKNOWN; if (paramList.Count < 1) goto FEW; var password = paramList[0]; //�Œᕶ���� var minimumLength = (int) Conf.Get("minimumLength"); if (password.Length < minimumLength){ sockTcp.AsciiSend("-ERR The number of letter is not enough."); continue; } //���[�U���Ɠ���̃p�X���[�h������Ȃ� if ((bool) Conf.Get("disableJoe")){ if (user.ToUpper() == password.ToUpper()){ sockTcp.AsciiSend("-ERR Don't admit a JOE."); continue; } } //�K���܂܂Ȃ���Ȃ�Ȃ������̃`�F�b�N bool checkNum = false; bool checkSmall = false; bool checkLarge = false; bool checkSign = false; foreach (char c in password){ if ('0' <= c && c <= '9') checkNum = true; else if ('a' <= c && c <= 'z') checkSmall = true; else if ('A' <= c && c <= 'Z') checkLarge = true; else checkSign = true; } if (((bool) Conf.Get("useNum") && !checkNum) || ((bool) Conf.Get("useSmall") && !checkSmall) || ((bool) Conf.Get("useLarge") && !checkLarge) || ((bool) Conf.Get("useSign") && !checkSign)){ sockTcp.AsciiSend("-ERR A required letter is not included."); continue; } var conf = new Conf(Kernel.ListOption.Get("MailBox")); if(!Chps.Change(user, password, Kernel.MailBox, conf)){ //if (!Kernel.MailBox.Chps(user, password, conf)){ sockTcp.AsciiSend("-ERR A problem occurred to a mailbox."); continue; } sockTcp.AsciiSend("+OK Password changed."); } } continue; UNKNOWN: sockTcp.AsciiSend(string.Format("-ERR Invalid command.")); continue; FEW: sockTcp.AsciiSend(string.Format("-ERR Too few arguments for the {0} command.", str)); continue; END: sockTcp.AsciiSend(string.Format("+OK Pop Server at {0} signing off.", Kernel.ServerName)); break; } Kernel.MailBox.Logout(user); if (sockTcp != null) sockTcp.Close(); }
//接続単位の処理 protected override void OnSubThread(SockObj sockObj) { //Ver5.6.9 //UpperProxy upperProxy = new UpperProxy((bool)Conf.Get("useUpperProxy"),(string)this.Conf.Get("upperProxyServer"),(int)this.Conf.Get("upperProxyPort"),disableAddressList); var upperProxy = new UpperProxy((bool)Conf.Get("useUpperProxy"), (string)Conf.Get("upperProxyServer"), (int)Conf.Get("upperProxyPort"), _disableAddressList, (bool)Conf.Get("upperProxyUseAuth"), (string)Conf.Get("upperProxyAuthName"), (string)Conf.Get("upperProxyAuthPass")); var proxy = new Proxy(Kernel,Logger, (SockTcp)sockObj, Timeout, upperProxy);//プロキシ接続情報 ProxyObj proxyObj = null; OneObj oneObj = null; //最初のリクエスト取得 for(int i = 0;IsLife() && proxy.Length(CS.Client) == 0;i++) { //まだサーバと未接続の段階では、クライアントからのリクエストがない場合、 //このスレッドはエラーとなる Thread.Sleep(50); if(i > 100) goto end;//切断 } //新たなHTTPオブジェクトを生成する oneObj = new OneObj(proxy); //リクエスト行・ヘッダ・POSTデータの読み込み・URL制限 if(!oneObj.RecvRequest(_useRequestLog,_limitUrl,this)) goto end; //HTTPの場合 if (oneObj.Request.Protocol == ProxyProtocol.Http) { proxyObj = new ProxyHttp(proxy,Kernel,Conf,_cache,_limitString);//HTTPデータ管理オブジェクト //最初のオブジェクトの追加 proxyObj.Add(oneObj); while(IsLife()) {//デフォルトで継続型 //******************************************************* //プロキシ処理 //******************************************************* if(!proxyObj.Pipe(this)) goto end; if(!((ProxyHttp)proxyObj).KeepAlive) { if(proxyObj.IsFinish()) { Logger.Set(LogKind.Debug,null,999,"break keepAlive=false"); break; } } //******************************************************* //次のリクエストを取得 //******************************************************* //if(((ProxyHttp)proxyObj).KeepAlive) { for(var i = 0;i < 30;i++) { if(proxy.Length(CS.Client) != 0) { //Ver5.9.0 if (oneObj != null){ oneObj.Dispose(); } //新たなHTTPオブジェクトを生成する oneObj = new OneObj(proxy); //リクエスト行・ヘッダ・POSTデータの読み込み・URL制限 if(!oneObj.RecvRequest(_useRequestLog,_limitUrl,this)) goto end; if (oneObj.Request.Protocol != ProxyProtocol.Http) { goto end;//Ver5.0.2 } //HTTPオブジェクトの追加 proxyObj.Add(oneObj); } else { if(!proxyObj.IsFinish()) break; //Ver5.6.1 最適化 if (!proxyObj.WaitProcessing()) { Thread.Sleep(5); } } } //} //デバッグログ //proxyObj.DebugLog(); if(proxyObj.IsTimeout()) { Logger.Set(LogKind.Debug,null,999,string.Format("break waitTime>{0}sec [Option Timeout]",proxy.OptionTimeout)); break; } //Ver5.1.4-b1 //Thread.Sleep(500); Thread.Sleep(1);//Ver5.6.1これを0にするとCPU使用率が100%になってしまう } } else if (oneObj.Request.Protocol == ProxyProtocol.Ssl) { proxyObj = new ProxySsl(proxy);//SSLデータ管理オブジェクト //オブジェクトの追加 proxyObj.Add(oneObj); while(IsLife()) {//デフォルトで継続型 //******************************************************* //プロキシ処理 //******************************************************* if(!proxyObj.Pipe(this)) goto end; //デバッグログ //proxyObj.DebugLog(); if(proxyObj.IsTimeout()) { Logger.Set(LogKind.Debug,null,999,string.Format("break waitTime>{0}sec [Option Timeout]",proxy.OptionTimeout)); break; } //Ver5.0.0-b13 //Thread.Sleep(500); Thread.Sleep(1); } } else if (oneObj.Request.Protocol == ProxyProtocol.Ftp) { proxyObj = new ProxyFtp(proxy,Kernel,Conf,this,++_dataPort);//FTPデータ管理オブジェクト //オブジェクトの追加 proxyObj.Add(oneObj); //******************************************************* //プロキシ処理 //******************************************************* proxyObj.Pipe(this); _dataPort = ((ProxyFtp)proxyObj).DataPort; if(_dataPort>DataPortMax) _dataPort = DataPortMin; } end: //Ver5.9.0 if (oneObj != null){ oneObj.Dispose(); } //終了処理 if(proxyObj != null) proxyObj.Dispose(); proxy.Dispose(); //Java fix Ver5.9.0 GC.Collect(); }