예제 #1
0
        internal SmtpCommand MakeRcpt(TokenEnumerator enumerator)
        {
            enumerator.Consume(1);
            enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
            if (enumerator.Consume(1) != new Token(TokenKind.Text, "TO") || enumerator.Consume(1) != new Token(TokenKind.Punctuation, ":"))
            {
                return(MakeInvalid(SmtpReplyCode.SyntaxError, "missing the TO:"));
            }
            enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
            MailAddress address;

            return(!_parser.TryMakePath(enumerator, out address) ? MakeInvalid(SmtpReplyCode.SyntaxError, ""): new RcptCommand(address, _server.ValidateRecipient));
        }
예제 #2
0
 internal bool TryMakeAddressLiteral(TokenEnumerator enumerator, out string address)
 {
     address = null;
     if (enumerator.Consume(1) != new Token(TokenKind.Punctuation, "["))
     {
         return(false);
     }
     enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
     if (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeIpv4AddressLiteral), out address))
     {
         return(false);
     }
     enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
     return(!(enumerator.Consume(1) != new Token(TokenKind.Punctuation, "]")) && address != null);
 }
예제 #3
0
        internal bool TryMakeMailbox(TokenEnumerator enumerator, out MailAddress mailbox)
        {
            mailbox = null;
            string user;

            if (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeLocalPart), out user))
            {
                return(false);
            }
            if (enumerator.Consume(1) != new Token(TokenKind.Punctuation, "@"))
            {
                return(false);
            }
            string host;

            if (TryMake(enumerator, new TryMakeDelegate <string>(TryMakeDomain), out host))
            {
                mailbox = new MailAddress($"{user}@{host}");
                return(true);
            }
            string host2;

            if (TryMake(enumerator, new TryMakeDelegate <string>(TryMakeAddressLiteral), out host2))
            {
                mailbox = new MailAddress($"{user}@{host2}");
                return(true);
            }
            return(false);
        }
예제 #4
0
        internal bool TryMakePath(TokenEnumerator enumerator, out MailAddress mailbox)
        {
            mailbox = null;
            string text;

            return(!(enumerator.Consume(1) != new Token(TokenKind.Symbol, "<")) && (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeAtDomainList), out text) || !(enumerator.Consume(1) != new Token(TokenKind.Punctuation, ":"))) && TryMake <MailAddress>(enumerator, new TryMakeDelegate <MailAddress>(TryMakeMailbox), out mailbox) && enumerator.Consume(1) == new Token(TokenKind.Symbol, ">"));
        }
예제 #5
0
        internal bool TryMakeTextOrNumber(TokenEnumerator enumerator, out string textOrNumber)
        {
            Token token = enumerator.Consume(1);

            textOrNumber = token.Text;
            return(token.Kind == TokenKind.Text || token.Kind == TokenKind.Number);
        }
예제 #6
0
        internal SmtpCommand MakeHelo(TokenEnumerator enumerator)
        {
            enumerator.Consume(1);
            enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
            string domain;

            return(!_parser.TryMakeDomain(enumerator, out domain)? MakeInvalid(SmtpReplyCode.SyntaxError, "") : new HeloCommand(domain));
        }
예제 #7
0
 internal bool TryMakeReversePath(TokenEnumerator enumerator, out MailAddress mailbox)
 {
     if (TryMake <MailAddress>(enumerator, new TryMakeDelegate <MailAddress>(TryMakePath), out mailbox))
     {
         return(true);
     }
     if (enumerator.Consume(1) != new Token(TokenKind.Symbol, "<"))
     {
         return(false);
     }
     if (enumerator.Consume(1) != new Token(TokenKind.Symbol, ">"))
     {
         return(false);
     }
     mailbox = null;
     return(true);
 }
예제 #8
0
 internal SmtpCommand MakeStartTls(TokenEnumerator enumerator)
 {
     enumerator.Consume(1);
     enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
     if (enumerator.Count > 1)
     {
         return(MakeInvalid(SmtpReplyCode.SyntaxError, ""));
     }
     return(new StartTlsCommand(_server.ServerCertificate));
 }
예제 #9
0
 internal SmtpCommand MakeDbug(TokenEnumerator enumerator)
 {
     enumerator.Consume(1);
     enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
     if (enumerator.Count > 1)
     {
         return(MakeInvalid(SmtpReplyCode.SyntaxError, ""));
     }
     return(new DbugCommand());
 }
예제 #10
0
        internal SmtpCommand MakeAuth(TokenEnumerator enumerator)
        {
            enumerator.Consume(1);
            enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
            AuthenticationMethod method;

            if (!Enum.TryParse(enumerator.Peek(0).Text, true, out method))
            {
                return(MakeInvalid(SmtpReplyCode.SyntaxError, ""));
            }
            enumerator.Consume(1);
            string parameter = null;

            if (enumerator.Count > 0 && !_parser.TryMakeBase64(enumerator, out parameter))
            {
                return(MakeInvalid(SmtpReplyCode.SyntaxError, ""));
            }
            return(new AuthCommand(_server.UserAuthenticator, method, parameter));
        }
예제 #11
0
        internal bool TryMakeEsmtpKeyword(TokenEnumerator enumerator, out string keyword)
        {
            keyword = null;
            Token left = enumerator.Peek(0);

            while (left.Kind == TokenKind.Text || left.Kind == TokenKind.Number || left == new Token(TokenKind.Punctuation, "-"))
            {
                keyword += enumerator.Consume(1).Text;
                left     = enumerator.Peek(0);
            }
            return(keyword != null);
        }
예제 #12
0
        internal bool TryMakeTextOrNumberOrHyphenString(TokenEnumerator enumerator, out string textOrNumberOrHyphenString)
        {
            textOrNumberOrHyphenString = null;
            Token left = enumerator.Peek(0);

            while (left.Kind == TokenKind.Text || left.Kind == TokenKind.Number || left == new Token(TokenKind.Punctuation, "-"))
            {
                textOrNumberOrHyphenString += enumerator.Consume(1).Text;
                left = enumerator.Peek(0);
            }
            return(textOrNumberOrHyphenString != null && left != new Token(TokenKind.Punctuation, "-"));
        }
예제 #13
0
        internal SmtpCommand MakeMail(TokenEnumerator enumerator)
        {
            enumerator.Consume(1);
            enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
            if (enumerator.Consume(1) != new Token(TokenKind.Text, "FROM") || enumerator.Consume(1) != new Token(TokenKind.Punctuation, ":"))
            {
                return(MakeInvalid(SmtpReplyCode.SyntaxError, "missing the FROM:"));
            }
            enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);

            MailAddress address;

            if (!_parser.TryMakeReversePath(enumerator, out address))
            {
                return(MakeInvalid(SmtpReplyCode.SyntaxError, ""));
            }
            IDictionary <string, string> parameters;

            if (!_parser.TryMakeMailParameters(enumerator, out parameters))
            {
                parameters = new Dictionary <string, string>();
            }
            return(new MailCommand(address, parameters, _server.ValidateFrom, 0));
        }
예제 #14
0
        internal bool TryMakeEsmtpValue(TokenEnumerator enumerator, out string value)
        {
            value = null;
            Token token = enumerator.Peek(0);

            while (token.Text.Length > 0)
            {
                if (!token.Text.ToCharArray().All((char ch) => (ch >= '!' && ch <= 'B') || (ch >= '>' && ch <= '\u007f')))
                {
                    break;
                }
                value += enumerator.Consume(1).Text;
                token  = enumerator.Peek(0);
            }
            return(value != null);
        }
예제 #15
0
        internal bool TryMakeAtDomain(TokenEnumerator enumerator, out string atDomain)
        {
            atDomain = null;
            if (enumerator.Consume(1) != new Token(TokenKind.Punctuation, "@"))
            {
                return(false);
            }
            string arg;

            if (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeDomain), out arg))
            {
                return(false);
            }
            atDomain = string.Format("@{0}", arg);
            return(true);
        }
예제 #16
0
 internal bool TryMakeAtDomainList(TokenEnumerator enumerator, out string atDomainList)
 {
     if (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeAtDomain), out atDomainList))
     {
         return(false);
     }
     while (enumerator.Peek(0) == new Token(TokenKind.Punctuation, ","))
     {
         enumerator.Consume(1);
         string arg;
         if (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeAtDomain), out arg))
         {
             return(false);
         }
         atDomainList += string.Format(",{0}", arg);
     }
     return(true);
 }
예제 #17
0
        internal SmtpCommand MakeEhlo(TokenEnumerator enumerator)
        {
            enumerator.Consume(1);
            enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
            string domainOrAddress;

            if (_parser.TryMakeDomain(enumerator, out domainOrAddress))
            {
                return(new EhloCommand(domainOrAddress, _server));
            }
            string domainOrAddress2;

            if (_parser.TryMakeAddressLiteral(enumerator, out domainOrAddress2))
            {
                return(new EhloCommand(domainOrAddress2, _server));
            }
            return(MakeInvalid(SmtpReplyCode.SyntaxError, ""));
        }
예제 #18
0
 internal bool TryMakeDotString(TokenEnumerator enumerator, out string dotString)
 {
     if (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeAtom), out dotString))
     {
         return(false);
     }
     while (enumerator.Peek(0) == new Token(TokenKind.Punctuation, "."))
     {
         enumerator.Consume(1);
         string str;
         if (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeAtom), out str))
         {
             return(true);
         }
         dotString += "." + str;
     }
     return(true);
 }
예제 #19
0
        internal bool TryMakeEsmtpParameter(TokenEnumerator enumerator, out KeyValuePair <string, string> parameter)
        {
            parameter = default(KeyValuePair <string, string>);
            string key;

            if (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeEsmtpKeyword), out key))
            {
                return(false);
            }
            if (enumerator.Consume(1) != new Token(TokenKind.Symbol, "="))
            {
                return(false);
            }
            string value;

            if (!TryMake <string>(enumerator, new TryMakeDelegate <string>(TryMakeEsmtpValue), out value))
            {
                return(false);
            }
            parameter = new KeyValuePair <string, string>(key, value);
            return(true);
        }
예제 #20
0
        private static bool TryMakeBase64Chars(TokenEnumerator enumerator, out string base64Chars)
        {
            base64Chars = null;
            Token token = enumerator.Consume(1);

            switch (token.Kind)
            {
            case TokenKind.Text:
            case TokenKind.Number:
                base64Chars = token.Text;
                return(true);

            case TokenKind.Symbol:
            {
                char c = token.Text[0];
                if (c == '+')
                {
                    base64Chars = token.Text;
                    return(true);
                }
                break;
            }

            case TokenKind.Punctuation:
            {
                char c2 = token.Text[0];
                if (c2 == '/')
                {
                    base64Chars = token.Text;
                    return(true);
                }
                break;
            }
            }
            return(false);
        }
예제 #21
0
        internal bool TryMakeIpv4AddressLiteral(TokenEnumerator enumerator, out string address)
        {
            address = null;
            int num;

            if (!TryMake <int>(enumerator, new TryMakeDelegate <int>(TryMakeSnum), out num))
            {
                return(false);
            }
            address = num.ToString(CultureInfo.InvariantCulture);
            int num2 = 0;

            while (num2 < 3 && enumerator.Peek(0) == new Token(TokenKind.Punctuation, "."))
            {
                enumerator.Consume(1);
                if (!TryMake <int>(enumerator, new TryMakeDelegate <int>(TryMakeSnum), out num))
                {
                    return(false);
                }
                address = address + '.' + num;
                num2++;
            }
            return(true);
        }
예제 #22
0
 internal SmtpCommand MakeRset(TokenEnumerator enumerator)
 {
     enumerator.Consume(1);
     enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
     return(enumerator.Count > 1 ? MakeInvalid(SmtpReplyCode.SyntaxError, ""): new RsetCommand());
 }
예제 #23
0
 internal SmtpCommand MakeData(TokenEnumerator enumerator)
 {
     enumerator.Consume(1);
     enumerator.ConsumeWhile((Token t) => t.Kind == TokenKind.Space);
     return(enumerator.Count > 1 ? MakeInvalid(SmtpReplyCode.SyntaxError, ""): new DataCommand(_server.OnMessageArrived));
 }
예제 #24
0
        internal bool TryMakeSnum(TokenEnumerator enumerator, out int snum)
        {
            Token token = enumerator.Consume(1);

            return(int.TryParse(token.Text, out snum) && token.Kind == TokenKind.Number && snum >= 0 && snum <= 255);
        }
예제 #25
0
        internal bool TryMakeAtext(TokenEnumerator enumerator, out string atext)
        {
            atext = null;
            Token token = enumerator.Consume(1);

            switch (token.Kind)
            {
            case TokenKind.Text:
            case TokenKind.Number:
                atext = token.Text;
                return(true);

            case TokenKind.Symbol:
            {
                char c = token.Text[0];
                if (c <= '+')
                {
                    if (c != '$' && c != '+')
                    {
                        break;
                    }
                }
                else
                {
                    if (c != '=')
                    {
                        switch (c)
                        {
                        case '^':
                        case '`':
                            break;

                        case '_':
                            return(false);

                        default:
                            switch (c)
                            {
                            case '|':
                            case '~':
                                break;

                            case '}':
                                return(false);

                            default:
                                return(false);
                            }
                            break;
                        }
                    }
                }
                atext = token.Text;
                return(true);
            }

            case TokenKind.Punctuation:
            {
                char c2 = token.Text[0];
                if (c2 <= '?')
                {
                    switch (c2)
                    {
                    case '!':
                    case '#':
                    case '%':
                    case '&':
                    case '\'':
                    case '*':
                    case '-':
                    case '/':
                        break;

                    case '"':
                    case '$':
                    case '(':
                    case ')':
                    case '+':
                    case ',':
                    case '.':
                        return(false);

                    default:
                        if (c2 != '?')
                        {
                            return(false);
                        }
                        break;
                    }
                }
                else
                {
                    if (c2 != '_')
                    {
                        switch (c2)
                        {
                        case '{':
                        case '}':
                            break;

                        case '|':
                            return(false);

                        default:
                            return(false);
                        }
                    }
                }
                atext = token.Text;
                return(true);
            }
            }
            return(false);
        }