1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-30 22:50:10 +03:00

feature #203: Initial version for the Authorization Manager and Drivers

This commit is contained in:
Ruben S. Montero 2010-05-28 00:27:29 +02:00
parent e86c0f07eb
commit baca5e4a44
5 changed files with 911 additions and 0 deletions

346
include/AuthManager.h Normal file
View File

@ -0,0 +1,346 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef AUTH_MANAGER_H_
#define AUTH_MANAGER_H_
#include "MadManager.h"
#include "ActionManager.h"
#include "AuthManagerDriver.h"
using namespace std;
//Forward definition of the AuthManager
class AuthManager;
/**
* The AuthRequest class is used to pass an Authorization or Authentication
* request to the AuthManager. The result of the request will be stored
* in the result and message attributes of this class.
*/
class AuthRequest
{
public:
AuthRequest(ActionManager *_am, int _uid, const string& _auth_driver):
result(false),
am(_am),
auth_driver(_auth_driver),
uid(_uid)
{};
~AuthRequest(){};
/**
* Authorization Request Type
*/
enum Operation
{
CREATION, /** Authorization to create an object (host, vm, net, image)*/
DELETION, /** Authorization to delete an object */
USAGE, /** Authorization to use an object */
MANAGE /** Authorization to manage an object */
};
/**
* OpenNebula objects to perform an Operation
*/
enum Object
{
VM,
HOST,
NET,
IMAGE
};
/**
* Sets the challenge to authenticate an user
* @param challenge a driver specific authentication challenge
*/
void set_challenge(const string &ch)
{
challenge = ch;
}
/**
* Adds a new authorization item to this requests
* @param op the operation to be authorized
* @param ob the object over which the operation will be performed
* @param oid id of the object
*/
void add_auth(Operation op, Object ob, int oid)
{
ostringstream oss;
switch (op)
{
case CREATION: oss << "CREATION:" ; break;
case DELETION: oss << "DELETION:" ; break;
case USAGE: oss << "USAGE:" ; break;
case MANAGE: oss << "MANAGE:" ; break;
}
switch (ob)
{
case VM: oss << "VM:" ; break;
case HOST: oss << "HOST:" ; break;
case NET: oss << "NET:" ; break;
case IMAGE: oss << "IMAGE:" ; break;
}
oss << oid;
auths.push_back(oss.str());
};
/**
* Gets the authorization requests in a single string
* @return a space separated list of auth requests.
*/
string get_auths()
{
ostringstream oss;
for (unsigned int i=0; i<auths.size(); i++)
{
oss << auths[i] << " ";
}
return oss.str();
};
/**
* Notify client that we have an answer for the request
*/
void notify()
{
am->trigger(ActionListener::ACTION_FINALIZE,0);
};
/**
* The result of the request, true if authorized or authenticated
*/
bool result;
/**
* Error message for negative results
*/
string message;
private:
friend class AuthManager;
/**
* The ActionManager that will be notify when the request is ready.
*/
ActionManager * am;
/**
* The name of the Authorization driver to use with this request
*/
string auth_driver;
/**
* The user id for this request
*/
int uid;
/**
* Authentication challenge
*/
string challenge;
/**
* A list of authorization requests
*/
vector<string> auths;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
extern "C" void * authm_action_loop(void *arg);
class AuthManager : public MadManager, public ActionListener
{
public:
AuthManager(
vector<const Attribute*>& _mads):
MadManager(_mads)
{
am.addListener(this);
};
~AuthManager(){};
enum Actions
{
AUTHENTICATE,
AUTHORIZE,
FINALIZE
};
/**
* Triggers specific actions to the Auth Manager. This function
* wraps the ActionManager trigger function.
* @param action the Auth Manager action
* @param request an auth request
*/
void trigger(
Actions action,
AuthRequest * request);
/**
* This functions starts the associated listener thread, and creates a
* new thread for the Information Manager. This thread will wait in
* an action loop till it receives ACTION_FINALIZE.
* @return 0 on success.
*/
int start();
/**
* Loads Virtual Machine Manager Mads defined in configuration file
* @param uid of the user executing the driver. When uid is 0 the nebula
* identity will be used. Otherwise the Mad will be loaded through the
* sudo application.
*/
void load_mads(int uid);
/**
* Gets the thread identification.
* @return pthread_t for the manager thread (that in the action loop).
*/
pthread_t get_thread_id() const
{
return authm_thread;
};
/**
* Notify the result of an auth request
*/
void notify(int auth_id, bool result, const string& message);
private:
/**
* Thread id for the Transfer Manager
*/
pthread_t authm_thread;
/**
* Action engine for the Manager
*/
ActionManager am;
/**
* Action engine for the Manager
*/
map<int, AuthRequest *> auth_requests;
/**
* Mutex to access the auth_requests
*/
pthread_mutex_t mutex;
/**
* Returns a pointer to a Auth Manager driver.
* @param name of an attribute of the driver (e.g. its type)
* @param value of the attribute
* @return the Auth driver with attribute name equal to value
* or 0 in not found
*/
const AuthManagerDriver * get(
const string& name,
const string& value)
{
return static_cast<const AuthManagerDriver *>
(MadManager::get(0,name,value));
};
/**
* Returns a pointer to a Auth Manager driver. The driver is
* searched by its name.
* @param name the name of the driver
* @return the TM driver owned by uid with attribute name equal to value
* or 0 in not found
*/
const AuthManagerDriver * get(const string& name)
{
string _name("NAME");
return static_cast<const AuthManagerDriver *>
(MadManager::get(0,_name,name));
};
/**
* Function to execute the Manager action loop method within a new pthread
* (requires C linkage)
*/
friend void * authm_action_loop(void *arg);
/**
* The action function executed when an action is triggered.
* @param action the name of the action
* @param arg arguments for the action function
*/
void do_action(
const string & action,
void * arg);
/**
* This function authenticates a user
*/
void authenticate_action(AuthRequest * ar);
/**
* This function authorizes a user request
*/
void authorize_action(AuthRequest * ar);
/**
* Function to lock the pool
*/
void lock()
{
pthread_mutex_lock(&mutex);
};
/**
* Function to unlock the pool
*/
void unlock()
{
pthread_mutex_unlock(&mutex);
};
/**
* Add a new request to the Request map
* @param ar pointer to the AuthRequest
* @return the id for the request
*/
int add_request(AuthRequest *ar);
/**
* Gets request from the Request map
* @param id for the request
* @return pointer to the AuthRequest
*/
AuthRequest * get_request(int id);
};
#endif /*AUTH_MANAGER_H*/

View File

@ -0,0 +1,92 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef AUTH_MANAGER_DRIVER_H_
#define AUTH_MANAGER_DRIVER_H_
#include <map>
#include <string>
#include <sstream>
#include "Mad.h"
using namespace std;
//Forward definition of the AuthManager Class
class AuthManager;
/**
* AuthManagerDriver provides a base class to implement TM
* Drivers. This class implements the protocol and recover functions
* from the Mad interface.
*/
class AuthManagerDriver : public Mad
{
public:
AuthManagerDriver(
int userid,
const map<string,string>& attrs,
bool sudo,
AuthManager * _authm):
Mad(userid,attrs,sudo), authm(_authm){};
virtual ~AuthManagerDriver(){};
/**
* Implements the VM Manager driver protocol.
* @param message the string read from the driver
*/
void protocol(
string& message);
/**
* Re-starts the driver
*/
void recover();
private:
friend class AuthManager;
/**
* The AuthManager to notify results.
*/
AuthManager * authm;
/**
* Sends an authorization request to the MAD:
* "AUTHORIZE OPERATION_ID USER_ID REQUEST1 REQUEST2..."
* @param oid an id to identify the request.
* @param uid the user id.
* @param requests space separated list of requests in the form OP:OBJ:ID
*/
void authorize(int oid, int uid, const string& requests) const;
/**
* Sends an authorization request to the MAD:
* "AUTHENTICATE OPERATION_ID USER_ID CHALLENGE"
* @param oid an id to identify the request.
* @param uid the user id.
* @param challenge to authenticate the user
*/
void authenticate(int oid, int uid, const string& ch) const;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#endif /*AUTH_MANAGER_DRIVER_H_*/

319
src/authm/AuthManager.cc Normal file
View File

@ -0,0 +1,319 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "AuthManager.h"
#include "NebulaLog.h"
#include "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
extern "C" void * authm_action_loop(void *arg)
{
AuthManager * authm;
if ( arg == 0 )
{
return 0;
}
authm = static_cast<AuthManager *>(arg);
NebulaLog::log("AuM",Log::INFO,"Authorization Manager started.");
authm->am.loop(0,0);
NebulaLog::log("TrM",Log::INFO,"Authorization Manager stopped.");
return 0;
}
/* -------------------------------------------------------------------------- */
int AuthManager::start()
{
int rc;
pthread_attr_t pattr;
rc = MadManager::start();
if ( rc != 0 )
{
return -1;
}
NebulaLog::log("AuM",Log::INFO,"Starting Auth Manager...");
pthread_attr_init (&pattr);
pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE);
rc = pthread_create(&authm_thread,&pattr,authm_action_loop,(void *) this);
return rc;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManager::trigger(Actions action, AuthRequest * request)
{
string aname;
switch (action)
{
case AUTHENTICATE:
aname = "AUTHENTICATE";
break;
case AUTHORIZE:
aname = "AUTHORIZE";
break;
case FINALIZE:
aname = ACTION_FINALIZE;
break;
default:
return;
}
am.trigger(aname,request);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManager::do_action(const string &action, void * arg)
{
AuthRequest * request;
if (arg == 0)
{
return;
}
request = static_cast<AuthRequest *>(arg);
if (action == "AUTHENTICATE")
{
authenticate_action(request);
}
else if (action == "AUTHORIZE")
{
authorize_action(request);
}
else if (action == ACTION_FINALIZE)
{
NebulaLog::log("AuM",Log::INFO,"Stopping Authorization Manager...");
MadManager::stop();
}
else
{
ostringstream oss;
oss << "Unknown action name: " << action;
NebulaLog::log("AuM", Log::ERROR, oss);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManager::authenticate_action(AuthRequest * ar)
{
const AuthManagerDriver * authm_md;
int id;
// ------------------------------------------------------------------------
// Get the driver
// ------------------------------------------------------------------------
authm_md = get(ar->auth_driver);
if (authm_md == 0)
{
goto error_driver;
}
// ------------------------------------------------------------------------
// Queue the request
// ------------------------------------------------------------------------
id = add_request(ar);
// ------------------------------------------------------------------------
// Make the request to the driver
// ------------------------------------------------------------------------
authm_md->authenticate(id,ar->uid,ar->challenge);
return;
error_driver:
ar->result = false;
ar->message = "Could not find Authorization driver";
ar->notify();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManager::authorize_action(AuthRequest * ar)
{
const AuthManagerDriver * authm_md;
int id;
string auths;
// ------------------------------------------------------------------------
// Get the driver
// ------------------------------------------------------------------------
authm_md = get(ar->auth_driver);
if (authm_md == 0)
{
goto error_driver;
}
// ------------------------------------------------------------------------
// Queue the request
// ------------------------------------------------------------------------
id = add_request(ar);
// ------------------------------------------------------------------------
// Make the request to the driver
// ------------------------------------------------------------------------
auths = ar->get_auths();
authm_md->authorize(id, ar->uid, auths);
return;
error_driver:
ar->result = false;
ar->message = "Could not find Authorization driver";
ar->notify();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int AuthManager::add_request(AuthRequest *ar)
{
static int auth_id = 0;
int id;
lock();
id = auth_id++;
auth_requests.insert(auth_requests.end(),make_pair(auth_id,ar));
unlock();
return id;
}
/* -------------------------------------------------------------------------- */
AuthRequest * AuthManager::get_request(int id)
{
AuthRequest * ar = 0;
map<int,AuthRequest *>::iterator it;
lock();
it=auth_requests.find(id);
if ( it != auth_requests.end())
{
ar = it->second;
}
auth_requests.erase(it);
unlock();
return ar;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManager::notify(int auth_id, bool result, const string& message)
{
AuthRequest * ar;
ar = get_request(auth_id);
if ( ar == 0 )
{
return;
}
ar->result = result;
ar->message= message;
ar->notify();
}
/* ************************************************************************** */
/* MAD Loading */
/* ************************************************************************** */
void AuthManager::load_mads(int uid)
{
unsigned int i;
ostringstream oss;
const VectorAttribute * vattr;
int rc;
string name;
AuthManagerDriver * authm_driver = 0;
oss << "Loading Authorization Manager drivers.";
NebulaLog::log("AuM",Log::INFO,oss);
for(i=0,oss.str("");i<mad_conf.size();i++,oss.str(""),authm_driver=0)
{
vattr = static_cast<const VectorAttribute *>(mad_conf[i]);
name = vattr->vector_value("NAME");
oss << "\tLoading driver: " << name;
NebulaLog::log("AuM", Log::INFO, oss);
authm_driver = new AuthManagerDriver(uid,vattr->value(),(uid!=0),this);
if ( authm_driver == 0 )
continue;
rc = add(authm_driver);
if ( rc == 0 )
{
oss.str("");
oss << "\tDriver " << name << " loaded.";
NebulaLog::log("AuM",Log::INFO,oss);
}
}
}

View File

@ -0,0 +1,124 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "AuthManagerDriver.h"
#include "AuthManager.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include <sstream>
/* ************************************************************************** */
/* Driver ASCII Protocol Implementation */
/* ************************************************************************** */
void AuthManagerDriver::authorize(int oid, int uid, const string& reqs) const
{
ostringstream os;
os << "AUTHORIZE " << oid << " " << uid << " " << reqs << endl;
write(os);
}
void AuthManagerDriver::authenticate(int oid, int uid, const string& ch) const
{
ostringstream os;
os << "AUTHENTICATE " << oid << " " << uid << " " << ch << endl;
write(os);
}
/* ************************************************************************** */
/* MAD Interface */
/* ************************************************************************** */
void AuthManagerDriver::protocol(
string& message)
{
istringstream is(message);
ostringstream os;
string action;
string result;
string info="";
int id;
os << "Message received: " << message;
NebulaLog::log("AuM", Log::DEBUG, os);
// Parse the driver message
if ( is.good() )
is >> action >> ws;
else
return;
if ( is.good() )
is >> result >> ws;
else
return;
if ( is.good() )
{
is >> id >> ws;
if ( is.fail() )
{
if ( action == "LOG" )
{
string info;
is.clear();
getline(is,info);
NebulaLog::log("AuM",Log::INFO, info.c_str());
}
return;
}
}
else
return;
if (action == "LOG")
{
string info;
getline(is,info);
NebulaLog::log("AuM",Log::INFO,info.c_str());
}
else if (result == "SUCCESS")
{
authm->notify(id,true,info);
}
else
{
getline(is,info);
authm->notify(id,false,info);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManagerDriver::recover()
{
NebulaLog::log("AuM",Log::INFO,"Recovering Authorization drivers");
}

30
src/authm/SConstruct Normal file
View File

@ -0,0 +1,30 @@
# SConstruct for src/vm
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
Import('env')
lib_name='nebula_authm'
# Sources to generate the library
source_files=[
'AuthManager.cc',
'AuthManagerDriver.cc'
]
# Build library
env.StaticLibrary(lib_name, source_files)