From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../x-cvsweb-markup&sortby=author/index.html | 508 +++++++++++++++++++++ 1 file changed, 508 insertions(+) create mode 100644 cvs/cvsweb.cgi/code/nelns/login_service/connection_client.cpp?rev=1.11&content-type=text/x-cvsweb-markup&sortby=author/index.html (limited to 'cvs/cvsweb.cgi/code/nelns/login_service/connection_client.cpp?rev=1.11&content-type=text') diff --git a/cvs/cvsweb.cgi/code/nelns/login_service/connection_client.cpp?rev=1.11&content-type=text/x-cvsweb-markup&sortby=author/index.html b/cvs/cvsweb.cgi/code/nelns/login_service/connection_client.cpp?rev=1.11&content-type=text/x-cvsweb-markup&sortby=author/index.html new file mode 100644 index 00000000..19d52d3b --- /dev/null +++ b/cvs/cvsweb.cgi/code/nelns/login_service/connection_client.cpp?rev=1.11&content-type=text/x-cvsweb-markup&sortby=author/index.html @@ -0,0 +1,508 @@ + + + +code/nelns/login_service/connection_client.cpp - view - 1.11 + +
[BACK] Return to connection_client.cpp + CVS log [TXT][DIR] Up to Nevrax / code / nelns / login_service

File: Nevrax / code / nelns / login_service / connection_client.cpp (download)
+Revision 1.11, Mon Mar 25 09:29:24 2002 UTC (4 months ago) by lecroart +
Branch: MAIN +
CVS Tags: HEAD
Changes since 1.10: +3 -3 + lines
+CHANGED: use new service functions
+
+

/** \file login_service.cpp
+ * Login Service (LS)
+ *
+ * $Id: connection_client.cpp,v 1.11 2002/03/25 09:29:24 lecroart Exp $
+ *
+ */
+
+/* Copyright, 2000 Nevrax Ltd.
+ *
+ * This file is part of NEVRAX NeL Network Services.
+ * NEVRAX NeL Network Services is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * NEVRAX NeL Network Services is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NEVRAX NeL Network Services; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#include "nel/misc/types_nl.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+
+#include <vector>
+#include <map>
+
+#include "nel/misc/debug.h"
+#include "nel/misc/config_file.h"
+#include "nel/misc/displayer.h"
+#include "nel/misc/log.h"
+
+#include "nel/net/service.h"
+#include "nel/net/net_manager.h"
+#include "nel/net/login_cookie.h"
+#include "login_service.h"
+
+#define CRYPT_PASSWORD 1
+
+#if defined(NL_OS_UNIX) && CRYPT_PASSWORD
+extern "C" char *crypt (const char *__key, const char *__salt);
+#endif
+
+using namespace std;
+using namespace NLMISC;
+using namespace NLNET;
+
+
+// These functions enable crypting password, work only on unix
+
+const uint32 EncryptedSize = 13;
+
+// Get a number between 0 and 64, used by cryptPassword
+static uint32 rand64 ()
+{
+        return (uint32) floor(64.0*(double)rand()/((double)RAND_MAX+1.0));
+}
+
+// Crypt a password
+string cryptPassword (const string &password)
+{
+#if defined(NL_OS_UNIX) && CRYPT_PASSWORD
+        if (CryptPassword)
+        {
+                char Salt[3];
+                static char SaltString[65] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
+
+                Salt[0] = SaltString[rand64()];
+                Salt[1] = SaltString[rand64()];
+                Salt[2] = '\0';
+
+                return string (crypt (password.c_str(), Salt));
+        }
+        else
+                return password;
+#else
+        return password;
+#endif
+}
+
+// Check if a password is valid
+bool checkPassword (const string &password, const string &encrypted)
+{
+#if defined(NL_OS_UNIX) && CRYPT_PASSWORD
+        if (CryptPassword)
+        {
+                char Salt[3];
+
+                if (encrypted.size() != EncryptedSize)
+                {
+                        nlwarning ("checkPassword(): \"%s\" is not a valid encrypted password", encrypted.c_str());
+                        return false;
+                }
+
+                Salt[0] = encrypted[0];
+                Salt[1] = encrypted[1];
+                Salt[2] = '\0';
+
+                return encrypted == crypt (password.c_str(), Salt);
+        }
+        else
+        {
+                return encrypted == password;
+        }
+#else
+        return encrypted == password;
+#endif
+}
+
+sint findUser (string &login)
+{
+        for (sint i = 0; i < (sint) Users.size (); i++)
+        {
+                if (Users[i].Login == login)
+                {
+                        return i;
+                }
+        }
+        // user not found
+        return -1;
+}
+
+void addUser (string &login, string &password)
+{
+        if (findUser (login) == -1)
+        {
+                Users.push_back (CUser (login, cryptPassword(password)));
+                writePlayerDatabase ();
+        }
+        else
+        {
+                nlwarning ("user '%s' already exists in the base", login.c_str ());
+        }
+}
+
+sint userToLog(sint userPos)
+{
+        if (userPos == -1) return userPos;
+        else return Users[userPos].Id;
+}
+
+
+bool stringIsStandard(const string &str)
+{
+        for (sint i = 0; i < (sint) str.size(); i++)
+        {
+                if (!isalnum (str[i])) return false;
+        }
+        return true;
+}
+
+bool havePrivilege (string userPriv, string shardPriv)
+{
+        if (userPriv == "::")
+        {
+                return shardPriv == "::";
+        }
+        else
+        {
+                if (shardPriv == "::")
+                        return true;
+                else
+                        return userPriv.find (shardPriv) != string::npos;
+        }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////// CONNECTION TO THE CLIENTS //////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Callback for service unregistration.
+ *
+ * Message expected :
+ * - nothing
+ */
+static void cbClientVerifyLoginPassword (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+{
+        // reason is empty if everything goes right or contains the reason of the failure
+        string reason = "";
+
+        //
+        // S03: check the validity of the client login/password and send "VLP" message to client
+        //
+
+        string Login, Password;
+        msgin.serial (Login);
+        msgin.serial (Password);
+
+        sint userPos = findUser (Login);
+        const CInetAddress &ia = netbase.hostAddress (from);
+
+        Output.displayNL ("***: %3d Login '%s' Ip '%s'", userToLog(userPos), Login.c_str(), ia.asString().c_str());
+
+        // recv the client version and check it
+
+        uint32 ClientVersion;
+        msgin.serial (ClientVersion);
+        if (ClientVersion < ServerVersion || ClientVersion > ServerVersion)
+        {
+                // reject the use, bad version
+                if (ClientVersion < ServerVersion)
+                        reason = "Your client is out of date. You have to download the last version.";
+                else
+                        reason = "Your client is too new compare to the server. You have to get an older version of the client.";
+                Output.displayNL ("---: %3d Bad Version, ClientVersion: %d ServerVersion: %d", userToLog(userPos), ClientVersion, ServerVersion);
+        }
+
+        // recv client hardware info
+
+        string OS, Proc, Mem, Gfx;
+
+        msgin.serial (OS);
+        msgin.serial (Proc);
+        msgin.serial (Mem);
+        msgin.serial (Gfx);
+
+        if (!OS.empty()) Output.displayNL ("OS : %3d %s", userToLog(userPos), OS.c_str());
+        if (!Proc.empty()) Output.displayNL ("PRC: %3d %s", userToLog(userPos), Proc.c_str());
+        if (!Mem.empty()) Output.displayNL ("MEM: %3d %s", userToLog(userPos), Mem.c_str());
+        if (!Gfx.empty()) Output.displayNL ("GFX: %3d %s", userToLog(userPos), Gfx.c_str());
+
+        // check the login & pass
+
+        if (reason.empty() && !stringIsStandard (Login))
+        {
+                // reject the new user, bad login format
+                reason = "Bad login format, only alphanumeric character";
+                Output.displayNL ("---: %3d Bad Login Format", userToLog(userPos));
+        }
+
+        if (reason.empty() && !stringIsStandard (Password))
+        {
+                // reject the new user, bad password format
+                reason = "Bad password format, only alphanumeric character";
+                Output.displayNL ("---: %3d Bad Password Format", userToLog(userPos));
+        }
+
+        if (reason.empty())
+        {
+                if (userPos == -1)
+                {
+                        // unknown user
+                        if (AcceptNewUser)
+                        {
+                                // add the new user
+                                addUser (Login, Password);
+                                // take the new user entry
+                                userPos = findUser (Login);
+                                Output.displayNL ("---: %3d New User (new id:%d)", -1, userToLog(userPos));
+                        }
+                        else
+                        {
+                                // reject the new user
+                                reason = "Bad login";
+                                Output.displayNL ("---: %3d Bad Login", userToLog(userPos));
+                        }
+                }
+                else
+                {
+                        // check id the account is active
+
+                        if (!Users[userPos].Active)
+                        {
+                                reason = "Your account was disactivated";
+                                Output.displayNL ("---: %3d Your account was disactivated", userToLog(userPos));
+                        }
+                        else if (!checkPassword (Password, Users[userPos].Password))
+                        {
+                                // error reason
+                                reason = "Bad password";
+                                Output.displayNL ("---: %3d Bad Password", userToLog(userPos));
+                        }
+                        else
+                        {
+                                Output.displayNL ("---: %3d Ok", userToLog(userPos));
+                        }
+                }
+        }
+
+        if (reason.empty())
+        {
+                reason = Users[userPos].Authorize (from, netbase);
+        }
+
+        uint32 nbshard = 0;
+        if (reason.empty())
+        {
+                // count online shards
+                for (uint i = 0; i < Shards.size (); i++)
+                {
+                        // add it only if the shard is on line and the user can go to this shard
+                        if (Shards[i].Online && havePrivilege(Users[userPos].ShardPrivilege, Shards[i].ShardName))
+                        {
+                                nbshard++;
+                        }
+                }
+                if (nbshard==0)
+                {
+                        reason = "No shards available";
+                }
+
+        }
+
+        CMessage msgout (netbase.getSIDA (), "VLP");
+
+        if (reason.empty())
+        {
+                uint8 ok = 1;
+                msgout.serial (ok);
+
+                // send number of online shard
+                msgout.serial (nbshard);
+
+                // send address and name of all online shards
+                for (uint i = 0; i < Shards.size (); i++)
+                {
+                        if (Shards[i].Online && havePrivilege (Users[userPos].ShardPrivilege, Shards[i].ShardName))
+                        {
+                                // serial the name of the shard
+                                string shardname;
+                                shardname = Shards[i].Name;
+
+                                if (Shards[i].NbPlayers == 0)
+                                {
+                                        shardname += " (no users)";
+                                }
+                                else
+                                {
+                                        char num[1024];
+                                        smprintf(num, 1024, "%d", Shards[i].NbPlayers);
+                                        shardname += " (";
+                                        shardname += num;
+                                        if (Shards[i].NbPlayers == 1)
+                                                shardname += " user)";
+                                        else
+                                                shardname += " users)";
+                                }
+                                msgout.serial (shardname);
+                                
+                                // serial the address of the WS service
+                                msgout.serial (Shards[i].WSAddr);
+                        }
+                }
+                netbase.send (msgout, from);
+
+                netbase.authorizeOnly ("CS", from);
+        }
+        else
+        {
+                // put the error message
+                uint8 ok = 0;
+                msgout.serial (ok);
+                msgout.serial (reason);
+                netbase.send (msgout, from);
+// FIX: On linux, when we disconnect now, sometime the other side doesnt receive the message sent just before.
+//      So it's the other side to disconnect
+//              netbase.disconnect (from);
+        }
+}
+
+static void cbClientChooseShard (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+{
+        //
+        // S06: receive "CS" message from client
+        //
+
+        // first find if the user is authorized
+        for (vector<CUser>::iterator it = Users.begin (); it != Users.end (); it++)
+        {
+                if ((*it).Authorized && (*it).SockId == from)
+                {
+                        // it's ok, so we found the wanted shard
+                        string WSAddr;
+                        msgin.serial (WSAddr);
+
+                        for (sint32 i = 0; i < (sint32) Shards.size (); i++)
+                        {
+                                if (Shards[i].Online && Shards[i].WSAddr == WSAddr && havePrivilege ((*it).ShardPrivilege, Shards[i].ShardName))
+                                {
+                                        CMessage msgout (CNetManager::getNetBase("WSLS")->getSIDA (), "CS");
+                                        const CInetAddress &ia = netbase.hostAddress ((*it).SockId);
+                                        msgout.serial ((*it).Cookie);
+                                        CNetManager::send("WSLS", msgout, Shards[i].SockId);
+                                        beep (1000, 1, 100, 100);
+                                        return;
+                                }
+                        }
+                        // the shard is not available, denied the user
+                        nlwarning("User try to choose a shard without authorization");
+
+                        CMessage msgout (netbase.getSIDA (), "SCS");
+                        uint8 ok = false;
+                        string reason = "Selected shard is not available";
+                        msgout.serial (ok);
+                        msgout.serial (reason);
+                        netbase.send (msgout, from);
+// FIX: On linux, when we disconnect now, sometime the other side doesnt receive the message sent just before.
+//      So it's the other side to disconnect
+//                      netbase.disconnect (from);
+                        return;
+                }
+        }
+
+        // the user isn t authorized
+        nlwarning("User try to choose a shard without authorization");
+        // disconnect him
+        netbase.disconnect (from);
+}
+
+static void cbClientConnection (const string &serviceName, TSockId from, void *arg)
+{
+        CCallbackNetBase *cnb = CNetManager::getNetBase("LS");
+        const CInetAddress &ia = cnb->hostAddress (from);
+
+        nldebug("new client connection: %s", ia.asString ().c_str ());
+
+        Output.displayNL ("CCC: Connection from %s", ia.asString ().c_str ());
+
+        if (ia.asString().find ("nevrax") != string::npos)
+        {
+                // internal connection
+                beep ();
+        }
+        else
+        {
+                // external connection
+                beep (1000, 2, 100, 100);
+        }
+
+        cnb->authorizeOnly ("VLP", from);
+}
+
+static void cbClientDisconnection (const string &serviceName, TSockId from, void *arg)
+{
+        CCallbackNetBase *cnb = CNetManager::getNetBase("LS");
+        const CInetAddress &ia = cnb->hostAddress (from);
+
+        nldebug("new client disconnection: %s", ia.asString ().c_str ());
+
+        // remove the user if necessary
+        for (vector<CUser>::iterator it = Users.begin (); it != Users.end (); it++)
+        {
+                if ((*it).SockId == from)
+                {
+                        if ((*it).State == CUser::Awaiting)
+                        {
+                                // the user is disconnected from me because he have to connect to the front end right now, so we wait...
+                        }
+                        else
+                        {
+                                // prematurated disconnection, clean everything
+                                disconnectClient (*it, false, false);
+                        }
+                        (*it).SockId = NULL;
+                        return;
+                }
+        }
+}
+
+
+const TCallbackItem ClientCallbackArray[] =
+{
+        { "VLP", cbClientVerifyLoginPassword },
+        { "CS", cbClientChooseShard },
+};
+
+// if you add callback in the client side, don't forget to add it here!!!
+static const char *OtherSideAssociations[] =
+{
+        "AA",
+        "RA",
+        "RAA",
+        "VLP",
+        "SCS",
+};
+
+void connectionClientInit ()
+{
+        CNetManager::addCallbackArray ("LS", ClientCallbackArray, sizeof(ClientCallbackArray)/sizeof(ClientCallbackArray[0]));
+        CNetManager::setConnectionCallback ("LS", cbClientConnection, NULL);
+        CNetManager::setDisconnectionCallback ("LS", cbClientDisconnection, NULL);
+        CNetManager::getNetBase("LS")->setOtherSideAssociations(OtherSideAssociations, sizeof(OtherSideAssociations)/sizeof(OtherSideAssociations[0]));
+}
+
\ No newline at end of file -- cgit v1.2.1