Sellonis Posted May 26, 2021 Share Posted May 26, 2021 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. expandcollapse popup#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 More sharing options...
Gianni Posted May 26, 2021 Share Posted May 26, 2021 (edited) 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 May 26, 2021 by Chimp Sellonis and FrancescoDiMuro 2 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted May 26, 2021 Share Posted May 26, 2021 Hi @Sellonis, and a cool welcome to the AutoIt forum! 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 Sellonis and JockoDundee 1 1 Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
TheXman Posted May 26, 2021 Share Posted May 26, 2021 (edited) 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 May 26, 2021 by TheXman Sellonis 1 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
Sellonis Posted May 26, 2021 Author Share Posted May 26, 2021 @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 More sharing options...
TheXman Posted May 26, 2021 Share Posted May 26, 2021 (edited) 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 May 26, 2021 by TheXman Sellonis 1 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
Sellonis Posted May 26, 2021 Author Share Posted May 26, 2021 @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! TheXman and FrancescoDiMuro 2 Link to comment Share on other sites More sharing options...
JockoDundee Posted May 26, 2021 Share Posted May 26, 2021 1 hour ago, FrancescoDiMuro said: before a cat shows up I’m not so sure, he hasn’t been eating much lately FrancescoDiMuro 1 Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
mikell Posted May 26, 2021 Share Posted May 26, 2021 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 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 Sellonis 1 Link to comment Share on other sites More sharing options...
TheXman Posted May 26, 2021 Share Posted May 26, 2021 (edited) 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. expandcollapse popup#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 May 27, 2021 by TheXman Changed blacklist validation logic / Removed unused variable / Aesthetic modifications / Fixed overlapping labels in form / Change error msg wording Sellonis 1 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
Sellonis Posted May 26, 2021 Author Share Posted May 26, 2021 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 More sharing options...
JockoDundee Posted May 26, 2021 Share Posted May 26, 2021 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. Sellonis 1 Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
mikell Posted May 27, 2021 Share Posted May 27, 2021 16 hours ago, JockoDundee said: Users will find it frustrating. Off topic... by definition any constraint requirement is frustrating 16 hours ago, JockoDundee said: a negative correlation, if broad enough is really the same deal Right. I didn't consider that So the code above from TheXman is absolutely adequate For the fun a little regex way #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]) Sellonis 1 Link to comment Share on other sites More sharing options...
Sellonis Posted June 5, 2021 Author Share Posted June 5, 2021 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now