Page 1 of 1

User.Disconnect?

Posted: 10 Dec 2010, 05:14
by dragagon
I have a server running with an extension.
I have the user log in with no password.

The reason the user logs in with no password is because the webserver stores the password in a salted hash. So because SmartFox encrypts the password for safety, I cannot recreate the salted hash by asking the db for the password field.

The server and client then exchange public keys and they can encrypt/decrypt data just fine, I tested that.
I then have the user log in by passing encrypted strings for username and password that are checked against my website's user/pass.

Now here is my question. I validate they have the correct data when entered correctly, so I will be passing the correct success message. However, on an error or invalid password I want to disconnect the user. So I was calling

Code: Select all

User.Disconnect(ClientDisconnectReason.valueOf("Username or Password is incorrect."));
to force the user to be disconnected (authoritative server)

For the life of me I cannot figure out what message, if any, is coming across to Unity3d to inform me that we are no longer connected so I can show the message and kick the user back to the login screen. Is there a message or do I need to go to the effort of sending back a notification with a failure like OnLogin?

Posted: 10 Dec 2010, 14:00
by Lapo
Hi
I don't understand where User.Disconnect is coming from.
Is this server side code?
If so this is not the right approach. Always use the API, via the SFSApi class which is available in your extension calling getAPI()

There you find a method for disconnecting the user.
http://docs2x.smartfoxserver.com/api-do ... FSApi.html

Additionally the Disconnection Reason is not customizable, it's an Enum:
http://docs2x.smartfoxserver.com/api-do ... eason.html

If you want you can send a custom message to the client before disconnecting him. See the kickUser method which allows to send a custom message.

Posted: 10 Dec 2010, 16:06
by dragagon
Lapo,

Thanks, the API call works. I was trying to use the User.Disconnect since I didn't see any other way to kick them. Now that I can kick them, the documentation doesn't make it clear how to retrieve the kick message so I can display it to the user. For now I'm going to write separate functions to see which message type it is so I can get the text to display to the user.

--Update found it in the Mod message.

--Feature Request: Is there any way to also send it with the disconnection? It would make more sense to be able to have it there, otherwise it could be confused with any other moderator message, or better yet as its own "Kick/Ban" message type.

Posted: 10 Dec 2010, 18:33
by Democre
Just a quick ideological rather than technical note.

It seems to me that kicking a user for mistyping a username/password combination is not appropriate. It is telling the user that, "Hey, you are wrong, and if you keep it up, you won't be able to play here."

Instead, if you are validating username/password in a custom login handler, you can throw a SFSLoginException with appropriate error data. This will stop the login process and is also handled in the client API separately from kick/ban messages.

What you have works, though, so be it.

Posted: 10 Dec 2010, 18:50
by dragagon
Andy,

I think you may have missed my paragraph in the middle. My Web Server has a registration and stores the password in its own fashion. Unless the Custom Login Handler can give me the password as plain text on the server, its useless as I cannot rebuild the password on the server unless it is in plain text.

For security reasons I will not add the password in clear text to the list of parameters on login. In order to encrypt/decrypt the password I either need to hard code the public key into the client or send generated keys across the wire. In order to send generated keys across the wire, i have to have a logged in user.

In my code I do not actually connect the user until they hit the login button with the user/pass filled in, so kicking them facilitates the return to the login screen very well.

Posted: 10 Dec 2010, 20:44
by Democre
Sorry about that, I had read over the webserver and the transmission of public keys.

I too am storing salted MD5 hashes of passwords in my db.

In the client I salt and hash the user's clearText password in the same manner.

I then send the saltedHash as the password parameter in the login request.

On the server I call the following in the handler:

Code: Select all

 ...
SFSErrorData errData = new SFSErrorData(SFSErrorCode.LOGIN_BAD_USERNAME);
String name = (String) event.getParameter(SFSEventParam.LOGIN_NAME);
String password = (String) event.getParameter(SFSEventParam.LOGIN_PASSWORD);
ISession session = (ISession) event.getParameter(SFSEventParam.SESSION);
errData.addParameter(name);

String dbPass = getPasswordFromDb(name);

if(getApi().checkSecurePassword(session, dbPass, password.toLowerCase())){
    /*do some stuff like setting session properties returning other fields from db, etc...*/
} else {
   throw new SFSLoginException("Bad username or password", errData);
}
...
If you want to use the public/private key you can still send the password encrypted with the public key in the LoginEvent as additional parameters.
Before checking if the passwords match, you would need to decrypt the dbPassword and then encrypt it with the public key.

If you want to deal with generated keys instead of hardcoding a public key, you could do a guest login to a keymanager zone, request a key for a username (store the private key in the server for that username) and then encrypt and use the login event as above. The custom login handler would need to look up the private key for the incoming user name and decrypt before matching the passwords as above.