Click here to Skip to main content
14,698,365 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
hi my name is vishal i am process of developing my application named:Mini Project in c# windows forms with sql server 2008.
For 3 days i have been breaking my head on how to display a message box telling he/she has exceeded her limit for today of entering into the application after 3 unsuccessful attempts by him/her in c# windows forms with sql server 2008.

I have a login form named:frmLogin.
My default username:admin and default password:password is for entering into the application.
Given below is my c# code of frmLogin:
using System.Data.SqlClient;
using System.Management;
using System.Runtime.InteropServices;
using System.Net;
namespace Mini_Project
{
    public partial class frmLogin : Form
    {
int hit;
        public frmLogin()
        {
            InitializeComponent();
        }
private void btnLogin_Click(object sender, EventArgs e)
        {
            if ((txtPassword.Text == "password") && (txtUsername.Text.ToLower() == "admin"))
            {
                MDIParent1 h = new MDIParent1();
                h.Show();
                this.Close();
            }
            else
            {
                string username = txtUsername.Text;
                string password = txtPassword.Text;
                bool validUser = ValidateUser(username, password);
                if (validUser)
                {
                   
                    MDIParent1 m = new MDIParent1();
                    m.Show();
                    this.Close();
                }
                else
                {
                    MessageBox.Show("Invalid user name or password. Please try with another user name or password", "Task", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    txtUsername.Focus();
                }
               
            }
}
private bool ValidateUser(string username, string password)
        {
            bool success = false;
            SqlConnection conn = new SqlConnection("Data Source=NPD-4\\SQLEXPRESS;Initial Catalog=Task;Integrated Security=true");
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd = new SqlCommand("Select @count = Count(*) from [dbo].[UserDetail] where username=@username and password=@password", conn);
            cmd.Parameters.AddWithValue("@username", txtUsername.Text);
            cmd.Parameters.AddWithValue("@password", txtPassword.Text);
            cmd.Parameters.Add("@count", SqlDbType.Int).Direction = ParameterDirection.Output;
            conn.Open();
            cmd.ExecuteNonQuery();
            if (Convert.ToInt32(cmd.Parameters["@count"].Value) > 0)
            {
                success = true;
                cmd = new SqlCommand("Update [dbo].[UserDetail] set LoginAttempts=0 where username='" + txtUsername.Text + "'", conn);
                cmd.ExecuteNonQuery();
            }
            else
            {
                success = false;
                cmd = new SqlCommand("Update [dbo].[UserDetail] set LoginAttempts=LoginAttempts+1 where username='"+txtUsername.Text+"'", conn);
                cmd.ExecuteNonQuery();
            }
conn.Close();
            return success;
        }
    }
}

The above code works fine to some extent! But not the way i want!
Given below is structure of my table:UserDetail in sql server 2008
ColumnName DataType AllowNulls
user_id(auto-increment primary key) Int No
user_first_name nvarchar(50) Yes
user_last_name nvarchar(50) Yes
user_dob date Yes
user_sex nvarchar(20) Yes
email nvarchar(80) Yes
username nvarchar(25) Yes
password nvarchar(15) Yes
user_type Int Yes
status bit Yes
row_upd_date datetime Yes
LoginAttempts Int Yes

As you can see that i increment my LoginAttempts of username by 1 upon unsuccessful attempt
and reset it to 0 upon successful attempt/login.

What i want is when LoginAttempts of that username is greater than 3 then i want a message box with message "User has exceeded his limits of login for today."

What i am trying to say/want is if LoginAttempts of that username is greater than 3 then then i want a message box with message "User has exceeded his limits of login for today." when the user press/click btnLogin in frmLogin(login form) that is what i want!
Can anyone help me please! Can anyone tell me/guide me on what modifications must i need to do in my c# code of frmLogin(login form) to achieve my required result? Any help/guidance in solving of this problem would be greatly appreciated!
Posted
Updated 24-Jul-14 0:03am
v3
Comments
Richard Deeming 19-Feb-15 7:50am
   
Your code is vulnerable to SQL Injection[^].

NEVER use string concatenation to build a SQL query. ALWAYS use a parameterized query.

You are also storing passwords in plain-text. That is a very bad idea. You should only ever store a salted hash of the password.
Secure Password Authentication Explained Simply[^]
Salted Password Hashing - Doing it Right[^]

You also need to store the last login attempt time so that you can block the login for 24 hours or so. You may use "row_upd_date" to store the last login attempt time.

Update this line of code in validateuser() in the else part
cmd = new SqlCommand("Update [dbo].[UserDetail] set LoginAttempts=LoginAttempts+1 where username='"+txtUsername.Text+"'", conn);

with following
cmd = new SqlCommand("Update [dbo].[UserDetail] set LoginAttempts= (case when datediff(row_upd_date,getdate())<24 then LoginAttempts+1 else 1 end),row_upd_date=getdate() where username='"+txtUsername.Text+"'", conn);

This will increment the counter only if the user has attempted within 24 hours of time else will reset the counter to 1.

Now, get the counter and if it is 3 or more than display the message.

In case, you need further assistance please let me know :)
   
Comments
Richard Deeming 19-Feb-15 7:50am
   
You have copied the SQL Injection[^] vulnerability from the question.

NEVER use string concatenation to build a SQL query. ALWAYS use a parameterized query.
Hi,
Try below code.
(May contain syntax error but help you to develop logic :) )

using System.Data.SqlClient;
using System.Management;
using System.Runtime.InteropServices;
using System.Net;
namespace Mini_Project
{
    public partial class frmLogin : Form
    {
int hit;
        public frmLogin()
        {
            InitializeComponent();
        }
private void btnLogin_Click(object sender, EventArgs e)
        {
            if ((txtPassword.Text == "password") && (txtUsername.Text.ToLower() == "admin"))
            {
                MDIParent1 h = new MDIParent1();
                h.Show();
                this.Close();
            }
            else
            {
                string username = txtUsername.Text;
                string password = txtPassword.Text;
                bool validUser = ValidateUser(username, password);
                if (validUser)
                {                   
                    MDIParent1 m = new MDIParent1();
                    m.Show();
                    this.Close();
                }
                else
                {
                    MessageBox.Show("Invalid user name or password. Please try with another user name or password", "Task", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    txtUsername.Focus();
                }               
            }
}
private bool ValidateUser(string username, string password)
        {
            bool success = false;
			SqlConnection conn = new SqlConnection("Data Source=NPD-4\\SQLEXPRESS;Initial Catalog=Task;Integrated Security=true");
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd = new SqlCommand("Select @count = Count(*) from [dbo].[UserDetail] where username=@username and password=@password and LoginAttempts >= 3 and datediff(day,row_upd_date,getdate())= 0", conn);
            cmd.Parameters.AddWithValue("@username", txtUsername.Text);
            cmd.Parameters.AddWithValue("@password", txtPassword.Text);
            cmd.Parameters.Add("@count", SqlDbType.Int).Direction = ParameterDirection.Output;
            conn.Open();
            cmd.ExecuteNonQuery();
			if (Convert.ToInt32(cmd.Parameters["@count"].Value) >= 1)
            {			
				 MessageBox.Show("User has exceeded his limits of login for today.", "Task", MessageBoxButtons.OK, MessageBoxIcon.Warning);
			}
			else
			{
				cmd = new SqlCommand("Select @count = Count(*) from [dbo].[UserDetail] where username=@username and password=@password ", conn);
				cmd.Parameters.AddWithValue("@username", txtUsername.Text);
				cmd.Parameters.AddWithValue("@password", txtPassword.Text);
				cmd.Parameters.Add("@count", SqlDbType.Int).Direction = ParameterDirection.Output;
				cmd.ExecuteNonQuery();
				if (Convert.ToInt32(cmd.Parameters["@count"].Value) > 0)
				{
					success = true;
					cmd = new SqlCommand("Update [dbo].[UserDetail] set LoginAttempts = (case when datediff(day,row_upd_date,getdate())=0 then LoginAttempts+1 else 0 end),row_upd_date=getdate() where username='" + txtUsername.Text + "'", conn);
					cmd.ExecuteNonQuery();
				}
				else
				{
					//No need to update LoginAttempts because this block will get execute only if username and password is not correct . 
					success = false;				
				}
			}
			conn.Close();
            return success;
        }
    }
} 
   
v3
Comments
Richard Deeming 19-Feb-15 7:50am
   
You have copied the SQL Injection[^] vulnerability from the question.

NEVER use string concatenation to build a SQL query. ALWAYS use a parameterized query.
Suvendu Shekhar Giri 19-Feb-15 7:57am
   
Yes, at that time I wanted to go for a simple solution. I'll update the answer soon.
Thanks for pointing the issue :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900