ServerAdminSessions.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <server/ServerAdminSessions.h>
00022 #include <server/ScorchedServer.h>
00023 #include <server/ServerCommon.h>
00024 #include <common/OptionsScorched.h>
00025 #include <common/Logger.h>
00026 #include <XML/XMLFile.h>
00027 #include <time.h>
00028 
00029 std::string ServerAdminSessions::PERMISSION_BANPLAYER("banplayer");
00030 std::string ServerAdminSessions::PERMISSION_KICKPLAYER("kickplayer");
00031 std::string ServerAdminSessions::PERMISSION_ALIASPLAYER("aliasplayer");
00032 std::string ServerAdminSessions::PERMISSION_ADDPLAYER("addplayer");
00033 std::string ServerAdminSessions::PERMISSION_VIEWLOGS("viewlogs");
00034 std::string ServerAdminSessions::PERMISSION_ALTERGAME("altergame");
00035 std::string ServerAdminSessions::PERMISSION_ALTERSERVER("alterserver");
00036 std::string ServerAdminSessions::PERMISSION_ALTERSETTINGS("altersettings");
00037 
00038 ServerAdminSessions *ServerAdminSessions::instance()
00039 {
00040         static ServerAdminSessions *instance = 
00041                 new ServerAdminSessions;
00042         return instance;
00043 }
00044 
00045 ServerAdminSessions::ServerAdminSessions()
00046 {
00047         localCreds_.password = "";
00048         localCreds_.username = "localaccount";
00049         localCreds_.permissions.insert(ServerAdminSessions::PERMISSION_BANPLAYER);
00050         localCreds_.permissions.insert(ServerAdminSessions::PERMISSION_KICKPLAYER);
00051         localCreds_.permissions.insert(ServerAdminSessions::PERMISSION_ALIASPLAYER);
00052         localCreds_.permissions.insert(ServerAdminSessions::PERMISSION_ADDPLAYER);
00053         localCreds_.permissions.insert(ServerAdminSessions::PERMISSION_VIEWLOGS);
00054         localCreds_.permissions.insert(ServerAdminSessions::PERMISSION_ALTERGAME);
00055         localCreds_.permissions.insert(ServerAdminSessions::PERMISSION_ALTERSERVER);
00056         localCreds_.permissions.insert(ServerAdminSessions::PERMISSION_ALTERSETTINGS);
00057 }
00058 
00059 ServerAdminSessions::~ServerAdminSessions()
00060 {
00061 }
00062 
00063 ServerAdminSessions::SessionParams *ServerAdminSessions::getFirstSession()
00064 {
00065         if (sessions_.empty()) return 0;
00066         return &(sessions_.begin()->second);
00067 }
00068 
00069 ServerAdminSessions::SessionParams *ServerAdminSessions::getSession(unsigned int sid)
00070 {
00071         const unsigned int SessionTimeOut = 60 * 15;
00072         unsigned int currentTime = (unsigned int) time(0);
00073 
00074         // Tidy expired sessions
00075         std::map <unsigned int, SessionParams>::iterator sitor;
00076         for (sitor = sessions_.begin();
00077                 sitor != sessions_.end();
00078                 sitor++)
00079         {
00080                 SessionParams &params = (*sitor).second;
00081                 if (currentTime > params.sessionTime + SessionTimeOut)
00082                 {
00083                         sessions_.erase(sitor);
00084                         break;
00085                 }
00086         }
00087 
00088         // Check if user has a valid session
00089         std::map <unsigned int, SessionParams>::iterator findItor =
00090                 sessions_.find(sid);
00091         if (findItor != sessions_.end())
00092         {
00093                 SessionParams &params = (*findItor).second;
00094                 if (currentTime < params.sessionTime + SessionTimeOut)
00095                 {
00096                         params.sessionTime = currentTime;
00097                         return &params;
00098                 }
00099                 else
00100                 {
00101                         sessions_.erase(findItor);
00102                 }
00103         }
00104 
00105         return 0;
00106 }
00107 
00108 unsigned int ServerAdminSessions::login(const char *name, const char *password, const char *ipAddress)
00109 {
00110         bool local = (0 == strcmp(ipAddress, "127.0.0.1"));
00111 #ifndef S3D_SERVER
00112         local = true;
00113 #endif
00114 
00115         // Find if the username and password match
00116         Credential userCreds;
00117         if (local)
00118         {
00119                 userCreds = localCreds_;
00120         }
00121         else
00122         {
00123                 bool found = false;
00124                 {
00125                         std::list<Credential> creds;
00126                         getAllCredentials(creds);
00127                         std::list<Credential>::iterator itor;
00128                         for (itor = creds.begin();
00129                                 itor != creds.end();
00130                                 itor++)
00131                         {
00132                                 Credential &credential = (*itor);
00133                                 if (0 == strcmp(name, credential.username.c_str()) &&
00134                                         0 == strcmp(password, credential.password.c_str()))
00135                                 {
00136                                         userCreds = credential;
00137                                         found = true;
00138                                         break;
00139                                 }
00140                         }
00141                 }
00142                 if (!found) return 0;
00143         }
00144 
00145         unsigned int sid = 0;
00146 
00147         // Try to find an existing session for this user
00148         std::map<unsigned int, SessionParams>::iterator itor;
00149         for (itor = sessions_.begin();
00150                 itor != sessions_.end();
00151                 itor++)
00152         {
00153                 SessionParams &params = (*itor).second;
00154                 if (0 == strcmp(params.credentials.username.c_str(), 
00155                         userCreds.username.c_str()))
00156                 {
00157                         // Found one
00158                         sid = (*itor).first;
00159                         break;
00160                 }
00161         }
00162 
00163         // Generate a sid if we didn't find an existing login
00164         if (sid == 0)
00165         {
00166                 // Generate a new unique session id
00167                 do 
00168                 {
00169                         sid = rand();
00170                 } while (sessions_.find(sid) != sessions_.end() || sid == 0);
00171         }
00172 
00173         // Update the session params
00174         unsigned int currentTime = (unsigned int) time(0);
00175         SessionParams params;
00176         params.sessionTime = currentTime;
00177         params.credentials = userCreds;
00178         params.ipAddress = ipAddress;
00179         params.sid = sid;
00180         sessions_[sid] = params;
00181 
00182         return sid;
00183 }
00184 
00185 void ServerAdminSessions::logout(unsigned int sid)
00186 {
00187         std::map <unsigned int, SessionParams>::iterator sitor =
00188                 sessions_.find(sid);
00189         if (sitor != sessions_.end())
00190         {
00191                 sessions_.erase(sitor);
00192         }
00193 }
00194 
00195 bool ServerAdminSessions::setPassword(const char *name, 
00196         const char *oldpassword, const char *newpassword)
00197 {
00198         std::list<Credential> creds;
00199         getAllCredentials(creds);
00200         std::list<Credential>::iterator itor;
00201         for (itor = creds.begin();
00202                 itor != creds.end();
00203                 itor++)
00204         {
00205                 Credential &credential = (*itor);
00206                 if (0 == strcmp(name, credential.username.c_str()) &&
00207                         0 == strcmp(oldpassword, credential.password.c_str()))
00208                 {
00209                         credential.password = newpassword;
00210                         setAllCredentials(creds);
00211                         return true;
00212                 }
00213         }
00214         return false;
00215 }
00216 
00217 bool ServerAdminSessions::setAllCredentials(std::list<Credential> &creds)
00218 {
00219         std::string fileName = 
00220                 S3D::getSettingsFile(S3D::formatStringBuffer("adminpassword-%i.xml",
00221                         ScorchedServer::instance()->getOptionsGame().getPortNo()));
00222 
00223         XMLNode usersNode("users");
00224         std::list<Credential>::iterator itor;
00225         for (itor = creds.begin();
00226                 itor != creds.end();
00227                 itor++)
00228         {
00229                 Credential &credential = *itor;
00230                 XMLNode *userNode = new XMLNode("user");
00231 
00232                 userNode->addChild(new XMLNode("name", credential.username));
00233                 userNode->addChild(new XMLNode("password", credential.password));
00234 
00235                 std::set<std::string>::iterator permitor;
00236                 for (permitor = credential.permissions.begin();
00237                         permitor != credential.permissions.end();
00238                         permitor++)
00239                 {
00240                         userNode->addChild(new XMLNode("permission", *permitor));
00241                 }
00242 
00243                 usersNode.addChild(userNode);
00244         }
00245 
00246         if (!usersNode.writeToFile(fileName)) return false;
00247 
00248         return true;    
00249 }
00250 
00251 bool ServerAdminSessions::getAllCredentials(std::list<Credential> &creds)
00252 {
00253         std::string fileName = 
00254                 S3D::getSettingsFile(S3D::formatStringBuffer("adminpassword-%i.xml",
00255                         ScorchedServer::instance()->getOptionsGame().getPortNo()));
00256 
00257         XMLFile file;
00258         if (!file.readFile(fileName))
00259         {
00260                 ServerCommon::serverLog( 
00261                         S3D::formatStringBuffer("Failed to parse \"%s\"\n%s", 
00262                         fileName.c_str(),
00263                         file.getParserError()));
00264                 return false;
00265         }
00266         if (!file.getRootNode())
00267         {
00268                 ServerCommon::serverLog( 
00269                         S3D::formatStringBuffer("Please create file %s to have admin users", 
00270                         fileName.c_str()));
00271                 return false;
00272         }
00273 
00274         // Itterate all of the users in the file
00275     std::list<XMLNode *>::iterator childrenItor;
00276         std::list<XMLNode *> &children = file.getRootNode()->getChildren();
00277     for (childrenItor = children.begin();
00278                  childrenItor != children.end();
00279                  childrenItor++)
00280     {
00281         XMLNode *currentNode = (*childrenItor);
00282                 if (strcmp(currentNode->getName(), "user")) return false;
00283 
00284                 Credential credential;
00285                 if (!currentNode->getNamedChild("name", credential.username)) return false;
00286                 if (!currentNode->getNamedChild("password", credential.password)) return false;
00287 
00288                 std::string permission;
00289                 while (currentNode->getNamedChild("permission", permission, false))
00290                 {
00291                         if (localCreds_.hasPermission(permission))
00292                         {
00293                                 credential.permissions.insert(permission);
00294                         }
00295                         else
00296                         {
00297                                 Logger::log(S3D::formatStringBuffer(
00298                                         "ERROR: Trying to give admin %s unavailable permission %s",
00299                                         credential.username.c_str(),
00300                                         permission.c_str()));
00301                         }
00302                 }
00303 
00304                 if (!currentNode->failChildren()) return false;
00305                 creds.push_back(credential);
00306         }
00307 
00308         return true;    
00309 }

Generated on Mon Feb 16 15:14:53 2009 for Scorched3D by  doxygen 1.5.3