Changing a user Password in vb.net - mysql

So i am trying to change the password of a user in my vb.net project that i been working on. but everytime i run my code i get me catch "Something went wrong". i can't figur out why. i am using a MYSQL database. can anybody help me?
Try
reader = cmd.ExecuteReader()
Dim found As Boolean = False
Do While reader.Read()
If username = DirectCast(reader("username"), String) Then
If password = DirectCast(reader("password"), String) Then
found = True
Else
MessageBox.Show("username and password do not match")
End If
End If
If found = True Then
Dim cmd2 As New MySqlCommand
Dim insertStatment As String = "UPDATE login set password = '" +
newpassword + "' where username = '" + username + "'" , con)
cmd2.ExecuteNonQuery()
MessageBox.Show("password change successfully")
'End If
End If
Loop
Catch
MessageBox.Show("Something went wrong")

You should avoid to use string concatenation to build sql statements. Doing in this way leads the path to errors like when you have a username/password with single quote characters or worst if you have a smart and malicious user that writes something like this in your input textboxes
So you should write
Dim insertStatment As String = "UPDATE login set password = #p1 where username = #p2"
Dim cmd2 As New MySqlCommand(insertStatment, con)
cmd2.Parameters.AddWithValue("#p1", password)
cmd2.Parameters.AddWithValue("#p2", username)
cmd2.ExecuteNonQuery()
Another possible cause of your error is the handling of the MySqlConnection. In your code there is no Open of the connection, so I assume that it is open, but this leads to another problem of your code:
Do not catch exception and then print unusable error message.
If you really want to give a message try to print the error message given in the exception
Catch e As Exception
MessageBox.Show("Something went wrong: " & Environment.NewLine & e.Message)
This will give a pretty clear message that explains what the problem is.

Related

BCrypt generate hash and salt then compare to MySQL database

I'm looking to BCrypt to hash and salt and compare it to the hash stored in my database. There seems to be a lack of vb.net with BCrypt, which is why I'm asking.
So, from what I understand is we generate a hash and a salt when the user enters their password. Then we compare that hash to the one in the database, however since I've found nothing online for vb.net I'm not sure how to do it.
This is what I have so far. If the code looks messy it's because I copied and pasted it from Visual Studio to here, on VS it looks neat and tidy.
Now I know there will be flaws with the code etc. I'm not that bothered as this is for personal use and learning. Just need to learn how to generate salt + hash with BCrypt and then compare it with the already hash & salted password in my database but in terms of how to go about and redo this bit of code and implement the check that both salt & hashes are the same I'm stuck.
Dim pw As String = TextBox_Password.Text
Dim Salt As String = BCrypt.Net.BCrypt.GenerateSalt(12)
Dim Hash As String = BCryot.Net.BCrypt.HashPassword(pw, salt)
Try
Connection.Open()
Dim SQLQuery
SQLQuery = "SELECT * FROM `core_members` where name='" & TextBox_Username & " ' and members_pass_hash='" & I don't know if you're meant to put Hash? here to hash the inputed password from the user? Or the TextBox_Password.Text & "'"
'As for the verify function... to compare the hashed password I do try to do this
If (BCRYpt.Net.BCrypt.Verify(pw, hash)) Then
Command1 = New MySqlCommand(SQLQuery, Connection)
READER = Command1.ExecuteReader
Dim Count As Integer
count = 0
While READER.read
count += 1
end while
READER.close()
If count = 1 then
'User Successfully Logged In
end if
'I definitely know the count = 1 etc probably not the best way to allow a user to login. I've seen something with MyData.HasRows or something like that to login?
'I know that the code above is probably no where near close to actually how it's done but as I said due to the lack of documentation with vb.net and BCrypt not making it easy.
Any help with cleaning up the login function would be great including comparing the hashed password in my database.
Just want to give the biggest thanks to #Mary for being so kind and helpful for providing a solution to solve my biggest problem thus far! Thank you!
I'm only making this Answer because for me there were a few typo's I had to fix, but all of it goes to Mary!
So, first off I'm using a mysql.dat.dll which uses Imports MySql.Data.MySqlClient (Which changes a few things from Mary's code)
Imports Crypt = BCRypt.Net.BCrypt - Allows us to use Crypt Instead of having to type the whole BCrypt.Net.BCrypt
Please note for me, if your textbox's are empty then you will get an error Object Reference not set to an instance of an object. This is if you're on visual studio. It won't happen if you run the program as a normal user. I will tell the user make sure they have entered a username and password
Imports Crypt = BCRypt.Net.BCrypt
Private Sub VerifyPassword()
try
Dim Password As String = "TextBox_UserPassword"
Dim Hashword As String = ""
Using Conn As New MySqlCommand(Connection),
Command As New MySqlCommand("SELECT password FROM members where Username= #Username;", Conn)
Command.Parameters.Add("#Username", MySqlDbType.VarChar).Value = TextBox_Username
Conn.Open()
Hashword = Command.ExecuteScalar.ToString
End Using
Dim Result = Crypt.Verify(Password, Hashword)
If result = true then
MsgBox("Logged in")
else
MsgBox("Logged in Failed")
end if
Catch ex As Exception
MessageBox.Show(ex.Message) 'Optional'
MsgBox("Make sure have entered a Username or Password", vbcritical) 'If the textbox have nothing it will remind the user to make sure they enter a username or password'
End try
End Sub
I used Sql Server to test code because it was what I had handy. It will work the same for MySql. With BCrypt you don't have to store the salt separately.
Private Sub InsertNewUser()
Dim HashWord As String = BCrypt.Net.BCrypt.HashPassword(TextBox2.Text, BCrypt.Net.BCrypt.GenerateSalt(12))
Using cn As New SqlConnection(My.Settings.PublishCon),
cmd As New SqlCommand("Insert Into Users (UserName, Password) Values (#Name, #HashWord);", cn)
cmd.Parameters.Add("#Name", SqlDbType.VarChar, 100).Value = TextBox1.Text
cmd.Parameters.Add("#HashWord", SqlDbType.VarChar, 100).Value = HashWord
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Sub
Private Sub VerifyPassword()
Dim pw As String = TextBox2.Text
Dim HashWord As String = ""
Using cn As New SqlConnection(My.Settings.PublishCon),
cmd As New SqlCommand("SELECT Password FROM Users where UserName= #UserName;", cn)
cmd.Parameters.Add("#UserName", SqlDbType.VarChar).Value = TextBox1.Text
cn.Open()
HashWord = cmd.ExecuteScalar.ToString
End Using
Dim result = BCrypt.Net.BCrypt.Verify(pw, HashWord)
If result Then
MessageBox.Show("Successful Login")
Else
MessageBox.Show("Sorry login failed")
End If
End Sub

Unknown database 'database'

I am trying to make a secure login for my database, using a MySQL database.
Private Sub logIn_Click(sender As Object, e As EventArgs) Handles logIn.Click
MysqlConn = New MySqlConnection
MysqlConn.ConnectionString =
"server=localhost;userid=root;password=Catawba;database=catawbapartnership"
Dim READER As MySqlDataReader
Try
MysqlConn.Open()
Dim Query As String
Query = "select * from database.admininfo where admin_username= ' " & TB_UN.Text & " ' and admin_password= ' " & TB_PD.Text & " '"
COMMAND = New MySqlCommand(Query, MysqlConn)
READER = COMMAND.ExecuteReader
Dim count As Integer
count = 0
While READER.Read
count = count + 1
End While
If count = 1 Then
MessageBox.Show("Username and Password Accepted")
ElseIf count > 1 Then
MessageBox.Show("Username and Password Are Incorrect")
Else
MessageBox.Show("Username and Password Are Incorrect")
End If
MysqlConn.Close()
Catch ex As MySqlException
MessageBox.Show(ex.Message)
Finally
MysqlConn.Dispose()
End Try`
This is the code, but I keep getting the error of Unknown database'database'
In MySQL Workbench, the entire database is named catawbapartnership
And the table I need to get info from is called admininfo
But, it keep saying I have entered it incorrectly. Please help!
Remove database. from your code. As a default database is in the connection you don't need to specify it in the question.
Please copy your implementation from somewhere else. This has SQL injection vulnerabilities and you should never store plain text passwords.
OWASP has a lot of guidance on being a responsible programmer.

Invalid attempt to access a field before calling Read() vb.NET and MySQL

I receive this error every time I try log in with incorrect details which should show a message-box "invalid username..." and when no details are entered it should show "please enter...
conn = New MySqlConnection
conn.ConnectionString = "server=localhost; userid=root; password=...; database=..."
Dim reader As MySqlDataReader
Try
conn.Open()
Dim Query As String
Query = "SELECT Username, Password, Admin FROM appointments.tblLogin WHERE Username='" & TextBox_Username.Text & "' AND Password='" & TextBox_Password.Text & "' "
cmd = New MySqlCommand(Query, conn)
reader = cmd.ExecuteReader
Dim count As Integer
count = 0
While reader.Read
count = count + 1
End While
If reader.GetInt32("Admin") = 1 Then
AdminMainMenu.Show()
Me.Hide()
ElseIf reader.GetInt32("Admin") = 0 Then
MainMenu.Show()
Me.Hide()
Else
MessageBox.Show("Invalid username or password")
End If
If TextBox_Username.Text.Equals("") And TextBox_Password.Text.Equals("") Then
MessageBox.Show("Please enter a username and password")
End If
conn.Close()
Catch ex As MySqlException
MessageBox.Show(ex.GetBaseException.ToString)
Finally
conn.Dispose()
End Try
The MySqlDataReader can move forward-only, once it reaches the end of the rows retrieved by the command, it cannot go back to read previous rows.
The loop used to count the number of rows moves the reader to the end of the data stream. So trying to read the Admin field result in an exception.
If TextBox_Username.Text.Equals("") And _
TextBox_Password.Text.Equals("") Then
MessageBox.Show("Please enter a username and password")
Return
End If
.... opening and executing the command code....
If reader.Read Then
Dim isAdmin = (reader.GetInt32("Admin") = 1)
If isAdmin Then
AdminMainMenu.Show()
Me.Hide()
Else Then
MainMenu.Show()
Me.Hide()
End If
Else
MessageBox.Show("Invalid username or password")
End If
conn.Close()
Notice that I have removed the loop and used a simple if/else statement around the Read method to display the error message and I have changed the reading of the Admin flag creating a boolean variable to simplify the logic inside the true part of the if block.
Said that, you need to look at how build parameterized queries because your string concatenation to build the commandtext exposes your program to Sql Injection Attacks (not to mention syntax errors if some of your textbox contains a single quote, try it...)
Consider also that from a security standpoint you should never store passwords in the database in clear text. Use always an hash of the password

VB.NET log in form using MySQL database

Can someone help me with the following please.
I have created a database called dbhr and a table in it called user with two fields 'username' and 'password' having VARCHAR data type.
I have a log in form with two textboxes (tbxUsername,tbxPassword) and an OK button. I have connected my database to authenticate the username and password. But it always give me wrong password message. I don't know where I went wrong.
Please help.
I use MySQL Workbench 6.1
Thanks in advance.
Here is the VB.NET log in button code.
Imports MySql.Data.MySqlClient
Public Class Login
Dim mydbcon As MySqlConnection
Dim COMMAND As MySqlCommand
' TODO: Insert code to perform custom authentication using the provided username and password
' (See http://go.microsoft.com/fwlink/?LinkId=35339).
' The custom principal can then be attached to the current thread's principal as follows:
' My.User.CurrentPrincipal = CustomPrincipal
' where CustomPrincipal is the IPrincipal implementation used to perform authentication.
' Subsequently, My.User will return identity information encapsulated in the CustomPrincipal object
' such as the username, display name, etc.
Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click
mydbcon = New MySqlConnection
mydbcon.ConnectionString = "server=localhost;userid=root;password=rootword;database=hrdb"
Dim reader As MySqlDataReader
Try
mydbcon.Open()
Dim Query As String
Query = "select * from user where username= ' " & tbxUsername.Text & "' and password= ' " & tbxPassword.Text & "' "
COMMAND = New MySqlCommand(Query, mydbcon)
reader = COMMAND.ExecuteReader
Dim count As Integer
count = 0
While reader.Read
count = count + 1
End While
If count = 1 Then
MessageBox.Show("Username and password are correct")
ElseIf count > 1 Then
MessageBox.Show("Username and password are duplicate")
Else
MessageBox.Show("Username and password are wrong")
End If
mydbcon.Close()
Catch ex As MySqlException
MessageBox.Show(ex.Message)
Finally
mydbcon.Dispose()
End Try
End Sub
Please click the following links to see the database table records and data types.
Click here!
You have some extra spaces in the line
Query = "select * from user where username= ' " & tbxUsername.Text & "' and password= ' " & tbxPassword.Text & "' "
which I would change to
Query = String.Format("SELECT * FROM user WHERE username = '{0}' AND password = '{1}'", Me.tbxUsername.Text.Trim(), Me.tbxPassword.Text.Trim())
I would use String.Format() to make it clearer, less chance to overlook those extra spaces.

String from Database set as public string

Ok from the answer from the previous question the reasoning still applies here but this time A different issue. There is a login system (Loginvb.vb) that I got for the launcher I was creating and was wondering 2 things:
Is there a better way to do the Login check with the database (as in
more secure) (the login style will have a web based registration
setting via PHP script)?
Is there a way to take a certain column (labled as access) in the database and put it
as a public string so I can check if it will equal 1 2 or 3 in a
different form labeled as Main.vb
Here is the current login check:
Public Sub login_Click(sender As Object, e As EventArgs) Handles login.Click
If txtuserName.Text = "" Or txtpassWord.Text = "" Then
MsgBox("You cannot progress until you login....(moron =p)")
Else
'Connects To the Database
Dim connect As MySqlConnection
connect = New MySqlConnection()
connect.ConnectionString = "server=127.0.0.1;user id=sc;Password=derp;database=sclaunch" 'not the actual login ;)
Try
connect.Open()
Catch myerror As MySqlException
MsgBox("Error Connecting to Database. Please Try again !")
End Try
'SQL Query To Get The Details
Dim myAdapter As New MySqlDataAdapter
Dim sqlquerry = "Select * From login where username = '" + txtuserName.Text + "' And password= '" + txtpassWord.Text + "'"
Dim myCommand As New MySqlCommand()
'My fail attempt at what I am trying to do :(
Dim sql22 As MySqlConnection
sql22 = New MySqlConnection()
sql22.ConnectionString = "Select * From login where access ="
'End of fail attempt
myCommand.Connection = connect
myCommand.CommandText = sqlquerry
'Starting The Query
myAdapter.SelectCommand = myCommand
Dim mydata As MySqlDataReader
mydata = myCommand.ExecuteReader
'To check the Username and password and to validate the login
If mydata.HasRows = 0 Then
MsgBox("Invalid Login")
Else
'fail testing xD
Label3.Text = sql22
MsgBox("You are now Loged In!")
End If
End If
End Sub
Still basically learning more and more as I am coding all this got to love trial and error and the moments where you get stuck =/ (Sorry to the admins or whatever for fixing tag issues still new to the site xD)
Assuming that the same table login that contains the credentials contains also the access column that you want to retrieve, then I have changed a lot of your code
Dim sqlquerry = "Select * From login where username = #name AND password=#pwd"
Dim myCommand As New MySqlCommand(sqlquery, connect)
myCommand.Parameters.AddWithValue("#name", txtuserName.Text)
myCommand.Parameters.AddWithValue("#pwd", txtpassWord.Text)
Dim mydata = myCommand.ExecuteReader
If mydata.HasRows = False Then
MsgBox("Invalid Login")
Else
' the same record that contains the credentials contains the access field'
mydata.Read()
Label3.Text = mydata("access").ToString()
MsgBox("You are now Loged In!")
End If
What I have changed:
Removed the string concatenation and added the appropriate parameters
Removed myAdapter and every references to it (not needed, you don't
fill DataTable/DataSet)
Removed sql22 and every references to it. It's a Connection and you
try to use like a Command
Fixed the check on HasRows (Returns a boolean not an integer. Are you
using Option Strict Off?)