Skip to content

Instantly share code, notes, and snippets.

@monkeym4ster
Created October 18, 2017 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monkeym4ster/e20d4ac76070370e739dea7388ce979b to your computer and use it in GitHub Desktop.
Save monkeym4ster/e20d4ac76070370e739dea7388ce979b to your computer and use it in GitHub Desktop.
Email address verification
import Dns from 'dns'
import Net from 'net'
class VerifyMail {
constructor (email) {
this.email = email
}
fetchMx (domain) {
return new Promise((resolve, reject) => {
Dns.setServers(['223.5.5.5', '223.6.6.6'])
Dns.resolveMx(domain, (err, data) => {
if (err) return reject(err)
return resolve(data)
})
})
}
sendMSG1(socket) {
return new Promise((resolve, reject) => {
console.log('=> HELO verify-email')
socket.write('HELO verify-email\r\n', resolve)
})
}
sendMSG2(socket) {
return new Promise((resolve, reject) => {
const from = 'verify-email@gmail.com'
console.log(`=> MAIL FROM: <${from}>`)
socket.write(`MAIL FROM: <${from}>\r\n`, resolve)
})
}
sendMSG3(socket) {
return new Promise((resolve, reject) => {
console.log(`=> RCPT TO: <${this.email}>`)
socket.write(`RCPT TO: <${this.email}>\r\n`, resolve)
})
}
sendMSG4(socket) {
return new Promise((resolve, reject) => {
console.log(`=> QUIT`)
socket.write(`QUIT\r\n`, resolve)
})
}
verify (email, domain) {
return new Promise((resolve, reject) => {
let data = Buffer('')
const socket = Net.connect(25, domain)
socket.on('error', err => {
console.error('err', `* Connection STMP server failed, ${err.message}`)
return reject(err)
})
socket.on('data', (chunk) => {
console.log(`<= ${chunk.toString('utf8').trim()}`)
data = Buffer.concat([data, chunk])
})
socket.on('connect', async () => {
console.log(`* Connection succeeded to ${domain} SMTP.`)
await this.sendMSG1(socket)
await this.sendMSG2(socket)
await this.sendMSG3(socket)
await this.sendMSG4(socket)
})
socket.on('end', () => {
const verify = !data.toString('utf8').includes('550')
console.log(`\n* ${this.email} - Result: ${verify ? 'Success': 'Bad'}`)
return resolve(verify)
})
})
}
async run () {
const email = this.email
const domain = email.split('@')[1]
try {
const mxList = await this.fetchMx(domain)
const mx = mxList[0].exchange
console.log(`* MX record about ${domain} is ${mx}.`)
return this.verify(email, mx)
} catch (err) {
console.log(`* Fetch MX record about ${domain} failed. ${err.message}`)
throw err
}
}
}
const EMAIL = 'admin@qq.com'
console.log(`* Target email: ${EMAIL}`)
const verifyMail = new VerifyMail(EMAIL)
verifyMail.run()
@monkeym4ster
Copy link
Author

monkeym4ster commented Oct 18, 2017

验证原理

MX record found: mx3.qq.com (Priority 10)
MX record found: mx2.qq.com (Priority 20)
MX record found: mx1.qq.com (Priority 30)
Connecting to mx3.qq.com
Connected to mx3.qq.com
Dialog with mx3.qq.com ok
------------------------------------------------------------
220 newusamx25.qq.com MX QQ Mail Server
HELO verifyemailaddress.org
250 newusamx25.qq.com
MAIL FROM: <noreply@verifyemailaddress.org>
250 Ok
RCPT TO: <master@qq.com>
550 Mailbox not found. http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000728
QUIT
------------------------------------------------------------
Email address master@qq.com rejected

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment