Jump to content

Search within a variable for a case insensitive match from a second variable to see if they contain the same word/phrase


Recommended Posts

Hello!

 

This is my first time ever posting here.  I've been following these forums for several years and have always been able to figure out what I've needed to do thanks to the wonderful posts made by the community, until yesterday.  I'm trying to write a small script that will prompt a user to enter an email address and password, then check to make sure that this password meets the complexity requirements.  I have every feature working so far except for one.

 

The script checks for an uppercase and lowercase letter, number or symbol and a minimum/maximum length correctly.  What I cannot figure out how to do is to verify that the password does not contain a portion of the email address.  Example: if the email contains bob@email.com and the password contains BobIsSecure!23 then I'd like a function that will see everything before the @ and say woah woah, your password is bad.

 

I am not a programmer, just in IT, so I apologize if the below just makes someone ill just looking at it.  I've removed the portion of the script that checks to see if the folder below exists and then creates it if not then pulls a copy of the blacklist file into that folder after the fact.  I felt that portion of the code wasn't relevant so if someone wants to download and tinker they'd need to create a folder structure as follows or point the file location to a new place:      c:\users\user\Autoit\Blacklist\blacklist.txt      and then put like 123456 or something in there to have the blacklist search function to work.  Honestly the blacklist portion isn't 100% perfect either - if the password/blacklist are a 1:1 match like 123456 or baconbits it'll work but if the user password is Baconbits it won't find a match.

 

#include <File.au3>
#include <AutoItConstants.au3>
#include <Constants.au3>
#include <String.au3>
#include <StringConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

;Declare local variable $HomeFolder to equal the home drive (C:\) and then combine it with the user's home directory with & (@HomeDrive & @HomePath)
Local $HomeFolder = @HomeDrive & @HomePath

;Declare variable to set file location of the blacklist.txt
$filepath = ($HomeFolder & "\Autoit\Blacklist\blacklist.txt")

;Declare variable $file to open the blacklist file
$file = FileOpen($HomeFolder & "\Autoit\Blacklist\blacklist.txt", 0)

;Declare variable $read to perform the FileOpen on the blacklist file
$read = FileRead($file)


#Region
$Form1 = GUICreate("Password Checker", 332, 126, 373, 136)
$InfoTextBlock = GUICtrlCreateLabel("Enter the email and password to check below", 54, 8, 219, 17)
$EmailAddressBox = GUICtrlCreateInput("Address", 91, 32, 153, 21)
$PasswordBox = GUICtrlCreateInput("Password", 90, 63, 153, 21)
$CheckButton = GUICtrlCreateButton("Check!", 50, 89, 113, 25)
$CancelButton = GUICtrlCreateButton("Cancel", 168, 89, 113, 25)
GUISetState(@SW_SHOW)
#EndRegion

Func CheckExistsBlacklistFile()
    ;Check to make sure the blacklist.txt can be found/read from, exit otherwise
    If Not FileExists($filepath) Then
        MsgBox(0, "Validation failed!", "The blacklist file is missing, cannot validate the password! Please contact Batman!")
        Exit
    EndIf
EndFunc   ;==>CheckExistsBlacklistFile

Func uppercheck()
    $password = GUICtrlRead($PasswordBox)
    $UpperCaseCheck = StringRegExp($password, '[A-Z\s]+', 0)
    If $UpperCaseCheck = 0 Then
        MsgBox(0, "Uppercase check results", "Uppercase letter not detected.  Please suggest another password.")
        Exit
    EndIf
EndFunc   ;==>uppercheck

Func lowercheck()
    ;Lowercase check begin
    $password = GUICtrlRead($PasswordBox)
    $LowerCaseCheck = StringRegExp($password, '[a-z\s]+', 0)
    If $LowerCaseCheck = 0 Then
        MsgBox(0, "Lowercase check results", "Lowercase letter not detected.  Please suggest another password.")
        Exit
    EndIf
EndFunc   ;==>lowercheck

Func symbolcheck()
    ;Symbol check begin
    $password = GUICtrlRead($PasswordBox)
    $SymbolCheck = StringRegExp($password, '[0-9\W]+', 0)
    If $SymbolCheck = 0 Then
        MsgBox(0, "Symbol check results", "Symbol not detected.  Please suggest another password.")
        Exit
    EndIf
EndFunc   ;==>symbolcheck

Func blacklistcheck()
    ;If the blacklist.txt was found, blacklistcheck function opens the file for reading and performs a regex search on the input $password variable to check for a matching blacklisted word/term.
    $password = GUICtrlRead($PasswordBox)
    If StringRegExp($read, $password) Then
        MsgBox(0, "Password Invalid", "Password contains a commonly used word/number combination and is invalid.  Please suggest a new password!")
        Exit
    EndIf
EndFunc   ;==>blacklistcheck

Func PasswordLengthCheck()
    ;Use StringLen to count the number of characters in the password.  If it is less than 6 or more than 40 then return error to user.
    $password = GUICtrlRead($PasswordBox)
    If StringLen($password) < 6 Then
        MsgBox(0, "Password too short", "Please suggest a password at least six characters long.")
        Exit
    EndIf
    If StringLen($password) > 40 Then
        MsgBox(0, "Password too long.", "Please suggest a password less than forty characters long.")
        Exit
    EndIf
EndFunc   ;==>PasswordLengthCheck

Func EmailPasswordCompare()
    $password = GUICtrlRead($PasswordBox)
    $emailpassword = GUICtrlRead($EmailAddressBox)
    If StringRegExp($password, $emailpassword) Then
        MsgBox(0, "Password invalid", "Password cannot contain a portion of the email address!  Example - if the email address is bob@etex.net, the password cannot be Bob123!")
        Exit
    EndIf
EndFunc   ;==>EmailPasswordCompare

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

        Case ($CancelButton)
            Exit
        Case ($CheckButton)
            Call(CheckExistsBlacklistFile)
            Call(PasswordLengthCheck)
            Call(blacklistcheck)
            Call(uppercheck)
            Call(lowercheck)
            Call(symbolcheck)
            Call(EmailPasswordCompare)
            MsgBox(0, "Password is Valid", "The password passed all the complexity requirement checks.  The password has been copied into the clipboard to enter into the system.")
            $password = GUICtrlRead($PasswordBox)
            ClipPut($password)
            FileClose($file)
            Exit
    EndSwitch

WEnd

 

PassCheck.au3

Link to comment
Share on other sites

this checks if everything to the left of @ also appears in the password, or do you want to check even just a portion of the email address?

If StringInStr($password, StringLeft($emailpassword, StringInStr($emailpassword, "@") - 1)) Then
        MsgBox(0, "Password invalid", "Password cannot contain a portion of the email address!  Example - if the email address is bob@etex.net, the password cannot be Bob123!")
        Exit
    EndIf

 

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Hi @Sellonis, and a cool welcome to the AutoIt forum! :welcome:
This is one of many flavours (before a cat shows up):

ConsoleWrite(ValidatePassword("Someone@something.it", "WhatPasswordIsTh1s@") & @CRLF)
ConsoleWrite(ValidatePassword("Someone@something.it", "SomeoneNot@g00dPassword") & @CRLF)
ConsoleWrite(ValidatePassword("Address@something.it", "ThisShoulB3aG00dPassword!") & @CRLF)
ConsoleWrite(ValidatePassword("Address123@something.it", "ThisShoulB3aG00dPassword!too") & @CRLF)
ConsoleWrite(ValidatePassword("AnotherAddress1234@something.it", "ThisPasswordIsT00Long1234567890!!!!!!!!!!!!!!!!!!!!") & @CRLF)

Func ValidatePassword($strEmail, $strPassword)

    Return StringRegExp($strPassword, '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{6,40}$)', $STR_REGEXPMATCH) And _
           Not StringRegExp($strPassword, '(?i)' & StringRegExp($strEmail, '([^@]+)@.*', $STR_REGEXPARRAYMATCH)[0], $STR_REGEXPMATCH)

EndFunc

^_^

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to comment
Share on other sites

57 minutes ago, Sellonis said:

The script checks for an uppercase and lowercase letter, number or symbol and a minimum/maximum length correctly.

Not quite.  Using your logic, something as simple as 6 spaces will pass your checks as a valid password.  You should not be including "any whitespace character" (\s) in your upper and lower case letter validations?

Your symbolcheck may be a little lax also. 

Can you list your specific complexity requirements, like:

  • Must contain at least 1 uppercase lietter
  • Must contain at least 1 lowercase letter
  • Must contain at least 1 symbol (!,@,#,$,%)
  • etc

That makes it much easier for others to confirm whether you validations are working the way you think they should.

Edited by TheXman
Link to comment
Share on other sites

@Chimp Thank you for that code suggestion, I was not aware that I could use the code that way and am looking it over but I believe I understand what's taking place there

@FrancescoDiMuro I'm looking at your code as well and trying to learn what all is going on there.  I've not made much use of ConsoleWrite though looking at your example I can see where that could have a lot of value.

@TheXmanThank you for pointing that out, I did not intend to have white space characters.  Literal facepalm moment!  In this instance I'm just looking for some very simple requirements to get this script off the ground:

  • 1 uppercase character
  • 1 lowercase character
  • 1 symbol or number
  • Password cannot contain a portion of the email before the @ sign

I am very grateful for the feedback so far, I had not expected to get so much great feedback so quickly! 😀

Link to comment
Share on other sites

22 minutes ago, Sellonis said:
  • 1 symbol or number
  • Password cannot contain a portion of the email before the @ sign

In my opinion, those 2 requirements are a bit too vague.  I would explicitly state what those requirements are.  Doing so makes it easier for you to validate in your script and for the user to understand.  For instance, saying "symbol" could mean a lot of things.  Saying the the symbol must be one of the following symbols (!@#$%^), makes it easier for a user to know exactly which symbols are allowed.

As for the "password cannot contain a portion...", you need to define what a "portion" is.  Does "portion" mean any 2 consecutive characters, 3 consecutive characters, or what?  It needs to be explicit for you to be able to validate it and for your user to know what is acceptable.

Edited by TheXman
Link to comment
Share on other sites

@TheXman Yes, you are 100% correct.  I need to more specifically outline the acceptable requirements.  Specifically stating that !@#$%^&* are acceptable symbols to use will help a lot. And making it perfectly clear to the user that consecutive characters in the password cannot contain any part of the email address before the @ sign in the password will indeed cut down on end user confusion as well.

 

I will take what I have here and work with it to see if I can get it to do what I was working towards.  I'll update the post later and let everyone know how it goes.  Thanks again so very much, I am truly appreciative!

 

Link to comment
Share on other sites

4 hours ago, Sellonis said:

Password cannot contain a portion of the email before the @ sign

This one is tricky, and hard to handle - as TheXman pointed it out :huh2:
If you want to keep such a constraint may I suggest this : in the password, forbid any character which is present in the email before the @ sign
This is strong enough and *much* easier to achieve
The other requirements are simple :)

Link to comment
Share on other sites

Assuming that the blacklist file has one password per line, the example below is one way to handle the validations.  This also assumes that only the email account is entered, not including the domain.  If it includes the domain, then you would need to parse out the email account.

#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d

#include <Constants.au3>
#include <File.au3>
#include <String.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>


Const  $BLACKLIST_FILE = @ScriptDir & "\blacklist.txt" ;<== Modify as needed

Global $gsBlacklist = ""
Global $gnMsg = 0

#Region - Form
Global $Form1 = GUICreate("Password Checker", 332, 126, 373, 136)
Global $InfoTextBlock = GUICtrlCreateLabel("Enter the email and password to check below", 54, 8, 219, 17)
GUICtrlCreateLabel("Address:", 35, 34, 54, 21)
Global $EmailAddressBox = GUICtrlCreateInput("Address", 91, 32, 153, 21)
GUICtrlCreateLabel("Password:", 35, 66, 54, 21)
Global $PasswordBox = GUICtrlCreateInput("", 90, 63, 153, 21)
Global $CheckButton = GUICtrlCreateButton("Check!", 50, 89, 113, 25, $BS_DEFPUSHBUTTON)
Global $CancelButton = GUICtrlCreateButton("Cancel", 168, 89, 113, 25)
#EndRegion


;If blacklist file does not exist, then exit with error message
If Not FileExists($BLACKLIST_FILE) Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "Blacklist file not found!")

;Read blacklist file into variable
$gsBlacklist = FileRead($BLACKLIST_FILE)

;Show form and process form messages
GUISetState(@SW_SHOW)
While 1
    $gnMsg = GUIGetMsg()
    Switch $gnMsg
        Case $GUI_EVENT_CLOSE
            Exit

        Case $CancelButton
            Exit
        Case $CheckButton
            ;If password not valid, then continue loop
            If Not IsPasswordValid(GUICtrlRead($PasswordBox), GUICtrlRead($EmailAddressBox)) Then ContinueLoop

            ;Do valid data processing below
            MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, "Password is valid", _
                   "The password passed all the complexity requirement checks.  " & _
                   "The password has been copied into the clipboard to enter into the system.")
            ClipPut(GUICtrlRead($PasswordBox))
            ExitLoop
    EndSwitch
WEnd


Func IsPasswordValid($sPassword, $sEmail)
    #cs
        Password validation rules:
        - Must contain at least 1 uppercase letter
        - Must contain at least 1 lowercase letter
        - Must contain at least one numeric digit or one of the following characters (!@#$%^&.-)
        - Cannot contain more than specified number of consecutive characters of the email account.
        - Length must be 6-40 characters

        Returns TRUE if password passes all validation checks, otherwise FALSE
    #ce

    Const $CONSECUTIVE_CHARS = 3

    Local $sErrorMessage = "", $sEmailAcct = ""

    ;Uppercase/Lowercase/Numeric/Symbol/Length Validations
    If Not StringRegExp($sPassword, "[A-Z]")          Then $sErrorMessage &= "- Password must have at least 1 uppercase letter." & @CRLF
    If Not StringRegExp($sPassword, "[a-z]")          Then $sErrorMessage &= "- Password must have at least 1 lowercase letter." & @CRLF
    If Not StringRegExp($sPassword, "[0-9!@#$%^&.-]") Then $sErrorMessage &= "- Password must have at least 1 numeric digit or " & _
                                                                             "!@#$%^&.- symbol." & @CRLF
    If StringLen($sPassword) < 6                      Then $sErrorMessage &= "- Password cannot be less than 6 characters." & @CRLF
    If StringLen($sPassword) > 40                     Then $sErrorMessage &= "- Password cannot be greater than 40 characters." & @CRLF

    ;Substring of email account validation (not case-sensitive/sliding window algorithm)
    $sEmailAcct = StringRegExp($sEmail, "^[^@]+", 1)[0]
    For $i = 1 To StringLen($sPassword) - $CONSECUTIVE_CHARS + 1
        If StringInStr($sEmailAcct, StringMid($sPassword, $i, $CONSECUTIVE_CHARS)) Then
            $sErrorMessage &= "- Password cannot have " & $CONSECUTIVE_CHARS & " or more consecutive characters in email account." & @CRLF
            ExitLoop
        EndIf
    Next

    ;Blacklist validation (This assumes that there is one blacklisted password per line)
    If StringRegExp($gsBlacklist, "(?im)^\Q" & $sPassword & "\E$") Then
        $sErrorMessage &= "- Password cannot be a commonly used word/number combination." & @CRLF
    EndIf

    ;If any errors were found, then display an error message and return false to signal validation failed
    If $sErrorMessage <> "" Then
        MsgBox($MB_ICONERROR + $MB_TOPMOST, "VALIDATION ERROR", $sErrorMessage)
        Return False
    EndIf

    ;All is good
    Return True
EndFunc

 

Edited by TheXman
Changed blacklist validation logic / Removed unused variable / Aesthetic modifications / Fixed overlapping labels in form / Change error msg wording
Link to comment
Share on other sites

That's a very clean rewrite @TheXman, I hope to have some time to take that and digest it this afternoon or in the morning.  I've been too busy today to have time to tinker a whole lot but I made some progress with the script that I uploaded earlier to at least do what I was originally wanting to make happen.  I really like how clean your code is and it would be very neat to compact it that way and get rid of all my Func calls.

Link to comment
Share on other sites

2 hours ago, mikell said:

If you want to keep such a constraint may I suggest this : in the password, forbid any character which is present in the email before the @ sign

I’m not sure that’s really a good idea, for a couple of reasons:

1) Users will find it frustrating.

   Consider an email like stephan.williamson@yahoo.com, where one would have step-over half the letters in the alphabet.

2) Passwords would be less secure because they would be easier to guess because the letters from the email could be skipped in brute force attempts.

IMHO, correlation between username and email is precisely what the OP is trying to prevent here, and a negative correlation, if broad enough is really the same deal.

 

 

Code hard, but don’t hard code...

Link to comment
Share on other sites

16 hours ago, JockoDundee said:

 Users will find it frustrating.

Off topic... by definition any constraint requirement is frustrating :D
 

16 hours ago, JockoDundee said:

a negative correlation, if broad enough is really the same deal

Right. I didn't consider that :think:

So the code above from TheXman is absolutely adequate
For the fun a little regex way  :whistle:

#Include <Array.au3>

$s = "stephan.williamson@yahoo.com"
$pw = "123lia#abc"

Local $cnt = 3, $ok = 1, $no = ""
$r = Stringregexp($s, '(?=([^@.]{' & $cnt & '}))(?=.*@)', 3) ; if i.e. the dot is not allowed in pw
; _ArrayDisplay($r)
For $i = 0 to UBound($r)-1
    If StringInStr($pw, $r[$i]) Then 
        $ok = 0
        Exitloop
    EndIf
Next
Msgbox(0,"", $ok & @crlf & $r[$i])

 

Link to comment
Share on other sites

  • 2 weeks later...

Hello everyone!

 

With everyone's help I got it working the way it was intended 😀  I'll definitely be going back later and cleaning it up the logic examples provided above once I get some "free time" to understand how it works.  Thanks so much to everyone here, you've all been a great help!!!

 

Is there a way to mark the topic closed/solved short of selecting one of the above as "Mark as Solution"? 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...