-
New to C++
i am trying to scirpt a loggin program for a project of mine i do not have that much programming experience and have only been using C++ for around 3 days, i think i have done ok to write this so far but you may not and this would really help me to know that what i have done is wrong,
here is what i have so far
Code:
// Login program
#include <iostream>
#include <string>
using namespace std;
int main()
{
string user;
string username = "john";
string pass;
string password = "hello";
cout << "\tWelcome to Login\n\n";
do
{
cout << "Enter your Username: ";
cin >> user; // put Username into user
cout << "Enter your Password: ";
cin >> pass; // put passoword into pass
if (user + pass == username + password) // If Username & Password are correct then will state
cout << "Correct Username & Passowrd\n\n";
if (user + pass != username + password) // If Usename & Password are incorrect then will state
cout << "Incorrect Username or Password\n\n";
}
while (user + pass != username + password); // While User & Pass is not equal to the Username + Password
cout << "\nConnecting to Login server.\n\n";
return 0;
}
ok i hope this is ok and all, BUT here is where i am stuck i do not want to have to store X amount of strings in this C++ document what i would like to be able to do is store them in a database and have say 200 logins and username and password pairs that can be accessed through the login program above, i do not know is his is even possible, the problem with me storing the passwords and usernames in this program is that they can get crossed eg
User1 can use User2's password and this makes it unsecure and means that there is a higher chance that anyone can get in by just random guessing, also on most password/login programs the password dose not apper as letters but as * could anyone give me advice or show me to a link that will explain it all to me.
Best wishes
Oscardin
-
try std::vector
have two vectors, one storing the usernames, the other one storing the passwords
make sure their indexes are aligned (eg. usernames[1] corresponds to passwords[1])
then you can iterate through the vectors to find a match.
Also, I don't know if what you have written is valid (never seen it written like that, but my experience is rather limited), but I would have done it this way -
Code:
if (user == username && pass == password) // If Username & Password are correct then will state
cout << "Correct Username & Passowrd\n\n";
else // If Usename & Password are incorrect then will state
cout << "Incorrect Username or Password\n\n";
-
Ok, so this is not so easy as it may seem.
There was a rather lengthy discussion on how to enter passwords (without seeing the actual text). If you search for "password" in the Search function, then you should find it not so far back. Note that it will depend on your actual system how to solve this - the post I'm referring to is using Windows native calls, so it won't work on Unix/Linux.
Forcing people to have a unique password is actually not increasing security - if you try to use password "Hello", and you get the message "This password is already in use" - wouldn't that give you some information you previously didn't have?
You don't really need to store the password in a DATABASE [unless you have tens of thousands of users], but you do need to store them in some sort of persistant storage - such as a file. One method would be to store the MD5 as a base64 value. [look up those terms]
If you store your passwords in a file, make sure you do that in a encrypted way, so that anyone reading the file can't see the passwords [although you may, for simplicity during development wait to implement this until you have the actual data structure of your user "database".]
To do all of this, you'll need more experience, but I'm sure you can get some help here, and you will have to spend some time of your own on the problem.
--
Mats
-
On basic principle, every password system where passwords are stored locally and you have access to them before authenticating is easily crackable. Just overwrite the passwords. That works even if the passwords are hashed in order to prevent reading them.
Now. A password DB consists of pairs of usernames and passwords. E.g. a Unix shadow file contains something that looks roughly like
Code:
root:u9u0wufjskl39fm
frank:c28398n3892cpn5q8
bob:sm093un21n2390tus
alice:13n329s3j30935s3m2
Your program reads in a username and a password. (And sadly, there is no portable way to hide password input. On POSIX, you can use the readpass function to obtain a password, but the function is deprecated, apparently without replacement. (At least none I could find.))
Then you look up the username and the associated password in the passdb. If you don't find the username, it is invalid and you give an error. If you find it, you compare the given password with the one you found in the passdb.
A higher-level authentication mechanism on POSIX would be PAM, but that's a wholly different story.
-
Confirmaion
ok to use a vector i need to give the vector a name, size and type
so
Code:
vector <string> username (9)
and this would store upto 10 strings
then to set one of the elements in the sting i would need to do
Code:
username[0] = john
username[1] = smith
then i would also need to set the vector for password in the same fashion
so this would do as my storing method
seeking a little confermation a yes will do and please dont tell me exactly how to do i need to work it out for myself but someone saying im doing right or wrong is a big help
-
> and this would store upto 10 strings
No, 9 strings (in this case, the subscript ranges from 0 to 8).
-
Code:
username[0] = john
username[1] = david
would make more sense. At least, I take it that you mean that username[0] is one user, and username[1] is a different one - your example looks a bit like the user could be "John Smith" and the first name is stored at one index and the password at another.
And of course the same would apply to the password string, and of course, the username index and the password index are the same.
An alternative solution is to have a struct [or class] that holds your pair of data:
Code:
struct userinfo {
string username;
string password;
};
vector <userinfo> users;
This would help in the sense that you can easily get to the password directly.
Oh, and finally:
Your original code checks if username + password == user + pass. Let's say we have one user called "John" and the Password is "eHello", and another user "Johne" and a password "Hello" - both would then match! Test the password and username separately and you won't have that problem.
Can I also suggest that you have a numeric user-id - it makes life much easier in other places.
--
Mats
-
so you mean use
Code:
if (user == username)
if (pass == password)
cout << "correct username and password"
else
cout << "incorrect Username and password"
-
No. Enter a bad username and see what happens. You need to connect the two comparisons using a logical AND.
-
silly me sorry about that
Code:
if (user == username && pass == password) // If Username & password are correct
cout << "Correct Username & Passowrd\n\n";
else // If Usename & Password are incorrect then will state
cout << "Incorrect Username or Password\n\n";
so what they meant was this
-
well your nested for loops should work. stylistically it should look like this though:
Code:
if (user == username)
if (pass == password)
cout << "correct username and password"
else
cout << "incorrect Username and password"
This way both would have to be true.
I have a related anecdote. There was a text RPG that I played once that stored game saves to files. Well being the curious person that I am, I found the save file and started editing it. To my surprise, the next time I loaded the save file, it new I had cheated. I didn't see any traces of hashes or anything inside the file, so how did the app know? like passwords should be, the save file was kinda protected.
-
that would be interpreted as:
Code:
if (user == username)
if (pass == password)
cout << "correct username and password";
else
cout << "incorrect Username and password";
to have it as you indented it, use braces:
Code:
if (user == username)
{
if (pass == password)
cout << "correct username and password";
} else
cout << "incorrect Username and password";
-
yeah, I just copied his thing and indented it. I'm pretty sure he understood what I was saying. Besides the way i had it would merely not declare that the pair was rejected.
-
That actually doesn't work, though, because the error message only gets displayed if the username is wrong and not if the password is wrong.