00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00075 std::map <unsigned int, SessionParams>::iterator sitor;
00076 for (sitor = sessions_.begin();
00077 sitor != sessions_.end();
00078 sitor++)
00079 {
00080 SessionParams ¶ms = (*sitor).second;
00081 if (currentTime > params.sessionTime + SessionTimeOut)
00082 {
00083 sessions_.erase(sitor);
00084 break;
00085 }
00086 }
00087
00088
00089 std::map <unsigned int, SessionParams>::iterator findItor =
00090 sessions_.find(sid);
00091 if (findItor != sessions_.end())
00092 {
00093 SessionParams ¶ms = (*findItor).second;
00094 if (currentTime < params.sessionTime + SessionTimeOut)
00095 {
00096 params.sessionTime = currentTime;
00097 return ¶ms;
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
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
00148 std::map<unsigned int, SessionParams>::iterator itor;
00149 for (itor = sessions_.begin();
00150 itor != sessions_.end();
00151 itor++)
00152 {
00153 SessionParams ¶ms = (*itor).second;
00154 if (0 == strcmp(params.credentials.username.c_str(),
00155 userCreds.username.c_str()))
00156 {
00157
00158 sid = (*itor).first;
00159 break;
00160 }
00161 }
00162
00163
00164 if (sid == 0)
00165 {
00166
00167 do
00168 {
00169 sid = rand();
00170 } while (sessions_.find(sid) != sessions_.end() || sid == 0);
00171 }
00172
00173
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
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 }