Subscribe to chuckjessup's Blog        RSS Feed
-----

my log in tut... for VB 6.0

Icon Leave Comment
In my watching the vb forums I have seen several different posts regarding user long in and security of programs and files. Also I have noted that they don't generally get easy to understand answers, the purpose of this tutorial will be to work with ones who wish to secure their applications.

There are several ways to secure a program, and two major methods, the first and simplest is with a flat file system, and the other is through a database. Since each system has advantages and drawbacks, and my lack of working with databases with in vb, I will cover the 'flat-file' file system.

Like I said each system has advantages and drawbacks, so I will spend a few moments in explaining a few things about them, and typically databases are ultimately the better, faster way of working with securing your program from unwanted attempts to access the program its self. However flat files mean that you wont have to fuss with databases, and are fast if they are not too large. the biggest drawback to the flat file system I have found is that you have to code a bit more.

the first way to look into securing the program is to hard code the user name and password into the program, the drawbacks should be obvious, although you would be sure that people who attempt to access your program are less likely to gain access, its hard coded into the code, and thus cannot be changed... with out re-releasing the application...
The code for hard coding user names and passwords, either in an array or one by one...

create a standard exe with two text boxes, and a command button. I will use default names for the controls here.
Private Sub Command1_Click()
'here we will set what to look for, then check against it, as well as create checks...'
If Text1.Text = "Test" Then
     If Text2.Text = "PassW0rd" then
          'code to do if correct... like someform.Visible = True '
     Else 'this creates a catch for incorrect passwords'
          MsgBox "The password that you have entered is incorrect.", vbCritical + vbOkOnly, "Invalid Password"
          Text2.Text = "" 'clears text for re-input'
          Text2.SetFocus 'Sets the cursor back in password field
     End If
Else 'creates the catch if the user is incorrect'
     MsgBox "The user That you entered is incorrect.", vbCritical + vbOkOnly, "Invalid User"
     Text1.Text = "" 'clears user for re-entry'
     Text2.Text = "" 'clears password for reentry'
     Text1.SetFocus ''Sets the curser in the user field for re-entry'
End If
End Sub

Private Sub Form_Load()

Me.Caption = "Log in example"
Text1.Text = "" 'Or VbNullString , Clears the text box'
Text2.Text = "" 'Or VbNullString , Clears the text box'
Text2.PasswordChar = "*" 'makes the text in text2 field = *'s to hide what you are typing' 
Command1.Caption = "Log In"
'Other controls should go here if needed, such as labels and what not'
End Sub



To set multiple users and passwords it adds a little bit of code to the above sample(depending is the passwords are user specific), using the code above:

Private Sub Command1_Click()
'here we will set what to look for, then check against it, as well as create catches...'
If Text1.Text = "Test" Or "Admin" Or "Foo" Then 'with the Or statement you can add as many as you want.
     If Text2.Text = "PassW0rd" Or "Administrator" then 'with the Or statement you can add as many as you want.
          'code to do if correct... like someform.Visible = True '
     Else 'this creates a catch for incorrect passwords'
          MsgBox "The password that you have entered is incorrect.", vbCritical + vbOkOnly, "Invalid Password"
          Text2.Text = "" 'clears text for re-input'
          Text2.SetFocus 'Sets the cursor back in password field
     End If
Else 'creates the catch if the user is incorrect'
     MsgBox "The user That you entered is incorrect.", vbCritical + vbOkOnly, "Invalid User"
     Text1.Text = "" 'clears user for re-entry'
     Text2.Text = "" 'clears password for reentry'
     Text1.SetFocus ''Sets the curser in the user field for re-entry'
End If
End Sub

Private Sub Form_Load()

Me.Caption = "Log in example"
Text1.Text = "" 'Or VbNullString , Clears the text box'
Text2.Text = "" 'Or VbNullString , Clears the text box'
Text2.PasswordChar = "*" 'makes the text in text2 field = *'s to hide what you are typing' 
Command1.Caption = "Log In"
'Other controls should go here if needed, such as labels and what not'
End Sub



For set passwords for each user, you will need to set each individually with in one big long and hopelessly confusing If..Then..Else statement, which would looks something like this...
If Text1.Text = "Test" then
      If Text2.Text = "Password1"
           'code if correct
      Else
           MsgBox "The password that you have entered is incorrect.", vbCritical + vbOkOnly, "Invalid Password"
           Text2.Text = "" 'clears text for re-input'
           Text2.SetFocus 'Sets the cursor back in password field
      End If
ElseIf Text1.Text = "Admin" Then
      If Text2.Text = "AdmPswd" Then
           'code if correct
      Else
           MsgBox "The password that you have entered is incorrect.", vbCritical + vbOkOnly, "Invalid Password"
           Text2.Text = "" 'clears text for re-input'
           Text2.SetFocus 'Sets the cursor back in password field
      End If
'other users and passwords... would go here...'
Else 'creates the catch if the user is incorrect'
     MsgBox "The user That you entered is incorrect.", vbCritical + vbOkOnly, "Invalid User"
     Text1.Text = "" 'clears user for re-entry'
     Text2.Text = "" 'clears password for reentry'
     Text1.SetFocus ''Sets the curser in the user field for re-entry'
End If


If you have not noticed that that was less than well good, its a lot of work doing that, The cleanest way to hard code the Users and passwords is to use arrays, two of them to be correct... and a loop statemenmt.
We will use a variant of the first example:

Private Sub Command1_Click()
'here we will Create and set the values of the arrays, then check against it, as well as create catches...'
Dim UName() As Variant, PWord() As Variant
UName() = Array(0,...,10) 'remember that the array starts as 0, and to add a ',' behind each array item index'
PWord() = Array(0,...,10) 'must be the same number as the array 'UName''
'Now you will have to fill out the arrays... note that I will show how this is done the ... is to show that you continue with the pattern'
UName(0) = "Test"
...
UName(10) = "Admin"

'now for passwords...'
PWord(0) = "PassWord1"
...
PWord(10) = "AdmPswd"

'Now we need to search through the UName() array for the user that was entered in Text1.Text, and cross it with PWord()'
Dim I As Integer, X As Integer, User As String, Password As String
I = (0) 'Remember that arrays start at 0 so we need to start at -1 or add after the end of the if statement.'
X = (0) 

Do
          User = UName(I)
          Password = PWord(X)
          If Uname(I) = Text1.Text then
               If Password(X) = Text2.Text then
                    'code to do if correct info is given...'
               end if
          End If
     I = I + 1 'sets I to 0 see, it will work out...
     X = I + 1 'Sets X to 0 and continues to add 1 so we can cross Users with Passwords
Loop Until (User = Text1.Text) And (Password = Text2.Text) Or (UName(I) = 9) 'The last Value in this line needs to be '9' it wont work otherwise, even if you have 15 items, it has to be 9, it stops the loop should no  correct information as provided, this should be changed to the number of items in your array'
'now we will deal with what to do if nothing matched, or if something was not right...'
If User <> Text1.Text Or Password <> Text2.Text Then
     MsgBox "You have entered incorrect log-in credentials, Please check your information and try again.", vbCritical + vbOKOnly, "Log In Failed!"
     Text1.Text = ""
     Text2.Text = ""
     Text1.SetFocus
End If
End Sub


Now I know that this looks like a bear to take on, however it is fairly easy to maintain, and add to if you would like to... to add to the possible users and passwords add the lines UName(#) = "something" and PWord(#) = "154236" where the # is the next number in the array, and between the " " is what you would like the user/password to be. although this is a more flexible to work with it still requires you to recompile the program and redistribute it, which can be a pain.

Well then we have an opportunity to set up the ability for the user to create his or her own accounts with the program, this not only frees you up as the coder, but allows the users to use personalized user names and passwords. In this way you will also have fewer required releases.
The code to do this is a bit more complicated and takes three forms to use. What we will need to accomplish is to create a user file, and the individual user account file, and then use the information to validate the user and allow him/her access to the program. The following example will cover the creation of the user accounts. This is taken from a programs that i already employ and are known to be working. We will also want to add a hard-coded user account to use to gain limited access, in this case we will use 'Admin' and 'Admin' for the password. The two main forms will be the log in and the user account creation forms, The log in will use the same controls as above ( 2x text boxes, and 1x command button) the user account creation form will need at this time 3X test boxes, 3x command buttons and a few labels to explain what the text boxes are for. The reason there are three text boxes is because we want the user to have the correct password entered, so we want it twice, the other reason, is the last example I will cover with this tutorial will cover encryption, which means you will want to make sure that the user know his/her passwords... On the middle form, which would be your application, add 1 command button, in your application you can add a file menu and allow it to be visible to only the admin account, but that is another tutorial.
'This will be the main form'
Private Sub Form_Load()
Me.Caption = "My App Name"
Command1.Caption = "&Admin Panel" 'The & char creates a alt+ hot key in this instance 'Alt + A' '
End Sub

Private Sub Command1_Click()
frmAdmin.Visible = True
Me.Visible = False
End Sub



Now we will suppose that there are three labels on the admin form, one for each of the text boxes.
'General Dec.s'
Private FSO As New FileSystemObject
'you may have noticed that the file system object is not there until you add it as a refrence. This will be discussed at the end of this forms example.'

Private Sub Form_Load()
Me.Caption = "Administrator Panel"
Command1.Caption = "&Create Directory" 'we will do some nifty stuff with this.'
Command2.Caption = "&Add User" 'will process the user info in the text boxes'
Command3.Caption = "&Exit" ' in your main program use a log off menu item or button, this will exit directly to the log in form.
Label1.Caption = "Enter User Name" 'we will also cover restricting user names and passwords under the command2_click'
Label2.Caption = "Enter Desired Password"
Label3.Caption = "Re-Enter Password"
Text1.Text = ""
Text2.Text = ""
Text3.Text = ""
Text3.PasswordChar = "*"
'After you have added all the naming and other things you want done then you will want to process this code.'
'This will prevent you from attempting to create the User directory while it exists. also directs your cursor to the add user...'
If FSO.FileExists(App.Path & "\User\Dir.dll") then
     Command1.Enabled = False
End If

Private Sub Command1_Click()
If Len(Dir(App.Path & "\User", vbDirectory)) = 0 Then 'Creates user directory if not already done. Now we will create a file to disable this button on loading the form if the file exists.'
    MkDir App.Path & "\User"
End If
If FSO.FileExists(App.Path & \User\Dir.dll") then
     Open App.Path & "\User\Dir.dll" For Append As #1
        print #1, "what ever you want to..."
     close #1
Else
     Open App.Path & "\User\Dir.dll" For Output As #1
        print #1, "what ever you want to..."
     close #1
End If
Command1.Enabled = False
End Sub

Private Sub Command2_Click()
' here we will prevent any user other than hard coded ones from being created.'
'checking the user name against forbidden types'
    Dim forbidname As String

    forbidname = Mid(Text1.Text, 1, 5)
    If forbidname = "Admin" Then
        MsgBox "You have entered a Forbiden User name!", vbCritical, "Error: Forbiden UserName"
        Text1.Text = ""
        Text1.BackColor = vbRed
        Text1.SetFocus

    End If
    If forbidname = "admin" Then
        MsgBox "You have entered a Forbiden UserName!", vbCritical, "Error: Forbiden UserName"
        Text1.Text = ""
        Text1.BackColor = vbRed
        Text1.SetFocus
    End If
    Dim username3 As String
    username3 = Mid(Text1.Text, 1, 1)
        If username3 = "&" Then
            MsgBox "You have entered a Forbiden User name!", vbCritical, "Error: Forbiden UserName"
            Text1.BackColor = vbRed
            Text1.Text = ""
            Text1.SetFocus
        Else
        End If
'check if passwords are O.K. by making sure that the passwords match.'
    If Text2.Text <> Text3.Text Then
        MsgBox "Your passwords do not match. You must correct this.", vbCritical + vbOKOnly, "Error: Passwords don't match"
            Text2.BackColor = vbRed
            Text3.BackColor = vbRed
            Text2.Text = ""
            Text3.Text = ""
            Text2.SetFocus
    Else
        Text2.BackColor = vbWhite
        Text3.BackColor = vbWhite
    End If
'Alright if your user name and password make it here we need to create the user file and a file to store the password, now I like to separate the files for each user so I use directories, which I find are easier to use for the log in.
If Len(Dir(App.Path & "\User\" & Text1.Text, vbDirectory)) = 0 Then 'Creates the directory for the individual user.
    MkDir App.Path & "\User\" & Text1.Text
End If
'Now we create the password file, This file for this example will be called PW.Dat, Rename this file if you use this code as it is too obvious.
If FSO.FileExists(App.Path & "\Users\" & Text1.Text & "\PW.Dat") Then
     'do nothing as it isn't the job if this to overwrite the user's pw file. although if you would like for unencrypted files you can copy the other part and paste it here and it will reset the selected users PW.dat file - Not Recommended'
Else
     Open App.Path & "\User\" & Text1.Text & "\PW.Dat" For Output As #2
          Print #2, Text2.Text
     Close #2
End If
MsgBox "User Created: " & Text1.Text & "PW: " & Text2.Text, vbInformation + vbOKOnly, "User Created Successfully"
End Sub

Private Sub Comman3_Click()
'now we need to log off the user (most commonly Admin) so that you can start using the the new account, REMEMBER that I would recommend that the code in this sub be transferred to the main form somewhere (like in a menu or button).'
Close All 'Closes all open Files.'
frmLogin.Visible = True 'Use the form name of the login form, and MDI forms use .show'
Unload frmMain 'if you have this in the main form, when you exit all other forms unload them, Then All you would have to do is three lines of code :)/>'
'Close All
'frmLongin.Visible = True
'Unload Me 
'And this button would only require you to Close All, and Unload Me, Simple.
End Sub



Now I told you that I would go over the Adding of a Reference for the FileSystemObject we declared at the beginning of this form. It is really simple to do:
In the top in Menu Bar(File, Edit, ect.) in the 'Projects' menu, there is an option that is 'References...'
Scroll and find the Microsoft Scripting Runtime. (c:windows\system32\sccrun.dll)
Check it and click OK, and you shouldn't have issues with it, You will have to include this file in any distributions you make.
And we will now move on to the log in form, and This example will be a bit expanded from first ones:
'General dec.s'
Private FSO As New FileSystemObject

Private Form_Load()
Me.Caption = "Log in example"
Text1.Text = "" 'Or VbNullString , Clears the text box'
Text2.Text = "" 'Or VbNullString , Clears the text box'
Text2.PasswordChar = "*" 'makes the text in text2 field = *'s to hide what you are typing' 
Command1.Caption = "Log In"
'Other controls should go here if needed, such as labels and what not'
end Sub

Private Sub Command1_Click()
Dim Pw1 as string
'ok we need to look at the user name, then the password, then see if they all match up. some of this will be directly completed.'
If FSO.FolderExists(App.Path & "\User\" & Text1.text) = True Then
     If FSO.FileExixts(App.Path & "\User\" & Text1.text & "\PW.Dat") Then
          Open App.Path & "\User\" & Text1.text & "\PW.Dat" For Input As #1
               Line Input #1, Pw1
          Close #1
     Else
          MsgBox "User Doesn't Exist.", vbCritical + vbOKOnly, "Error: User Not Found"
     End If
     If Pw1 = Text2.Text Then
          'process code here'
          frmMain.Visible = True
          Unload Me
     Else
          MsgBox "The Password you entered is Incorrect.", vbCritical + vbOKOnly, "Incorrect Password"
          Text2.Text = ""
     End If
Else
     MsgBox "The User that you have entered is incorrect, Please try again.", vbCritical + vbOKOnly, "Incorrect UserName"
End If
'I almost forgot the Admin Account!'
If Text1.Text = "Admin" Then
     If Text2.Text = "Admin" Then
          'add code for admin account here, this will just open the frmMain.'
          frmMain.Visible = True
     Else
          MsgBox "Incorrect Password", vbCritical + vbOKOnly, "Incorrect Password Entry"
     End If
Else
     MsgBox "Incorrect User Name", vbCritical + vbOKOnly, "Incorrect User Name Entry"
End If
End Sub



That's all that you will need for allowing users to create their own user accounts, however, you may wonder how do you protect the password file? Well the short and simple answer is to Encrypt it. There are a ton of different ways to do this, however there is a very nice one found in the snippets section HERE. I recommend that which ever you choose that you turn it into a custom dll file ( to do that create a new project and select ActiveX DLL, and then compile it, add it to the references like you did for the Microsoft Scripting Runtime, and then create a public sub...)
'using the snippet from the link Do this in the main form, and call it from every where else'
Public Sub EncodeDecode(InputFile As String, OutputFile As String, PasswordKey As String)
dim MyCls As New (project name of dll).Class1
call MyCls.FileEncodeAndDecode(InputFile As String, OutputFile As String, PasswordKey As String)
End Sub



like this:
Call frmMain.EncodeDecode(input path to PW file, Output path to PW file, "some long sentence as the passwordkey")


The major difference that I like to do in the Login form, is that instead of overwriting the PW file, set the output file as something like "PW1.Dat" and then remember to delete the file when done looking at it. Like this [inline]Kill app.path & "\User\" & Text1.Text & "\(What ever you named the outputfile i.e. PW1.Dat)"[\inline]
The expanded example of the log in form:

Private Sub Command1_Click()
Dim Pw1 as string
'ok we need to look at the user name, then the password, then see if they all match up. some of this will be directly completed.'
If FSO.FolderExists(App.Path & "\User\" & Text1.text) = True Then
     call frmMain.EncodeDecode(App.Path & "\User\" & Text1.text & "\PW.Dat", App.Path & "\User\" & Text1.text & "\PW1.Dat", "same passwordkey as the original was encrypted with...")
     If FSO.FileExixts(App.Path & "\User\" & Text1.text & "\PW1.Dat") Then
          Open App.Path & "\User\" & Text1.text & "\PW1.Dat" For Input As #1
               Line Input #1, Pw1
          Close #1
     Else
          MsgBox "User Doesn't Exist.", vbCritical + vbOKOnly, "Error: User Not Found"
     End If
     If Pw1 = Text2.Text Then
          'process code here'
          Kill App.Path & "\User\" & Text1.text & "\PW1.Dat"
          frmMain.Visible = True
          Unload Me
     Else
          MsgBox "The Password you entered is Incorrect.", vbCritical + vbOKOnly, "Incorrect Password"
          Text2.Text = ""
     End If
Else
     MsgBox "The User that you have entered is incorrect, Please try again.", vbCritical + vbOKOnly, "Incorrect UserName"
End If
     If FSO.FileExixts(App.Path & "\User\" & Text1.text & "\PW1.Dat") Then 'removes the file to look at for the users password if not already done.'
          Kill App.Path & "\User\" & Text1.text & "\PW1.Dat"
     End If

'I almost forgot the Admin Account!'
If Text1.Text = "Admin" Then
     If Text2.Text = "Admin" Then
          'add code for admin account here, this will just open the frmMain.'
          frmMain.Visible = True
     Else
          MsgBox "Incorrect Password", vbCritical + vbOKOnly, "Incorrect Password Entry"
     End If
Else
     MsgBox "Incorrect User Name", vbCritical + vbOKOnly, "Incorrect User Name Entry"
End If
End Sub



And that's really it. Please understand that the code in here are working samples, they should work for you, and you can add different things for the program to do... You can even create a password recovery.
Ok this is what that would look like:
You will need an additional 2x command buttons and three text boxes, the first command button is for making the other editing controls visible, caption would be like: "&Edit User". The second command button should have something like: "&Done".
Text boxes 4-6 should be: "" or vbNullString. This is the code for the command buttons...
'remember this is for the admin form'
Private Sub Command4_Click()
Command5.Visible = True
Text4.Visible = True
Text5.Visible = True
Text6.Visible = True
End Sub

Private Sub Command5_Click()
If FSO.FolderExists(App.Path & "\Users\" & Text4.Text) Then 'creates the away directory
     If Text5.Text = Text6.Text Then
          If FSO.FileExists(App.Path & "\User\" & Text4.Text & "\PW.Dat") Then
               Open App.Path & "\User\" & Text4.Text & "\PW.Dat" for output as #1
                    Print #1, Text5.Text
               Close #1
          Else
          End If
Else
     MsgBox "User Doesn't Exist.", vbCritical + vbOKOnly, "Error: User Not Found"
End If
Call frmMain.EncodeDecode(App.Path & "\User\" & Text4.Text & "\PW.Dat", App.Path & "\User\" & Text4.Text & "\PW.Dat", "same passwordkey as the original was encrypted with...")
End Sub



The password should be set to go for the next time you log in with that user.
That's all folks, at least for now.

0 Comments On This Entry

 

Trackbacks for this entry [ Trackback URL ]

There are no Trackbacks for this entry

August 2014

S M T W T F S
     12
3456789
10111213141516
17181920212223
242526272829 30
31      

Search My Blog

0 user(s) viewing

0 Guests
0 member(s)
0 anonymous member(s)

Categories