Esempio n. 1
0
bool BZFSHTTPAuth::generatePage ( const HTTPRequest &request, HTTPReply &reply )
{
  if (!authPage.size())
    setupAuth();

  flushTasks();
  int sessionID = request.sessionID;
  reply.docType = HTTPReply::eHTML;
  reply.returnCode = HTTPReply::e200OK;

  std::map<int,AuthInfo>::iterator authItr = authedSessions.find(sessionID);
  if ( authItr != authedSessions.end() )  // it is one of our authorized users, be nice and forward the request to our child
  {
    // put this back to the default
    reply.docType = HTTPReply::eText;

    authItr->second.time = bz_getCurrentTime();
    bool complete = handleAuthedRequest(authItr->second.level,request,reply);

    if (!complete)
      defferedAuthedRequests.push_back(request.requestID);

    return complete;
  }
  else	// they are not fully authorized yet
  {
    std::map<int,PendingTokenTask*>::iterator pendingItr = pendingTokenTasks.find(request.requestID);
    if (pendingItr != pendingTokenTasks.end())	// they have a token, check it
    {
      AuthInfo info;
      info.time = bz_getCurrentTime();

      if (!pendingItr->second->groups.size())
	info.level = -1;
      else
      {
	if (pendingItr->second->groups.size() == 1)
	{
	  info.username = pendingItr->second->groups[0];
	  info.level = 0; // just authed, no levels
	}
	else
	{
	  info.username = pendingItr->second->groups[0];
	  info.level = getLevelFromGroups(pendingItr->second->groups);
	  info.groups = pendingItr->second->groups;
	  info.groups.erase(info.groups.begin()); // pull off the first 'group' because it's a name
	}
	if (info.level >= 0)
	  authedSessions[request.sessionID] = info;
      }

      delete(pendingItr->second);
      pendingTokenTasks.erase(pendingItr);

      // put this back to the default
      reply.docType = HTTPReply::eText;

      bool complete = handleAuthedRequest(info.level,request,reply);

      if (!complete)
	defferedAuthedRequests.push_back(request.requestID);

      return complete;
    }
    else
    {
      std::string action,user,token;
      request.getParam("action",action);
      request.getParam("user",user);
      request.getParam("token",token);
      if (compare_nocase(action,"login") == 0 && user.size() && token.size()) // it's a response from weblogin
	return verifyToken(request,reply);
      else
      {
	// it's someone we know NOTHING about, send them the login
	templateSystem.startTimer();
	size_t s = authPage.find_last_of('.');
	if (s != std::string::npos)
	{
	  if (compare_nocase(authPage.c_str()+s,".tmpl") == 0)
	  {
	    if(!templateSystem.processTemplateFile(reply.body,authPage.c_str()))
	      templateSystem.processTemplate(reply.body,authPage);
	  }
	  else
	    templateSystem.processTemplate(reply.body,authPage);
	}
	else
	  templateSystem.processTemplate(reply.body,authPage);
      }
    }
  }

  return true;
}
Esempio n. 2
0
bool BZFSHTTPAuth::verifyToken ( const HTTPRequest &request, HTTPReply &reply )
{
  // build up the groups list
  std::string token,user;
  request.getParam("token",token);
  request.getParam("user",user);

  std::vector<std::string> groups;

  std::map<int, std::vector<std::string> >::iterator itr = authLevels.begin();

  while (itr != authLevels.end())
  {
    for (size_t i = 0; i < itr->second.size();i++)
    {
      std::string &perm = itr->second[i];

      std::vector<std::string> groupsWithPerm;

      if (compare_nocase(perm,"ADMIN")==0)
	groupsWithPerm = findGroupsWithAdmin();
      else
	groupsWithPerm = findGroupsWithPerm(perm);

      // only add groups that are not in the list yet
      for (size_t g = 0; g < groupsWithPerm.size(); g++)
      {
	if (std::find(groups.begin(),groups.end(),groupsWithPerm[g]) == groups.end())
	  groups.push_back(groupsWithPerm[g]);
      }
    }
    itr++;
  }

  PendingTokenTask *task = new PendingTokenTask;

  if (!user.size() || !token.size())
  {
    reply.body += "Invalid response";
    reply.docType = HTTPReply::eText;
    return true;
  }
  task->requestID = request.requestID;
  task->URL = "http://my.bzflag.org/db/";
  task->URL += "?action=CHECKTOKENS&checktokens=" + url_encode(user);
  if (!ipIsLocal(request.ip))
    task->URL += "@" + request.ip;
  task->URL += "%3D" + token;

  task->URL += "&groups=";
  for (size_t g = 0; g < groups.size(); g++)
  {
    task->URL += groups[g];
    if ( g+1 < groups.size())
      task->URL += "%0D%0A";
  }

  // give the task to bzfs and let it do it, when it's done it'll be processed
  bz_addURLJob(task->URL.c_str(),task);

  return false;
}