Qt Checking Login using Database - mysql

I am using qt to create a user login. I am using Sqlite as my database and am stuck for some reason it is not working properly. I was able to corectly bypass the login screen only when typing in the first row from the database. Any other user cannot log in (row 2, 3,4 ... in database). I have been reading all kinds of posts for the past days and have not come to a proper solution. Here is my code. I have also tried creating a query through QSqlQuery and passing it into the QSQlQueryModel Object which did not work at all.
void MainWindow::on_login_clicked()
{
QSqlDatabase m_db;
QString path = "C:/Users/annea/Summer2019Database.db";
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName(path);
m_db.open();
if (!m_db.open())
{
qDebug() << "Error: connection with database fail";
}
else
{
qDebug() << "Database: connection ok";
}
QString username = ui->username->text();
QString password = ui->password->text();
QSqlQueryModel *queryModel = new QSqlQueryModel;
queryModel->setQuery("SELECT * FROM [User Database] WHERE Username= username"); //select the row of where the Username == username
queryModel->query().exec(); //execute it (not really sure why or what this does
if(queryModel->record(0).value(1).toString()== password) //if a row is found check column 2 for password
{
destroy(); //destroy current window
if(queryModel->record(0).value(3).toString()== 1) //if id is equal to one log in as user
{
user.showMaximized();
}
else {
dbManager.showMaximized();
}
}
else {
qWarning("Wrong Password or Username");
}
}

I think your query is wrong. Instead of writing like this:
queryModel->setQuery("SELECT * FROM [User Database] WHERE Username= username"); //select the row of where the Username == username
You might want writing like this:
queryModel->setQuery(QString("SELECT * FROM [User Database] WHERE Username = '%1'").arg(username)); //select the row of where the Username == username
Why? Because you are writing a query, and you probably want to check against the user name entered, not the string "username". Also, don't forget apostrophes when comparing.
In order to find more information which might help with your problem, you should read Qt's documentation regarding its' classes. Also, it would be beneficial to take a look into the SQLite WHERE clause and how strings are represented when writing queries:
https://doc.qt.io/qt-5/qsqlquerymodel.html#setQuery
https://doc.qt.io/qt-5/qsqlquery.html#QSqlQuery-1
http://www.sqlitetutorial.net/sqlite-where/
https://www.sqlite.org/datatype3.html

Related

Comparison of strings will not return true, even tough they are identical

I am currently creating a super simple login system for educational purpose only in Processing.
What i am doing in short is comparing the inputs from 2 textfields created with the controllerP5-library, with information from a MySQL database which i am using the BezierSQlib-library to connect to. All of the code is contained in a method inside a class called DbHandler which has all of the code which is related to the database.
But the final if statement where i compare the retrieved password from the database with the password that is inputted by the user will not work. Even though the 2 strings are identical they it will not return true. I´ve tried just putting in " if('1234 == '1234')" and that returned true.
But if i do it like so "if(_rPass == '1234')" with the _rPass being the password from the database, and the password being set to 1234 it still returns false.
void loginCheck(String name, String password){ //This is the method that checks if the login information is correct
String _rPass; //where we store the retrieved password from the database
if(_msql.connect()){ //if there´s connection to the database
println("connection"); //we write out there´s a connection in the prompt
_msql.query("SELECT password FROM users WHERE username='" + name + "'"); //a query is done to find the matching password to the username
_msql.next(); //selects the next row in the retrieved table
if(_msql.getString(1) == null){ //if there´s no user with that username in the user table
println("wrong username"); //the username must be wrong
} //end if
else{ //if something is returned!
_rPass = _msql.getString(1); //the password from the database is stored in _rPass
if(_rPass == password) { //!!!THIS WILL NOT RETURN TRUE NO MATTER WHAT!!!
println("succesfull login!"); //if the strings are the same we´re logged in!
}
else{
println("wrong password");
}
}
}
}
The following code is a part of a "DbHandler" class which controls all of the code that is related to the database, and is being called in another class called "interface" through a method.
The part where the above method is activated is like so:
if(btn_login.isPositionWithinButton(mouseX,mouseY)){ //checks if the login button has been clicked
DbHandler.loginCheck( cp5.get(Textfield.class,"username").getText(), cp5.get(Textfield.class,"password").getText() ); //the loginCheck method is called with the arguments being the text from the textFields
}
Thanks in advance!
Use string. equal method instead of ==.
As == compares the reference so it will return false if reference is not same.
To compare value of string use equal method.
i. e. If (_rpass.equals(password)){}

how to inject sql in login process

I've received an old application which completely lacks user input sanitization and is vulnerable to sql injection. To prove gravity of the situation i need to give client an example and what can be better to scare him than the login process. I've tried standard techniques but the problem with them is that they return multiple rows and due to nature of the code it returns an error instead of logging him in. What sql should i inject so that only a single row is returned and the execution reaches "return $access" line in order to pass the value of this "access" column to code calling this login function. The request is made via POST method and magic quotes are off on the server. Please let me know if you need any other information.
function login($username, $pw)
{
global $dbname, $connection, $sqluser, $sqlpw;
$db = mysql_connect($connection,$sqluser,$sqlpw);
mysql_select_db($dbname);
if(!($dba = mysql_query("select * from users where username = '$username' AND password = '$pw'"))){
printf("%s", sprintf("internal error5 %d:%s\n", mysql_errno(), mysql_error()));
exit();
}
$row = mysql_fetch_array($dba);
$access = $row['access'];
if ($access != ''){
return $access;
} else {
return "error occured";
}
mysql_close ($db);
}
Note: it turns out that magic_quotes_gpc is turned on and the php version is 5.2.17
Thanks
Starting with the goal query:
SELECT *
FROM users
WHERE username = '' OR '1'='1'
AND password = '' OR 1=1 LIMIT 1;#'
We get username is ' OR '1'='1 and password is ' OR 1=1 LIMIT 1;#
It depends what values the login function is called with. If there's sanitation before passing it to the function it might actually be safe. However it's better to filter it right before the query so you can see that your built query is safe.
However if you have something like this:
login($_POST['user'], $_POST['pass']);
In that case just put foo' OR 1=1 OR ' in the user field in the login form :)

Issue in setting password for existing in JDBC MS Access Workgroup (MDW) Java

Here is my Scenario
I have MS Access DB (MDB file), and work group security file. I have credentials which have all the permit (Administrator user). This DB and MDW file is created on some other computer and i am using it on my computer now.
What I am able to do till now is, I can log in the DB with different user name and password which are existing in the DB. Verified this by using Correct user name and wrong password It give error, but correct credentials it logins.
Now I need to create a interface In Java to basic functionality.
1. Change password of currently logged user.
Change password of current user
Following is my code to change the password
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String database = "jdbc:odbc:"+"mdbTEST";
// mdbTEST is created in System DNS which uses SECURED.MDW file and
// ExtendedAnsiSQL is set to 1
conn = DriverManager.getConnection(database, "administrator", "hello");
String q = "ALTER USER "+uname+" PASSWORD "+newPass+" '"+oldPass+"'";
stmt = conn.createStatement();
stmt.execute(q);
It returns successful.
But when I try to log in the with the username and new password it says wrong passowrd and even the old password stops working.
Moreover, I tried to read all the username and passwords in the WorkGroup file using some third party software, it shows the new password is updated correctly in the MDW file.
I am using JDK 1.7 on Windows XP 32 bit.
What can be the problem? Am I doing something wrong here?
Thanks in Advance.
If you want to put quotes around the password values to accommodate passwords that contain spaces, you should enclose them in double quotes ("). If you enclose them in single quotes (') then the single quote characters become part of the password. For example, after executing my test code...
import java.sql.*;
public class ulsTest {
public static void main( String args[] )
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection(
"jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};" +
"DBQ=C:\\Users\\Public\\uls\\ulsTest.mdb;" +
"SystemDB=C:\\Users\\Public\\uls\\Security.mdw;" +
"Uid=Gord;" +
"Pwd=obfuscated;" +
"ExtendedAnsiSQL=1;");
String UID = "Tim";
String oldPWD = "oldpassword";
String newPWD = "I like Java";
Statement s = conn.createStatement();
s.execute("ALTER USER " + UID + " PASSWORD \"" + newPWD + "\" \"" + oldPWD + "\"");
// ALTER USER Tim PASSWORD "I like Java" "oldpassword"
System.out.println("User updated.");
s.close();
conn.close();
}
catch( Exception e ) {
e.printStackTrace();
}
}
}
...Tim is able to log in using the new password
I like Java
However, if I change my code to...
s.execute("ALTER USER " + UID + " PASSWORD '" + newPWD + "' '" + oldPWD + "'");
// ALTER USER Tim PASSWORD 'I like Java' 'oldpassword'
...then the single quotes become part of the new password and Tim must type the password...
'I like Java'
...(including the single quotes) to log in.
Side note: I was hoping that a parameterized query might avoid messing with string quoting, but unfortunately the code...
PreparedStatement s = conn.prepareStatement("ALTER USER ? PASSWORD ? ?");
s.setString(1, UID);
s.setString(2, newPWD);
s.setString(3, oldPWD);
s.execute();
...fails with the error:
[Microsoft][ODBC Microsoft Access Driver] Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'.

Multiple databases on one SQL server with same table names. Two Linq to SQL Classes - Ambiguity error

I'm trying to write a tool which will update a users account credentials across several databases. Each of these databases are basically supporting a different version of the same application so each database has the same table names. I'm only interested in one table called opususer on each of these databases.
I was able to create the first Linq to SQL class and using a checkbox list I create a collection of selected items and send it to a method which loops through and should update the user credentials. This works fine when I have one DataContext, but when I add another Linq to SQL class and try to recreate the same thing except on a different database I receive several Ambiguity errors and "The member is defined more than once" errors.
I don't understand as the LinqToSQL class is pointing to a completely different database although the table name is the same, but why should that matter as the datacontext should keep it separate no?
I've tried using one DataContext and also adding an alias, but I'm not sure if this can be done. I'm new to ASP.NET...
if (DatabaseName == "clincomm_243x")
{
using (UserAccountDataContext Data = new UserAccountDataContext()) // database clincomm_243x
{
string UserName = TextBoxUserName.Text.ToUpper();
opususer CheckUser = Data.opususers
.SingleOrDefault(opususer => opususer.username == UserName && opususer.active == true);
if (CheckUser == null || TextBoxUserName.Text.Length ==0)
{
TextBoxResult.Visible = true;
TextBoxResult.Text = "Username " + UserName + " does not exist. Please check and try again!";
}
else
{
TextBoxResult.Text = "";
TextBoxResult.Text = "User " + UserName + " has been found.";
TextBoxResult.Visible = true;
TextBoxResult.Visible = true;
TextBoxResult.Text += "\nAttempting to update user account details.....\n";
// Set the new values for the record returned
CheckUser.password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4";
CheckUser.hashtype_code = "SHA-256";
CheckUser.unsuccessfullogons = 0;
CheckUser.active = true;
DateTime newPasswordExpiryDate = DateTime.Now.Date.AddYears(10);
CheckUser.passwordexpirationdate = newPasswordExpiryDate;
Data.SubmitChanges();
TextBoxResult.Text += "\nUser Account " + UserName + " has been successfully updated\n";
TextBoxResult.Text += "\nPassword has now been set to 1234 and will not expire until " + newPasswordExpiryDate;
}
}
}
Even though you are using a new data context, the classes that represent your table(s) will reside in the same namespace - unless you specify a different namespace. Try giving unique namespaces to the "Entity Namespace" property for each of your DataContexts.

How to validate username from MySql with JSP

hello guys i am try to validate username from the database with the username that the user entered in the html from, assume
un//be the variable where username entered now from html form is stored
now how to retrieve all the columns of the uname from user table
uname //column name in mysql for usernames
user //table name in mysql
and check weather the username i.e,un entered now is present or not in the database
i am using
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/mebps","root","admin");
Statement stmt = (Statement) con.createStatement();
ResultSet rs = stmt.executeQuery("select un from userinfo");
while(rs.next())
{
if(rs.getString("uname") == un)
{
out.println("user is present");
}
}
There are at least two major mistakes:
You're comparing string instances by == instead of comparing their values by equals() method. The proper line would be if (rs.getString("uname").equals(un)).
You're not letting the DB do the job of returning the right row, instead you're copying the entire DB table into Java's memory and doing the comparison in Java. This is very inefficient. Make use of SQL powers the smart way so that it always returns exactly the information you need. There's for example a WHERE clause.
On an unrelated note, you seem not to be closing DB resources properly after use. This will result in resource leaking which is also a bad idea as it may cause your application to crash on long term. Further, the column name uname and un are not the same. But I'll assume it to be careless oversimplifying of the example.
Here's a minor rewrite:
public boolean exist(String username) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
boolean exist = false;
try {
connection = database.getConnection();
statement = connection.prepareStatement("SELECT uname FROM userinfo WHERE uname=?");
statement.setString(1, username);
resultSet = statement.executeQuery();
exist = resultSet.next();
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
return exist;
}
You see, if there's a match, then it returns true (at least one record), otherwise false (no one record). No need to copy the entire table into Java's memory and crawl through it in Java.
Last but not least, this code doesn't belong in a JSP file, but in a normal Java class, starting with a servlet. See also our servlets wiki page to learn more about it.