Utilities/PasswordChecker.py

changeset 2997
7f0ef975da9e
parent 2965
d133c7edd88a
child 3034
7ce719013078
child 3057
10516539f238
equal deleted inserted replaced
2996:c6f16f1b9958 2997:7f0ef975da9e
82 82
83 # how much redundancy is permitted, if the password is 83 # how much redundancy is permitted, if the password is
84 # long enough. we will skip the redudancy penalty if this 84 # long enough. we will skip the redudancy penalty if this
85 # number is not exceeded (meaning redundancy < this number) 85 # number is not exceeded (meaning redundancy < this number)
86 self.redundancy = { 86 self.redundancy = {
87 "value": 1, # 1 means, not double characters, default to start 87 "value": 1, # 1 means, not double characters,
88 "permitted": 2.0, # 2 means, in average every character can occur twice 88 # default to start
89 "permitted": 2.0, # 2 means, in average every character
90 # can occur twice
89 "status": self.Status_Failed, 91 "status": self.Status_Failed,
90 "rating": 0, 92 "rating": 0,
91 } 93 }
92 94
93 # number of uppercase letters, such as A-Z 95 # number of uppercase letters, such as A-Z
314 uniqueCharacters.append(password[index1]) 316 uniqueCharacters.append(password[index1])
315 317
316 # calculate a redundancy number 318 # calculate a redundancy number
317 self.redundancy["value"] = len(password) / len(uniqueCharacters) 319 self.redundancy["value"] = len(password) / len(uniqueCharacters)
318 320
319 # Check for sequential alpha string patterns (forward and reverse) but only, 321 # Check for sequential alpha string patterns (forward and reverse)
320 # if the string has already a length to check for, does not make sense to check 322 # but only, if the string has already a length to check for, does
321 # the password "ab" for the sequential data "abc" 323 # not make sense to check the password "ab" for the sequential data
324 # "abc"
322 lowercasedPassword = password.lower() 325 lowercasedPassword = password.lower()
323 326
324 if self.passwordLength["count"] >= self.sequentialLetters["length"]: 327 if self.passwordLength["count"] >= self.sequentialLetters["length"]:
325 for index in range(len(self.sequentialLetters["data"]) - \ 328 for index in range(len(self.sequentialLetters["data"]) - \
326 self.sequentialLetters["length"] + 1): 329 self.sequentialLetters["length"] + 1):
346 349
347 # Check common keyboard patterns 350 # Check common keyboard patterns
348 patternsMatched = [] 351 patternsMatched = []
349 if self.passwordLength["count"] >= self.keyboardPatterns["length"]: 352 if self.passwordLength["count"] >= self.keyboardPatterns["length"]:
350 for pattern in self.keyboardPatterns["data"]: 353 for pattern in self.keyboardPatterns["data"]:
351 for index in range(len(pattern) - self.keyboardPatterns["length"] + 1): 354 for index in range(
352 fwd = pattern[index:index + self.keyboardPatterns["length"]] 355 len(pattern) - self.keyboardPatterns["length"] + 1):
356 fwd = pattern[index:index +
357 self.keyboardPatterns["length"]]
353 rev = self.__strReverse(fwd) 358 rev = self.__strReverse(fwd)
354 if lowercasedPassword.find(fwd) != -1: 359 if lowercasedPassword.find(fwd) != -1:
355 if fwd not in patternsMatched: 360 if fwd not in patternsMatched:
356 self.keyboardPatterns["count"] += 1 361 self.keyboardPatterns["count"] += 1
357 patternsMatched.append(fwd) 362 patternsMatched.append(fwd)
362 367
363 # Try to find repeated sequences of characters. 368 # Try to find repeated sequences of characters.
364 if self.passwordLength["count"] >= self.repeatedSequences["length"]: 369 if self.passwordLength["count"] >= self.repeatedSequences["length"]:
365 for index in range(len(lowercasedPassword) - \ 370 for index in range(len(lowercasedPassword) - \
366 self.repeatedSequences["length"] + 1): 371 self.repeatedSequences["length"] + 1):
367 fwd = lowercasedPassword[index:index + self.repeatedSequences["length"]] 372 fwd = lowercasedPassword[
373 index:index + self.repeatedSequences["length"]]
368 if lowercasedPassword.find( 374 if lowercasedPassword.find(
369 fwd, index + self.repeatedSequences["length"]) != -1: 375 fwd, index + self.repeatedSequences["length"]) != -1:
370 self.repeatedSequences["count"] += 1 376 self.repeatedSequences["count"] += 1
371 377
372 # Try to find mirrored sequences of characters. 378 # Try to find mirrored sequences of characters.
373 if self.passwordLength["count"] >= self.mirroredSequences["length"]: 379 if self.passwordLength["count"] >= self.mirroredSequences["length"]:
374 for index in range(len(lowercasedPassword) - \ 380 for index in range(len(lowercasedPassword) - \
375 self.mirroredSequences["length"] + 1): 381 self.mirroredSequences["length"] + 1):
376 fwd = lowercasedPassword[index:index + self.mirroredSequences["length"]] 382 fwd = lowercasedPassword[
383 index:index + self.mirroredSequences["length"]]
377 rev = self.__strReverse(fwd) 384 rev = self.__strReverse(fwd)
378 if lowercasedPassword.find( 385 if lowercasedPassword.find(
379 fwd, index + self.mirroredSequences["length"]) != -1: 386 fwd, index + self.mirroredSequences["length"]) != -1:
380 self.mirroredSequences["count"] += 1 387 self.mirroredSequences["count"] += 1
381 388
382 # Initial score based on length 389 # Initial score based on length
383 self.score["count"] = self.passwordLength["count"] * self.passwordLength["factor"] 390 self.score["count"] = self.passwordLength["count"] * \
391 self.passwordLength["factor"]
384 392
385 # passwordLength 393 # passwordLength
386 # credit additional length or punish "under" length 394 # credit additional length or punish "under" length
387 if self.passwordLength["count"] >= self.passwordLength["minimum"]: 395 if self.passwordLength["count"] >= self.passwordLength["minimum"]:
388 # credit additional characters over minimum 396 # credit additional characters over minimum
389 self.passwordLength["rating"] = self.passwordLength["bonus"] + \ 397 self.passwordLength["rating"] = self.passwordLength["bonus"] + \
390 (self.passwordLength["count"] - self.passwordLength["minimum"]) * \ 398 (self.passwordLength["count"] -
399 self.passwordLength["minimum"]) * \
391 self.passwordLength["factor"] 400 self.passwordLength["factor"]
392 else: 401 else:
393 self.passwordLength["rating"] = self.passwordLength["penalty"] 402 self.passwordLength["rating"] = self.passwordLength["penalty"]
394 self.score["count"] += self.passwordLength["rating"] 403 self.score["count"] += self.passwordLength["rating"]
395 404
396 # recommendedPasswordLength 405 # recommendedPasswordLength
397 # Credit reaching the recommended password length or put a 406 # Credit reaching the recommended password length or put a
398 # penalty on it 407 # penalty on it
399 if self.passwordLength["count"] >= self.recommendedPasswordLength["minimum"]: 408 if self.passwordLength["count"] >= \
409 self.recommendedPasswordLength["minimum"]:
400 self.recommendedPasswordLength["rating"] = \ 410 self.recommendedPasswordLength["rating"] = \
401 self.recommendedPasswordLength["bonus"] + \ 411 self.recommendedPasswordLength["bonus"] + \
402 (self.passwordLength["count"] - \ 412 (self.passwordLength["count"] - \
403 self.recommendedPasswordLength["minimum"]) * \ 413 self.recommendedPasswordLength["minimum"]) * \
404 self.recommendedPasswordLength["factor"] 414 self.recommendedPasswordLength["factor"]
408 self.score["count"] += self.recommendedPasswordLength["rating"] 418 self.score["count"] += self.recommendedPasswordLength["rating"]
409 419
410 # lowercaseLetters 420 # lowercaseLetters
411 # Honor or punish the lowercase letter use 421 # Honor or punish the lowercase letter use
412 if self.lowercaseLetters["count"] > 0: 422 if self.lowercaseLetters["count"] > 0:
413 self.lowercaseLetters["rating"] = self.lowercaseLetters["bonus"] + \ 423 self.lowercaseLetters["rating"] = \
414 self.lowercaseLetters["count"] * self.lowercaseLetters["factor"] 424 self.lowercaseLetters["bonus"] + \
425 self.lowercaseLetters["count"] * \
426 self.lowercaseLetters["factor"]
415 else: 427 else:
416 self.lowercaseLetters["rating"] = self.lowercaseLetters["penalty"] 428 self.lowercaseLetters["rating"] = self.lowercaseLetters["penalty"]
417 self.score["count"] += self.lowercaseLetters["rating"] 429 self.score["count"] += self.lowercaseLetters["rating"]
418 430
419 # uppercaseLetters 431 # uppercaseLetters
420 # Honor or punish the lowercase letter use 432 # Honor or punish the lowercase letter use
421 if self.uppercaseLetters["count"] > 0: 433 if self.uppercaseLetters["count"] > 0:
422 self.uppercaseLetters["rating"] = self.uppercaseLetters["bonus"] + \ 434 self.uppercaseLetters["rating"] = \
423 self.uppercaseLetters["count"] * self.uppercaseLetters["factor"] 435 self.uppercaseLetters["bonus"] + \
436 self.uppercaseLetters["count"] * \
437 self.uppercaseLetters["factor"]
424 else: 438 else:
425 self.uppercaseLetters["rating"] = self.uppercaseLetters["penalty"] 439 self.uppercaseLetters["rating"] = self.uppercaseLetters["penalty"]
426 self.score["count"] += self.uppercaseLetters["rating"] 440 self.score["count"] += self.uppercaseLetters["rating"]
427 441
428 # numerics 442 # numerics
462 self.score["count"] += self.middleNumerics["rating"] 476 self.score["count"] += self.middleNumerics["rating"]
463 477
464 # sequentialLetters 478 # sequentialLetters
465 # Honor or punish the sequential letter use 479 # Honor or punish the sequential letter use
466 if self.sequentialLetters["count"] == 0: 480 if self.sequentialLetters["count"] == 0:
467 self.sequentialLetters["rating"] = self.sequentialLetters["bonus"] + \ 481 self.sequentialLetters["rating"] = \
468 self.sequentialLetters["count"] * self.sequentialLetters["factor"] 482 self.sequentialLetters["bonus"] + \
469 else: 483 self.sequentialLetters["count"] * \
470 self.sequentialLetters["rating"] = self.sequentialLetters["penalty"] 484 self.sequentialLetters["factor"]
485 else:
486 self.sequentialLetters["rating"] = \
487 self.sequentialLetters["penalty"]
471 self.score["count"] += self.sequentialLetters["rating"] 488 self.score["count"] += self.sequentialLetters["rating"]
472 489
473 # sequentialNumerics 490 # sequentialNumerics
474 # Honor or punish the sequential numerics use 491 # Honor or punish the sequential numerics use
475 if self.sequentialNumerics["count"] == 0: 492 if self.sequentialNumerics["count"] == 0:
476 self.sequentialNumerics["rating"] = self.sequentialNumerics["bonus"] + \ 493 self.sequentialNumerics["rating"] = \
477 self.sequentialNumerics["count"] * self.sequentialNumerics["factor"] 494 self.sequentialNumerics["bonus"] + \
478 else: 495 self.sequentialNumerics["count"] * \
479 self.sequentialNumerics["rating"] = self.sequentialNumerics["penalty"] 496 self.sequentialNumerics["factor"]
497 else:
498 self.sequentialNumerics["rating"] = \
499 self.sequentialNumerics["penalty"]
480 self.score["count"] += self.sequentialNumerics["rating"] 500 self.score["count"] += self.sequentialNumerics["rating"]
481 501
482 # keyboardPatterns 502 # keyboardPatterns
483 # Honor or punish the keyboard patterns use 503 # Honor or punish the keyboard patterns use
484 if self.keyboardPatterns["count"] == 0: 504 if self.keyboardPatterns["count"] == 0:
485 self.keyboardPatterns["rating"] = self.keyboardPatterns["bonus"] + \ 505 self.keyboardPatterns["rating"] = \
486 self.keyboardPatterns["count"] * self.keyboardPatterns["factor"] 506 self.keyboardPatterns["bonus"] + \
507 self.keyboardPatterns["count"] * \
508 self.keyboardPatterns["factor"]
487 else: 509 else:
488 self.keyboardPatterns["rating"] = self.keyboardPatterns["penalty"] 510 self.keyboardPatterns["rating"] = self.keyboardPatterns["penalty"]
489 self.score["count"] += self.keyboardPatterns["rating"] 511 self.score["count"] += self.keyboardPatterns["rating"]
490 512
491 # Count our basicRequirements and set the status 513 # Count our basicRequirements and set the status
526 # requirement met 548 # requirement met
527 self.basicRequirements["count"] += 1 549 self.basicRequirements["count"] += 1
528 550
529 # judge the requirement status 551 # judge the requirement status
530 self.basicRequirements["status"] = self.__determineStatus( 552 self.basicRequirements["status"] = self.__determineStatus(
531 self.basicRequirements["count"] - self.basicRequirements["minimum"]) 553 self.basicRequirements["count"] -
554 self.basicRequirements["minimum"])
532 if self.basicRequirements["status"] != self.Status_Failed: 555 if self.basicRequirements["status"] != self.Status_Failed:
533 self.basicRequirements["rating"] = \ 556 self.basicRequirements["rating"] = \
534 self.basicRequirements["bonus"] + \ 557 self.basicRequirements["bonus"] + \
535 self.basicRequirements["factor"] * self.basicRequirements["count"] 558 self.basicRequirements["factor"] * \
536 else: 559 self.basicRequirements["count"]
537 self.basicRequirements["rating"] = self.basicRequirements["penalty"] 560 else:
561 self.basicRequirements["rating"] = \
562 self.basicRequirements["penalty"]
538 self.score["count"] += self.basicRequirements["rating"] 563 self.score["count"] += self.basicRequirements["rating"]
539 564
540 # beyond basic requirements 565 # beyond basic requirements
541 self.recommendedPasswordLength["status"] = self.__determineStatus( 566 self.recommendedPasswordLength["status"] = self.__determineStatus(
542 self.recommendedPasswordLength["count"] - \ 567 self.recommendedPasswordLength["count"] - \
561 # we apply them only, if the length is not awesome 586 # we apply them only, if the length is not awesome
562 if self.recommendedPasswordLength["status"] != self.Status_Exceeded: 587 if self.recommendedPasswordLength["status"] != self.Status_Exceeded:
563 # repeatedSequences 588 # repeatedSequences
564 # Honor or punish the use of repeated sequences 589 # Honor or punish the use of repeated sequences
565 if self.repeatedSequences["count"] == 0: 590 if self.repeatedSequences["count"] == 0:
566 self.repeatedSequences["rating"] = self.repeatedSequences["bonus"] 591 self.repeatedSequences["rating"] = \
592 self.repeatedSequences["bonus"]
567 else: 593 else:
568 self.repeatedSequences["rating"] = self.repeatedSequences["penalty"] + \ 594 self.repeatedSequences["rating"] = \
595 self.repeatedSequences["penalty"] + \
569 self.repeatedSequences["count"] * \ 596 self.repeatedSequences["count"] * \
570 self.repeatedSequences["factor"] 597 self.repeatedSequences["factor"]
571 598
572 # mirroredSequences 599 # mirroredSequences
573 # Honor or punish the use of mirrored sequences 600 # Honor or punish the use of mirrored sequences
574 if self.mirroredSequences["count"] == 0: 601 if self.mirroredSequences["count"] == 0:
575 self.mirroredSequences["rating"] = self.mirroredSequences["bonus"] 602 self.mirroredSequences["rating"] = \
603 self.mirroredSequences["bonus"]
576 else: 604 else:
577 self.mirroredSequences["rating"] = self.mirroredSequences["penalty"] + \ 605 self.mirroredSequences["rating"] = \
606 self.mirroredSequences["penalty"] + \
578 self.mirroredSequences["count"] * \ 607 self.mirroredSequences["count"] * \
579 self.mirroredSequences["factor"] 608 self.mirroredSequences["factor"]
580 609
581 # save value before redundancy 610 # save value before redundancy
582 self.score["beforeRedundancy"] = self.score["count"] 611 self.score["beforeRedundancy"] = self.score["count"]
583 612
584 # apply the redundancy 613 # apply the redundancy
585 # is the password length requirement fulfilled? 614 # is the password length requirement fulfilled?
586 if self.recommendedPasswordLength["status"] != self.Status_Exceeded: 615 if self.recommendedPasswordLength["status"] != self.Status_Exceeded:
587 # full penalty, because password is not long enough, only for a positive score 616 # full penalty, because password is not long enough, only for
617 # a positive score
588 if self.score["count"] > 0: 618 if self.score["count"] > 0:
589 self.score["count"] *= 1.0 / self.redundancy["value"] 619 self.score["count"] *= 1.0 / self.redundancy["value"]
590 620
591 # level it out 621 # level it out
592 if self.score["count"] > 100: 622 if self.score["count"] > 100:

eric ide

mercurial