public MailInfo(string fileName) { Clear();//初期値 if (!File.Exists(fileName)) return; try { using (var sr = new StreamReader(fileName, Encoding.GetEncoding("ascii"))) { Uid = sr.ReadLine(); Size = Convert.ToInt64(sr.ReadLine()); Host = sr.ReadLine(); Addr = new Ip(sr.ReadLine()); Date = sr.ReadLine(); RetryCounter = Convert.ToInt32(sr.ReadLine()); var ticks = Convert.ToInt64(sr.ReadLine()); _dt = new DateTime(ticks); From = new MailAddress(sr.ReadLine()); To = new MailAddress(sr.ReadLine()); sr.Close(); } int index = fileName.LastIndexOf("DF_"); if (index != -1) FileName = fileName.Substring(index + 3); } catch { Clear();//初期値 } }
//MAILコマンド public void Mail(MailAddress mailAddress) { //セッション初期化 Rest(); From = mailAddress; }
public MlEnvelope(MailAddress from, MailAddress to, string host, Ip addr) { From = from; To = to; Host = host; Addr = addr; }
public OneSubscribe(MailAddress mailAddress, string name, string confirmStr) { Dt = DateTime.Now; MailAddress = mailAddress; Name = name; ConfirmStr = confirmStr; }
//Server及びMlから使用される //メールの保存(宛先はML以外であることが確定してから使用する) //テスト用のモックオブジェクト(TsMailSaveでSave()をオーバーライドできるようにvirtualにする public virtual bool Save(MailAddress from, MailAddress to, Mail orgMail, string host, Ip addr) { //Mailのヘッダ内容等を変更するので、この関数内だけの変更にとどめるため、テンポラリを作成する var mail = new Mail(); //orgMail.CreateClone(); mail.Init2(orgMail.GetBytes()); //ユニークなID文字列の生成 var uidStr = string.Format("bjd.{0:D20}.{1:D3}", DateTime.Now.Ticks, _idCounter++); //日付文字列の生成 //var date = Util.LocalTime2Str(DateTime.Now); //Receivedヘッダの追加 mail.AddHeader("Received", _receivedHeader.Get(to, host, addr)); // //Message-Idの追加 // if (null == mail.GetHeader("Message-ID")) // mail.AddHeader("Message-ID", string.Format("<{0}@{1}>", uidStr, _domainList[0])); // //Fromの追加 // if (null == mail.GetHeader("From")) // mail.AddHeader("From", string.Format("<{0}>", @from)); // //Dateの追加 // if (null == mail.GetHeader("Date")) // mail.AddHeader("Date", string.Format("{0}", date)); //ローカル宛(若しくはローカルファイル) if (to.IsLocal(_domainList)) { //ローカル保存の場合は、X-UIDLを追加する mail.AddHeader("X-UIDL", uidStr); //ヘッダを追加してサイズが変わるので、ここで初期化する var mailInfo = new MailInfo(uidStr, mail.Length, host, addr, from, to); if (to.IsFile()) { //ローカルファイルの場合(直接ファイルにAppendする) if (!_localBox.Save(to,mail,mailInfo)){ return false; } } else { //ローカルユーザの場合(メールボックスへSaveする) if (!_mailBox.Save(to.User, mail, mailInfo)){ return false; } } _logger.Set(LogKind.Normal, null, 8, mailInfo.ToString()); } else { //Toの追加 // if (null == mail.GetHeader("To")) { // mail.AddHeader("To", string.Format("<{0}>", to)); // } //ヘッダを追加してサイズが変わるので、ここで初期化する var mailInfo = new MailInfo(uidStr, mail.Length, host, addr, from, to); if (!_mailQueue.Save(mail, mailInfo)) { _logger.Set(LogKind.Error, null, 9000059, mail.GetLastError()); return false; } _logger.Set(LogKind.Normal, null, 9, mailInfo.ToString()); } return true; }
public void コンストラクタによる名前とドメイン名の初期化(string mailaddress, string user, string domain) { //setUp var sut = new MailAddress(mailaddress); //verify Assert.That(sut.User, Is.EqualTo(user)); Assert.That(sut.Domain, Is.EqualTo(domain)); }
public void コンストラクタによる初期化(string str, string user, string domain) { //setUp var sut = new MailAddress(str); //exercise Assert.That(sut.User,Is.EqualTo(user)); Assert.That(sut.Domain, Is.EqualTo(domain)); }
public OneSubscribe Add(MailAddress mailAddress, string name) { lock (SyncObj) { var confirmStr = string.Format("{0:D20}.{1:D5}", DateTime.Now.Ticks, _random.Next(99999)); var oneSubscribe = new OneSubscribe(mailAddress, name, confirmStr); _ar.Add(oneSubscribe); return oneSubscribe; } }
public void IsLocalによるドメインに属するかどうかの確認(string mailaddress, string[] domainList, bool expected) { //setUp var sut = new MailAddress(mailaddress); //exercise var actual = sut.IsLocal(domainList.ToList()); //verify Assert.That(actual, Is.EqualTo(expected)); }
//削除(unsubscribeによる) public Dat Del(MailAddress mailAddress) { var o = Search(mailAddress); if (o != null && !o.IsManager) { _ar.Remove(o); return Export();//更新 Update()が必要 } return null; }
public MlOneUser(bool enable, string name, MailAddress mailAddress, bool isManager, bool isReader, bool isContributor, string password) { Enable = enable; Name = name; MailAddress = mailAddress; IsManager = isManager; IsReader = isReader; IsContributor = isContributor; Psssword = password; }
//追加(subscribeによる) public Dat Add(MailAddress mailAddress, string name) { const bool enabled = true; //var password = Crypt.Encrypt("");//パスワード var password = "";//パスワード const bool isManager = false; //管理者 const bool isReader = true; //配信する const bool isContributor = true; //投稿者 _ar.Add(new MlOneUser(enabled, name, mailAddress, isManager, isReader, isContributor, password)); return Export();//更新 Update()が必要 }
public bool Save(MailAddress to,Mail mail,MailInfo mailInfo) { if (mail.Append(to.ToString())) { if (_logger != null){ _logger.Set(LogKind.Normal, null, 21, string.Format("[{0}] {1}", to.User, mailInfo)); } } else { _logger.Set(LogKind.Error, null, 9000059, mail.GetLastError()); _logger.Set(LogKind.Error, null, 22, string.Format("[{0}] {1}", to.User, mailInfo)); } return true; }
public bool Del(MailAddress mailAddress) { lock (SyncObj) { for (var i = 0; i < _ar.Count; i++) { if (!mailAddress.Compare(_ar[i].MailAddress)) continue; _ar.RemoveAt(i); return true; } } return false; }
public bool Save(MailAddress from, List<MailAddress> rcptList, Mail mail, string host, Ip addr) { List<MailAddress> toList = _alias.Reflection(rcptList, _logger); foreach (var to in toList) { if (!Save(from, to, mail, host, addr)){ //Ver5.9.8 //_logger.Set(LogKind.Error, null, 7, String.Format("From:{0} To:{1}", from, to)); _logger.Set(LogKind.Error, null, 55, String.Format("From:{0} To:{1}", from, to)); return false; } } return true; }
//通常のコンストラクタ public MlUserList(IEnumerable<OneDat> memberList) { foreach (var d in memberList) { var name = d.StrList[0]; //名前 var mailAddress = new MailAddress(d.StrList[1]); //メールアドレス if (mailAddress.User == "" || mailAddress.Domain == "") { continue; } var isManager = (d.StrList[2] == "True"); //管理者 var isReader = (d.StrList[3] == "True"); //配信する var isContributor = (d.StrList[4] == "True"); //投稿者 var password = Crypt.Decrypt(d.StrList[5]) ?? ""; //パスワード _ar.Add(new MlOneUser(d.Enable, name, mailAddress, isManager, isReader, isContributor,password)); } }
//代表アドレスの種類判定 public MlAddrKind GetKind(MailAddress mailAddress) { if (mailAddress.IsLocal(DomainList)) { //「投稿アドレス」 if (mailAddress.User.ToUpper() == Name.ToUpper()) return MlAddrKind.Post; //「制御アドレス」 if (mailAddress.User.ToUpper() == (Name + "-ctl").ToUpper()) return MlAddrKind.Ctrl; //「管理者アドレス」 if (mailAddress.User.ToUpper() == (Name + "-admin").ToUpper()) return MlAddrKind.Admin; } return MlAddrKind.None;//無効 }
DateTime _dt; //最終処理時刻 #endregion Fields #region Constructors public MailInfo(string uid, long size, string host, Ip addr, MailAddress from, MailAddress to) { Clear();//初期値 Uid = uid; Size = size; Host = host; Addr = addr; //日付文字列の生成 Date = Util.LocalTime2Str(DateTime.Now); _dt = new DateTime(0);//最初は0で初期化して、とりあえずキューの処理対象になるようにする From = from; To = to; }
public bool FromString(string str) { str = Inet.TrimCrlf(str);//\r\nの排除 var tmp = str.Split('\t'); if (tmp.Length == 4) { try { var ticks = Convert.ToInt64(tmp[0]); Dt = new DateTime(ticks); MailAddress = new MailAddress(tmp[1]); Name = tmp[2]; ConfirmStr = tmp[3]; return true;//初期化成功 } catch (Exception){ } } return false; }
public void AddSearchTest(string users, string searchUser, bool success) { //複数のユーザを追加 var ar = users.Split(new[]{','},StringSplitOptions.RemoveEmptyEntries); foreach (var user in ar) { var addr = new MailAddress(string.Format("{0}@example.com",user)); _mlSubscribeDb.Add(addr, user); } //検索アドレス var searchAddr = new MailAddress(searchUser, "example.com"); //検索実行 var o = _mlSubscribeDb.Search(searchAddr); if (success) {//成功の場合 Assert.AreEqual(o.MailAddress.ToString(), searchAddr.ToString()); } else {//失敗の場合 Assert.IsNull(o);//NULLが返る } }
public bool Mail(List<String>paramList ) { if (paramList.Count < 1) { Message = "501 Syntax error in parameters scanning \"\""; return false; } if (paramList[0].ToUpper() != "FROM:") { Message = string.Format("501 5.5.2 Syntax error in parameters scanning {0}", paramList[0]); return false; } if (paramList.Count < 2) { Message = "501 Syntax error in parameters scanning \"\""; return false; } //\bをエラーではじく if (paramList[1].IndexOf('\b') != -1) { Message = "501 Syntax error in parameters scanning \"From\""; return false; } var mailAddress = new MailAddress(paramList[1]); if (mailAddress.User == "" && mailAddress.Domain == "") { //空白のFROM(MAIN From:<>)を許可するかどうかをチェックする if (!_useNullFrom) { Message = "501 Syntax error in parameters scanning \"From\""; return false; } } else { if (mailAddress.User == "") { Message = "501 Syntax error in parameters scanning \"MailAddress\""; return false; } //ドメイン名の無いFROMを許可するかどうかのチェック if (!_useNullDomain && mailAddress.Domain == "") { Message = string.Format("553 {0}... Domain part missing", paramList[1]); return false; } } Message = ""; return true; }
public String Get(MailAddress to,String host,Ip addr) { //ユニークなID文字列の生成 var uidStr = string.Format("bjd.{0:D20}.{1:D3}", DateTime.Now.Ticks, _idCounter++); //日付文字列の生成 var date = Util.LocalTime2Str(DateTime.Now); var str = ""; if (_headerStr != null) { str = _headerStr; //Ver5.0.0-b5 $aと$hをkernel.ChangeTag()に送る前に修正する str = Util.SwapStr("$a", addr.ToString(), str); str = Util.SwapStr("$h", host, str); str = Util.SwapStr("$i", uidStr, str); str = Util.SwapStr("$t", to.ToString(), str); str = Util.SwapStr("$d", date, str); str = _kernel.ChangeTag(str); } return str; }
public MlList(Kernel kernel,Server server,MailSave mailSave, List<string> domainList) { var optionMl = kernel.ListOption.Get("Ml"); //メーリングストの一覧を取得する var dat = (Dat) optionMl.GetValue("mlList"); if (dat != null){ foreach (var o2 in dat){ if (!o2.Enable) continue; //メーリングリスト名の読込 var mlName = o2.StrList[0]; var op = kernel.ListOption.Get("Ml-" + mlName); var logger = kernel.CreateLogger(mlName, (bool) op.GetValue("useDetailsLog"), server); var mlOption = new MlOption(kernel,op); //無効なメンバ指定の確認と警告 foreach (var d in mlOption.MemberList){ var mailAddress = new MailAddress(d.StrList[1]); //メールアドレス if (mailAddress.User != "" && mailAddress.Domain != "") continue; if (logger != null){ logger.Set(LogKind.Error, null, 53, string.Format("{0}", d.StrList[1])); } } if (mlOption.MemberList.Count == 0){ logger.Set(LogKind.Error, null, 57, string.Format("{0}", mlName)); continue; } var ml = new Ml(kernel, logger, mailSave, mlOption, mlName, domainList); //MLの管理領域の初期化に失敗している場合は、追加しない if (!ml.Status) continue; _ar.Add(ml); if (logger != null) logger.Set(LogKind.Normal, null, 44, mlName); } } }
public void DelTest(string users, string delUser, string searchUser, bool success) { //複数のユーザを追加 string[] ar = users.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var user in ar) { var addr = new MailAddress(string.Format("{0}@example.com", user)); _mlSubscribeDb.Add(addr, user); } //削除アドレス if (delUser != "") { var delAddr = new MailAddress(delUser, "example.com"); _mlSubscribeDb.Del(delAddr); } //検索アドレス var searchAddr = new MailAddress(searchUser, "example.com"); var o = _mlSubscribeDb.Search(searchAddr); if (success) { Assert.AreEqual(o.Name,searchUser); //Assert.IsNotNull(o); } else { Assert.IsNull(o); } }
//見つからないとき、nullを返す public OneSubscribe Search(MailAddress mailAddress) { lock (SyncObj) { for (var i = 0; i < _ar.Count; i++) { if (!mailAddress.Compare(_ar[i].MailAddress)) continue; if (_ar[i].Dt.AddMilliseconds(_effectiveMsec) > DateTime.Now) { return _ar[i];//経過時間内のデータなので有効 } _ar.RemoveAt(i);//経過時間を超えた情報は削除される return null; } return null; } }
//接続単位の処理 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(); }
//メール保存(MLとそれ以外を振り分ける) public bool MailSave2(MailAddress from, MailAddress to, Mail mail, string host, Ip addr) { //#if ML_SERVER if (_mlList.IsUser(to)) { var mlEnvelope = new MlEnvelope(from, to, host, addr); return _mlList.Job(mlEnvelope,mail); } else { //#endif return _mailSave.Save(from, to, mail, host, addr); //#if ML_SERVER } //#endif }
//検索 public MlOneUser Search(MailAddress mailAddress) { for (var i = 0; i < _ar.Count; i++) { if (_ar[i].MailAddress.Compare(mailAddress)){ return !_ar[i].Enable ? null : _ar[i]; } } return null; }
//「制御アドレス」宛の処理 void JobCtrl(MlEnvelope mlEnvelope, Mail mail, MlOneUser mlOneUser) { var adminLogin = false;//管理者としての認証が済んでいるかどうかのフラグ var log = new StringBuilder();//コマンドLog var mlCmd = new MlCmd(_logger, mail, mlOneUser);//コマンド解釈 //var envelopeAdmin = mlEnvelope.ChangeFrom(mlAddr.Admin); var envelopeReturn = mlEnvelope.Swap().ChangeFrom(_mlAddr.Admin); //コマンドの処理 foreach (OneMlCmd oneCmd in mlCmd) { //ログ出力 var memberStr = (oneCmd.MlOneUser == null) ? "not member" : oneCmd.MlOneUser.MailAddress.ToString(); var prompt = adminLogin ? "#" : "$"; var logStr = string.Format("{0}>{1} {2} [{3}]", prompt, oneCmd.CmdKind.ToString().ToLower(), oneCmd.ParamStr, memberStr); log.Append(logStr + "\r\n"); _logger.Set(LogKind.Detail, null, 41, logStr); //メンバーでない場合 if (mlOneUser == null) { //subscribe/confirm の場合 if (oneCmd.CmdKind == MlCmdKind.Subscribe || oneCmd.CmdKind == MlCmdKind.Confirm){ if (_autoRegistration) {//自動登録が有効の場合、処理対象になる goto ok; } } //メンバー外からのリクエストの場合、Guide以外は受け付けない if (oneCmd.CmdKind != MlCmdKind.Guide) { //投稿者にDenyメールを送信 _mlDevivery.Deny(mail, mlEnvelope); break; } } ok: //権限確認 return "" エラーなし var errStr = ""; switch (oneCmd.CmdKind) { case MlCmdKind.Guide: break; case MlCmdKind.Exit: case MlCmdKind.Quit: case MlCmdKind.Members: case MlCmdKind.Member: case MlCmdKind.Summary: case MlCmdKind.Subject: break; case MlCmdKind.Bye: case MlCmdKind.Unsubscribe: if (oneCmd.MlOneUser.IsManager) { errStr = _kernel.IsJp() ? "管理者は、このコマンドを使用できません" : "cannot use a manager"; } break; case MlCmdKind.Subscribe: case MlCmdKind.Confirm: if (mlOneUser != null){ errStr = _kernel.IsJp() ? "このコマンドはメンバー以外しか使用できません" : "cannot use a memeber"; } break; case MlCmdKind.Password: case MlCmdKind.Add: case MlCmdKind.Del: if (!oneCmd.MlOneUser.IsManager) {//管理者しか使用できない errStr = _kernel.IsJp() ? "このコマンドは管理者しか使用できません" : "net administrator"; } break; } if (errStr != "") {//権限に問題あり _logger.Set(LogKind.Error, null, 47, errStr); log.Append(errStr + "\r\n"); goto end; } //管理者ログイン確認 if (!adminLogin) { switch (oneCmd.CmdKind) { case MlCmdKind.Del: case MlCmdKind.Add: _logger.Set(LogKind.Error, null, 50, "The certification is not over"); log.Append(errStr + "\r\n"); goto end; } } //パラメータの処理 MlParamSpan mlParamSpan = null; switch (oneCmd.CmdKind) { case MlCmdKind.Get: case MlCmdKind.Summary: case MlCmdKind.Subject: mlParamSpan = new MlParamSpan(oneCmd.ParamStr, _mlMailDb.Count()); if (mlParamSpan.Start == -1) { errStr = _kernel.IsJp() ? "パラメータに矛盾がありあます" : "Appointment includes contradiction"; _logger.Set(LogKind.Error, null, 51, errStr); log.Append(errStr + "\r\n"); //ここエラーメールを返すようにする _mlDevivery.Error(mlEnvelope, string.Format("ERROR \"{0} {1}\"", oneCmd.CmdKind.ToString().ToUpper(),oneCmd.ParamStr)); goto end; } break; } switch (oneCmd.CmdKind) { case MlCmdKind.Bye: case MlCmdKind.Unsubscribe: //メンバーの削除 using (var dat = _mlUserList.Del(mlEnvelope.From)){ if (dat == null){ errStr = _kernel.IsJp() ? "メンバーの削除に失敗しました" : "Failed in delete of a member"; } else{ UpdateMemberList(dat);//memberListの更新 } } break; case MlCmdKind.Password: if (mlOneUser.Psssword == oneCmd.ParamStr) { adminLogin = true;//管理者として認証 } else { errStr = _kernel.IsJp() ? "パスワードが違います" : "A password is different"; } break; case MlCmdKind.Del: var tmp = oneCmd.ParamStr.Split(new char[] { ' ' }, 2); var mailAddress = new MailAddress(tmp[0]); //メンバーの削除 using (var dat = _mlUserList.Del(mailAddress)){ if (dat == null){ errStr = _kernel.IsJp() ? "メンバーの削除に失敗しました" : "Failed in addition of a member"; } else{ UpdateMemberList(dat);//memberListの更新 } } break; case MlCmdKind.Add: //メンバーの追加 var tmp2 = oneCmd.ParamStr.Split(new char[] { ' ' }, 2); var mailAddress2 = new MailAddress(tmp2[0]); var name = "USER";//表示名が指定されていない場合 if (tmp2.Length >= 2){ name = tmp2[1]; } if (null != _mlUserList.Search(mailAddress2)) { errStr = _kernel.IsJp() ? "既にメンバーが登録されています" : "There is already a member"; } else { using(var dat = _mlUserList.Add(mailAddress2, name)){ if (dat == null){ errStr = _kernel.IsJp() ? "メンバーの追加に失敗しました" : "Failed in addition of a member"; } else{ UpdateMemberList(dat);//memberListの更新 } } } break; case MlCmdKind.Subscribe: { var oneSubscribe = _mlSubscribeDb.Search(mlEnvelope.From); if (oneSubscribe == null) { oneSubscribe = _mlSubscribeDb.Add(mlEnvelope.From, oneCmd.ParamStr);//subscribeDbへの追加 } var confirmStr = string.Format("confirm {0} {1}", oneSubscribe.ConfirmStr, oneSubscribe.Name); _mlSender.Send(envelopeReturn, _mlCreator2.Confirm(confirmStr)); log.Length = 0;//ログメールの送信抑制 } break; case MlCmdKind.Confirm: { var success = false; var oneSubscribe = _mlSubscribeDb.Search(mlEnvelope.From); if (oneSubscribe != null) { //Ver6.0.1 var paramStr = string.Format("{0} {1}", oneSubscribe.ConfirmStr, oneSubscribe.Name); if (oneCmd.ParamStr == paramStr){ success = true; //認証成功 _mlSubscribeDb.Del(mlEnvelope.From); //subscribeDbの削除 if (_autoRegistration){ //自動登録の場合 //メンバーの追加 using (var dat = _mlUserList.Add(mlEnvelope.From, oneSubscribe.Name)){ if (dat != null){ UpdateMemberList(dat); //memberListの更新 //Welcodeメールの送信 _mlSender.Send(envelopeReturn, _mlCreator2.Welcome()); _logger.Set(LogKind.Detail, null, 46, mlEnvelope.From.ToString()); } else{ _logger.Set(LogKind.Detail, null, 48, mlEnvelope.From.ToString()); } } } else{ //管理者による登録 //管理者宛にconfirmが有ったことを連絡する var mlenv = mlEnvelope.ChangeFrom(_mlAddr.Admin).ChangeTo(_mlAddr.Admin); var appendStr = string.Format("{0} {1}", mlEnvelope.From, oneSubscribe.Name); _mlSender.Send(mlenv, _mlCreator2.Append(appendStr)); } } //confirm行の検索 //var confirmStr = string.Format("confirm {0} {1}", oneSubscribe.ConfirmStr, oneSubscribe.Name); //var lines = Inet.GetLines(mail.GetBody()); //foreach (var line in lines) { // var str = mail.GetEncoding().GetString(line); // if (str.IndexOf(confirmStr) != -1) { // success = true;//認証成功 // // _mlSubscribeDb.Del(mlEnvelope.From);//subscribeDbの削除 // // if (_autoRegistration) {//自動登録の場合 // //メンバーの追加 // using (var dat = _mlUserList.Add(mlEnvelope.From, oneSubscribe.Name)) { // if (dat != null){ // // UpdateMemberList(dat);//memberListの更新 // // //Welcodeメールの送信 // _mlSender.Send(envelopeReturn, _mlCreator2.Welcome()); // _logger.Set(LogKind.Detail, null, 46, mlEnvelope.From.ToString()); // // } // else{ // _logger.Set(LogKind.Detail, null, 48, mlEnvelope.From.ToString()); // } // } // } else { // //管理者による登録 // //管理者宛にconfirmが有ったことを連絡する // var mlenv = mlEnvelope.ChangeFrom(_mlAddr.Admin).ChangeTo(_mlAddr.Admin); // var appendStr = string.Format("{0} {1}", mlEnvelope.From, oneSubscribe.Name); // _mlSender.Send(mlenv, _mlCreator2.Append(appendStr)); // // } // } // } } if (!success) { //認証失敗 _mlSender.Send(envelopeReturn, _mlCreator2.Guide()); } } break; case MlCmdKind.Members: case MlCmdKind.Member: var sb = new StringBuilder(); foreach (var o in from MlOneUser o in _mlUserList where !o.IsManager select o){ sb.Append(string.Format("{0} {1}\r\n", o.MailAddress,o.Name)); } _mlSender.Send(envelopeReturn, _mlCreator2.Member(sb.ToString())); break; case MlCmdKind.Get: _mlDevivery.Get(mail, mlEnvelope, mlParamSpan); break; case MlCmdKind.Summary: case MlCmdKind.Subject: _mlDevivery.Summary(mail, mlEnvelope, mlParamSpan); break; case MlCmdKind.Guide: _mlDevivery.Doc(MlDocKind.Guide, mail, mlEnvelope); break; case MlCmdKind.Help: _mlDevivery.Doc(mlOneUser.IsManager ? MlDocKind.Admin : MlDocKind.Help, mail, mlEnvelope); break; case MlCmdKind.Exit: case MlCmdKind.Quit: goto end;//コマンド終了 } if (errStr != ""){ //コマンド実行にエラー発生 log.Append(string.Format("error! {0}\r\n", errStr)); _logger.Set(LogKind.Error, null, 49, errStr); goto end; } log.Append("success!\r\n"); } end: ; //ログが必要なコマンド時だけログを送信する //if (log.Length != 0) { // mlSender2.Send(envelopeAdmin,mlCreator2.Log(log.ToString())); //} }
//有効なあて先かどうかの確認 public bool IsUser(MailAddress mailAddress) { return _mlAddr.IsUser(mailAddress); }